OpenKalman
invocable_on_collection.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_INVOCABLE_ON_COLLECTION_HPP
17 #define OPENKALMAN_INVOCABLE_ON_COLLECTION_HPP
18 
19 #include "collection.hpp"
20 #include "uniformly_gettable.hpp"
23 
25 {
26  namespace detail
27  {
28 #if not defined(__cpp_concepts) or __cpp_generic_lambdas < 201707L
29  template<typename R, typename F, typename = void, typename...Args>
30  struct is_invocable_on_range : std::false_type {};
31 
32  template<typename R, typename F, typename...Args>
33  struct is_invocable_on_range<R, F, std::enable_if_t<stdex::ranges::range<R>>, Args...>
34  : std::bool_constant<std::is_invocable_v<F, stdex::ranges::range_value_t<R>, Args...>> {};
35 
36 
37  template<typename Tup, typename = void>
38  struct is_invocable_on_tuple_sequence { using type = std::index_sequence<>; };
39 
40  template<typename Tup>
41  struct is_invocable_on_tuple_sequence<Tup, std::enable_if_t<uniformly_gettable<Tup>>>
42  { using type = std::make_index_sequence<size_of_v<Tup>>; };
43 
44 
45  template<typename Tup, typename F, typename Seq, typename...Args>
46  struct is_invocable_on_tuple : std::false_type {};
47 
48  template<typename Tup, typename F, std::size_t...Ix, typename...Args>
49  struct is_invocable_on_tuple<Tup, F, std::index_sequence<Ix...>, Args...>
50  : std::bool_constant<(... and std::is_invocable_v<F&, collection_element_t<Ix, Tup>, Args...>)> {};
51 #endif
52 
53  }
54 
55 
59  template<typename F, typename C, typename...Args>
60 #if defined(__cpp_concepts) and __cpp_generic_lambdas >= 201707L
61  concept invocable_on_collection = collection<C> and
62  (not stdex::ranges::range<C> or std::regular_invocable<F, stdex::ranges::range_value_t<C>, Args&&...>) and
63  (not uniformly_gettable<C> or
64  []<std::size_t...i>(std::index_sequence<i...>) {
65  return (... and std::regular_invocable<F&, typename collection_element<i, C>::type, Args&&...>);
66  } (std::make_index_sequence<size_of_v<C>>{}));
67 #else
68  constexpr bool invocable_on_collection =
69  (not stdex::ranges::range<C> or detail::is_invocable_on_range<C, F, void, Args&&...>::value) and
70  (not uniformly_gettable<C> or
71  detail::is_invocable_on_tuple<C, F, typename detail::is_invocable_on_tuple_sequence<C>::type, Args&&...>::value);
72 #endif
73 
74 
75 }
76 
77 #endif
Namespace for collections.
Definition: collections.hpp:27
Definition for collections::collection.
constexpr bool uniformly_gettable
T is a fixed-size object that is gettable for all indices.
Definition: uniformly_gettable.hpp:55
constexpr bool invocable_on_collection
Callable object F is invocable on each element of collection C, with additional parameters Args...
Definition: invocable_on_collection.hpp:68
Definition for collections::size_of.
constexpr bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
Definition: trait_backports.hpp:64
Definition for collections::uniformly_gettable.
Definition for collections::collection_element.