From f8e9879d4e9c81fef30ee09b744907e75e5d1440 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 31 May 2020 02:47:41 -0400 Subject: [PATCH 1/3] Implement conjunction, disjunction, negation --- doc/conjunction.qbk | 36 ++++++++++++++++++++ doc/disjunction.qbk | 36 ++++++++++++++++++++ doc/negation.qbk | 35 ++++++++++++++++++++ doc/type_traits.qbk | 6 ++++ include/boost/type_traits.hpp | 3 ++ include/boost/type_traits/conjunction.hpp | 40 +++++++++++++++++++++++ include/boost/type_traits/disjunction.hpp | 40 +++++++++++++++++++++++ include/boost/type_traits/negation.hpp | 23 +++++++++++++ test/conjunction_test.cpp | 35 ++++++++++++++++++++ test/disjunction_test.cpp | 35 ++++++++++++++++++++ test/negation_test.cpp | 26 +++++++++++++++ 11 files changed, 315 insertions(+) create mode 100644 doc/conjunction.qbk create mode 100644 doc/disjunction.qbk create mode 100644 doc/negation.qbk create mode 100644 include/boost/type_traits/conjunction.hpp create mode 100644 include/boost/type_traits/disjunction.hpp create mode 100644 include/boost/type_traits/negation.hpp create mode 100644 test/conjunction_test.cpp create mode 100644 test/disjunction_test.cpp create mode 100644 test/negation_test.cpp diff --git a/doc/conjunction.qbk b/doc/conjunction.qbk new file mode 100644 index 0000000..668ec3f --- /dev/null +++ b/doc/conjunction.qbk @@ -0,0 +1,36 @@ +[/ +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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:conjunction conjunction] + + template + struct conjunction; + +__inherit Inherits from the first type `U` in the list for which +`bool(U::value)` is `false`, or the last type in the list if there is no such +type. If `sizeof...(T)` is `0` then inherits from `__true_type`. + +__header `#include ` + +[all_compilers] In the absence of variadic-template support, `conjunction` has +only 2 parameters. + +__examples + +[:Given: `template struct Int { static const int value = N };` ] + +[:`conjunction<>` inherits from `__true_type`.] + +[:`conjunction >` inherits from `Int<1>`.] + +[:`conjunction, Int<2>, Int<3> >` inherits from `Int<3>`.] + +[:`conjunction, Int<0>, Int<3> >` inherits from `Int<0>`.] + +[endsect] diff --git a/doc/disjunction.qbk b/doc/disjunction.qbk new file mode 100644 index 0000000..bbaf7a1 --- /dev/null +++ b/doc/disjunction.qbk @@ -0,0 +1,36 @@ +[/ +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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:disjunction disjunction] + + template + struct disjunction; + +__inherit Inherits from the first type `U` in the list for which +`bool(U::value)` is `true`, or the last type in the list if there is no such +type. If `sizeof...(T)` is `0` then inherits from `__false_type`. + +__header `#include ` + +[all_compilers] In the absence of variadic-template support, `disjunction` has +only 2 parameters. + +__examples + +[:Given: `template struct Int { static const int value = N };` ] + +[:`disjunction<>` inherits from `__false_type`.] + +[:`disjunction >` inherits from `Int<1>`.] + +[:`disjunction, Int<2>, Int<3> >` inherits from `Int<1>`.] + +[:`disjunction, Int<2>, Int<3> >` inherits from `Int<2>`.] + +[endsect] diff --git a/doc/negation.qbk b/doc/negation.qbk new file mode 100644 index 0000000..0bf5501 --- /dev/null +++ b/doc/negation.qbk @@ -0,0 +1,35 @@ +[/ +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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:negation negation] + + template + struct negation + : public __integral_constant { }; + +__inherit Inherits from `__integral_constant`. + +__header `#include ` + +[all_compilers] + +__examples + +[:`negation<__true_type>` inherits from `__false_type`.] + +[:`negation<__false_type>` inherits from `__true_type`.] + +[:`negation<__integral_constant >::type` is the type `__false_type`.] + +[:`negation<__integral_constant >::value` is an integral constant +expression that evaluates to /true/.] + +[:`negation::value_type` is the type `bool`.] + +[endsect] diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index ce3f1d4..b67ed55 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -129,6 +129,9 @@ [def __add_cv [link boost_typetraits.reference.add_cv add_cv]] [def __common_type [link boost_typetraits.reference.common_type common_type]] [def __conditional [link boost_typetraits.reference.conditional conditional]] +[def __conjunction [link boost_typetraits.reference.conjunction conjunction]] +[def __disjunction [link boost_typetraits.reference.disjunction disjunction]] +[def __negation [link boost_typetraits.reference.negation negation]] [def __type_with_alignment [link boost_typetraits.reference.type_with_alignment type_with_alignment]] [def __aligned_storage [link boost_typetraits.reference.aligned_storage aligned_storage]] @@ -307,6 +310,7 @@ that is the result of the transformation. [include aligned_storage.qbk] [include alignment_of.qbk] [include conditional.qbk] +[include conjunction.qbk] [include common_type.qbk] [include copy_cv.qbk] [include copy_cv_ref.qbk] @@ -315,6 +319,7 @@ that is the result of the transformation. [include declval.qbk] [include detected.qbk] [include detected_or.qbk] +[include disjunction.qbk] [include enable_if.qbk] [include extent.qbk] [include floating_point_promotion.qbk] @@ -441,6 +446,7 @@ See __has_trivial_constructor. [include make_signed.qbk] [include make_unsigned.qbk] [include make_void.qbk] +[include negation.qbk] [include nonesuch.qbk] [include promote.qbk] diff --git a/include/boost/type_traits.hpp b/include/boost/type_traits.hpp index 8e55bc5..052cf00 100644 --- a/include/boost/type_traits.hpp +++ b/include/boost/type_traits.hpp @@ -21,11 +21,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -136,6 +138,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/type_traits/conjunction.hpp b/include/boost/type_traits/conjunction.hpp new file mode 100644 index 0000000..aa5440b --- /dev/null +++ b/include/boost/type_traits/conjunction.hpp @@ -0,0 +1,40 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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_CONJUNCTION_HPP_INCLUDED +#define BOOST_TT_CONJUNCTION_HPP_INCLUDED + +#include +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif + +namespace boost { + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +struct conjunction + : true_type { }; + +template +struct conjunction + : T { }; + +template +struct conjunction + : conditional, T>::type { }; +#else +template +struct conjunction + : conditional::type { }; +#endif + +} /* boost */ + +#endif diff --git a/include/boost/type_traits/disjunction.hpp b/include/boost/type_traits/disjunction.hpp new file mode 100644 index 0000000..dd06991 --- /dev/null +++ b/include/boost/type_traits/disjunction.hpp @@ -0,0 +1,40 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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_DISJUNCTION_HPP_INCLUDED +#define BOOST_TT_DISJUNCTION_HPP_INCLUDED + +#include +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif + +namespace boost { + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +struct disjunction + : false_type { }; + +template +struct disjunction + : T { }; + +template +struct disjunction + : conditional >::type { }; +#else +template +struct disjunction + : conditional::type { }; +#endif + +} /* boost */ + +#endif diff --git a/include/boost/type_traits/negation.hpp b/include/boost/type_traits/negation.hpp new file mode 100644 index 0000000..939e7a7 --- /dev/null +++ b/include/boost/type_traits/negation.hpp @@ -0,0 +1,23 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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_NEGATION_HPP_INCLUDED +#define BOOST_TT_NEGATION_HPP_INCLUDED + +#include + +namespace boost { + +template +struct negation + : integral_constant { }; + +} /* boost */ + +#endif diff --git a/test/conjunction_test.cpp b/test/conjunction_test.cpp new file mode 100644 index 0000000..246f1c6 --- /dev/null +++ b/test/conjunction_test.cpp @@ -0,0 +1,35 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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) +*/ +#ifdef TEST_STD +#include +#else +#include +#endif +#include "check_integral_constant.hpp" + +template +struct Int { + static const int value = V; +}; + +TT_TEST_BEGIN(conjunction) + +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::conjunction, Int<4> >::value), 4); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::conjunction, Int<4> >::value), 0); + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::conjunction, Int<4>, Int<6>, + Int<8>, Int<10> >::value), 10); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::conjunction, Int<0>, Int<4>, + Int<6>, Int<8> >::value), 0); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::conjunction >::value, 4); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::conjunction<>::value, true); +#endif + +TT_TEST_END diff --git a/test/disjunction_test.cpp b/test/disjunction_test.cpp new file mode 100644 index 0000000..56b3416 --- /dev/null +++ b/test/disjunction_test.cpp @@ -0,0 +1,35 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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) +*/ +#ifdef TEST_STD +#include +#else +#include +#endif +#include "check_integral_constant.hpp" + +template +struct Int { + static const int value = V; +}; + +TT_TEST_BEGIN(disjunction) + +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::disjunction, Int<4> >::value), 2); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::disjunction, Int<4> >::value), 4); + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::disjunction, Int<4>, Int<6>, + Int<8>, Int<10> >::value), 2); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::disjunction, Int<0>, Int<6>, + Int<0>, Int<0> >::value), 6); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::disjunction >::value, 4); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::disjunction<>::value, false); +#endif + +TT_TEST_END diff --git a/test/negation_test.cpp b/test/negation_test.cpp new file mode 100644 index 0000000..604b7fe --- /dev/null +++ b/test/negation_test.cpp @@ -0,0 +1,26 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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) +*/ +#ifdef TEST_STD +#include +#else +#include +#endif +#include "check_integral_constant.hpp" + +template +struct Int { + static const int value = V; +}; + +TT_TEST_BEGIN(negation) + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::negation >::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::negation >::value, true); + +TT_TEST_END From 7a071a5918d2b16b0b03ebe16c85cb5886172fa7 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 31 May 2020 02:49:03 -0400 Subject: [PATCH 2/3] Implement is_scoped_enum and is_unscoped_enum --- doc/is_scoped_enum.qbk | 45 +++++++++++++++++++ doc/is_unscoped_enum.qbk | 45 +++++++++++++++++++ doc/type_traits.qbk | 4 ++ include/boost/type_traits.hpp | 2 + include/boost/type_traits/is_scoped_enum.hpp | 26 +++++++++++ .../boost/type_traits/is_unscoped_enum.hpp | 25 +++++++++++ test/is_scoped_enum_test.cpp | 36 +++++++++++++++ test/is_unscoped_enum_test.cpp | 36 +++++++++++++++ 8 files changed, 219 insertions(+) create mode 100644 doc/is_scoped_enum.qbk create mode 100644 doc/is_unscoped_enum.qbk create mode 100644 include/boost/type_traits/is_scoped_enum.hpp create mode 100644 include/boost/type_traits/is_unscoped_enum.hpp create mode 100644 test/is_scoped_enum_test.cpp create mode 100644 test/is_unscoped_enum_test.cpp diff --git a/doc/is_scoped_enum.qbk b/doc/is_scoped_enum.qbk new file mode 100644 index 0000000..911a33d --- /dev/null +++ b/doc/is_scoped_enum.qbk @@ -0,0 +1,45 @@ +[/ +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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_scoped_enum is_scoped_enum] + + template + struct is_scoped_enum + : __tof { }; + +__inherit If T is a (possibly cv-qualified) scoped enumeration type +(`enum class` but not `enum`), then inherits from __true_type, otherwise +inherits from __false_type. + +__header `#include ` + +[all_compilers] + +__examples + +[:Given: `enum class color { red, blue };` and `enum fruit { apple, orange };`] + +[:`is_scoped_enum` inherits from `__true_type`.] + +[:`is_scoped_enum` inherits from `__false_type`.] + +[:`is_scoped_enum::type` is the type `__true_type`.] + +[:`is_scoped_enum::value` is an integral constant expression that +evaluates to /true/.] + +[:`is_scoped_enum::value` is an integral constant expression that +evaluates to /false/.] + +[:`is_scoped_enum::value` is an integral constant expression that +evaluates to /false/.] + +[:`is_scoped_enum::value_type` is the type `bool`.] + +[endsect] diff --git a/doc/is_unscoped_enum.qbk b/doc/is_unscoped_enum.qbk new file mode 100644 index 0000000..39b32e1 --- /dev/null +++ b/doc/is_unscoped_enum.qbk @@ -0,0 +1,45 @@ +[/ +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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_unscoped_enum is_unscoped_enum] + + template + struct is_unscoped_enum + : __tof { }; + +__inherit If T is a (possibly cv-qualified) unscoped enumeration type +(`enum` but not `enum class`), then inherits from __true_type, otherwise +inherits from __false_type. + +__header `#include ` + +[all_compilers] + +__examples + +[:Given: `enum color { red, blue };` and `enum class fruit { apple, orange };`] + +[:`is_unscoped_enum` inherits from `__true_type`.] + +[:`is_unscoped_enum` inherits from `__false_type`.] + +[:`is_unscoped_enum::type` is the type `__true_type`.] + +[:`is_unscoped_enum::value` is an integral constant expression that +evaluates to /true/.] + +[:`is_unscoped_enum::value` is an integral constant expression that +evaluates to /false/.] + +[:`is_unscoped_enum::value` is an integral constant expression that +evaluates to /false/.] + +[:`is_unscoped_enum::value_type` is the type `bool`.] + +[endsect] diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index b67ed55..26b1d74 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -55,6 +55,8 @@ [def __is_unbounded_array [link boost_typetraits.reference.is_unbounded_array is_unbounded_array]] [def __is_union [link boost_typetraits.reference.is_union is_union]] [def __is_class [link boost_typetraits.reference.is_class is_class]] +[def __is_scoped_enum [link boost_typetraits.reference.is_scoped_enum is_scoped_enum]] +[def __is_unscoped_enum [link boost_typetraits.reference.is_unscoped_enum is_unscoped_enum]] [def __is_enum [link boost_typetraits.reference.is_enum is_enum]] [def __is_enum [link boost_typetraits.reference.is_enum is_enum]] [def __is_function [link boost_typetraits.reference.is_function is_function]] @@ -434,10 +436,12 @@ See __has_trivial_constructor. [include is_rvalue_reference.qbk] [include is_same.qbk] [include is_scalar.qbk] +[include is_scoped_enum.qbk] [include is_signed.qbk] [include is_stateless.qbk] [include is_unbounded_array.qbk] [include is_union.qbk] +[include is_unscoped_enum.qbk] [include is_unsigned.qbk] [include is_virtual_base_of.qbk] [include is_void.qbk] diff --git a/include/boost/type_traits.hpp b/include/boost/type_traits.hpp index 052cf00..008d8b6 100644 --- a/include/boost/type_traits.hpp +++ b/include/boost/type_traits.hpp @@ -128,9 +128,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include diff --git a/include/boost/type_traits/is_scoped_enum.hpp b/include/boost/type_traits/is_scoped_enum.hpp new file mode 100644 index 0000000..7566859 --- /dev/null +++ b/include/boost/type_traits/is_scoped_enum.hpp @@ -0,0 +1,26 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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_SCOPED_ENUM_HPP_INCLUDED +#define BOOST_TT_IS_SCOPED_ENUM_HPP_INCLUDED + +#include +#include +#include +#include + +namespace boost { + +template +struct is_scoped_enum + : conjunction, negation > >::type { }; + +} /* boost */ + +#endif diff --git a/include/boost/type_traits/is_unscoped_enum.hpp b/include/boost/type_traits/is_unscoped_enum.hpp new file mode 100644 index 0000000..99f9acb --- /dev/null +++ b/include/boost/type_traits/is_unscoped_enum.hpp @@ -0,0 +1,25 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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_UNSCOPED_ENUM_HPP_INCLUDED +#define BOOST_TT_IS_UNSCOPED_ENUM_HPP_INCLUDED + +#include +#include +#include + +namespace boost { + +template +struct is_unscoped_enum + : conjunction, is_convertible >::type { }; + +} /* boost */ + +#endif diff --git a/test/is_scoped_enum_test.cpp b/test/is_scoped_enum_test.cpp new file mode 100644 index 0000000..df52ead --- /dev/null +++ b/test/is_scoped_enum_test.cpp @@ -0,0 +1,36 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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) +*/ +#ifdef TEST_STD +#include +#else +#include +#endif +#include "check_integral_constant.hpp" + +enum Unscoped { + Constant = 1 +}; + +#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS) +enum class Scoped { + Constant = 2 +}; +#endif + +TT_TEST_BEGIN(is_scoped_enum) + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_scoped_enum::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_scoped_enum::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_scoped_enum::value, false); + +#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS) +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_scoped_enum::value, true); +#endif + +TT_TEST_END diff --git a/test/is_unscoped_enum_test.cpp b/test/is_unscoped_enum_test.cpp new file mode 100644 index 0000000..5499e32 --- /dev/null +++ b/test/is_unscoped_enum_test.cpp @@ -0,0 +1,36 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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) +*/ +#ifdef TEST_STD +#include +#else +#include +#endif +#include "check_integral_constant.hpp" + +enum Unscoped { + Constant = 1 +}; + +#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS) +enum class Scoped { + Constant = 2 +}; +#endif + +TT_TEST_BEGIN(is_unscoped_enum) + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_unscoped_enum::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_unscoped_enum::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_unscoped_enum::value, true); + +#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS) +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_unscoped_enum::value, false); +#endif + +TT_TEST_END From f7f7dbf16e89ac97d51eca3fa1f96dd1e151419e Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 31 May 2020 02:49:24 -0400 Subject: [PATCH 3/3] Implement is_trivially_copyable --- doc/is_trivially_copyable.qbk | 40 ++++ doc/type_traits.qbk | 4 +- include/boost/type_traits.hpp | 1 + .../type_traits/is_trivially_copyable.hpp | 27 +++ test/is_trivially_copyable_test.cpp | 224 ++++++++++++++++++ 5 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 doc/is_trivially_copyable.qbk create mode 100644 include/boost/type_traits/is_trivially_copyable.hpp create mode 100644 test/is_trivially_copyable_test.cpp diff --git a/doc/is_trivially_copyable.qbk b/doc/is_trivially_copyable.qbk new file mode 100644 index 0000000..1257825 --- /dev/null +++ b/doc/is_trivially_copyable.qbk @@ -0,0 +1,40 @@ +[/ +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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_trivially_copyable is_trivially_copyable] + + template + struct is_trivially_copyable + : __tof { }; + +__inherit If T is a (possibly cv-qualified) type that is trivially copyable +then inherits from __true_type, otherwise inherits from __false_type. + +__compat This trait is implemented as the conjunction of `has_trivial_copy`, +`has_trivial_assign`, and `has_trivial_destructor`. + +__header `#include ` + +__examples + +[:`is_trivially_copyable` inherits from `__true_type`.] + +[:`is_trivially_copyable` inherits from `__false_type`.] + +[:`is_trivially_copyable::type` is the type `__true_type`.] + +[:`is_trivially_copyable::value` is an integral constant +expression that evaluates to /true/.] + +[:`is_trivially_copyable::value` is an integral constant expression +that evaluates to /false/.] + +[:`is_trivially_copyable::value_type` is the type `bool`.] + +[endsect] diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index 26b1d74..cdb181c 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -8,7 +8,7 @@ [library Boost.TypeTraits [quickbook 1.5] [copyright 2000 2011 Adobe Systems Inc, David Abrahams, Frederic Bron, - Steve Cleary, Beman Dawes, Aleksey Gurtovoy, Howard Hinnant, Jesse Jones, + Steve Cleary, Beman Dawes, Glen Fernandes, Aleksey Gurtovoy, Howard Hinnant, Jesse Jones, Mat Marcus, Itay Maman, John Maddock, Alexander Nasonov, Thorsten Ottosen, Roman Perepelitsa, Robert Ramey, Jeremy Siek, Robert Stewart and Steven Watanabe] [purpose Meta-programming support library] @@ -87,6 +87,7 @@ [def __is_signed [link boost_typetraits.reference.is_signed is_signed]] [def __is_unsigned [link boost_typetraits.reference.is_unsigned is_unsigned]] [def __has_virtual_destructor [link boost_typetraits.reference.has_virtual_destructor has_virtual_destructor]] +[def __is_trivially_copyable [link boost_typetraits.reference.is_trivially_copyable is_trivially_copyable]] [def __is_pod [link boost_typetraits.reference.is_pod is_pod]] [def __is_final [link boost_typetraits.reference.is_final is_final]] [def __has_trivial_constructor [link boost_typetraits.reference.has_trivial_constructor has_trivial_constructor]] @@ -439,6 +440,7 @@ See __has_trivial_constructor. [include is_scoped_enum.qbk] [include is_signed.qbk] [include is_stateless.qbk] +[include is_trivially_copyable.qbk] [include is_unbounded_array.qbk] [include is_union.qbk] [include is_unscoped_enum.qbk] diff --git a/include/boost/type_traits.hpp b/include/boost/type_traits.hpp index 008d8b6..406fd02 100644 --- a/include/boost/type_traits.hpp +++ b/include/boost/type_traits.hpp @@ -131,6 +131,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/type_traits/is_trivially_copyable.hpp b/include/boost/type_traits/is_trivially_copyable.hpp new file mode 100644 index 0000000..468945e --- /dev/null +++ b/include/boost/type_traits/is_trivially_copyable.hpp @@ -0,0 +1,27 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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_TRIVIALLY_COPYABLE_HPP_INCLUDED +#define BOOST_TT_IS_TRIVIALLY_COPYABLE_HPP_INCLUDED + +#include +#include +#include + +namespace boost { + +template +struct is_trivially_copyable + : integral_constant::value && + has_trivial_assign::value && + has_trivial_destructor::value> { }; + +} /* boost */ + +#endif diff --git a/test/is_trivially_copyable_test.cpp b/test/is_trivially_copyable_test.cpp new file mode 100644 index 0000000..3718e51 --- /dev/null +++ b/test/is_trivially_copyable_test.cpp @@ -0,0 +1,224 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +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) +*/ +#ifdef TEST_STD +#include +#else +#include +#endif +#include "test.hpp" +#include "check_integral_constant.hpp" + +class private_copy { +public: + private_copy(); +private: + private_copy(const private_copy&); +}; + +class private_assign { +public: + private_assign(); +private: + private_assign& operator=(const private_assign&); +}; + +class private_destruct { +public: + private_destruct(); +private: + ~private_destruct(); +}; + +#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS +struct deleted_assign { + deleted_assign(); + deleted_assign& operator=(const deleted_assign&) = delete; +}; + +struct deleted_copy { + deleted_copy() { } + deleted_copy(const deleted_copy&) = delete; + deleted_copy(deleted_copy&&) { } +}; + +struct deleted_destruct { + deleted_destruct(); + ~deleted_destruct() = delete; +}; +#endif + +TT_TEST_BEGIN(is_trivially_copyable) + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#endif +#ifdef BOOST_HAS_LONG_LONG +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable< ::boost::ulong_long_type>::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable< ::boost::long_long_type>::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable< ::boost::ulong_long_type const>::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable< ::boost::long_long_type const>::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable< ::boost::ulong_long_type volatile>::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable< ::boost::long_long_type volatile>::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable< ::boost::ulong_long_type const volatile>::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable< ::boost::long_long_type const volatile>::value, false); +#endif +#endif +#ifdef BOOST_HAS_MS_INT64 +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int8>::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int8 const>::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int8 volatile>::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int8 const volatile>::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int16>::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int16 const>::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int16 volatile>::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int16 const volatile>::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int32>::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int32 const>::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int32 volatile>::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int32 const volatile>::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int64>::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int64 const>::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int64 volatile>::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable<__int64 const volatile>::value, false); +#endif +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#ifndef TEST_STD +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true, false); +BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true, false); +BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true, false); +BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, true, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable >::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable >::value, false); +BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::is_trivially_copyable >::value, true, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable >::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_assign::value, false); +#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_trivially_copyable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_assign::value, false); +#endif + +TT_TEST_END