diff --git a/include/boost/core/launder.hpp b/include/boost/core/launder.hpp new file mode 100644 index 0000000..d32d5a0 --- /dev/null +++ b/include/boost/core/launder.hpp @@ -0,0 +1,55 @@ +#ifndef BOOST_CORE_LAUNDER_HPP_INCLUDED +#define BOOST_CORE_LAUNDER_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#if defined(__has_builtin) +# if __has_builtin(__builtin_launder) +# define BOOST_CORE_HAS_BUILTIN_LAUNDER +# endif +#endif + +#if !defined(BOOST_CORE_HAS_BUILTIN_LAUNDER) +# include +#endif + +namespace boost +{ +namespace core +{ + +#if defined(BOOST_CORE_HAS_BUILTIN_LAUNDER) + +template T* launder( T* p ) +{ + return __builtin_launder( p ); +} + +#elif defined(__cpp_lib_launder) + +template T* launder( T* p ) +{ + return std::launder( p ); +} + +#else + +template T* launder( T* p ) +{ + return p; +} + +#endif + +} // namespace core +} // namespace boost + +#endif // #ifndef BOOST_CORE_LAUNDER_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index e9743be..3b1b5a1 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -352,5 +352,7 @@ run-fail verbose_terminate_handler_fail.cpp : : : off : verb run-fail verbose_terminate_handler_fail.cpp : : : off : verbose_terminate_handler_fail_nr ; run-fail verbose_terminate_handler_fail.cpp : : : off off : verbose_terminate_handler_fail_nxr ; +run launder_test.cpp ; + use-project /boost/core/swap : ./swap ; build-project ./swap ; diff --git a/test/launder_test.cpp b/test/launder_test.cpp new file mode 100644 index 0000000..98adcfb --- /dev/null +++ b/test/launder_test.cpp @@ -0,0 +1,34 @@ +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +struct X +{ + int v_; + + explicit X( int v = 0 ): v_( v ) {} +}; + +int main() +{ + X x; + + typedef X const CX; + + ::new( &x ) CX( 1 ); + X const* px1 = &x; + + BOOST_TEST_EQ( px1->v_, 1 ); + + ::new( &x ) CX( 2 ); + X const* px2 = boost::core::launder( px1 ); + + BOOST_TEST_EQ( px1, px2 ); + BOOST_TEST_EQ( px2->v_, 2 ); + + return boost::report_errors(); +}