1 // 2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) 3 // Copyright (c) 2019-2020 Krystian Stasiowski (sdkrystian at gmail dot com) 4 // 5 // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 // 8 // Official repository: https://github.com/boostorg/static_string 9 // 10 11 #ifndef BOOST_STATIC_STRING_CONFIG_HPP 12 #define BOOST_STATIC_STRING_CONFIG_HPP 13 14 // Are we dependent on Boost? 15 // #define BOOST_STATIC_STRING_STANDALONE 16 17 // Can we have deduction guides? 18 #if __cpp_deduction_guides >= 201703L 19 #define BOOST_STATIC_STRING_USE_DEDUCT 20 #endif 21 22 // Include <version> if we can 23 #ifdef __has_include 24 #if __has_include(<version>) 25 #include <version> 26 #endif 27 #endif 28 29 // Can we use __has_builtin? 30 #ifdef __has_builtin 31 #define BOOST_STATIC_STRING_HAS_BUILTIN(arg) __has_builtin(arg) 32 #else 33 #define BOOST_STATIC_STRING_HAS_BUILTIN(arg) 0 34 #endif 35 36 // Can we use is_constant_evaluated? 37 #if __cpp_lib_is_constant_evaluated >= 201811L 38 #define BOOST_STATIC_STRING_IS_CONST_EVAL std::is_constant_evaluated() 39 #elif BOOST_STATIC_STRING_HAS_BUILTIN(__builtin_is_constant_evaluated) 40 #define BOOST_STATIC_STRING_IS_CONST_EVAL __builtin_is_constant_evaluated() 41 #endif 42 43 // Check for an attribute 44 #if defined(__has_cpp_attribute) 45 #define BOOST_STATIC_STRING_CHECK_FOR_ATTR(x) __has_cpp_attribute(x) 46 #elif defined(__has_attribute) 47 #define BOOST_STATIC_STRING_CHECK_FOR_ATTR(x) __has_attribute(x) 48 #else 49 #define BOOST_STATIC_STRING_CHECK_FOR_ATTR(x) 0 50 #endif 51 52 // Decide which attributes we can use 53 #define BOOST_STATIC_STRING_UNLIKELY 54 #define BOOST_STATIC_STRING_NODISCARD 55 #define BOOST_STATIC_STRING_NORETURN 56 #define BOOST_STATIC_STRING_NO_NORETURN 57 // unlikely 58 #if BOOST_STATIC_STRING_CHECK_FOR_ATTR(unlikely) 59 #undef BOOST_STATIC_STRING_UNLIKELY 60 #define BOOST_STATIC_STRING_UNLIKELY [[unlikely]] 61 #endif 62 // nodiscard 63 #if BOOST_STATIC_STRING_CHECK_FOR_ATTR(nodiscard) 64 #undef BOOST_STATIC_STRING_NODISCARD 65 #define BOOST_STATIC_STRING_NODISCARD [[nodiscard]] 66 #elif defined(_MSC_VER) && _MSC_VER >= 1700 67 #undef BOOST_STATIC_STRING_NODISCARD 68 #define BOOST_STATIC_STRING_NODISCARD _Check_return_ 69 #elif defined(__GNUC__) || defined(__clang__) 70 #undef BOOST_STATIC_STRING_NODISCARD 71 #define BOOST_STATIC_STRING_NODISCARD __attribute__((warn_unused_result)) 72 #endif 73 // noreturn 74 #if BOOST_STATIC_STRING_CHECK_FOR_ATTR(noreturn) 75 #undef BOOST_STATIC_STRING_NORETURN 76 #undef BOOST_STATIC_STRING_NO_NORETURN 77 #define BOOST_STATIC_STRING_NORETURN [[noreturn]] 78 #elif defined(_MSC_VER) 79 #undef BOOST_STATIC_STRING_NORETURN 80 #undef BOOST_STATIC_STRING_NO_NORETURN 81 #define BOOST_STATIC_STRING_NORETURN __declspec(noreturn) 82 #elif defined(__GNUC__) || defined(__clang__) 83 #undef BOOST_STATIC_STRING_NORETURN 84 #undef BOOST_STATIC_STRING_NO_NORETURN 85 #define BOOST_STATIC_STRING_NORETURN __attribute__((__noreturn__)) 86 #endif 87 88 // _MSVC_LANG isn't avaliable until after VS2015 89 #if defined(_MSC_VER) && _MSC_VER < 1910L 90 // The constexpr support in this version is effectively that of 91 // c++11, so we treat it as such 92 #define BOOST_STATIC_STRING_STANDARD_VERSION 201103L 93 #elif defined(_MSVC_LANG) 94 // MSVC doesn't define __cplusplus by default 95 #define BOOST_STATIC_STRING_STANDARD_VERSION _MSVC_LANG 96 #else 97 #define BOOST_STATIC_STRING_STANDARD_VERSION __cplusplus 98 #endif 99 100 // Decide what level of constexpr we can use 101 #define BOOST_STATIC_STRING_CPP20_CONSTEXPR 102 #define BOOST_STATIC_STRING_CPP17_CONSTEXPR 103 #define BOOST_STATIC_STRING_CPP14_CONSTEXPR 104 #define BOOST_STATIC_STRING_CPP11_CONSTEXPR 105 #if BOOST_STATIC_STRING_STANDARD_VERSION >= 202002L 106 #define BOOST_STATIC_STRING_CPP20 107 #undef BOOST_STATIC_STRING_CPP20_CONSTEXPR 108 #define BOOST_STATIC_STRING_CPP20_CONSTEXPR constexpr 109 #endif 110 #if BOOST_STATIC_STRING_STANDARD_VERSION >= 201703L 111 #define BOOST_STATIC_STRING_CPP17 112 #undef BOOST_STATIC_STRING_CPP17_CONSTEXPR 113 #define BOOST_STATIC_STRING_CPP17_CONSTEXPR constexpr 114 #endif 115 #if BOOST_STATIC_STRING_STANDARD_VERSION >= 201402L 116 #define BOOST_STATIC_STRING_CPP14 117 #undef BOOST_STATIC_STRING_CPP14_CONSTEXPR 118 #define BOOST_STATIC_STRING_CPP14_CONSTEXPR constexpr 119 #endif 120 #if BOOST_STATIC_STRING_STANDARD_VERSION >= 201103L 121 #define BOOST_STATIC_STRING_CPP11 122 #undef BOOST_STATIC_STRING_CPP11_CONSTEXPR 123 #define BOOST_STATIC_STRING_CPP11_CONSTEXPR constexpr 124 #endif 125 126 // Boost and non-Boost versions of utilities 127 #ifndef BOOST_STATIC_STRING_STANDALONE 128 #ifndef BOOST_STATIC_STRING_THROW 129 #define BOOST_STATIC_STRING_THROW(ex) BOOST_THROW_EXCEPTION(ex) 130 #endif 131 #ifndef BOOST_STATIC_STRING_STATIC_ASSERT 132 #define BOOST_STATIC_STRING_STATIC_ASSERT(cond, msg) BOOST_STATIC_ASSERT_MSG(cond, msg) 133 #endif 134 #ifndef BOOST_STATIC_STRING_ASSERT 135 #define BOOST_STATIC_STRING_ASSERT(cond) BOOST_ASSERT(cond) 136 #endif 137 #else 138 #ifndef BOOST_STATIC_STRING_THROW 139 #define BOOST_STATIC_STRING_THROW(ex) throw ex 140 #endif 141 #ifndef BOOST_STATIC_STRING_STATIC_ASSERT 142 #define BOOST_STATIC_STRING_STATIC_ASSERT(cond, msg) static_assert(cond, msg) 143 #endif 144 #ifndef BOOST_STATIC_STRING_ASSERT 145 #define BOOST_STATIC_STRING_ASSERT(cond) assert(cond) 146 #endif 147 #endif 148 149 #ifndef BOOST_STATIC_STRING_STANDALONE 150 #include <boost/assert.hpp> 151 #include <boost/container_hash/hash.hpp> 152 #include <boost/static_assert.hpp> 153 #include <boost/utility/string_view.hpp> 154 #include <boost/throw_exception.hpp> 155 #else 156 #include <cassert> 157 #include <stdexcept> 158 #include <string_view> 159 #endif 160 161 // Compiler bug prevents constexpr from working with clang 4.x and 5.x 162 // if it is detected, we disable constexpr. 163 #if (BOOST_STATIC_STRING_STANDARD_VERSION >= 201402L && \ 164 BOOST_STATIC_STRING_STANDARD_VERSION < 201703L) && \ 165 defined(__clang__) && \ 166 ((__clang_major__ == 4) || (__clang_major__ == 5)) 167 // This directive works on clang 168 #warning "C++14 constexpr is not supported in clang 4.x and 5.x due to a compiler bug." 169 #ifdef BOOST_STATIC_STRING_CPP14 170 #undef BOOST_STATIC_STRING_CPP14 171 #endif 172 #undef BOOST_STATIC_STRING_CPP14_CONSTEXPR 173 #define BOOST_STATIC_STRING_CPP14_CONSTEXPR 174 #endif 175 176 // This is for compiler/library configurations 177 // that cannot use the library comparison function 178 // objects at all in constant expresssions. In these 179 // cases, we use whatever will make more constexpr work. 180 #if defined(__clang__) && \ 181 (defined(__GLIBCXX__) || defined(_MSC_VER)) 182 #define BOOST_STATIC_STRING_NO_PTR_COMP_FUNCTIONS 183 #endif 184 185 // In gcc-5, we cannot use throw expressions in a 186 // constexpr function. However, we have a workaround 187 // for this using constructors. Also, non-static member 188 // functions that return the class they are a member of 189 // causes an ICE during constant evaluation. 190 #if defined(__GNUC__) && (__GNUC__== 5) && \ 191 defined(BOOST_STATIC_STRING_CPP14) 192 #define BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR 193 #endif 194 195 namespace boost { 196 namespace static_strings { 197 198 /// The type of `basic_string_view` used by the library 199 template<typename CharT, typename Traits> 200 using basic_string_view = 201 #ifndef BOOST_STATIC_STRING_STANDALONE 202 boost::basic_string_view<CharT, Traits>; 203 #else 204 std::basic_string_view<CharT, Traits>; 205 #endif 206 } // static_strings 207 } // boost 208 #endif