libsemigroups  v3.0.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
word-range.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2020-2025 James D. Mitchell
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <http://www.gnu.org/licenses/>.
17//
18
19// This file contains declarations for function related to words (counting, and
20// converting) in libsemigroups.
21
22// TODO:
23// * iwyu
24// * nodiscard
25// * tests for code coverage
26
27#ifndef LIBSEMIGROUPS_WORD_RANGE_HPP_
28#define LIBSEMIGROUPS_WORD_RANGE_HPP_
29
30#include <cstddef> // for size_t
31#include <cstdint> // for uint64_t, uint8_t
32#include <initializer_list> // for initializer_list
33#include <limits> // for numeric_limits
34#include <string> // for basic_string
35#include <string_view> // for string_view
36#include <type_traits> // for enable_if_t
37#include <unordered_map> // for vector, operator==
38#include <utility> // for forward
39#include <variant> // for visit, operator==
40#include <vector> // for vector, operator==
41
42#include "debug.hpp" // for LIBSEMIGROUPS_ASSERT
43#include "exception.hpp" // for LibsemigroupsException
44#include "ranges.hpp" // for begin, end
45#include "types.hpp" // for word_type
46
47#include "detail/word-iterators.hpp" // for const_wilo_iterator
48
49namespace libsemigroups {
50
51 enum class Order : uint8_t; // forward decl
52
53 namespace detail {
54 std::string const& chars_in_human_readable_order();
55 }
56
68 template <typename Word>
69 Word& reverse(Word&& w) {
70 std::reverse(w.begin(), w.end());
71 return w;
72 }
73
75 // Words
77
103
123 [[nodiscard]] uint64_t number_of_words(size_t n, size_t min, size_t max);
124
139 [[nodiscard]] word_type random_word(size_t length, size_t nr_letters);
140
186 [[nodiscard]] detail::const_wilo_iterator cbegin_wilo(size_t n,
187 size_t upper_bound,
188 word_type&& first,
189 word_type&& last);
190
194 [[nodiscard]] detail::const_wilo_iterator cbegin_wilo(size_t n,
195 size_t upper_bound,
196 word_type const& first,
197 word_type const& last);
198
207 [[nodiscard]] detail::const_wilo_iterator
208 cend_wilo(size_t n, size_t upper_bound, word_type&& first, word_type&& last);
209
214 [[nodiscard]] detail::const_wilo_iterator cend_wilo(size_t n,
215 size_t upper_bound,
216 word_type const& first,
217 word_type const& last);
218
256 [[nodiscard]] detail::const_wislo_iterator cbegin_wislo(size_t n,
257 word_type&& first,
258 word_type&& last);
259
263 [[nodiscard]] detail::const_wislo_iterator
264 cbegin_wislo(size_t n, word_type const& first, word_type const& last);
265
274 [[nodiscard]] detail::const_wislo_iterator cend_wislo(size_t n,
275 word_type&& first,
276 word_type&& last);
277
282 [[nodiscard]] detail::const_wislo_iterator cend_wislo(size_t n,
283 word_type const& first,
284 word_type const& last);
285
318 class WordRange {
319 public:
322
324 using output_type = word_type const&;
325
326 private:
327 using const_iterator = std::variant<detail::const_wilo_iterator,
328 detail::const_wislo_iterator>;
329
330 size_type _alphabet_size;
331 mutable const_iterator _current;
332 mutable const_iterator _end;
333 mutable bool _current_valid;
334 word_type _first;
335 word_type _last;
336 Order _order;
337 size_type _upper_bound;
338 mutable size_type _visited;
339
340 void set_iterator() const;
341
342 public:
354 [[nodiscard]] output_type get() const noexcept {
355 set_iterator();
356 return std::visit(
357 [](auto& it) -> auto const& { return *it; }, _current);
358 }
359
368 void next() noexcept {
369 set_iterator();
370 if (!at_end()) {
371 ++_visited;
372 }
373 std::visit([](auto& it) { ++it; }, _current);
374 }
375
383 [[nodiscard]] bool at_end() const noexcept {
384 set_iterator();
385 return _current == _end;
386 }
387
398 [[nodiscard]] size_t size_hint() const noexcept {
399 return number_of_words(_alphabet_size, _first.size(), _last.size())
400 - _visited;
401 // This is only the actual size if _order is shortlex
402 }
403
415 [[nodiscard]] size_t count() const noexcept;
416
417 // For some reason, there needs to be two doxygen comment lines here for
418 // this to render.
421 static constexpr bool is_finite = true; // This may not always be true
422
426 static constexpr bool is_idempotent = true;
427
439 init();
440 }
441
452
457
462
467
472
476 ~WordRange();
477
489 _current_valid &= (n == _alphabet_size);
490 _alphabet_size = n;
491 return *this;
492 }
493
502 [[nodiscard]] size_type alphabet_size() const noexcept {
503 return _alphabet_size;
504 }
505
519 WordRange& first(word_type const& frst) {
520 _current_valid &= (frst == _first);
521 _first = frst;
522 return *this;
523 }
524
535 [[nodiscard]] word_type const& first() const noexcept {
536 return _first;
537 }
538
551 WordRange& last(word_type const& lst) {
552 _current_valid &= (lst == _last);
553 _last = lst;
554 return *this;
555 }
556
567 [[nodiscard]] word_type const& last() const noexcept {
568 return _last;
569 }
570
582
591 [[nodiscard]] Order order() const noexcept {
592 return _order;
593 }
594
607 _current_valid &= (n == _upper_bound);
608 _upper_bound = n;
609 return *this;
610 }
611
621 [[nodiscard]] size_type upper_bound() const noexcept {
622 return _upper_bound;
623 }
624
637 first(word_type(val, 0));
638 return *this;
639 }
640
641 // No corresponding getter for min, because what would it mean? Could be the
642 // length of first(), but that doesn't correspond well to what happens with
643 // the setter.
644
657 last(word_type(val, 0));
658 return *this;
659 }
660
676 // REQUIRED so that we can use StringRange in range based loops
677 auto begin() const noexcept {
678 return rx::begin(*this);
679 }
680
696 // REQUIRED so that we can use StringRange in range based loops
697 auto end() const noexcept {
698 return rx::end(*this);
699 }
700
701 // TODO(now) this doc doesn't feel nice, but JDE can't think of a good way
702 // to write it.
721 // Required so StringRange can accurately set _current_valid
722 bool valid() const noexcept {
723 return _current_valid;
724 }
725 };
726
740 size_t max_width = 72);
741
743 // Strings -> Words
745
767 // TODO (later) a version that takes a word_type, so that we can permute the
768 // letters in a word
769 class ToWord {
770 public:
774 // Not noexcept because std::array::fill isn't
775 ToWord() : _alphabet_map() {
776 init();
777 }
778
779 // TODO (later) noexcept?
783 ToWord(ToWord const&);
784
789
794
799
803 ~ToWord();
804
817 _alphabet_map.clear();
818 return *this;
819 }
820
829 explicit ToWord(std::string const& alphabet) : _alphabet_map() {
830 init(alphabet);
831 }
832
847
857 [[nodiscard]] bool empty() const noexcept {
858 return _alphabet_map.empty();
859 }
860
876 [[nodiscard]] std::string alphabet() const;
877
889 [[nodiscard]] bool can_convert_letter(char const& c) const {
890 return _alphabet_map.count(c) == 1;
891 }
892
913 void call_no_checks(word_type& output, std::string const& input) const;
914
931 [[nodiscard]] word_type call_no_checks(std::string const& input) const {
932 word_type output;
933 call_no_checks(output, input);
934 return output;
935 }
936
956 void operator()(word_type& output, std::string const& input) const;
957
973 [[nodiscard]] word_type operator()(std::string const& input) const {
974 word_type output;
975 operator()(output, input);
976 return output;
977 }
978
994 [[nodiscard]] letter_type operator()(char input) const {
995 // TODO improve this
996 // FIXME(1) it also doesn't work for example to_word('a') returns 63 for
997 // some reason
998 word_type output;
999 // operator()(output, std::string_view(&input, 1));
1000 operator()(output, std::string(input, 1));
1001 return output[0];
1002 }
1003
1020 [[nodiscard]] letter_type call_no_checks(char input) const {
1021 return _alphabet_map.find(input)->second;
1022 }
1023
1024 template <typename InputRange>
1025 struct Range;
1026
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>;
1049 return Range<Inner>(std::forward<InputRange>(input), *this);
1050 }
1051
1052 private:
1054 };
1055
1056 template <typename InputRange>
1057 struct ToWord::Range {
1058 using output_type = word_type;
1059
1060 static constexpr bool is_finite = rx::is_finite_v<InputRange>;
1061 static constexpr bool is_idempotent = rx::is_idempotent_v<InputRange>;
1062
1063 InputRange _input;
1064 ToWord _to_word;
1065
1066 explicit Range(InputRange const& input, ToWord const& t_wrd)
1067 : _input(input), _to_word(t_wrd) {}
1068
1069 explicit Range(InputRange&& input, ToWord const& t_wrd)
1070 : _input(std::move(input)), _to_word(t_wrd) {}
1071
1072 explicit Range(InputRange const& input, ToWord&& t_wrd)
1073 : _input(input), _to_word(std::move(t_wrd)) {}
1074
1075 explicit Range(InputRange&& input, ToWord&& t_wrd)
1076 : _input(std::move(input)), _to_word(std::move(t_wrd)) {}
1077
1078 // Not noexcept because ToWord()() isn't
1079 [[nodiscard]] output_type get() const {
1080 return _to_word.operator()(_input.get());
1081 }
1082
1083 constexpr void next() noexcept {
1084 _input.next();
1085 }
1086
1087 [[nodiscard]] constexpr bool at_end() const noexcept {
1088 return _input.at_end();
1089 }
1090
1091 [[nodiscard]] constexpr size_t size_hint() const noexcept {
1092 return _input.size_hint();
1093 }
1094 };
1095
1106 [[nodiscard]] inline std::string to_human_readable_repr(ToWord const& twrd) {
1107 return fmt::format("<ToWord object with alphabet \"{}\">", twrd.alphabet());
1108 }
1109
1111 // Words -> Strings
1113
1135 class ToString {
1136 public:
1140 ToString() : _alphabet_map() {
1141 init();
1142 }
1143
1144 // TODO (later) noexcept?
1149
1154
1159
1164
1168 ~ToString();
1169
1181 ToString& init() noexcept {
1182 _alphabet_map.clear();
1183 return *this;
1184 }
1185
1194 explicit ToString(std::string const& alphabet) : _alphabet_map() {
1195 init(alphabet);
1196 }
1197
1212
1222 [[nodiscard]] bool empty() const noexcept {
1223 return _alphabet_map.empty();
1224 }
1225
1241 [[nodiscard]] std::string alphabet() const;
1242
1254 [[nodiscard]] bool can_convert_letter(letter_type const& l) const {
1255 return _alphabet_map.count(l) == 1;
1256 }
1257
1278 void call_no_checks(std::string& output, word_type const& input) const;
1279
1296 [[nodiscard]] std::string call_no_checks(word_type const& input) const {
1297 std::string output;
1298 call_no_checks(output, input);
1299 return output;
1300 }
1301
1321 void operator()(std::string& output, word_type const& input) const;
1322
1338 [[nodiscard]] std::string operator()(word_type const& input) const {
1339 std::string output;
1340 operator()(output, input);
1341 return output;
1342 }
1343
1360 template <typename Int>
1361 [[nodiscard]] std::string
1363 static_assert(std::is_integral_v<Int>);
1364 word_type copy(input.begin(), input.end());
1365 return operator()(copy);
1366 }
1367
1368 template <typename InputRange>
1369 struct Range;
1370
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>;
1391 return Range<Inner>(std::forward<InputRange>(input), *this);
1392 }
1393
1394 private:
1395 // We could use std::vector<char> (or similar) here, but an
1396 // unordered_ordered hap has been used instead to allow for potential future
1397 // conversions between different types.
1399 };
1400
1401 template <typename InputRange>
1402 struct ToString::Range {
1403 using output_type = std::string;
1404
1405 static constexpr bool is_finite = rx::is_finite_v<InputRange>;
1406 static constexpr bool is_idempotent = rx::is_idempotent_v<InputRange>;
1407
1408 InputRange _input;
1409 ToString _to_string;
1410
1411 Range(InputRange const& input, ToString const& t_str)
1412 : _input(input), _to_string(t_str) {}
1413
1414 Range(InputRange&& input, ToString const& t_str)
1415 : _input(std::move(input)), _to_string(t_str) {}
1416
1417 Range(InputRange const& input, ToString&& t_str)
1418 : _input(input), _to_string(std::move(t_str)) {}
1419
1420 Range(InputRange&& input, ToString&& t_str)
1421 : _input(std::move(input)), _to_string(std::move(t_str)) {}
1422
1423 ~Range();
1424
1425 // Not noexcept because ToString()() isn't
1426 [[nodiscard]] output_type get() const {
1427 return _to_string(_input.get());
1428 }
1429
1430 constexpr void next() noexcept {
1431 _input.next();
1432 }
1433
1434 [[nodiscard]] constexpr bool at_end() const noexcept {
1435 return _input.at_end();
1436 }
1437
1438 [[nodiscard]] constexpr size_t size_hint() const noexcept {
1439 return _input.size_hint();
1440 }
1441 };
1442
1443 // NOTE: This is a terrible hack to avoid compiler warnings. Maybe remove in
1444 // the future?
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;
1451#endif
1452
1463 [[nodiscard]] inline std::string
1465 return fmt::format("<ToString object with alphabet \"{}\">",
1466 tstr.alphabet());
1467 }
1468
1470 // StringRange
1472
1473 namespace detail {
1474 void throw_if_random_string_should_throw(std::string const& alphabet,
1475 size_t min,
1476 size_t max);
1477 } // namespace detail
1478
1493 std::string random_string(std::string const& alphabet, size_t length);
1494
1513 size_t min,
1514 size_t max);
1515
1534 auto inline random_strings(std::string const& alphabet,
1535 size_t number,
1536 size_t min,
1537 size_t max) {
1538 detail::throw_if_random_string_should_throw(alphabet, min, max);
1539
1540 // Lambda must capture by copy, as the lambda will exist outside the scope
1541 // of this function once the range is returned.
1542 return rx::generate([alphabet, min, max] {
1543 return random_string(alphabet, min, max);
1544 })
1545 | rx::take(number);
1546 }
1547
1580 // This can in many places be replaced by "WordRange | ToString" but this
1581 // makes some things more awkward and so we retain this class for its
1582 // convenience.
1584 public:
1587
1589 using output_type = std::string const&;
1590
1591 private:
1592 mutable std::string _current;
1593 mutable bool _current_valid;
1594 std::string _letters;
1595 ToWord _to_word;
1596 ToString _to_string;
1597 WordRange _word_range;
1598
1599 void init_current() const {
1600 if (!_current_valid) {
1601 _current = _to_string(_word_range.get());
1602 _current_valid = true;
1603 }
1604 }
1605
1606 public:
1619 init_current();
1620 return _current;
1621 }
1622
1631 void next() noexcept {
1632 _word_range.next();
1633 _current_valid = false;
1634 }
1635
1645 bool at_end() const noexcept {
1646 return _word_range.at_end();
1647 }
1648
1659 size_t size_hint() const noexcept {
1660 return _word_range.size_hint();
1661 }
1662
1674 size_t count() const noexcept {
1675 return _word_range.count();
1676 }
1677
1679 static constexpr bool is_finite = true; // This may not always be true
1680
1684 static constexpr bool is_idempotent = true;
1685
1697 init();
1698 }
1699
1710
1713
1716
1719
1722
1724 ~StringRange();
1725
1736
1745 [[nodiscard]] std::string const& alphabet() const noexcept {
1746 return _letters;
1747 }
1748
1762 _word_range.first(_to_word(frst));
1763 _current_valid &= _word_range.valid();
1764 return *this;
1765 }
1766
1777 [[nodiscard]] std::string first() const noexcept {
1778 return _to_string(_word_range.first());
1779 }
1780
1798 _word_range.last(_to_word(lst));
1799 _current_valid &= _word_range.valid();
1800 return *this;
1801 }
1802
1813 [[nodiscard]] std::string last() const noexcept {
1814 return _to_string(_word_range.last());
1815 }
1816
1828 _word_range.order(val);
1829 _current_valid &= _word_range.valid();
1830 return *this;
1831 }
1832
1841 [[nodiscard]] Order order() const noexcept {
1842 return _word_range.order();
1843 }
1844
1857 _word_range.upper_bound(n);
1858 _current_valid &= _word_range.valid();
1859 return *this;
1860 }
1861
1871 [[nodiscard]] size_type upper_bound() const noexcept {
1872 return _word_range.upper_bound();
1873 }
1874
1887 _word_range.min(val);
1888 _current_valid &= _word_range.valid();
1889 return *this;
1890 }
1891
1892 // No corresponding getter for min, because what would it mean? Could be the
1893 // length of first(), but that doesn't correspond well to what happens with
1894 // the setter.
1895
1910 _word_range.max(val);
1911 _current_valid &= _word_range.valid();
1912 return *this;
1913 }
1914
1930 // REQUIRED so that we can use StringRange in range based loops
1931 auto begin() const noexcept {
1932 return rx::begin(*this);
1933 }
1934
1950 // REQUIRED so that we can use StringRange in range based loops
1951 auto end() const noexcept {
1952 return rx::end(*this);
1953 }
1954 };
1955
1969 size_t max_width = 72);
1970
1972 // Literals
1974
1989 namespace literals {
2017 word_type operator"" _w(const char* w, size_t n);
2018
2022 word_type operator"" _w(const char* w);
2023
2045 std::string operator"" _p(const char* w, size_t n);
2046
2051 std::string operator"" _p(const char* w);
2052 } // namespace literals
2053
2055
2072 namespace words {
2073
2089 [[nodiscard]] letter_type human_readable_index(char c);
2090
2107 template <typename Word = std::string>
2108 typename Word::value_type human_readable_letter(size_t i) {
2109 // This check ensures that i is not too large to be converted to a
2110 // Word::value_type. This is check is only needed if the number of
2111 // distinct Word::value objects is less than the number of distinct size_t
2112 // objects.
2113 if constexpr (sizeof(typename Word::value_type) < sizeof(size_t)) {
2117 "expected the argument to be in the range [0, {}), found {}",
2120 i);
2121 }
2122 }
2123 if constexpr (!std::is_same_v<Word, std::string>) {
2124 return static_cast<typename Word::value_type>(i);
2125 } else {
2126 // Choose visible characters a-zA-Z0-9 first before anything else
2127 // The ascii ranges for these characters are: [97, 123), [65, 91),
2128 // [48, 58) so the remaining range of chars that are appended to the end
2129 // after these chars are [0,48), [58, 65), [91, 97), [123, 255]
2130 return detail::chars_in_human_readable_order()[i];
2131 }
2132 }
2133
2135 // operator+
2137
2151
2156
2161
2163 // operator+=
2165
2178 static inline void operator+=(word_type& u, word_type const& v) {
2179 u.insert(u.end(), v.cbegin(), v.cend());
2180 }
2181
2185 inline void operator+=(word_type& u, letter_type a) {
2186 u.push_back(a);
2187 }
2188
2192 inline void operator+=(letter_type a, word_type& u) {
2193 u.insert(u.begin(), a);
2194 }
2195
2197 // pow
2199
2211 template <typename Word>
2212 void pow_inplace(Word& w, size_t n);
2213 // No pow_inplace for string_view or initializer_list because there's no
2214 // where to store the result.
2215
2229 template <typename Word>
2230 Word pow(Word const& x, size_t n) {
2231 Word y(x);
2232 pow_inplace(y, n);
2233 return y;
2234 }
2235
2240
2244 std::string pow(std::string_view w, size_t n);
2245
2247 // prod
2249
2288 template <typename Container, typename Word = Container>
2289 Word prod(Container const& elts, int first, int last, int step = 1);
2290
2295 int first,
2296 int last,
2297 int step = 1) {
2298 return prod<word_type>(word_type(ilist), first, last, step);
2299 }
2300
2304 static inline std::string
2305 prod(std::string_view sv, int first, int last, int step = 1) {
2306 return prod<std::string>(std::string(sv), first, last, step);
2307 }
2308
2313 int first,
2314 int last,
2315 int step = 1) {
2317 std::vector<word_type>(elts), first, last, step);
2318 }
2319
2323 static inline std::string
2325 int first,
2326 int last,
2327 int step = 1) {
2329 sv, first, last, step);
2330 }
2331
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);
2340 }
2341
2348 size_t last) {
2349 return prod(elts, 0, static_cast<int>(last), 1);
2350 }
2351
2357 static inline std::string prod(std::string_view elts, size_t last) {
2359 elts, 0, static_cast<int>(last), 1);
2360 }
2361
2368 size_t last) {
2369 return prod(elts, 0, static_cast<int>(last), 1);
2370 }
2371
2377 static inline std::string
2380 std::vector<std::string_view>(elts), 0, static_cast<int>(last), 1);
2381 }
2382
2384 // pow - implementation
2386
2387 template <typename Word>
2388 void pow_inplace(Word& x, size_t n) {
2389 Word y(x);
2390 x.reserve(x.size() * n);
2391 if (n % 2 == 0) {
2392 x = Word({});
2393 }
2394
2395 while (n > 1) {
2396 y += y;
2397 n /= 2;
2398 if (n % 2 == 1) {
2399 x += y;
2400 }
2401 }
2402 }
2403
2405 // prod - implementation
2407
2408 // Note: we could do a version of the below using insert on words, where
2409 // the step is +/- 1.
2410 template <typename Container, typename Word>
2411 Word prod(Container const& elts, int first, int last, int step) {
2412 if (step == 0) {
2413 LIBSEMIGROUPS_EXCEPTION("the 4th argument must not be 0");
2414 } else if (((first < last && step > 0) || (first > last && step < 0))
2415 && elts.size() == 0) {
2416 LIBSEMIGROUPS_EXCEPTION("the 1st argument must not be empty if the "
2417 "given range is not empty");
2418 // TODO Is int signed? Should this also contain
2419 // std::numeric_limits<int>::min?
2420 } else if (elts.size() > std::numeric_limits<int>::max()) {
2422 "the 1st argument must have size less than or equal to {}",
2424 }
2425 Word result;
2426 int const s = elts.size();
2427
2428 if (first < last) {
2429 if (step < 0) {
2430 return result;
2431 }
2432 result.reserve((last - first) / step);
2433
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);
2437 result += elts[a];
2438 }
2439 } else {
2440 if (step > 0) {
2441 return result;
2442 }
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);
2448 result += elts[a];
2449 }
2450 }
2451 return result;
2452 }
2453 } // namespace words
2454 //
2455} // namespace libsemigroups
2456
2457#endif // LIBSEMIGROUPS_WORD_RANGE_HPP_
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.
T forward(T... args)
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.
T insert(T... args)
T max(T... args)
T min(T... args)
T move(T... args)
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
T push_back(T... args)
T reverse(T... args)