////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2013. // // 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_CONTAINER_DETAIL_PAIR_HPP #define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP #if defined(_MSC_VER) # pragma once #endif #include #include #include #include #include #include #include //std::pair #include //std::swap #include #ifndef BOOST_CONTAINER_PERFECT_FORWARDING #include #endif namespace boost { namespace container { namespace container_detail { template struct pair; template struct is_pair { static const bool value = false; }; template struct is_pair< pair > { static const bool value = true; }; template struct is_pair< std::pair > { static const bool value = true; }; struct pair_nat; struct piecewise_construct_t { }; static const piecewise_construct_t piecewise_construct = piecewise_construct_t(); /* template struct pair { template pair(pair&& p); template pair(piecewise_construct_t, tuple first_args, tuple second_args); template pair& operator=(const pair& p); pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable::value && is_nothrow_move_assignable::value); template pair& operator=(pair&& p); void swap(pair& p) noexcept(noexcept(swap(first, p.first)) && noexcept(swap(second, p.second))); }; template bool operator==(const pair&, const pair&); template bool operator!=(const pair&, const pair&); template bool operator< (const pair&, const pair&); template bool operator> (const pair&, const pair&); template bool operator>=(const pair&, const pair&); template bool operator<=(const pair&, const pair&); */ template struct pair { private: BOOST_COPYABLE_AND_MOVABLE(pair) public: typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; //Default constructor pair() : first(), second() {} //pair copy assignment pair(const pair& x) : first(x.first), second(x.second) {} //pair move constructor pair(BOOST_RV_REF(pair) p) : first(::boost::move(p.first)), second(::boost::move(p.second)) {} template pair(const pair &p) : first(p.first), second(p.second) {} template pair(BOOST_RV_REF_BEG pair BOOST_RV_REF_END p) : first(::boost::move(p.first)), second(::boost::move(p.second)) {} //pair from two values pair(const T1 &t1, const T2 &t2) : first(t1) , second(t2) {} template pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v) : first(::boost::forward(u)) , second(::boost::forward(v)) {} //And now compatibility with std::pair pair(const std::pair& x) : first(x.first), second(x.second) {} template pair(const std::pair& p) : first(p.first), second(p.second) {} pair(BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END p) : first(::boost::move(p.first)), second(::boost::move(p.second)) {} template pair(BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END p) : first(::boost::move(p.first)), second(::boost::move(p.second)) {} //piecewise_construct missing //template pair(pair&& p); //template // pair(piecewise_construct_t, tuple first_args, // tuple second_args); /* //Variadic versions template pair(BOOST_CONTAINER_PP_PARAM(U, u), typename container_detail::disable_if < container_detail::is_pair< typename container_detail::remove_ref_const::type >, pair_nat>::type* = 0) : first(::boost::forward(u)) , second() {} #ifdef BOOST_CONTAINER_PERFECT_FORWARDING template pair(U &&u, V &&v) : first(::boost::forward(u)) , second(::boost::forward(v), ::boost::forward(args)...) {} #else #define BOOST_PP_LOCAL_MACRO(n) \ template \ pair(BOOST_CONTAINER_PP_PARAM(U, u) \ ,BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ : first(::boost::forward(u)) \ , second(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \ {} \ //! #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) #include BOOST_PP_LOCAL_ITERATE() #endif */ //pair copy assignment pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p) { first = p.first; second = p.second; return *this; } //pair move assignment pair& operator=(BOOST_RV_REF(pair) p) { first = ::boost::move(p.first); second = ::boost::move(p.second); return *this; } template typename ::boost::container::container_detail::enable_if_c < !(::boost::container::container_detail::is_same::value && ::boost::container::container_detail::is_same::value) , pair &>::type operator=(const pair&p) { first = p.first; second = p.second; return *this; } template typename ::boost::container::container_detail::enable_if_c < !(::boost::container::container_detail::is_same::value && ::boost::container::container_detail::is_same::value) , pair &>::type operator=(BOOST_RV_REF_BEG pair BOOST_RV_REF_END p) { first = ::boost::move(p.first); second = ::boost::move(p.second); return *this; } //std::pair copy assignment pair& operator=(const std::pair &p) { first = p.first; second = p.second; return *this; } template pair& operator=(const std::pair &p) { first = ::boost::move(p.first); second = ::boost::move(p.second); return *this; } //std::pair move assignment pair& operator=(BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END p) { first = ::boost::move(p.first); second = ::boost::move(p.second); return *this; } template pair& operator=(BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END p) { first = ::boost::move(p.first); second = ::boost::move(p.second); return *this; } //swap void swap(pair& p) { using std::swap; swap(this->first, p.first); swap(this->second, p.second); } }; template inline bool operator==(const pair& x, const pair& y) { return static_cast(x.first == y.first && x.second == y.second); } template inline bool operator< (const pair& x, const pair& y) { return static_cast(x.first < y.first || (!(y.first < x.first) && x.second < y.second)); } template inline bool operator!=(const pair& x, const pair& y) { return static_cast(!(x == y)); } template inline bool operator> (const pair& x, const pair& y) { return y < x; } template inline bool operator>=(const pair& x, const pair& y) { return static_cast(!(x < y)); } template inline bool operator<=(const pair& x, const pair& y) { return static_cast(!(y < x)); } template inline pair make_pair(T1 x, T2 y) { return pair(x, y); } template inline void swap(pair& x, pair& y) { swap(x.first, y.first); swap(x.second, y.second); } } //namespace container_detail { } //namespace container { //Without this specialization recursive flat_(multi)map instantiation fails //because is_enum needs to instantiate the recursive pair, leading to a compilation error). //This breaks the cycle clearly stating that pair is not an enum avoiding any instantiation. template struct is_enum; template struct is_enum< ::boost::container::container_detail::pair > { static const bool value = false; }; template struct is_class; //This specialization is needed to avoid instantiation of pair in //is_class, and allow recursive maps. template struct is_class< ::boost::container::container_detail::pair > { static const bool value = true; }; #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES template struct has_move_emulation_enabled< ::boost::container::container_detail::pair > { static const bool value = true; }; #endif namespace move_detail{ template struct is_class_or_union; template struct is_class_or_union< ::boost::container::container_detail::pair > //This specialization is needed to avoid instantiation of pair in //is_class, and allow recursive maps. { static const bool value = true; }; } //namespace move_detail{ } //namespace boost { #include #endif //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP