Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:33:57

0001 /*
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * Copyright (c) 2018 Andrey Semashev
0007  */
0008 /*!
0009  * \file   atomic/detail/integral_conversions.hpp
0010  *
0011  * This header defines sign/zero extension and truncation utilities for Boost.Atomic. The tools assume two's complement signed integer representation.
0012  */
0013 
0014 #ifndef BOOST_ATOMIC_DETAIL_INTEGRAL_CONVERSIONS_HPP_INCLUDED_
0015 #define BOOST_ATOMIC_DETAIL_INTEGRAL_CONVERSIONS_HPP_INCLUDED_
0016 
0017 #include <boost/atomic/detail/config.hpp>
0018 #include <boost/atomic/detail/bitwise_cast.hpp>
0019 #include <boost/atomic/detail/type_traits/integral_constant.hpp>
0020 #include <boost/atomic/detail/type_traits/is_signed.hpp>
0021 #include <boost/atomic/detail/type_traits/make_signed.hpp>
0022 #include <boost/atomic/detail/type_traits/make_unsigned.hpp>
0023 #include <boost/atomic/detail/header.hpp>
0024 
0025 #ifdef BOOST_HAS_PRAGMA_ONCE
0026 #pragma once
0027 #endif
0028 
0029 namespace boost {
0030 namespace atomics {
0031 namespace detail {
0032 
0033 template< typename Output, typename Input >
0034 BOOST_FORCEINLINE Output zero_extend_impl(Input input, atomics::detail::true_type) BOOST_NOEXCEPT
0035 {
0036     // Note: If we are casting with truncation or to the same-sized output, don't cause signed integer overflow by this chain of conversions
0037     return atomics::detail::bitwise_cast< Output >(static_cast< typename atomics::detail::make_unsigned< Output >::type >(
0038         static_cast< typename atomics::detail::make_unsigned< Input >::type >(input)));
0039 }
0040 
0041 template< typename Output, typename Input >
0042 BOOST_FORCEINLINE Output zero_extend_impl(Input input, atomics::detail::false_type) BOOST_NOEXCEPT
0043 {
0044     return static_cast< Output >(static_cast< typename atomics::detail::make_unsigned< Input >::type >(input));
0045 }
0046 
0047 //! Zero-extends or truncates (wraps) input operand to fit in the output type
0048 template< typename Output, typename Input >
0049 BOOST_FORCEINLINE Output zero_extend(Input input) BOOST_NOEXCEPT
0050 {
0051     return atomics::detail::zero_extend_impl< Output >(input, atomics::detail::integral_constant< bool, atomics::detail::is_signed< Output >::value >());
0052 }
0053 
0054 //! Truncates (wraps) input operand to fit in the output type
0055 template< typename Output, typename Input >
0056 BOOST_FORCEINLINE Output integral_truncate(Input input) BOOST_NOEXCEPT
0057 {
0058     // zero_extend does the truncation
0059     return atomics::detail::zero_extend< Output >(input);
0060 }
0061 
0062 template< typename Output, typename Input >
0063 BOOST_FORCEINLINE Output sign_extend_impl(Input input, atomics::detail::true_type) BOOST_NOEXCEPT
0064 {
0065     return atomics::detail::integral_truncate< Output >(input);
0066 }
0067 
0068 template< typename Output, typename Input >
0069 BOOST_FORCEINLINE Output sign_extend_impl(Input input, atomics::detail::false_type) BOOST_NOEXCEPT
0070 {
0071     return static_cast< Output >(atomics::detail::bitwise_cast< typename atomics::detail::make_signed< Input >::type >(input));
0072 }
0073 
0074 //! Sign-extends or truncates (wraps) input operand to fit in the output type
0075 template< typename Output, typename Input >
0076 BOOST_FORCEINLINE Output sign_extend(Input input) BOOST_NOEXCEPT
0077 {
0078     return atomics::detail::sign_extend_impl< Output >(input, atomics::detail::integral_constant< bool, sizeof(Output) <= sizeof(Input) >());
0079 }
0080 
0081 //! Sign-extends or truncates (wraps) input operand to fit in the output type
0082 template< typename Output, typename Input >
0083 BOOST_FORCEINLINE Output integral_extend(Input input, atomics::detail::true_type) BOOST_NOEXCEPT
0084 {
0085     return atomics::detail::sign_extend< Output >(input);
0086 }
0087 
0088 //! Zero-extends or truncates (wraps) input operand to fit in the output type
0089 template< typename Output, typename Input >
0090 BOOST_FORCEINLINE Output integral_extend(Input input, atomics::detail::false_type) BOOST_NOEXCEPT
0091 {
0092     return atomics::detail::zero_extend< Output >(input);
0093 }
0094 
0095 //! Sign- or zero-extends or truncates (wraps) input operand to fit in the output type
0096 template< bool Signed, typename Output, typename Input >
0097 BOOST_FORCEINLINE Output integral_extend(Input input) BOOST_NOEXCEPT
0098 {
0099     return atomics::detail::integral_extend< Output >(input, atomics::detail::integral_constant< bool, Signed >());
0100 }
0101 
0102 } // namespace detail
0103 } // namespace atomics
0104 } // namespace boost
0105 
0106 #include <boost/atomic/detail/footer.hpp>
0107 
0108 #endif // BOOST_ATOMIC_DETAIL_INTEGRAL_CONVERSIONS_HPP_INCLUDED_