From ced4870cb0d3ba183e4b17edf94bbb60c8a73629 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 15 Jul 2017 23:03:38 +0300 Subject: [PATCH 1/4] Add is_list_constructible --- doc/is_list_constructible.qbk | 23 +++++ doc/type_traits.qbk | 2 + doc/value_traits.qbk | 3 + include/boost/type_traits.hpp | 1 + .../type_traits/is_list_constructible.hpp | 41 ++++++++ test/is_list_constructible_test.cpp | 95 +++++++++++++++++++ 6 files changed, 165 insertions(+) create mode 100644 doc/is_list_constructible.qbk create mode 100644 include/boost/type_traits/is_list_constructible.hpp create mode 100644 test/is_list_constructible_test.cpp diff --git a/doc/is_list_constructible.qbk b/doc/is_list_constructible.qbk new file mode 100644 index 0000000..733d2e8 --- /dev/null +++ b/doc/is_list_constructible.qbk @@ -0,0 +1,23 @@ +[/ + Copyright 2017 Peter Dimov + + 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_list_constructible is_list_constructible] + + template + struct is_list_constructible : public __tof {}; + +__inherit If `T` can be constructed from `Args` using list initialization +(`T{declval()...}`), then inherits from __true_type, otherwise inherits from +__false_type. `T` must be a complete type. + +__compat This trait requires C++11. + +__header ` #include ` or ` #include ` + +[endsect] diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index 1a1fa5b..0c917e1 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -72,6 +72,7 @@ [def __is_copy_constructible [link boost_typetraits.reference.is_copy_constructible is_copy_constructible]] [def __is_copy_assignable [link boost_typetraits.reference.is_copy_assignable is_copy_assignable]] [def __is_constructible [link boost_typetraits.reference.is_constructible is_constructible]] +[def __is_list_constructible [link boost_typetraits.reference.is_list_constructible is_list_constructible]] [def __is_default_constructible [link boost_typetraits.reference.is_default_constructible is_default_constructible]] [def __is_destructible [link boost_typetraits.reference.is_destructible is_destructible]] [def __is_volatile [link boost_typetraits.reference.is_volatile is_volatile]] @@ -294,6 +295,7 @@ See __has_trivial_constructor. [include is_function.qbk] [include is_fundamental.qbk] [include is_integral.qbk] +[include is_list_constructible.qbk] [include is_lvalue_reference.qbk] [include is_member_function_pointer.qbk] [include is_member_object_pointer.qbk] diff --git a/doc/value_traits.qbk b/doc/value_traits.qbk index 5f667aa..f8ff399 100644 --- a/doc/value_traits.qbk +++ b/doc/value_traits.qbk @@ -168,6 +168,9 @@ The following templates describe the general properties of a type. template struct __is_default_constructible; + template + struct __is_list_constructible; + template struct __is_destructible; diff --git a/include/boost/type_traits.hpp b/include/boost/type_traits.hpp index dbc8c95..e5810b4 100644 --- a/include/boost/type_traits.hpp +++ b/include/boost/type_traits.hpp @@ -107,6 +107,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/type_traits/is_list_constructible.hpp b/include/boost/type_traits/is_list_constructible.hpp new file mode 100644 index 0000000..518a75b --- /dev/null +++ b/include/boost/type_traits/is_list_constructible.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_TYPE_TRAITS_IS_LIST_CONSTRUCTIBLE_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_IS_LIST_CONSTRUCTIBLE_HPP_INCLUDED + +// Copyright 2017 Peter Dimov +// +// 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 +#include +#include + +namespace boost +{ + +#if defined(BOOST_NO_SFINAE_EXPR) || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) || defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) + +template struct is_list_constructible: false_type +{ +}; + +#else + +namespace type_traits_detail +{ + +template()...} )> true_type is_list_constructible_impl( int ); +template false_type is_list_constructible_impl( ... ); + +} // namespace type_traits_detail + +template struct is_list_constructible: decltype( type_traits_detail::is_list_constructible_impl(0) ) +{ +}; + +#endif + +} // namespace boost + +#endif // #ifndef BOOST_TYPE_TRAITS_IS_LIST_CONSTRUCTIBLE_HPP_INCLUDED diff --git a/test/is_list_constructible_test.cpp b/test/is_list_constructible_test.cpp new file mode 100644 index 0000000..d659196 --- /dev/null +++ b/test/is_list_constructible_test.cpp @@ -0,0 +1,95 @@ + +// Copyright 2017 Peter Dimov +// +// 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 + +#if defined( __GNUC__ ) && (__GNUC__ >= 7) +#pragma GCC diagnostic ignored "-Wnarrowing" +#endif + +#ifdef TEST_STD +# include +#else +# include +#endif +#include "test.hpp" +#include "check_integral_constant.hpp" + +#if defined(BOOST_NO_SFINAE_EXPR) || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE) \ + || defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) || defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) + +int main() {} + +#else + +#include + +struct X +{ + int a; + int b; +}; + +struct Y +{ + Y( int = 0, int = 0 ); +}; + +struct Z +{ + explicit Z( int = 0, int = 0 ); +}; + +struct V +{ + V( int&, int& ); +}; + +TT_TEST_BEGIN(is_list_constructible) + +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); + +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); + +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); + +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); + +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); + +TT_TEST_END + +#endif From d5be3746a1eb202663cb8264ab2d4769f6fe9d12 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Jul 2017 01:20:50 +0300 Subject: [PATCH 2/4] Suppress warnings on g++ 4.x --- test/is_list_constructible_test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/is_list_constructible_test.cpp b/test/is_list_constructible_test.cpp index d659196..2e7ee62 100644 --- a/test/is_list_constructible_test.cpp +++ b/test/is_list_constructible_test.cpp @@ -5,8 +5,9 @@ // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt -#if defined( __GNUC__ ) && (__GNUC__ >= 7) +#if defined( __GNUC__ ) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 407) #pragma GCC diagnostic ignored "-Wnarrowing" +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" #endif #ifdef TEST_STD From a3bef3752cf823917b36dfcf4a9a3316f5435bc2 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Jul 2017 01:44:06 +0300 Subject: [PATCH 3/4] Disable failures caused by g++-7 -std=c++17 bug --- test/is_list_constructible_test.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/is_list_constructible_test.cpp b/test/is_list_constructible_test.cpp index 2e7ee62..455da09 100644 --- a/test/is_list_constructible_test.cpp +++ b/test/is_list_constructible_test.cpp @@ -72,8 +72,13 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value) BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); + +#if defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(__GNUC__) && (__GNUC__ == 7) && (__cplusplus >= 201500) +// g++ 7.1 in -std=c++1z, c++17 has a bug +#else BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +#endif BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); @@ -81,8 +86,13 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value) BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); + +#if defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(__GNUC__) && (__GNUC__ == 7) && (__cplusplus >= 201500) +// -"- +#else BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +#endif BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); From aa2158f97b309d656533a5087d67559b0afaa2a2 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Jul 2017 02:29:40 +0300 Subject: [PATCH 4/4] Define CI_SUPPRESS_KNOWN_ISSUES on Travis, suppress known g++-4 issues --- .travis.yml | 2 +- test/is_list_constructible_test.cpp | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index f469d33..0764781 100644 --- a/.travis.yml +++ b/.travis.yml @@ -584,7 +584,7 @@ script: - |- echo "using $TOOLSET : : $COMPILER : -std=$CXXSTD ;" > ~/user-config.jam - (cd libs/config/test && ../../../b2 config_info_travis_install toolset=$TOOLSET && ./config_info_travis) - - ./b2 -j3 libs/type_traits/test toolset=$TOOLSET + - ./b2 -j3 libs/type_traits/test toolset=$TOOLSET define=CI_SUPPRESS_KNOWN_ISSUES notifications: email: diff --git a/test/is_list_constructible_test.cpp b/test/is_list_constructible_test.cpp index 455da09..bbf1d59 100644 --- a/test/is_list_constructible_test.cpp +++ b/test/is_list_constructible_test.cpp @@ -55,7 +55,12 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), tr BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); + +#if defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(__GNUC__) && (__GNUC__ == 4) +// g++ 4.x doesn't seem to disallow narrowing +#else BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +#endif BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); @@ -63,8 +68,13 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value) BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); + +#if defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(__GNUC__) && (__GNUC__ == 4) +// g++ 4.x doesn't seem to disallow narrowing +#else BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); +#endif BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); @@ -73,7 +83,9 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); -#if defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(__GNUC__) && (__GNUC__ == 7) && (__cplusplus >= 201500) +#if defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(__GNUC__) && (__GNUC__ == 4) +// g++ 4.x doesn't seem to disallow narrowing +#elif defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(__GNUC__) && (__GNUC__ == 7) && (__cplusplus >= 201500) // g++ 7.1 in -std=c++1z, c++17 has a bug #else BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); @@ -87,8 +99,10 @@ BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), true); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); -#if defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(__GNUC__) && (__GNUC__ == 7) && (__cplusplus >= 201500) -// -"- +#if defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(__GNUC__) && (__GNUC__ == 4) +// g++ 4.x doesn't seem to disallow narrowing +#elif defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(__GNUC__) && (__GNUC__ == 7) && (__cplusplus >= 201500) +// g++ 7.1 in -std=c++1z, c++17 has a bug #else BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_list_constructible::value), false);