Reaktoro  v2.11.0
A unified framework for modeling chemically reactive systems
TraitsUtils.hpp
1 // Reaktoro is a unified framework for modeling chemically reactive systems.
2 //
3 // Copyright © 2014-2024 Allan Leal
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this library. If not, see <http://www.gnu.org/licenses/>.
17 
18 #pragma once
19 
20 // C++ includes
21 #include <functional>
22 #include <limits>
23 #include <type_traits>
24 
25 namespace Reaktoro {
26 
27 template<bool value>
28 using EnableIf = std::enable_if_t<value>;
29 
30 template<bool value>
31 using Requires = std::enable_if_t<value, bool>;
32 
33 template<typename T>
34 using Decay = std::decay_t<T>;
35 
36 template<typename T>
37 constexpr auto isArithmetic = std::is_arithmetic_v<T>;
38 
39 template<typename T>
40 constexpr auto isInteger = std::numeric_limits<Decay<T>>::is_integer;
41 
42 template<typename T>
43 constexpr auto isFloatingPoint = std::is_floating_point_v<T>;
44 
45 template<typename From, typename To>
46 constexpr auto isConvertible = std::is_convertible_v<From, To>;
47 
48 template<typename T, typename U>
49 constexpr auto isSame = std::is_same_v<Decay<T>, Decay<U>>;
50 
51 template<typename T, typename U>
52 constexpr auto isBaseOf = std::is_base_of_v<Decay<T>, Decay<U>>;
53 
54 namespace detail {
55 
56 template<typename T>
57 struct isFunction { static constexpr auto value = false; };
58 
59 template<typename Signature>
60 struct isFunction<std::function<Signature>> { static constexpr auto value = true; };
61 
62 template<typename T>
63 struct asFunction : public asFunction<decltype(&T::operator())> {};
64 
65 template<typename Ret, typename... Args>
66 struct asFunction<Ret(Args...)> { using type = std::function<Ret(Args...)>; };
67 
68 template<typename Ret, typename... Args>
69 struct asFunction<Ret(*)(Args...)> { using type = std::function<Ret(Args...)>; };
70 
71 template<typename Class, typename Ret, typename... Args>
72 struct asFunction<Ret(Class::*)(Args...) const> { using type = std::function<Ret(Args...)>; };
73 
74 template<typename T, typename U, typename... Us>
75 constexpr auto isOneOf()
76 {
77  if constexpr (sizeof...(Us) > 0)
78  return isSame<T, U> || isOneOf<T, Us...>();
79  else return isSame<T, U>;
80 }
81 
82 } // namespace detail
83 
84 template<typename T>
85 constexpr auto isFunction = detail::isFunction<Decay<T>>::value;
86 
91 template<typename Fun>
92 constexpr auto asFunction(const Fun& f) { return typename detail::asFunction<Fun>::type{f}; } // Reference: https://stackoverflow.com/a/39182901/418875
93 
94 template<typename T, typename U, typename... Us>
95 constexpr auto isOneOf = detail::isOneOf<T, U, Us...>();
96 
97 //======================================================================
98 // Reference type traits
99 //======================================================================
100 namespace detail { template<typename T> struct Ref { using type = T&; }; }
101 
102 template<typename T>
103 using Ref = typename detail::Ref<T>::type;
104 
105 #define REAKTORO_DEFINE_REFERENCE_TYPE_OF(basetype, reftype) \
106  namespace detail { template<> struct Ref<basetype> { using type = reftype; }; }
107 
108 //======================================================================
109 
110 } // namespace Reaktoro
The namespace containing all components of the Reaktoro library.
Definition: Algorithms.hpp:29
constexpr auto asFunction(const Fun &f)
Convert lambda/function pointers/member functions to std::function.
Definition: TraitsUtils.hpp:92
Definition: TraitsUtils.hpp:100
Definition: TraitsUtils.hpp:63
Definition: TraitsUtils.hpp:57