xrpld
Loading...
Searching...
No Matches
RangeSet.h
1#pragma once
2
3#include <xrpl/beast/core/LexicalCast.h>
4
5#include <boost/algorithm/string.hpp>
6#include <boost/icl/closed_interval.hpp>
7#include <boost/icl/interval_set.hpp>
8
9#include <functional>
10#include <optional>
11#include <string>
12#include <vector>
13
14namespace xrpl {
15
26template <class T>
27using ClosedInterval = boost::icl::closed_interval<T>;
28
35template <class T>
37range(T low, T high)
38{
39 return ClosedInterval<T>(low, high);
40}
41
53template <class T>
54using RangeSet = boost::icl::interval_set<T, std::less, ClosedInterval<T>>;
55
66template <class T>
69{
70 if (ci.first() == ci.last())
71 return std::to_string(ci.first());
72 return std::to_string(ci.first()) + "-" + std::to_string(ci.last());
73}
74
84template <class T>
87{
88 if (rs.empty())
89 return "empty";
90
92 for (auto const& interval : rs)
93 s += xrpl::to_string(interval) + ",";
94 s.pop_back();
95
96 return s;
97}
98
109template <class T>
110[[nodiscard]] bool
112{
113 std::vector<std::string> intervals;
115 bool result{true};
116
117 rs.clear();
118 boost::split(tokens, s, boost::algorithm::is_any_of(","));
119 for (auto const& t : tokens)
120 {
121 boost::split(intervals, t, boost::algorithm::is_any_of("-"));
122 switch (intervals.size())
123 {
124 case 1: {
125 T front;
126 if (!beast::lexicalCastChecked(front, intervals.front()))
127 {
128 result = false;
129 }
130 else
131 {
132 rs.insert(front);
133 }
134 break;
135 }
136 case 2: {
137 T front;
138 if (!beast::lexicalCastChecked(front, intervals.front()))
139 {
140 result = false;
141 }
142 else
143 {
144 T back;
145 if (!beast::lexicalCastChecked(back, intervals.back()))
146 {
147 result = false;
148 }
149 else
150 {
151 rs.insert(range(front, back));
152 }
153 }
154 break;
155 }
156 default:
157 result = false;
158 }
159
160 if (!result)
161 break;
162 intervals.clear();
163 }
164
165 if (!result)
166 rs.clear();
167 return result;
168}
169
179template <class T>
181prevMissing(RangeSet<T> const& rs, T t, T minVal = 0)
182{
183 if (rs.empty() || t == minVal)
184 return std::nullopt;
185 RangeSet<T> tgt{ClosedInterval<T>{minVal, t - 1}};
186 tgt -= rs;
187 if (tgt.empty())
188 return std::nullopt;
189 return boost::icl::last(tgt);
190}
191
192} // namespace xrpl
T back(T... args)
T clear(T... args)
T front(T... args)
constexpr bool lexicalCastChecked(Out &out, In in)
Intelligently convert from one type to another.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::optional< T > prevMissing(RangeSet< T > const &rs, T t, T minVal=0)
Find the largest value not in the set that is less than a given value.
Definition RangeSet.h:181
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition RangeSet.h:37
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:651
bool fromString(RangeSet< T > &rs, std::string const &s)
Convert the given styled string to a RangeSet.
Definition RangeSet.h:111
boost::icl::closed_interval< T > ClosedInterval
A closed interval over the domain T.
Definition RangeSet.h:27
boost::icl::interval_set< T, std::less, ClosedInterval< T > > RangeSet
A set of closed intervals over the domain T.
Definition RangeSet.h:54
T pop_back(T... args)
T size(T... args)
T to_string(T... args)