Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:10

0001 // Copyright 2019 Hans Dembinski
0002 //
0003 // Distributed under the Boost Software License, Version 1.0.
0004 // (See accompanying file LICENSE_1_0.txt
0005 // or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_HISTOGRAM_AXIS_METADATA_BASE_HPP
0008 #define BOOST_HISTOGRAM_AXIS_METADATA_BASE_HPP
0009 
0010 #include <boost/histogram/axis/traits.hpp>
0011 #include <boost/histogram/detail/replace_type.hpp>
0012 #include <string>
0013 #include <type_traits>
0014 
0015 namespace boost {
0016 namespace histogram {
0017 namespace axis {
0018 
0019 /** Meta data holder with space optimization for empty meta data types.
0020 
0021   Allows write-access to metadata even if const.
0022 
0023   @tparam Metadata Wrapped meta data type.
0024  */
0025 template <class Metadata, bool Detail>
0026 class metadata_base {
0027 protected:
0028   using metadata_type = Metadata;
0029 
0030   static_assert(std::is_default_constructible<metadata_type>::value,
0031                 "metadata must be default constructible");
0032 
0033   static_assert(std::is_copy_constructible<metadata_type>::value,
0034                 "metadata must be copy constructible");
0035 
0036   static_assert(std::is_copy_assignable<metadata_type>::value,
0037                 "metadata must be copy assignable");
0038 
0039   // std::string explicitly guarantees nothrow only in C++17
0040   static_assert(std::is_same<metadata_type, std::string>::value ||
0041                     std::is_nothrow_move_constructible<metadata_type>::value,
0042                 "metadata must be nothrow move constructible");
0043 
0044   metadata_base() = default;
0045   metadata_base(const metadata_base&) = default;
0046   metadata_base& operator=(const metadata_base&) = default;
0047 
0048   // make noexcept because std::string is nothrow move constructible only in C++17
0049   metadata_base(metadata_base&& o) noexcept : data_(std::move(o.data_)) {}
0050   metadata_base(metadata_type&& o) noexcept : data_(std::move(o)) {}
0051   // make noexcept because std::string is nothrow move constructible only in C++17
0052   metadata_base& operator=(metadata_base&& o) noexcept {
0053     data_ = std::move(o.data_);
0054     return *this;
0055   }
0056 
0057 public:
0058   /// Returns reference to metadata.
0059   metadata_type& metadata() noexcept { return data_; }
0060 
0061   /// Returns reference to mutable metadata from const axis.
0062   metadata_type& metadata() const noexcept { return data_; }
0063 
0064 private:
0065   mutable metadata_type data_;
0066 };
0067 
0068 #ifndef BOOST_HISTOGRAM_DOXYGEN_INVOKED
0069 
0070 // specialization for empty metadata
0071 template <class Metadata>
0072 class metadata_base<Metadata, true> {
0073 protected:
0074   using metadata_type = Metadata;
0075 
0076   metadata_base() = default;
0077 
0078   metadata_base(metadata_type&&) {}
0079   metadata_base& operator=(metadata_type&&) { return *this; }
0080 
0081 public:
0082   metadata_type& metadata() noexcept {
0083     return static_cast<const metadata_base&>(*this).metadata();
0084   }
0085 
0086   metadata_type& metadata() const noexcept {
0087     static metadata_type data;
0088     return data;
0089   }
0090 };
0091 
0092 template <class Metadata, class Detail = detail::replace_default<Metadata, std::string>>
0093 using metadata_base_t =
0094     metadata_base<Detail, (std::is_empty<Detail>::value && std::is_final<Detail>::value)>;
0095 
0096 #endif
0097 
0098 } // namespace axis
0099 } // namespace histogram
0100 } // namespace boost
0101 
0102 #endif