rippled
RangeSet.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef RIPPLE_BASICS_RANGESET_H_INCLUDED
21 #define RIPPLE_BASICS_RANGESET_H_INCLUDED
22 
23 #include <ripple/beast/core/LexicalCast.h>
24 
25 #include <boost/algorithm/string.hpp>
26 #include <boost/icl/closed_interval.hpp>
27 #include <boost/icl/interval_set.hpp>
28 #include <boost/optional.hpp>
29 
30 #include <string>
31 
32 namespace ripple {
33 
43 template <class T>
44 using ClosedInterval = boost::icl::closed_interval<T>;
45 
51 template <class T>
53 range(T low, T high)
54 {
55  return ClosedInterval<T>(low, high);
56 }
57 
68 template <class T>
69 using RangeSet = boost::icl::interval_set<T, std::less, ClosedInterval<T>>;
70 
80 template <class T>
83 {
84  if (ci.first() == ci.last())
85  return std::to_string(ci.first());
86  return std::to_string(ci.first()) + "-" + std::to_string(ci.last());
87 }
88 
97 template <class T>
100 {
101  using ripple::to_string;
102 
103  if (rs.empty())
104  return "empty";
105  std::string res = "";
106  for (auto const& interval : rs)
107  {
108  if (!res.empty())
109  res += ",";
110  res += to_string(interval);
111  }
112  return res;
113 }
114 
124 template <class T>
125 bool
127 {
128  std::vector<std::string> intervals;
130  bool result{true};
131 
132  boost::split(tokens, s, boost::algorithm::is_any_of(","));
133  for (auto const& t : tokens)
134  {
135  boost::split(intervals, t, boost::algorithm::is_any_of("-"));
136  switch (intervals.size())
137  {
138  case 1: {
139  T front;
140  if (!beast::lexicalCastChecked(front, intervals.front()))
141  result = false;
142  else
143  rs.insert(front);
144  break;
145  }
146  case 2: {
147  T front;
148  if (!beast::lexicalCastChecked(front, intervals.front()))
149  result = false;
150  else
151  {
152  T back;
153  if (!beast::lexicalCastChecked(back, intervals.back()))
154  result = false;
155  else
156  rs.insert(range(front, back));
157  }
158  break;
159  }
160  default:
161  result = false;
162  }
163 
164  if (!result)
165  break;
166  intervals.clear();
167  }
168 
169  if (!result)
170  rs.clear();
171  return result;
172 }
173 
182 template <class T>
183 boost::optional<T>
184 prevMissing(RangeSet<T> const& rs, T t, T minVal = 0)
185 {
186  if (rs.empty() || t == minVal)
187  return boost::none;
188  RangeSet<T> tgt{ClosedInterval<T>{minVal, t - 1}};
189  tgt -= rs;
190  if (tgt.empty())
191  return boost::none;
192  return boost::icl::last(tgt);
193 }
194 
195 } // namespace ripple
196 
197 #endif
std::string
STL class.
std::vector< std::string >
std::vector::size
T size(T... args)
ripple::from_string
bool from_string(RangeSet< T > &rs, std::string const &s)
Convert the given styled string to a RangeSet.
Definition: RangeSet.h:126
std::vector::back
T back(T... args)
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:45
std::vector::front
T front(T... args)
std::vector::clear
T clear(T... args)
ripple::prevMissing
boost::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:184
std::to_string
T to_string(T... args)
ripple::range
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition: RangeSet.h:53
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
beast::lexicalCastChecked
bool lexicalCastChecked(Out &out, In in)
Intelligently convert from one type to another.
Definition: LexicalCast.h:266
std::string::empty
T empty(T... args)
ripple::RangeSet
boost::icl::interval_set< T, std::less, ClosedInterval< T > > RangeSet
A set of closed intervals over the domain T.
Definition: RangeSet.h:69
ripple::ClosedInterval
boost::icl::closed_interval< T > ClosedInterval
A closed interval over the domain T.
Definition: RangeSet.h:44
string