OpenKalman
get_element.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_ELEMENT_HPP
17 #define OPENKALMAN_COLLECTIONS_GET_ELEMENT_HPP
18 
19 #include "values/values.hpp"
21 
23 {
24  namespace detail_get
25  {
26 #ifdef __cpp_concepts
27  template<typename T, typename I>
28 #else
29  template<typename T, typename I, typename = void>
30 #endif
31  struct has_member_get_function : std::false_type {};
32 
33 #ifdef __cpp_concepts
34  template<typename T, typename I> requires requires { std::declval<T&&>().template get<values::fixed_value_of<I>::value>(); }
35  struct has_member_get_function<T, I>
36 #else
37  template<typename T, typename I>
38  struct has_member_get_function<T, I, std::void_t<decltype(std::declval<T>().template get<values::fixed_value_of<I>::value>())>>
39 #endif
40  : std::true_type {};
41 
42 
43  using std::get;
44 
45 #ifdef __cpp_concepts
46  template<typename T, typename I>
47 #else
48  template<typename T, typename I, typename = void>
49 #endif
50  struct has_adl_get_function : std::false_type {};
51 
52 #ifdef __cpp_concepts
53  template<typename T, typename I> requires requires { get<values::fixed_value_of<I>::value>(std::declval<T&&>()); }
54  struct has_adl_get_function<T, I>
55 #else
56  template<typename T, typename I>
57  struct has_adl_get_function<T, I, std::void_t<decltype(get<values::fixed_value_of<I>::value>(std::declval<T>()))>>
58 #endif
59  : std::true_type {};
60 
61 
62  template<typename Arg, typename I>
63  constexpr decltype(auto)
64  get_element_impl(Arg&& arg, I ix)
65  {
67  {
68  return std::forward<Arg>(arg).template get<values::fixed_value_of_v<I>>();
69  }
70  else if constexpr (has_adl_get_function<Arg, I>::value)
71  {
72  return get<values::fixed_value_of_v<I>>(std::forward<Arg>(arg));
73  }
74  else
75  {
76  std::size_t n = values::to_value_type(std::move(ix));
77  if constexpr (std::is_array_v<stdex::remove_cvref_t<Arg>>)
78  {
79  return std::forward<Arg>(arg)[n];
80  }
81  else if constexpr (stdex::ranges::borrowed_range<Arg>)
82  {
83  return stdex::ranges::begin(std::forward<Arg>(arg))[n];
84  }
85  else
86  {
87  using namespace std;
88  return begin(std::forward<Arg>(arg))[n];
89  }
90  }
91 
92  };
93 
94  }
95 
96 
108 #ifdef __cpp_concepts
109  template<typename Arg, values::index I> requires
110  (not values::size_compares_with<I, size_of<Arg>, &stdex::is_gteq>) and
111  (stdex::ranges::random_access_range<Arg> or
114 #else
115  template<typename Arg, typename I, std::enable_if_t<values::index<I> and
116  (not values::size_compares_with<I, size_of<Arg>, &stdex::is_gteq>) and
117  (stdex::ranges::random_access_range<Arg> or
118  detail_get::has_member_get_function<Arg, I>::value or
119  detail_get::has_adl_get_function<Arg, I>::value), int> = 0>
120 #endif
121  constexpr decltype(auto)
122  get_element(Arg&& arg, I i)
123  {
124  return detail_get::get_element_impl(std::forward<Arg>(arg), i);
125  }
126 
127 
128 }
129 
130 #endif
Namespace for collections.
Definition: collections.hpp:27
constexpr detail_get::get_impl< i > get
A generalization of std::get, where the index is known at compile time.
Definition: get.hpp:50
Header file for code relating to values (e.g., scalars and indices)
decltype(auto) constexpr to_value_type(Arg &&arg)
Convert, if necessary, a fixed or dynamic value to its underlying base type.
Definition: to_value_type.hpp:28
Definition for collections::size_of.
The size of a sized object (including a collection).
Definition: size_of.hpp:33
The fixed value associated with a fixed.
Definition: fixed_value_of.hpp:44
constexpr bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
constexpr bool size_compares_with
T and U are sizes that compare in a particular way based on parameter comp.
Definition: size_compares_with.hpp:98
decltype(auto) constexpr get_element(Arg &&arg, I i)
A generalization of std::get and the range subscript operator.
Definition: get_element.hpp:122