Skip to content

Commit

Permalink
add assign
Browse files Browse the repository at this point in the history
  • Loading branch information
shogo314 committed Feb 11, 2024
1 parent 1e19897 commit d30a94c
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 9 deletions.
72 changes: 63 additions & 9 deletions cpp/rolling-hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <random>
#include <cassert>

#include "traits.hpp"

struct RHString;

/**
Expand Down Expand Up @@ -116,13 +118,19 @@ struct RHString {
RHString(RollingHash& rh) : rh(rh), sz(0), hash1(0), hash2(0) {}
RHString(RollingHash& rh, size_t sz, unsigned long long hash1, unsigned long long hash2) : rh(rh), sz(sz), hash1(hash1), hash2(hash2) {}
RHString(const RHString& o) : rh(o.rh), sz(o.sz), hash1(o.hash1), hash2(o.hash2) {}
template <typename R>
RHString(RollingHash& rh, R s) : rh(rh) {
using std::begin, std::end;
template <class R, class = std::enable_if_t<is_range_v<R>>>
RHString(RollingHash& rh, R&& s) : rh(rh) {
using std::begin, std::end, std::rbegin, std::rend;
sz = std::distance(begin(s), end(s));
hash1 = rh.build(begin(s), end(s)).back();
hash2 = rh.build(rbegin(s), rend(s)).back();
}
template <class T, class = std::enable_if_t<!is_range_v<T>>>
RHString(RollingHash& rh, T x) : rh(rh) {
sz = 1;
hash1 = x;
hash2 = x;
}

/**
* @brief 回文か否か
Expand Down Expand Up @@ -150,22 +158,68 @@ struct RHString {
sz += o.sz;
return *this;
}
RHString& operator=(const RHString& o) {
/**
* @brief 再代入する
*/
void assign(const RHString& o) {
assert(&rh == &o.rh);
sz = o.sz;
hash1 = o.hash1;
hash2 = o.hash2;
return *this;
}
/**
* @brief 文字列などで初期化する
* @brief 文字列(std::string)などで再代入する
*/
template <typename R>
RHString& assign(const R& s) {
template <class R, class = std::enable_if_t<is_range_v<R>>>
void assign(R&& s) {
using std::begin, std::end;
sz = std::distance(begin(s), end(s));
hash1 = rh.build(begin(s), end(s)).back();
hash2 = rh.build(rbegin(s), rend(s)).back();
}
/**
* @brief 文字(char)などで再代入する
*/
template <class T, class = std::enable_if_t<not is_range_v<T>>>
void assign(T x) {
sz = 1;
hash1 = x;
hash2 = x;
}
/**
* @brief const char*で再代入する
*/
void assign(const char* s) {
assign(std::string(s));
}
/**
* @brief 再代入する
*/
RHString& operator=(const RHString& o) {
assign(o);
return *this;
}
/**
* @brief 文字列(std::string)などで再代入する
*/
template <class R, class = std::enable_if_t<is_range_v<R>>>
RHString& operator=(R&& s) {
assign(s);
return *this;
}
/**
* @brief 文字(char)などで再代入する
*/
template <class T, class = std::enable_if_t<not is_range_v<T>>>
RHString& operator=(T x) {
assign(x);
return *this;
}
/**
* @brief const char*で再代入する
*/
RHString& operator=(const char* s) {
assign(s);
return *this;
}
friend RHString operator+(const RHString& t1, const RHString& t2) {
Expand All @@ -175,7 +229,7 @@ struct RHString {
}
friend bool operator==(const RHString& t1, const RHString& t2) {
assert(&t1.rh == &t2.rh);
return t1.hash1 == t2.hash1 && t1.hash2 == t2.hash2;
return t1.sz == t2.sz && t1.hash1 == t2.hash1 && t1.hash2 == t2.hash2;
}
friend bool operator!=(const RHString& t1, const RHString& t2) { return !(t1 == t2); }
};
19 changes: 19 additions & 0 deletions cpp/traits.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <iterator>
#include <type_traits>
#include <utility>

namespace detail {
using std::begin, std::end;

template <class T, class = void>
struct is_range_impl : std::false_type {};
template <class T>
struct is_range_impl<T, std::void_t<decltype(begin(std::declval<T&>()), end(std::declval<T&>()))>> : std::true_type {};
} // namespace detail

template <class T>
struct is_range : detail::is_range_impl<T>::type {};
template <class T>
inline constexpr bool is_range_v = is_range<T>::value;

0 comments on commit d30a94c

Please sign in to comment.