1 /*
2    Copyright (C) 2017-2018 by the Battle for Wesnoth Project https://www.wesnoth.org/
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY.
10 
11    See the COPYING file for more details.
12 */
13 
14 #pragma once
15 
16 #include "global.hpp"
17 
18 #include <type_traits>
19 
20 namespace utils
21 {
22 //
23 // These aliases are part of the standard starting with C++14.
24 // MSVC included them itself starting from VS2013 (our min supported version).
25 // However, they can't be used via alias templates in VS2013 due to lack of
26 // support for expression SFINAE.
27 // Forward to their declarations as appropriate.
28 //
29 #if defined(HAVE_CXX14) || _MSC_VER >= 1900
30 
31 template<typename T>
32 using add_const_t = std::add_const_t<T>;
33 template<bool B, typename T, typename F>
34 using conditional_t = std::conditional_t<B, T, F>;
35 template<bool B, typename T = void>
36 using enable_if_t = std::enable_if_t<B, T>;
37 template<typename T>
38 using remove_const_t = std::remove_const_t<T>;
39 template<typename T>
40 using remove_reference_t = std::remove_reference_t<T>;
41 template<typename T>
42 using remove_pointer_t = std::remove_pointer_t<T>;
43 
44 #else // We do not have C++14 or MSVC >= 2015
45 
46 // add_const
47 template<typename T>
48 using add_const_t = typename std::add_const<T>::type;
49 
50 // conditional
51 template<bool B, typename T, typename F>
52 using conditional_t = typename std::conditional<B, T, F>::type;
53 
54 // enable_if
55 template<bool B, typename T = void>
56 using enable_if_t = typename std::enable_if<B, T>::type;
57 
58 // remove_const
59 template<typename T>
60 using remove_const_t = typename std::remove_const<T>::type;
61 
62 // remove_reference
63 template<typename T>
64 using remove_reference_t = typename std::remove_reference<T>::type;
65 
66 // remove_pointer
67 template<typename T>
68 using remove_pointer_t = typename std::remove_pointer<T>::type;
69 
70 #endif // defined(HAVE_CXX14) || _MSC_VER >= 1900
71 
72 // Since there's really no way to implement these without variable templates, I've commented
73 // this whole section out until we bump our min compiler support to VS 2015 and GCC 5.
74 #if 0
75 
76 //
77 // These aliases are part of the standard starting with C++17.
78 // However, MSVC includes them as of VS 2015 Update 2, and they can also be implemented
79 // using variable templates in C++14.
80 //
81 #ifdef HAVE_CXX17 || defined(_MSC_VER) && _MSC_VER >= 1900
82 
83 using std::is_base_of_v;
84 using std::is_same_v;
85 
86 #elif defined(HAVE_CXX14)
87 
88 // is_base_of
89 template<typename Base, typename Derived>
90 static constexpr bool is_base_of_v = std::is_base_of<Base, Derived>::value;
91 
92 // is_same
93 template<typename T, typename U>
94 static constexpr bool is_same_v = std::is_same<T, U>::value;
95 
96 #endif // HAVE_CXX17
97 
98 #endif
99 
100 } // end namespace utils
101