32 explicit LinearRangeIntToIntFunction(
33 std::function<int64_t(int64_t)> base_function)
34 : base_function_(std::move(base_function)) {}
37 LinearRangeIntToIntFunction(
const LinearRangeIntToIntFunction&) =
delete;
38 LinearRangeIntToIntFunction& operator=(
const LinearRangeIntToIntFunction&) =
41 int64_t Query(int64_t argument)
const override {
42 return base_function_(argument);
45 int64_t RangeMin(int64_t range_begin, int64_t range_end)
const override {
46 DCHECK_LT(range_begin, range_end);
48 for (int64_t i = range_begin;
i < range_end; ++
i) {
49 min_val = std::min(min_val, base_function_(i));
54 int64_t RangeMax(int64_t range_begin, int64_t range_end)
const override {
55 DCHECK_LT(range_begin, range_end);
57 for (int64_t i = range_begin;
i < range_end; ++
i) {
58 max_val = std::max(max_val, base_function_(i));
63 int64_t RangeFirstInsideInterval(int64_t range_begin, int64_t range_end,
64 int64_t interval_begin,
65 int64_t interval_end)
const override {
67 DCHECK_LT(range_begin, range_end);
68 DCHECK_LT(interval_begin, interval_end);
69 int64_t
i = range_begin;
70 for (;
i < range_end; ++
i) {
71 const int64_t value = base_function_(i);
72 if (interval_begin <= value && value < interval_end)
break;
77 int64_t RangeLastInsideInterval(int64_t range_begin, int64_t range_end,
78 int64_t interval_begin,
79 int64_t interval_end)
const override {
82 DCHECK_LT(range_begin, range_end);
83 DCHECK_LT(interval_begin, interval_end);
84 int64_t
i = range_end - 1;
85 for (;
i >= range_begin; --
i) {
86 const int64_t value = base_function_(i);
87 if (interval_begin <= value && value < interval_end)
break;
93 std::function<int64_t(int64_t)> base_function_;
96std::vector<int64_t> FunctionToVector(
const std::function<int64_t(int64_t)>& f,
99 CHECK_LT(domain_start, domain_end);
100 std::vector<int64_t> output(domain_end - domain_start, 0);
101 for (int64_t i = 0;
i < domain_end - domain_start; ++
i) {
102 output[
i] = f(i + domain_start);
113 CachedRangeIntToIntFunction(
114 const std::function<int64_t(int64_t)>& base_function,
115 int64_t domain_start, int64_t domain_end)
116 : domain_start_(domain_start),
117 rmq_min_(FunctionToVector(base_function, domain_start, domain_end)),
118 rmq_max_(rmq_min_.array()) {
119 CHECK_LT(domain_start, domain_end);
123 CachedRangeIntToIntFunction(
const CachedRangeIntToIntFunction&) =
delete;
124 CachedRangeIntToIntFunction& operator=(
const CachedRangeIntToIntFunction&) =
127 int64_t Query(int64_t argument)
const override {
128 DCHECK_LE(domain_start_, argument);
129 DCHECK_LE(argument, domain_start_ +
static_cast<int64_t
>(array().size()));
130 return array()[argument - domain_start_];
132 int64_t RangeMin(int64_t from, int64_t
to)
const override {
133 DCHECK_LE(domain_start_, from);
135 DCHECK_LE(
to, domain_start_ +
static_cast<int64_t
>(array().size()));
136 return rmq_min_.RangeMinimum(from - domain_start_,
to - domain_start_);
138 int64_t RangeMax(int64_t from, int64_t
to)
const override {
139 DCHECK_LE(domain_start_, from);
141 DCHECK_LE(
to, domain_start_ +
static_cast<int64_t
>(array().size()));
142 return rmq_max_.RangeMinimum(from - domain_start_,
to - domain_start_);
144 int64_t RangeFirstInsideInterval(int64_t range_begin, int64_t range_end,
145 int64_t interval_begin,
146 int64_t interval_end)
const override {
148 DCHECK_LE(domain_start_, range_begin);
149 DCHECK_LT(range_begin, range_end);
150 DCHECK_LE(range_end, domain_start_ + array().size());
151 DCHECK_LT(interval_begin, interval_end);
152 int64_t
i = range_begin;
153 for (;
i < range_end; ++
i) {
154 const int64_t value = array()[
i - domain_start_];
155 if (interval_begin <= value && value < interval_end)
break;
159 int64_t RangeLastInsideInterval(int64_t range_begin, int64_t range_end,
160 int64_t interval_begin,
161 int64_t interval_end)
const override {
163 DCHECK_LE(domain_start_, range_begin);
164 DCHECK_LT(range_begin, range_end);
165 DCHECK_LE(range_end, domain_start_ + array().size());
166 DCHECK_LT(interval_begin, interval_end);
167 int64_t
i = range_end - 1;
168 for (;
i >= range_begin; --
i) {
169 const int64_t value = array()[
i - domain_start_];
170 if (interval_begin <= value && value < interval_end)
break;
176 const std::vector<int64_t>& array()
const {
return rmq_min_.array(); }
178 const int64_t domain_start_;
179 const RangeMinimumQuery<int64_t, std::less<int64_t>> rmq_min_;
180 const RangeMinimumQuery<int64_t, std::greater<int64_t>> rmq_max_;
185 CachedRangeMinMaxIndexFunction(
const std::function<int64_t(int64_t)>& f,
186 int64_t domain_start, int64_t domain_end)
187 : domain_start_(domain_start),
188 domain_end_(domain_end),
189 index_rmq_min_(FunctionToVector(f, domain_start, domain_end)),
190 index_rmq_max_(index_rmq_min_.array()) {
191 CHECK_LT(domain_start, domain_end);
195 CachedRangeMinMaxIndexFunction(
const CachedRangeMinMaxIndexFunction&) =
197 CachedRangeMinMaxIndexFunction& operator=(
198 const CachedRangeMinMaxIndexFunction&) =
delete;
200 inline int64_t RangeMinArgument(int64_t from, int64_t
to)
const override {
201 DCHECK_LE(domain_start_, from);
203 DCHECK_LE(
to, domain_end_);
204 return index_rmq_min_.GetMinimumIndexFromRange(from - domain_start_,
205 to - domain_start_) +
208 inline int64_t RangeMaxArgument(int64_t from, int64_t
to)
const override {
209 DCHECK_LE(domain_start_, from);
211 DCHECK_LE(
to, domain_end_);
212 return index_rmq_max_.GetMinimumIndexFromRange(from - domain_start_,
213 to - domain_start_) +
218 const int64_t domain_start_;
219 const int64_t domain_end_;
220 const RangeMinimumIndexQuery<int64_t, std::less<int64_t>> index_rmq_min_;
221 const RangeMinimumIndexQuery<int64_t, std::greater<int64_t>> index_rmq_max_;
226 std::function<int64_t(int64_t)> f) {
227 return new LinearRangeIntToIntFunction(std::move(f));
231 const std::function<int64_t(int64_t)>& f, int64_t domain_start,
232 int64_t domain_end) {
233 return new CachedRangeIntToIntFunction(f, domain_start, domain_end);
237 const std::function<int64_t(int64_t)>& f, int64_t domain_start,
238 int64_t domain_end) {
239 return new CachedRangeMinMaxIndexFunction(f, domain_start, domain_end);
In SWIG mode, we don't want anything besides these top-level includes.
RangeIntToIntFunction * MakeCachedIntToIntFunction(const std::function< int64_t(int64_t)> &f, int64_t domain_start, int64_t domain_end)
RangeIntToIntFunction * MakeBareIntToIntFunction(std::function< int64_t(int64_t)> f)
RangeMinMaxIndexFunction * MakeCachedRangeMinMaxIndexFunction(const std::function< int64_t(int64_t)> &f, int64_t domain_start, int64_t domain_end)
trees with all degrees equal to
static const int64_t kint64max
static const int64_t kint64min