m1une's library

This documentation is automatically generated by online-judge-tools/verification-helper

View on GitHub

:question: Monoid
(monoid/monoid.hpp)

Overview

This file provides a generic struct to define a Monoid, which is a fundamental algebraic structure used in various data structures.

Properties

A monoid is a set of elements $S$ equipped with a single binary operation $(\cdot)$ that satisfies the following two properties:

  1. Associativity: For any three elements $a, b, c \in S$, the equation $(a \cdot b) \cdot c = a \cdot (b \cdot c)$ holds.
  2. Identity Element: There exists an identity element $e \in S$ such that for any element $a \in S$, the equation $e \cdot a = a \cdot e = a$ holds.

This monoid struct serves as a template for creating specific monoids (like for addition, multiplication, etc.) that can be passed as template parameters to data structures like the Segment Tree.

Template Parameters

Members

Usage Example

The library provides several pre-defined monoids. Here is how add_monoid is defined using this base struct:

template <typename T>
using add_monoid = monoid<T, [](T a, T b) { return a + b; }, []() { return T(0); }, true>;

This defines a monoid for addition on any type T, where the operation is +, the identity is 0, and the operation is commutative.

Required by

Verified with

Code

#ifndef M1UNE_MONOID_HPP
#define M1UNE_MONOID_HPP 1

#include <concepts>
#include <functional>
#include <type_traits>

namespace m1une {

template <typename T, auto operation, auto identity, bool commutative>
struct monoid {
    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()");

    using value_type = T;
    static constexpr auto op = operation;
    static constexpr auto id = identity;
    static constexpr bool is_commutative = commutative;
};

template <typename T>
concept Monoid = requires(typename T::value_type v) {
    typename T::value_type;
    { T::op(v, v) } -> std::same_as<typename T::value_type>;
    { T::id() } -> std::same_as<typename T::value_type>;
    { T::is_commutative } -> std::convertible_to<bool>;
};

}  // namespace m1une

#endif  // M1UNE_MONOID_HPP
#line 1 "monoid/monoid.hpp"



#include <concepts>
#include <functional>
#include <type_traits>

namespace m1une {

template <typename T, auto operation, auto identity, bool commutative>
struct monoid {
    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()");

    using value_type = T;
    static constexpr auto op = operation;
    static constexpr auto id = identity;
    static constexpr bool is_commutative = commutative;
};

template <typename T>
concept Monoid = requires(typename T::value_type v) {
    typename T::value_type;
    { T::op(v, v) } -> std::same_as<typename T::value_type>;
    { T::id() } -> std::same_as<typename T::value_type>;
    { T::is_commutative } -> std::convertible_to<bool>;
};

}  // namespace m1une
Back to top page