Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
DisjointDiscreteRange.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Traversal_DisjointDiscreteRange_h_
5#define _Stroika_Foundation_Traversal_DisjointDiscreteRange_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
10#include "Stroika/Foundation/Common/Common.h"
11#include "Stroika/Foundation/Containers/Sequence.h"
12#include "Stroika/Foundation/Containers/SortedSet.h"
15
16/**
17 * \file
18 *
19 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
20 *
21 * TODO:
22 * @todo More efficient DisjointDiscreteRange<T, RANGE_TYPE>::Elements () implementation
23 */
24
25namespace Stroika::Foundation::Traversal {
26
27 /**
28 * @todo Add CONCEPT to require RANGE_TYPE subtype of DiscreteRange
29 */
30 template <typename T, typename RANGE_TYPE = DiscreteRange<T>>
31 class DisjointDiscreteRange : public DisjointRange<T, RANGE_TYPE> {
32 private:
35
36 public:
37 using value_type = typename inherited::value_type;
38 static_assert (same_as<T, value_type>);
39 using RangeType = typename inherited::RangeType;
40 static_assert (same_as<RANGE_TYPE, RangeType>);
41
42 public:
43 /**
44 * You can pass in empty Ranges, and ranges out of order, but the constructor always filters out
45 * empty ranges, and re-orders so subranges well-ordered.
46 */
49 DisjointDiscreteRange (const RangeType& from);
50 DisjointDiscreteRange (const initializer_list<RangeType>& from);
51 template <IIterableOfTo<RANGE_TYPE> RANGES_OF_T>
52 explicit DisjointDiscreteRange (RANGES_OF_T&& from);
53 template <IIterableOfTo<T> TS>
54 explicit DisjointDiscreteRange (TS&& from);
55 template <IInputIterator<RANGE_TYPE> ITERATOR_OF_RANGE_OF_T, sentinel_for<remove_cvref_t<ITERATOR_OF_RANGE_OF_T>> ITERATOR_OF_RANGE_OF_T2>
56 explicit DisjointDiscreteRange (ITERATOR_OF_RANGE_OF_T&& start, ITERATOR_OF_RANGE_OF_T2&& end);
57 template <IInputIterator<T> ITERATOR_OF_T, sentinel_for<remove_cvref_t<ITERATOR_OF_T>> ITERATOR_OF_T2>
58 explicit DisjointDiscreteRange (ITERATOR_OF_T&& start, ITERATOR_OF_T2&& end);
59
60 public:
61 nonvirtual DisjointDiscreteRange& operator= (const DisjointDiscreteRange& rhs) = default;
62
63 public:
64 /**
65 */
66 nonvirtual void Add (const value_type& elt);
67
68 public:
69 /**
70 */
71 nonvirtual DisjointDiscreteRange Intersection (const RangeType& rhs) const;
72 nonvirtual DisjointDiscreteRange Intersection (const DisjointDiscreteRange& rhs) const;
73
74 public:
75 /**
76 */
77 nonvirtual optional<value_type> GetNext (value_type elt) const;
78
79 public:
80 /**
81 */
82 nonvirtual optional<value_type> GetPrevious (value_type elt) const;
83
84 public:
85 /**
86 * \par Example Usage
87 * \code
88 * DisjointDiscreteRange<DiscreteRange<int>> t;
89 * for (T i : t.Elements ()) {
90 * }
91 * \endcode
92 *
93 * Elements () makes no guarantees about whether or not modifications to the underlying DisjointDiscreteRange<> will
94 * appear in the Elements() Iterable<T>.
95 */
96 nonvirtual Iterable<value_type> Elements () const;
97
98 public:
99 /**
100 * Not needed, but this provides the ability to performance tweak the search done by Find/FindLastThat
101 */
102 struct FindHints {
103 value_type fSeedPosition;
104 bool fForwardFirst;
105 FindHints (value_type seedPosition, bool forwardFirst);
106 };
107
108 public:
109 /**
110 * Find the first element of the DisjointDiscreteRange that passes the argument function test.
111 &&&& docs - assumes a bit that one subrange meeting criteria - fill in details
112 */
113 nonvirtual optional<value_type> Find (const function<bool (value_type)>& that) const;
114 nonvirtual optional<value_type> Find (const function<bool (value_type)>& that, const FindHints& hints) const;
115
116 public:
117 /**
118 * Find the last element of the DisjointDiscreteRange that passes the argument function test.
119 &&&& docs - assumes a bit that one subrange meeting criteria - fill in details
120 */
121 nonvirtual optional<value_type> FindLastThat (const function<bool (value_type)>& testF) const;
122 nonvirtual optional<value_type> FindLastThat (const function<bool (value_type)>& testF, const FindHints& hints) const;
123
124 private:
125 nonvirtual optional<value_type> ScanTil_ (const function<bool (value_type)>& testF,
126 const function<optional<value_type> (value_type)>& iterNext, value_type seedPosition) const;
127 nonvirtual optional<value_type> ScanFindAny_ (const function<bool (value_type)>& testF, value_type seedPosition, bool forwardFirst) const;
128 };
129
130}
131
132/*
133 ********************************************************************************
134 ******************************* Implementation Details *************************
135 ********************************************************************************
136 */
137#include "DisjointDiscreteRange.inl"
138
139#endif /*_Stroika_Foundation_Traversal_DisjointDiscreteRange_h_ */
nonvirtual optional< value_type > FindLastThat(const function< bool(value_type)> &testF) const
nonvirtual optional< value_type > Find(const function< bool(value_type)> &that) const
A DisjointRange is NOT a range, but a collection of non-overlapping (except at the edges) Ranges....
typename RangeType::value_type value_type
Range::value_type is the type of the contained elements of the range (say range of integers,...
RANGE_TYPE RangeType
a Disjoint range collection of (disjoint) ranges of this type.
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:237