OpenKalman
operation.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-2024 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_SCALAR_CONSTANT_OPERATION_HPP
18 #define OPENKALMAN_SCALAR_CONSTANT_OPERATION_HPP
19 
22 
23 namespace OpenKalman::values
24 {
31 #ifdef __cpp_concepts
32  template<typename Operation, typename...Args>
33  struct operation {};
34 
35 
36  template<typename Operation, value...Args> requires (... or not fixed<Args>) or
37  (not requires { std::bool_constant<(Operation{}(to_number(Args{})...), true)>::value; })
38  struct operation<Operation, Args...>
39  {
40  explicit constexpr operation(const Operation& op, Args...args) : value {op(to_number(std::move(args))...)} {};
41  using value_type = std::decay_t<decltype(std::declval<const Operation&>()(to_number(std::declval<Args&&>())...))>;
42  using type = operation;
43  constexpr operator value_type() const { return value; }
44  constexpr value_type operator()() const { return value; }
45 
46  private:
47  value_type value;
48  };
49 
50 
54  template<typename Operation, values::fixed...Args> requires
55  std::bool_constant<(Operation{}(values::to_number(Args{})...), true)>::value
56  struct operation<Operation, Args...>
57  {
58  constexpr operation() = default;
59  explicit constexpr operation(const Operation&, const Args&...) {};
60  static constexpr auto value = Operation{}(values::to_number(Args{})...);
61  using value_type = std::decay_t<decltype(value)>;
62  using type = operation;
63  constexpr operator value_type() const { return value; }
64  constexpr value_type operator()() const { return value; }
65 
66  };
67 #else
68  template<typename Operation, typename...Args>
69  struct operation;
70 
71 
72  namespace detail
73  {
74  template<typename Operation, typename = void, typename...Args>
76 
77 
78  template<typename Op, typename = void, typename...Args>
79  struct operation_invocable : std::false_type{};
80 
81  template<typename Op, typename...Args>
82  struct operation_invocable<Op, std::void_t<std::bool_constant<(Op{}(values::to_number(Args{})...), true)>>, Args...>
83  : std::true_type{};
84 
85 
86  // n-ary, not calculable at compile time
87  template<typename Operation, typename...Args>
88  struct constant_operation_impl<Operation, std::enable_if_t<(... and value<Args>) and
89  ((... or not fixed<Args>) or not operation_invocable<Operation, void, Args...>::value)>, Args...>
90  {
91  explicit constexpr constant_operation_impl(const Operation& op, Args...args) : value {op(values::to_number(std::move(args))...)} {};
92  using value_type = std::decay_t<decltype(std::declval<const Operation&>()(values::to_number(std::declval<Args&&>())...))>;
93  using type = operation<Operation, Args...>;
94  constexpr operator value_type() const { return value; }
95  constexpr value_type operator()() const { return value; }
96 
97  private:
98  value_type value;
99  };
100 
101 
102  // n-ary, all arguments calculable at compile time
103  template<typename Operation, typename...Args>
104  struct constant_operation_impl<Operation, std::enable_if_t<
105  (... and values::fixed<Args>) and operation_invocable<Operation, void, Args...>::value>, Args...>
106  {
107  constexpr constant_operation_impl() = default;
108  explicit constexpr constant_operation_impl(const Operation&, const Args&...) {};
109  static constexpr auto value = Operation{}(values::to_number(Args{})...);
110  using value_type = std::decay_t<decltype(value)>;
111  using type = operation<Operation, Args...>;
112  constexpr operator value_type() const { return value; }
113  constexpr value_type operator()() const { return value; }
114  constexpr auto operator+() { return static_cast<type&>(*this); }
115  constexpr auto operator-() { return operation {std::negate<value_type>{}, static_cast<type&>(*this)}; }
116  };
117  }
118 
119 
120  template<typename Operation, typename...Args>
121  struct operation : detail::constant_operation_impl<Operation, void, Args...>
122  {
123  private:
124  using Base = detail::constant_operation_impl<Operation, void, Args...>;
125  public:
126  using Base::Base;
127  };
128 #endif
129 
130 
134  template<typename Operation, typename...Args>
135  explicit operation(const Operation&, const Args&...) -> operation<Operation, Args...>;
136 
137 } // namespace OpenKalman::values
138 
139 #endif //OPENKALMAN_SCALAR_CONSTANT_OPERATION_HPP
Definition for values::to_number.
An operation involving some number of values.
Definition: operation.hpp:69
Definition: tuple_reverse.hpp:103
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
constexpr auto to_number(Arg arg)
Convert any values::value to a values::number.
Definition: to_number.hpp:34
Definition for values::abs.
Definition: constant_coefficient.hpp:25
constexpr bool fixed
T is a values::value that is determinable at compile time.
Definition: fixed.hpp:60
operation(const Operation &, const Args &...) -> operation< Operation, Args... >
Deduction guide.
Definition for ::value.