rotgen/include/rotgen/operators.hpp
2025-09-28 16:15:15 +02:00

97 lines
No EOL
3.8 KiB
C++

//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <rotgen/concepts.hpp>
#include <cassert>
#include <iosfwd>
namespace rotgen
{
template<concepts::entity E>
std::ostream& operator<<(std::ostream& os, E const& arg)
{
return os << arg.base();
}
template<typename A, typename B>
constexpr bool operator==(A const& a, B const& b) noexcept
requires(concepts::entity<A> || concepts::entity<B>)
{
static_assert ( std::same_as<typename A::value_type,typename B::value_type>
, "[ROTGEN] Incompatible type in operator=="
);
if constexpr(!use_expression_templates) return generalize_t<A const>(a) == generalize_t<B const>(b);
else return base_of(a) == base_of(b);
}
template<typename A, typename B>
constexpr bool operator!=(A const& a, B const& b) noexcept
requires(concepts::entity<A> || concepts::entity<B>)
{
static_assert ( std::same_as<typename A::value_type,typename B::value_type>
, "[ROTGEN] Incompatible type in operator!="
);
if constexpr(!use_expression_templates) return generalize_t<A const>(a) != generalize_t<B const>(b);
else return base_of(a) != base_of(b);
}
template<typename A, typename B>
auto operator+(A const& a, B const& b) requires(concepts::entity<A> || concepts::entity<B>)
{
if constexpr(!use_expression_templates) return generalize_t<A const>(a) + generalize_t<B const>(b);
else return base_of(a) + base_of(b);
}
template<typename A, typename B>
auto operator-(A const& a, B const& b) requires(concepts::entity<A> || concepts::entity<B>)
{
if constexpr(!use_expression_templates) return generalize_t<A const>(a) - generalize_t<B const>(b);
else return base_of(a) - base_of(b);
}
template<typename A, typename B>
auto operator*(A const& a, B const& b) requires(concepts::entity<A> || concepts::entity<B>)
{
if constexpr(!use_expression_templates) return generalize_t<A const>(a) * generalize_t<B const>(b);
else return base_of(a) * base_of(b);
}
template<typename A, typename B>
auto operator/(A const& a, B const& b) requires(concepts::entity<A> && std::is_arithmetic_v<B>)
{
if constexpr(!use_expression_templates) return generalize_t<A const>(a) / b;
else return base_of(a) / b;
}
//------------------------------------------------------------------------------------------------
// Compounds operators across types
template<typename A, typename B>
auto operator+=(A& a, B const& b)
requires(concepts::entity<A> || concepts::entity<B>)
{
if constexpr(!use_expression_templates) return generalize_t<A>(a) += generalize_t<B const>(b);
else return base_of(a) += base_of(b);
}
template<typename A, typename B>
auto operator-=(A& a, B const& b)
requires(concepts::entity<A> || concepts::entity<B>)
{
if constexpr(!use_expression_templates) return generalize_t<A>(a) -= generalize_t<B const>(b);
else return base_of(a) -= base_of(b);
}
template<typename A, typename B>
auto operator*=(A& a, B const& b)
requires(concepts::entity<A> || concepts::entity<B>)
{
if constexpr(!use_expression_templates) return generalize_t<A>(a) *= generalize_t<B const>(b);
else return base_of(a) *= base_of(b);
}
}