Home | History | Annotate | Download | only in map.modifiers
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // UNSUPPORTED: c++98, c++03, c++11, c++14
     11 
     12 // <map>
     13 
     14 // class map
     15 
     16 // template <class... Args>
     17 //  pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);          // C++17
     18 // template <class... Args>
     19 //  pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);               // C++17
     20 // template <class... Args>
     21 //  iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
     22 // template <class... Args>
     23 //  iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);      // C++17
     24 
     25 #include <map>
     26 #include <cassert>
     27 #include <tuple>
     28 
     29 class Moveable
     30 {
     31     Moveable(const Moveable&);
     32     Moveable& operator=(const Moveable&);
     33 
     34     int int_;
     35     double double_;
     36 public:
     37     Moveable() : int_(0), double_(0) {}
     38     Moveable(int i, double d) : int_(i), double_(d) {}
     39     Moveable(Moveable&& x)
     40         : int_(x.int_), double_(x.double_)
     41             {x.int_ = -1; x.double_ = -1;}
     42     Moveable& operator=(Moveable&& x)
     43         {int_ = x.int_; x.int_ = -1;
     44          double_ = x.double_; x.double_ = -1;
     45          return *this;
     46         }
     47 
     48     bool operator==(const Moveable& x) const
     49         {return int_ == x.int_ && double_ == x.double_;}
     50     bool operator<(const Moveable& x) const
     51         {return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);}
     52 
     53     int get() const {return int_;}
     54     bool moved() const {return int_ == -1;}
     55 };
     56 
     57 
     58 int main()
     59 {
     60     { // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
     61         typedef std::map<int, Moveable> M;
     62         typedef std::pair<M::iterator, bool> R;
     63         M m;
     64         R r;
     65         for (int i = 0; i < 20; i += 2)
     66             m.emplace (i, Moveable(i, (double) i));
     67         assert(m.size() == 10);
     68 
     69         Moveable mv1(3, 3.0);
     70         for (int i=0; i < 20; i += 2)
     71         {
     72             r = m.try_emplace(i, std::move(mv1));
     73             assert(m.size() == 10);
     74             assert(!r.second);              // was not inserted
     75             assert(!mv1.moved());           // was not moved from
     76             assert(r.first->first == i);    // key
     77         }
     78 
     79         r = m.try_emplace(-1, std::move(mv1));
     80         assert(m.size() == 11);
     81         assert(r.second);                   // was inserted
     82         assert(mv1.moved());                // was moved from
     83         assert(r.first->first == -1);       // key
     84         assert(r.first->second.get() == 3); // value
     85 
     86         Moveable mv2(5, 3.0);
     87         r = m.try_emplace(5, std::move(mv2));
     88         assert(m.size() == 12);
     89         assert(r.second);                   // was inserted
     90         assert(mv2.moved());                // was moved from
     91         assert(r.first->first == 5);        // key
     92         assert(r.first->second.get() == 5); // value
     93 
     94         Moveable mv3(-1, 3.0);
     95         r = m.try_emplace(117, std::move(mv2));
     96         assert(m.size() == 13);
     97         assert(r.second);                    // was inserted
     98         assert(mv2.moved());                 // was moved from
     99         assert(r.first->first == 117);       // key
    100         assert(r.first->second.get() == -1); // value
    101     }
    102 
    103     {  // pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
    104         typedef std::map<Moveable, Moveable> M;
    105         typedef std::pair<M::iterator, bool> R;
    106         M m;
    107         R r;
    108         for ( int i = 0; i < 20; i += 2 )
    109             m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
    110         assert(m.size() == 10);
    111 
    112         Moveable mvkey1(2, 2.0);
    113         Moveable mv1(4, 4.0);
    114         r = m.try_emplace(std::move(mvkey1), std::move(mv1));
    115         assert(m.size() == 10);
    116         assert(!r.second);                 // was not inserted
    117         assert(!mv1.moved());              // was not moved from
    118         assert(!mvkey1.moved());           // was not moved from
    119         assert(r.first->first == mvkey1);  // key
    120 
    121         Moveable mvkey2(3, 3.0);
    122         r = m.try_emplace(std::move(mvkey2), std::move(mv1));
    123         assert(m.size() == 11);
    124         assert(r.second);                   // was inserted
    125         assert(mv1.moved());                // was moved from
    126         assert(mvkey2.moved());             // was moved from
    127         assert(r.first->first.get()  == 3); // key
    128         assert(r.first->second.get() == 4); // value
    129     }
    130 
    131     {  // iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
    132         typedef std::map<int, Moveable> M;
    133         M m;
    134         M::iterator r;
    135         for ( int i = 0; i < 20; i += 2 )
    136             m.try_emplace ( i, Moveable(i, (double) i));
    137         assert(m.size() == 10);
    138         M::const_iterator it = m.find(2);
    139 
    140         Moveable mv1(3, 3.0);
    141         for (int i=0; i < 20; i += 2)
    142         {
    143             r = m.try_emplace(it, i, std::move(mv1));
    144             assert(m.size() == 10);
    145             assert(!mv1.moved());         // was not moved from
    146             assert(r->first == i);        // key
    147             assert(r->second.get() == i); // value
    148         }
    149 
    150         r = m.try_emplace(it, 3, std::move(mv1));
    151         assert(m.size() == 11);
    152         assert(mv1.moved());          // was moved from
    153         assert(r->first == 3);        // key
    154         assert(r->second.get() == 3); // value
    155     }
    156 
    157     {  // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
    158         typedef std::map<Moveable, Moveable> M;
    159         M m;
    160         M::iterator r;
    161         for ( int i = 0; i < 20; i += 2 )
    162             m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
    163         assert(m.size() == 10);
    164         M::const_iterator it = std::next(m.cbegin());
    165 
    166         Moveable mvkey1(2, 2.0);
    167         Moveable mv1(4, 4.0);
    168         r = m.try_emplace(it, std::move(mvkey1), std::move(mv1));
    169         assert(m.size() == 10);
    170         assert(!mv1.moved());        // was not moved from
    171         assert(!mvkey1.moved());     // was not moved from
    172         assert(r->first == mvkey1);  // key
    173 
    174         Moveable mvkey2(3, 3.0);
    175         r = m.try_emplace(it, std::move(mvkey2), std::move(mv1));
    176         assert(m.size() == 11);
    177         assert(mv1.moved());          // was moved from
    178         assert(mvkey2.moved());       // was moved from
    179         assert(r->first.get()  == 3); // key
    180         assert(r->second.get() == 4); // value
    181     }
    182 }
    183