blob: c72c34e9921f798a1b8a24c7978b8347a1910d1e [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001// common_type.hpp ---------------------------------------------------------//
2
3// Copyright 2008 Howard Hinnant
4// Copyright 2008 Beman Dawes
5
6// Distributed under the Boost Software License, Version 1.0.
7// See http://www.boost.org/LICENSE_1_0.txt
8
Jeff Thompson3d613fd2013-10-15 15:39:04 -07009#ifndef NDNBOOST_TYPE_TRAITS_COMMON_TYPE_HPP
10#define NDNBOOST_TYPE_TRAITS_COMMON_TYPE_HPP
Jeff Thompsona28eed82013-08-22 16:21:10 -070011
12#include <ndnboost/config.hpp>
13
Jeff Thompson3d613fd2013-10-15 15:39:04 -070014#if defined(__SUNPRO_CC) && !defined(NDNBOOST_COMMON_TYPE_DONT_USE_TYPEOF)
15# define NDNBOOST_COMMON_TYPE_DONT_USE_TYPEOF
Jeff Thompsona28eed82013-08-22 16:21:10 -070016#endif
Jeff Thompson3d613fd2013-10-15 15:39:04 -070017#if defined(__IBMCPP__) && !defined(NDNBOOST_COMMON_TYPE_DONT_USE_TYPEOF)
18# define NDNBOOST_COMMON_TYPE_DONT_USE_TYPEOF
Jeff Thompsona28eed82013-08-22 16:21:10 -070019#endif
20
21//----------------------------------------------------------------------------//
Jeff Thompson3d613fd2013-10-15 15:39:04 -070022#if defined(NDNBOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(NDNBOOST_COMMON_TYPE_ARITY)
23#define NDNBOOST_COMMON_TYPE_ARITY 3
Jeff Thompsona28eed82013-08-22 16:21:10 -070024#endif
25
26//----------------------------------------------------------------------------//
Jeff Thompson3d613fd2013-10-15 15:39:04 -070027#if defined(NDNBOOST_NO_CXX11_DECLTYPE) && !defined(NDNBOOST_COMMON_TYPE_DONT_USE_TYPEOF)
Jeff Thompsona28eed82013-08-22 16:21:10 -070028#include <ndnboost/typeof/typeof.hpp> // boost wonders never cease!
29#endif
30
31//----------------------------------------------------------------------------//
Jeff Thompson3d613fd2013-10-15 15:39:04 -070032#ifndef NDNBOOST_NO_CXX11_STATIC_ASSERT
33#define NDNBOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) static_assert(CND,MSG)
34#elif defined(NDNBOOST_COMMON_TYPE_USES_MPL_ASSERT)
Jeff Thompsona28eed82013-08-22 16:21:10 -070035#include <ndnboost/mpl/assert.hpp>
36#include <ndnboost/mpl/bool.hpp>
Jeff Thompson3d613fd2013-10-15 15:39:04 -070037#define NDNBOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) \
38 NDNBOOST_MPL_ASSERT_MSG(ndnboost::mpl::bool_< (CND) >::type::value, MSG, TYPES)
Jeff Thompsona28eed82013-08-22 16:21:10 -070039#else
40#include <ndnboost/static_assert.hpp>
Jeff Thompson3d613fd2013-10-15 15:39:04 -070041#define NDNBOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) NDNBOOST_STATIC_ASSERT(CND)
Jeff Thompsona28eed82013-08-22 16:21:10 -070042#endif
43
Jeff Thompson3d613fd2013-10-15 15:39:04 -070044#if !defined(NDNBOOST_NO_CXX11_STATIC_ASSERT) || !defined(NDNBOOST_COMMON_TYPE_USES_MPL_ASSERT)
45#define NDNBOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE "must be complete type"
Jeff Thompsona28eed82013-08-22 16:21:10 -070046#endif
47
Jeff Thompson3d613fd2013-10-15 15:39:04 -070048#if defined(NDNBOOST_NO_CXX11_DECLTYPE) && defined(NDNBOOST_COMMON_TYPE_DONT_USE_TYPEOF)
Jeff Thompsona28eed82013-08-22 16:21:10 -070049#include <ndnboost/type_traits/detail/common_type_imp.hpp>
50#include <ndnboost/type_traits/remove_cv.hpp>
51#endif
52#include <ndnboost/mpl/if.hpp>
53#include <ndnboost/utility/declval.hpp>
54#include <ndnboost/type_traits/add_rvalue_reference.hpp>
55
56//----------------------------------------------------------------------------//
57// //
58// C++03 implementation of //
59// 20.9.7.6 Other transformations [meta.trans.other] //
60// Written by Howard Hinnant //
61// Adapted for Boost by Beman Dawes, Vicente Botet and Jeffrey Hellrung //
62// //
63//----------------------------------------------------------------------------//
64
65namespace ndnboost {
66
67// prototype
Jeff Thompson3d613fd2013-10-15 15:39:04 -070068#if !defined(NDNBOOST_NO_CXX11_VARIADIC_TEMPLATES)
Jeff Thompsona28eed82013-08-22 16:21:10 -070069 template<typename... T>
70 struct common_type;
71#else // or no specialization
72 template <class T, class U = void, class V = void>
73 struct common_type
74 {
75 public:
76 typedef typename common_type<typename common_type<T, U>::type, V>::type type;
77 };
78#endif
79
80
81// 1 arg
82 template<typename T>
Jeff Thompson3d613fd2013-10-15 15:39:04 -070083#if !defined(NDNBOOST_NO_CXX11_VARIADIC_TEMPLATES)
Jeff Thompsona28eed82013-08-22 16:21:10 -070084 struct common_type<T>
85#else
86 struct common_type<T, void, void>
87
88#endif
89 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -070090 NDNBOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, NDNBOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T));
Jeff Thompsona28eed82013-08-22 16:21:10 -070091 public:
92 typedef T type;
93 };
94
95// 2 args
96namespace type_traits_detail {
97
98 template <class T, class U>
99 struct common_type_2
100 {
101 private:
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700102 NDNBOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, NDNBOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T));
103 NDNBOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(U) > 0, NDNBOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (U));
Jeff Thompsona28eed82013-08-22 16:21:10 -0700104 static bool declval_bool(); // workaround gcc bug; not required by std
105 static typename add_rvalue_reference<T>::type declval_T(); // workaround gcc bug; not required by std
106 static typename add_rvalue_reference<U>::type declval_U(); // workaround gcc bug; not required by std
107 static typename add_rvalue_reference<bool>::type declval_b();
108
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700109#if !defined(NDNBOOST_NO_CXX11_DECLTYPE)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700110 public:
111 typedef decltype(declval<bool>() ? declval<T>() : declval<U>()) type;
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700112#elif defined(NDNBOOST_COMMON_TYPE_DONT_USE_TYPEOF)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700113 public:
114 typedef typename detail_type_traits_common_type::common_type_impl<
115 typename remove_cv<T>::type,
116 typename remove_cv<U>::type
117 >::type type;
118#else
119 public:
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700120 typedef NDNBOOST_TYPEOF_TPL(declval_b() ? declval_T() : declval_U()) type;
Jeff Thompsona28eed82013-08-22 16:21:10 -0700121#endif
122
123#if defined(__GNUC__) && __GNUC__ == 3 && (__GNUC_MINOR__ == 2 || __GNUC_MINOR__ == 3)
124 public:
125 void public_dummy_function_just_to_silence_warning();
126#endif
127 };
128
129 template <class T>
130 struct common_type_2<T, T>
131 {
132 typedef T type;
133 };
134 }
135
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700136#if !defined(NDNBOOST_NO_CXX11_VARIADIC_TEMPLATES)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700137 template <class T, class U>
138 struct common_type<T, U>
139#else
140 template <class T, class U>
141 struct common_type<T, U, void>
142#endif
143 : public type_traits_detail::common_type_2<T,U>
144 { };
145
146
147// 3 or more args
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700148#if !defined(NDNBOOST_NO_CXX11_VARIADIC_TEMPLATES)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700149 template<typename T, typename U, typename... V>
150 struct common_type<T, U, V...> {
151 public:
152 typedef typename common_type<typename common_type<T, U>::type, V...>::type type;
153 };
154#endif
155} // namespace ndnboost
156
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700157#endif // NDNBOOST_TYPE_TRAITS_COMMON_TYPE_HPP