common_type.hpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2014, 2015 Ableton AG, Berlin. All rights reserved.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
21 //
22 
27 #pragma once
28 
29 #include <atria/meta/utils.hpp>
30 #include <atria/meta/pack.hpp>
32 
33 #include <ableton/build_system/Warnings.hpp>
34 ABL_DISABLE_WARNINGS
35 #include <boost/mpl/eval_if.hpp>
36 #include <boost/mpl/and.hpp>
37 #include <boost/mpl/not.hpp>
38 #include <boost/mpl/vector.hpp>
39 #include <boost/mpl/fold.hpp>
40 #include <boost/mpl/identity.hpp>
41 ABL_RESTORE_WARNINGS
42 #include <type_traits>
43 #include <utility>
44 
45 namespace atria {
46 namespace meta {
47 
51 namespace mpl = boost::mpl;
52 
56 template <typename ...Ts>
58 {
59  template <typename T>
62 };
63 
64 namespace detail {
65 
67 // Removes r-value reference from type T if is not present in any of
68 // the types in `OrigT`. This allows to remove unexpected r-references
69 // from a type that were added because of the use of `declval`.
70 //
71 template<class ValT, class ...OrigTs>
72 struct undeclval
73  : mpl::eval_if<mpl::and_<std::is_rvalue_reference<ValT>,
74  mpl::not_<std::is_rvalue_reference<OrigTs> >... >,
75  std::remove_reference<ValT>,
76  identity<ValT> >
77 {};
78 
79 template <typename T, typename U, typename Enable=void>
80 struct common_type2
81 {
82  using type = could_not_find_common_type<T, U>;
83 };
84 
85 template <typename T, typename U>
86 struct common_type2<
87  T, U,
88  estd::void_t<decltype(
89  true ? std::declval<T>() : std::declval<U>())>>
90 {
91  using type = typename undeclval<
92  decltype(true ? std::declval<T>() : std::declval<U>()),
93  T, U
94  >::type;
95 };
96 
97 } // namespace detail
98 
114 template <typename... Ts>
115 struct common_type;
116 
117 template <typename T, typename ...Ts>
118 struct common_type<T, Ts...>
119  : mpl::fold<pack<Ts...>, T, detail::common_type2<mpl::_1, mpl::_2> >
120 {};
121 
122 template <>
123 struct common_type<>
124 {
125  using type = could_not_find_common_type<>;
126 };
127 
131 template <typename ...Ts>
132 using common_type_t = typename common_type<Ts...>::type;
133 
134 } // namespace meta
135 } // namespace atria
typename detail::make_void< Ts... >::type void_t
Similar to C++17 std::void_t.
Definition: type_traits.hpp:48
typename common_type< Ts... >::type common_type_t
C++14 style alias for common_type
Type to enable making a type convertible from void.
Definition: utils.hpp:63
Similar to std::common_type but addresses several issues.
It is allowed to alias boost::mpl inside atria::meta.
Definition: common_type.hpp:57
C++ amazing templates and reusable implementations awesomeness.
Definition: _doc.hpp:35
Fork me on GitHub