Generated on for Gecode by doxygen 1.15.0
int-set.cpp
Go to the documentation of this file.
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.dev>
5 *
6 * Contributing authors:
7 * Alexander Shepil <alexander.shepil@sap.com>
8 * Mikael Zayenz Lagerkvist <lagerkvist@gecode.dev>
9 *
10 * Copyright:
11 * Christian Schulte, 2003
12 * Alexander Shepil, 2024
13 * Mikael Zayenz Lagerkvist, 2026
14 *
15 * This file is part of Gecode, the generic constraint
16 * development environment:
17 * http://www.gecode.dev
18 *
19 * Permission is hereby granted, free of charge, to any person obtaining
20 * a copy of this software and associated documentation files (the
21 * "Software"), to deal in the Software without restriction, including
22 * without limitation the rights to use, copy, modify, merge, publish,
23 * distribute, sublicense, and/or sell copies of the Software, and to
24 * permit persons to whom the Software is furnished to do so, subject to
25 * the following conditions:
26 *
27 * The above copyright notice and this permission notice shall be
28 * included in all copies or substantial portions of the Software.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 *
38 */
39
40#include <gecode/int.hh>
41
42namespace Gecode {
43
44#ifdef GECODE_HAS_FAULT_INJECTION
45 std::atomic<int> IntSet::IntSetObject::fault_live_objects{0};
46
47 void*
48 IntSet::IntSetObject::operator new(size_t s) {
49 void* p = ::operator new(s);
50 fault_live_objects.fetch_add(1, std::memory_order_relaxed);
51 return p;
52 }
53
54 void
55 IntSet::IntSetObject::operator delete(void* p) {
56 fault_live_objects.fetch_sub(1, std::memory_order_relaxed);
57 ::operator delete(p);
58 }
59
60 void
61 IntSet::fault_reset_allocations(void) {
62 IntSetObject::fault_live_objects.store(0, std::memory_order_relaxed);
63 }
64
65 int
66 IntSet::fault_live_allocations(void) {
67 return IntSetObject::fault_live_objects.load(std::memory_order_relaxed);
68 }
69#endif
70
71 IntSet::IntSetObject*
72 IntSet::IntSetObject::allocate(int n) {
73 IntSetObject* o = new IntSetObject;
74 o->size = 0U;
75 o->n = 0;
76 o->r = nullptr;
77 try {
78#ifdef GECODE_HAS_FAULT_INJECTION
80#endif
81 o->r = heap.alloc<Range>(n);
82 } catch (...) {
83 delete o;
84 throw;
85 }
86 o->n = n;
87 return o;
88 }
89
90 bool
91 IntSet::IntSetObject::in(int n) const {
92 int l = 0;
93 int r = this->n - 1;
94
95 while (l <= r) {
96 int m = l + (r - l) / 2;
97 if ((this->r[m].min <= n) && (n <= this->r[m].max)) {
98 return true;
99 } else if (l == r) {
100 return false;
101 } else if (n < this->r[m].min) {
102 r=m-1;
103 } else {
104 l=m+1;
105 }
106 }
107 return false;
108 }
109
110 bool
111 IntSet::IntSetObject::equal(const IntSetObject& iso) const {
112 assert((size == iso.size) || (n == iso.n));
113 for (int i=0; i<n; i++)
114 if ((r[i].min != iso.r[i].min) || (r[i].max != iso.r[i].max))
115 return false;
116 return true;
117 }
118
119 IntSet::IntSetObject::~IntSetObject(void) {
120 if (r != nullptr)
121 heap.free<Range>(r,n);
122 }
123
126 public:
127 bool operator ()(const Range &x, const Range &y);
128 };
129
130 forceinline bool
131 IntSet::MinInc::operator ()(const Range &x, const Range &y) {
132 return x.min < y.min;
133 }
134
135 void
136 IntSet::normalize(Range* r, int n) {
137 if (n > 0) {
138 // Sort ranges
139 {
140 MinInc lt_mi;
141 Support::quicksort<Range>(r, n, lt_mi);
142 }
143 // Conjoin continuous ranges
144 {
145 int min = r[0].min;
146 int max = r[0].max;
147 int i = 1;
148 int j = 0;
149 while (i < n) {
150 if (max+1 < r[i].min) {
151 r[j].min = min; r[j].max = max; j++;
152 min = r[i].min; max = r[i].max; i++;
153 } else {
154 max = std::max(max,r[i].max); i++;
155 }
156 }
157 r[j].min = min; r[j].max = max;
158 n=j+1;
159 }
160 IntSetObject* o = IntSetObject::allocate(n);
161 unsigned int s = 0;
162 for (int i=0; i<n; i++) {
163 s += static_cast<unsigned int>(r[i].max) -
164 static_cast<unsigned int>(r[i].min) + 1U;
165 o->r[i]=r[i];
166 }
167 o->size = s;
168 object(o);
169 }
170 }
171
172 void
173 IntSet::init(const int r[], int n) {
174 assert(n > 0);
175 Region reg;
176 Range* dr = reg.alloc<Range>(n);
177 for (int i=0; i<n; i++) {
178 dr[i].min=r[i]; dr[i].max=r[i];
179 }
180 normalize(&dr[0],n);
181 }
182
183 void
184 IntSet::init(const int r[][2], int n) {
185 assert(n > 0);
186 Region reg;
187 Range* dr = reg.alloc<Range>(n);
188 int j = 0;
189 for (int i=0; i<n; i++)
190 if (r[i][0] <= r[i][1]) {
191 dr[j].min=r[i][0]; dr[j].max=r[i][1]; j++;
192 }
193 normalize(&dr[0],j);
194 }
195
196 IntSet::IntSet(std::initializer_list<int> r) {
197 int n = static_cast<int>(r.size());
198 assert(n > 0);
199 Region reg;
200 Range* dr = reg.alloc<Range>(n);
201 int j=0;
202 for (int k : r) {
203 dr[j].min=dr[j].max=k; j++;
204 }
205 normalize(&dr[0],j);
206 }
207
208 IntSet::IntSet(std::initializer_list<std::pair<int,int>> r) {
209 int n = static_cast<int>(r.size());
210 assert(n > 0);
211 Region reg;
212 Range* dr = reg.alloc<Range>(n);
213 int j=0;
214 for (const std::pair<int,int>& k : r)
215 if (k.first <= k.second) {
216 dr[j].min=k.first; dr[j].max=k.second; j++;
217 }
218 normalize(&dr[0],j);
219 }
220
221
222 void
223 IntSet::init(int n, int m) {
224 if (n <= m) {
225 IntSetObject* o = IntSetObject::allocate(1);
226 o->r[0].min = n; o->r[0].max = m;
227 o->size = static_cast<unsigned int>(m) - static_cast<unsigned int>(n) + 1U;
228 object(o);
229 }
230 }
231
232 const IntSet IntSet::empty;
233
234}
235
236// STATISTICS: int-var
void free(T *b, long unsigned int n)
Delete n objects starting at b.
Definition heap.hpp:467
T * alloc(long unsigned int n)
Allocate block of n objects of type T from heap.
Definition heap.hpp:441
Sort ranges according to increasing minimum.
Definition int-set.cpp:125
bool operator()(const Range &x, const Range &y)
Definition int-set.cpp:131
int min(int i) const
Return minimum of range at position i.
int max(int i) const
Return maximum of range at position i.
int max(void) const
Return maximum of entire set.
unsigned int size(void) const
Return size (cardinality) of set.
IntSet(void)
Initialize as empty set.
Definition int-set-1.hpp:47
static const IntSet empty
Empty set.
Definition int.hh:301
Handle to region.
Definition region.hpp:55
T * alloc(long unsigned int n)
Allocate block of n objects of type T from region.
Definition region.hpp:386
SharedHandle::Object * object(void) const
Access to the shared object.
Heap heap
The single global heap.
Definition heap.cpp:44
void check(Phase p)
Check failpoint for phase p.
void quicksort(Type *l, Type *r, Less &less)
Standard quick sort.
Definition sort.hpp:130
Gecode toplevel namespace
void min(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Gecode::IntArgs i({1, 2, 3, 4})
const int r[4][2]
Definition dom.cpp:152
#define forceinline
Definition config.hpp:141