libsemigroups  v3.3.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
94 // TODO(2) this should be able to emit any number of random items not only
95 // one.
96 struct Random {
100 Random() = default;
101
105 Random(Random const&) = default;
106
110 Random(Random&&) = default;
111
115 Random& operator=(Random const&) = default;
116
120 Random& operator=(Random&&) = default;
121
122 template <typename InputRange>
123 struct Range {
124 using output_type = typename InputRange::output_type;
125
126 static constexpr bool is_finite = rx::is_finite_v<InputRange>;
127 static constexpr bool is_idempotent = rx::is_idempotent_v<InputRange>;
128
129 bool _at_end;
130 InputRange _input;
131 std::decay_t<output_type> _val;
132 bool _val_set;
133
134 explicit constexpr Range(InputRange&& input) noexcept
135 : _at_end(false), _input(std::move(input)), _val(), _val_set(false) {}
136
137 explicit constexpr Range(InputRange const& input) noexcept
138 : _at_end(false), _input(input), _val(), _val_set(false) {}
139
140 [[nodiscard]] output_type get() noexcept;
141
142 constexpr void next() noexcept {
143 _at_end = true;
144 }
145
146 [[nodiscard]] constexpr bool at_end() const noexcept {
147 return _at_end;
148 }
149
150 [[nodiscard]] constexpr size_t size_hint() const noexcept {
151 if (!at_end()) {
152 return 1;
153 } else {
154 return 0;
155 }
156 }
157 };
158
159#ifndef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
160 template <typename InputRange>
161 [[nodiscard]] constexpr auto operator()(InputRange&& input) const {
162 using Inner = rx::get_range_type_t<InputRange>;
163 return Range<Inner>(std::forward<InputRange>(input));
164 }
165#endif // LIBSEMIGROUPS_PARSED_BY_DOXYGEN
166 };
167
169 // Comparison functions
171
192 template <typename Range, typename Compare>
193 bool is_sorted(Range r, Compare&& comp);
194
212 template <typename Range>
213 bool is_sorted(Range r) {
214 return std::is_sorted(r, std::less<>());
215 }
216
234 template <typename Range1, typename Range2>
235 bool equal(Range1 r1, Range2 r2);
236
255 template <typename Range1, typename Range2>
256 bool lexicographical_compare(Range1 r1, Range2 r2);
257
276 template <typename Range1, typename Range2>
277 bool shortlex_compare(Range1 r1, Range2 r2);
278
279 // TODO(1) recursive_path_compare?
280
282 // Custom combinators
284
303 template <typename S, typename T>
304 auto chain(S const& x, T const& y) {
305 return rx::chain(rx::iterator_range(x.cbegin(), x.cend()),
306 rx::iterator_range(y.cbegin(), y.cend()));
307 }
308
325 template <typename T>
326 auto enumerate(T const& thing) {
327 return rx::enumerate(rx::iterator_range(thing));
328 }
329
331 // String representation
333
350 template <typename Range,
351 typename = std::enable_if_t<rx::is_input_or_sink_v<Range>>>
353
354} // namespace libsemigroups
355
356#include "ranges.tpp"
357
358#endif // LIBSEMIGROUPS_RANGES_HPP_
T forward(T... args)
std::ostringstream & operator<<(std::ostringstream &os, BMat8 const &x)
Insertion operator.
bool lexicographical_compare(Thing const &x, Thing const &y)
Compare two objects of the same type using std::lexicographical_compare.
Definition order.hpp:112
bool shortlex_compare(Iterator first1, Iterator last1, Iterator first2, Iterator last2)
Compare two objects of the same type using the short-lex reduction ordering.
Definition order.hpp:288
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:326
auto chain(S const &x, T const &y)
Chain objects (const references).
Definition ranges.hpp:304
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.