1 /*=============================================================================
2     Copyright (c) 2016 Paul Fultz II
3     config.hpp
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 
8 #ifndef BOOST_HOF_GUARD_CONFIG_HPP
9 #define BOOST_HOF_GUARD_CONFIG_HPP
10 
11 // Unpack has extra checks to ensure that the function will be invoked with
12 // the sequence. This extra check can help improve error reporting but it can
13 // slow down compilation. This is enabled by default.
14 #ifndef BOOST_HOF_CHECK_UNPACK_SEQUENCE
15 #define BOOST_HOF_CHECK_UNPACK_SEQUENCE 1
16 #endif
17 
18 // Check for std version
19 #if __cplusplus >= 201606
20 #define BOOST_HOF_HAS_STD_17 1
21 #else
22 #define BOOST_HOF_HAS_STD_17 0
23 #endif
24 
25 #if __cplusplus >= 201402
26 #define BOOST_HOF_HAS_STD_14 1
27 #else
28 #define BOOST_HOF_HAS_STD_14 0
29 #endif
30 
31 #if __cplusplus >= 201103
32 #define BOOST_HOF_HAS_STD_11 1
33 #else
34 #define BOOST_HOF_HAS_STD_11 0
35 #endif
36 
37 
38 // This determines if it safe to use inheritance for EBO. On every platform
39 // except clang, compilers have problems with ambigous base conversion. So
40 // this configures the library to use a different technique to achieve empty
41 // optimization.
42 #ifndef BOOST_HOF_HAS_EBO
43 #ifdef __clang__
44 #define BOOST_HOF_HAS_EBO 1
45 #else
46 #define BOOST_HOF_HAS_EBO 0
47 #endif
48 #endif
49 
50 // This configures the library whether expression sfinae can be used to detect
51 // callability of a function.
52 #ifndef BOOST_HOF_NO_EXPRESSION_SFINAE
53 #ifdef _MSC_VER
54 #define BOOST_HOF_NO_EXPRESSION_SFINAE 1
55 #else
56 #define BOOST_HOF_NO_EXPRESSION_SFINAE 0
57 #endif
58 #endif
59 
60 // This configures the library to use manual type deduction in a few places
61 // where it problematic on a few platforms.
62 #ifndef BOOST_HOF_HAS_MANUAL_DEDUCTION
63 #if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 8)
64 #define BOOST_HOF_HAS_MANUAL_DEDUCTION 1
65 #else
66 #define BOOST_HOF_HAS_MANUAL_DEDUCTION 0
67 #endif
68 #endif
69 
70 // Whether the compiler has relaxed constexpr.
71 #ifndef BOOST_HOF_HAS_RELAXED_CONSTEXPR
72 #ifdef __cpp_constexpr
73 #if __cpp_constexpr >= 201304
74 #define BOOST_HOF_HAS_RELAXED_CONSTEXPR 1
75 #else
76 #define BOOST_HOF_HAS_RELAXED_CONSTEXPR 0
77 #endif
78 #else
79 #define BOOST_HOF_HAS_RELAXED_CONSTEXPR BOOST_HOF_HAS_STD_14
80 #endif
81 #endif
82 
83 // Whether the compiler supports generic lambdas
84 #ifndef BOOST_HOF_HAS_GENERIC_LAMBDA
85 #if defined(__cpp_generic_lambdas) || defined(_MSC_VER)
86 #define BOOST_HOF_HAS_GENERIC_LAMBDA 1
87 #else
88 #define BOOST_HOF_HAS_GENERIC_LAMBDA BOOST_HOF_HAS_STD_14
89 #endif
90 #endif
91 
92 // Whether the compiler supports constexpr lambdas
93 #ifndef BOOST_HOF_HAS_CONSTEXPR_LAMBDA
94 #if defined(__cpp_constexpr) && __cpp_constexpr >= 201603
95 #define BOOST_HOF_HAS_CONSTEXPR_LAMBDA 1
96 #else
97 #define BOOST_HOF_HAS_CONSTEXPR_LAMBDA BOOST_HOF_HAS_STD_17
98 #endif
99 #endif
100 
101 // Whether the compiler supports inline variables
102 #ifndef BOOST_HOF_HAS_INLINE_VARIABLES
103 #if defined(__cpp_inline_variables)
104 #define BOOST_HOF_HAS_INLINE_VARIABLES 1
105 #else
106 #define BOOST_HOF_HAS_INLINE_VARIABLES BOOST_HOF_HAS_STD_17
107 #endif
108 #endif
109 
110 // Whether inline variables defined with lambdas have external linkage.
111 // Currently, no compiler supports this yet.
112 #ifndef BOOST_HOF_HAS_INLINE_LAMBDAS
113 #define BOOST_HOF_HAS_INLINE_LAMBDAS 0
114 #endif
115 
116 // Whether the compiler supports variable templates
117 #ifndef BOOST_HOF_HAS_VARIABLE_TEMPLATES
118 #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ < 5
119 #define BOOST_HOF_HAS_VARIABLE_TEMPLATES 0
120 #elif defined(__cpp_variable_templates)
121 #define BOOST_HOF_HAS_VARIABLE_TEMPLATES 1
122 #else
123 #define BOOST_HOF_HAS_VARIABLE_TEMPLATES BOOST_HOF_HAS_STD_14
124 #endif
125 #endif
126 
127 // Whether a constexpr function can use a void return type
128 #ifndef BOOST_HOF_NO_CONSTEXPR_VOID
129 #if BOOST_HOF_HAS_RELAXED_CONSTEXPR
130 #define BOOST_HOF_NO_CONSTEXPR_VOID 0
131 #else
132 #define BOOST_HOF_NO_CONSTEXPR_VOID 1
133 #endif
134 #endif
135 
136 // Whether to use template aliases
137 #ifndef BOOST_HOF_HAS_TEMPLATE_ALIAS
138 #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 8
139 #define BOOST_HOF_HAS_TEMPLATE_ALIAS 0
140 #else
141 #define BOOST_HOF_HAS_TEMPLATE_ALIAS 1
142 #endif
143 #endif
144 
145 // Whether evaluations of function in brace initialization is ordered from
146 // left-to-right.
147 #ifndef BOOST_HOF_NO_ORDERED_BRACE_INIT
148 #if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9) || defined(_MSC_VER)
149 #define BOOST_HOF_NO_ORDERED_BRACE_INIT 1
150 #else
151 #define BOOST_HOF_NO_ORDERED_BRACE_INIT 0
152 #endif
153 #endif
154 
155 // Whether the compiler has trouble mangling some expressions used in
156 // decltype.
157 #ifndef BOOST_HOF_HAS_MANGLE_OVERLOAD
158 #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
159 #define BOOST_HOF_HAS_MANGLE_OVERLOAD 0
160 #else
161 #define BOOST_HOF_HAS_MANGLE_OVERLOAD 1
162 #endif
163 #endif
164 
165 // Whether an incomplete 'this' pointer can be used in a trailing decltype.
166 #ifndef BOOST_HOF_HAS_COMPLETE_DECLTYPE
167 #if !BOOST_HOF_HAS_MANGLE_OVERLOAD || (defined(__GNUC__) && !defined (__clang__))
168 #define BOOST_HOF_HAS_COMPLETE_DECLTYPE 0
169 #else
170 #define BOOST_HOF_HAS_COMPLETE_DECLTYPE 1
171 #endif
172 #endif
173 
174 // Whether function will deduce noexcept from an expression
175 #ifndef BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
176 #if defined(__GNUC__) && !defined (__clang__) && ((__GNUC__ == 4 && __GNUC_MINOR__ < 8) || (__GNUC__ == 7 && __GNUC_MINOR__ == 1))
177 #define BOOST_HOF_HAS_NOEXCEPT_DEDUCTION 0
178 #else
179 #define BOOST_HOF_HAS_NOEXCEPT_DEDUCTION 1
180 #endif
181 #endif
182 
183 // Some type expansion failures on gcc 4.6
184 #ifndef BOOST_HOF_NO_TYPE_PACK_EXPANSION_IN_TEMPLATE
185 #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
186 #define BOOST_HOF_NO_TYPE_PACK_EXPANSION_IN_TEMPLATE 1
187 #else
188 #define BOOST_HOF_NO_TYPE_PACK_EXPANSION_IN_TEMPLATE 0
189 #endif
190 #endif
191 
192 // Whether to use std::default_constructible, it is a little buggy on gcc 4.6.
193 #ifndef BOOST_HOF_NO_STD_DEFAULT_CONSTRUCTIBLE
194 #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
195 #define BOOST_HOF_NO_STD_DEFAULT_CONSTRUCTIBLE 1
196 #else
197 #define BOOST_HOF_NO_STD_DEFAULT_CONSTRUCTIBLE 0
198 #endif
199 #endif
200 
201 #endif
202