diff --git a/.travis.yml b/.travis.yml index 865ffbc..d99ece4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -170,6 +170,17 @@ matrix: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-4.0 + - os: linux + compiler: clang++-5.0 + env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z + addons: + apt: + packages: + - clang-5.0 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-5.0 + - os: osx env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z osx_image: xcode8.3 diff --git a/doc/credits.qbk b/doc/credits.qbk index b51382f..d266524 100644 --- a/doc/credits.qbk +++ b/doc/credits.qbk @@ -18,8 +18,8 @@ current maintainer of the library. This version of type traits library is based on contributions by Adobe Systems Inc, David Abrahams, Steve Cleary, Beman Dawes, Aleksey Gurtovoy, Howard Hinnant, Jesse Jones, Mat Marcus, -Itay Maman, John Maddock, Thorsten Ottosen, Robert Ramey, Jeremy Siek -and Antony Polukhin. +Itay Maman, John Maddock, Thorsten Ottosen, Robert Ramey, Jeremy Siek, +Antony Polukhin and Glen Fernandes. Mat Marcus and Jesse Jones invented, and [@http://opensource.adobe.com/project4/project.shtml published a paper describing], diff --git a/doc/detected.qbk b/doc/detected.qbk new file mode 100644 index 0000000..cbe4d90 --- /dev/null +++ b/doc/detected.qbk @@ -0,0 +1,24 @@ +[/ +Copyright 2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt). +] + +[section:detected detected] + + template class Op, class... Args> + using detected_t = __below; + +__alias `Op` if it is a valid template-id, otherwise +`boost::nonesuch`. + +__std_paper [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf N4502] + +__compat Requires C++11 variadic templates and C++11 template aliases. + +__header `#include ` + +[endsect] diff --git a/doc/detected_or.qbk b/doc/detected_or.qbk new file mode 100644 index 0000000..aeb8186 --- /dev/null +++ b/doc/detected_or.qbk @@ -0,0 +1,38 @@ +[/ +Copyright 2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt). +] + +[section:detected_or detected_or] + + template class Op, class... Args> + using detected_or = __below; + + template class Op, class... Args> + using detected_or_t = typename detected_or::type; + +__alias An unspecified type with two public member type definitions: + +* `value_t` is __true_type if `Op` is a valid template-id, otherwise + __false_type +* `type` is `Op` if it is a valid template-id, otherwise `Default` + +__std_paper [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf N4502] + +__compat Requires C++11 variadic templates and C++11 template aliases. + +__header `#include ` + +__examples + + template + using difference_t = typename T::difference_type; + + template + using difference_type = boost::detected_or_t; + +[endsect] diff --git a/doc/is_detected.qbk b/doc/is_detected.qbk new file mode 100644 index 0000000..4477be8 --- /dev/null +++ b/doc/is_detected.qbk @@ -0,0 +1,42 @@ +[/ +Copyright 2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt). +] + +[section:is_detected is_detected] + + template class Op, class... Args> + using is_detected = __below; + + template class Op, class... Args> + constexpr bool is_detected_v = is_detected::value; + +__alias If `Op` is a valid template-id, aliases __true_type, +otherwise aliases __false_type. + +__std_paper [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf N4502] + +__compat Requires C++11 variadic templates and C++11 template aliases. + +__header `#include ` + +__examples + + template + using clear_t = decltype(boost::declval().clear()); + + template + void clear(T& value) + { + if constexpr (boost::is_detected_v) { + value.clear(); + } else { + value = T(); + } + } + +[endsect] diff --git a/doc/is_detected_convertible.qbk b/doc/is_detected_convertible.qbk new file mode 100644 index 0000000..8c16574 --- /dev/null +++ b/doc/is_detected_convertible.qbk @@ -0,0 +1,31 @@ +[/ +Copyright 2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt). +] + +[section:is_detected_convertible is_detected_convertible] + + template class Op, class... Args> + using is_detected_convertible = is_convertible, To>; + + template class Op, class... Args> + constexpr bool is_detected_convertible_v = is_detected_convertible::value; + +__std_paper [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf N4502] + +__compat Requires C++11 variadic templates and C++11 template aliases. + +__header `#include ` + +__examples + + template + using size_type_t = typename T::size_type; + + static_assert(boost::is_detected_convertible_v); + +[endsect] diff --git a/doc/is_detected_exact.qbk b/doc/is_detected_exact.qbk new file mode 100644 index 0000000..caef5ac --- /dev/null +++ b/doc/is_detected_exact.qbk @@ -0,0 +1,31 @@ +[/ +Copyright 2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt). +] + +[section:is_detected_exact is_detected_exact] + + template class Op, class... Args> + using is_detected_exact = is_same >; + + template class Op, class... Args> + constexpr bool is_detected_exact_v = is_detected_exact::value; + +__std_paper [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf N4502] + +__compat Requires C++11 variadic templates and C++11 template aliases. + +__header `#include ` + +__examples + + template + using difference_t = typename T::difference_type; + + static_assert(boost::is_detected_exact_v); + +[endsect] diff --git a/doc/nonesuch.qbk b/doc/nonesuch.qbk new file mode 100644 index 0000000..22768c1 --- /dev/null +++ b/doc/nonesuch.qbk @@ -0,0 +1,21 @@ +[/ +Copyright 2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt). +] + +[section:nonesuch nonesuch] + + struct nonesuch { + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(const nonesuch&) = delete; + void operator=(const nonesuch&) = delete; + }; + +__header `#include ` + +[endsect] diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index 9bd3d31..b751f9f 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -31,7 +31,9 @@ [def __true_type [link boost_typetraits.reference.integral_constant true_type]] [def __false_type [link boost_typetraits.reference.integral_constant false_type]] [def __integral_constant [link boost_typetraits.reference.integral_constant integral_constant]] +[def __alias [*Aliases:]] [def __inherit [*Inherits:]] +[def __std_paper [*C++ Standard Paper:]] [def __std_ref [*C++ Standard Reference:]] [def __header [*Header:]] [def __compat [*Compiler Compatibility:]] @@ -145,6 +147,13 @@ [def __type_identity [link boost_typetraits.reference.type_identity type_identity]] [def __declval [link boost_typetraits.reference.declval declval]] +[def __detected [link boost_typetraits.reference.detected detected]] +[def __detected_or [link boost_typetraits.reference.detected_or detected_or]] +[def __is_detected [link boost_typetraits.reference.is_detected is_detected]] +[def __is_detected_convertible [link boost_typetraits.reference.is_detected_convertible is_detected_convertible]] +[def __is_detected_exact [link boost_typetraits.reference.is_detected_exact is_detected_exact]] +[def __nonesuch [link boost_typetraits.reference.nonesuch nonesuch]] + [def __compat [*Compiler Compatibility:]] [template all_compilers[] __compat All current compilers are supported by this trait.] [template has_binary_operator_compat[] __compat Requires working SFINAE (i.e. BOOST_NO_SFINAE is not set). Only a minority of rather old compilers do not support this.] @@ -204,6 +213,8 @@ that is the result of the transformation. [include copy_cv.qbk] [include decay.qbk] [include declval.qbk] +[include detected.qbk] +[include detected_or.qbk] [include extent.qbk] [include floating_point_promotion.qbk] [include function_traits.qbk] @@ -289,6 +300,9 @@ See __has_trivial_constructor. [include is_copy_constructible.qbk] [include is_default_constructible.qbk] [include is_destructible.qbk] +[include is_detected.qbk] +[include is_detected_convertible.qbk] +[include is_detected_exact.qbk] [include is_empty.qbk] [include is_enum.qbk] [include is_final.qbk] @@ -323,6 +337,7 @@ See __has_trivial_constructor. [include make_signed.qbk] [include make_unsigned.qbk] [include make_void.qbk] +[include nonesuch.qbk] [include promote.qbk] [include rank.qbk] diff --git a/include/boost/type_traits/detail/detector.hpp b/include/boost/type_traits/detail/detector.hpp new file mode 100644 index 0000000..12e6fd7 --- /dev/null +++ b/include/boost/type_traits/detail/detector.hpp @@ -0,0 +1,35 @@ +/* +Copyright 2017-2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_TT_DETAIL_DETECTOR_HPP_INCLUDED +#define BOOST_TT_DETAIL_DETECTOR_HPP_INCLUDED + +#include +#include + +namespace boost { +namespace detail { + +template class, class...> +struct detector { + using value_t = boost::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector >::type, Op, + Args...> { + using value_t = boost::true_type; + using type = Op; +}; + +} /* detail */ +} /* boost */ + +#endif diff --git a/include/boost/type_traits/detected.hpp b/include/boost/type_traits/detected.hpp new file mode 100644 index 0000000..f9a4d85 --- /dev/null +++ b/include/boost/type_traits/detected.hpp @@ -0,0 +1,24 @@ +/* +Copyright 2017-2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_TT_DETECTED_HPP_INCLUDED +#define BOOST_TT_DETECTED_HPP_INCLUDED + +#include +#include + +namespace boost { + +template class Op, class... Args> +using detected_t = typename + detail::detector::type; + +} /* boost */ + +#endif diff --git a/include/boost/type_traits/detected_or.hpp b/include/boost/type_traits/detected_or.hpp new file mode 100644 index 0000000..676ac06 --- /dev/null +++ b/include/boost/type_traits/detected_or.hpp @@ -0,0 +1,25 @@ +/* +Copyright 2017-2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_TT_DETECTED_OR_HPP_INCLUDED +#define BOOST_TT_DETECTED_OR_HPP_INCLUDED + +#include + +namespace boost { + +template class Op, class... Args> +using detected_or = detail::detector; + +template class Op, class... Args> +using detected_or_t = typename detected_or::type; + +} /* boost */ + +#endif diff --git a/include/boost/type_traits/is_detected.hpp b/include/boost/type_traits/is_detected.hpp new file mode 100644 index 0000000..8bff9d9 --- /dev/null +++ b/include/boost/type_traits/is_detected.hpp @@ -0,0 +1,29 @@ +/* +Copyright 2017-2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_TT_IS_DETECTED_HPP_INCLUDED +#define BOOST_TT_IS_DETECTED_HPP_INCLUDED + +#include +#include + +namespace boost { + +template class Op, class... Args> +using is_detected = typename + detail::detector::value_t; + +#if !defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) +template class Op, class... Args> +constexpr bool is_detected_v = is_detected::value; +#endif + +} /* boost */ + +#endif diff --git a/include/boost/type_traits/is_detected_convertible.hpp b/include/boost/type_traits/is_detected_convertible.hpp new file mode 100644 index 0000000..8a6d82f --- /dev/null +++ b/include/boost/type_traits/is_detected_convertible.hpp @@ -0,0 +1,29 @@ +/* +Copyright 2017-2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_TT_IS_DETECTED_CONVERTIBLE_HPP_INCLUDED +#define BOOST_TT_IS_DETECTED_CONVERTIBLE_HPP_INCLUDED + +#include +#include + +namespace boost { + +template class Op, class... Args> +using is_detected_convertible = is_convertible, To>; + +#if !defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) +template class Op, class... Args> +constexpr bool is_detected_convertible_v = is_detected_convertible::value; +#endif + +} /* boost */ + +#endif diff --git a/include/boost/type_traits/is_detected_exact.hpp b/include/boost/type_traits/is_detected_exact.hpp new file mode 100644 index 0000000..1a9b045 --- /dev/null +++ b/include/boost/type_traits/is_detected_exact.hpp @@ -0,0 +1,29 @@ +/* +Copyright 2017-2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_TT_IS_DETECTED_EXACT_HPP_INCLUDED +#define BOOST_TT_IS_DETECTED_EXACT_HPP_INCLUDED + +#include +#include + +namespace boost { + +template class Op, class... Args> +using is_detected_exact = is_same >; + +#if !defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) +template class Op, class... Args> +constexpr bool is_detected_exact_v = is_detected_exact::value; +#endif + +} /* boost */ + +#endif diff --git a/include/boost/type_traits/nonesuch.hpp b/include/boost/type_traits/nonesuch.hpp new file mode 100644 index 0000000..85466b4 --- /dev/null +++ b/include/boost/type_traits/nonesuch.hpp @@ -0,0 +1,35 @@ +/* +Copyright 2017 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_TT_NONESUCH_HPP_INCLUDED +#define BOOST_TT_NONESUCH_HPP_INCLUDED + +#include + +namespace boost { + +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +struct nonesuch { + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(const nonesuch&) = delete; + void operator=(const nonesuch&) = delete; +}; +#else +class nonesuch { + nonesuch(); + ~nonesuch(); + nonesuch(const nonesuch&); + void operator=(const nonesuch&); +}; +#endif + +} /* boost */ + +#endif diff --git a/test/detected_or_test.cpp b/test/detected_or_test.cpp new file mode 100644 index 0000000..d737b40 --- /dev/null +++ b/test/detected_or_test.cpp @@ -0,0 +1,50 @@ +/* +Copyright 2017 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +#ifdef TEST_STD +#include +#else +#include +#endif +#include "check_integral_constant.hpp" +#include "check_type.hpp" + +#define CHECK_FALSE(e) BOOST_CHECK_INTEGRAL_CONSTANT(e, false) +#define CHECK_TRUE(e) BOOST_CHECK_INTEGRAL_CONSTANT(e, true) + +template +using type_t = typename T::type; + +struct has_type { + using type = char; +}; + +struct no_type { }; + +TT_TEST_BEGIN(detected_or) + +CHECK_FALSE((::tt::detected_or::value_t::value)); +CHECK_TRUE((::tt::detected_or::value_t::value)); +CHECK_FALSE((::tt::detected_or::value_t::value)); +BOOST_CHECK_TYPE4(::tt::detected_or::type, bool); +BOOST_CHECK_TYPE4(::tt::detected_or::type, char); +BOOST_CHECK_TYPE4(::tt::detected_or::type, bool); +BOOST_CHECK_TYPE4(::tt::detected_or_t, bool); +BOOST_CHECK_TYPE4(::tt::detected_or_t, char); +BOOST_CHECK_TYPE4(::tt::detected_or_t, bool); + +TT_TEST_END +#else +int main() +{ + return 0; +} +#endif diff --git a/test/detected_test.cpp b/test/detected_test.cpp new file mode 100644 index 0000000..6eee462 --- /dev/null +++ b/test/detected_test.cpp @@ -0,0 +1,44 @@ +/* +Copyright 2017 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +#ifdef TEST_STD +#include +#else +#include +#endif +#include "check_integral_constant.hpp" +#include "check_type.hpp" + +#define CHECK_FALSE(e) BOOST_CHECK_INTEGRAL_CONSTANT(e, false) +#define CHECK_TRUE(e) BOOST_CHECK_INTEGRAL_CONSTANT(e, true) + +template +using type_t = typename T::type; + +struct has_type { + using type = char; +}; + +struct no_type { }; + +TT_TEST_BEGIN(detected) + +BOOST_CHECK_TYPE3(::tt::detected_t, boost::nonesuch); +BOOST_CHECK_TYPE3(::tt::detected_t, char); +BOOST_CHECK_TYPE3(::tt::detected_t, boost::nonesuch); + +TT_TEST_END +#else +int main() +{ + return 0; +} +#endif diff --git a/test/is_detected_convertible.cpp b/test/is_detected_convertible.cpp new file mode 100644 index 0000000..c98e273 --- /dev/null +++ b/test/is_detected_convertible.cpp @@ -0,0 +1,49 @@ +/* +Copyright 2017-2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +#ifdef TEST_STD +#include +#else +#include +#endif +#include "check_integral_constant.hpp" +#include "check_type.hpp" + +#define CHECK_FALSE(e) BOOST_CHECK_INTEGRAL_CONSTANT(e, false) +#define CHECK_TRUE(e) BOOST_CHECK_INTEGRAL_CONSTANT(e, true) + +template +using type_t = typename T::type; + +struct has_type { + using type = char; +}; + +struct no_type { }; + +TT_TEST_BEGIN(is_detected_convertible) + +CHECK_FALSE((::tt::is_detected_convertible::value)); +CHECK_TRUE((::tt::is_detected_convertible::value)); +CHECK_FALSE((::tt::is_detected_convertible::value)); +#ifndef BOOST_NO_CXX14_VARIABLE_TEMPLATES +CHECK_FALSE((::tt::is_detected_convertible_v)); +CHECK_TRUE((::tt::is_detected_convertible_v)); +CHECK_FALSE((::tt::is_detected_convertible_v)); +#endif + +TT_TEST_END +#else +int main() +{ + return 0; +} +#endif diff --git a/test/is_detected_exact_test.cpp b/test/is_detected_exact_test.cpp new file mode 100644 index 0000000..4b1a071 --- /dev/null +++ b/test/is_detected_exact_test.cpp @@ -0,0 +1,49 @@ +/* +Copyright 2017-2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +#ifdef TEST_STD +#include +#else +#include +#endif +#include "check_integral_constant.hpp" +#include "check_type.hpp" + +#define CHECK_FALSE(e) BOOST_CHECK_INTEGRAL_CONSTANT(e, false) +#define CHECK_TRUE(e) BOOST_CHECK_INTEGRAL_CONSTANT(e, true) + +template +using type_t = typename T::type; + +struct has_type { + using type = char; +}; + +struct no_type { }; + +TT_TEST_BEGIN(is_detected_exact) + +CHECK_FALSE((::tt::is_detected_exact::value)); +CHECK_TRUE((::tt::is_detected_exact::value)); +CHECK_FALSE((::tt::is_detected_exact::value)); +#ifndef BOOST_NO_CXX14_VARIABLE_TEMPLATES +CHECK_FALSE((::tt::is_detected_exact_v)); +CHECK_TRUE((::tt::is_detected_exact_v)); +CHECK_FALSE((::tt::is_detected_exact_v)); +#endif + +TT_TEST_END +#else +int main() +{ + return 0; +} +#endif diff --git a/test/is_detected_test.cpp b/test/is_detected_test.cpp new file mode 100644 index 0000000..a58987b --- /dev/null +++ b/test/is_detected_test.cpp @@ -0,0 +1,49 @@ +/* +Copyright 2017-2018 Glen Joseph Fernandes + + +Distributed under the Boost Software License, +Version 1.0. (See accompanying file LICENSE_1_0.txt +or copy at http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +#ifdef TEST_STD +#include +#else +#include +#endif +#include "check_integral_constant.hpp" +#include "check_type.hpp" + +#define CHECK_FALSE(e) BOOST_CHECK_INTEGRAL_CONSTANT(e, false) +#define CHECK_TRUE(e) BOOST_CHECK_INTEGRAL_CONSTANT(e, true) + +template +using type_t = typename T::type; + +struct has_type { + using type = char; +}; + +struct no_type { }; + +TT_TEST_BEGIN(is_detected) + +CHECK_FALSE((::tt::is_detected::value)); +CHECK_TRUE((::tt::is_detected::value)); +CHECK_FALSE((::tt::is_detected::value)); +#ifndef BOOST_NO_CXX14_VARIABLE_TEMPLATES +CHECK_FALSE((::tt::is_detected_v)); +CHECK_TRUE((::tt::is_detected_v)); +CHECK_FALSE((::tt::is_detected_v)); +#endif + +TT_TEST_END +#else +int main() +{ + return 0; +} +#endif