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 #include "collections/traits/std-extents.hpp"
22 
23 
25 {
26  namespace detail_get
27  {
28 #ifdef __cpp_concepts
29  template<typename T, typename I>
30 #else
31  template<typename T, typename I, typename = void>
32 #endif
33  struct has_member_get_function : std::false_type {};
34 
35 #ifdef __cpp_concepts
36  template<typename T, typename I> requires requires { std::declval<T&&>().template get<values::fixed_value_of<I>::value>(); }
37  struct has_member_get_function<T, I>
38 #else
39  template<typename T, typename I>
40  struct has_member_get_function<T, I, std::void_t<decltype(std::declval<T>().template get<values::fixed_value_of<I>::value>())>>
41 #endif
42  : std::true_type {};
43 
44 
45  using std::get;
46 
47 #ifdef __cpp_concepts
48  template<typename T, typename I>
49 #else
50  template<typename T, typename I, typename = void>
51 #endif
52  struct has_adl_get_function : std::false_type {};
53 
54 #ifdef __cpp_concepts
55  template<typename T, typename I> requires requires { get<values::fixed_value_of<I>::value>(std::declval<T&&>()); }
56  struct has_adl_get_function<T, I>
57 #else
58  template<typename T, typename I>
59  struct has_adl_get_function<T, I, std::void_t<decltype(get<values::fixed_value_of<I>::value>(std::declval<T>()))>>
60 #endif
61  : std::true_type {};
62 
63 
64  template<typename Arg, typename I>
65  constexpr decltype(auto)
66  get_element_impl(Arg&& arg, I ix)
67  {
69  {
70  return std::forward<Arg>(arg).template get<values::fixed_value_of_v<I>>();
71  }
72  else if constexpr (has_adl_get_function<Arg, I>::value)
73  {
74  return get<values::fixed_value_of_v<I>>(std::forward<Arg>(arg));
75  }
76  else
77  {
78  std::size_t n = values::to_value_type(std::move(ix));
79  if constexpr (std::is_array_v<stdex::remove_cvref_t<Arg>>)
80  {
81  return std::forward<Arg>(arg)[n];
82  }
83  else if constexpr (stdex::ranges::borrowed_range<Arg>)
84  {
85  return stdex::ranges::begin(std::forward<Arg>(arg))[n];
86  }
87  else
88  {
89  using namespace std;
90  return begin(std::forward<Arg>(arg))[n];
91  }
92  }
93 
94  };
95 
96  }
97 
98 
110 #ifdef __cpp_concepts
111  template<typename Arg, values::index I> requires
112  (not values::size_compares_with<I, size_of<Arg>, &stdex::is_gteq>) and
113  (stdex::ranges::random_access_range<Arg> or
116 #else
117  template<typename Arg, typename I, std::enable_if_t<values::index<I> and
118  (not values::size_compares_with<I, size_of<Arg>, &stdex::is_gteq>) and
119  (stdex::ranges::random_access_range<Arg> or
120  detail_get::has_member_get_function<Arg, I>::value or
121  detail_get::has_adl_get_function<Arg, I>::value), int> = 0>
122 #endif
123  constexpr decltype(auto)
124  get_element(Arg&& arg, I i)
125  {
126  return detail_get::get_element_impl(std::forward<Arg>(arg), i);
127  }
128 
129 
130 }
131 
132 
133 #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:124