OpenKalman
get.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 
16 #ifndef OPENKALMAN_COLLECTIONS_GET_HPP
17 #define OPENKALMAN_COLLECTIONS_GET_HPP
18 
19 #include <tuple>
20 #ifdef __cpp_lib_ranges
21 #include <ranges>
22 #endif
30 
32 {
33 #ifndef __cpp_lib_ranges
34  namespace detail
35  {
36  template<typename T, typename I>
37  inline constexpr bool gettable_with_i = []
38  {
39  if constexpr (values::fixed<I>) { return gettable<values::fixed_number_of_v<I>, T>; }
40  else { return false; }
41  }();
42  }
43 #endif
44 
45 
54 #ifdef __cpp_lib_ranges
55  template<collection Arg, values::index I> requires std::ranges::random_access_range<Arg> or
56  (values::fixed<I> and gettable<values::fixed_number_of_v<I>, Arg>)
57 #else
58  template<typename Arg, typename I, std::enable_if_t<collection<Arg> and values::index<I> and
59  (ranges::random_access_range<Arg> or detail::gettable_with_i<Arg, I>), int> = 0>
60 #endif
61  constexpr decltype(auto)
62  get(Arg&& arg, I i)
63  {
64  if constexpr (sized<Arg> and values::fixed<I>)
65  { static_assert(size_of_v<Arg> == dynamic_size or values::fixed_number_of_v<I> < size_of_v<Arg>, "Index out of range"); }
66 
67 #ifdef __cpp_lib_ranges
68  if constexpr (values::fixed<I> and requires { requires gettable<values::fixed_number_of<I>::value, Arg>; })
69 #else
70  if constexpr (detail::gettable_with_i<Arg, I>)
71 #endif
72  {
73  return OpenKalman::internal::generalized_std_get<values::fixed_number_of_v<I>>(std::forward<Arg>(arg));
74  }
75  else
76  {
77 #ifdef __cpp_lib_remove_cvref
78  using std::remove_cvref_t;
79 #endif
80 #ifdef __cpp_lib_ranges
81  namespace ranges = std::ranges;
82 #endif
83 
84  std::size_t n = values::to_number(std::move(i));
85  if constexpr (std::is_array_v<remove_cvref_t<Arg>>)
86  return std::forward<Arg>(arg)[n];
87  else if constexpr (ranges::borrowed_range<Arg>)
88  return ranges::begin(std::forward<Arg>(arg))[n];
89  else
90  return begin(std::forward<Arg>(arg))[n];
91  }
92  }
93 
94 
95 } // namespace OpenKalman::collections
96 
97 #endif //OPENKALMAN_COLLECTIONS_GET_HPP
Definition for values::index.
Namespace for collections.
Definition: collections.hpp:27
Definition for collections::collection.
decltype(auto) constexpr get(Arg &&arg, I i)
A generalization of std::get.
Definition: get.hpp:62
Definition for values::fixed_number_of.
constexpr bool gettable
T has an element i that is accessible by a get(...) function.
Definition: gettable.hpp:58
Definition for collections::size_of.
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
constexpr auto to_number(Arg arg)
Convert any values::value to a values::number.
Definition: to_number.hpp:34
Definitions implementing features of the c++ ranges library for compatibility.
Definition for ::fixed.
constexpr std::size_t dynamic_size
A constant indicating that a size or index is dynamic.
Definition: global-definitions.hpp:33
Global definitions for OpenKalman.