libsemigroups  v3.0.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
ranges.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2023-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 of some ranges (in the sense of rx-ranges)
20// that augment those in rx-ranges.
21
22#ifndef LIBSEMIGROUPS_RANGES_HPP_
23#define LIBSEMIGROUPS_RANGES_HPP_
24
25#include <algorithm> // for is_sorted
26#include <cstddef> // for size_t
27#include <functional> // for less
28#include <ostream> // for operator<<, ostream
29#include <random> // for mt19937, random_device, uniform_int_distribution
30#include <type_traits> // for enable_if_t
31#include <utility> // for forward
32
33#pragma GCC diagnostic push
34#pragma GCC diagnostic ignored "-Wshadow"
35#pragma GCC diagnostic ignored "-Winline"
36#if defined(__GNUC__) && !defined(__clang__)
37#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
38#endif
39#include <rx/ranges.hpp> // for count, iterator_range
40#pragma GCC diagnostic pop
41
42#include "config.hpp" // for LIBSEMIGROUPS_PARSED_BY_DOXYGEN
43
44#include "detail/fmt.hpp" // for fmt::join
45#include "detail/string.hpp" // for detail::to_string
46
47namespace libsemigroups {
48
69
71 // Custom ranges
73
93 // TODO(2) this should be able to emit any number of random items not only
94 // one.
95 struct Random {
99 Random() = default;
100
104 Random(Random const&) = default;
105
109 Random(Random&&) = default;
110
114 Random& operator=(Random const&) = default;
115
119 Random& operator=(Random&&) = default;
120
121 template <typename InputRange>
122 struct Range {
123 using output_type = typename InputRange::output_type;
124
125 // TODO(1) this is probably not correct, should depend on InputRange
126 static constexpr bool is_finite = rx::is_finite_v<InputRange>;
127 // TODO(1) this is probably not correct, should depend on InputRange
128 static constexpr bool is_idempotent = rx::is_idempotent_v<InputRange>;
129
130 bool _at_end;
131 InputRange _input;
132 mutable output_type _val;
133 mutable bool _val_set;
134
135 explicit constexpr Range(InputRange&& input) noexcept
136 : _at_end(false), _input(std::move(input)), _val(), _val_set(false) {}
137
138 [[nodiscard]] output_type get() const noexcept;
139
140 constexpr void next() noexcept {
141 _at_end = true;
142 }
143
144 [[nodiscard]] constexpr bool at_end() const noexcept {
145 return _at_end;
146 }
147
148 [[nodiscard]] constexpr size_t size_hint() const noexcept {
149 if (!at_end()) {
150 return 1;
151 } else {
152 return 0;
153 }
154 }
155 };
156
157#ifndef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
158 template <typename InputRange>
159 [[nodiscard]] constexpr auto operator()(InputRange&& input) const {
160 using Inner = rx::get_range_type_t<InputRange>;
161 return Range<Inner>(std::forward<InputRange>(input));
162 }
163#endif // LIBSEMIGROUPS_PARSED_BY_DOXYGEN
164 };
165
167 // Comparison functions
169
190 template <typename Range, typename Compare>
191 bool is_sorted(Range r, Compare&& comp);
192
210 template <typename Range>
211 bool is_sorted(Range r) {
212 return std::is_sorted(r, std::less<>());
213 }
214
232 template <typename Range1, typename Range2>
233 bool equal(Range1 r1, Range2 r2);
234
253 template <typename Range1, typename Range2>
254 bool lexicographical_compare(Range1 r1, Range2 r2);
255
274 template <typename Range1, typename Range2>
275 bool shortlex_compare(Range1 r1, Range2 r2);
276
277 // TODO(1) recursive_path_compare?
278
280 // Custom combinators
282
301 template <typename S, typename T>
302 auto chain(S const& x, T const& y) {
303 return rx::chain(rx::iterator_range(x.cbegin(), x.cend()),
304 rx::iterator_range(y.cbegin(), y.cend()));
305 }
306
323 template <typename T>
324 auto enumerate(T const& thing) {
325 return rx::enumerate(rx::iterator_range(thing));
326 }
327
329 // String representation
331
348 template <typename Range,
349 typename = std::enable_if_t<rx::is_input_or_sink_v<Range>>>
351
352} // namespace libsemigroups
353
354#include "ranges.tpp"
355
356#endif // LIBSEMIGROUPS_RANGES_HPP_
T forward(T... args)
std::ostringstream & operator<<(std::ostringstream &os, BMat8 const &x)
Insertion operator.
bool shortlex_compare(T const &first1, T const &last1, T const &first2, T const &last2)
Compare two objects of the same type using the short-lex reduction ordering.
Definition order.hpp:267
bool lexicographical_compare(T const &x, T const &y)
Compare two objects of the same type using std::lexicographical_compare.
Definition order.hpp:96
bool is_sorted(Range r, Compare &&comp)
Check if a range is sorted according to comp.
auto enumerate(T const &thing)
Enumerate an object (by const reference).
Definition ranges.hpp:324
auto chain(S const &x, T const &y)
Chain objects (const references).
Definition ranges.hpp:302
bool equal(Range1 r1, Range2 r2)
Check two ranges for equality.
T is_sorted(T... args)
T move(T... args)
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
Random & operator=(Random const &)=default
Default copy assignment operator.
Random()=default
Default constructor.
Random(Random &&)=default
Default move constructor.
Random & operator=(Random &&)=default
Default move assignment operator.
Random(Random const &)=default
Default copy constructor.