rippled
Loading...
Searching...
No Matches
RangeSet.h
1#ifndef XRPL_BASICS_RANGESET_H_INCLUDED
2#define XRPL_BASICS_RANGESET_H_INCLUDED
3
4#include <xrpl/beast/core/LexicalCast.h>
5
6#include <boost/algorithm/string.hpp>
7#include <boost/icl/closed_interval.hpp>
8#include <boost/icl/interval_set.hpp>
9
10#include <optional>
11#include <string>
12#include <vector>
13
14namespace ripple {
15
25template <class T>
26using ClosedInterval = boost::icl::closed_interval<T>;
27
33template <class T>
35range(T low, T high)
36{
37 return ClosedInterval<T>(low, high);
38}
39
50template <class T>
51using RangeSet = boost::icl::interval_set<T, std::less, ClosedInterval<T>>;
52
62template <class T>
65{
66 if (ci.first() == ci.last())
67 return std::to_string(ci.first());
68 return std::to_string(ci.first()) + "-" + std::to_string(ci.last());
69}
70
79template <class T>
82{
83 if (rs.empty())
84 return "empty";
85
87 for (auto const& interval : rs)
88 s += ripple::to_string(interval) + ",";
89 s.pop_back();
90
91 return s;
92}
93
103template <class T>
104[[nodiscard]] bool
106{
107 std::vector<std::string> intervals;
109 bool result{true};
110
111 rs.clear();
112 boost::split(tokens, s, boost::algorithm::is_any_of(","));
113 for (auto const& t : tokens)
114 {
115 boost::split(intervals, t, boost::algorithm::is_any_of("-"));
116 switch (intervals.size())
117 {
118 case 1: {
119 T front;
120 if (!beast::lexicalCastChecked(front, intervals.front()))
121 result = false;
122 else
123 rs.insert(front);
124 break;
125 }
126 case 2: {
127 T front;
128 if (!beast::lexicalCastChecked(front, intervals.front()))
129 result = false;
130 else
131 {
132 T back;
133 if (!beast::lexicalCastChecked(back, intervals.back()))
134 result = false;
135 else
136 rs.insert(range(front, back));
137 }
138 break;
139 }
140 default:
141 result = false;
142 }
143
144 if (!result)
145 break;
146 intervals.clear();
147 }
148
149 if (!result)
150 rs.clear();
151 return result;
152}
153
162template <class T>
164prevMissing(RangeSet<T> const& rs, T t, T minVal = 0)
165{
166 if (rs.empty() || t == minVal)
167 return std::nullopt;
168 RangeSet<T> tgt{ClosedInterval<T>{minVal, t - 1}};
169 tgt -= rs;
170 if (tgt.empty())
171 return std::nullopt;
172 return boost::icl::last(tgt);
173}
174
175} // namespace ripple
176
177#endif
T back(T... args)
T clear(T... args)
T front(T... args)
T is_same_v
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:6
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:164
boost::icl::closed_interval< T > ClosedInterval
A closed interval over the domain T.
Definition RangeSet.h:26
bool from_string(RangeSet< T > &rs, std::string const &s)
Convert the given styled string to a RangeSet.
Definition RangeSet.h:105
boost::icl::interval_set< T, std::less, ClosedInterval< T > > RangeSet
A set of closed intervals over the domain T.
Definition RangeSet.h:51
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition RangeSet.h:35
T pop_back(T... args)
T size(T... args)
T to_string(T... args)