Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / histogram / detail / optional_index.hpp
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_DETAIL_OPTIONAL_INDEX_HPP
8 #define BOOST_HISTOGRAM_DETAIL_OPTIONAL_INDEX_HPP
9
10 #include <boost/assert.hpp>
11 #include <cstdint>
12
13 namespace boost {
14 namespace histogram {
15 namespace detail {
16
17 constexpr auto invalid_index = ~static_cast<std::size_t>(0);
18
19 // integer with a persistent invalid state, similar to NaN
20 struct optional_index {
21   std::size_t value;
22
23   optional_index& operator=(std::size_t x) noexcept {
24     value = x;
25     return *this;
26   }
27
28   optional_index& operator+=(std::intptr_t x) noexcept {
29     BOOST_ASSERT(x >= 0 || static_cast<std::size_t>(-x) <= value);
30     if (value != invalid_index) { value += x; }
31     return *this;
32   }
33
34   optional_index& operator+=(const optional_index& x) noexcept {
35     if (value != invalid_index) return operator+=(x.value);
36     value = invalid_index;
37     return *this;
38   }
39
40   operator std::size_t() const noexcept { return value; }
41
42   friend bool operator<=(std::size_t x, optional_index idx) noexcept {
43     return x <= idx.value;
44   }
45 };
46
47 constexpr inline bool is_valid(const std::size_t) noexcept { return true; }
48
49 inline bool is_valid(const optional_index x) noexcept { return x.value != invalid_index; }
50
51 } // namespace detail
52 } // namespace histogram
53 } // namespace boost
54
55 #endif