From 74b5bea140a86e052c572a3e820a735b81d09fb1 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 17 Jul 2014 13:21:19 +0100 Subject: [PATCH 01/12] Partially revert "Fixes for msvc-13." This reverts commit e69dd6740a420473a73231d997cb621072e32230. --- include/boost/type_traits/intrinsics.hpp | 4 ++-- include/boost/type_traits/is_nothrow_move_assignable.hpp | 9 --------- .../boost/type_traits/is_nothrow_move_constructible.hpp | 9 --------- 3 files changed, 2 insertions(+), 20 deletions(-) diff --git a/include/boost/type_traits/intrinsics.hpp b/include/boost/type_traits/intrinsics.hpp index 4bcfd3c..94dbea2 100644 --- a/include/boost/type_traits/intrinsics.hpp +++ b/include/boost/type_traits/intrinsics.hpp @@ -109,8 +109,8 @@ // # define BOOST_ALIGNMENT_OF(T) __alignof(T) # if defined(_MSC_VER) && (_MSC_VER >= 1700) -# define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) ((__has_trivial_move_constructor(T) || ::boost::is_pod::value) && !::boost::is_volatile::value && !::boost::is_reference::value) -# define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) ((__has_trivial_move_assign(T) || ::boost::is_pod::value) && ! ::boost::is_const::value && !::boost::is_volatile::value && !::boost::is_reference::value) +# define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) ((__has_trivial_move_constructor(T) || __is_pod(T)) && !::boost::is_volatile::value && !::boost::is_reference::value) +# define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) ((__has_trivial_move_assign(T) || __is_pod(T)) && ! ::boost::is_const::value && !::boost::is_volatile::value && !::boost::is_reference::value) # endif # define BOOST_HAS_TYPE_TRAITS_INTRINSICS diff --git a/include/boost/type_traits/is_nothrow_move_assignable.hpp b/include/boost/type_traits/is_nothrow_move_assignable.hpp index 9188c6c..5a3427f 100644 --- a/include/boost/type_traits/is_nothrow_move_assignable.hpp +++ b/include/boost/type_traits/is_nothrow_move_assignable.hpp @@ -51,15 +51,6 @@ struct is_nothrow_move_assignable_imp{ >::value)); }; -#ifdef BOOST_NO_NOEXCEPT -// -// The above logic doesn't quite work in the absense of noexcept, -// this is really to improve things with VC13: -// -template -struct is_nothrow_move_assignable_imp{ BOOST_STATIC_CONSTANT(bool, value = false); }; -#endif - #else template diff --git a/include/boost/type_traits/is_nothrow_move_constructible.hpp b/include/boost/type_traits/is_nothrow_move_constructible.hpp index c7218be..bc7fb88 100644 --- a/include/boost/type_traits/is_nothrow_move_constructible.hpp +++ b/include/boost/type_traits/is_nothrow_move_constructible.hpp @@ -66,15 +66,6 @@ struct is_nothrow_move_constructible_imp{ #endif -#ifdef BOOST_NO_NOEXCEPT -// -// The above logic doesn't quite work in the absense of noexcept, -// this is really to improve things with VC13: -// -template -struct is_nothrow_move_constructible_imp{ BOOST_STATIC_CONSTANT(bool, value = false); }; -#endif - } BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_nothrow_move_constructible,T,::boost::detail::is_nothrow_move_constructible_imp::value) From 9b3c90a32015441a4ed316f7b9c265ed44b71a38 Mon Sep 17 00:00:00 2001 From: K-ballo Date: Fri, 18 Jul 2014 21:57:34 -0300 Subject: [PATCH 02/12] Fixed typo varaible -> variable --- .../reference/is_nothrow_move_assignable.html | 4 ++-- .../reference/is_nothrow_move_constructible.html | 2 +- doc/is_nothrow_move_assignable.qbk | 4 ++-- doc/is_nothrow_move_constructible.qbk | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/html/boost_typetraits/reference/is_nothrow_move_assignable.html b/doc/html/boost_typetraits/reference/is_nothrow_move_assignable.html index 9fd6f8f..29b804f 100644 --- a/doc/html/boost_typetraits/reference/is_nothrow_move_assignable.html +++ b/doc/html/boost_typetraits/reference/is_nothrow_move_assignable.html @@ -40,8 +40,8 @@

In other words, inherits from true_type - only if expression varaible1 = std::move(varaible2) won't throw (varaible1 - and varaible2 are variables + only if expression variable1 = std::move(variable2) won't throw (variable1 + and variable2 are variables of type T).

diff --git a/doc/html/boost_typetraits/reference/is_nothrow_move_constructible.html b/doc/html/boost_typetraits/reference/is_nothrow_move_constructible.html index d43f291..741400e 100644 --- a/doc/html/boost_typetraits/reference/is_nothrow_move_constructible.html +++ b/doc/html/boost_typetraits/reference/is_nothrow_move_constructible.html @@ -39,7 +39,7 @@

In other words, inherits from true_type - only if expression T(std::move(varaible1)) won't throw (varaible1 + only if expression T(std::move(variable1)) won't throw (variable1 is a variable of type T).

