From afcf0b097b926e3e0c2e0d81032e6091b4f482bb Mon Sep 17 00:00:00 2001 From: Julien Blanc Date: Thu, 23 May 2024 14:09:47 +0200 Subject: [PATCH] Add constexprs buffers - refs #54 * allows several operations on buffer types to be constexpr * ensure old execution path is still used at runtime, to avoid any performance regression Signed-off-by: Julien Blanc --- include/boost/endian/arithmetic.hpp | 20 ++-- include/boost/endian/buffers.hpp | 30 +++--- include/boost/endian/detail/constexpr.hpp | 16 ++++ include/boost/endian/detail/endian_load.hpp | 98 ++++++++++++-------- include/boost/endian/detail/endian_store.hpp | 89 +++++++++++------- 5 files changed, 156 insertions(+), 97 deletions(-) create mode 100644 include/boost/endian/detail/constexpr.hpp diff --git a/include/boost/endian/arithmetic.hpp b/include/boost/endian/arithmetic.hpp index e771e06..3be410b 100644 --- a/include/boost/endian/arithmetic.hpp +++ b/include/boost/endian/arithmetic.hpp @@ -184,53 +184,53 @@ class endian_arithmetic #ifndef BOOST_ENDIAN_NO_CTORS - endian_arithmetic() = default; + BOOST_ENDIAN_CONSTEXPR endian_arithmetic() = default; - BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic( T val ) BOOST_NOEXCEPT: buf_( val ) + BOOST_ENDIAN_EXPLICIT_OPT BOOST_ENDIAN_CONSTEXPR endian_arithmetic( T val ) BOOST_NOEXCEPT: buf_( val ) { } #endif - endian_arithmetic& operator=( T val ) BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR endian_arithmetic& operator=( T val ) BOOST_NOEXCEPT { buf_ = val; return *this; } - value_type value() const BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR value_type value() const BOOST_NOEXCEPT { return buf_.value(); } - unsigned char const * data() const BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR unsigned char const * data() const BOOST_NOEXCEPT { return buf_.data(); } - unsigned char * data() BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR unsigned char * data() BOOST_NOEXCEPT { return buf_.data(); } - operator value_type() const BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR operator value_type() const BOOST_NOEXCEPT { return this->value(); } - operator buffer_type& () BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR operator buffer_type& () BOOST_NOEXCEPT { return buf_; } - operator buffer_type const& () BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR operator buffer_type const& () BOOST_NOEXCEPT { return buf_; } // operators - T operator+() const BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR T operator+() const BOOST_NOEXCEPT { return this->value(); } diff --git a/include/boost/endian/buffers.hpp b/include/boost/endian/buffers.hpp index 92701df..b568482 100644 --- a/include/boost/endian/buffers.hpp +++ b/include/boost/endian/buffers.hpp @@ -219,27 +219,27 @@ class endian_buffer #ifndef BOOST_ENDIAN_NO_CTORS - endian_buffer() = default; + BOOST_ENDIAN_CONSTEXPR endian_buffer() = default; - explicit endian_buffer( T val ) BOOST_NOEXCEPT + explicit BOOST_ENDIAN_CONSTEXPR endian_buffer( T val ) BOOST_NOEXCEPT { boost::endian::endian_store( value_, val ); } #endif - endian_buffer& operator=( T val ) BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR endian_buffer& operator=( T val ) BOOST_NOEXCEPT { boost::endian::endian_store( value_, val ); return *this; } - value_type value() const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR value_type value() const BOOST_NOEXCEPT { return boost::endian::endian_load( value_ ); } - unsigned char const * data() const BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR unsigned char const * data() const BOOST_NOEXCEPT { return value_; } @@ -274,27 +274,27 @@ class endian_buffer #ifndef BOOST_ENDIAN_NO_CTORS - endian_buffer() = default; + BOOST_ENDIAN_CONSTEXPR endian_buffer() = default; - explicit endian_buffer( T val ) BOOST_NOEXCEPT + explicit BOOST_ENDIAN_CONSTEXPR endian_buffer( T val ) BOOST_NOEXCEPT { boost::endian::endian_store( value_, val ); } #endif - endian_buffer& operator=( T val ) BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR endian_buffer& operator=( T val ) BOOST_NOEXCEPT { boost::endian::endian_store( value_, val ); return *this; } - value_type value() const BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR value_type value() const BOOST_NOEXCEPT { return boost::endian::endian_load( value_ ); } - unsigned char const * data() const BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR unsigned char const * data() const BOOST_NOEXCEPT { return value_; } @@ -323,26 +323,26 @@ class endian_buffer #ifndef BOOST_ENDIAN_NO_CTORS - endian_buffer() = default; + BOOST_ENDIAN_CONSTEXPR endian_buffer() = default; - explicit endian_buffer( T val ) BOOST_NOEXCEPT: value_( val ) + explicit BOOST_ENDIAN_CONSTEXPR endian_buffer( T val ) BOOST_NOEXCEPT: value_( val ) { } #endif - endian_buffer& operator=( T val ) BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR endian_buffer& operator=( T val ) BOOST_NOEXCEPT { value_ = val; return *this; } - value_type value() const BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR value_type value() const BOOST_NOEXCEPT { return value_; } - unsigned char const * data() const BOOST_NOEXCEPT + BOOST_ENDIAN_CONSTEXPR unsigned char const * data() const BOOST_NOEXCEPT { return reinterpret_cast< unsigned char const* >( &value_ ); } diff --git a/include/boost/endian/detail/constexpr.hpp b/include/boost/endian/detail/constexpr.hpp new file mode 100644 index 0000000..f8104e1 --- /dev/null +++ b/include/boost/endian/detail/constexpr.hpp @@ -0,0 +1,16 @@ +#ifndef BOOST_ENDIAN_DETAIL_CONSTEXPR_HPP_INCLUDED +#define BOOST_ENDIAN_DETAIL_CONSTEXPR_HPP_INCLUDED + +// Copyright 2024 Julien Blanc +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#if __cpp_lib_is_constant_evaluated >= 201802L && __cpp_lib_bit_cast >= 201806L +#define BOOST_ENDIAN_CXX20_CONSTEXPR constexpr +#define BOOST_ENDIAN_HAS_CXX20_CONSTEXPR 1 +#else +#define BOOST_ENDIAN_CXX20_CONSTEXPR inline +#define BOOST_ENDIAN_HAS_CXX20_CONSTEXPR 0 +#endif + +#endif // BOOST_ENDIAN_DETAIL_CONSTEXPR_HPP_INCLUDED diff --git a/include/boost/endian/detail/endian_load.hpp b/include/boost/endian/detail/endian_load.hpp index eac2407..20f7132 100644 --- a/include/boost/endian/detail/endian_load.hpp +++ b/include/boost/endian/detail/endian_load.hpp @@ -6,6 +6,7 @@ // Distributed under the Boost Software License, Version 1.0. // http://www.boost.org/LICENSE_1_0.txt +#include #include #include #include @@ -15,6 +16,11 @@ #include #include +#if BOOST_ENDIAN_HAS_CXX20_CONSTEXPR +#include +#include +#endif + namespace boost { namespace endian @@ -37,7 +43,7 @@ template struct end // if N < sizeof(T), T is integral or enum template -inline T endian_load( unsigned char const * p ) BOOST_NOEXCEPT +BOOST_ENDIAN_CONSTEXPR T endian_load( unsigned char const * p ) BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8 ); BOOST_ENDIAN_STATIC_ASSERT( N >= 1 && N <= sizeof(T) ); @@ -52,13 +58,21 @@ namespace detail template struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( is_trivially_copyable::value ); - - T t; - std::memcpy( &t, p, N ); - return t; +#if BOOST_ENDIAN_HAS_CXX20_CONSTEXPR + if (std::is_constant_evaluated()) { + unsigned char v[N]; + std::copy(p, p + N, v); + return std::bit_cast(v); + } else +#endif + { + T t; + std::memcpy(&t, p, N); + return t; + } } }; @@ -66,18 +80,26 @@ template struct endian_load_impl template struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( is_trivially_copyable::value ); - - typename integral_by_size::type tmp; - std::memcpy( &tmp, p, N ); - - endian_reverse_inplace( tmp ); - - T t; - std::memcpy( &t, &tmp, N ); - return t; +#if BOOST_ENDIAN_HAS_CXX20_CONSTEXPR + if (std::is_constant_evaluated()) { + unsigned char v[N]; + std::reverse_copy(p, p + N, v); + return std::bit_cast(v); + } else +#endif + { + typename integral_by_size::type tmp; + std::memcpy( &tmp, p, N ); + + endian_reverse_inplace(tmp); + + T t; + std::memcpy(&t, &tmp, N); + return t; + } } }; @@ -85,7 +107,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -100,7 +122,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -117,7 +139,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -136,7 +158,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -157,7 +179,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -176,7 +198,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -197,7 +219,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -214,7 +236,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -233,7 +255,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -257,7 +279,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -283,7 +305,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -307,7 +329,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -333,7 +355,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -357,7 +379,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -383,7 +405,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -407,7 +429,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -433,7 +455,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -457,7 +479,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -483,7 +505,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -507,7 +529,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -533,7 +555,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -557,7 +579,7 @@ template struct endian_load_impl struct endian_load_impl { - inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); diff --git a/include/boost/endian/detail/endian_store.hpp b/include/boost/endian/detail/endian_store.hpp index 523f039..6e7aaf8 100644 --- a/include/boost/endian/detail/endian_store.hpp +++ b/include/boost/endian/detail/endian_store.hpp @@ -6,6 +6,7 @@ // Distributed under the Boost Software License, Version 1.0. // http://www.boost.org/LICENSE_1_0.txt +#include #include #include #include @@ -15,6 +16,12 @@ #include #include +#if BOOST_ENDIAN_HAS_CXX20_CONSTEXPR +#include +#include +#endif + + namespace boost { namespace endian @@ -37,7 +44,7 @@ template struct end // if N < sizeof(T), T is integral or enum template -inline void endian_store( unsigned char * p, T const & v ) BOOST_NOEXCEPT +BOOST_ENDIAN_CXX20_CONSTEXPR void endian_store( unsigned char * p, T const & v ) BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8 ); BOOST_ENDIAN_STATIC_ASSERT( N >= 1 && N <= sizeof(T) ); @@ -52,11 +59,18 @@ namespace detail template struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( is_trivially_copyable::value ); - - std::memcpy( p, &v, N ); +#if BOOST_ENDIAN_HAS_CXX20_CONSTEXPR + if (std::is_constant_evaluated()) { + auto tmp = std::bit_cast>(v); + std::copy(tmp.data(), tmp.data() + N, p); + } else +#endif + { + std::memcpy(p, &v, N); + } } }; @@ -64,16 +78,23 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( is_trivially_copyable::value ); - - typename integral_by_size::type tmp; - std::memcpy( &tmp, &v, N ); - - endian_reverse_inplace( tmp ); - - std::memcpy( p, &tmp, N ); +#if BOOST_ENDIAN_HAS_CXX20_CONSTEXPR + if (std::is_constant_evaluated()) { + auto tmp = std::bit_cast>(v); + std::reverse_copy(tmp.data(), tmp.data() + N, p); + } else +#endif + { + typename integral_by_size::type tmp; + std::memcpy( &tmp, &v, N ); + + endian_reverse_inplace(tmp); + + std::memcpy( p, &tmp, N ); + } } }; @@ -81,7 +102,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -94,7 +115,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -109,7 +130,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -122,7 +143,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -137,7 +158,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -151,7 +172,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -167,7 +188,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -182,7 +203,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -199,7 +220,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -212,7 +233,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -227,7 +248,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -241,7 +262,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -257,7 +278,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -272,7 +293,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -289,7 +310,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -305,7 +326,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -323,7 +344,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -340,7 +361,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -359,7 +380,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -377,7 +398,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -397,7 +418,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value ); @@ -416,7 +437,7 @@ template struct endian_store_impl struct endian_store_impl { - inline void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT + BOOST_ENDIAN_CXX20_CONSTEXPR void operator()( unsigned char * p, T const & v ) const BOOST_NOEXCEPT { BOOST_ENDIAN_STATIC_ASSERT( std::is_integral::value || std::is_enum::value );