From 9c1c935f835e44591764fa022075ec4a32a9e45c Mon Sep 17 00:00:00 2001 From: Nick Thompson Date: Sat, 10 Feb 2024 09:54:44 -0800 Subject: [PATCH] Make quantity a trivial type --- include/boost/units/config.hpp | 8 - include/boost/units/quantity.hpp | 294 ------------------------------- test/test_trivial.cpp | 13 ++ 3 files changed, 13 insertions(+), 302 deletions(-) create mode 100644 test/test_trivial.cpp diff --git a/include/boost/units/config.hpp b/include/boost/units/config.hpp index 64e9025c..1a7eefdc 100644 --- a/include/boost/units/config.hpp +++ b/include/boost/units/config.hpp @@ -70,14 +70,6 @@ #endif -#ifdef BOOST_UNITS_REQUIRE_LAYOUT_COMPATIBILITY - ///INTERNAL ONLY - #define BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(a, b) BOOST_STATIC_ASSERT((sizeof(a) == sizeof(b))) -#else - ///INTERNAL ONLY - #define BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(a, b) -#endif - #ifdef BOOST_UNITS_DOXYGEN /// If defined will trigger a static assertion if quantity diff --git a/include/boost/units/quantity.hpp b/include/boost/units/quantity.hpp index c6ae6e73..1e2989b5 100644 --- a/include/boost/units/quantity.hpp +++ b/include/boost/units/quantity.hpp @@ -88,156 +88,12 @@ struct disable_if_is_same {}; template class quantity { - // base units are not the same as units. - BOOST_MPL_ASSERT_NOT((detail::is_base_unit)); - enum { force_instantiation_of_unit = sizeof(Unit) }; - typedef void (quantity::*unspecified_null_pointer_constant_type)(int*******); public: typedef quantity this_type; typedef Y value_type; typedef Unit unit_type; - BOOST_CONSTEXPR quantity() : val_() - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - BOOST_CONSTEXPR quantity(unspecified_null_pointer_constant_type) : val_() - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - BOOST_CONSTEXPR quantity(const this_type& source) : val_(source.val_) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - // Need to make sure that the destructor of - // Unit which contains the checking is instantiated, - // on sun. - #ifdef __SUNPRO_CC - ~quantity() { - unit_type force_unit_instantiation; - } - #endif - - //~quantity() { } - - BOOST_CXX14_CONSTEXPR this_type& operator=(const this_type& source) - { - val_ = source.val_; - - return *this; - } - - #ifndef BOOST_NO_SFINAE - - /// implicit conversion between value types is allowed if allowed for value types themselves - template - BOOST_CONSTEXPR quantity(const quantity& source, - typename boost::enable_if >::type* = 0) : - val_(source.value()) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - /// implicit conversion between value types is not allowed if not allowed for value types themselves - template - explicit BOOST_CONSTEXPR quantity(const quantity& source, - typename boost::disable_if >::type* = 0) : - val_(static_cast(source.value())) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - #else - - /// implicit conversion between value types is allowed if allowed for value types themselves - template - BOOST_CONSTEXPR quantity(const quantity& source) : - val_(source.value()) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - BOOST_STATIC_ASSERT((boost::is_convertible::value == true)); - } - - #endif - - /// implicit assignment between value types is allowed if allowed for value types themselves - template - BOOST_CXX14_CONSTEXPR this_type& operator=(const quantity& source) - { - BOOST_STATIC_ASSERT((boost::is_convertible::value == true)); - - *this = this_type(source); - - return *this; - } - - #ifndef BOOST_NO_SFINAE - - /// explicit conversion between different unit systems is allowed if implicit conversion is disallowed - template - explicit - BOOST_CONSTEXPR quantity(const quantity& source, - typename boost::disable_if< - mpl::and_< - //is_implicitly_convertible should be undefined when the - //units are not convertible at all - typename is_implicitly_convertible::type, - detail::is_non_narrowing_conversion - >, - typename detail::disable_if_is_same::type - >::type* = 0) - : val_(conversion_helper,this_type>::convert(source).value()) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - BOOST_STATIC_ASSERT((boost::is_convertible::value == true)); - } - - /// implicit conversion between different unit systems is allowed if each fundamental dimension is implicitly convertible - template - BOOST_CONSTEXPR quantity(const quantity& source, - typename boost::enable_if< - mpl::and_< - typename is_implicitly_convertible::type, - detail::is_non_narrowing_conversion - >, - typename detail::disable_if_is_same::type - >::type* = 0) - : val_(conversion_helper,this_type>::convert(source).value()) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - BOOST_STATIC_ASSERT((boost::is_convertible::value == true)); - } - - #else - - /// without SFINAE we can't distinguish between explicit and implicit conversions so - /// the conversion is always explicit - template - explicit BOOST_CONSTEXPR quantity(const quantity& source) - : val_(conversion_helper,this_type>::convert(source).value()) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - BOOST_STATIC_ASSERT((boost::is_convertible::value == true)); - } - - #endif - - /// implicit assignment between different unit systems is allowed if each fundamental dimension is implicitly convertible - template - BOOST_CXX14_CONSTEXPR this_type& operator=(const quantity& source) - { - - BOOST_STATIC_ASSERT((is_implicitly_convertible::value == true)); - BOOST_STATIC_ASSERT((boost::is_convertible::value == true)); - - *this = this_type(source); - - return *this; - } BOOST_CONSTEXPR const value_type& value() const { return val_; } ///< constant accessor to value @@ -283,8 +139,6 @@ class quantity /// Construct quantity directly from @c value_type (potentially dangerous). static BOOST_CONSTEXPR this_type from_value(const value_type& val) { return this_type(val, 0); } - protected: - explicit BOOST_CONSTEXPR quantity(const value_type& val, int) : val_(val) { } private: value_type val_; @@ -305,154 +159,6 @@ class quantity typedef dimensionless_type dimension_type; typedef unit unit_type; - BOOST_CONSTEXPR quantity() : val_() - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - /// construction from raw @c value_type is allowed - BOOST_CONSTEXPR quantity(value_type val) : val_(val) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - BOOST_CONSTEXPR quantity(const this_type& source) : val_(source.val_) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - //~quantity() { } - - BOOST_CXX14_CONSTEXPR this_type& operator=(const this_type& source) - { - val_ = source.val_; - - return *this; - } - - #ifndef BOOST_NO_SFINAE - - /// implicit conversion between value types is allowed if allowed for value types themselves - template - BOOST_CONSTEXPR quantity(const quantity,YY>& source, - typename boost::enable_if >::type* = 0) : - val_(source.value()) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - /// implicit conversion between value types is not allowed if not allowed for value types themselves - template - explicit BOOST_CONSTEXPR quantity(const quantity,YY>& source, - typename boost::disable_if >::type* = 0) : - val_(static_cast(source.value())) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - #else - - /// implicit conversion between value types is allowed if allowed for value types themselves - template - BOOST_CONSTEXPR quantity(const quantity,YY>& source) : - val_(source.value()) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - BOOST_STATIC_ASSERT((boost::is_convertible::value == true)); - } - - #endif - - /// implicit assignment between value types is allowed if allowed for value types themselves - template - BOOST_CXX14_CONSTEXPR this_type& operator=(const quantity,YY>& source) - { - BOOST_STATIC_ASSERT((boost::is_convertible::value == true)); - - *this = this_type(source); - - return *this; - } - - #if 1 - - /// implicit conversion between different unit systems is allowed - template - BOOST_CONSTEXPR quantity(const quantity,Y2>& source, - #ifdef __SUNPRO_CC - typename boost::enable_if< - boost::mpl::and_< - detail::is_non_narrowing_conversion, - detail::is_dimensionless_system - > - >::type* = 0 - #else - typename boost::enable_if >::type* = 0, - typename detail::disable_if_is_same::type* = 0, - typename boost::enable_if >::type* = 0 - #endif - ) : - val_(source.value()) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - /// implicit conversion between different unit systems is allowed - template - explicit BOOST_CONSTEXPR quantity(const quantity,Y2>& source, - #ifdef __SUNPRO_CC - typename boost::enable_if< - boost::mpl::and_< - boost::mpl::not_ >, - detail::is_dimensionless_system - > - >::type* = 0 - #else - typename boost::disable_if >::type* = 0, - typename detail::disable_if_is_same::type* = 0, - typename boost::enable_if >::type* = 0 - #endif - ) : - val_(static_cast(source.value())) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - #else - - /// implicit conversion between different unit systems is allowed - template - BOOST_CONSTEXPR quantity(const quantity >,Y2>& source) : - val_(source.value()) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - BOOST_STATIC_ASSERT((boost::is_convertible::value == true)); - } - - #endif - - /// conversion between different unit systems is explicit when - /// the units are not equivalent. - template - explicit BOOST_CONSTEXPR quantity(const quantity,Y2>& source, - typename boost::disable_if >::type* = 0) : - val_(conversion_helper,Y2>, this_type>::convert(source).value()) - { - BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y); - } - - #ifndef __SUNPRO_CC - - /// implicit assignment between different unit systems is allowed - template - BOOST_CXX14_CONSTEXPR this_type& operator=(const quantity& source) - { - *this = this_type(source); - - return *this; - } - - #endif /// implicit conversion to @c value_type is allowed BOOST_CONSTEXPR operator value_type() const { return val_; } diff --git a/test/test_trivial.cpp b/test/test_trivial.cpp new file mode 100644 index 00000000..15955a7d --- /dev/null +++ b/test/test_trivial.cpp @@ -0,0 +1,13 @@ +#include +#include +// Remove this when https://github.com/boostorg/units/issues/60 is fixed: +#include + +using namespace boost::units; +using namespace boost::units::si; + +static_assert(std::is_trivial_v>); + +int main() { + return 0; +}