OpenKalman
view_interface.hpp
Go to the documentation of this file.
1 /* This file is part of OpenKalman, a header-only C++ library for
2  * Kalman filters and other recursive filters.
3  *
4  * Copyright (c) 2025 Christopher Lee Ogden <ogden@gatech.edu>
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
9  */
10 
17 #ifndef OPENKALMAN_COMPATIBILITY_RANGES_VIEW_INTERFACE_HPP
18 #define OPENKALMAN_COMPATIBILITY_RANGES_VIEW_INTERFACE_HPP
19 
20 #ifndef __cpp_lib_ranges
21 
22 #include <type_traits>
24 
25 namespace OpenKalman::ranges
26 {
31  template<typename Derived>
33  {
34  template<typename D = Derived, std::enable_if_t<sized_range<D> or forward_range<D>, int> = 0>
35  [[nodiscard]] constexpr bool
36  empty()
37  {
38  auto& derived = static_cast<D&>(*this);
39  if constexpr (sized_range<D>) return ranges::size(derived) == 0;
40  else return begin(derived) == end(derived);
41  }
42 
43  template<typename D = const Derived, std::enable_if_t<sized_range<D> or forward_range<D>, int> = 0>
44  [[nodiscard]] constexpr bool
45  empty() const
46  {
47  auto& derived = static_cast<D&>(*this);
48  if constexpr (sized_range<D>) return ranges::size(derived) == 0;
49  else return begin(derived) == end(derived);
50  }
51 
52 
53  template<typename D = Derived, std::enable_if_t<range<D>, int> = 0>
54  constexpr auto
55  cbegin() { return ranges::cbegin(static_cast<D&>(*this)); }
56 
57  template<typename D = const Derived, std::enable_if_t<range<D>, int> = 0>
58  constexpr auto
59  cbegin() const { return ranges::cbegin(static_cast<D&>(*this)); }
60 
61 
62  template<typename D = Derived, std::enable_if_t<range<D>, int> = 0>
63  constexpr auto
64  cend() { return ranges::cend(static_cast<D&>(*this)); }
65 
66  template<typename D = const Derived, std::enable_if_t<range<D>, int> = 0>
67  constexpr auto
68  cend() const { return ranges::cend(static_cast<D&>(*this)); }
69 
70 
71  template<typename D = Derived, typename = std::void_t<decltype(ranges::empty(std::declval<D&>()))>>
72  constexpr explicit
73  operator bool() { return not ranges::empty(static_cast<D&>(*this)); }
74 
75  template<typename D = const Derived, typename = std::void_t<decltype(ranges::empty(std::declval<D&>()))>>
76  constexpr explicit
77  operator bool() const { return not ranges::empty(static_cast<D&>(*this)); }
78 
79 
80  template<typename D = Derived, std::enable_if_t<forward_range<D>, int> = 0,
81  typename = std::void_t<decltype(end(std::declval<D&>()) - begin(std::declval<D&>()))>>
82  constexpr auto
83  size() { return end(static_cast<D&>(*this)) - begin(static_cast<D&>(*this)); }
84 
85  template<typename D = const Derived, std::enable_if_t<forward_range<D>, int> = 0,
86  typename = std::void_t<decltype(end(std::declval<D&>()) - begin(std::declval<D&>()))>>
87  constexpr auto
88  size() const { return end(static_cast<D&>(*this)) - begin(static_cast<D&>(*this)); }
89 
90 
91  template<typename D = Derived, std::enable_if_t<forward_range<D>, int> = 0>
92  constexpr decltype(auto)
93  front() { return *begin(static_cast<D&>(*this)); }
94 
95  template<typename D = const Derived, std::enable_if_t<forward_range<D>, int> = 0>
96  constexpr decltype(auto)
97  front() const { return *begin(static_cast<D&>(*this)); }
98 
99 
100  template<typename D = Derived, std::enable_if_t<bidirectional_range<D> and common_range<D>, int> = 0>
101  constexpr decltype(auto)
102  back() { return *std::prev(end(static_cast<D&>(*this))); }
103 
104  template<typename D = const Derived, std::enable_if_t<bidirectional_range<D> and common_range<D>, int> = 0>
105  constexpr decltype(auto)
106  back() const { return *std::prev(end(static_cast<D&>(*this))); }
107 
108 
109  template<typename D = Derived, std::enable_if_t<random_access_range<D>, int> = 0>
110  constexpr decltype(auto)
111  operator[](range_difference_t<D> n) { return begin(static_cast<D&>(*this))[n]; }
112 
113  template<typename D = const Derived, std::enable_if_t<random_access_range<D>, int> = 0>
114  constexpr decltype(auto)
115  operator[](range_difference_t<D> n) const { return begin(static_cast<D&>(*this))[n]; }
116 
117  };
118 
119 
120 } // namespace OpenKalman::collections
121 
122 #endif
123 
124 #endif //OPENKALMAN_COMPATIBILITY_RANGES_VIEW_INTERFACE_HPP
Definition: view_interface.hpp:32
Definition: range-access.hpp:25
constexpr bool size
T is either an index representing a size, or void which represents that there is no size...
Definition: size.hpp:32
Definitions implementing features of the c++ ranges library for compatibility.