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/print.hpp"
48#include "detail/word-iterators.hpp"
52 enum class Order : uint8_t;
55 std::string
const& chars_in_human_readable_order();
69 template <
typename Word>
208 [[nodiscard]] detail::const_wilo_iterator
215 [[nodiscard]] detail::const_wilo_iterator
cend_wilo(
size_t n,
264 [[nodiscard]] detail::const_wislo_iterator
275 [[nodiscard]] detail::const_wislo_iterator
cend_wislo(
size_t n,
283 [[nodiscard]] detail::const_wislo_iterator
cend_wislo(
size_t n,
328 using const_iterator = std::variant<detail::const_wilo_iterator,
329 detail::const_wislo_iterator>;
332 mutable const_iterator _current;
333 mutable const_iterator _end;
334 mutable bool _current_valid;
341 void set_iterator()
const;
358 [](
auto& it) ->
auto const& {
return *it; }, _current);
374 std::visit([](
auto& it) { ++it; }, _current);
384 [[nodiscard]]
bool at_end() const noexcept {
386 return _current == _end;
416 [[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);
771 template <
typename From>
825 _alphabet_map.clear();
865 [[nodiscard]]
bool empty() const noexcept {
866 return _alphabet_map.empty();
899 return _alphabet_map.count(c) == 1;
1036 return _alphabet_map.find(input)->second;
1039 template <
typename InputRange>
1061 template <
typename InputRange,
1062 typename = std::enable_if_t<rx::is_input_or_sink_v<InputRange>>>
1063 [[nodiscard]]
constexpr auto operator()(InputRange&& input)
const {
1064 using Inner = rx::get_range_type_t<InputRange>;
1072 template <
typename From>
1073 template <
typename InputRange>
1074 struct ToWord<From>::Range {
1077 static constexpr bool is_finite = rx::is_finite_v<InputRange>;
1078 static constexpr bool is_idempotent = rx::is_idempotent_v<InputRange>;
1083 explicit Range(InputRange
const& input,
ToWord<From> const& t_wrd)
1084 : _input(input), _to_word(t_wrd) {}
1086 explicit Range(InputRange&& input,
ToWord<From> const& t_wrd)
1087 : _input(
std::move(input)), _to_word(t_wrd) {}
1089 explicit Range(InputRange
const& input,
ToWord<From>&& t_wrd)
1090 : _input(input), _to_word(std::
move(t_wrd)) {}
1092 explicit Range(InputRange&& input,
ToWord<From>&& t_wrd)
1093 : _input(std::
move(input)), _to_word(std::
move(t_wrd)) {}
1096 [[nodiscard]] output_type get()
const {
1097 return _to_word.operator()(_input.get());
1100 constexpr void next() noexcept {
1104 [[nodiscard]]
constexpr bool at_end() const noexcept {
1105 return _input.at_end();
1108 [[nodiscard]]
constexpr size_t size_hint() const noexcept {
1109 return _input.size_hint();
1123 template <
typename From>
1125 return fmt::format(
"<ToWord object with alphabet \"{}\">",
1131 using ToWord [[deprecated]] = v4::ToWord<std::string>;
1205 _alphabet_map.clear();
1245 [[nodiscard]]
bool empty() const noexcept {
1246 return _alphabet_map.empty();
1278 return _alphabet_map.count(l) == 1;
1383 template <
typename Int>
1386 static_assert(std::is_integral_v<Int>);
1391 template <
typename InputRange>
1411 template <
typename InputRange,
1412 typename = std::enable_if_t<rx::is_input_or_sink_v<InputRange>>>
1413 [[nodiscard]]
constexpr auto operator()(InputRange&& input)
const {
1414 using Inner = rx::get_range_type_t<InputRange>;
1425 template <
typename InputRange>
1426 struct ToString::Range {
1429 static constexpr bool is_finite = rx::is_finite_v<InputRange>;
1430 static constexpr bool is_idempotent = rx::is_idempotent_v<InputRange>;
1435 Range(InputRange
const& input,
ToString const& t_str)
1436 : _input(input), _to_string(t_str) {}
1438 Range(InputRange&& input,
ToString const& t_str)
1439 : _input(std::
move(input)), _to_string(t_str) {}
1441 Range(InputRange
const& input,
ToString&& t_str)
1442 : _input(input), _to_string(std::
move(t_str)) {}
1444 Range(InputRange&& input,
ToString&& t_str)
1445 : _input(std::
move(input)), _to_string(std::
move(t_str)) {}
1450 [[nodiscard]] output_type get()
const {
1451 return _to_string(_input.get());
1454 constexpr void next() noexcept {
1458 [[nodiscard]]
constexpr bool at_end() const noexcept {
1459 return _input.at_end();
1462 [[nodiscard]]
constexpr size_t size_hint() const noexcept {
1463 return _input.size_hint();
1466 [[nodiscard]]
constexpr size_t count() const noexcept {
1467 return _input.count();
1473#if defined(__clang__)
1474 template <
typename InputRange>
1475 ToString::Range<InputRange>::~Range<InputRange>() =
default;
1476#elif defined(__GNUC__)
1477 template <
typename InputRange>
1478 ToString::Range<InputRange>::~Range() =
default;
1491 [[nodiscard]]
inline std::string
1493 return fmt::format(
"<ToString object with alphabet \"{}\">",
1502 void throw_if_random_string_should_throw(
std::string const& alphabet,
1566 detail::throw_if_random_string_should_throw(alphabet, min, max);
1570 return rx::generate([alphabet, min, max] {
1621 mutable bool _current_valid;
1627 void init_current()
const {
1628 if (!_current_valid) {
1629 _current = _to_string(_word_range.get());
1630 _current_valid =
true;
1661 _current_valid =
false;
1674 return _word_range.at_end();
1688 return _word_range.size_hint();
1703 return _word_range.count();
1790 _word_range.
first(_to_word(frst));
1791 _current_valid &= _word_range.valid();
1806 return _to_string(_word_range.first());
1826 _word_range.
last(_to_word(lst));
1827 _current_valid &= _word_range.valid();
1842 return _to_string(_word_range.last());
1856 _word_range.
order(val);
1857 _current_valid &= _word_range.valid();
1870 return _word_range.order();
1886 _current_valid &= _word_range.valid();
1900 return _word_range.upper_bound();
1915 _word_range.
min(val);
1916 _current_valid &= _word_range.valid();
1938 _word_range.
max(val);
1939 _current_valid &= _word_range.valid();
1960 return rx::begin(*
this);
1980 return rx::end(*
this);
1997 size_t max_width = 72);
2135 template <
typename Word = std::
string>
2141 if constexpr (
sizeof(
typename Word::value_type) <
sizeof(size_t)) {
2145 "expected the argument to be in the range [0, {}), found {}",
2151 if constexpr (!std::is_same_v<Word, std::string>) {
2152 return static_cast<typename Word::value_type
>(i);
2158 return detail::chars_in_human_readable_order()[i];
2239 template <
typename Word>
2257 template <
typename Word>
2258 Word
pow(Word
const& x,
size_t n) {
2316 template <
typename Container,
typename Word = Container>
2317 Word
prod(Container
const& elts,
int first,
int last,
int step = 1);
2333 prod(std::string_view sv,
int first,
int last,
int step = 1) {
2357 sv, first, last, step);
2365 template <
typename Container,
typename Word = Container>
2366 Word
prod(Container
const& elts,
size_t last) {
2367 return prod(elts, 0,
static_cast<int>(last), 1);
2377 return prod(elts, 0,
static_cast<int>(last), 1);
2387 elts, 0,
static_cast<int>(last), 1);
2397 return prod(elts, 0,
static_cast<int>(last), 1);
2415 template <
typename Word>
2418 x.reserve(x.size() * n);
2438 template <
typename Container,
typename Word>
2439 Word
prod(Container
const& elts,
int first,
int last,
int step) {
2442 }
else if (((first < last && step > 0) || (first > last && step < 0))
2443 && elts.size() == 0) {
2445 "given range is not empty");
2450 "the 1st argument must have size less than or equal to {}",
2454 int const s = elts.size();
2460 result.reserve((last - first) / step);
2462 for (
int i = first; i < last; i += step) {
2463 size_t const a = (i % s + s) % s;
2464 LIBSEMIGROUPS_ASSERT(
static_cast<int>(a) < s);
2471 size_t steppos =
static_cast<size_t>(-step);
2472 result.reserve((first - last) / steppos);
2473 for (
int i = first; i > last; i += step) {
2474 size_t const a = (i % s + s) % s;
2475 LIBSEMIGROUPS_ASSERT(
static_cast<int>(a) < s);
2488 template <
typename From>
2491 template <
typename From>
2494 template <
typename From>
2497 template <
typename From>
2500 template <
typename From>
2503 template <
typename From>
2508 "at most 256, found {}",
2511 auto _old_alphabet_map = _alphabet_map;
2513 LIBSEMIGROUPS_ASSERT(_alphabet_map.empty());
2515 auto it = _alphabet_map.emplace(
alphabet[l], l);
2518 std::swap(_old_alphabet_map, _alphabet_map);
2522 "invalid alphabet {}, duplicate letter {}!",
2523 libsemigroups::detail::to_printable(
alphabet),
2524 libsemigroups::detail::to_printable(
alphabet[l]));
2530 template <
typename From>
2535 From output(_alphabet_map.size(),
typename From::value_type());
2536 for (
auto it : _alphabet_map) {
2537 output[it.second] = it.first;
2542 template <
typename From>
2544 From
const& input)
const {
2548 output.
resize(input.size(), 0);
2552 [](
char c) { return words::human_readable_index(c); });
2557 for (
auto const& c : input) {
2563 template <
typename From>
2566 for (
auto const& c : input) {
2567 if (_alphabet_map.find(c) == _alphabet_map.cend()) {
2571 "invalid letter {} in the 2nd argument (input word), "
2572 "expected letters in the alphabet {}!",
2573 libsemigroups::detail::to_printable(c),
2574 libsemigroups::detail::to_printable(
alphabet()));
Class for generating strings in a given range and in a particular order.
Definition word-range.hpp:1611
static constexpr bool is_finite
Value indicating that the range is finite.
Definition word-range.hpp:1707
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:1914
auto end() const noexcept
Returns an input iterator pointing one beyond the last string in the range.
Definition word-range.hpp:1979
StringRange & upper_bound(size_type n)
Set an upper bound for the length of a string in the range.
Definition word-range.hpp:1884
std::string first() const noexcept
The current first string in the range.
Definition word-range.hpp:1805
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:1937
std::string last() const noexcept
The current one past the last string in the range.
Definition word-range.hpp:1841
StringRange & alphabet(std::string const &x)
Set the alphabet.
std::string const & alphabet() const noexcept
The current alphabet.
Definition word-range.hpp:1773
StringRange & order(Order val)
Set the order of the strings in the range.
Definition word-range.hpp:1855
StringRange()
Default constructor.
Definition word-range.hpp:1724
output_type get() const
Get the current value.
Definition word-range.hpp:1646
StringRange & first(std::string const &frst)
Set the first string in the range.
Definition word-range.hpp:1789
auto begin() const noexcept
Returns an input iterator pointing to the first string in the range.
Definition word-range.hpp:1959
size_type upper_bound() const noexcept
The current upper bound on the length of a string in the range.
Definition word-range.hpp:1899
StringRange(StringRange &&)
Default move constructor.
Order order() const noexcept
The current order of the strings in the range.
Definition word-range.hpp:1869
void next() noexcept
Advance to the next value.
Definition word-range.hpp:1659
static constexpr bool is_idempotent
Definition word-range.hpp:1712
size_t size_hint() const noexcept
The possible size of the range.
Definition word-range.hpp:1687
typename std::vector< std::string >::size_type size_type
Alias for the size type.
Definition word-range.hpp:1614
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:1617
size_t count() const noexcept
The actual size of the range.
Definition word-range.hpp:1702
bool at_end() const noexcept
Check if the range object is exhausted.
Definition word-range.hpp:1673
StringRange & last(std::string const &lst)
Set one past the last string in the range.
Definition word-range.hpp:1825
StringRange(StringRange const &)
Default copy constructor.
Class for converting word_type into std::string with specified alphabet.
Definition word-range.hpp:1158
ToString & init() noexcept
Initialize an existing ToString object.
Definition word-range.hpp:1204
bool can_convert_letter(letter_type const &l) const
Definition word-range.hpp:1277
ToString()
Default constructor.
Definition word-range.hpp:1163
constexpr auto operator()(InputRange &&input) const
Call operator for combining with other range objects.
Definition word-range.hpp:1413
bool empty() const noexcept
Check if the alphabet is defined.
Definition word-range.hpp:1245
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:1385
std::string call_no_checks(word_type const &input) const
Convert a word_type to a std::string.
Definition word-range.hpp:1319
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:1361
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:1217
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:772
void operator()(word_type &output, From const &input) const
Convert a string to a word_type.
Definition word-range.hpp:2564
ToWord & init(From const &alphabet)
Initialize an existing ToWord object.
Definition word-range.hpp:2504
std::string from_type
Definition word-range.hpp:779
from_type alphabet() const
Definition word-range.hpp:2531
ToWord()
Default constructor.
Definition word-range.hpp:784
void call_no_checks(word_type &output, From const &input) const
Convert a string to a word_type.
Definition word-range.hpp:2543
Class for generating words in a given range and in a particular order.
Definition word-range.hpp:319
static constexpr bool is_finite
Value indicating that the range is finite.
Definition word-range.hpp:421
output_type get() const noexcept
Get the current value.
Definition word-range.hpp:355
word_type const & output_type
The type of the output of a WordRange object.
Definition word-range.hpp:325
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:322
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:369
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:399
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:384
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.
Class for converting strings to word_type with specified alphabet.
Definition word-range.hpp:772
void operator()(word_type &output, From const &input) const
Convert a string to a word_type.
Definition word-range.hpp:2564
ToWord & init()
Initialize an existing ToWord object.
Definition word-range.hpp:824
bool can_convert_letter(typename from_type::value_type const &c) const
Definition word-range.hpp:898
From from_type
The type of values an instance of ToWord will convert into word_type.
Definition word-range.hpp:779
constexpr auto operator()(InputRange &&input) const
Call operator for combining with other range objects.
Definition word-range.hpp:1063
bool empty() const noexcept
Check if the alphabet is defined.
Definition word-range.hpp:865
word_type operator()(From const &input) const
Convert a string to a word_type.
Definition word-range.hpp:985
ToWord & operator=(ToWord const &)
Default copy assignment.
letter_type call_no_checks(typename From::value_type input) const
Convert a char to a letter_type.
Definition word-range.hpp:1035
ToWord & operator=(ToWord &&)
Default move assignment.
from_type alphabet() const
Return the alphabet used for conversion.
Definition word-range.hpp:2531
ToWord(ToWord &&)
Default move constructor.
ToWord(From const &alphabet)
Construct with given alphabet.
Definition word-range.hpp:837
ToWord()
Default constructor.
Definition word-range.hpp:784
letter_type operator()(typename From::value_type input) const
Convert a char to a letter_type.
Definition word-range.hpp:1008
word_type call_no_checks(From const &input) const
Convert a string to a word_type.
Definition word-range.hpp:942
void call_no_checks(word_type &output, From const &input) const
Convert a string to a word_type.
Definition word-range.hpp:2543
ToWord(ToWord const &)
Default copy constructor.
std::string to_human_readable_repr(Action< Element, Point, Func, Traits, LeftOrRight > const &action)
Return a human readable representation of an Action object.
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:99
std::vector< letter_type > word_type
Type for a word over the generators of a semigroup.
Definition types.hpp:99
size_t letter_type
Type for the index of a generator of a semigroup.
Definition types.hpp:96
Order
The possible orderings of words and strings.
Definition order.hpp:54
std::string to_human_readable_repr(WordGraph< Node > const &wg)
Return a human readable representation of a WordGraph object.
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:70
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:1562
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:2017
Namespace containing some operators for creating words.
Definition word-range.hpp:2100
static void operator+=(word_type &u, word_type const &v)
Concatenate a word with another word in-place.
Definition word-range.hpp:2206
Word pow(Word const &x, size_t n)
Returns the power of a word.
Definition word-range.hpp:2258
void pow_inplace(Word &w, size_t n)
Power a word in-place.
Definition word-range.hpp:2416
Word prod(Container const &elts, int first, int last, int step=1)
Returns a product of letters or words.
Definition word-range.hpp:2439
Word::value_type human_readable_letter(size_t i)
Returns a character by index in human readable order.
Definition word-range.hpp:2136
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