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