OpenKalman
set_chip.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) 2022-2023 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_SET_CHIP_HPP
17 #define OPENKALMAN_SET_CHIP_HPP
18 
19 namespace OpenKalman
20 {
21 
22  namespace detail
23  {
24  template<std::size_t>
25  constexpr auto chip_index_match() { return std::integral_constant<std::size_t, 0> {}; }
26 
27  template<std::size_t ai, std::size_t index, std::size_t...indices, typename I, typename...Is>
28  constexpr auto chip_index_match(I i, Is...is)
29  {
30  if constexpr (ai == index) return i;
31  else return chip_index_match<ai, indices...>(is...);
32  }
33 
34  template<std::size_t...indices, typename Arg, typename Chip, std::size_t...all_indices, typename...Is>
35  constexpr Arg& set_chip_impl(Arg&& arg, Chip&& chip, std::index_sequence<all_indices...>, Is...is)
36  {
37  return set_slice(std::forward<Arg>(arg), std::forward<Chip>(chip), chip_index_match<all_indices, indices...>(is...)...);
38  }
39  } // namespace detail
40 
41 
56 #ifdef __cpp_concepts
57  template<std::size_t...indices, writable Arg, indexible Chip, values::index...Ixs> requires
58  (sizeof...(indices) == sizeof...(Ixs))
59 #else
60  template<std::size_t...indices, typename Arg, typename Chip, typename...Ixs, std::enable_if_t<
61  writable<Arg> and indexible<Chip> and (values::index<Ixs> and ...) and (sizeof...(indices) == sizeof...(Ixs)), int> = 0>
62 #endif
63  constexpr Arg&&
64  set_chip(Arg&& arg, Chip&& chip, Ixs...ixs)
65  {
66  (... , []{
67  if constexpr (values::fixed<Ixs> and not dynamic_dimension<Arg, indices>)
68  static_assert(std::decay_t<Ixs>::value < index_dimension_of_v<Arg, indices>, "set_chip: indices must be in range");
69  }());
70 
71  static_assert((... and dimension_size_of_index_is<Chip, indices, 1, Applicability::permitted>),
72  "Argument chip to set_chip must be 1D in all the specified indices.");
73 
74  return detail::set_chip_impl<indices...>(std::forward<Arg>(arg), std::forward<Chip>(chip),
75  std::make_index_sequence<index_count_v<Arg>> {}, ixs...);
76  }
77 
78 } // namespace OpenKalman
79 
80 #endif //OPENKALMAN_SET_CHIP_HPP
constexpr bool indexible
T is a generalized tensor type.
Definition: indexible.hpp:32
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
The root namespace for OpenKalman.
Definition: basics.hpp:34
constexpr bool index
T is an index value.
Definition: index.hpp:56
constexpr Arg && set_chip(Arg &&arg, Chip &&chip, Ixs...ixs)
Set a sub-array having rank less than the rank of the input object.
Definition: set_chip.hpp:64
constexpr bool index
An object describing a collection of /ref values::index objects.
Definition: index.hpp:75
constexpr Arg && set_slice(Arg &&arg, Block &&block, const Begin &...begin)
Assign an object to a particular slice of a matrix or tensor.
Definition: set_slice.hpp:56