From 5d936acc05e79f60bae84e4c61d46aee759c93c7 Mon Sep 17 00:00:00 2001 From: K-ballo Date: Mon, 11 Aug 2014 09:43:28 -0300 Subject: [PATCH] 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):

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 { };