////////////////////////////////////////////////////////////////////////////// | |
// | |
// (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 |