diff options
author | Marshall Clow <mclow.lists@gmail.com> | 2015-07-07 05:45:35 +0000 |
---|---|---|
committer | Marshall Clow <mclow.lists@gmail.com> | 2015-07-07 05:45:35 +0000 |
commit | 0ce05a9f86509167fd821fdb9b187e25d2e15742 (patch) | |
tree | a65adc045fb575d33dc581f04282d887ad90222a /test | |
parent | f3a1a187a1af2188f47a6e8c20cbfac74ca24823 (diff) | |
download | external_libcxx-0ce05a9f86509167fd821fdb9b187e25d2e15742.tar.gz external_libcxx-0ce05a9f86509167fd821fdb9b187e25d2e15742.tar.bz2 external_libcxx-0ce05a9f86509167fd821fdb9b187e25d2e15742.zip |
The rest of N4279 and LWG#2464 - for unordered_map
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@241555 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/std/containers/unord/unord.map/unorder.map.modifiers/insert_or_assign.pass.cpp | 198 | ||||
-rw-r--r-- | test/std/containers/unord/unord.map/unorder.map.modifiers/try.emplace.pass.cpp | 195 |
2 files changed, 393 insertions, 0 deletions
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/insert_or_assign.pass.cpp b/test/std/containers/unord/unord.map/unorder.map.modifiers/insert_or_assign.pass.cpp new file mode 100644 index 000000000..89929c856 --- /dev/null +++ b/test/std/containers/unord/unord.map/unorder.map.modifiers/insert_or_assign.pass.cpp @@ -0,0 +1,198 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: c++03, c++11, c++14 + +// <unordered_map> + +// class unordered_map + +// template <class M> +// pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17 +// template <class M> +// pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17 +// template <class M> +// iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17 +// template <class M> +// iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17 + +#include <__config> +#include <unordered_map> +#include <cassert> +#include <tuple> + +#include <iostream> + +class Moveable +{ + Moveable(const Moveable&); + Moveable& operator=(const Moveable&); + + int int_; + double double_; +public: + Moveable() : int_(0), double_(0) {} + Moveable(int i, double d) : int_(i), double_(d) {} + Moveable(Moveable&& x) + : int_(x.int_), double_(x.double_) + {x.int_ = -1; x.double_ = -1;} + Moveable& operator=(Moveable&& x) + {int_ = x.int_; x.int_ = -1; + double_ = x.double_; x.double_ = -1; + return *this; + } + + bool operator==(const Moveable& x) const + {return int_ == x.int_ && double_ == x.double_;} + bool operator<(const Moveable& x) const + {return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);} + size_t hash () const { return std::hash<int>()(int_) + std::hash<double>()(double_); } + + int get() const {return int_;} + bool moved() const {return int_ == -1;} +}; + +namespace std { + template <> struct hash<Moveable> { + size_t operator () (const Moveable &m) const { return m.hash(); } + }; +} + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + + { // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); + typedef std::unordered_map<int, Moveable> M; + typedef std::pair<M::iterator, bool> R; + M m; + R r; + for (int i = 0; i < 20; i += 2) + m.emplace ( i, Moveable(i, (double) i)); + assert(m.size() == 10); + + for (int i=0; i < 20; i += 2) + { + Moveable mv(i+1, i+1); + r = m.insert_or_assign(i, std::move(mv)); + assert(m.size() == 10); + assert(!r.second); // was not inserted + assert(mv.moved()); // was moved from + assert(r.first->first == i); // key + assert(r.first->second.get() == i+1); // value + } + + Moveable mv1(5, 5.0); + r = m.insert_or_assign(-1, std::move(mv1)); + assert(m.size() == 11); + assert(r.second); // was inserted + assert(mv1.moved()); // was moved from + assert(r.first->first == -1); // key + assert(r.first->second.get() == 5); // value + + Moveable mv2(9, 9.0); + r = m.insert_or_assign(3, std::move(mv2)); + assert(m.size() == 12); + assert(r.second); // was inserted + assert(mv2.moved()); // was moved from + assert(r.first->first == 3); // key + assert(r.first->second.get() == 9); // value + + Moveable mv3(-1, 5.0); + r = m.insert_or_assign(117, std::move(mv3)); + assert(m.size() == 13); + assert(r.second); // was inserted + assert(mv3.moved()); // was moved from + assert(r.first->first == 117); // key + assert(r.first->second.get() == -1); // value + } + { // pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); + typedef std::unordered_map<Moveable, Moveable> M; + typedef std::pair<M::iterator, bool> R; + M m; + R r; + for (int i = 0; i < 20; i += 2) + m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1)); + assert(m.size() == 10); + + Moveable mvkey1(2, 2.0); + Moveable mv1(4, 4.0); + r = m.insert_or_assign(std::move(mvkey1), std::move(mv1)); + assert(m.size() == 10); + assert(!r.second); // was not inserted + assert(!mvkey1.moved()); // was not moved from + assert(mv1.moved()); // was moved from + assert(r.first->first == mvkey1); // key + assert(r.first->second.get() == 4); // value + + Moveable mvkey2(3, 3.0); + Moveable mv2(5, 5.0); + r = m.try_emplace(std::move(mvkey2), std::move(mv2)); + assert(m.size() == 11); + assert(r.second); // was inserted + assert(mv2.moved()); // was moved from + assert(mvkey2.moved()); // was moved from + assert(r.first->first.get() == 3); // key + assert(r.first->second.get() == 5); // value + } + { // iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + typedef std::unordered_map<int, Moveable> M; + M m; + M::iterator r; + for (int i = 0; i < 20; i += 2) + m.emplace ( i, Moveable(i, (double) i)); + assert(m.size() == 10); + M::const_iterator it = m.find(2); + + Moveable mv1(3, 3.0); + r = m.insert_or_assign(it, 2, std::move(mv1)); + assert(m.size() == 10); + assert(mv1.moved()); // was moved from + assert(r->first == 2); // key + assert(r->second.get() == 3); // value + + Moveable mv2(5, 5.0); + r = m.insert_or_assign(it, 3, std::move(mv2)); + assert(m.size() == 11); + assert(mv2.moved()); // was moved from + assert(r->first == 3); // key + assert(r->second.get() == 5); // value + } + { // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + typedef std::unordered_map<Moveable, Moveable> M; + M m; + M::iterator r; + for (int i = 0; i < 20; i += 2) + m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1)); + assert(m.size() == 10); + M::const_iterator it = std::next(m.cbegin()); + + Moveable mvkey1(2, 2.0); + Moveable mv1(4, 4.0); + r = m.insert_or_assign(it, std::move(mvkey1), std::move(mv1)); + assert(m.size() == 10); + assert(mv1.moved()); // was moved from + assert(!mvkey1.moved()); // was not moved from + assert(r->first == mvkey1); // key + assert(r->second.get() == 4); // value + + Moveable mvkey2(3, 3.0); + Moveable mv2(5, 5.0); + r = m.insert_or_assign(it, std::move(mvkey2), std::move(mv2)); + assert(m.size() == 11); + assert(mv2.moved()); // was moved from + assert(mvkey2.moved()); // was moved from + assert(r->first.get() == 3); // key + assert(r->second.get() == 5); // value + } + +#endif // _LIBCPP_HAS_NO_VARIADICS +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +}
\ No newline at end of file diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/try.emplace.pass.cpp b/test/std/containers/unord/unord.map/unorder.map.modifiers/try.emplace.pass.cpp new file mode 100644 index 000000000..e6964ce94 --- /dev/null +++ b/test/std/containers/unord/unord.map/unorder.map.modifiers/try.emplace.pass.cpp @@ -0,0 +1,195 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: c++03, c++11, c++14 + +// <unordered_map> + +// class unordered_map + +// template <class... Args> +// pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17 +// template <class... Args> +// pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17 +// template <class... Args> +// iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17 +// template <class... Args> +// iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17 + +#include <__config> +#include <unordered_map> +#include <cassert> +#include <tuple> + +class Moveable +{ + Moveable(const Moveable&); + Moveable& operator=(const Moveable&); + + int int_; + double double_; +public: + Moveable() : int_(0), double_(0) {} + Moveable(int i, double d) : int_(i), double_(d) {} + Moveable(Moveable&& x) + : int_(x.int_), double_(x.double_) + {x.int_ = -1; x.double_ = -1;} + Moveable& operator=(Moveable&& x) + {int_ = x.int_; x.int_ = -1; + double_ = x.double_; x.double_ = -1; + return *this; + } + + bool operator==(const Moveable& x) const + {return int_ == x.int_ && double_ == x.double_;} + bool operator<(const Moveable& x) const + {return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);} + size_t hash () const { return std::hash<int>()(int_) + std::hash<double>()(double_); } + + int get() const {return int_;} + bool moved() const {return int_ == -1;} +}; + +namespace std { + template <> struct hash<Moveable> { + size_t operator () (const Moveable &m) const { return m.hash(); } + }; +} + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_HAS_NO_VARIADICS + + { // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); + typedef std::unordered_map<int, Moveable> M; + typedef std::pair<M::iterator, bool> R; + M m; + R r; + for (int i = 0; i < 20; i += 2) + m.emplace (i, Moveable(i, (double) i)); + assert(m.size() == 10); + + Moveable mv1(3, 3.0); + for (int i=0; i < 20; i += 2) + { + r = m.try_emplace(i, std::move(mv1)); + assert(m.size() == 10); + assert(!r.second); // was not inserted + assert(!mv1.moved()); // was not moved from + assert(r.first->first == i); // key + } + + r = m.try_emplace(-1, std::move(mv1)); + assert(m.size() == 11); + assert(r.second); // was inserted + assert(mv1.moved()); // was moved from + assert(r.first->first == -1); // key + assert(r.first->second.get() == 3); // value + + Moveable mv2(5, 3.0); + r = m.try_emplace(5, std::move(mv2)); + assert(m.size() == 12); + assert(r.second); // was inserted + assert(mv2.moved()); // was moved from + assert(r.first->first == 5); // key + assert(r.first->second.get() == 5); // value + + Moveable mv3(-1, 3.0); + r = m.try_emplace(117, std::move(mv2)); + assert(m.size() == 13); + assert(r.second); // was inserted + assert(mv2.moved()); // was moved from + assert(r.first->first == 117); // key + assert(r.first->second.get() == -1); // value + } + + { // pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); + typedef std::unordered_map<Moveable, Moveable> M; + typedef std::pair<M::iterator, bool> R; + M m; + R r; + for (int i = 0; i < 20; i += 2) + m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1)); + assert(m.size() == 10); + + Moveable mvkey1(2, 2.0); + Moveable mv1(4, 4.0); + r = m.try_emplace(std::move(mvkey1), std::move(mv1)); + assert(m.size() == 10); + assert(!r.second); // was not inserted + assert(!mv1.moved()); // was not moved from + assert(!mvkey1.moved()); // was not moved from + assert(r.first->first == mvkey1); // key + + Moveable mvkey2(3, 3.0); + r = m.try_emplace(std::move(mvkey2), std::move(mv1)); + assert(m.size() == 11); + assert(r.second); // was inserted + assert(mv1.moved()); // was moved from + assert(mvkey2.moved()); // was moved from + assert(r.first->first.get() == 3); // key + assert(r.first->second.get() == 4); // value + } + + { // iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + typedef std::unordered_map<int, Moveable> M; + M m; + M::iterator r; + for (int i = 0; i < 20; i += 2) + m.try_emplace ( i, Moveable(i, (double) i)); + assert(m.size() == 10); + M::const_iterator it = m.find(2); + + Moveable mv1(3, 3.0); + for (int i=0; i < 20; i += 2) + { + r = m.try_emplace(it, i, std::move(mv1)); + assert(m.size() == 10); + assert(!mv1.moved()); // was not moved from + assert(r->first == i); // key + assert(r->second.get() == i); // value + } + + r = m.try_emplace(it, 3, std::move(mv1)); + assert(m.size() == 11); + assert(mv1.moved()); // was moved from + assert(r->first == 3); // key + assert(r->second.get() == 3); // value + } + + { // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + typedef std::unordered_map<Moveable, Moveable> M; + M m; + M::iterator r; + for ( int i = 0; i < 20; i += 2 ) + m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1)); + assert(m.size() == 10); + M::const_iterator it = std::next(m.cbegin()); + + Moveable mvkey1(2, 2.0); + Moveable mv1(4, 4.0); + r = m.try_emplace(it, std::move(mvkey1), std::move(mv1)); + assert(m.size() == 10); + assert(!mv1.moved()); // was not moved from + assert(!mvkey1.moved()); // was not moved from + assert(r->first == mvkey1); // key + + Moveable mvkey2(3, 3.0); + r = m.try_emplace(it, std::move(mvkey2), std::move(mv1)); + assert(m.size() == 11); + assert(mv1.moved()); // was moved from + assert(mvkey2.moved()); // was moved from + assert(r->first.get() == 3); // key + assert(r->second.get() == 4); // value + } + +#endif // _LIBCPP_HAS_NO_VARIADICS +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} |