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 <optional>
10#include <string>
11#include <vector>
12
13namespace xrpl {
14
24template <class T>
25using ClosedInterval = boost::icl::closed_interval<T>;
26
32template <class T>
34range(T low, T high)
35{
36 return ClosedInterval<T>(low, high);
37}
38
49template <class T>
50using RangeSet = boost::icl::interval_set<T, std::less, ClosedInterval<T>>;
51
61template <class T>
64{
65 if (ci.first() == ci.last())
66 return std::to_string(ci.first());
67 return std::to_string(ci.first()) + "-" + std::to_string(ci.last());
68}
69
78template <class T>
81{
82 if (rs.empty())
83 return "empty";
84
86 for (auto const& interval : rs)
87 s += xrpl::to_string(interval) + ",";
88 s.pop_back();
89
90 return s;
91}
92
102template <class T>
103[[nodiscard]] bool
105{
106 std::vector<std::string> intervals;
108 bool result{true};
109
110 rs.clear();
111 boost::split(tokens, s, boost::algorithm::is_any_of(","));
112 for (auto const& t : tokens)
113 {
114 boost::split(intervals, t, boost::algorithm::is_any_of("-"));
115 switch (intervals.size())
116 {
117 case 1: {
118 T front;
119 if (!beast::lexicalCastChecked(front, intervals.front()))
120 {
121 result = false;
122 }
123 else
124 {
125 rs.insert(front);
126 }
127 break;
128 }
129 case 2: {
130 T front;
131 if (!beast::lexicalCastChecked(front, intervals.front()))
132 {
133 result = false;
134 }
135 else
136 {
137 T back;
138 if (!beast::lexicalCastChecked(back, intervals.back()))
139 {
140 result = false;
141 }
142 else
143 {
144 rs.insert(range(front, back));
145 }
146 }
147 break;
148 }
149 default:
150 result = false;
151 }
152
153 if (!result)
154 break;
155 intervals.clear();
156 }
157
158 if (!result)
159 rs.clear();
160 return result;
161}
162
171template <class T>
173prevMissing(RangeSet<T> const& rs, T t, T minVal = 0)
174{
175 if (rs.empty() || t == minVal)
176 return std::nullopt;
177 RangeSet<T> tgt{ClosedInterval<T>{minVal, t - 1}};
178 tgt -= rs;
179 if (tgt.empty())
180 return std::nullopt;
181 return boost::icl::last(tgt);
182}
183
184} // namespace xrpl
T back(T... args)
T clear(T... args)
T front(T... args)
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:173
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition RangeSet.h:34
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:633
bool fromString(RangeSet< T > &rs, std::string const &s)
Convert the given styled string to a RangeSet.
Definition RangeSet.h:104
boost::icl::closed_interval< T > ClosedInterval
A closed interval over the domain T.
Definition RangeSet.h:25
boost::icl::interval_set< T, std::less, ClosedInterval< T > > RangeSet
A set of closed intervals over the domain T.
Definition RangeSet.h:50
T pop_back(T... args)
T size(T... args)
T to_string(T... args)