1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
#include <utility>
#include <tuple>
#include <type_traits>
namespace dsa
{
namespace detail
{
struct empty {};
using tuple_type = std::tuple<int,empty> ;
constexpr bool use_tuple = sizeof(tuple_type) == sizeof(int) ;
struct integer : empty { int m ; } ;
constexpr bool use_home_grown_ebo = !use_tuple &&
( sizeof(integer) == sizeof(int) ) ;
}
template < typename FIRST, typename SECOND, typename = void >
struct pair : std::pair<FIRST,SECOND>
{
using base = std::pair<FIRST,SECOND> ;
using first_type = typename base::first_type ;
using second_type = typename base::second_type ;
using base::base ;
using base::operator= ;
using base::swap ;
first_type& first() { return base::first ; }
const first_type& first() const { return base::first ; }
second_type& second() { return base::second ; }
const second_type& second() const { return base::second ; }
};
template < typename FIRST, typename SECOND >
struct pair< FIRST, SECOND,
std::enable_if< detail::use_tuple >::type > : std::tuple<FIRST,SECOND>
{
using base = std::tuple<FIRST,SECOND> ;
using first_type = typename std::pair<FIRST,SECOND>::first_type ;
using second_type = typename std::pair<FIRST,SECOND>::second_type ;
using base::base ;
using base::operator= ;
using base::swap ;
first_type& first() { return std::get<0>(*this) ; }
const first_type& first() const { return std::get<0>(*this) ; }
second_type& second() { return std::get<1>(*this) ; }
const second_type& second() const { return std::get<1>(*this) ; }
};
template < typename FIRST, typename SECOND >
struct pair< FIRST, SECOND,
typename std::enable_if< detail::use_home_grown_ebo &&
std::is_empty<SECOND>::value >::type >
: SECOND
{
FIRST m ;
// typedefs
// constructors, templated constructors
// operator=, templated operator=s
// operator pair<A,B>, templated operator pair<A,B>
// first(), second()
// swap
// whatever else
};
}
|