OpenKalman
truncate_indices.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) 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 
17 #ifndef OPENKALMAN_ELEMENT_FUNCTIONS_HPP
18 #define OPENKALMAN_ELEMENT_FUNCTIONS_HPP
19 
20 #include <algorithm>
21 #include <stdexcept>
22 #include <vector>
23 #if defined(__cpp_lib_ranges)
24 #include <ranges>
25 #else
27 #endif
28 
29 namespace OpenKalman::internal
30 {
31 #if __cpp_lib_ranges >= 202202L
32  template<std::ranges::input_range Indices, values::index MinCount>
33  constexpr decltype(auto) truncate_indices(const Indices& indices, const MinCount& min_count)
34  {
35  auto n {static_cast<std::ranges::range_difference_t<Indices>>(min_count)};
36  if (std::ranges::any_of(indices | std::ranges::views::drop(n), [](const auto& x){ return x != 0; }))
37  throw std::invalid_argument {"Component access: one or more trailing indices are not 0."};
38  return indices | std::ranges::views::take(n);
39  }
40 #else
41  template<typename Indices, typename MinCount, std::enable_if_t<values::index<MinCount>, int> = 0>
42  decltype(auto) truncate_indices(const Indices& indices, const MinCount& min_count)
43  {
44 #ifdef __cpp_lib_ranges
45  namespace ranges = std::ranges;
46 #endif
47  auto n {static_cast<std::size_t>(min_count)};
48  auto ad = ranges::begin(indices);
49  std::advance(ad, n);
50  if (std::any_of(ad, ranges::end(indices), [](const auto& x){ return x != 0; }))
51  throw std::invalid_argument {"Component access: one or more trailing indices are not 0."};
52  if constexpr (values::fixed<MinCount>)
53  {
54  std::array<std::size_t, MinCount::value> ret;
55  std::copy(ranges::begin(indices), ad, ranges::begin(ret));
56  return ret;
57  }
58  else
59  {
60  std::vector<std::size_t> ret {n};
61  std::copy(ranges::begin(indices), ad, ranges::begin(ret));
62  return ret;
63  }
64  }
65 #endif
66 } // namespace OpenKalman::internal
67 
68 #endif //OPENKALMAN_ELEMENT_FUNCTIONS_HPP
Definitions implementing features of the c++ ranges library for compatibility.
Definition: basics.hpp:48