This documentation is automatically generated by competitive-verifier/competitive-verifier
#include "tools/square.hpp"
(1)
template <typename M>
typename M::T square(typename M::T x);
(2)
template <typename T>
T square(T x);
It returns $x^2$ under a given monoid. The default monoid is $(\mathbb{Z}, \times)$.
x * x
is defined.M::op(x, x)
x * x
#ifndef TOOLS_SQUARE_HPP
#define TOOLS_SQUARE_HPP
#include <type_traits>
#include "tools/is_monoid.hpp"
namespace tools {
template <typename M>
::std::enable_if_t<::tools::is_monoid_v<M>, typename M::T> square(const typename M::T& x) {
return M::op(x, x);
}
template <typename T>
::std::enable_if_t<!::tools::is_monoid_v<T>, T> square(const T& x) {
return x * x;
}
}
#endif
#line 1 "tools/square.hpp"
#include <type_traits>
#line 1 "tools/is_monoid.hpp"
#line 5 "tools/is_monoid.hpp"
#include <utility>
namespace tools {
template <typename M, typename = void>
struct is_monoid : ::std::false_type {};
template <typename M>
struct is_monoid<M, ::std::enable_if_t<
::std::is_same_v<typename M::T, decltype(M::op(::std::declval<typename M::T>(), ::std::declval<typename M::T>()))> &&
::std::is_same_v<typename M::T, decltype(M::e())>
, void>> : ::std::true_type {};
template <typename M>
inline constexpr bool is_monoid_v = ::tools::is_monoid<M>::value;
}
#line 6 "tools/square.hpp"
namespace tools {
template <typename M>
::std::enable_if_t<::tools::is_monoid_v<M>, typename M::T> square(const typename M::T& x) {
return M::op(x, x);
}
template <typename T>
::std::enable_if_t<!::tools::is_monoid_v<T>, T> square(const T& x) {
return x * x;
}
}