#line 1 "monoid/monoid_addsz.hpp"
#include<concepts>#line 1 "monoid/monoid.hpp"
#line 5 "monoid/monoid.hpp"
#include<functional>
#include<type_traits>namespacem1une{template<typenameT,autooperation,autoidentity,boolcommutative>structmonoid{static_assert(std::is_invocable_r_v<T,decltype(operation),T,T>,"operation must work as T(T, T)");static_assert(std::is_invocable_r_v<T,decltype(identity)>,"identity must work as T()");usingvalue_type=T;staticconstexprautoop=operation;staticconstexprautoid=identity;staticconstexprboolis_commutative=commutative;};template<typenameT>conceptMonoid=requires(typenameT::value_typev){typenameT::value_type;{T::op(v,v)}->std::same_as<typenameT::value_type>;{T::id()}->std::same_as<typenameT::value_type>;{T::is_commutative}->std::convertible_to<bool>;};}// namespace m1une#line 7 "monoid/monoid_addsz.hpp"
namespacem1une{template<typenameT>structvalue_and_size{Tvalue;intsize;};template<MonoidM>usingmonoid_addsz=monoid<value_and_size<typenameM::value_type>,[](value_and_size<typenameM::value_type>a,value_and_size<typenameM::value_type>b){returnvalue_and_size<typenameM::value_type>{M::op(a.value,b.value),a.size+b.size};},[](){returnvalue_and_size<typenameM::value_type>{M::id(),0};},M::is_commutative>;}// namespace m1une