27#ifndef LIBSEMIGROUPS_WORD_RANGE_HPP_
28#define LIBSEMIGROUPS_WORD_RANGE_HPP_
32#include <initializer_list>
37#include <unordered_map>
43#include "exception.hpp"
47#include "detail/word-iterators.hpp"
51 enum class Order : uint8_t;
54 std::string
const& chars_in_human_readable_order();
68 template <
typename Word>
207 [[nodiscard]] detail::const_wilo_iterator
214 [[nodiscard]] detail::const_wilo_iterator
cend_wilo(
size_t n,
263 [[nodiscard]] detail::const_wislo_iterator
274 [[nodiscard]] detail::const_wislo_iterator
cend_wislo(
size_t n,
282 [[nodiscard]] detail::const_wislo_iterator
cend_wislo(
size_t n,
327 using const_iterator = std::variant<detail::const_wilo_iterator,
328 detail::const_wislo_iterator>;
331 mutable const_iterator _current;
332 mutable const_iterator _end;
333 mutable bool _current_valid;
340 void set_iterator()
const;
357 [](
auto& it) ->
auto const& {
return *it; }, _current);
373 std::visit([](
auto& it) { ++it; }, _current);
383 [[nodiscard]]
bool at_end() const noexcept {
385 return _current == _end;
415 [[nodiscard]]
size_t count() const noexcept;
489 _current_valid &= (n == _alphabet_size);
503 return _alphabet_size;
520 _current_valid &= (frst == _first);
552 _current_valid &= (lst == _last);
607 _current_valid &= (n == _upper_bound);
678 return rx::begin(*
this);
697 auto end() const noexcept {
698 return rx::end(*
this);
723 return _current_valid;
740 size_t max_width = 72);
817 _alphabet_map.clear();
857 [[nodiscard]]
bool empty() const noexcept {
858 return _alphabet_map.empty();
890 return _alphabet_map.count(c) == 1;
1021 return _alphabet_map.find(input)->second;
1024 template <
typename InputRange>
1045 template <
typename InputRange,
1046 typename = std::enable_if_t<rx::is_input_or_sink_v<InputRange>>>
1047 [[nodiscard]]
constexpr auto operator()(InputRange&& input)
const {
1048 using Inner = rx::get_range_type_t<InputRange>;
1056 template <
typename InputRange>
1057 struct ToWord::Range {
1060 static constexpr bool is_finite = rx::is_finite_v<InputRange>;
1061 static constexpr bool is_idempotent = rx::is_idempotent_v<InputRange>;
1066 explicit Range(InputRange
const& input,
ToWord const& t_wrd)
1067 : _input(input), _to_word(t_wrd) {}
1069 explicit Range(InputRange&& input,
ToWord const& t_wrd)
1070 : _input(std::
move(input)), _to_word(t_wrd) {}
1072 explicit Range(InputRange
const& input,
ToWord&& t_wrd)
1073 : _input(input), _to_word(std::
move(t_wrd)) {}
1075 explicit Range(InputRange&& input,
ToWord&& t_wrd)
1076 : _input(std::
move(input)), _to_word(std::
move(t_wrd)) {}
1079 [[nodiscard]] output_type get()
const {
1080 return _to_word.operator()(_input.get());
1083 constexpr void next() noexcept {
1087 [[nodiscard]]
constexpr bool at_end() const noexcept {
1088 return _input.at_end();
1091 [[nodiscard]]
constexpr size_t size_hint() const noexcept {
1092 return _input.size_hint();
1107 return fmt::format(
"<ToWord object with alphabet \"{}\">", twrd.
alphabet());
1182 _alphabet_map.clear();
1222 [[nodiscard]]
bool empty() const noexcept {
1223 return _alphabet_map.empty();
1255 return _alphabet_map.count(l) == 1;
1360 template <
typename Int>
1363 static_assert(std::is_integral_v<Int>);
1368 template <
typename InputRange>
1387 template <
typename InputRange,
1388 typename = std::enable_if_t<rx::is_input_or_sink_v<InputRange>>>
1389 [[nodiscard]]
constexpr auto operator()(InputRange&& input)
const {
1390 using Inner = rx::get_range_type_t<InputRange>;
1401 template <
typename InputRange>
1402 struct ToString::Range {
1405 static constexpr bool is_finite = rx::is_finite_v<InputRange>;
1406 static constexpr bool is_idempotent = rx::is_idempotent_v<InputRange>;
1411 Range(InputRange
const& input,
ToString const& t_str)
1412 : _input(input), _to_string(t_str) {}
1414 Range(InputRange&& input,
ToString const& t_str)
1415 : _input(std::
move(input)), _to_string(t_str) {}
1417 Range(InputRange
const& input,
ToString&& t_str)
1418 : _input(input), _to_string(std::
move(t_str)) {}
1420 Range(InputRange&& input,
ToString&& t_str)
1421 : _input(std::
move(input)), _to_string(std::
move(t_str)) {}
1426 [[nodiscard]] output_type get()
const {
1427 return _to_string(_input.get());
1430 constexpr void next() noexcept {
1434 [[nodiscard]]
constexpr bool at_end() const noexcept {
1435 return _input.at_end();
1438 [[nodiscard]]
constexpr size_t size_hint() const noexcept {
1439 return _input.size_hint();
1445#if defined(__clang__)
1446 template <
typename InputRange>
1447 ToString::Range<InputRange>::~Range<InputRange>() =
default;
1448#elif defined(__GNUC__)
1449 template <
typename InputRange>
1450 ToString::Range<InputRange>::~Range() =
default;
1463 [[nodiscard]]
inline std::string
1465 return fmt::format(
"<ToString object with alphabet \"{}\">",
1474 void throw_if_random_string_should_throw(
std::string const& alphabet,
1538 detail::throw_if_random_string_should_throw(alphabet, min, max);
1542 return rx::generate([alphabet, min, max] {
1593 mutable bool _current_valid;
1599 void init_current()
const {
1600 if (!_current_valid) {
1601 _current = _to_string(_word_range.get());
1602 _current_valid =
true;
1633 _current_valid =
false;
1646 return _word_range.at_end();
1660 return _word_range.size_hint();
1675 return _word_range.count();
1762 _word_range.
first(_to_word(frst));
1763 _current_valid &= _word_range.valid();
1778 return _to_string(_word_range.first());
1798 _word_range.
last(_to_word(lst));
1799 _current_valid &= _word_range.valid();
1814 return _to_string(_word_range.last());
1828 _word_range.
order(val);
1829 _current_valid &= _word_range.valid();
1842 return _word_range.order();
1858 _current_valid &= _word_range.valid();
1872 return _word_range.upper_bound();
1887 _word_range.
min(val);
1888 _current_valid &= _word_range.valid();
1910 _word_range.
max(val);
1911 _current_valid &= _word_range.valid();
1932 return rx::begin(*
this);
1952 return rx::end(*
this);
1969 size_t max_width = 72);
2107 template <
typename Word = std::
string>
2113 if constexpr (
sizeof(
typename Word::value_type) <
sizeof(size_t)) {
2117 "expected the argument to be in the range [0, {}), found {}",
2123 if constexpr (!std::is_same_v<Word, std::string>) {
2124 return static_cast<typename Word::value_type
>(i);
2130 return detail::chars_in_human_readable_order()[i];
2211 template <
typename Word>
2229 template <
typename Word>
2230 Word
pow(Word
const& x,
size_t n) {
2288 template <
typename Container,
typename Word = Container>
2289 Word
prod(Container
const& elts,
int first,
int last,
int step = 1);
2305 prod(std::string_view sv,
int first,
int last,
int step = 1) {
2329 sv, first, last, step);
2337 template <
typename Container,
typename Word = Container>
2338 Word
prod(Container
const& elts,
size_t last) {
2339 return prod(elts, 0,
static_cast<int>(last), 1);
2349 return prod(elts, 0,
static_cast<int>(last), 1);
2359 elts, 0,
static_cast<int>(last), 1);
2369 return prod(elts, 0,
static_cast<int>(last), 1);
2387 template <
typename Word>
2390 x.reserve(x.size() * n);
2410 template <
typename Container,
typename Word>
2411 Word
prod(Container
const& elts,
int first,
int last,
int step) {
2414 }
else if (((first < last && step > 0) || (first > last && step < 0))
2415 && elts.size() == 0) {
2417 "given range is not empty");
2422 "the 1st argument must have size less than or equal to {}",
2426 int const s = elts.size();
2432 result.reserve((last - first) / step);
2434 for (
int i = first; i < last; i += step) {
2435 size_t const a = (i % s + s) % s;
2436 LIBSEMIGROUPS_ASSERT(
static_cast<int>(a) < s);
2443 size_t steppos =
static_cast<size_t>(-step);
2444 result.reserve((first - last) / steppos);
2445 for (
int i = first; i > last; i += step) {
2446 size_t const a = (i % s + s) % s;
2447 LIBSEMIGROUPS_ASSERT(
static_cast<int>(a) < s);
Class for generating strings in a given range and in a particular order.
Definition word-range.hpp:1583
static constexpr bool is_finite
Value indicating that the range is finite.
Definition word-range.hpp:1679
StringRange & operator=(StringRange const &)
Default copy assignment operator.
StringRange & min(size_type val)
Set the first string in the range by length.
Definition word-range.hpp:1886
auto end() const noexcept
Returns an input iterator pointing one beyond the last string in the range.
Definition word-range.hpp:1951
StringRange & upper_bound(size_type n)
Set an upper bound for the length of a string in the range.
Definition word-range.hpp:1856
std::string first() const noexcept
The current first string in the range.
Definition word-range.hpp:1777
StringRange & init()
Initialize an existing StringRange object.
StringRange & max(size_type val)
Set one past the last string in the range by length.
Definition word-range.hpp:1909
std::string last() const noexcept
The current one past the last string in the range.
Definition word-range.hpp:1813
StringRange & alphabet(std::string const &x)
Set the alphabet.
std::string const & alphabet() const noexcept
The current alphabet.
Definition word-range.hpp:1745
StringRange & order(Order val)
Set the order of the strings in the range.
Definition word-range.hpp:1827
StringRange()
Default constructor.
Definition word-range.hpp:1696
output_type get() const
Get the current value.
Definition word-range.hpp:1618
StringRange & first(std::string const &frst)
Set the first string in the range.
Definition word-range.hpp:1761
auto begin() const noexcept
Returns an input iterator pointing to the first string in the range.
Definition word-range.hpp:1931
size_type upper_bound() const noexcept
The current upper bound on the length of a string in the range.
Definition word-range.hpp:1871
StringRange(StringRange &&)
Default move constructor.
Order order() const noexcept
The current order of the strings in the range.
Definition word-range.hpp:1841
void next() noexcept
Advance to the next value.
Definition word-range.hpp:1631
static constexpr bool is_idempotent
Definition word-range.hpp:1684
size_t size_hint() const noexcept
The possible size of the range.
Definition word-range.hpp:1659
typename std::vector< std::string >::size_type size_type
Alias for the size type.
Definition word-range.hpp:1586
StringRange & operator=(StringRange &&)
Default move assignment operator.
std::string const & output_type
The type of the output of the range object.
Definition word-range.hpp:1589
size_t count() const noexcept
The actual size of the range.
Definition word-range.hpp:1674
bool at_end() const noexcept
Check if the range object is exhausted.
Definition word-range.hpp:1645
StringRange & last(std::string const &lst)
Set one past the last string in the range.
Definition word-range.hpp:1797
StringRange(StringRange const &)
Default copy constructor.
Class for converting word_type into std::string with specified alphabet.
Definition word-range.hpp:1135
ToString & init() noexcept
Initialize an existing ToString object.
Definition word-range.hpp:1181
bool can_convert_letter(letter_type const &l) const
Definition word-range.hpp:1254
ToString()
Default constructor.
Definition word-range.hpp:1140
constexpr auto operator()(InputRange &&input) const
Call operator for combining with other range objects.
Definition word-range.hpp:1389
bool empty() const noexcept
Check if the alphabet is defined.
Definition word-range.hpp:1222
ToString(ToString &&)
Default move constructor.
std::string operator()(std::initializer_list< Int > input) const
Convert a std::initializer_list to a std::string.
Definition word-range.hpp:1362
std::string call_no_checks(word_type const &input) const
Convert a word_type to a std::string.
Definition word-range.hpp:1296
ToString(ToString const &)
Default copy constructor.
std::string operator()(word_type const &input) const
Convert a word_type to a std::string.
Definition word-range.hpp:1338
ToString & init(std::string const &alphabet)
Initialize an existing Tostring object.
ToString & operator=(ToString &&)
Default move assignment.
void call_no_checks(std::string &output, word_type const &input) const
Convert a word_type to a std::string.
ToString(std::string const &alphabet)
Construct with given alphabet.
Definition word-range.hpp:1194
void operator()(std::string &output, word_type const &input) const
Convert a word_type to a std::string.
std::string alphabet() const
Return the alphabet used for conversion.
ToString & operator=(ToString const &)
Default copy assignment.
Class for converting strings to word_type with specified alphabet.
Definition word-range.hpp:769
ToWord & init(std::string const &alphabet)
Initialize an existing ToWord object.
word_type call_no_checks(std::string const &input) const
Convert a string to a word_type.
Definition word-range.hpp:931
ToWord & init()
Initialize an existing ToWord object.
Definition word-range.hpp:816
word_type operator()(std::string const &input) const
Convert a string to a word_type.
Definition word-range.hpp:973
void operator()(word_type &output, std::string const &input) const
Convert a string to a word_type.
ToWord(std::string const &alphabet)
Construct with given alphabet.
Definition word-range.hpp:829
constexpr auto operator()(InputRange &&input) const
Call operator for combining with other range objects.
Definition word-range.hpp:1047
bool empty() const noexcept
Check if the alphabet is defined.
Definition word-range.hpp:857
ToWord & operator=(ToWord const &)
Default copy assignment.
ToWord & operator=(ToWord &&)
Default move assignment.
ToWord(ToWord &&)
Default move constructor.
bool can_convert_letter(char const &c) const
Definition word-range.hpp:889
letter_type call_no_checks(char input) const
Convert a char to a letter_type.
Definition word-range.hpp:1020
void call_no_checks(word_type &output, std::string const &input) const
Convert a string to a word_type.
ToWord()
Default constructor.
Definition word-range.hpp:775
std::string alphabet() const
Return the alphabet used for conversion.
ToWord(ToWord const &)
Default copy constructor.
letter_type operator()(char input) const
Convert a char to a letter_type.
Definition word-range.hpp:994
Class for generating words in a given range and in a particular order.
Definition word-range.hpp:318
static constexpr bool is_finite
Definition word-range.hpp:421
output_type get() const noexcept
Get the current value.
Definition word-range.hpp:354
word_type const & output_type
The type of the output of a WordRange object.
Definition word-range.hpp:324
auto end() const noexcept
Returns an input iterator pointing one beyond the last word in the range.
Definition word-range.hpp:697
word_type const & last() const noexcept
The current one past the last word in the range.
Definition word-range.hpp:567
WordRange & last(word_type const &lst)
Set one past the last word in the range.
Definition word-range.hpp:551
WordRange(WordRange &&)
Default move constructor.
WordRange & min(size_type val)
Set the first word in the range by length.
Definition word-range.hpp:636
WordRange & max(size_type val)
Set one past the last word in the range by length.
Definition word-range.hpp:656
typename std::vector< word_type >::size_type size_type
Alias for the size type.
Definition word-range.hpp:321
WordRange(WordRange const &)
Default copy constructor.
WordRange & upper_bound(size_type n)
Set an upper bound for the length of a word in the range.
Definition word-range.hpp:606
word_type const & first() const noexcept
The current first word in the range.
Definition word-range.hpp:535
WordRange & order(Order val)
Set the order of the words in the range.
WordRange()
Default constructor.
Definition word-range.hpp:438
WordRange & operator=(WordRange const &)
Default copy assignment operator.
auto begin() const noexcept
Returns an input iterator pointing to the first word in the range.
Definition word-range.hpp:677
size_type upper_bound() const noexcept
The current upper bound on the length of a word in the range.
Definition word-range.hpp:621
bool valid() const noexcept
Returns whether or not the settings have been changed since the last time either next or get has been...
Definition word-range.hpp:722
Order order() const noexcept
The current order of the words in the range.
Definition word-range.hpp:591
void next() noexcept
Advance to the next value.
Definition word-range.hpp:368
static constexpr bool is_idempotent
Definition word-range.hpp:426
WordRange & alphabet_size(size_type n) noexcept
Set the number of letters in the alphabet.
Definition word-range.hpp:488
size_t size_hint() const noexcept
The possible size of the range.
Definition word-range.hpp:398
size_type alphabet_size() const noexcept
The current number of letters in the alphabet.
Definition word-range.hpp:502
size_t count() const noexcept
The actual size of the range.
bool at_end() const noexcept
Check if the range object is exhausted.
Definition word-range.hpp:383
WordRange & first(word_type const &frst)
Set the first word in the range.
Definition word-range.hpp:519
WordRange & init()
Initialize an existing WordRange object.
WordRange & operator=(WordRange &&)
Default move assignment operator.
std::string to_human_readable_repr(AhoCorasick const &ac)
Return a string representation.
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:95
Order
The possible orderings of words and strings.
Definition order.hpp:48
std::vector< letter_type > word_type
Type for a word over the generators of a semigroup.
Definition types.hpp:101
size_t letter_type
Type for the index of a generator of a semigroup.
Definition types.hpp:98
detail::const_wislo_iterator cend_wislo(size_t n, word_type &&first, word_type &&last)
Returns a forward iterator pointing to one after the end of the range from first to last.
std::string random_string(std::string const &alphabet, size_t length)
Returns a random string.
detail::const_wilo_iterator cbegin_wilo(size_t n, size_t upper_bound, word_type &&first, word_type &&last)
Returns a forward iterator pointing to the 3rd parameter first.
Word & reverse(Word &&w)
Reverse an object.
Definition word-range.hpp:69
detail::const_wislo_iterator cbegin_wislo(size_t n, word_type &&first, word_type &&last)
Returns a forward iterator pointing to the 2nd parameter first.
auto random_strings(std::string const &alphabet, size_t number, size_t min, size_t max)
Returns a range object of random strings.
Definition word-range.hpp:1534
detail::const_wilo_iterator cend_wilo(size_t n, size_t upper_bound, word_type &&first, word_type &&last)
Returns a forward iterator pointing to one after the end of the range from first to last.
uint64_t number_of_words(size_t n, size_t min, size_t max)
Returns the number of words over an alphabet with a given number of letters with length in a specifie...
word_type random_word(size_t length, size_t nr_letters)
Returns a random word.
Namespace containing some custom literals for creating words.
Definition word-range.hpp:1989
Namespace containing some operators for creating words.
Definition word-range.hpp:2072
static void operator+=(word_type &u, word_type const &v)
Concatenate a word with another word in-place.
Definition word-range.hpp:2178
Word pow(Word const &x, size_t n)
Returns the power of a word.
Definition word-range.hpp:2230
void pow_inplace(Word &w, size_t n)
Power a word in-place.
Definition word-range.hpp:2388
Word prod(Container const &elts, int first, int last, int step=1)
Returns a product of letters or words.
Definition word-range.hpp:2411
Word::value_type human_readable_letter(size_t i)
Returns a character by index in human readable order.
Definition word-range.hpp:2108
word_type operator+(word_type const &u, word_type const &w)
Concatenate two words.
letter_type human_readable_index(char c)
Returns the index of a character in human readable order.
Namespace for everything in the libsemigroups library.
Definition action.hpp:44