]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // Copyright 2019 Hans Dembinski |
2 | // | |
3 | // Distributed under the Boost Software License, Version 1.0. | |
4 | // (See accompanying file LICENSE_1_0.txt | |
5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | #ifndef BOOST_HISTOGRAM_AXIS_METADATA_BASE_HPP | |
8 | #define BOOST_HISTOGRAM_AXIS_METADATA_BASE_HPP | |
9 | ||
20effc67 | 10 | #include <boost/histogram/axis/traits.hpp> |
92f5a8d4 TL |
11 | #include <boost/histogram/detail/replace_type.hpp> |
12 | #include <string> | |
13 | #include <type_traits> | |
14 | ||
15 | namespace boost { | |
16 | namespace histogram { | |
17 | namespace axis { | |
18 | ||
20effc67 | 19 | /** Meta data holder with space optimization for empty meta data types. |
92f5a8d4 | 20 | |
20effc67 TL |
21 | Allows write-access to metadata even if const. |
22 | ||
23 | @tparam Metadata Wrapped meta data type. | |
24 | */ | |
25 | template <class Metadata, bool Detail> | |
26 | class metadata_base { | |
92f5a8d4 | 27 | protected: |
20effc67 | 28 | using metadata_type = Metadata; |
92f5a8d4 TL |
29 | |
30 | // std::string explicitly guarantees nothrow only in C++17 | |
31 | static_assert(std::is_same<metadata_type, std::string>::value || | |
32 | std::is_nothrow_move_constructible<metadata_type>::value, | |
33 | "metadata must be nothrow move constructible"); | |
34 | ||
35 | metadata_base() = default; | |
36 | metadata_base(const metadata_base&) = default; | |
37 | metadata_base& operator=(const metadata_base&) = default; | |
38 | ||
39 | // make noexcept because std::string is nothrow move constructible only in C++17 | |
20effc67 TL |
40 | metadata_base(metadata_base&& o) noexcept : data_(std::move(o.data_)) {} |
41 | metadata_base(metadata_type&& o) noexcept : data_(std::move(o)) {} | |
92f5a8d4 TL |
42 | // make noexcept because std::string is nothrow move constructible only in C++17 |
43 | metadata_base& operator=(metadata_base&& o) noexcept { | |
20effc67 | 44 | data_ = std::move(o.data_); |
92f5a8d4 TL |
45 | return *this; |
46 | } | |
47 | ||
20effc67 TL |
48 | private: |
49 | mutable metadata_type data_; | |
50 | ||
92f5a8d4 TL |
51 | public: |
52 | /// Returns reference to metadata. | |
20effc67 TL |
53 | metadata_type& metadata() noexcept { return data_; } |
54 | ||
55 | /// Returns reference to mutable metadata from const axis. | |
56 | metadata_type& metadata() const noexcept { return data_; } | |
57 | }; | |
92f5a8d4 | 58 | |
20effc67 | 59 | #ifndef BOOST_HISTOGRAM_DOXYGEN_INVOKED |
92f5a8d4 | 60 | |
20effc67 TL |
61 | // specialization for empty metadata |
62 | template <class Metadata> | |
63 | class metadata_base<Metadata, true> { | |
64 | protected: | |
65 | using metadata_type = Metadata; | |
66 | ||
67 | metadata_base() = default; | |
68 | ||
69 | metadata_base(metadata_type&&) {} | |
70 | metadata_base& operator=(metadata_type&&) { return *this; } | |
71 | ||
72 | public: | |
73 | metadata_type& metadata() noexcept { | |
74 | return static_cast<const metadata_base&>(*this).metadata(); | |
92f5a8d4 TL |
75 | } |
76 | ||
20effc67 TL |
77 | metadata_type& metadata() const noexcept { |
78 | static metadata_type data; | |
79 | return data; | |
92f5a8d4 TL |
80 | } |
81 | }; | |
82 | ||
20effc67 TL |
83 | template <class Metadata, class Detail = detail::replace_default<Metadata, std::string>> |
84 | using metadata_base_t = | |
85 | metadata_base<Detail, (std::is_empty<Detail>::value && std::is_final<Detail>::value)>; | |
86 | ||
87 | #endif | |
88 | ||
92f5a8d4 TL |
89 | } // namespace axis |
90 | } // namespace histogram | |
91 | } // namespace boost | |
92 | ||
93 | #endif |