boost/interprocess/containers/container/detail/pair.hpp
////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2009. // // 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_CONTAINERS_CONTAINERS_DETAIL_PAIR_HPP #define BOOST_CONTAINERS_CONTAINERS_DETAIL_PAIR_HPP #if (defined _MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif #include "config_begin.hpp" #include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP #include INCLUDE_BOOST_CONTAINER_DETAIL_MPL_HPP #include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP #include <utility> //std::pair #include INCLUDE_BOOST_CONTAINER_MOVE_HPP #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING #include INCLUDE_BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP #endif namespace boost { namespace container { namespace containers_detail { template <class T1, class T2> struct pair { private: BOOST_MOVE_MACRO_COPYABLE_AND_MOVABLE(pair) public: typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; //std::pair compatibility template <class D, class S> pair(const std::pair<D, S>& p) : first(p.first), second(p.second) {} //To resolve ambiguity with the variadic constructor of 1 argument //and the previous constructor pair(std::pair<T1, T2>& x) : first(x.first), second(x.second) {} template <class D, class S> pair(BOOST_MOVE_MACRO_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p) : first(BOOST_CONTAINER_MOVE_NAMESPACE::move(p.first)), second(BOOST_CONTAINER_MOVE_NAMESPACE::move(p.second)) {} pair() : first(), second() {} pair(const pair<T1, T2>& x) : first(x.first), second(x.second) {} //To resolve ambiguity with the variadic constructor of 1 argument //and the copy constructor pair(pair<T1, T2>& x) : first(x.first), second(x.second) {} pair(BOOST_MOVE_MACRO_RV_REF(pair) p) : first(BOOST_CONTAINER_MOVE_NAMESPACE::move(p.first)), second(BOOST_CONTAINER_MOVE_NAMESPACE::move(p.second)) {} template <class D, class S> pair(BOOST_MOVE_MACRO_RV_REF_2_TEMPL_ARGS(pair, D, S) p) : first(BOOST_CONTAINER_MOVE_NAMESPACE::move(p.first)), second(BOOST_CONTAINER_MOVE_NAMESPACE::move(p.second)) {} #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING template<class U, class ...Args> pair(U &&u, Args &&... args) : first(BOOST_CONTAINER_MOVE_NAMESPACE::forward<U>(u)) , second(BOOST_CONTAINER_MOVE_NAMESPACE::forward<Args>(args)...) {} #else template<class U> pair( BOOST_CONTAINERS_PARAM(U, u) #ifdef BOOST_NO_RVALUE_REFERENCES , typename containers_detail::disable_if < containers_detail::is_same<U, ::BOOST_CONTAINER_MOVE_NAMESPACE::rv<pair> > >::type* = 0 #endif ) : first(BOOST_CONTAINER_MOVE_NAMESPACE::forward<U>(const_cast<U&>(u))) {} #define BOOST_PP_LOCAL_MACRO(n) \ template<class U, BOOST_PP_ENUM_PARAMS(n, class P)> \ pair(BOOST_CONTAINERS_PARAM(U, u) \ ,BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \ : first(BOOST_CONTAINER_MOVE_NAMESPACE::forward<U>(const_cast<U&>(u))) \ , second(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \ {} \ //! #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS) #include BOOST_PP_LOCAL_ITERATE() #endif pair& operator=(BOOST_MOVE_MACRO_COPY_ASSIGN_REF(pair) p) { first = p.first; second = p.second; return *this; } pair& operator=(BOOST_MOVE_MACRO_RV_REF(pair) p) { first = BOOST_CONTAINER_MOVE_NAMESPACE::move(p.first); second = BOOST_CONTAINER_MOVE_NAMESPACE::move(p.second); return *this; } pair& operator=(BOOST_MOVE_MACRO_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p) { first = BOOST_CONTAINER_MOVE_NAMESPACE::move(p.first); second = BOOST_CONTAINER_MOVE_NAMESPACE::move(p.second); return *this; } template <class D, class S> pair& operator=(BOOST_MOVE_MACRO_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p) { first = BOOST_CONTAINER_MOVE_NAMESPACE::move(p.first); second = BOOST_CONTAINER_MOVE_NAMESPACE::move(p.second); return *this; } void swap(pair& p) { std::swap(*this, p); } }; template <class T1, class T2> inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y) { return static_cast<bool>(x.first == y.first && x.second == y.second); } template <class T1, class T2> inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y) { return static_cast<bool>(x.first < y.first || (!(y.first < x.first) && x.second < y.second)); } template <class T1, class T2> inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y) { return static_cast<bool>(!(x == y)); } template <class T1, class T2> inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y) { return y < x; } template <class T1, class T2> inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y) { return static_cast<bool>(!(x < y)); } template <class T1, class T2> inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y) { return static_cast<bool>(!(y < x)); } template <class T1, class T2> inline pair<T1, T2> make_pair(T1 x, T2 y) { return pair<T1, T2>(x, y); } template <class T1, class T2> inline void swap(pair<T1, T2>& x, pair<T1, T2>& y) { swap(x.first, y.first); swap(x.second, y.second); } } //namespace containers_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<class T> struct is_enum; template<class T, class U> struct is_enum< ::boost::container::containers_detail::pair<T, U> > { static const bool value = false; }; } //namespace boost { #include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP #endif //#ifndef BOOST_CONTAINERS_DETAIL_PAIR_HPP