JASL  [1.2.0]-2018-09-11
jasl_feature_test_macro.hpp
1 // JASL: For more information see https://github.com/matepek/jasl
2 //
3 // Copyright (c) 2018 Mate Pek
4 //
5 // This code is licensed under the MIT License (MIT).
6 
7 #pragma once
8 
9 /*
10  * JASL_cpp_constexpr
11  * JASL library will try to figure out the correct value of __cpp_constexpr and
12  * will define JASL_cpp_constexpr to it. JASL_cpp_constexpr also can be manually
13  * defined.
14  */
15 
16 /*
17  * JASL_cpp_lib_string_view
18  * JASL library will try to figure out the correct value of
19  * __cpp_lib_string_view and will define JASL_cpp_lib_string_view to it.
20  * JASL_cpp_lib_string_view also can be manually defined.
21  */
22 
23 #if defined(__GNUG__) && !defined(__clang__) // gcc
24 /*
25  * https://gcc.gnu.org/projects/cxx-status.html
26  * https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html
27  * http://nadeausoftware.com/articles/2012/10/c_c_tip_how_detect_compiler_name_and_version_using_compiler_predefined_macros
28  */
29 
30 # ifndef JASL_cpp_constexpr
31 # ifdef __cpp_constexpr
32 # define JASL_cpp_constexpr __cpp_constexpr
33 # else
34 # define JASL_cpp_constexpr \
35  (__GNUC__ >= 7L \
36  ? 201603L \
37  : (__GNUC__ >= 5L \
38  ? 201304L \
39  : (__GNUC__ == 4L && __GNUC_MINOR__ >= 6L ? 200704L \
40  : 0L)))
41 # endif // __cpp_constexpr
42 # endif // JASL_cpp_constexpr
43 # ifndef JASL_cpp_lib_string_view
44 # ifdef __cpp_lib_string_view
45 # define JASL_cpp_lib_string_view __cpp_lib_string_view
46 # else
47 # define JASL_cpp_lib_string_view \
48  (__cplusplus >= 201703 && \
49  (__GNUC__ > 7L || (__GNUC__ == 7L && __GNUC_MINOR__ >= 1L)) \
50  ? 201606L \
51  : 0L)
52 # endif // __cpp_lib_string_view
53 # endif // JASL_cpp_lib_string_view
54 
55 #elif defined(__clang__) // clang
56 
57 # ifndef JASL_cpp_constexpr
58 # ifdef __cpp_constexpr
59 # define JASL_cpp_constexpr __cpp_constexpr
60 # else
61 # error "Probably unsupported compiler version!"
62 # endif
63 # endif // JASL_cpp_constexpr
64 # ifndef JASL_cpp_lib_string_view
65 # ifdef __cpp_lib_string_view
66 # define JASL_cpp_lib_string_view __cpp_lib_string_view
67 # elif __cplusplus >= 201703
68 # define JASL_cpp_lib_string_view (__has_include(<string_view>) ? 201606L : 0L)
69 # else
70 # define JASL_cpp_lib_string_view 0L
71 # endif
72 # endif // JASL_cpp_lib_string_view
73 
74 #elif defined(_MSC_VER) // msvc
75 /*
76  * https://msdn.microsoft.com/en-us/library/b0084kay.aspx
77  * https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B
78  * https://docs.microsoft.com/en-us/cpp/visual-cpp-language-conformance
79  */
80 
81 # ifndef JASL_cpp_constexpr
82 # ifndef __cpp_constexpr
83 # define JASL_cpp_constexpr \
84  (_MSC_VER >= 1911L && _MSVC_LANG >= 201703L \
85  ? 201603L \
86  : (_MSC_VER >= 1910L && _MSVC_LANG >= 201402L \
87  ? 201304L \
88  : (_MSC_VER >= 1900L ? 200704L : 0L)))
89 # else // it works from 1915L
90 # define JASL_cpp_constexpr __cpp_constexpr
91 # endif // __cpp_constexpr
92 # endif // JASL_cpp_constexpr
93 # ifndef JASL_cpp_lib_string_view
94 # ifndef __cpp_lib_string_view
95 # define JASL_cpp_lib_string_view \
96  (__cplusplus >= 201703 && _MSC_VER >= 1910L && _MSVC_LANG >= 201703L \
97  ? 201606L \
98  : 0L)
99 # else
100 # define JASL_cpp_lib_string_view __cpp_lib_string_view
101 # endif // __cpp_lib_string_view
102 # endif // JASL_cpp_lib_string_view
103 
104 #else
105 
106 # if !defined(JASL_cpp_constexpr) || !defined(JASL_cpp_lib_string_view)
107 # error \
108  "Unsupported compiler! In case of an unsupported compiler JASL_cpp_constexpr and JASL_cpp_lib_string_view macros should be defined manually according to the used compiler (constexpr) and the used std library (std::string_view)."
109 # endif
110 
111 #endif // <compiler types>
112 
113 #if !JASL_cpp_constexpr
114 # undef JASL_cpp_constexpr
115 #endif // !JASL_cpp_constexpr
116 
117 #if !JASL_cpp_lib_string_view
118 # undef JASL_cpp_lib_string_view
119 #endif // !JASL_cpp_lib_string_view
120 
121 /*
122  * http://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros
123  * http://en.cppreference.com/w/cpp/language/constexpr
124  */
125 #ifdef JASL_cpp_constexpr
126 # if JASL_cpp_constexpr >= 201304L
127 # define JASL_CONSTEXPR_CXX14 constexpr
128 # elif JASL_cpp_constexpr >= 200704L
129 # define JASL_CONSTEXPR_CXX14
130 # else
131 // JASL_cpp_constexpr should not be defined.
132 # error "Something wrong with the defines."
133 # endif
134 #else // ifdef JASL_cpp_constexpr
135 // There is no reason to support it without supporting noexcept.
136 # error "Unsupported C++ standard!"
137 #endif // ifdef JASL_cpp_constexpr
138 
139 #ifdef __cpp_lib_is_swappable
140 # define JASL_is_nothrow_swappable_value(type) \
141  (std::is_nothrow_swappable<type>::value)
142 #else
143 // http://en.cppreference.com/w/cpp/algorithm/swap
144 # define JASL_is_nothrow_swappable_value(type) \
145  (std::is_nothrow_move_constructible<type>::value && \
146  std::is_nothrow_move_assignable<type>::value)
147 #endif