123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686 |
- //////////////////////////////////////////////////////////////////////////////
- //
- // (C) Copyright Ion Gaztanaga 2008. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // See http://www.boost.org/libs/container for documentation.
- //
- //////////////////////////////////////////////////////////////////////////////
- #ifndef BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP
- #define BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP
- #include <iostream>
- #include <typeinfo>
- #include <boost/container/detail/config_begin.hpp>
- #include <boost/container/detail/workaround.hpp>
- #include <boost/container/detail/mpl.hpp>
- #include <boost/move/utility_core.hpp>
- #include <boost/container/detail/type_traits.hpp>
- namespace boost{
- namespace container {
- namespace test{
- class EmplaceInt
- {
- BOOST_MOVABLE_BUT_NOT_COPYABLE(EmplaceInt)
- public:
- EmplaceInt(int a = 0, int b = 0, int c = 0, int d = 0, int e = 0)
- : a_(a), b_(b), c_(c), d_(d), e_(e)
- {}
- EmplaceInt(BOOST_RV_REF(EmplaceInt) o)
- : a_(o.a_), b_(o.b_), c_(o.c_), d_(o.d_), e_(o.e_)
- {}
- EmplaceInt& operator=(BOOST_RV_REF(EmplaceInt) o)
- {
- this->a_ = o.a_;
- this->b_ = o.b_;
- this->c_ = o.c_;
- this->d_ = o.d_;
- this->e_ = o.e_;
- return *this;
- }
- friend bool operator==(const EmplaceInt &l, const EmplaceInt &r)
- {
- return l.a_ == r.a_ &&
- l.b_ == r.b_ &&
- l.c_ == r.c_ &&
- l.d_ == r.d_ &&
- l.e_ == r.e_;
- }
- friend bool operator<(const EmplaceInt &l, const EmplaceInt &r)
- { return l.sum() < r.sum(); }
- friend bool operator>(const EmplaceInt &l, const EmplaceInt &r)
- { return l.sum() > r.sum(); }
- friend bool operator!=(const EmplaceInt &l, const EmplaceInt &r)
- { return !(l == r); }
- friend std::size_t hash_value(const EmplaceInt &v)
- { return std::size_t(v.a_); }
- friend std::ostream &operator <<(std::ostream &os, const EmplaceInt &v)
- {
- os << "EmplaceInt: " << v.a_ << ' ' << v.b_ << ' ' << v.c_ << ' ' << v.d_ << ' ' << v.e_;
- return os;
- }
- ~EmplaceInt()
- { a_ = b_ = c_ = d_ = e_ = 0; }
- //private:
- int sum() const
- { return this->a_ + this->b_ + this->c_ + this->d_ + this->e_; }
- int a_, b_, c_, d_, e_;
- int padding[6];
- };
- } //namespace test {
- namespace test {
- enum EmplaceOptions{
- EMPLACE_BACK = 1 << 0,
- EMPLACE_FRONT = 1 << 1,
- EMPLACE_BEFORE = 1 << 2,
- EMPLACE_AFTER = 1 << 3,
- EMPLACE_ASSOC = 1 << 4,
- EMPLACE_HINT = 1 << 5,
- EMPLACE_ASSOC_PAIR = 1 << 6,
- EMPLACE_HINT_PAIR = 1 << 7
- };
- template<class Container>
- bool test_expected_container(const Container &ec, const EmplaceInt *Expected, unsigned int only_first_n, unsigned int cont_offset = 0)
- {
- typedef typename Container::const_iterator const_iterator;
- const_iterator itb(ec.begin()), ite(ec.end());
- unsigned int cur = 0;
- if(cont_offset > ec.size()){
- return false;
- }
- if(only_first_n > (ec.size() - cont_offset)){
- return false;
- }
- while(cont_offset--){
- ++itb;
- }
- for(; itb != ite && only_first_n--; ++itb, ++cur){
- const EmplaceInt & cr = *itb;
- if(cr != Expected[cur]){
- return false;
- }
- }
- return true;
- }
- template<class Container>
- bool test_expected_container(const Container &ec, const std::pair<EmplaceInt, EmplaceInt> *Expected, unsigned int only_first_n)
- {
- typedef typename Container::const_iterator const_iterator;
- const_iterator itb(ec.begin()), ite(ec.end());
- unsigned int cur = 0;
- if(only_first_n > ec.size()){
- return false;
- }
- for(; itb != ite && only_first_n--; ++itb, ++cur){
- if(itb->first != Expected[cur].first){
- std::cout << "Error in first: " << itb->first << ' ' << Expected[cur].first << std::endl;
- return false;
- }
- else if(itb->second != Expected[cur].second){
- std::cout << "Error in second: " << itb->second << ' ' << Expected[cur].second << std::endl;
- return false;
- }
- }
- return true;
- }
- typedef std::pair<EmplaceInt, EmplaceInt> EmplaceIntPair;
- static boost::container::dtl::aligned_storage<sizeof(EmplaceIntPair)*10>::type pair_storage;
- static EmplaceIntPair* initialize_emplace_int_pair()
- {
- EmplaceIntPair* ret = reinterpret_cast<EmplaceIntPair*>(&pair_storage);
- for(unsigned int i = 0; i != 10; ++i){
- new(&ret->first)EmplaceInt();
- new(&ret->second)EmplaceInt();
- }
- return ret;
- }
- static EmplaceIntPair * expected_pair = initialize_emplace_int_pair();
- template<class Container>
- bool test_emplace_back(dtl::true_)
- {
- std::cout << "Starting test_emplace_back." << std::endl << " Class: "
- << typeid(Container).name() << std::endl;
- static EmplaceInt expected [10];
- {
- new(&expected [0]) EmplaceInt();
- new(&expected [1]) EmplaceInt(1);
- new(&expected [2]) EmplaceInt(1, 2);
- new(&expected [3]) EmplaceInt(1, 2, 3);
- new(&expected [4]) EmplaceInt(1, 2, 3, 4);
- new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
- Container c;
- typedef typename Container::reference reference;
- {
- reference r = c.emplace_back();
- if(&r != &c.back() && !test_expected_container(c, &expected[0], 1)){
- return false;
- }
- }
- {
- reference r = c.emplace_back(1);
- if(&r != &c.back() && !test_expected_container(c, &expected[0], 2)){
- return false;
- }
- }
- c.emplace_back(1, 2);
- if(!test_expected_container(c, &expected[0], 3)){
- return false;
- }
- c.emplace_back(1, 2, 3);
- if(!test_expected_container(c, &expected[0], 4)){
- return false;
- }
- c.emplace_back(1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0], 5)){
- return false;
- }
- c.emplace_back(1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0], 6)){
- return false;
- }
- }
- std::cout << "...OK" << std::endl;
- return true;
- }
- template<class Container>
- bool test_emplace_back(dtl::false_)
- { return true; }
- template<class Container>
- bool test_emplace_front(dtl::true_)
- {
- std::cout << "Starting test_emplace_front." << std::endl << " Class: "
- << typeid(Container).name() << std::endl;
- static EmplaceInt expected [10];
- {
- new(&expected [0]) EmplaceInt(1, 2, 3, 4, 5);
- new(&expected [1]) EmplaceInt(1, 2, 3, 4);
- new(&expected [2]) EmplaceInt(1, 2, 3);
- new(&expected [3]) EmplaceInt(1, 2);
- new(&expected [4]) EmplaceInt(1);
- new(&expected [5]) EmplaceInt();
- Container c;
- typedef typename Container::reference reference;
- {
- reference r = c.emplace_front();
- if(&r != &c.front() && !test_expected_container(c, &expected[0] + 5, 1)){
- return false;
- }
- }
- {
- reference r = c.emplace_front(1);
- if(&r != &c.front() && !test_expected_container(c, &expected[0] + 4, 2)){
- return false;
- }
- }
- c.emplace_front(1, 2);
- if(!test_expected_container(c, &expected[0] + 3, 3)){
- return false;
- }
- c.emplace_front(1, 2, 3);
- if(!test_expected_container(c, &expected[0] + 2, 4)){
- return false;
- }
- c.emplace_front(1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0] + 1, 5)){
- return false;
- }
- c.emplace_front(1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0] + 0, 6)){
- return false;
- }
- }
- std::cout << "...OK" << std::endl;
- return true;
- }
- template<class Container>
- bool test_emplace_front(dtl::false_)
- { return true; }
- template<class Container>
- bool test_emplace_before(dtl::true_)
- {
- std::cout << "Starting test_emplace_before." << std::endl << " Class: "
- << typeid(Container).name() << std::endl;
- static EmplaceInt expected [10];
- {
- new(&expected [0]) EmplaceInt();
- new(&expected [1]) EmplaceInt(1);
- new(&expected [2]) EmplaceInt();
- Container c;
- c.emplace(c.cend(), 1);
- c.emplace(c.cbegin());
- if(!test_expected_container(c, &expected[0], 2)){
- return false;
- }
- c.emplace(c.cend());
- if(!test_expected_container(c, &expected[0], 3)){
- return false;
- }
- }
- {
- new(&expected [0]) EmplaceInt();
- new(&expected [1]) EmplaceInt(1);
- new(&expected [2]) EmplaceInt(1, 2);
- new(&expected [3]) EmplaceInt(1, 2, 3);
- new(&expected [4]) EmplaceInt(1, 2, 3, 4);
- new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
- //emplace_front-like
- Container c;
- c.emplace(c.cbegin(), 1, 2, 3, 4, 5);
- c.emplace(c.cbegin(), 1, 2, 3, 4);
- c.emplace(c.cbegin(), 1, 2, 3);
- c.emplace(c.cbegin(), 1, 2);
- c.emplace(c.cbegin(), 1);
- c.emplace(c.cbegin());
- if(!test_expected_container(c, &expected[0], 6)){
- return false;
- }
- c.clear();
- //emplace_back-like
- typename Container::const_iterator i = c.emplace(c.cend());
- if(!test_expected_container(c, &expected[0], 1)){
- return false;
- }
- i = c.emplace(++i, 1);
- if(!test_expected_container(c, &expected[0], 2)){
- return false;
- }
- i = c.emplace(++i, 1, 2);
- if(!test_expected_container(c, &expected[0], 3)){
- return false;
- }
- i = c.emplace(++i, 1, 2, 3);
- if(!test_expected_container(c, &expected[0], 4)){
- return false;
- }
- i = c.emplace(++i, 1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0], 5)){
- return false;
- }
- i = c.emplace(++i, 1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0], 6)){
- return false;
- }
- c.clear();
- //emplace in the middle
- c.emplace(c.cbegin());
- if(!test_expected_container(c, &expected[0], 1)){
- return false;
- }
- i = c.emplace(c.cend(), 1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0], 1)){
- return false;
- }
- if(!test_expected_container(c, &expected[5], 1, 1)){
- return false;
- }
- i = c.emplace(i, 1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0], 1)){
- return false;
- }
- if(!test_expected_container(c, &expected[4], 2, 1)){
- return false;
- }
- i = c.emplace(i, 1, 2, 3);
- if(!test_expected_container(c, &expected[0], 1)){
- return false;
- }
- if(!test_expected_container(c, &expected[3], 3, 1)){
- return false;
- }
- i = c.emplace(i, 1, 2);
- if(!test_expected_container(c, &expected[0], 1)){
- return false;
- }
- if(!test_expected_container(c, &expected[2], 4, 1)){
- return false;
- }
- i = c.emplace(i, 1);
- if(!test_expected_container(c, &expected[0], 6)){
- return false;
- }
- std::cout << "...OK" << std::endl;
- }
- return true;
- }
- template<class Container>
- bool test_emplace_before(dtl::false_)
- { return true; }
- template<class Container>
- bool test_emplace_after(dtl::true_)
- {
- std::cout << "Starting test_emplace_after." << std::endl << " Class: "
- << typeid(Container).name() << std::endl;
- static EmplaceInt expected [10];
- {
- new(&expected [0]) EmplaceInt();
- new(&expected [1]) EmplaceInt(1);
- new(&expected [2]) EmplaceInt();
- Container c;
- typename Container::const_iterator i = c.emplace_after(c.cbefore_begin(), 1);
- c.emplace_after(c.cbefore_begin());
- if(!test_expected_container(c, &expected[0], 2)){
- return false;
- }
- c.emplace_after(i);
- if(!test_expected_container(c, &expected[0], 3)){
- return false;
- }
- }
- {
- new(&expected [0]) EmplaceInt();
- new(&expected [1]) EmplaceInt(1);
- new(&expected [2]) EmplaceInt(1, 2);
- new(&expected [3]) EmplaceInt(1, 2, 3);
- new(&expected [4]) EmplaceInt(1, 2, 3, 4);
- new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
- //emplace_front-like
- Container c;
- c.emplace_after(c.cbefore_begin(), 1, 2, 3, 4, 5);
- c.emplace_after(c.cbefore_begin(), 1, 2, 3, 4);
- c.emplace_after(c.cbefore_begin(), 1, 2, 3);
- c.emplace_after(c.cbefore_begin(), 1, 2);
- c.emplace_after(c.cbefore_begin(), 1);
- c.emplace_after(c.cbefore_begin());
- if(!test_expected_container(c, &expected[0], 6)){
- return false;
- }
- c.clear();
- //emplace_back-like
- typename Container::const_iterator i = c.emplace_after(c.cbefore_begin());
- if(!test_expected_container(c, &expected[0], 1)){
- return false;
- }
- i = c.emplace_after(i, 1);
- if(!test_expected_container(c, &expected[0], 2)){
- return false;
- }
- i = c.emplace_after(i, 1, 2);
- if(!test_expected_container(c, &expected[0], 3)){
- return false;
- }
- i = c.emplace_after(i, 1, 2, 3);
- if(!test_expected_container(c, &expected[0], 4)){
- return false;
- }
- i = c.emplace_after(i, 1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0], 5)){
- return false;
- }
- i = c.emplace_after(i, 1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0], 6)){
- return false;
- }
- c.clear();
- //emplace_after in the middle
- i = c.emplace_after(c.cbefore_begin());
- c.emplace_after(i, 1, 2, 3, 4, 5);
- c.emplace_after(i, 1, 2, 3, 4);
- c.emplace_after(i, 1, 2, 3);
- c.emplace_after(i, 1, 2);
- c.emplace_after(i, 1);
- if(!test_expected_container(c, &expected[0], 6)){
- return false;
- }
- std::cout << "...OK" << std::endl;
- }
- return true;
- }
- template<class Container>
- bool test_emplace_after(dtl::false_)
- { return true; }
- template<class Container>
- bool test_emplace_assoc(dtl::true_)
- {
- std::cout << "Starting test_emplace_assoc." << std::endl << " Class: "
- << typeid(Container).name() << std::endl;
- static EmplaceInt expected [10];
- new(&expected [0]) EmplaceInt();
- new(&expected [1]) EmplaceInt(1);
- new(&expected [2]) EmplaceInt(1, 2);
- new(&expected [3]) EmplaceInt(1, 2, 3);
- new(&expected [4]) EmplaceInt(1, 2, 3, 4);
- new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
- {
- Container c;
- c.emplace();
- if(!test_expected_container(c, &expected[0], 1)){
- return false;
- }
- c.emplace(1);
- if(!test_expected_container(c, &expected[0], 2)){
- return false;
- }
- c.emplace(1, 2);
- if(!test_expected_container(c, &expected[0], 3)){
- return false;
- }
- c.emplace(1, 2, 3);
- if(!test_expected_container(c, &expected[0], 4)){
- return false;
- }
- c.emplace(1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0], 5)){
- return false;
- }
- c.emplace(1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0], 6)){
- return false;
- }
- std::cout << "...OK" << std::endl;
- }
- return true;
- }
- template<class Container>
- bool test_emplace_assoc(dtl::false_)
- { return true; }
- template<class Container>
- bool test_emplace_hint(dtl::true_)
- {
- std::cout << "Starting test_emplace_hint." << std::endl << " Class: "
- << typeid(Container).name() << std::endl;
- static EmplaceInt expected [10];
- new(&expected [0]) EmplaceInt();
- new(&expected [1]) EmplaceInt(1);
- new(&expected [2]) EmplaceInt(1, 2);
- new(&expected [3]) EmplaceInt(1, 2, 3);
- new(&expected [4]) EmplaceInt(1, 2, 3, 4);
- new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
- {
- Container c;
- typename Container::const_iterator it;
- it = c.emplace_hint(c.begin());
- if(!test_expected_container(c, &expected[0], 1)){
- return false;
- }
- it = c.emplace_hint(it, 1);
- if(!test_expected_container(c, &expected[0], 2)){
- return false;
- }
- it = c.emplace_hint(it, 1, 2);
- if(!test_expected_container(c, &expected[0], 3)){
- return false;
- }
- it = c.emplace_hint(it, 1, 2, 3);
- if(!test_expected_container(c, &expected[0], 4)){
- return false;
- }
- it = c.emplace_hint(it, 1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0], 5)){
- return false;
- }
- it = c.emplace_hint(it, 1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0], 6)){
- return false;
- }
- std::cout << "...OK" << std::endl;
- }
- return true;
- }
- template<class Container>
- bool test_emplace_hint(dtl::false_)
- { return true; }
- template<class Container>
- bool test_emplace_assoc_pair(dtl::true_)
- {
- std::cout << "Starting test_emplace_assoc_pair." << std::endl << " Class: "
- << typeid(Container).name() << std::endl;
- new(&expected_pair[0].first) EmplaceInt();
- new(&expected_pair[0].second) EmplaceInt();
- new(&expected_pair[1].first) EmplaceInt(1);
- new(&expected_pair[1].second) EmplaceInt(1);
- new(&expected_pair[2].first) EmplaceInt(2);
- new(&expected_pair[2].second) EmplaceInt(2);
- {
- Container c;
- c.emplace();
- if(!test_expected_container(c, &expected_pair[0], 1)){
- std::cout << "Error after c.emplace();\n";
- return false;
- }
- c.emplace(1, 1);
- if(!test_expected_container(c, &expected_pair[0], 2)){
- std::cout << "Error after c.emplace(1);\n";
- return false;
- }
- c.emplace(2, 2);
- if(!test_expected_container(c, &expected_pair[0], 3)){
- std::cout << "Error after c.emplace(2, 2);\n";
- return false;
- }
- std::cout << "...OK" << std::endl;
- }
- return true;
- }
- template<class Container>
- bool test_emplace_assoc_pair(dtl::false_)
- { return true; }
- template<class Container>
- bool test_emplace_hint_pair(dtl::true_)
- {
- std::cout << "Starting test_emplace_hint_pair." << std::endl << " Class: "
- << typeid(Container).name() << std::endl;
- new(&expected_pair[0].first) EmplaceInt();
- new(&expected_pair[0].second) EmplaceInt();
- new(&expected_pair[1].first) EmplaceInt(1);
- new(&expected_pair[1].second) EmplaceInt(1);
- new(&expected_pair[2].first) EmplaceInt(2);
- new(&expected_pair[2].second) EmplaceInt(2);
- {
- Container c;
- typename Container::const_iterator it;
- it = c.emplace_hint(c.begin());
- if(!test_expected_container(c, &expected_pair[0], 1)){
- std::cout << "Error after c.emplace(1);\n";
- return false;
- }
- it = c.emplace_hint(it, 1, 1);
- if(!test_expected_container(c, &expected_pair[0], 2)){
- std::cout << "Error after c.emplace(it, 1);\n";
- return false;
- }
- it = c.emplace_hint(it, 2, 2);
- if(!test_expected_container(c, &expected_pair[0], 3)){
- std::cout << "Error after c.emplace(it, 2, 2);\n";
- return false;
- }
- std::cout << "...OK" << std::endl;
- }
- return true;
- }
- template<class Container>
- bool test_emplace_hint_pair(dtl::false_)
- { return true; }
- template <EmplaceOptions O, EmplaceOptions Mask>
- struct emplace_active
- {
- static const bool value = (0 != (O & Mask));
- typedef dtl::bool_<value> type;
- operator type() const{ return type(); }
- };
- template<class Container, EmplaceOptions O>
- bool test_emplace()
- {
- if(!test_emplace_back<Container>(emplace_active<O, EMPLACE_BACK>())){
- return false;
- }
- if(!test_emplace_front<Container>(emplace_active<O, EMPLACE_FRONT>())){
- return false;
- }
- if(!test_emplace_before<Container>(emplace_active<O, EMPLACE_BEFORE>())){
- return false;
- }
- if(!test_emplace_after<Container>(emplace_active<O, EMPLACE_AFTER>())){
- return false;
- }
- if(!test_emplace_assoc<Container>(emplace_active<O, EMPLACE_ASSOC>())){
- return false;
- }
- if(!test_emplace_hint<Container>(emplace_active<O, EMPLACE_HINT>())){
- return false;
- }
- if(!test_emplace_assoc_pair<Container>(emplace_active<O, EMPLACE_ASSOC_PAIR>())){
- return false;
- }
- if(!test_emplace_hint_pair<Container>(emplace_active<O, EMPLACE_HINT_PAIR>())){
- return false;
- }
- return true;
- }
- } //namespace test{
- } //namespace container {
- } //namespace boost{
- #include <boost/container/detail/config_end.hpp>
- #endif //#ifndef BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP
|