Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-19 08:44:21

0001 /*
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * https://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * Copyright (c) 2022 Andrey Semashev
0007  */
0008 /*!
0009  * \file scope/detail/compact_storage.hpp
0010  *
0011  * This header contains utility helpers for implementing compact storage
0012  * for class members. In particular, it allows to leverage empty base optimization (EBO).
0013  */
0014 
0015 #ifndef BOOST_SCOPE_DETAIL_COMPACT_STORAGE_HPP_INCLUDED_
0016 #define BOOST_SCOPE_DETAIL_COMPACT_STORAGE_HPP_INCLUDED_
0017 
0018 #include <type_traits>
0019 #include <boost/scope/detail/config.hpp>
0020 #include <boost/scope/detail/type_traits/is_final.hpp>
0021 #include <boost/scope/detail/type_traits/negation.hpp>
0022 #include <boost/scope/detail/type_traits/conjunction.hpp>
0023 #include <boost/scope/detail/header.hpp>
0024 
0025 #ifdef BOOST_HAS_PRAGMA_ONCE
0026 #pragma once
0027 #endif
0028 
0029 namespace boost {
0030 namespace scope {
0031 namespace detail {
0032 
0033 //! The class allows to place data members in the tail padding of type \a T if the user's class derives from it
0034 template<
0035     typename T,
0036     typename Tag = void,
0037     bool = detail::conjunction< std::is_class< T >, detail::negation< detail::is_final< T > > >::value
0038 >
0039 class compact_storage :
0040     private T
0041 {
0042 public:
0043     template< typename... Args >
0044     constexpr compact_storage(Args&&... args) noexcept(std::is_nothrow_constructible< T, Args... >::value) :
0045         T(static_cast< Args&& >(args)...)
0046     {
0047     }
0048 
0049     compact_storage(compact_storage&&) = default;
0050     compact_storage& operator= (compact_storage&&) = default;
0051 
0052     compact_storage(compact_storage const&) = default;
0053     compact_storage& operator= (compact_storage const&) = default;
0054 
0055     T& get() noexcept
0056     {
0057         return *static_cast< T* >(this);
0058     }
0059 
0060     T const& get() const noexcept
0061     {
0062         return *static_cast< const T* >(this);
0063     }
0064 };
0065 
0066 template< typename T, typename Tag >
0067 class compact_storage< T, Tag, false >
0068 {
0069 private:
0070     T m_data;
0071 
0072 public:
0073     template< typename... Args >
0074     constexpr compact_storage(Args&&... args) noexcept(std::is_nothrow_constructible< T, Args... >::value) :
0075         m_data(static_cast< Args&& >(args)...)
0076     {
0077     }
0078 
0079     compact_storage(compact_storage&&) = default;
0080     compact_storage& operator= (compact_storage&&) = default;
0081 
0082     compact_storage(compact_storage const&) = default;
0083     compact_storage& operator= (compact_storage const&) = default;
0084 
0085     T& get() noexcept
0086     {
0087         return m_data;
0088     }
0089 
0090     T const& get() const noexcept
0091     {
0092         return m_data;
0093     }
0094 };
0095 
0096 } // namespace detail
0097 } // namespace scope
0098 } // namespace boost
0099 
0100 #include <boost/scope/detail/footer.hpp>
0101 
0102 #endif // BOOST_SCOPE_DETAIL_COMPACT_STORAGE_HPP_INCLUDED_