rippled
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 result = false;
121 else
122 rs.insert(front);
123 break;
124 }
125 case 2: {
126 T front;
127 if (!beast::lexicalCastChecked(front, intervals.front()))
128 result = false;
129 else
130 {
131 T back;
132 if (!beast::lexicalCastChecked(back, intervals.back()))
133 result = false;
134 else
135 rs.insert(range(front, back));
136 }
137 break;
138 }
139 default:
140 result = false;
141 }
142
143 if (!result)
144 break;
145 intervals.clear();
146 }
147
148 if (!result)
149 rs.clear();
150 return result;
151}
152
161template <class T>
163prevMissing(RangeSet<T> const& rs, T t, T minVal = 0)
164{
165 if (rs.empty() || t == minVal)
166 return std::nullopt;
167 RangeSet<T> tgt{ClosedInterval<T>{minVal, t - 1}};
168 tgt -= rs;
169 if (tgt.empty())
170 return std::nullopt;
171 return boost::icl::last(tgt);
172}
173
174} // namespace xrpl
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: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:163
bool from_string(RangeSet< T > &rs, std::string const &s)
Convert the given styled string to a RangeSet.
Definition RangeSet.h:104
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition RangeSet.h:34
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:597
boost::icl::interval_set< T, std::less, ClosedInterval< T > > RangeSet
A set of closed intervals over the domain T.
Definition RangeSet.h:50
boost::icl::closed_interval< T > ClosedInterval
A closed interval over the domain T.
Definition RangeSet.h:25
T pop_back(T... args)
T size(T... args)
T to_string(T... args)