diff --git a/doc/is_nothrow_move_assignable.qbk b/doc/is_nothrow_move_assignable.qbk index 107f660..5e0edb9 100644 --- a/doc/is_nothrow_move_assignable.qbk +++ b/doc/is_nothrow_move_assignable.qbk @@ -16,8 +16,8 @@ or a type without move assignment-operator but with non-throwing assignment-oper then inherits from __true_type, otherwise inherits from __false_type. Type `T` must be a complete type. -In other words, inherits from __true_type only if expression `varaible1 = std::move(varaible2)` -won't throw (`varaible1` and `varaible2` are variables of type `T`). +In other words, inherits from __true_type only if expression `variable1 = std::move(variable2)` +won't throw (`variable1` and `variable2` are variables of type `T`). __compat If the compiler does not support partial-specialization of class templates, then this template can not be used with function types. diff --git a/doc/is_nothrow_move_constructible.qbk b/doc/is_nothrow_move_constructible.qbk index 797af4c..863054b 100644 --- a/doc/is_nothrow_move_constructible.qbk +++ b/doc/is_nothrow_move_constructible.qbk @@ -16,8 +16,8 @@ or a type without move-constructor but with non-throwing copy-constructor, then inherits from __true_type, otherwise inherits from __false_type. Type `T` must be a complete type. -In other words, inherits from __true_type only if expression `T(std::move(varaible1))` -won't throw (`varaible1` is a variable of type `T`). +In other words, inherits from __true_type only if expression `T(std::move(variable1))` +won't throw (`variable1` is a variable of type `T`). __compat If the compiler does not support partial-specialization of class templates, then this template can not be used with function types. From dea1f79512dc43e405cd2f0cd303c52510b61d06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 18 Aug 2014 01:09:13 +0200 Subject: [PATCH 03/12] Fix for MSVC 12.0 std::is_copy_constructible and boost::is_copy_constructible return true for types with deleted copy constructors --- include/boost/type_traits/is_copy_constructible.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/type_traits/is_copy_constructible.hpp b/include/boost/type_traits/is_copy_constructible.hpp index e90ecb7..24f5eeb 100644 --- a/include/boost/type_traits/is_copy_constructible.hpp +++ b/include/boost/type_traits/is_copy_constructible.hpp @@ -32,7 +32,10 @@ struct is_copy_constructible_impl2 { // error: function *function_name* cannot be referenced -- it is a deleted function // static boost::type_traits::yes_type test(T1&, decltype(T1(boost::declval()))* = 0); // ^ -#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_INTEL_CXX_VERSION) +// +// MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See: +// https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_INTEL_CXX_VERSION) && !(defined(BOOST_MSVC) && _MSC_VER == 1800) #ifdef BOOST_NO_CXX11_DECLTYPE template From d11a87472a2c4dbdacb54eb17c9b51da72bbca5c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 18 Aug 2014 15:11:59 +0100 Subject: [PATCH 04/12] Add metadata file. --- meta/libraries.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 meta/libraries.json diff --git a/meta/libraries.json b/meta/libraries.json new file mode 100644 index 0000000..97fcb65 --- /dev/null +++ b/meta/libraries.json @@ -0,0 +1,18 @@ +{ + "key": "type_traits", + "name": "Type Traits", + "authors": [ + "John Maddock, Steve Cleary, et al" + ], + "description": "Templates for fundamental properties of types.", + "std": [ + "tr1" + ], + "category": [ + "Generic", + "Metaprogramming" + ], + "maintainers": [ + "John Maddock " + ] +} From 5d936acc05e79f60bae84e4c61d46aee759c93c7 Mon Sep 17 00:00:00 2001 From: K-ballo Date: Mon, 11 Aug 2014 09:43:28 -0300 Subject: [PATCH 05/12] Added is_final type trait. Added BOOST_IS_FINAL intrinsic. --- doc/html/boost_typetraits/intrinsics.html | 18 ++- doc/html/boost_typetraits/reference.html | 1 + .../boost_typetraits/reference/is_enum.html | 6 +- .../boost_typetraits/reference/is_final.html | 105 ++++++++++++++++++ .../reference/is_floating_point.html | 6 +- doc/html/index.html | 1 + doc/html/index/s11.html | 3 +- doc/html/index/s12.html | 2 +- doc/html/index/s13.html | 9 +- doc/html/index/s14.html | 17 ++- doc/intrinsics.qbk | 4 +- doc/is_final.qbk | 47 ++++++++ doc/type_traits.qbk | 2 + include/boost/type_traits/intrinsics.hpp | 6 + include/boost/type_traits/is_final.hpp | 41 +++++++ test/is_final_test.cpp | 72 ++++++++++++ test/test.hpp | 5 + 17 files changed, 333 insertions(+), 12 deletions(-) create mode 100644 doc/html/boost_typetraits/reference/is_final.html create mode 100644 doc/is_final.qbk create mode 100644 include/boost/type_traits/is_final.hpp create mode 100644 test/is_final_test.cpp diff --git a/doc/html/boost_typetraits/intrinsics.html b/doc/html/boost_typetraits/intrinsics.html index 2458b75..80d5626 100644 --- a/doc/html/boost_typetraits/intrinsics.html +++ b/doc/html/boost_typetraits/intrinsics.html @@ -38,6 +38,9 @@ for all types (but all have safe fallback positions if this support is unavailable):

    +
  • + is_final +
  • is_union
  • @@ -360,7 +363,20 @@

    - Should evaluate to the alignment requirements of type T. + Should evaluate to the alignment requirements of type T +

    + + + + +

    + BOOST_IS_FINAL(T) +

    + + +

    + Should evaluate to true if T is a class type declared with the final + specifier

    diff --git a/doc/html/boost_typetraits/reference.html b/doc/html/boost_typetraits/reference.html index 6a6d0c6..f47511e 100644 --- a/doc/html/boost_typetraits/reference.html +++ b/doc/html/boost_typetraits/reference.html @@ -109,6 +109,7 @@
    is_copy_constructible
    is_empty
    is_enum
    +
    is_final
    is_floating_point
    is_function
    is_fundamental
    diff --git a/doc/html/boost_typetraits/reference/is_enum.html b/doc/html/boost_typetraits/reference/is_enum.html index c9fa5ad..bbc3cbd 100644 --- a/doc/html/boost_typetraits/reference/is_enum.html +++ b/doc/html/boost_typetraits/reference/is_enum.html @@ -7,7 +7,7 @@ - + @@ -20,7 +20,7 @@

    -PrevUpHomeNext +PrevUpHomeNext

    @@ -94,7 +94,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/boost_typetraits/reference/is_final.html b/doc/html/boost_typetraits/reference/is_final.html new file mode 100644 index 0000000..13cf7db --- /dev/null +++ b/doc/html/boost_typetraits/reference/is_final.html @@ -0,0 +1,105 @@ + + + +is_final + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +
    template <class T>
    +struct is_final : public true_type-or-false_type {};
    +
    +

    + Inherits: If T is a (possibly cv-qualified) + class type declared with the final specifier type then inherits from true_type, + otherwise inherits from false_type. + Currently requires some kind of compiler support. +

    +

    + C++ Standard Reference: 9p3. +

    +

    + Compiler Compatibility: Without (some as + yet unspecified) help from the compiler, we cannot detect class types declared + with the final specifier using only standard C++, as a result this type will + never inherit from true_type, + unless the user explicitly specializes the template for their user-defined + final class types, or unless the compiler supplies some unspecified intrinsic + that implements this functionality. Currently (Aug 2014) compilers more recent + than GCC-4.7, and Clang have the necessary compiler intrinsics + to ensure that this trait "just works". You may also test to see + if the necessary intrinsics + are available by checking to see if the macro BOOST_IS_FINAL + is defined. +

    +

    + Header: #include + <boost/type_traits/is_final.hpp> + or #include <boost/type_traits.hpp> +

    +

    + Examples: +

    +

    + Given struct my_final + final {}; + then: +

    +

    + is_final<my_final> + inherits from true_type. +

    +

    + is_final<const my_final>::type + is the type true_type. +

    +

    + is_final<my_final>::value is an integral constant expression + that evaluates to true. +

    +

    + is_final<my_final*>::value is an integral constant expression + that evaluates to false. +

    +

    + is_final<T>::value_type is the type bool. +

    +
    + + + +
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_typetraits/reference/is_floating_point.html b/doc/html/boost_typetraits/reference/is_floating_point.html index 5cfcb9d..4dcd393 100644 --- a/doc/html/boost_typetraits/reference/is_floating_point.html +++ b/doc/html/boost_typetraits/reference/is_floating_point.html @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -74,7 +74,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/index.html b/doc/html/index.html index 9493928..0dab041 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -165,6 +165,7 @@
    is_copy_constructible
    is_empty
    is_enum
    +
    is_final
    is_floating_point
    is_function
    is_fundamental
    diff --git a/doc/html/index/s11.html b/doc/html/index/s11.html index 4d09385..e38fc68 100644 --- a/doc/html/index/s11.html +++ b/doc/html/index/s11.html @@ -24,7 +24,7 @@

    -Class Index

    +Class Index

    A C D E F H I M N O P R T

    @@ -235,6 +235,7 @@
  • is_copy_constructible

  • is_empty

  • is_enum

  • +
  • is_final

  • is_floating_point

  • is_function

  • is_fundamental

  • diff --git a/doc/html/index/s12.html b/doc/html/index/s12.html index bfb5d56..cc0c5e4 100644 --- a/doc/html/index/s12.html +++ b/doc/html/index/s12.html @@ -24,7 +24,7 @@

    -Typedef Index

    +Typedef Index

A F R T

diff --git a/doc/html/index/s13.html b/doc/html/index/s13.html index 6c97dae..3e615b2 100644 --- a/doc/html/index/s13.html +++ b/doc/html/index/s13.html @@ -24,7 +24,7 @@

-Macro Index

+Macro Index

B

@@ -141,6 +141,13 @@
  • +

    BOOST_IS_FINAL

    + +
  • +
  • BOOST_IS_POD

    • is_pod

    • diff --git a/doc/html/index/s14.html b/doc/html/index/s14.html index 08119b6..0d15a16 100644 --- a/doc/html/index/s14.html +++ b/doc/html/index/s14.html @@ -23,7 +23,7 @@

    -Index

    +Index
  • A B C D E F H I M N O P R T U

    @@ -186,6 +186,13 @@
  • +

    BOOST_IS_FINAL

    + +
  • +
  • BOOST_IS_POD

  • is_enum

  • +
  • +

    is_final

    + +
  • is_floating_point

  • is_function

    @@ -828,6 +842,7 @@
  • BOOST_IS_CONVERTIBLE

  • BOOST_IS_EMPTY

  • BOOST_IS_ENUM

  • +
  • BOOST_IS_FINAL

  • BOOST_IS_POD

  • BOOST_IS_POLYMORPHIC

  • BOOST_IS_UNION

  • diff --git a/doc/intrinsics.qbk b/doc/intrinsics.qbk index abffdac..4967e47 100644 --- a/doc/intrinsics.qbk +++ b/doc/intrinsics.qbk @@ -17,6 +17,7 @@ The Following traits classes always need compiler support to do the right thing for all types (but all have safe fallback positions if this support is unavailable): +* __is_final * __is_union * __is_pod * __has_trivial_constructor @@ -67,7 +68,8 @@ a matter of defining one of more of the following macros: [[BOOST_IS_CONVERTIBLE(T,U)][Should evaluate to true if T is convertible to U]] [[BOOST_IS_ENUM(T)][Should evaluate to true is T is an enum]] [[BOOST_IS_POLYMORPHIC(T)][Should evaluate to true if T is a polymorphic type]] - [[BOOST_ALIGNMENT_OF(T)][Should evaluate to the alignment requirements of type T.]] + [[BOOST_ALIGNMENT_OF(T)][Should evaluate to the alignment requirements of type T]] + [[BOOST_IS_FINAL(T)][Should evaluate to true if T is a class type declared with the final specifier]] ] diff --git a/doc/is_final.qbk b/doc/is_final.qbk new file mode 100644 index 0000000..6f3e326 --- /dev/null +++ b/doc/is_final.qbk @@ -0,0 +1,47 @@ +[/ + Copyright (c) 2014 Agustin Berge + 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_final is_final] + template + struct is_final : public __tof {}; + +__inherit If T is a (possibly cv-qualified) class type declared with the final +specifier type then inherits from __true_type, otherwise inherits from __false_type. +Currently requires some kind of compiler support. + +__std_ref 9p3. + +__compat Without (some as yet unspecified) help from the compiler, we cannot detect +class types declared with the final specifier using only standard C++, +as a result this type will never inherit from __true_type, unless the user explicitly +specializes the template for their user-defined final class types, or unless the compiler +supplies some unspecified intrinsic that implements this functionality. +Currently (Aug 2014) compilers more recent than GCC-4.7, and Clang +have the necessary compiler __intrinsics to ensure that this +trait "just works". You may also test to see if the necessary __intrinsics are available +by checking to see if the macro `BOOST_IS_FINAL` is defined. + +__header ` #include ` or ` #include ` + +__examples + +Given `struct my_final final {};` then: + +[:`is_final` inherits from `__true_type`.] + +[:`is_final::type` is the type `__true_type`.] + +[:`is_final::value` is an integral constant +expression that evaluates to /true/.] + +[:`is_final::value` is an integral constant +expression that evaluates to /false/.] + +[:`is_final::value_type` is the type `bool`.] + +[endsect] + diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index 22e59ef..cbb4fd6 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -76,6 +76,7 @@ [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_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]] [def __has_new_operator [link boost_typetraits.reference.has_new_operator has_new_operator]] [def __has_trivial_copy [link boost_typetraits.reference.has_trivial_copy has_trivial_copy]] @@ -263,6 +264,7 @@ See __has_trivial_constructor. [include is_copy_constructible.qbk] [include is_empty.qbk] [include is_enum.qbk] +[include is_final.qbk] [include is_floating_point.qbk] [include is_function.qbk] [include is_fundamental.qbk] diff --git a/include/boost/type_traits/intrinsics.hpp b/include/boost/type_traits/intrinsics.hpp index 94dbea2..d08f45f 100644 --- a/include/boost/type_traits/intrinsics.hpp +++ b/include/boost/type_traits/intrinsics.hpp @@ -197,6 +197,9 @@ # define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) __has_trivial_move_assign(T) # endif # define BOOST_ALIGNMENT_OF(T) __alignof(T) +# if __has_feature(is_final) +# define BOOST_IS_FINAL(T) __is_final(T) +# endif # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif @@ -262,6 +265,9 @@ # define BOOST_IS_ENUM(T) __is_enum(T) # define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) # define BOOST_ALIGNMENT_OF(T) __alignof__(T) +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) +# define BOOST_IS_FINAL(T) __is_final(T) +# endif # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif diff --git a/include/boost/type_traits/is_final.hpp b/include/boost/type_traits/is_final.hpp new file mode 100644 index 0000000..36bd62e --- /dev/null +++ b/include/boost/type_traits/is_final.hpp @@ -0,0 +1,41 @@ + +// Copyright (c) 2014 Agustin Berge +// +// Use, modification and distribution are subject to 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). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + + +#ifndef BOOST_TT_IS_FINAL_HPP_INCLUDED +#define BOOST_TT_IS_FINAL_HPP_INCLUDED + +#include +#include +#include + +// should be the last #include +#include + +namespace boost { + +namespace detail { +template struct is_final_impl +{ +#ifdef BOOST_IS_FINAL + typedef typename remove_cv::type cvt; + BOOST_STATIC_CONSTANT(bool, value = BOOST_IS_FINAL(cvt)); +#else + BOOST_STATIC_CONSTANT(bool, value = false); +#endif +}; +} // namespace detail + +BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_final,T,::boost::detail::is_final_impl::value) + +} // namespace boost + +#include + +#endif // BOOST_TT_IS_FINAL_HPP_INCLUDED diff --git a/test/is_final_test.cpp b/test/is_final_test.cpp new file mode 100644 index 0000000..0bb46c2 --- /dev/null +++ b/test/is_final_test.cpp @@ -0,0 +1,72 @@ + +// Copyright (c) 2014 Agustin Berge +// +// Use, modification and distribution are subject to 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 "test.hpp" +#include "check_integral_constant.hpp" +#ifdef TEST_STD +# include +#else +# include +#endif +#include + +TT_TEST_BEGIN(is_final) + + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); +#endif + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + +#if defined(BOOST_HAS_TYPE_TRAITS_INTRINSICS) + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, true); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, true); +#else + std::cout << + "\n\n" + "This compiler version does not provide support for is_final on\n" + "final types.n" + "\n"; +#endif + + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); + +TT_TEST_END + + + + + + + + + diff --git a/test/test.hpp b/test/test.hpp index 1f2211e..ae3d24e 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -265,6 +265,11 @@ struct nothrow_construct_UDT { return true; } }; +#ifndef BOOST_NO_CXX11_FINAL +struct final_UDT final +{}; +#endif + class Base { }; class Derived : public Base { }; From 6f6e288daf51162b0df6dd703768d7ee4d23581b Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Wed, 20 Aug 2014 18:13:21 +0100 Subject: [PATCH 06/12] Oops, move gcc config to correct section. --- include/boost/type_traits/intrinsics.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/boost/type_traits/intrinsics.hpp b/include/boost/type_traits/intrinsics.hpp index d08f45f..b5f1e08 100644 --- a/include/boost/type_traits/intrinsics.hpp +++ b/include/boost/type_traits/intrinsics.hpp @@ -238,6 +238,9 @@ // old implementation instead in that case: # define BOOST_ALIGNMENT_OF(T) __alignof__(T) # endif +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) +# define BOOST_IS_FINAL(T) __is_final(T) +# endif # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif @@ -265,10 +268,6 @@ # define BOOST_IS_ENUM(T) __is_enum(T) # define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) # define BOOST_ALIGNMENT_OF(T) __alignof__(T) -# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) -# define BOOST_IS_FINAL(T) __is_final(T) -# endif - # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif From 0e78687e7d2179b2bee015f327973ef2c9765f31 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Wed, 20 Aug 2014 18:15:30 +0100 Subject: [PATCH 07/12] Fix test case: * Don't test incomplete types. * Use new BOOST_NO_CXX11_FINAL macro for checks. * Use soft checks when no compiler support is present. --- test/is_final_test.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/is_final_test.cpp b/test/is_final_test.cpp index 0bb46c2..40ad226 100644 --- a/test/is_final_test.cpp +++ b/test/is_final_test.cpp @@ -30,9 +30,18 @@ TT_TEST_BEGIN(is_final) BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); -#if defined(BOOST_HAS_TYPE_TRAITS_INTRINSICS) +#if !defined(BOOST_NO_CXX11_FINAL) + // + // These are "soft" checks: since we cannot implement this trait + // ourselves and instead rely on the compiler. + // +# ifndef BOOST_IS_FINAL + BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::is_final::value, true, false); + BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::is_final::value, true, false); +# else BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, true); +# endif #else std::cout << "\n\n" @@ -58,7 +67,6 @@ TT_TEST_BEGIN(is_final) BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); - BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_final::value, false); TT_TEST_END From df74811a4c996f0e5fd5551622aefed803db27d4 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 23 Aug 2014 12:20:26 +0100 Subject: [PATCH 08/12] Fix has_trivial_copy so that non-copyable types are never trivially copyable! Also fix clang to detect trivially copyable array types. --- include/boost/type_traits/has_trivial_copy.hpp | 18 ++++++++++++++++++ test/has_trivial_copy_test.cpp | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/include/boost/type_traits/has_trivial_copy.hpp b/include/boost/type_traits/has_trivial_copy.hpp index ba4d884..1c567cf 100644 --- a/include/boost/type_traits/has_trivial_copy.hpp +++ b/include/boost/type_traits/has_trivial_copy.hpp @@ -17,6 +17,10 @@ #include #include +#ifdef __clang__ +#include +#endif + // should be the last #include #include @@ -28,7 +32,11 @@ template struct has_trivial_copy_impl { #ifdef BOOST_HAS_TRIVIAL_COPY +# ifdef __clang__ + BOOST_STATIC_CONSTANT(bool, value = BOOST_HAS_TRIVIAL_COPY(T) && boost::is_copy_constructible::value); +# else BOOST_STATIC_CONSTANT(bool, value = BOOST_HAS_TRIVIAL_COPY(T)); +# endif #else BOOST_STATIC_CONSTANT(bool, value = (::boost::type_traits::ice_and< @@ -38,6 +46,16 @@ struct has_trivial_copy_impl #endif }; +#ifdef __clang__ + +template +struct has_trivial_copy_impl +{ + static const bool value = has_trivial_copy_impl::value; +}; + +#endif + } // namespace detail BOOST_TT_AUX_BOOL_TRAIT_DEF1(has_trivial_copy,T,::boost::detail::has_trivial_copy_impl::value) diff --git a/test/has_trivial_copy_test.cpp b/test/has_trivial_copy_test.cpp index 6ed8df8..9a0a042 100644 --- a/test/has_trivial_copy_test.cpp +++ b/test/has_trivial_copy_test.cpp @@ -12,6 +12,19 @@ # include #endif +#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS + +class bug_10389 +{ + int m_data; +public: + bug_10389() { m_data = 0; } + bug_10389(const bug_10389&) = delete; + bug_10389(bug_10389&& r) : m_data(r.m_data) { r.m_data = 0; } +}; + +#endif + TT_TEST_BEGIN(has_trivial_copy) BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_copy::value, true); @@ -203,6 +216,10 @@ BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_copy::value, false); +#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_copy::value, false); +#endif + TT_TEST_END From bbcfff027842576b6a1e712c33d66271ba9d1190 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 23 Aug 2014 13:26:15 +0100 Subject: [PATCH 09/12] Fix clang is_convertible test failure - we don't need to check for abstract targets as clang does the right thing. --- include/boost/type_traits/intrinsics.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/boost/type_traits/intrinsics.hpp b/include/boost/type_traits/intrinsics.hpp index b5f1e08..8bccb6f 100644 --- a/include/boost/type_traits/intrinsics.hpp +++ b/include/boost/type_traits/intrinsics.hpp @@ -181,8 +181,7 @@ # define BOOST_IS_CLASS(T) __is_class(T) # endif # if __has_feature(is_convertible_to) -# include -# define BOOST_IS_CONVERTIBLE(T,U) (__is_convertible_to(T,U) && !::boost::is_abstract::value) +# define BOOST_IS_CONVERTIBLE(T,U) __is_convertible_to(T,U) # endif # if __has_feature(is_enum) # define BOOST_IS_ENUM(T) __is_enum(T) From cf18d2bbac0b681fe3b6ce4951d67c4dbe7a935e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Tue, 26 Aug 2014 23:23:12 +0200 Subject: [PATCH 10/12] is_copy_assignable implementation added. It needs C++11 support to work reliable. --- doc/is_copy_assignable.qbk | 51 ++++ doc/type_traits.qbk | 1 + include/boost/type_traits.hpp | 1 + .../boost/type_traits/is_copy_assignable.hpp | 147 ++++++++++++ test/is_copy_assignable.cpp | 223 ++++++++++++++++++ 5 files changed, 423 insertions(+) create mode 100644 doc/is_copy_assignable.qbk create mode 100644 include/boost/type_traits/is_copy_assignable.hpp create mode 100644 test/is_copy_assignable.cpp diff --git a/doc/is_copy_assignable.qbk b/doc/is_copy_assignable.qbk new file mode 100644 index 0000000..e1de31a --- /dev/null +++ b/doc/is_copy_assignable.qbk @@ -0,0 +1,51 @@ +[/ + Copyright 2007 John Maddock. + Copyright 2014 Ion Gaztanaga. + 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_copy_assignable is_copy_assignable] + + template + struct is_copy_assignable : public __tof {}; + +__inherit If `T` is `CopyAssignable` (i.e. has an accessible explicit or implicit copy assignment operator), +then inherits from __true_type, otherwise inherits from __false_type. Type `T` +must be a complete type. + +In other words, inherits from __true_type only if copy assignment of `T` from `const T &` is not +marked with `= delete`, `T` does not derives from `boost::noncopyable` and +is not marked with `BOOST_MOVABLE_BUT_NOT_COPYABLE(T)`. + +__compat If the compiler does not support partial-specialization of class +templates, then this template can not be used. + +If your compiler does not support C++11 deleted functions (`= delete`) or does not support +SFINAE for the deleted assignments, then derive your classes from `boost::noncopyable` or +mark them with `BOOST_MOVABLE_BUT_NOT_COPYABLE(T)` to show that class is non-assignable. + +Trait does not care about access modifiers, so if you see errors like this: + + 'T::operator=(const T&)' is private + boost/type_traits/is_copy_assignable.hpp:68:5: error: within this context + +then you are trying to call that macro for a structure with private assignment: + + struct T { + // ... + private: + T &operator=(const T &); + // ... + }; + +To fix that you must modify your structure, explicitly marking it as noncopyable (`= delete`, +`boost::noncopyable` or `BOOST_MOVABLE_BUT_NOT_COPYABLE(T)`) or explicitly +[link boost_typetraits.user_defined specializing the trait]. + + +__header ` #include ` or ` #include ` + +[endsect] + diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index cbb4fd6..816f7af 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -69,6 +69,7 @@ [def __is_empty [link boost_typetraits.reference.is_empty is_empty]] [def __is_const [link boost_typetraits.reference.is_const is_const]] [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_volatile [link boost_typetraits.reference.is_volatile is_volatile]] [def __is_abstract [link boost_typetraits.reference.is_abstract is_abstract]] [def __is_polymorphic [link boost_typetraits.reference.is_polymorphic is_polymorphic]] diff --git a/include/boost/type_traits.hpp b/include/boost/type_traits.hpp index 9267a71..398c687 100644 --- a/include/boost/type_traits.hpp +++ b/include/boost/type_traits.hpp @@ -51,6 +51,7 @@ #include "boost/type_traits/is_const.hpp" #include "boost/type_traits/is_convertible.hpp" #include "boost/type_traits/is_copy_constructible.hpp" +#include "boost/type_traits/is_copy_assignable.hpp" #include "boost/type_traits/is_empty.hpp" #include "boost/type_traits/is_enum.hpp" #include "boost/type_traits/is_float.hpp" diff --git a/include/boost/type_traits/is_copy_assignable.hpp b/include/boost/type_traits/is_copy_assignable.hpp new file mode 100644 index 0000000..48af818 --- /dev/null +++ b/include/boost/type_traits/is_copy_assignable.hpp @@ -0,0 +1,147 @@ +// (C) Copyright Ion Gaztanaga 2014. +// +// Use, modification and distribution are subject to 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). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_COPY_ASSIGNABLE_HPP_INCLUDED +#define BOOST_TT_IS_COPY_ASSIGNABLE_HPP_INCLUDED + +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \ + && !defined(BOOST_INTEL_CXX_VERSION) && \ + !(defined(BOOST_MSVC) && _MSC_VER == 1800) +#define BOOST_TT_CXX11_IS_COPY_ASSIGNABLE +#include +#else + //For compilers without decltype + #include + #include + #include + #include +#endif + + +// should be the last #include +#include + +namespace boost { + +namespace detail{ + +template +struct is_copy_assignable_impl2 { + +// Intel compiler has problems with SFINAE for copy constructors and deleted functions: +// +// error: function *function_name* cannot be referenced -- it is a deleted function +// static boost::type_traits::yes_type test(T1&, decltype(T1(boost::declval()))* = 0); +// ^ +// +// MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See: +// https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken +#if defined(BOOST_TT_CXX11_IS_COPY_ASSIGNABLE) + typedef boost::type_traits::yes_type yes_type; + typedef boost::type_traits::no_type no_type; + + template + static decltype(::boost::declval() = ::boost::declval(), yes_type() ) test(int); + + template + static no_type test(...); + + static const bool value = sizeof(test(0)) == sizeof(yes_type); + +#else + static BOOST_DEDUCED_TYPENAME boost::add_reference::type produce(); + + template + static boost::type_traits::no_type test(T1&, typename T1::boost_move_no_copy_constructor_or_assign* = 0); + + static boost::type_traits::yes_type test(...); + // If you see errors like this: + // + // `'T::operator=(const T&)' is private` + // `boost/type_traits/is_copy_assignable.hpp:NN:M: error: within this context` + // + // then you are trying to call that macro for a structure defined like that: + // + // struct T { + // ... + // private: + // T & operator=(const T &); + // ... + // }; + // + // To fix that you must modify your structure: + // + // // C++03 and C++11 version + // struct T: private boost::noncopyable { + // ... + // private: + // T & operator=(const T &); + // ... + // }; + // + // // C++11 version + // struct T { + // ... + // private: + // T& operator=(const T &) = delete; + // ... + // }; + BOOST_STATIC_CONSTANT(bool, value = ( + sizeof(test(produce())) == sizeof(boost::type_traits::yes_type) + )); + #endif +}; + +template +struct is_copy_assignable_impl2 { + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_copy_assignable_impl { + +#if !defined(BOOST_TT_CXX11_IS_COPY_ASSIGNABLE) + //For compilers without decltype, at least return false on const types, arrays + //types derived from boost::noncopyable and types defined as BOOST_MOVEABLE_BUT_NOT_COPYABLE + typedef BOOST_DEDUCED_TYPENAME boost::remove_reference::type unreferenced_t; + BOOST_STATIC_CONSTANT(bool, value = ( + boost::detail::is_copy_assignable_impl2< + boost::is_base_and_derived::value + || boost::is_const::value || boost::is_array::value + ,T + >::value + )); + #else + BOOST_STATIC_CONSTANT(bool, value = ( + boost::detail::is_copy_assignable_impl2< + boost::is_base_and_derived::value,T + >::value + )); + #endif +}; + +} // namespace detail + +BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_copy_assignable,T,::boost::detail::is_copy_assignable_impl::value) +BOOST_TT_AUX_BOOL_TRAIT_SPEC1(is_copy_assignable,void,false) +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS +BOOST_TT_AUX_BOOL_TRAIT_SPEC1(is_copy_assignable,void const,false) +BOOST_TT_AUX_BOOL_TRAIT_SPEC1(is_copy_assignable,void const volatile,false) +BOOST_TT_AUX_BOOL_TRAIT_SPEC1(is_copy_assignable,void volatile,false) +#endif + +} // namespace boost + +#include + +#endif // BOOST_TT_IS_COPY_ASSIGNABLE_HPP_INCLUDED diff --git a/test/is_copy_assignable.cpp b/test/is_copy_assignable.cpp new file mode 100644 index 0000000..5171b32 --- /dev/null +++ b/test/is_copy_assignable.cpp @@ -0,0 +1,223 @@ +// (C) Copyright John Maddock 2000. +// (C) Copyright Ion Gaztanaga 2014. +// Use, modification and distribution are subject to 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) +//#define TEST_STD +#include "test.hpp" +#include "check_integral_constant.hpp" + +#ifdef TEST_STD +# include +#else +# include +#endif + + +#include + +struct has { + has(){} + has &operator=(const has&){ return *this; } +}; + +// MSVC can not generate neither default constructor, nor assignment operator, +// nor copy constructor for `has2` type. Supressing those warnings is essential, +// because we treat warnings as errors in those tests +#if (defined _MSC_VER) +# pragma warning( push ) +# pragma warning( disable : 4510 4512 4610) +#endif +struct has2 { + int i; + has2 &operator=(const int& val) { i = val; return *this; } +}; +#if (defined _MSC_VER) +# pragma warning( pop ) +#endif + +struct has3 { // Copy assignment must be generated by compiler + has3(has3*){} +}; + +struct has_not: public boost::noncopyable { + typedef boost::noncopyable base_t; + has_not() : base_t() {} +}; + +#if defined(BOOST_TT_CXX11_IS_COPY_ASSIGNABLE) + +struct has_not2 { + has_not2() {} + has_not2& operator=(has_not2&) = delete; +}; + +struct has_not3 { + has_not3() {} + has_not3& operator=(const has_not3&) = delete; +}; + +#endif // BOOST_TT_CXX11_IS_COPY_ASSIGNABLE + +struct has_not4: private boost::noncopyable { + typedef boost::noncopyable base_t; + has_not4() : base_t() {} +private: + has_not4& operator=(const has_not4&); +}; + +struct has_not5 { +private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(has_not5) +}; + +struct has_not6 { + has_not6& operator=(has_not6&){ return *this; } +}; + + +TT_TEST_BEGIN(is_copy_assignable) + +// Main part of the test +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +#if defined(BOOST_TT_CXX11_IS_COPY_ASSIGNABLE) +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +// Requires some basic support from Boost.Move in C++03 +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +#ifdef BOOST_HAS_LONG_LONG + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable< ::boost::ulong_long_type>::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable< ::boost::ulong_long_type const>::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable< ::boost::long_long_type>::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable< ::boost::long_long_type const>::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable< ::boost::ulong_long_type volatile>::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable< ::boost::ulong_long_type const volatile>::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable< ::boost::long_long_type volatile>::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable< ::boost::long_long_type const volatile>::value, false); + +#endif + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); +#endif + +// Following three tests may give different results because of compiler and C++03/C++11. +// On C++11 compiler following code: +// int c[2][4][5][6][3]; +// int b[2][4][5][6][3] = std::move(c); +// does not compile, so we expect `false` to be the result of those three tests. +BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false, true); +BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false, true); +BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false, true); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, false); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_copy_assignable::value, true); + + +TT_TEST_END + From 497b877d15434894ad35b6451064c7bbfc807dba Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 30 Aug 2014 09:19:06 +0100 Subject: [PATCH 11/12] Incrementable and decrementable traits failed to compile with array types: fix that by filtering out arrays early. --- include/boost/type_traits/has_post_decrement.hpp | 6 +++++- include/boost/type_traits/has_post_increment.hpp | 6 +++++- include/boost/type_traits/has_pre_decrement.hpp | 6 +++++- include/boost/type_traits/has_pre_increment.hpp | 6 +++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/boost/type_traits/has_post_decrement.hpp b/include/boost/type_traits/has_post_decrement.hpp index e277eaf..024acb0 100644 --- a/include/boost/type_traits/has_post_decrement.hpp +++ b/include/boost/type_traits/has_post_decrement.hpp @@ -9,6 +9,8 @@ #ifndef BOOST_TT_HAS_POST_DECREMENT_HPP_INCLUDED #define BOOST_TT_HAS_POST_DECREMENT_HPP_INCLUDED +#include + #define BOOST_TT_TRAIT_NAME has_post_decrement #define BOOST_TT_TRAIT_OP -- #define BOOST_TT_FORBIDDEN_IF\ @@ -27,7 +29,9 @@ ::boost::is_pointer< Lhs_noref >::value\ >::value,\ ::boost::is_const< Lhs_noref >::value\ - >::value\ + >::value,\ + /* Arrays */ \ + ::boost::is_array::value\ >::value diff --git a/include/boost/type_traits/has_post_increment.hpp b/include/boost/type_traits/has_post_increment.hpp index 085b2d5..b055607 100644 --- a/include/boost/type_traits/has_post_increment.hpp +++ b/include/boost/type_traits/has_post_increment.hpp @@ -9,6 +9,8 @@ #ifndef BOOST_TT_HAS_POST_INCREMENT_HPP_INCLUDED #define BOOST_TT_HAS_POST_INCREMENT_HPP_INCLUDED +#include + #define BOOST_TT_TRAIT_NAME has_post_increment #define BOOST_TT_TRAIT_OP ++ #define BOOST_TT_FORBIDDEN_IF\ @@ -27,7 +29,9 @@ ::boost::is_pointer< Lhs_noref >::value\ >::value,\ ::boost::is_const< Lhs_noref >::value\ - >::value\ + >::value,\ + /* Arrays */ \ + ::boost::is_array::value\ >::value diff --git a/include/boost/type_traits/has_pre_decrement.hpp b/include/boost/type_traits/has_pre_decrement.hpp index 8f08291..feb3d9d 100644 --- a/include/boost/type_traits/has_pre_decrement.hpp +++ b/include/boost/type_traits/has_pre_decrement.hpp @@ -9,6 +9,8 @@ #ifndef BOOST_TT_HAS_PRE_DECREMENT_HPP_INCLUDED #define BOOST_TT_HAS_PRE_DECREMENT_HPP_INCLUDED +#include + #define BOOST_TT_TRAIT_NAME has_pre_decrement #define BOOST_TT_TRAIT_OP -- #define BOOST_TT_FORBIDDEN_IF\ @@ -27,7 +29,9 @@ ::boost::is_pointer< Rhs_noref >::value\ >::value,\ ::boost::is_const< Rhs_noref >::value\ - >::value\ + >::value,\ + /* Arrays */ \ + ::boost::is_array::value\ >::value diff --git a/include/boost/type_traits/has_pre_increment.hpp b/include/boost/type_traits/has_pre_increment.hpp index fcb946d..6a2411d 100644 --- a/include/boost/type_traits/has_pre_increment.hpp +++ b/include/boost/type_traits/has_pre_increment.hpp @@ -9,6 +9,8 @@ #ifndef BOOST_TT_HAS_PRE_INCREMENT_HPP_INCLUDED #define BOOST_TT_HAS_PRE_INCREMENT_HPP_INCLUDED +#include + #define BOOST_TT_TRAIT_NAME has_pre_increment #define BOOST_TT_TRAIT_OP ++ #define BOOST_TT_FORBIDDEN_IF\ @@ -27,7 +29,9 @@ ::boost::is_pointer< Rhs_noref >::value\ >::value,\ ::boost::is_const< Rhs_noref >::value\ - >::value\ + >::value,\ + /* Arrays */ \ + ::boost::is_array::value\ >::value From 7e8ed986153bd5505ff5a5ae49758547408b7f2d Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sun, 31 Aug 2014 18:51:58 +0100 Subject: [PATCH 12/12] Include is_copy_assignable in doc build. --- doc/html/boost_typetraits/reference.html | 1 + .../reference/is_copy_assignable.html | 106 ++++++++++++++++++ .../reference/is_copy_constructible.html | 6 +- .../boost_typetraits/reference/is_empty.html | 6 +- doc/html/index.html | 1 + doc/html/index/s11.html | 3 +- doc/html/index/s12.html | 2 +- doc/html/index/s13.html | 2 +- doc/html/index/s14.html | 3 +- doc/type_traits.qbk | 1 + 10 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 doc/html/boost_typetraits/reference/is_copy_assignable.html diff --git a/doc/html/boost_typetraits/reference.html b/doc/html/boost_typetraits/reference.html index f47511e..c6686d2 100644 --- a/doc/html/boost_typetraits/reference.html +++ b/doc/html/boost_typetraits/reference.html @@ -107,6 +107,7 @@
    is_const
    is_convertible
    is_copy_constructible
    +
    is_copy_assignable
    is_empty
    is_enum
    is_final
    diff --git a/doc/html/boost_typetraits/reference/is_copy_assignable.html b/doc/html/boost_typetraits/reference/is_copy_assignable.html new file mode 100644 index 0000000..4294d78 --- /dev/null +++ b/doc/html/boost_typetraits/reference/is_copy_assignable.html @@ -0,0 +1,106 @@ + + + +is_copy_assignable + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +
    template <class T>
    +struct is_copy_assignable : public true_type-or-false_type {};
    +
    +

    + Inherits: If T + is CopyAssignable (i.e. has + an accessible explicit or implicit copy assignment operator), then inherits + from true_type, + otherwise inherits from false_type. + Type T must be a complete + type. +

    +

    + In other words, inherits from true_type + only if copy assignment of T + from const T + & is not marked with = delete, + T does not derives from + boost::noncopyable and is not marked with BOOST_MOVABLE_BUT_NOT_COPYABLE(T). +

    +

    + Compiler Compatibility: If the compiler + does not support partial-specialization of class templates, then this template + can not be used. +

    +

    + If your compiler does not support C++11 deleted functions (= delete) + or does not support SFINAE for the deleted assignments, then derive your + classes from boost::noncopyable or mark them with BOOST_MOVABLE_BUT_NOT_COPYABLE(T) to show + that class is non-assignable. +

    +

    + Trait does not care about access modifiers, so if you see errors like this: +

    +
    'T::operator=(const T&)' is private
    +boost/type_traits/is_copy_assignable.hpp:68:5: error: within this context
    +
    +

    + then you are trying to call that macro for a structure with private assignment: +

    +
    struct T {
    +    // ...
    +private:
    +    T &operator=(const T &);
    +    // ...
    +};
    +
    +

    + To fix that you must modify your structure, explicitly marking it as noncopyable + (= delete, + boost::noncopyable or BOOST_MOVABLE_BUT_NOT_COPYABLE(T)) + or explicitly specializing + the trait. +

    +

    + Header: #include + <boost/type_traits/is_copy_assignable.hpp> + or #include <boost/type_traits.hpp> +

    +
    + + + +
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_typetraits/reference/is_copy_constructible.html b/doc/html/boost_typetraits/reference/is_copy_constructible.html index 55d32db..4acb9bf 100644 --- a/doc/html/boost_typetraits/reference/is_copy_constructible.html +++ b/doc/html/boost_typetraits/reference/is_copy_constructible.html @@ -7,7 +7,7 @@ - + @@ -20,7 +20,7 @@

    -PrevUpHomeNext +PrevUpHomeNext

    @@ -97,7 +97,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/boost_typetraits/reference/is_empty.html b/doc/html/boost_typetraits/reference/is_empty.html index dfe876e..aa8fb86 100644 --- a/doc/html/boost_typetraits/reference/is_empty.html +++ b/doc/html/boost_typetraits/reference/is_empty.html @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -103,7 +103,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/index.html b/doc/html/index.html index 0dab041..106f026 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -163,6 +163,7 @@
    is_const
    is_convertible
    is_copy_constructible
    +
    is_copy_assignable
    is_empty
    is_enum
    is_final
    diff --git a/doc/html/index/s11.html b/doc/html/index/s11.html index e38fc68..6157287 100644 --- a/doc/html/index/s11.html +++ b/doc/html/index/s11.html @@ -24,7 +24,7 @@

    -Class Index

    +Class Index

    A C D E F H I M N O P R T

    @@ -232,6 +232,7 @@
  • is_compound

  • is_const

  • is_convertible

  • +
  • is_copy_assignable

  • is_copy_constructible

  • is_empty

  • is_enum

  • diff --git a/doc/html/index/s12.html b/doc/html/index/s12.html index cc0c5e4..ed1a99f 100644 --- a/doc/html/index/s12.html +++ b/doc/html/index/s12.html @@ -24,7 +24,7 @@

    -Typedef Index

    +Typedef Index

    A F R T

    diff --git a/doc/html/index/s13.html b/doc/html/index/s13.html index 3e615b2..d419ec7 100644 --- a/doc/html/index/s13.html +++ b/doc/html/index/s13.html @@ -24,7 +24,7 @@

    -Macro Index

    +Macro Index

    B

    diff --git a/doc/html/index/s14.html b/doc/html/index/s14.html index 0d15a16..ea4e467 100644 --- a/doc/html/index/s14.html +++ b/doc/html/index/s14.html @@ -23,7 +23,7 @@

    -Index

    +Index

    A B C D E F H I M N O P R T U

    @@ -744,6 +744,7 @@

    is_convertible_to_Ret

    +
  • is_copy_assignable

  • is_copy_constructible

  • is_empty

    diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index 816f7af..3965809 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -263,6 +263,7 @@ See __has_trivial_constructor. [include is_const.qbk] [include is_convertible.qbk] [include is_copy_constructible.qbk] +[include is_copy_assignable.qbk] [include is_empty.qbk] [include is_enum.qbk] [include is_final.qbk]