proconlib

This documentation is automatically generated by competitive-verifier/competitive-verifier

View the Project on GitHub anqooqie/proconlib

:heavy_check_mark: Concept for a type compatible with atcoder::static_modint (tools/modint_compatible.hpp)

template <typename T>
concept modint_compatible = std::regular<T>
  && std::equality_comparable<T>
  && std::constructible_from<T, bool>
  && std::constructible_from<T, char>
  && std::constructible_from<T, int>
  && std::constructible_from<T, long long>
  && std::constructible_from<T, unsigned int>
  && std::constructible_from<T, unsigned long long>
  && requires(T a, T b, int v_int, long long v_ll) {
    { T::mod() } -> std::convertible_to<int>;
    { T::raw(v_int) } -> std::same_as<T>;
    { a.val() } -> std::convertible_to<int>;
    { ++a } -> std::same_as<T&>;
    { --a } -> std::same_as<T&>;
    { a++ } -> std::same_as<T>;
    { a-- } -> std::same_as<T>;
    { a += b } -> std::same_as<T&>;
    { a -= b } -> std::same_as<T&>;
    { a *= b } -> std::same_as<T&>;
    { a /= b } -> std::same_as<T&>;
    { +a } -> std::same_as<T>;
    { -a } -> std::same_as<T>;
    { a.pow(v_ll) } -> std::same_as<T>;
    { a.inv() } -> std::same_as<T>;
    { a + b } -> std::same_as<T>;
    { a - b } -> std::same_as<T>;
    { a * b } -> std::same_as<T>;
    { a / b } -> std::same_as<T>;
  };

It is a concept that represents a type compatible with atcoder::static_modint. For example, it accepts atcoder::dynamic_modint and tools::modint_for_rolling_hash.

Constraints

Time Complexity

License

Author

Required by

Verified with

Code

#ifndef TOOLS_MODINT_COMPATIBLE_HPP
#define TOOLS_MODINT_COMPATIBLE_HPP

#include <concepts>
#include <type_traits>

namespace tools {
  template <typename T>
  concept modint_compatible = std::regular<std::remove_cv_t<T>>
    && std::equality_comparable<std::remove_cv_t<T>>
    && std::constructible_from<std::remove_cv_t<T>, bool>
    && std::constructible_from<std::remove_cv_t<T>, char>
    && std::constructible_from<std::remove_cv_t<T>, int>
    && std::constructible_from<std::remove_cv_t<T>, long long>
    && std::constructible_from<std::remove_cv_t<T>, unsigned int>
    && std::constructible_from<std::remove_cv_t<T>, unsigned long long>
    && requires(std::remove_cv_t<T> a, std::remove_cv_t<T> b, int v_int, long long v_ll) {
      { std::remove_cv_t<T>::mod() } -> std::convertible_to<int>;
      { std::remove_cv_t<T>::raw(v_int) } -> std::same_as<std::remove_cv_t<T>>;
      { a.val() } -> std::convertible_to<int>;
      { ++a } -> std::same_as<std::remove_cv_t<T>&>;
      { --a } -> std::same_as<std::remove_cv_t<T>&>;
      { a++ } -> std::same_as<std::remove_cv_t<T>>;
      { a-- } -> std::same_as<std::remove_cv_t<T>>;
      { a += b } -> std::same_as<std::remove_cv_t<T>&>;
      { a -= b } -> std::same_as<std::remove_cv_t<T>&>;
      { a *= b } -> std::same_as<std::remove_cv_t<T>&>;
      { a /= b } -> std::same_as<std::remove_cv_t<T>&>;
      { +a } -> std::same_as<std::remove_cv_t<T>>;
      { -a } -> std::same_as<std::remove_cv_t<T>>;
      { a.pow(v_ll) } -> std::same_as<std::remove_cv_t<T>>;
      { a.inv() } -> std::same_as<std::remove_cv_t<T>>;
      { a + b } -> std::same_as<std::remove_cv_t<T>>;
      { a - b } -> std::same_as<std::remove_cv_t<T>>;
      { a * b } -> std::same_as<std::remove_cv_t<T>>;
      { a / b } -> std::same_as<std::remove_cv_t<T>>;
    };
}

#endif
#line 1 "tools/modint_compatible.hpp"



#include <concepts>
#include <type_traits>

namespace tools {
  template <typename T>
  concept modint_compatible = std::regular<std::remove_cv_t<T>>
    && std::equality_comparable<std::remove_cv_t<T>>
    && std::constructible_from<std::remove_cv_t<T>, bool>
    && std::constructible_from<std::remove_cv_t<T>, char>
    && std::constructible_from<std::remove_cv_t<T>, int>
    && std::constructible_from<std::remove_cv_t<T>, long long>
    && std::constructible_from<std::remove_cv_t<T>, unsigned int>
    && std::constructible_from<std::remove_cv_t<T>, unsigned long long>
    && requires(std::remove_cv_t<T> a, std::remove_cv_t<T> b, int v_int, long long v_ll) {
      { std::remove_cv_t<T>::mod() } -> std::convertible_to<int>;
      { std::remove_cv_t<T>::raw(v_int) } -> std::same_as<std::remove_cv_t<T>>;
      { a.val() } -> std::convertible_to<int>;
      { ++a } -> std::same_as<std::remove_cv_t<T>&>;
      { --a } -> std::same_as<std::remove_cv_t<T>&>;
      { a++ } -> std::same_as<std::remove_cv_t<T>>;
      { a-- } -> std::same_as<std::remove_cv_t<T>>;
      { a += b } -> std::same_as<std::remove_cv_t<T>&>;
      { a -= b } -> std::same_as<std::remove_cv_t<T>&>;
      { a *= b } -> std::same_as<std::remove_cv_t<T>&>;
      { a /= b } -> std::same_as<std::remove_cv_t<T>&>;
      { +a } -> std::same_as<std::remove_cv_t<T>>;
      { -a } -> std::same_as<std::remove_cv_t<T>>;
      { a.pow(v_ll) } -> std::same_as<std::remove_cv_t<T>>;
      { a.inv() } -> std::same_as<std::remove_cv_t<T>>;
      { a + b } -> std::same_as<std::remove_cv_t<T>>;
      { a - b } -> std::same_as<std::remove_cv_t<T>>;
      { a * b } -> std::same_as<std::remove_cv_t<T>>;
      { a / b } -> std::same_as<std::remove_cv_t<T>>;
    };
}


Back to top page