GCC Code Coverage Report


Directory: ./
File: lib/geogram/basic/attributes.h
Date: 2026-09-07 02:25:23
Exec Total Coverage
Lines: 188 223 84.3%
Functions: 70 229 30.6%
Branches: 576 4515 12.8%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40
41 #ifndef GEOGRAM_BASIC_ATTRIBUTES
42 #define GEOGRAM_BASIC_ATTRIBUTES
43
44 #include <geogram/basic/common.h>
45 #include <geogram/basic/memory.h>
46 #include <geogram/basic/life_cycle.h>
47 #include <geogram/basic/numeric.h>
48 #include <geogram/basic/process.h>
49 #include <geogram/basic/geofile.h>
50 #include <geogram/basic/logger.h>
51
52 #include <map>
53 #include <typeinfo>
54 #include <set>
55 #include <type_traits>
56
57 /**
58 * \file geogram/basic/attributes.h
59 * \brief Generic mechanism for attributes.
60 */
61
62 namespace GEO {
63
64 class AttributeStore;
65
66 /**
67 * \brief Base class for attributes. They are notified
68 * whenever the AttributeStore is modified.
69 */
70 class GEOGRAM_API AttributeStoreObserver {
71 public:
72
73 /**
74 * \brief Creates a new uninitialied AttributeStore.
75 */
76 5642 AttributeStoreObserver() :
77 5642 base_addr_(nullptr), size_(0), dimension_(0),
78
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
5642 disconnected_(false) {
79 }
80
81 /**
82 * \brief Callback function, called by the AttributeStore
83 * whenever it is modified.
84 * \param[in] base_addr new base address of the AttributeStore
85 * \param[in] size new number of items in the AttributeStore
86 * \param[in] dim new dimension, i.e. number of elements per item
87 */
88 void notify(
89 Memory::pointer base_addr, index_t size, index_t dim
90 ) {
91 1950091 base_addr_ = base_addr;
92 1950091 size_ = size;
93 1950091 dimension_ = dim;
94 }
95
96 /**
97 * \brief Gets the size.
98 * \return the number of items
99 */
100 index_t size() const {
101 return size_;
102 }
103
104 /**
105 * \brief Gets the dimension.
106 * \return the number of elements per item
107 */
108 index_t dimension() const {
109
66/168
✓ Branch 0 taken 658 times.
✓ Branch 1 taken 101010 times.
✓ Branch 2 taken 5512 times.
✓ Branch 3 taken 922312 times.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 203 times.
✓ Branch 7 taken 60589 times.
✓ Branch 8 taken 458529 times.
✓ Branch 9 taken 31618 times.
✓ Branch 10 taken 4 times.
✓ Branch 11 taken 5 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 64430 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✓ Branch 40 taken 300 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✓ Branch 43 taken 10000 times.
✓ Branch 44 taken 80 times.
✓ Branch 45 taken 444 times.
✓ Branch 46 taken 2345 times.
✓ Branch 47 taken 2050 times.
✓ Branch 48 taken 356 times.
✓ Branch 49 taken 320 times.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✓ Branch 52 taken 300 times.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✓ Branch 55 taken 20000 times.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✓ Branch 58 taken 300 times.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✓ Branch 94 taken 518 times.
✓ Branch 95 taken 444 times.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✓ Branch 98 taken 108 times.
✓ Branch 99 taken 528 times.
✓ Branch 100 taken 5713 times.
✓ Branch 101 taken 3929 times.
✓ Branch 102 taken 392 times.
✓ Branch 103 taken 429 times.
✓ Branch 104 taken 93 times.
✓ Branch 105 taken 501 times.
✓ Branch 106 taken 4730 times.
✓ Branch 107 taken 3792 times.
✓ Branch 108 taken 378 times.
✓ Branch 109 taken 427 times.
✓ Branch 110 taken 93 times.
✓ Branch 111 taken 462 times.
✓ Branch 112 taken 3783 times.
✓ Branch 113 taken 3949 times.
✓ Branch 114 taken 358 times.
✓ Branch 115 taken 409 times.
✓ Branch 116 taken 85 times.
✓ Branch 117 taken 468 times.
✓ Branch 118 taken 4331 times.
✓ Branch 119 taken 3886 times.
✓ Branch 120 taken 338 times.
✓ Branch 121 taken 407 times.
✓ Branch 122 taken 89 times.
✓ Branch 123 taken 508 times.
✓ Branch 124 taken 6464 times.
✓ Branch 125 taken 5264 times.
✓ Branch 126 taken 376 times.
✓ Branch 127 taken 471 times.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✗ Branch 141 not taken.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✓ Branch 148 taken 521 times.
✓ Branch 149 taken 528 times.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✓ Branch 152 taken 470 times.
✓ Branch 153 taken 501 times.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✓ Branch 156 taken 518 times.
✓ Branch 157 taken 462 times.
✗ Branch 158 not taken.
✗ Branch 159 not taken.
✓ Branch 160 taken 540 times.
✓ Branch 161 taken 468 times.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✓ Branch 164 taken 540 times.
✓ Branch 165 taken 508 times.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
288944044 return dimension_;
110 }
111
112 /**
113 * \brief Gets the total number of elements.
114 * \details This corresponds to one position past
115 * the last valid index.
116 * \return the total number of elements.
117 */
118 index_t nb_elements() const {
119 return size_ * dimension_;
120 }
121
122 /**
123 * \brief Gets a pointer to the storage
124 * \return a pointer to the first element
125 */
126 Memory::pointer base_addr() const {
127 return base_addr_;
128 }
129
130 /**
131 * \brief Registers this observer to an AttributeStore.
132 * \param[in] store a pointer to the AttributeStore.
133 */
134 void register_me(AttributeStore* store);
135
136 /**
137 * \brief Unregisters this observer from an AttributeStore.
138 * \param[in] store a pointer to the AttributeStore.
139 */
140 void unregister_me(AttributeStore* store);
141
142 /**
143 * \brief Disconnects this AttributeStoreObserver from its
144 * AttributeStore.
145 * \details This function is called whenever the AttributesManager is
146 * destroyed before the Attributes (can occur when using Lua scripting
147 * with Attribute wrapper objects).
148 */
149 void disconnect() {
150 base_addr_ = nullptr;
151 size_ = 0;
152 dimension_ = 0;
153 disconnected_ = true;
154 }
155
156 /**
157 * \brief Tests whether this AttributeStoreObserver was disconnected
158 * \retval true if this AttributeStoreObserver was disconnected,
159 * \retval false otherwise
160 * \see disconnect()
161 */
162 bool disconnected() const {
163 return disconnected_;
164 }
165
166 protected:
167 Memory::pointer base_addr_;
168 index_t size_;
169 index_t dimension_;
170 bool disconnected_;
171 };
172
173
174 /*********************************************************************/
175
176
177 /**
178 * \brief Internal class for creating an AttributeStore
179 * from the type name of its elements.
180 */
181 class GEOGRAM_API AttributeStoreCreator : public Counted {
182 public:
183
184 /**
185 * \brief AttributeStoreCreator destructor.
186 */
187 ~AttributeStoreCreator() override;
188
189 /**
190 * \brief Creates a new attribute store.
191 * \param[in] dimension number of elements in each item
192 * \return a pointer to the newly created AttributeStore
193 */
194 virtual AttributeStore* create_attribute_store(index_t dimension) = 0;
195
196 /**
197 * \brief Tests whether elements of this attribute can be trivially
198 * copyable
199 * \retval true if elements can be copied with memcpy and read, saved
200 * using fread(), fwrite
201 * \retval false otherwise
202 */
203 virtual bool elements_are_trivially_copyable() const = 0;
204
205 private:
206 std::string element_type_name_;
207 std::string element_typeid_name_;
208 };
209
210 /**
211 * \brief An automatic reference-counted pointer to
212 * an AttributeStoreCreator.
213 */
214 typedef SmartPointer<AttributeStoreCreator> AttributeStoreCreator_var;
215
216 /**
217 * \brief Notifies a set of AttributeStoreObservers
218 * each time the stored array changes size and/or
219 * base address and/or dimension.
220 */
221 class GEOGRAM_API AttributeStore {
222 public:
223 /**
224 * \brief AttributeStore constructor.
225 * \param[in] elemsize size of one element,
226 * in bytes.
227 * \param[in] dim number of elements in
228 * each item. Default is 1 for standard
229 * attributes and can be greater for vector
230 * attributes.
231 */
232 AttributeStore(size_t elemsize, index_t dim=1);
233
234 /**
235 * \brief AttributeStore destructor.
236 */
237 virtual ~AttributeStore();
238
239
240 /**
241 * \brief Tests whether this AttributeStore stores
242 * elements of a given type.
243 * \param[in] type_name the name of the type, as given by
244 * typeid(T).name()
245 * \retval true if this AttributeStore stores elements
246 * of type \p type_name
247 * \retval false otherwise
248 */
249 virtual bool elements_type_matches(
250 const std::string& type_name
251 ) const = 0;
252
253 /**
254 * \brief Gets the typeid name of the element type stored
255 * in this AttributeStore.
256 * \return the typeid name, as a string.
257 */
258 virtual std::string element_typeid_name() const = 0;
259
260 /**
261 * \brief Gets the user typeid name of the element type stored
262 * in this AttributeStore.
263 * \details May be different from element_typeid_name() for instance
264 * for Attribute<bool>, implemented using Numeric::uint8.
265 * \return the typeid name, as a string.
266 */
267 virtual std::string user_element_typeid_name() const = 0;
268
269 /**
270 * \brief Gets the size.
271 * \return the number of items
272 */
273 index_t size() const {
274
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
165994 return cached_size_;
275 }
276
277 /**
278 * \brief Gets the capacity.
279 * \return the number of items that can be stored without
280 * a reallocation.
281 */
282 index_t capacity() const {
283 5958 return cached_capacity_;
284 }
285
286 /**
287 * \brief Resizes this AttributeStore
288 * \param[in] new_size new number of items
289 */
290 virtual void resize(index_t new_size) = 0;
291
292 /**
293 * \brief Reserves memory.
294 * \param[in] new_capacity total number of items to
295 * be stored.
296 */
297 virtual void reserve(index_t new_capacity) = 0;
298
299 /**
300 * \brief Resizes this AttributeStore to 0.
301 * \param[in] keep_memory if true, then memory
302 * is kept reserved for future use.
303 */
304 virtual void clear(bool keep_memory = false) = 0;
305
306 /**
307 * \brief Tests whether observers listen to this AttributeStore.
308 * \retval true if at least one observer is bound to this AttributeStore
309 * \retval false otherwise
310 */
311 bool has_observers() const {
312 return !observers_.empty();
313 }
314
315 /**
316 * \brief Gets the dimension.
317 * \details The dimension is 1 for standard attributes and
318 * can be greater for vector attributes.
319 */
320 index_t dimension() const {
321
2/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 532 times.
✓ Branch 3 taken 99 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1042 return dimension_;
322 }
323
324 /**
325 * \brief Sets the dimension.
326 * \details The dimension is 1 for standard attributes and
327 * can be greater for vector attributes. The existing
328 * fields are kept. If the new dimension is greater than
329 * the old one, then new fields are initialized to the default
330 * value for the attribute type.
331 * \param[in] dim the new dimension
332 */
333 virtual void redim(index_t dim) = 0;
334
335
336 /**
337 * \brief Applies a permutation to the stored attributes.
338 * \details Applying a permutation to the data is equivalent
339 * to:
340 * \code
341 * for(i=0; i<permutation.size(); i++) {
342 * data2[i] = data[permutation[i]]
343 * }
344 * data = data2 ;
345 * \endcode
346 * But it is done in-place.
347 * \param[in] permutation the permutation.
348 * It is temporarily changed during execution of the
349 * function, but identical to the input on exit.
350 */
351 virtual void apply_permutation(
352 const vector<index_t>& permutation
353 );
354
355
356 /**
357 * \brief Compresses the stored attributes, by
358 * applying an index mapping that fills-in the gaps.
359 * \details This is equivalent to:
360 * \code
361 * for(i=0; i<size(); i++) {
362 * if(old2new[i] != index_t(-1)) {
363 * data2[old2new[i]] = data[i];
364 * }
365 * }
366 * data = data2 ;
367 * \endcode
368 * \param[in] old2new the index mapping to be applied.
369 * \pre old2new[i] <= i || old2new[i] == index_t(-1)
370 */
371 virtual void compress(const vector<index_t>& old2new);
372
373 /**
374 * \brief Zeroes all the memory associated with this
375 * AttributeStore.
376 */
377 virtual void zero();
378
379 /**
380 * \brief Creates a new AttributeStore that is a carbon copy
381 * of this AttributeStore.
382 * \details Only the data is copied, observers are not copied.
383 */
384 virtual AttributeStore* clone() const = 0;
385
386
387 /**
388 * \brief Copies an item
389 * \param[in] to index of the destination item
390 * \param[in] from index of the source item
391 */
392 778797 void copy_item(index_t to, index_t from) {
393 geo_debug_assert(from < cached_size_);
394 geo_debug_assert(to < cached_size_);
395
1/2
✓ Branch 0 taken 778797 times.
✗ Branch 1 not taken.
778797 size_t item_size = element_size_ * dimension_;
396
1/2
✓ Branch 0 taken 778797 times.
✗ Branch 1 not taken.
778797 if(lifecycle_.is_null()) {
397 Memory::copy(
398 778797 cached_base_addr_+to*item_size,
399 778797 cached_base_addr_+from*item_size,
400 item_size
401 );
402 } else {
403 lifecycle_->assign(
404 cached_base_addr_+to*item_size,
405 cached_base_addr_+from*item_size
406 );
407 }
408 778797 }
409
410 /**
411 * \brief Sets an item to zero
412 * \param[in] to index of the item
413 */
414 291740 void zero_item(index_t to) {
415 geo_debug_assert(to < cached_size_);
416
2/2
✓ Branch 0 taken 209840 times.
✓ Branch 1 taken 81900 times.
291740 size_t item_size = element_size_ * dimension_;
417
2/2
✓ Branch 0 taken 209840 times.
✓ Branch 1 taken 81900 times.
291740 if(lifecycle_.is_null()) {
418 Memory::clear(
419 209840 cached_base_addr_+to*item_size,
420 item_size
421 );
422 } else {
423 81900 lifecycle_->reset(cached_base_addr_+to*item_size);
424 }
425 291740 }
426
427 /**
428 * \brief Scales an item
429 * \details item[to] *= s
430 * \param[in] to the index of the item
431 * \param[in] s the scaling factor
432 * \details default implementation does nothing
433 */
434 virtual void scale_item(index_t to, double s);
435
436 /**
437 * \brief Adds a scaled item to another item
438 * \detais item[to] += s * item[from]
439 * \param[in] to the item
440 * \param[in] s the scaling factor
441 * \param[in] from the item to be scaled and added
442 * \details default implementation does nothing
443 */
444 virtual void madd_item(index_t to, double s, index_t from);
445
446 /**
447 * \brief Swaps two items
448 * \param[in] i , j the indices of the items to be swapped
449 */
450 void swap_items(index_t i, index_t j);
451
452 /**
453 * \brief Gets a pointer to the stored data.
454 * \return A pointer to the memory block
455 */
456 void* data() {
457 2 return cached_base_addr_;
458 }
459
460 /**
461 * \brief Gets a pointer to the stored data.
462 * \return A const pointer to the memory block
463 */
464 const void* data() const {
465 return cached_base_addr_;
466 }
467
468 /**
469 * \brief Gets the element size.
470 * \return the size of an element, in bytes
471 */
472 size_t element_size() const {
473
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 return element_size_;
474 }
475
476 /**
477 * \brief Tests whether a given element type is registered in
478 * the system.
479 * \param[in] element_type_name a const reference to a string
480 * with the C++ type name
481 * \retval true if the element type was registered
482 * \retval false otherwise
483 */
484 static bool element_type_name_is_known(
485 const std::string& element_type_name
486 ) {
487 return (
488 type_name_to_creator_.find(element_type_name) !=
489 type_name_to_creator_.end()
490 );
491 }
492
493 /**
494 * \brief Tests whether a given element type is registered in
495 * the system.
496 * \param[in] element_typeid_name a const reference to a string
497 * with the mangled type, as given by typeid(T).name()
498 * \retval true if the element type was registered
499 * \retval false otherwise
500 */
501 static bool element_typeid_name_is_known(
502 const std::string& element_typeid_name
503 ) {
504 return (
505 typeid_name_to_type_name_.find(element_typeid_name) !=
506 typeid_name_to_type_name_.end()
507 );
508 }
509
510 /**
511 * \brief Tests whether an element type is trivially copyable
512 * \param[in] element_type_name the type name of the elements, as
513 * registered to the system using geo_register_attribute_type<T>()
514 * \retval true if elements can be copied with memcpy(), read and write
515 * using fread() , fwrite()
516 * \retval false otherwise
517 * \pre the element type was registered using geo_register_attribute_type.
518 */
519 37 static bool element_by_type_name_is_trivially_copyable(
520 const std::string& element_type_name
521 ) {
522 geo_debug_assert(element_type_name_is_known(element_type_name));
523 return (
524 type_name_to_creator_[
525 element_type_name
526 37 ]->elements_are_trivially_copyable()
527 37 );
528 }
529
530 /**
531 * \brief Tests whether an element type is trivially copyable
532 * \param[in] element_typeid_name the type name of the elements, as
533 * given by typeid(T).name()
534 * \retval true if elements can be copied with memcpy(), read and write
535 * using fread() , fwrite()
536 * \retval false otherwise
537 * \pre the element type was registerd using geo_register_attribute_type.
538 */
539 37 static bool element_by_typeid_name_is_trivially_copyable(
540 const std::string& element_typeid_name
541 ) {
542 geo_debug_assert(element_typeid_name_is_known(element_typeid_name));
543 std::string element_type_name =
544 37 typeid_name_to_type_name_[element_typeid_name];
545
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
74 return element_by_type_name_is_trivially_copyable(element_type_name);
546 }
547
548 /**
549 * \brief Creates an attribute store of a given type
550 * \param[in] element_type_name a const reference to a string with
551 * the C++ type of the elements to be stored in the attribute
552 * \param[in] dimension number of elements in each item
553 */
554
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 static AttributeStore* create_attribute_store_by_element_type_name(
555 const std::string& element_type_name,
556 index_t dimension
557 ) {
558
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
2 geo_assert(element_type_name_is_known(element_type_name));
559 2 return type_name_to_creator_[element_type_name]->
560 2 create_attribute_store(dimension);
561 }
562
563 /**
564 * \brief Gets an element type name from its mangled name
565 * \param[in] element_typeid_name a const reference to a
566 * string with the mangled type name, as given by typeid(T).name()
567 * \return a string with the C++ type name
568 * \pre element_typeid_name_is_known(element_typeid_name)
569 */
570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 static std::string element_type_name_by_element_typeid_name(
571 const std::string& element_typeid_name
572 ) {
573
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
37 geo_assert(element_typeid_name_is_known(element_typeid_name));
574 74 return typeid_name_to_type_name_[element_typeid_name];
575 }
576
577 /**
578 * \brief Gets an element mangled type name from its C++ name.
579 * \param[in] element_type_name a reference to a string with
580 * the C++ type name
581 * \return a string with the mangled type name, as given by
582 * typeid(T).name()
583 * \pre element_type_name_is_known(element_type_name)
584 */
585 static std::string element_typeid_name_by_element_type_name(
586 const std::string& element_type_name
587 ) {
588 geo_assert(element_type_name_is_known(element_type_name));
589 return type_name_to_typeid_name_[element_type_name];
590 }
591
592 /**
593 * \brief Registers a new element type
594 * \note Internal use function, one should use
595 * geo_register_attribute_type instead
596 * \param[in] creator a pointer to the AttributeStoreCreator
597 * \param[in] element_type_name a const reference to a string with the
598 * C++ type name of the elements
599 * \param[in] element_typeid_name a const reference to a string with
600 * the mangled type name of the elements, as given by typeid(T).name()
601 */
602 static void register_attribute_creator(
603 AttributeStoreCreator* creator,
604 const std::string& element_type_name,
605 const std::string& element_typeid_name
606 );
607
608 /**
609 * \brief Gets the LifeCycle.
610 * \details The LifeCycle know how to construct, destroy, copy-construct
611 * or copy objects.
612 * \return a pointer to the LifeCycle or nullptr if datatype is a
613 * POD (Plain Ordinary Datatype).
614 */
615 LifeCycle* lifecycle() const {
616 return lifecycle_;
617 }
618
619 protected:
620
621 /**
622 * \brief implementation of apply_permutation() used when there is a
623 * lifecycle, that is, when attribute type is not trivially copyable.
624 * \see apply_permutation()
625 */
626 void apply_permutation_with_lifecycle(
627 const vector<index_t>& permutation
628 );
629
630 /**
631 * \brief If size or base address differ from the
632 * cached values, notify all the observers,
633 * and update the cached base address and size.
634 * \param[in] base_addr the new base address
635 * \param[in] size the new size
636 * \param[in] dim the new dimension
637 */
638 virtual void notify(
639 Memory::pointer base_addr, index_t size, index_t dim
640 );
641
642 /**
643 * \brief Registers an observer.
644 * \details All the registered observers are notified whenever
645 * the size or base pointer in this AttributeStore change.
646 * The function is thread-safe.
647 * \param[in] observer the AttributeStoreObserver to be
648 * registered.
649 */
650 void register_observer(AttributeStoreObserver* observer);
651
652 /**
653 * \brief Unregisters an observer.
654 * \param[in] observer the AttributeStoreObserver to be
655 * unregistered.
656 * The function is thread-safe.
657 * \pre \p observer is registered.
658 */
659 void unregister_observer(AttributeStoreObserver* observer);
660
661
662 protected:
663 size_t element_size_;
664 index_t dimension_;
665 Memory::pointer cached_base_addr_;
666 index_t cached_size_;
667 index_t cached_capacity_;
668 LifeCycle_var lifecycle_;
669 std::set<AttributeStoreObserver*> observers_;
670 Process::spinlock lock_;
671
672 static std::map<std::string, AttributeStoreCreator_var>
673 type_name_to_creator_;
674
675 static std::map<std::string, std::string>
676 typeid_name_to_type_name_;
677
678 static std::map<std::string, std::string>
679 type_name_to_typeid_name_;
680
681 friend class AttributeStoreObserver;
682 };
683
684 /*********************************************************************/
685
686 /**
687 * \brief Stores an array of elements of a given type,
688 * and notifies a set of AttributeStoreObservers each time the
689 * storead array changes size and/or base address.
690 * \tparam ST storage type for the elements
691 */
692 template <class ST> class TypedAttributeStore : public AttributeStore {
693 public:
694
695 /**
696 * \brief Creates a new empty attribute store.
697 * \param[in] dim number of elements in each item,
698 * default value is 1, can be greater for vector
699 * attributes.
700 * \param[in] user_type_info optional user type (default is typeid(ST)
701 * \details \p user_type_info is used for instance by Attribute<bool>,
702 * with bool as user type and Numeric::uint8 as storage type
703 */
704 2060 TypedAttributeStore(
705 index_t dim=1, const std::type_info& user_type_info = typeid(ST)
706 ) :
707 AttributeStore(sizeof(ST),dim),
708 1997 storage_type_(typeid(ST)),
709
7/33
✓ Branch 2 taken 523 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 288 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 932 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 14 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✓ Branch 34 taken 2 times.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
2060 user_type_(user_type_info) {
710 if(!std::is_trivially_copyable<ST>::value) {
711
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lifecycle_ = new GenericLifeCycle<ST>();
712 }
713 1 }
714
715 4062053 void resize(index_t new_size) override {
716 4062053 store_.resize(new_size*dimension_);
717
2/2
✓ Branch 0 taken 2029952 times.
✓ Branch 1 taken 1078 times.
8121950 notify(
718 store_.empty() ? nullptr : Memory::pointer(store_.data()),
719 new_size,
720 dimension_
721 );
722 4062053 }
723
724 11087 void reserve(index_t new_capacity) override {
725
2/2
✓ Branch 0 taken 4493 times.
✓ Branch 1 taken 1054 times.
11087 if(new_capacity > capacity()) {
726 8979 store_.reserve(new_capacity*dimension_);
727 8979 cached_capacity_ = new_capacity;
728
2/2
✓ Branch 0 taken 2907 times.
✓ Branch 1 taken 1586 times.
14787 notify(
729 store_.empty() ? nullptr : Memory::pointer(store_.data()),
730 size(),
731 dimension_
732 );
733 }
734 11087 }
735
736 1070 void clear(bool keep_memory=false) override {
737
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 535 times.
1070 if(keep_memory) {
738 store_.resize(0);
739 } else {
740 store_.clear();
741 }
742 1070 notify(nullptr, 0, dimension_);
743 1070 }
744
745 1400 void redim(index_t dim) override {
746
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 411 times.
1400 if(dim == dimension()) {
747 578 return;
748 }
749 822 vector<ST> new_store(size()*dim);
750
1/2
✓ Branch 1 taken 411 times.
✗ Branch 2 not taken.
822 new_store.reserve(capacity()*dim);
751 index_t copy_dim = std::min(dim, dimension());
752
2/2
✓ Branch 0 taken 231278 times.
✓ Branch 1 taken 411 times.
463378 for(index_t i = 0; i < size(); ++i) {
753
2/2
✓ Branch 0 taken 466328 times.
✓ Branch 1 taken 231278 times.
1395212 for(index_t c = 0; c < copy_dim; ++c) {
754
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
932656 new_store[dim * i + c] = store_[dimension_ * i + c];
755 }
756 }
757 store_.swap(new_store);
758
3/4
✓ Branch 0 taken 182 times.
✓ Branch 1 taken 229 times.
✓ Branch 3 taken 411 times.
✗ Branch 4 not taken.
1186 notify(
759 store_.empty() ? nullptr : Memory::pointer(store_.data()),
760 size(),
761 dim
762 );
763 }
764
765 3898 bool elements_type_matches(const std::string& type_name) const override {
766 return (
767
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1949 times.
✓ Branch 2 taken 855 times.
✓ Branch 3 taken 1094 times.
3898 type_name == storage_type_.name() ||
768
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 855 times.
1710 type_name == user_type_.name()
769 3898 );
770 }
771
772 148 std::string element_typeid_name() const override {
773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 74 times.
148 return storage_type_.name();
774 }
775
776 74 std::string user_element_typeid_name() const override {
777
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
74 return user_type_.name();
778 }
779
780 590 AttributeStore* clone() const override {
781 TypedAttributeStore<ST>* result =
782
1/2
✓ Branch 2 taken 295 times.
✗ Branch 3 not taken.
590 new TypedAttributeStore<ST>(dimension(), user_type_);
783 590 result->resize(size());
784 result->store_ = store_;
785 590 result->lifecycle_ = lifecycle_;
786 590 return result;
787 }
788
789 vector<ST>& get_vector() {
790 return store_;
791 }
792
793 10240 void scale_item(index_t to, double s) override {
794
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 5120 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
10240 geo_assert(to < size());
795
2/2
✓ Branch 0 taken 15360 times.
✓ Branch 1 taken 5120 times.
40960 for(index_t i=0; i<dimension_; ++i) {
796 30720 scale_value(store_[to*dimension_+i], s);
797 }
798 10240 }
799
800 1023600 void madd_item(index_t to, double s, index_t from) override {
801
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 593700 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
1023600 geo_assert(from < size());
802
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 593700 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
1023600 geo_assert(to < size());
803
2/2
✓ Branch 0 taken 1289700 times.
✓ Branch 1 taken 429900 times.
3439200 for(index_t i=0; i<dimension_; ++i) {
804 2579400 madd_value(
805 2579400 store_[to*dimension_+i], s, store_[from*dimension_+i]
806 );
807 }
808 1023600 }
809
810 protected:
811 4072938 void notify(
812 Memory::pointer base_addr, index_t size, index_t dim
813 ) override {
814 4072938 AttributeStore::notify(base_addr, size, dim);
815
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 2036469 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2036469 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
4072938 geo_assert(size*dim <= store_.size());
816 4072938 }
817
818 template<class TT> static void scale_value(TT& to, double s) {
819 geo_argused(to);
820 geo_argused(s);
821 }
822
823 static void scale_value(uint8_t& to, double s) {
824 to = uint8_t(double(to)*s != 0.0);
825 }
826
827 static void scale_value(int32_t& to, double s) {
828 to = int32_t(double(to)*s);
829 }
830
831 static void scale_value(uint32_t& to, double s) {
832 to = uint32_t(double(to)*s);
833 }
834
835 static void scale_value(float& to, double s) {
836 to = float(double(to)*s);
837 }
838
839 static void scale_value(double& to, double s) {
840 15360 to *= s;
841 }
842
843 template<class TT> static void madd_value(TT& to, double s, TT& from) {
844 geo_argused(to);
845 geo_argused(s);
846 geo_argused(from);
847 }
848
849 static void madd_value(uint8_t& to, double s, uint8_t& from) {
850 to = uint8_t(double(to) + s*double(from) != 0.0);
851 }
852
853 static void madd_value(int32_t& to, double s, int32_t& from) {
854 to = int32_t(double(to) + s*double(from));
855 }
856
857 static void madd_value(uint32_t& to, double s, uint32_t& from) {
858 to = uint32_t(double(to) + s*double(from));
859 }
860
861 static void madd_value(float& to, double s, float& from) {
862 to = float(double(to) + s*double(from));
863 }
864
865 static void madd_value(double& to, double s, double& from) {
866 1289700 to += s*from;
867 }
868
869 private:
870 vector<ST> store_;
871 const std::type_info& storage_type_;
872 const std::type_info& user_type_;
873 };
874
875 /*********************************************************************/
876
877 /**
878 * \brief Implementation of AttributeStoreCreator for a specific type.
879 * \tparam UT type of the elements (user)
880 * \tparam ST type of the elements (storage), default is UT
881 */
882 template <class UT, class ST=UT>
883 2741 class TypedAttributeStoreCreator : public AttributeStoreCreator {
884 public:
885 /**
886 * \copydoc AttributeStoreCreator::create_attribute_store()
887 */
888 4 AttributeStore* create_attribute_store(index_t dim) override{
889
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 return new TypedAttributeStore<ST>(dim,typeid(UT));
890 }
891
892 /**
893 * \copydoc AttributeStoreCreator::elements_are_trivially_copyable()
894 */
895 74 bool elements_are_trivially_copyable() const override {
896 74 return(std::is_trivially_copyable<ST>::value);
897 }
898 };
899
900 /*********************************************************************/
901
902 /**
903 * \brief Helper class to register new attribute types
904 * \tparam UT attribute element type (user)
905 * \tparam ST attribute element type (storage), default is UT
906 * It can be different: for instance, for bool we use
907 * Numeric::uint8 (to avoid the std::vector<bool> insanity !!).
908 */
909 template <class UT, class ST=UT> class geo_register_attribute_type {
910 public:
911 /**
912 * \brief geo_register_attribute_type constructor
913 * \param[in] type_name a const reference to a string with
914 * the C++ type name.
915 * \details If the attribute is already registered with the same
916 * \p type_name and same \p T, then a warning message is issued.
917 * If the attribute is already registered with the same \p type_name
918 * but a different \p T, then an assertion failure is triggered.
919 */
920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2241 times.
5480 geo_register_attribute_type(const std::string& type_name) {
921
1/2
✓ Branch 1 taken 2741 times.
✗ Branch 2 not taken.
5480 AttributeStore::register_attribute_creator(
922
1/2
✓ Branch 1 taken 2741 times.
✗ Branch 2 not taken.
5480 new TypedAttributeStoreCreator<UT,ST>,
923 5480 type_name, typeid(UT).name()
924 );
925
2/2
✓ Branch 0 taken 249 times.
✓ Branch 1 taken 2492 times.
5480 if(type_name == "bool") {
926 498 GeoFile::register_ascii_attribute_serializer(
927 type_name,
928 read_ascii_attribute<bool>,
929 write_ascii_attribute<bool>
930 );
931 } else {
932 4982 GeoFile::register_ascii_attribute_serializer(
933 type_name,
934 read_ascii_attribute<UT>,
935 write_ascii_attribute<UT>
936 );
937 }
938 5480 }
939 };
940
941 /*********************************************************************/
942
943 /**
944 * \brief Manages a set of attributes attached to
945 * an object.
946 */
947 class GEOGRAM_API AttributesManager {
948 public:
949 /**
950 * \brief Constructs a new empty AttributesManager.
951 */
952 AttributesManager();
953
954
955 /**
956 * \brief AttributesManager destructor.
957 */
958 ~AttributesManager();
959
960 /**
961 * \brief Gets the number of attributes.
962 * \return The number of attributes managed by this
963 * AttributesManager.
964 */
965 index_t nb() const {
966 return index_t(attributes_.size());
967 }
968
969 /**
970 * \brief Gets the names of all the attributes in this
971 * AttributeStore.
972 * \param[out] names a vector of all attribute names
973 */
974 void list_attribute_names(vector<std::string>& names) const;
975
976 /**
977 * \brief Gets the size.
978 * \details All attributes stored in an AttributesManager have
979 * the same number of items.
980 * \return the number of items of each attribute.
981 */
982 index_t size() const {
983
2/3
✓ Branch 0 taken 1108 times.
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
1602 return size_;
984 }
985
986 /**
987 * \brief Gets the capacity.
988 * \return the number of items that can be stored without doing
989 * a reallocation.
990 */
991 index_t capacity() const {
992
2/2
✓ Branch 0 taken 6909 times.
✓ Branch 1 taken 6129829 times.
6137797 return capacity_;
993 }
994
995 /**
996 * \brief Resizes all the attributes managed by this
997 * AttributesManager.
998 * \param[in] new_size the new number of items for
999 * all attributes.
1000 */
1001 void resize(index_t new_size);
1002
1003 /**
1004 * \brief Pre-allocates memory for a number of items.
1005 * \details Has effect only if new_capacity is larger
1006 * than current capacity.
1007 * \param[in] new_capacity the number of items.
1008 */
1009 void reserve(index_t new_capacity);
1010
1011 /**
1012 * \brief Clears this AttributesManager
1013 * \param[in] keep_attributes if true, then all
1014 * attributes are resized to 0 but their names are
1015 * kept.
1016 * \param[in] keep_memory if true, allocated memory
1017 * is kept reserved.
1018 */
1019 void clear(bool keep_attributes, bool keep_memory = false);
1020
1021
1022 /**
1023 * \brief Zeroes all the attributes.
1024 */
1025 void zero();
1026
1027 /**
1028 * \brief Binds an AttributeStore with the specified name.
1029 * Ownership of this AttributeStore is transferred to
1030 * the AttributesManager.
1031 * \param[in] name the name
1032 * \param[in] as a pointer to the AttributeStore to be bound
1033 * \pre No AttributeStore is already bound to the same name
1034 */
1035 void bind_attribute_store(const std::string& name, AttributeStore* as);
1036
1037 /**
1038 * \brief Finds an AttributeStore by name.
1039 * \param[in] name the name under which the AttributeStore was bound
1040 * \return a pointer to the attribute store or nullptr
1041 * if is is undefined.
1042 */
1043 AttributeStore* find_attribute_store(const std::string& name);
1044
1045 /**
1046 * \brief Reads a double-typed attribute into a vector.
1047 * \param[out] out receives size() * dim values.
1048 * \param[out] dim the dimension of the attribute.
1049 * \retval false if no attribute \p name exists or it is not double-typed.
1050 */
1051 bool get_doubles(
1052 const std::string& name, vector<double>& out, index_t& dim
1053 ) const;
1054
1055 /**
1056 * \brief Writes a double-typed attribute, creating it if needed.
1057 * \retval false on type or size mismatch
1058 * (in.size() must be size() * dim).
1059 */
1060 bool set_doubles(
1061 const std::string& name, const vector<double>& in, index_t dim
1062 );
1063
1064 /**
1065 * \brief Finds an AttributeStore by name.
1066 * \param[in] name the name under which the AttributeStore was bound
1067 * \return a const pointer to the attribute store or nullptr if is is
1068 * undefined.
1069 */
1070 const AttributeStore* find_attribute_store(
1071 const std::string& name
1072 ) const;
1073
1074
1075 /**
1076 * \brief Tests whether an attribute is defined.
1077 * \param[in] name name of the attribute
1078 * \retval true if an attribute with the specified name exists
1079 * \retval false otherwise
1080 */
1081 bool is_defined(const std::string& name) const {
1082
4/14
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 39 times.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
46 return (find_attribute_store(name) != nullptr);
1083 }
1084
1085 /**
1086 * \brief Deletes an AttributeStore by name.
1087 * \param[in] name the name of the attribute store
1088 * to be deleted.
1089 */
1090 void delete_attribute_store(const std::string& name);
1091
1092 /**
1093 * \brief Deletes an AttributeStore.
1094 * \param[in] as a pointer to the attribute store
1095 * to be deleted.
1096 */
1097 void delete_attribute_store(AttributeStore* as);
1098
1099 /**
1100 * \brief Applies a permutation to the stored attributes.
1101 * \details Applying a permutation to the data is equivalent
1102 * to:
1103 * \code
1104 * for(i=0; i<permutation.size(); i++) {
1105 * data2[i] = data[permutation[i]]
1106 * }
1107 * data = data2 ;
1108 * \endcode
1109 * But it is done in-place.
1110 * \param[in] permutation the permutation.
1111 * It is temporarily changed during execution of the
1112 * function, but identical to the input on exit.
1113 */
1114 void apply_permutation(
1115 const vector<index_t>& permutation
1116 );
1117
1118 /**
1119 * \brief Compresses the stored attributes, by
1120 * applying an index mapping that fills-in the gaps.
1121 * \details This is equivalent to:
1122 * \code
1123 * for(i=0; i<size(); i++) {
1124 * if(old2new[i] != index_t(-1)) {
1125 * data2[old2new[i]] = data[i];
1126 * }
1127 * }
1128 * data = data2 ;
1129 * \endcode
1130 * \param[in] old2new the index mapping to be applied.
1131 * \pre old2new[i] <= i || old2new[i] == index_t(-1)
1132 */
1133 void compress(const vector<index_t>& old2new);
1134
1135 /**
1136 * \brief Copies all the attributes from another AttributesManager.
1137 * \details Previous content of this AttributesManager is erased.
1138 */
1139 void copy(const AttributesManager& rhs);
1140
1141
1142 /**
1143 * \brief Copies all the attributes of an item into another one.
1144 * \param[in] to index of the destination item
1145 * \param[in] from index of the source item
1146 * \note This function is not efficient.
1147 */
1148 void copy_item(index_t to, index_t from);
1149
1150 /**
1151 * \brief Swaps all the attributes of two items
1152 * \param[in] i , j the indices of the two items to be swapped
1153 * \note This function is not efficient.
1154 */
1155 void swap_items(index_t i, index_t j);
1156
1157
1158 /**
1159 * \brief Sets an item to zero
1160 * \param[in] to index of the item
1161 */
1162 void zero_item(index_t to);
1163
1164 /**
1165 * \brief Scales an item
1166 * \details item[to] *= s
1167 * \param[in] to the index of the item
1168 * \param[in] s the scaling factor
1169 * \details default implementation does nothing
1170 */
1171 void scale_item(index_t to, double s);
1172
1173 /**
1174 * \brief Adds a scaled item to another item
1175 * \detais item[to] += s * item[from]
1176 * \param[in] to the item
1177 * \param[in] s the scaling factor
1178 * \param[in] from the item to be scaled and added
1179 * \details default implementation does nothing
1180 */
1181 void madd_item(index_t to, double s, index_t from);
1182
1183 /**
1184 * \brief Copies an attribute.
1185 * \param[in] name the attribute to copy
1186 * \param[in] new_name new name of the attribute
1187 * \retval \c false and does nothing if \p old_name
1188 * attribute doesn't exist or if \p new_name attribute already exists.
1189 * \retval \c true if the copy occurs succesfully.
1190 */
1191 bool copy_attribute(
1192 const std::string& name, const std::string& new_name
1193 );
1194
1195 /**
1196 * \brief Renames an attribute.
1197 * \param[in] old_name current name of the attribute
1198 * \param[in] new_name new name of the attribute
1199 * \retval \c false and does nothing if \p old_name
1200 * attribute doesn't exist or if \p new_name attribute already exists.
1201 * \retval \c true if renaming occurs succesfully.
1202 */
1203 bool rename_attribute(
1204 const std::string& old_name, const std::string& new_name
1205 );
1206
1207 private:
1208 /**
1209 * \brief Forbids copy.
1210 * \details This is to make sure that client code does
1211 * not unintentionlly copies an AttributesManager (for
1212 * instance by passing it by-value to a function).
1213 * Use copy() instead.
1214 */
1215 AttributesManager(const AttributesManager& rhs) = delete;
1216
1217 /**
1218 * \brief Forbids copy.
1219 * \details This is to make sure that client code does
1220 * not unintentionlly copies an AttributesManager (for
1221 * instance by passing it by-value to a function).
1222 * Use copy() instead.
1223 */
1224 const AttributesManager& operator=(const AttributesManager& rhs) = delete;
1225
1226 private:
1227 index_t size_;
1228 index_t capacity_;
1229 std::map<std::string, AttributeStore*> attributes_;
1230 } ;
1231
1232
1233 /*********************************************************************/
1234
1235
1236 /**
1237 * \brief Base class for Attributes, that manipulates an
1238 * attribute stored in an AttributesManager.
1239 * \tparam UT user element type
1240 * \tparam ST stored element type (default = UT)
1241 */
1242 template <class UT, class ST = UT>
1243 class AttributeBase : public AttributeStoreObserver {
1244 public:
1245
1246 /**
1247 * \brief Creates an uninitialized (unbound) Attribute.
1248 */
1249 3720 AttributeBase() :
1250 3720 manager_(nullptr),
1251 3720 store_(nullptr),
1252
22/622
✗ Branch 0 not taken.
✓ Branch 1 taken 352 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 19 taken 3 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 5 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 166 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✓ Branch 142 taken 1 times.
✗ Branch 143 not taken.
✓ Branch 145 taken 36 times.
✗ Branch 146 not taken.
✗ Branch 148 not taken.
✗ Branch 149 not taken.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✗ Branch 163 not taken.
✗ Branch 164 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 169 not taken.
✗ Branch 170 not taken.
✓ Branch 172 taken 2 times.
✗ Branch 173 not taken.
✗ Branch 175 not taken.
✗ Branch 176 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 181 not taken.
✗ Branch 182 not taken.
✗ Branch 184 not taken.
✗ Branch 185 not taken.
✗ Branch 187 not taken.
✗ Branch 188 not taken.
✗ Branch 190 not taken.
✗ Branch 191 not taken.
✗ Branch 193 not taken.
✗ Branch 194 not taken.
✗ Branch 196 not taken.
✗ Branch 197 not taken.
✗ Branch 199 not taken.
✗ Branch 200 not taken.
✗ Branch 202 not taken.
✗ Branch 203 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 211 not taken.
✗ Branch 212 not taken.
✗ Branch 214 not taken.
✗ Branch 215 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✗ Branch 220 not taken.
✗ Branch 221 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✗ Branch 232 not taken.
✗ Branch 233 not taken.
✓ Branch 235 taken 160 times.
✗ Branch 236 not taken.
✗ Branch 238 not taken.
✗ Branch 239 not taken.
✗ Branch 241 not taken.
✗ Branch 242 not taken.
✗ Branch 244 not taken.
✗ Branch 245 not taken.
✗ Branch 247 not taken.
✗ Branch 248 not taken.
✗ Branch 250 not taken.
✗ Branch 251 not taken.
✓ Branch 253 taken 320 times.
✗ Branch 254 not taken.
✗ Branch 256 not taken.
✗ Branch 257 not taken.
✗ Branch 259 not taken.
✗ Branch 260 not taken.
✗ Branch 262 not taken.
✗ Branch 263 not taken.
✗ Branch 265 not taken.
✗ Branch 266 not taken.
✗ Branch 268 not taken.
✗ Branch 269 not taken.
✗ Branch 271 not taken.
✗ Branch 272 not taken.
✓ Branch 274 taken 1 times.
✗ Branch 275 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✗ Branch 280 not taken.
✗ Branch 281 not taken.
✗ Branch 283 not taken.
✗ Branch 284 not taken.
✗ Branch 286 not taken.
✗ Branch 287 not taken.
✗ Branch 289 not taken.
✗ Branch 290 not taken.
✗ Branch 292 not taken.
✗ Branch 293 not taken.
✗ Branch 295 not taken.
✗ Branch 296 not taken.
✗ Branch 298 not taken.
✗ Branch 299 not taken.
✗ Branch 301 not taken.
✗ Branch 302 not taken.
✗ Branch 304 not taken.
✗ Branch 305 not taken.
✗ Branch 307 not taken.
✗ Branch 308 not taken.
✗ Branch 310 not taken.
✗ Branch 311 not taken.
✗ Branch 313 not taken.
✗ Branch 314 not taken.
✗ Branch 316 not taken.
✗ Branch 317 not taken.
✗ Branch 319 not taken.
✗ Branch 320 not taken.
✗ Branch 322 not taken.
✗ Branch 323 not taken.
✗ Branch 325 not taken.
✗ Branch 326 not taken.
✗ Branch 328 not taken.
✗ Branch 329 not taken.
✗ Branch 331 not taken.
✗ Branch 332 not taken.
✗ Branch 334 not taken.
✗ Branch 335 not taken.
✗ Branch 337 not taken.
✗ Branch 338 not taken.
✗ Branch 340 not taken.
✗ Branch 341 not taken.
✗ Branch 343 not taken.
✗ Branch 344 not taken.
✗ Branch 346 not taken.
✗ Branch 347 not taken.
✗ Branch 349 not taken.
✗ Branch 350 not taken.
✗ Branch 352 not taken.
✗ Branch 353 not taken.
✗ Branch 355 not taken.
✗ Branch 356 not taken.
✗ Branch 358 not taken.
✗ Branch 359 not taken.
✗ Branch 361 not taken.
✗ Branch 362 not taken.
✗ Branch 364 not taken.
✗ Branch 365 not taken.
✓ Branch 367 taken 160 times.
✗ Branch 368 not taken.
✗ Branch 370 not taken.
✗ Branch 371 not taken.
✗ Branch 373 not taken.
✗ Branch 374 not taken.
✗ Branch 376 not taken.
✗ Branch 377 not taken.
✗ Branch 379 not taken.
✗ Branch 380 not taken.
✗ Branch 382 not taken.
✗ Branch 383 not taken.
✗ Branch 385 not taken.
✗ Branch 386 not taken.
✗ Branch 388 not taken.
✗ Branch 389 not taken.
✗ Branch 391 not taken.
✗ Branch 392 not taken.
✗ Branch 394 not taken.
✗ Branch 395 not taken.
✗ Branch 397 not taken.
✗ Branch 398 not taken.
✗ Branch 400 not taken.
✗ Branch 401 not taken.
✗ Branch 403 not taken.
✗ Branch 404 not taken.
✓ Branch 406 taken 1 times.
✗ Branch 407 not taken.
✗ Branch 409 not taken.
✗ Branch 410 not taken.
✗ Branch 412 not taken.
✗ Branch 413 not taken.
✗ Branch 415 not taken.
✗ Branch 416 not taken.
✗ Branch 418 not taken.
✗ Branch 419 not taken.
✗ Branch 421 not taken.
✗ Branch 422 not taken.
✗ Branch 424 not taken.
✗ Branch 425 not taken.
✗ Branch 427 not taken.
✗ Branch 428 not taken.
✗ Branch 430 not taken.
✗ Branch 431 not taken.
✗ Branch 433 not taken.
✗ Branch 434 not taken.
✓ Branch 436 taken 4 times.
✗ Branch 437 not taken.
✗ Branch 439 not taken.
✗ Branch 440 not taken.
✗ Branch 442 not taken.
✗ Branch 443 not taken.
✗ Branch 445 not taken.
✗ Branch 446 not taken.
✗ Branch 448 not taken.
✗ Branch 449 not taken.
✗ Branch 451 not taken.
✗ Branch 452 not taken.
✗ Branch 454 not taken.
✗ Branch 455 not taken.
✗ Branch 457 not taken.
✗ Branch 458 not taken.
✗ Branch 460 not taken.
✗ Branch 461 not taken.
✗ Branch 463 not taken.
✗ Branch 464 not taken.
✗ Branch 466 not taken.
✗ Branch 467 not taken.
✗ Branch 469 not taken.
✗ Branch 470 not taken.
✗ Branch 472 not taken.
✗ Branch 473 not taken.
✗ Branch 475 not taken.
✗ Branch 476 not taken.
✗ Branch 478 not taken.
✗ Branch 479 not taken.
✗ Branch 481 not taken.
✗ Branch 482 not taken.
✗ Branch 484 not taken.
✗ Branch 485 not taken.
✗ Branch 487 not taken.
✗ Branch 488 not taken.
✗ Branch 490 not taken.
✗ Branch 491 not taken.
✗ Branch 493 not taken.
✗ Branch 494 not taken.
✗ Branch 496 not taken.
✗ Branch 497 not taken.
✓ Branch 499 taken 160 times.
✗ Branch 500 not taken.
✗ Branch 502 not taken.
✗ Branch 503 not taken.
✗ Branch 505 not taken.
✗ Branch 506 not taken.
✗ Branch 508 not taken.
✗ Branch 509 not taken.
✗ Branch 511 not taken.
✗ Branch 512 not taken.
✗ Branch 514 not taken.
✗ Branch 515 not taken.
✓ Branch 517 taken 640 times.
✗ Branch 518 not taken.
✗ Branch 520 not taken.
✗ Branch 521 not taken.
✗ Branch 523 not taken.
✗ Branch 524 not taken.
✗ Branch 526 not taken.
✗ Branch 527 not taken.
✗ Branch 529 not taken.
✗ Branch 530 not taken.
✗ Branch 532 not taken.
✗ Branch 533 not taken.
✗ Branch 535 not taken.
✗ Branch 536 not taken.
✓ Branch 538 taken 1 times.
✗ Branch 539 not taken.
✗ Branch 541 not taken.
✗ Branch 542 not taken.
✗ Branch 544 not taken.
✗ Branch 545 not taken.
✗ Branch 547 not taken.
✗ Branch 548 not taken.
✗ Branch 550 not taken.
✗ Branch 551 not taken.
✗ Branch 553 not taken.
✗ Branch 554 not taken.
✗ Branch 556 not taken.
✗ Branch 557 not taken.
✗ Branch 559 not taken.
✗ Branch 560 not taken.
✗ Branch 562 not taken.
✗ Branch 563 not taken.
✗ Branch 565 not taken.
✗ Branch 566 not taken.
✗ Branch 568 not taken.
✗ Branch 569 not taken.
✗ Branch 571 not taken.
✗ Branch 572 not taken.
✗ Branch 574 not taken.
✗ Branch 575 not taken.
✗ Branch 577 not taken.
✗ Branch 578 not taken.
✗ Branch 580 not taken.
✗ Branch 581 not taken.
✗ Branch 583 not taken.
✗ Branch 584 not taken.
✗ Branch 586 not taken.
✗ Branch 587 not taken.
✗ Branch 589 not taken.
✗ Branch 590 not taken.
✗ Branch 592 not taken.
✗ Branch 593 not taken.
✗ Branch 595 not taken.
✗ Branch 596 not taken.
✗ Branch 598 not taken.
✗ Branch 599 not taken.
✗ Branch 601 not taken.
✗ Branch 602 not taken.
✗ Branch 604 not taken.
✗ Branch 605 not taken.
✗ Branch 607 not taken.
✗ Branch 608 not taken.
✗ Branch 610 not taken.
✗ Branch 611 not taken.
✗ Branch 613 not taken.
✗ Branch 614 not taken.
✗ Branch 616 not taken.
✗ Branch 617 not taken.
✗ Branch 619 not taken.
✗ Branch 620 not taken.
✗ Branch 622 not taken.
✗ Branch 623 not taken.
✗ Branch 625 not taken.
✗ Branch 626 not taken.
✗ Branch 628 not taken.
✗ Branch 629 not taken.
✓ Branch 631 taken 160 times.
✗ Branch 632 not taken.
✗ Branch 634 not taken.
✗ Branch 635 not taken.
✗ Branch 637 not taken.
✗ Branch 638 not taken.
✗ Branch 640 not taken.
✗ Branch 641 not taken.
✗ Branch 643 not taken.
✗ Branch 644 not taken.
✗ Branch 646 not taken.
✗ Branch 647 not taken.
✗ Branch 649 not taken.
✗ Branch 650 not taken.
✗ Branch 652 not taken.
✗ Branch 653 not taken.
✗ Branch 655 not taken.
✗ Branch 656 not taken.
✗ Branch 658 not taken.
✗ Branch 659 not taken.
✗ Branch 661 not taken.
✗ Branch 662 not taken.
✗ Branch 664 not taken.
✗ Branch 665 not taken.
✗ Branch 667 not taken.
✗ Branch 668 not taken.
✗ Branch 670 not taken.
✗ Branch 671 not taken.
✗ Branch 673 not taken.
✗ Branch 674 not taken.
✗ Branch 676 not taken.
✗ Branch 677 not taken.
✗ Branch 679 not taken.
✗ Branch 680 not taken.
✗ Branch 682 not taken.
✗ Branch 683 not taken.
✗ Branch 685 not taken.
✗ Branch 686 not taken.
✗ Branch 688 not taken.
✗ Branch 689 not taken.
✗ Branch 691 not taken.
✗ Branch 692 not taken.
✗ Branch 694 not taken.
✗ Branch 695 not taken.
✗ Branch 697 not taken.
✗ Branch 698 not taken.
✗ Branch 700 not taken.
✗ Branch 701 not taken.
✗ Branch 703 not taken.
✗ Branch 704 not taken.
✗ Branch 706 not taken.
✗ Branch 707 not taken.
✗ Branch 709 not taken.
✗ Branch 710 not taken.
✗ Branch 712 not taken.
✗ Branch 713 not taken.
✗ Branch 715 not taken.
✗ Branch 716 not taken.
✗ Branch 718 not taken.
✗ Branch 719 not taken.
✗ Branch 721 not taken.
✗ Branch 722 not taken.
✗ Branch 724 not taken.
✗ Branch 725 not taken.
✗ Branch 727 not taken.
✗ Branch 728 not taken.
✗ Branch 730 not taken.
✗ Branch 731 not taken.
✗ Branch 733 not taken.
✗ Branch 734 not taken.
✗ Branch 736 not taken.
✗ Branch 737 not taken.
✗ Branch 739 not taken.
✗ Branch 740 not taken.
✗ Branch 742 not taken.
✗ Branch 743 not taken.
✗ Branch 745 not taken.
✗ Branch 746 not taken.
✗ Branch 748 not taken.
✗ Branch 749 not taken.
✗ Branch 751 not taken.
✗ Branch 752 not taken.
✗ Branch 754 not taken.
✗ Branch 755 not taken.
✗ Branch 757 not taken.
✗ Branch 758 not taken.
✗ Branch 760 not taken.
✗ Branch 761 not taken.
✗ Branch 763 not taken.
✗ Branch 764 not taken.
✗ Branch 766 not taken.
✗ Branch 767 not taken.
✗ Branch 769 not taken.
✗ Branch 770 not taken.
✗ Branch 772 not taken.
✗ Branch 773 not taken.
✗ Branch 775 not taken.
✗ Branch 776 not taken.
✗ Branch 778 not taken.
✗ Branch 779 not taken.
✗ Branch 781 not taken.
✗ Branch 782 not taken.
✗ Branch 784 not taken.
✗ Branch 785 not taken.
✗ Branch 787 not taken.
✗ Branch 788 not taken.
✗ Branch 790 not taken.
✗ Branch 791 not taken.
✗ Branch 793 not taken.
✗ Branch 794 not taken.
✗ Branch 796 not taken.
✗ Branch 797 not taken.
✗ Branch 799 not taken.
✗ Branch 800 not taken.
✗ Branch 802 not taken.
✗ Branch 803 not taken.
✗ Branch 805 not taken.
✗ Branch 806 not taken.
✗ Branch 808 not taken.
✗ Branch 809 not taken.
✗ Branch 811 not taken.
✗ Branch 812 not taken.
✗ Branch 814 not taken.
✗ Branch 815 not taken.
✗ Branch 817 not taken.
✗ Branch 818 not taken.
✗ Branch 820 not taken.
✗ Branch 821 not taken.
✗ Branch 823 not taken.
✗ Branch 824 not taken.
✗ Branch 826 not taken.
✗ Branch 827 not taken.
✗ Branch 829 not taken.
✗ Branch 830 not taken.
✗ Branch 832 not taken.
✗ Branch 833 not taken.
✗ Branch 835 not taken.
✗ Branch 836 not taken.
✗ Branch 838 not taken.
✗ Branch 839 not taken.
✗ Branch 841 not taken.
✗ Branch 842 not taken.
✗ Branch 844 not taken.
✗ Branch 845 not taken.
✗ Branch 847 not taken.
✗ Branch 848 not taken.
✗ Branch 850 not taken.
✗ Branch 851 not taken.
✗ Branch 853 not taken.
✗ Branch 854 not taken.
✗ Branch 856 not taken.
✗ Branch 857 not taken.
✗ Branch 859 not taken.
✗ Branch 860 not taken.
✗ Branch 862 not taken.
✗ Branch 863 not taken.
✗ Branch 865 not taken.
✗ Branch 866 not taken.
✗ Branch 868 not taken.
✗ Branch 869 not taken.
✗ Branch 871 not taken.
✗ Branch 872 not taken.
✗ Branch 874 not taken.
✗ Branch 875 not taken.
✗ Branch 877 not taken.
✗ Branch 878 not taken.
✗ Branch 880 not taken.
✗ Branch 881 not taken.
✗ Branch 883 not taken.
✗ Branch 884 not taken.
✗ Branch 886 not taken.
✗ Branch 887 not taken.
✗ Branch 889 not taken.
✗ Branch 890 not taken.
✗ Branch 892 not taken.
✗ Branch 893 not taken.
✗ Branch 895 not taken.
✗ Branch 896 not taken.
✗ Branch 898 not taken.
✗ Branch 899 not taken.
✗ Branch 901 not taken.
✗ Branch 902 not taken.
✗ Branch 904 not taken.
✗ Branch 905 not taken.
✗ Branch 907 not taken.
✗ Branch 908 not taken.
✗ Branch 910 not taken.
✗ Branch 911 not taken.
✗ Branch 913 not taken.
✗ Branch 914 not taken.
✗ Branch 916 not taken.
✗ Branch 917 not taken.
✗ Branch 919 not taken.
✗ Branch 920 not taken.
✗ Branch 922 not taken.
✗ Branch 923 not taken.
✓ Branch 925 taken 86 times.
✗ Branch 926 not taken.
✓ Branch 928 taken 36 times.
✗ Branch 929 not taken.
3396 existed_already_(false) {
1253 }
1254
1255 /**
1256 * \brief Creates or retrieves a persistent attribute attached to
1257 * a given AttributesManager.
1258 * \details If the attribute already exists with the specified
1259 * name in the AttributesManager then it is retrieved, else
1260 * it is created and bound to the name.
1261 * \param[in] manager a reference to the AttributesManager
1262 * \param[in] name name of the attribute
1263 */
1264 1922 AttributeBase(AttributesManager& manager, const std::string& name) :
1265 1922 manager_(nullptr),
1266 1922 store_(nullptr),
1267 1922 existed_already_(false) {
1268
13/40
✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 108 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 116 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 57 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✓ Branch 25 taken 11 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 11 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 30 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 30 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 30 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 30 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 5 times.
✗ Branch 44 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✓ Branch 52 taken 57 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 27 times.
✗ Branch 56 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
722 bind(manager, name);
1269 }
1270
1271 /**
1272 * \brief Tests whether an Attribute is bound.
1273 * \retval true if this Attribute is bound
1274 * \retval false otherwise
1275 */
1276 bool is_bound() const {
1277
191/2688
✓ Branch 0 taken 656 times.
✓ Branch 1 taken 580637 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 940847 times.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 136 times.
✓ Branch 8 taken 60 times.
✓ Branch 9 taken 32015 times.
✓ Branch 10 taken 60 times.
✓ Branch 11 taken 6695 times.
✓ Branch 12 taken 6 times.
✓ Branch 13 taken 18 times.
✓ Branch 14 taken 81 times.
✓ Branch 15 taken 23 times.
✓ Branch 16 taken 139 times.
✓ Branch 17 taken 313 times.
✓ Branch 18 taken 60 times.
✓ Branch 19 taken 36 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 672 times.
✓ Branch 22 taken 15 times.
✓ Branch 23 taken 124 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 5 times.
✓ Branch 26 taken 132 times.
✓ Branch 27 taken 709 times.
✓ Branch 28 taken 30013 times.
✓ Branch 29 taken 2744 times.
✓ Branch 30 taken 29907 times.
✓ Branch 31 taken 810118 times.
✓ Branch 32 taken 219 times.
✓ Branch 33 taken 110 times.
✓ Branch 34 taken 255 times.
✓ Branch 35 taken 64660 times.
✓ Branch 36 taken 62 times.
✓ Branch 37 taken 9 times.
✓ Branch 38 taken 26 times.
✓ Branch 39 taken 53702 times.
✓ Branch 40 taken 26 times.
✓ Branch 41 taken 137 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 100 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 137 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 88 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 5 times.
✗ Branch 50 not taken.
✓ Branch 51 taken 181139 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 5 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 241877 times.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✓ Branch 58 taken 117880 times.
✓ Branch 59 taken 310755 times.
✓ Branch 60 taken 117880 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 1314 times.
✓ Branch 63 taken 15 times.
✓ Branch 64 taken 455244 times.
✗ Branch 65 not taken.
✓ Branch 66 taken 453959 times.
✓ Branch 67 taken 431 times.
✓ Branch 68 taken 29 times.
✓ Branch 69 taken 5 times.
✓ Branch 70 taken 59 times.
✓ Branch 71 taken 372 times.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✓ Branch 84 taken 11 times.
✗ Branch 85 not taken.
✓ Branch 86 taken 11 times.
✗ Branch 87 not taken.
✓ Branch 88 taken 11 times.
✗ Branch 89 not taken.
✓ Branch 90 taken 3 times.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✓ Branch 93 taken 3 times.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✓ Branch 98 taken 824 times.
✓ Branch 99 taken 2 times.
✓ Branch 100 taken 824 times.
✗ Branch 101 not taken.
✓ Branch 102 taken 30 times.
✓ Branch 103 taken 821 times.
✓ Branch 104 taken 30 times.
✗ Branch 105 not taken.
✓ Branch 106 taken 30 times.
✓ Branch 107 taken 2 times.
✓ Branch 108 taken 30 times.
✓ Branch 109 taken 1 times.
✓ Branch 110 taken 30 times.
✓ Branch 111 taken 62 times.
✗ Branch 112 not taken.
✓ Branch 113 taken 39 times.
✗ Branch 114 not taken.
✓ Branch 115 taken 62 times.
✗ Branch 116 not taken.
✓ Branch 117 taken 258 times.
✓ Branch 118 taken 60 times.
✗ Branch 119 not taken.
✓ Branch 120 taken 60 times.
✓ Branch 121 taken 60 times.
✗ Branch 122 not taken.
✓ Branch 123 taken 60 times.
✗ Branch 124 not taken.
✓ Branch 125 taken 24 times.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✓ Branch 129 taken 24 times.
✓ Branch 130 taken 60 times.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✓ Branch 133 taken 84 times.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✓ Branch 141 taken 10887 times.
✗ Branch 142 not taken.
✓ Branch 143 taken 72 times.
✗ Branch 144 not taken.
✗ Branch 145 not taken.
✓ Branch 146 taken 57 times.
✗ Branch 147 not taken.
✓ Branch 148 taken 57 times.
✗ Branch 149 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✗ Branch 153 not taken.
✓ Branch 154 taken 27 times.
✗ Branch 155 not taken.
✓ Branch 156 taken 27 times.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✗ Branch 159 not taken.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 168 not taken.
✗ Branch 169 not taken.
✓ Branch 170 taken 46 times.
✓ Branch 171 taken 14 times.
✗ Branch 172 not taken.
✓ Branch 173 taken 46 times.
✓ Branch 174 taken 46 times.
✓ Branch 175 taken 14 times.
✗ Branch 176 not taken.
✓ Branch 177 taken 46 times.
✓ Branch 178 taken 60 times.
✗ Branch 179 not taken.
✓ Branch 180 taken 60 times.
✗ Branch 181 not taken.
✗ Branch 182 not taken.
✗ Branch 183 not taken.
✗ Branch 184 not taken.
✗ Branch 185 not taken.
✓ Branch 186 taken 57 times.
✗ Branch 187 not taken.
✓ Branch 188 taken 57 times.
✗ Branch 189 not taken.
✓ Branch 190 taken 60 times.
✗ Branch 191 not taken.
✗ Branch 192 not taken.
✗ Branch 193 not taken.
✓ Branch 194 taken 128 times.
✓ Branch 195 taken 26 times.
✓ Branch 196 taken 128 times.
✗ Branch 197 not taken.
✗ Branch 198 not taken.
✓ Branch 199 taken 18502 times.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✓ Branch 202 taken 64430 times.
✓ Branch 203 taken 64 times.
✓ Branch 204 taken 64430 times.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✓ Branch 207 taken 1 times.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✓ Branch 211 taken 99589 times.
✗ Branch 212 not taken.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✓ Branch 215 taken 12 times.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✓ Branch 219 taken 1 times.
✗ Branch 220 not taken.
✗ Branch 221 not taken.
✗ Branch 222 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 225 not taken.
✗ Branch 226 not taken.
✓ Branch 227 taken 132 times.
✗ Branch 228 not taken.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✗ Branch 231 not taken.
✗ Branch 232 not taken.
✗ Branch 233 not taken.
✗ Branch 234 not taken.
✗ Branch 235 not taken.
✗ Branch 236 not taken.
✗ Branch 237 not taken.
✓ Branch 238 taken 22680 times.
✓ Branch 239 taken 119816 times.
✓ Branch 240 taken 22680 times.
✗ Branch 241 not taken.
✓ Branch 242 taken 45308 times.
✓ Branch 243 taken 235440 times.
✓ Branch 244 taken 45308 times.
✗ Branch 245 not taken.
✗ Branch 246 not taken.
✗ Branch 247 not taken.
✗ Branch 248 not taken.
✗ Branch 249 not taken.
✗ Branch 250 not taken.
✓ Branch 251 taken 1558 times.
✗ Branch 252 not taken.
✗ Branch 253 not taken.
✗ Branch 254 not taken.
✗ Branch 255 not taken.
✗ Branch 256 not taken.
✗ Branch 257 not taken.
✗ Branch 258 not taken.
✗ Branch 259 not taken.
✗ Branch 260 not taken.
✗ Branch 261 not taken.
✗ Branch 262 not taken.
✗ Branch 263 not taken.
✗ Branch 264 not taken.
✗ Branch 265 not taken.
✗ Branch 266 not taken.
✓ Branch 267 taken 13492 times.
✗ Branch 268 not taken.
✗ Branch 269 not taken.
✗ Branch 270 not taken.
✓ Branch 271 taken 53440 times.
✗ Branch 272 not taken.
✗ Branch 273 not taken.
✗ Branch 274 not taken.
✗ Branch 275 not taken.
✗ Branch 276 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✓ Branch 279 taken 122253 times.
✗ Branch 280 not taken.
✗ Branch 281 not taken.
✗ Branch 282 not taken.
✓ Branch 283 taken 40 times.
✗ Branch 284 not taken.
✗ Branch 285 not taken.
✗ Branch 286 not taken.
✗ Branch 287 not taken.
✗ Branch 288 not taken.
✗ Branch 289 not taken.
✗ Branch 290 not taken.
✗ Branch 291 not taken.
✗ Branch 292 not taken.
✗ Branch 293 not taken.
✗ Branch 294 not taken.
✗ Branch 295 not taken.
✗ Branch 296 not taken.
✗ Branch 297 not taken.
✗ Branch 298 not taken.
✗ Branch 299 not taken.
✗ Branch 300 not taken.
✗ Branch 301 not taken.
✓ Branch 302 taken 113 times.
✓ Branch 303 taken 109 times.
✓ Branch 304 taken 113 times.
✗ Branch 305 not taken.
✗ Branch 306 not taken.
✓ Branch 307 taken 222 times.
✗ Branch 308 not taken.
✗ Branch 309 not taken.
✓ Branch 310 taken 1 times.
✓ Branch 311 taken 223 times.
✓ Branch 312 taken 1 times.
✗ Branch 313 not taken.
✗ Branch 314 not taken.
✓ Branch 315 taken 224 times.
✗ Branch 316 not taken.
✗ Branch 317 not taken.
✗ Branch 318 not taken.
✗ Branch 319 not taken.
✓ Branch 320 taken 1 times.
✗ Branch 321 not taken.
✗ Branch 322 not taken.
✓ Branch 323 taken 59 times.
✗ Branch 324 not taken.
✗ Branch 325 not taken.
✓ Branch 326 taken 1 times.
✓ Branch 327 taken 58 times.
✓ Branch 328 taken 1 times.
✗ Branch 329 not taken.
✗ Branch 330 not taken.
✓ Branch 331 taken 58 times.
✗ Branch 332 not taken.
✗ Branch 333 not taken.
✓ Branch 334 taken 60 times.
✓ Branch 335 taken 1183297 times.
✗ Branch 336 not taken.
✓ Branch 337 taken 60 times.
✗ Branch 338 not taken.
✓ Branch 339 taken 1183297 times.
✗ Branch 340 not taken.
✗ Branch 341 not taken.
✓ Branch 342 taken 36 times.
✓ Branch 343 taken 23 times.
✓ Branch 344 taken 36 times.
✗ Branch 345 not taken.
✗ Branch 346 not taken.
✓ Branch 347 taken 166 times.
✗ Branch 348 not taken.
✗ Branch 349 not taken.
✓ Branch 350 taken 179790 times.
✓ Branch 351 taken 113 times.
✓ Branch 352 taken 179790 times.
✗ Branch 353 not taken.
✗ Branch 354 not taken.
✓ Branch 355 taken 113 times.
✗ Branch 356 not taken.
✗ Branch 357 not taken.
✓ Branch 358 taken 1944 times.
✓ Branch 359 taken 11265 times.
✓ Branch 360 taken 1944 times.
✗ Branch 361 not taken.
✗ Branch 362 not taken.
✓ Branch 363 taken 164 times.
✗ Branch 364 not taken.
✗ Branch 365 not taken.
✗ Branch 366 not taken.
✓ Branch 367 taken 2 times.
✗ Branch 368 not taken.
✗ Branch 369 not taken.
✗ Branch 370 not taken.
✓ Branch 371 taken 446504 times.
✗ Branch 372 not taken.
✗ Branch 373 not taken.
✗ Branch 374 not taken.
✓ Branch 375 taken 1339512 times.
✗ Branch 376 not taken.
✓ Branch 377 taken 1 times.
✗ Branch 378 not taken.
✓ Branch 379 taken 55506 times.
✗ Branch 380 not taken.
✗ Branch 381 not taken.
✗ Branch 382 not taken.
✓ Branch 383 taken 475706 times.
✗ Branch 384 not taken.
✓ Branch 385 taken 36 times.
✗ Branch 386 not taken.
✗ Branch 387 not taken.
✗ Branch 388 not taken.
✗ Branch 389 not taken.
✗ Branch 390 not taken.
✗ Branch 391 not taken.
✗ Branch 392 not taken.
✗ Branch 393 not taken.
✗ Branch 394 not taken.
✗ Branch 395 not taken.
✗ Branch 396 not taken.
✗ Branch 397 not taken.
✗ Branch 398 not taken.
✗ Branch 399 not taken.
✗ Branch 400 not taken.
✗ Branch 401 not taken.
✗ Branch 402 not taken.
✗ Branch 403 not taken.
✗ Branch 404 not taken.
✗ Branch 405 not taken.
✗ Branch 406 not taken.
✗ Branch 407 not taken.
✗ Branch 408 not taken.
✗ Branch 409 not taken.
✗ Branch 410 not taken.
✗ Branch 411 not taken.
✗ Branch 412 not taken.
✗ Branch 413 not taken.
✗ Branch 414 not taken.
✗ Branch 415 not taken.
✗ Branch 416 not taken.
✗ Branch 417 not taken.
✗ Branch 418 not taken.
✗ Branch 419 not taken.
✗ Branch 420 not taken.
✗ Branch 421 not taken.
✗ Branch 422 not taken.
✗ Branch 423 not taken.
✗ Branch 424 not taken.
✗ Branch 425 not taken.
✗ Branch 426 not taken.
✗ Branch 427 not taken.
✗ Branch 428 not taken.
✗ Branch 429 not taken.
✗ Branch 430 not taken.
✗ Branch 431 not taken.
✗ Branch 432 not taken.
✗ Branch 433 not taken.
✗ Branch 434 not taken.
✗ Branch 435 not taken.
✗ Branch 436 not taken.
✗ Branch 437 not taken.
✗ Branch 438 not taken.
✗ Branch 439 not taken.
✗ Branch 440 not taken.
✗ Branch 441 not taken.
✗ Branch 442 not taken.
✗ Branch 443 not taken.
✗ Branch 444 not taken.
✗ Branch 445 not taken.
✗ Branch 446 not taken.
✗ Branch 447 not taken.
✗ Branch 448 not taken.
✗ Branch 449 not taken.
✗ Branch 450 not taken.
✗ Branch 451 not taken.
✗ Branch 452 not taken.
✗ Branch 453 not taken.
✗ Branch 454 not taken.
✗ Branch 455 not taken.
✗ Branch 456 not taken.
✓ Branch 457 taken 2 times.
✗ Branch 458 not taken.
✗ Branch 459 not taken.
✗ Branch 460 not taken.
✗ Branch 461 not taken.
✗ Branch 462 not taken.
✗ Branch 463 not taken.
✗ Branch 464 not taken.
✗ Branch 465 not taken.
✗ Branch 466 not taken.
✗ Branch 467 not taken.
✗ Branch 468 not taken.
✗ Branch 469 not taken.
✗ Branch 470 not taken.
✗ Branch 471 not taken.
✗ Branch 472 not taken.
✗ Branch 473 not taken.
✗ Branch 474 not taken.
✗ Branch 475 not taken.
✗ Branch 476 not taken.
✗ Branch 477 not taken.
✗ Branch 478 not taken.
✗ Branch 479 not taken.
✗ Branch 480 not taken.
✗ Branch 481 not taken.
✗ Branch 482 not taken.
✗ Branch 483 not taken.
✗ Branch 484 not taken.
✗ Branch 485 not taken.
✗ Branch 486 not taken.
✗ Branch 487 not taken.
✗ Branch 488 not taken.
✗ Branch 489 not taken.
✗ Branch 490 not taken.
✗ Branch 491 not taken.
✗ Branch 492 not taken.
✗ Branch 493 not taken.
✗ Branch 494 not taken.
✗ Branch 495 not taken.
✗ Branch 496 not taken.
✗ Branch 497 not taken.
✗ Branch 498 not taken.
✗ Branch 499 not taken.
✗ Branch 500 not taken.
✗ Branch 501 not taken.
✗ Branch 502 not taken.
✗ Branch 503 not taken.
✗ Branch 504 not taken.
✗ Branch 505 not taken.
✗ Branch 506 not taken.
✗ Branch 507 not taken.
✗ Branch 508 not taken.
✗ Branch 509 not taken.
✗ Branch 510 not taken.
✗ Branch 511 not taken.
✗ Branch 512 not taken.
✗ Branch 513 not taken.
✗ Branch 514 not taken.
✗ Branch 515 not taken.
✗ Branch 516 not taken.
✗ Branch 517 not taken.
✗ Branch 518 not taken.
✗ Branch 519 not taken.
✗ Branch 520 not taken.
✗ Branch 521 not taken.
✗ Branch 522 not taken.
✗ Branch 523 not taken.
✗ Branch 524 not taken.
✗ Branch 525 not taken.
✗ Branch 526 not taken.
✗ Branch 527 not taken.
✗ Branch 528 not taken.
✗ Branch 529 not taken.
✗ Branch 530 not taken.
✗ Branch 531 not taken.
✗ Branch 532 not taken.
✗ Branch 533 not taken.
✗ Branch 534 not taken.
✗ Branch 535 not taken.
✗ Branch 536 not taken.
✗ Branch 537 not taken.
✗ Branch 538 not taken.
✗ Branch 539 not taken.
✗ Branch 540 not taken.
✗ Branch 541 not taken.
✗ Branch 542 not taken.
✗ Branch 543 not taken.
✗ Branch 544 not taken.
✗ Branch 545 not taken.
✗ Branch 546 not taken.
✗ Branch 547 not taken.
✗ Branch 548 not taken.
✗ Branch 549 not taken.
✗ Branch 550 not taken.
✗ Branch 551 not taken.
✗ Branch 552 not taken.
✗ Branch 553 not taken.
✗ Branch 554 not taken.
✗ Branch 555 not taken.
✗ Branch 556 not taken.
✗ Branch 557 not taken.
✗ Branch 558 not taken.
✗ Branch 559 not taken.
✗ Branch 560 not taken.
✗ Branch 561 not taken.
✗ Branch 562 not taken.
✗ Branch 563 not taken.
✗ Branch 564 not taken.
✗ Branch 565 not taken.
✗ Branch 566 not taken.
✗ Branch 567 not taken.
✗ Branch 568 not taken.
✗ Branch 569 not taken.
✗ Branch 570 not taken.
✗ Branch 571 not taken.
✗ Branch 572 not taken.
✗ Branch 573 not taken.
✗ Branch 574 not taken.
✗ Branch 575 not taken.
✗ Branch 576 not taken.
✗ Branch 577 not taken.
✗ Branch 578 not taken.
✗ Branch 579 not taken.
✗ Branch 580 not taken.
✗ Branch 581 not taken.
✗ Branch 582 not taken.
✗ Branch 583 not taken.
✗ Branch 584 not taken.
✗ Branch 585 not taken.
✗ Branch 586 not taken.
✗ Branch 587 not taken.
✗ Branch 588 not taken.
✗ Branch 589 not taken.
✗ Branch 590 not taken.
✗ Branch 591 not taken.
✗ Branch 592 not taken.
✗ Branch 593 not taken.
✗ Branch 594 not taken.
✗ Branch 595 not taken.
✗ Branch 596 not taken.
✗ Branch 597 not taken.
✗ Branch 598 not taken.
✗ Branch 599 not taken.
✗ Branch 600 not taken.
✗ Branch 601 not taken.
✗ Branch 602 not taken.
✗ Branch 603 not taken.
✗ Branch 604 not taken.
✗ Branch 605 not taken.
✗ Branch 606 not taken.
✗ Branch 607 not taken.
✗ Branch 608 not taken.
✗ Branch 609 not taken.
✗ Branch 610 not taken.
✗ Branch 611 not taken.
✗ Branch 612 not taken.
✗ Branch 613 not taken.
✗ Branch 614 not taken.
✗ Branch 615 not taken.
✗ Branch 616 not taken.
✗ Branch 617 not taken.
✗ Branch 618 not taken.
✗ Branch 619 not taken.
✗ Branch 620 not taken.
✗ Branch 621 not taken.
✗ Branch 622 not taken.
✗ Branch 623 not taken.
✗ Branch 624 not taken.
✓ Branch 625 taken 160 times.
✗ Branch 626 not taken.
✗ Branch 627 not taken.
✗ Branch 628 not taken.
✗ Branch 629 not taken.
✗ Branch 630 not taken.
✗ Branch 631 not taken.
✗ Branch 632 not taken.
✗ Branch 633 not taken.
✗ Branch 634 not taken.
✗ Branch 635 not taken.
✗ Branch 636 not taken.
✗ Branch 637 not taken.
✗ Branch 638 not taken.
✗ Branch 639 not taken.
✗ Branch 640 not taken.
✗ Branch 641 not taken.
✗ Branch 642 not taken.
✗ Branch 643 not taken.
✗ Branch 644 not taken.
✗ Branch 645 not taken.
✗ Branch 646 not taken.
✗ Branch 647 not taken.
✗ Branch 648 not taken.
✗ Branch 649 not taken.
✗ Branch 650 not taken.
✗ Branch 651 not taken.
✗ Branch 652 not taken.
✗ Branch 653 not taken.
✗ Branch 654 not taken.
✗ Branch 655 not taken.
✗ Branch 656 not taken.
✗ Branch 657 not taken.
✗ Branch 658 not taken.
✗ Branch 659 not taken.
✗ Branch 660 not taken.
✗ Branch 661 not taken.
✗ Branch 662 not taken.
✗ Branch 663 not taken.
✗ Branch 664 not taken.
✗ Branch 665 not taken.
✗ Branch 666 not taken.
✗ Branch 667 not taken.
✗ Branch 668 not taken.
✗ Branch 669 not taken.
✗ Branch 670 not taken.
✗ Branch 671 not taken.
✗ Branch 672 not taken.
✓ Branch 673 taken 320 times.
✗ Branch 674 not taken.
✗ Branch 675 not taken.
✗ Branch 676 not taken.
✗ Branch 677 not taken.
✗ Branch 678 not taken.
✗ Branch 679 not taken.
✗ Branch 680 not taken.
✗ Branch 681 not taken.
✗ Branch 682 not taken.
✗ Branch 683 not taken.
✗ Branch 684 not taken.
✗ Branch 685 not taken.
✗ Branch 686 not taken.
✗ Branch 687 not taken.
✗ Branch 688 not taken.
✗ Branch 689 not taken.
✗ Branch 690 not taken.
✗ Branch 691 not taken.
✗ Branch 692 not taken.
✗ Branch 693 not taken.
✗ Branch 694 not taken.
✗ Branch 695 not taken.
✗ Branch 696 not taken.
✗ Branch 697 not taken.
✗ Branch 698 not taken.
✗ Branch 699 not taken.
✗ Branch 700 not taken.
✗ Branch 701 not taken.
✗ Branch 702 not taken.
✗ Branch 703 not taken.
✗ Branch 704 not taken.
✗ Branch 705 not taken.
✗ Branch 706 not taken.
✗ Branch 707 not taken.
✗ Branch 708 not taken.
✗ Branch 709 not taken.
✗ Branch 710 not taken.
✗ Branch 711 not taken.
✗ Branch 712 not taken.
✗ Branch 713 not taken.
✗ Branch 714 not taken.
✗ Branch 715 not taken.
✗ Branch 716 not taken.
✗ Branch 717 not taken.
✗ Branch 718 not taken.
✗ Branch 719 not taken.
✗ Branch 720 not taken.
✗ Branch 721 not taken.
✗ Branch 722 not taken.
✗ Branch 723 not taken.
✗ Branch 724 not taken.
✗ Branch 725 not taken.
✗ Branch 726 not taken.
✗ Branch 727 not taken.
✗ Branch 728 not taken.
✓ Branch 729 taken 1 times.
✗ Branch 730 not taken.
✗ Branch 731 not taken.
✗ Branch 732 not taken.
✗ Branch 733 not taken.
✗ Branch 734 not taken.
✗ Branch 735 not taken.
✗ Branch 736 not taken.
✗ Branch 737 not taken.
✗ Branch 738 not taken.
✗ Branch 739 not taken.
✗ Branch 740 not taken.
✗ Branch 741 not taken.
✗ Branch 742 not taken.
✗ Branch 743 not taken.
✗ Branch 744 not taken.
✗ Branch 745 not taken.
✗ Branch 746 not taken.
✗ Branch 747 not taken.
✗ Branch 748 not taken.
✗ Branch 749 not taken.
✗ Branch 750 not taken.
✗ Branch 751 not taken.
✗ Branch 752 not taken.
✗ Branch 753 not taken.
✗ Branch 754 not taken.
✗ Branch 755 not taken.
✗ Branch 756 not taken.
✗ Branch 757 not taken.
✗ Branch 758 not taken.
✗ Branch 759 not taken.
✗ Branch 760 not taken.
✗ Branch 761 not taken.
✗ Branch 762 not taken.
✗ Branch 763 not taken.
✗ Branch 764 not taken.
✗ Branch 765 not taken.
✗ Branch 766 not taken.
✗ Branch 767 not taken.
✗ Branch 768 not taken.
✗ Branch 769 not taken.
✗ Branch 770 not taken.
✗ Branch 771 not taken.
✗ Branch 772 not taken.
✗ Branch 773 not taken.
✗ Branch 774 not taken.
✗ Branch 775 not taken.
✗ Branch 776 not taken.
✗ Branch 777 not taken.
✗ Branch 778 not taken.
✗ Branch 779 not taken.
✗ Branch 780 not taken.
✗ Branch 781 not taken.
✗ Branch 782 not taken.
✗ Branch 783 not taken.
✗ Branch 784 not taken.
✗ Branch 785 not taken.
✗ Branch 786 not taken.
✗ Branch 787 not taken.
✗ Branch 788 not taken.
✗ Branch 789 not taken.
✗ Branch 790 not taken.
✗ Branch 791 not taken.
✗ Branch 792 not taken.
✗ Branch 793 not taken.
✗ Branch 794 not taken.
✗ Branch 795 not taken.
✗ Branch 796 not taken.
✗ Branch 797 not taken.
✗ Branch 798 not taken.
✗ Branch 799 not taken.
✗ Branch 800 not taken.
✗ Branch 801 not taken.
✗ Branch 802 not taken.
✗ Branch 803 not taken.
✗ Branch 804 not taken.
✗ Branch 805 not taken.
✗ Branch 806 not taken.
✗ Branch 807 not taken.
✗ Branch 808 not taken.
✗ Branch 809 not taken.
✗ Branch 810 not taken.
✗ Branch 811 not taken.
✗ Branch 812 not taken.
✗ Branch 813 not taken.
✗ Branch 814 not taken.
✗ Branch 815 not taken.
✗ Branch 816 not taken.
✗ Branch 817 not taken.
✗ Branch 818 not taken.
✗ Branch 819 not taken.
✗ Branch 820 not taken.
✗ Branch 821 not taken.
✗ Branch 822 not taken.
✗ Branch 823 not taken.
✗ Branch 824 not taken.
✗ Branch 825 not taken.
✗ Branch 826 not taken.
✗ Branch 827 not taken.
✗ Branch 828 not taken.
✗ Branch 829 not taken.
✗ Branch 830 not taken.
✗ Branch 831 not taken.
✗ Branch 832 not taken.
✗ Branch 833 not taken.
✗ Branch 834 not taken.
✗ Branch 835 not taken.
✗ Branch 836 not taken.
✗ Branch 837 not taken.
✗ Branch 838 not taken.
✗ Branch 839 not taken.
✗ Branch 840 not taken.
✗ Branch 841 not taken.
✗ Branch 842 not taken.
✗ Branch 843 not taken.
✗ Branch 844 not taken.
✗ Branch 845 not taken.
✗ Branch 846 not taken.
✗ Branch 847 not taken.
✗ Branch 848 not taken.
✗ Branch 849 not taken.
✗ Branch 850 not taken.
✗ Branch 851 not taken.
✗ Branch 852 not taken.
✗ Branch 853 not taken.
✗ Branch 854 not taken.
✗ Branch 855 not taken.
✗ Branch 856 not taken.
✗ Branch 857 not taken.
✗ Branch 858 not taken.
✗ Branch 859 not taken.
✗ Branch 860 not taken.
✗ Branch 861 not taken.
✗ Branch 862 not taken.
✗ Branch 863 not taken.
✗ Branch 864 not taken.
✗ Branch 865 not taken.
✗ Branch 866 not taken.
✗ Branch 867 not taken.
✗ Branch 868 not taken.
✗ Branch 869 not taken.
✗ Branch 870 not taken.
✗ Branch 871 not taken.
✗ Branch 872 not taken.
✗ Branch 873 not taken.
✗ Branch 874 not taken.
✗ Branch 875 not taken.
✗ Branch 876 not taken.
✗ Branch 877 not taken.
✗ Branch 878 not taken.
✗ Branch 879 not taken.
✗ Branch 880 not taken.
✗ Branch 881 not taken.
✗ Branch 882 not taken.
✗ Branch 883 not taken.
✗ Branch 884 not taken.
✗ Branch 885 not taken.
✗ Branch 886 not taken.
✗ Branch 887 not taken.
✗ Branch 888 not taken.
✗ Branch 889 not taken.
✗ Branch 890 not taken.
✗ Branch 891 not taken.
✗ Branch 892 not taken.
✗ Branch 893 not taken.
✗ Branch 894 not taken.
✗ Branch 895 not taken.
✗ Branch 896 not taken.
✗ Branch 897 not taken.
✗ Branch 898 not taken.
✗ Branch 899 not taken.
✗ Branch 900 not taken.
✗ Branch 901 not taken.
✗ Branch 902 not taken.
✗ Branch 903 not taken.
✗ Branch 904 not taken.
✗ Branch 905 not taken.
✗ Branch 906 not taken.
✗ Branch 907 not taken.
✗ Branch 908 not taken.
✗ Branch 909 not taken.
✗ Branch 910 not taken.
✗ Branch 911 not taken.
✗ Branch 912 not taken.
✗ Branch 913 not taken.
✗ Branch 914 not taken.
✗ Branch 915 not taken.
✗ Branch 916 not taken.
✗ Branch 917 not taken.
✗ Branch 918 not taken.
✗ Branch 919 not taken.
✗ Branch 920 not taken.
✗ Branch 921 not taken.
✗ Branch 922 not taken.
✗ Branch 923 not taken.
✗ Branch 924 not taken.
✗ Branch 925 not taken.
✗ Branch 926 not taken.
✗ Branch 927 not taken.
✗ Branch 928 not taken.
✗ Branch 929 not taken.
✗ Branch 930 not taken.
✗ Branch 931 not taken.
✗ Branch 932 not taken.
✗ Branch 933 not taken.
✗ Branch 934 not taken.
✗ Branch 935 not taken.
✗ Branch 936 not taken.
✗ Branch 937 not taken.
✗ Branch 938 not taken.
✗ Branch 939 not taken.
✗ Branch 940 not taken.
✗ Branch 941 not taken.
✗ Branch 942 not taken.
✗ Branch 943 not taken.
✗ Branch 944 not taken.
✗ Branch 945 not taken.
✗ Branch 946 not taken.
✗ Branch 947 not taken.
✗ Branch 948 not taken.
✗ Branch 949 not taken.
✗ Branch 950 not taken.
✗ Branch 951 not taken.
✗ Branch 952 not taken.
✗ Branch 953 not taken.
✗ Branch 954 not taken.
✗ Branch 955 not taken.
✗ Branch 956 not taken.
✗ Branch 957 not taken.
✗ Branch 958 not taken.
✗ Branch 959 not taken.
✗ Branch 960 not taken.
✗ Branch 961 not taken.
✗ Branch 962 not taken.
✗ Branch 963 not taken.
✗ Branch 964 not taken.
✗ Branch 965 not taken.
✗ Branch 966 not taken.
✗ Branch 967 not taken.
✗ Branch 968 not taken.
✗ Branch 969 not taken.
✗ Branch 970 not taken.
✗ Branch 971 not taken.
✗ Branch 972 not taken.
✗ Branch 973 not taken.
✗ Branch 974 not taken.
✗ Branch 975 not taken.
✗ Branch 976 not taken.
✓ Branch 977 taken 160 times.
✗ Branch 978 not taken.
✗ Branch 979 not taken.
✗ Branch 980 not taken.
✗ Branch 981 not taken.
✗ Branch 982 not taken.
✗ Branch 983 not taken.
✗ Branch 984 not taken.
✗ Branch 985 not taken.
✗ Branch 986 not taken.
✗ Branch 987 not taken.
✗ Branch 988 not taken.
✗ Branch 989 not taken.
✗ Branch 990 not taken.
✗ Branch 991 not taken.
✗ Branch 992 not taken.
✗ Branch 993 not taken.
✗ Branch 994 not taken.
✗ Branch 995 not taken.
✗ Branch 996 not taken.
✗ Branch 997 not taken.
✗ Branch 998 not taken.
✗ Branch 999 not taken.
✗ Branch 1000 not taken.
✗ Branch 1001 not taken.
✗ Branch 1002 not taken.
✗ Branch 1003 not taken.
✗ Branch 1004 not taken.
✗ Branch 1005 not taken.
✗ Branch 1006 not taken.
✗ Branch 1007 not taken.
✗ Branch 1008 not taken.
✗ Branch 1009 not taken.
✗ Branch 1010 not taken.
✗ Branch 1011 not taken.
✗ Branch 1012 not taken.
✗ Branch 1013 not taken.
✗ Branch 1014 not taken.
✗ Branch 1015 not taken.
✗ Branch 1016 not taken.
✗ Branch 1017 not taken.
✗ Branch 1018 not taken.
✗ Branch 1019 not taken.
✗ Branch 1020 not taken.
✗ Branch 1021 not taken.
✗ Branch 1022 not taken.
✗ Branch 1023 not taken.
✗ Branch 1024 not taken.
✗ Branch 1025 not taken.
✗ Branch 1026 not taken.
✗ Branch 1027 not taken.
✗ Branch 1028 not taken.
✗ Branch 1029 not taken.
✗ Branch 1030 not taken.
✗ Branch 1031 not taken.
✗ Branch 1032 not taken.
✗ Branch 1033 not taken.
✗ Branch 1034 not taken.
✗ Branch 1035 not taken.
✗ Branch 1036 not taken.
✗ Branch 1037 not taken.
✗ Branch 1038 not taken.
✗ Branch 1039 not taken.
✗ Branch 1040 not taken.
✗ Branch 1041 not taken.
✗ Branch 1042 not taken.
✗ Branch 1043 not taken.
✗ Branch 1044 not taken.
✗ Branch 1045 not taken.
✗ Branch 1046 not taken.
✗ Branch 1047 not taken.
✗ Branch 1048 not taken.
✗ Branch 1049 not taken.
✗ Branch 1050 not taken.
✗ Branch 1051 not taken.
✗ Branch 1052 not taken.
✗ Branch 1053 not taken.
✗ Branch 1054 not taken.
✗ Branch 1055 not taken.
✗ Branch 1056 not taken.
✗ Branch 1057 not taken.
✗ Branch 1058 not taken.
✗ Branch 1059 not taken.
✗ Branch 1060 not taken.
✗ Branch 1061 not taken.
✗ Branch 1062 not taken.
✗ Branch 1063 not taken.
✗ Branch 1064 not taken.
✗ Branch 1065 not taken.
✗ Branch 1066 not taken.
✗ Branch 1067 not taken.
✗ Branch 1068 not taken.
✗ Branch 1069 not taken.
✗ Branch 1070 not taken.
✗ Branch 1071 not taken.
✗ Branch 1072 not taken.
✗ Branch 1073 not taken.
✗ Branch 1074 not taken.
✗ Branch 1075 not taken.
✗ Branch 1076 not taken.
✗ Branch 1077 not taken.
✗ Branch 1078 not taken.
✗ Branch 1079 not taken.
✗ Branch 1080 not taken.
✓ Branch 1081 taken 1 times.
✗ Branch 1082 not taken.
✗ Branch 1083 not taken.
✗ Branch 1084 not taken.
✗ Branch 1085 not taken.
✗ Branch 1086 not taken.
✗ Branch 1087 not taken.
✗ Branch 1088 not taken.
✗ Branch 1089 not taken.
✗ Branch 1090 not taken.
✗ Branch 1091 not taken.
✗ Branch 1092 not taken.
✗ Branch 1093 not taken.
✗ Branch 1094 not taken.
✗ Branch 1095 not taken.
✗ Branch 1096 not taken.
✗ Branch 1097 not taken.
✗ Branch 1098 not taken.
✗ Branch 1099 not taken.
✗ Branch 1100 not taken.
✗ Branch 1101 not taken.
✗ Branch 1102 not taken.
✗ Branch 1103 not taken.
✗ Branch 1104 not taken.
✗ Branch 1105 not taken.
✗ Branch 1106 not taken.
✗ Branch 1107 not taken.
✗ Branch 1108 not taken.
✗ Branch 1109 not taken.
✗ Branch 1110 not taken.
✗ Branch 1111 not taken.
✗ Branch 1112 not taken.
✗ Branch 1113 not taken.
✗ Branch 1114 not taken.
✗ Branch 1115 not taken.
✗ Branch 1116 not taken.
✗ Branch 1117 not taken.
✗ Branch 1118 not taken.
✗ Branch 1119 not taken.
✗ Branch 1120 not taken.
✗ Branch 1121 not taken.
✗ Branch 1122 not taken.
✗ Branch 1123 not taken.
✗ Branch 1124 not taken.
✗ Branch 1125 not taken.
✗ Branch 1126 not taken.
✗ Branch 1127 not taken.
✗ Branch 1128 not taken.
✗ Branch 1129 not taken.
✗ Branch 1130 not taken.
✗ Branch 1131 not taken.
✗ Branch 1132 not taken.
✗ Branch 1133 not taken.
✗ Branch 1134 not taken.
✗ Branch 1135 not taken.
✗ Branch 1136 not taken.
✗ Branch 1137 not taken.
✗ Branch 1138 not taken.
✗ Branch 1139 not taken.
✗ Branch 1140 not taken.
✗ Branch 1141 not taken.
✗ Branch 1142 not taken.
✗ Branch 1143 not taken.
✗ Branch 1144 not taken.
✗ Branch 1145 not taken.
✗ Branch 1146 not taken.
✗ Branch 1147 not taken.
✗ Branch 1148 not taken.
✗ Branch 1149 not taken.
✗ Branch 1150 not taken.
✗ Branch 1151 not taken.
✗ Branch 1152 not taken.
✗ Branch 1153 not taken.
✗ Branch 1154 not taken.
✗ Branch 1155 not taken.
✗ Branch 1156 not taken.
✗ Branch 1157 not taken.
✗ Branch 1158 not taken.
✗ Branch 1159 not taken.
✗ Branch 1160 not taken.
✓ Branch 1161 taken 4 times.
✗ Branch 1162 not taken.
✗ Branch 1163 not taken.
✗ Branch 1164 not taken.
✗ Branch 1165 not taken.
✗ Branch 1166 not taken.
✗ Branch 1167 not taken.
✗ Branch 1168 not taken.
✗ Branch 1169 not taken.
✗ Branch 1170 not taken.
✗ Branch 1171 not taken.
✗ Branch 1172 not taken.
✗ Branch 1173 not taken.
✗ Branch 1174 not taken.
✗ Branch 1175 not taken.
✗ Branch 1176 not taken.
✗ Branch 1177 not taken.
✗ Branch 1178 not taken.
✗ Branch 1179 not taken.
✗ Branch 1180 not taken.
✗ Branch 1181 not taken.
✗ Branch 1182 not taken.
✗ Branch 1183 not taken.
✗ Branch 1184 not taken.
✗ Branch 1185 not taken.
✗ Branch 1186 not taken.
✗ Branch 1187 not taken.
✗ Branch 1188 not taken.
✗ Branch 1189 not taken.
✗ Branch 1190 not taken.
✗ Branch 1191 not taken.
✗ Branch 1192 not taken.
✗ Branch 1193 not taken.
✗ Branch 1194 not taken.
✗ Branch 1195 not taken.
✗ Branch 1196 not taken.
✗ Branch 1197 not taken.
✗ Branch 1198 not taken.
✗ Branch 1199 not taken.
✗ Branch 1200 not taken.
✗ Branch 1201 not taken.
✗ Branch 1202 not taken.
✗ Branch 1203 not taken.
✗ Branch 1204 not taken.
✗ Branch 1205 not taken.
✗ Branch 1206 not taken.
✗ Branch 1207 not taken.
✗ Branch 1208 not taken.
✗ Branch 1209 not taken.
✗ Branch 1210 not taken.
✗ Branch 1211 not taken.
✗ Branch 1212 not taken.
✗ Branch 1213 not taken.
✗ Branch 1214 not taken.
✗ Branch 1215 not taken.
✗ Branch 1216 not taken.
✗ Branch 1217 not taken.
✗ Branch 1218 not taken.
✗ Branch 1219 not taken.
✗ Branch 1220 not taken.
✗ Branch 1221 not taken.
✗ Branch 1222 not taken.
✗ Branch 1223 not taken.
✗ Branch 1224 not taken.
✗ Branch 1225 not taken.
✗ Branch 1226 not taken.
✗ Branch 1227 not taken.
✗ Branch 1228 not taken.
✗ Branch 1229 not taken.
✗ Branch 1230 not taken.
✗ Branch 1231 not taken.
✗ Branch 1232 not taken.
✗ Branch 1233 not taken.
✗ Branch 1234 not taken.
✗ Branch 1235 not taken.
✗ Branch 1236 not taken.
✗ Branch 1237 not taken.
✗ Branch 1238 not taken.
✗ Branch 1239 not taken.
✗ Branch 1240 not taken.
✗ Branch 1241 not taken.
✗ Branch 1242 not taken.
✗ Branch 1243 not taken.
✗ Branch 1244 not taken.
✗ Branch 1245 not taken.
✗ Branch 1246 not taken.
✗ Branch 1247 not taken.
✗ Branch 1248 not taken.
✗ Branch 1249 not taken.
✗ Branch 1250 not taken.
✗ Branch 1251 not taken.
✗ Branch 1252 not taken.
✗ Branch 1253 not taken.
✗ Branch 1254 not taken.
✗ Branch 1255 not taken.
✗ Branch 1256 not taken.
✗ Branch 1257 not taken.
✗ Branch 1258 not taken.
✗ Branch 1259 not taken.
✗ Branch 1260 not taken.
✗ Branch 1261 not taken.
✗ Branch 1262 not taken.
✗ Branch 1263 not taken.
✗ Branch 1264 not taken.
✗ Branch 1265 not taken.
✗ Branch 1266 not taken.
✗ Branch 1267 not taken.
✗ Branch 1268 not taken.
✗ Branch 1269 not taken.
✗ Branch 1270 not taken.
✗ Branch 1271 not taken.
✗ Branch 1272 not taken.
✗ Branch 1273 not taken.
✗ Branch 1274 not taken.
✗ Branch 1275 not taken.
✗ Branch 1276 not taken.
✗ Branch 1277 not taken.
✗ Branch 1278 not taken.
✗ Branch 1279 not taken.
✗ Branch 1280 not taken.
✗ Branch 1281 not taken.
✗ Branch 1282 not taken.
✗ Branch 1283 not taken.
✗ Branch 1284 not taken.
✗ Branch 1285 not taken.
✗ Branch 1286 not taken.
✗ Branch 1287 not taken.
✗ Branch 1288 not taken.
✗ Branch 1289 not taken.
✗ Branch 1290 not taken.
✗ Branch 1291 not taken.
✗ Branch 1292 not taken.
✗ Branch 1293 not taken.
✗ Branch 1294 not taken.
✗ Branch 1295 not taken.
✗ Branch 1296 not taken.
✗ Branch 1297 not taken.
✗ Branch 1298 not taken.
✗ Branch 1299 not taken.
✗ Branch 1300 not taken.
✗ Branch 1301 not taken.
✗ Branch 1302 not taken.
✗ Branch 1303 not taken.
✗ Branch 1304 not taken.
✗ Branch 1305 not taken.
✗ Branch 1306 not taken.
✗ Branch 1307 not taken.
✗ Branch 1308 not taken.
✗ Branch 1309 not taken.
✗ Branch 1310 not taken.
✗ Branch 1311 not taken.
✗ Branch 1312 not taken.
✗ Branch 1313 not taken.
✗ Branch 1314 not taken.
✗ Branch 1315 not taken.
✗ Branch 1316 not taken.
✗ Branch 1317 not taken.
✗ Branch 1318 not taken.
✗ Branch 1319 not taken.
✗ Branch 1320 not taken.
✗ Branch 1321 not taken.
✗ Branch 1322 not taken.
✗ Branch 1323 not taken.
✗ Branch 1324 not taken.
✗ Branch 1325 not taken.
✗ Branch 1326 not taken.
✗ Branch 1327 not taken.
✗ Branch 1328 not taken.
✓ Branch 1329 taken 160 times.
✗ Branch 1330 not taken.
✗ Branch 1331 not taken.
✗ Branch 1332 not taken.
✗ Branch 1333 not taken.
✗ Branch 1334 not taken.
✗ Branch 1335 not taken.
✗ Branch 1336 not taken.
✗ Branch 1337 not taken.
✗ Branch 1338 not taken.
✗ Branch 1339 not taken.
✗ Branch 1340 not taken.
✗ Branch 1341 not taken.
✗ Branch 1342 not taken.
✗ Branch 1343 not taken.
✗ Branch 1344 not taken.
✗ Branch 1345 not taken.
✗ Branch 1346 not taken.
✗ Branch 1347 not taken.
✗ Branch 1348 not taken.
✗ Branch 1349 not taken.
✗ Branch 1350 not taken.
✗ Branch 1351 not taken.
✗ Branch 1352 not taken.
✗ Branch 1353 not taken.
✗ Branch 1354 not taken.
✗ Branch 1355 not taken.
✗ Branch 1356 not taken.
✗ Branch 1357 not taken.
✗ Branch 1358 not taken.
✗ Branch 1359 not taken.
✗ Branch 1360 not taken.
✗ Branch 1361 not taken.
✗ Branch 1362 not taken.
✗ Branch 1363 not taken.
✗ Branch 1364 not taken.
✗ Branch 1365 not taken.
✗ Branch 1366 not taken.
✗ Branch 1367 not taken.
✗ Branch 1368 not taken.
✗ Branch 1369 not taken.
✗ Branch 1370 not taken.
✗ Branch 1371 not taken.
✗ Branch 1372 not taken.
✗ Branch 1373 not taken.
✗ Branch 1374 not taken.
✗ Branch 1375 not taken.
✗ Branch 1376 not taken.
✓ Branch 1377 taken 640 times.
✗ Branch 1378 not taken.
✗ Branch 1379 not taken.
✗ Branch 1380 not taken.
✗ Branch 1381 not taken.
✗ Branch 1382 not taken.
✗ Branch 1383 not taken.
✗ Branch 1384 not taken.
✗ Branch 1385 not taken.
✗ Branch 1386 not taken.
✗ Branch 1387 not taken.
✗ Branch 1388 not taken.
✗ Branch 1389 not taken.
✗ Branch 1390 not taken.
✗ Branch 1391 not taken.
✗ Branch 1392 not taken.
✗ Branch 1393 not taken.
✗ Branch 1394 not taken.
✗ Branch 1395 not taken.
✗ Branch 1396 not taken.
✗ Branch 1397 not taken.
✗ Branch 1398 not taken.
✗ Branch 1399 not taken.
✗ Branch 1400 not taken.
✗ Branch 1401 not taken.
✗ Branch 1402 not taken.
✗ Branch 1403 not taken.
✗ Branch 1404 not taken.
✗ Branch 1405 not taken.
✗ Branch 1406 not taken.
✗ Branch 1407 not taken.
✗ Branch 1408 not taken.
✗ Branch 1409 not taken.
✗ Branch 1410 not taken.
✗ Branch 1411 not taken.
✗ Branch 1412 not taken.
✗ Branch 1413 not taken.
✗ Branch 1414 not taken.
✗ Branch 1415 not taken.
✗ Branch 1416 not taken.
✗ Branch 1417 not taken.
✗ Branch 1418 not taken.
✗ Branch 1419 not taken.
✗ Branch 1420 not taken.
✗ Branch 1421 not taken.
✗ Branch 1422 not taken.
✗ Branch 1423 not taken.
✗ Branch 1424 not taken.
✗ Branch 1425 not taken.
✗ Branch 1426 not taken.
✗ Branch 1427 not taken.
✗ Branch 1428 not taken.
✗ Branch 1429 not taken.
✗ Branch 1430 not taken.
✗ Branch 1431 not taken.
✗ Branch 1432 not taken.
✓ Branch 1433 taken 1 times.
✗ Branch 1434 not taken.
✗ Branch 1435 not taken.
✗ Branch 1436 not taken.
✗ Branch 1437 not taken.
✗ Branch 1438 not taken.
✗ Branch 1439 not taken.
✗ Branch 1440 not taken.
✗ Branch 1441 not taken.
✗ Branch 1442 not taken.
✗ Branch 1443 not taken.
✗ Branch 1444 not taken.
✗ Branch 1445 not taken.
✗ Branch 1446 not taken.
✗ Branch 1447 not taken.
✗ Branch 1448 not taken.
✗ Branch 1449 not taken.
✗ Branch 1450 not taken.
✗ Branch 1451 not taken.
✗ Branch 1452 not taken.
✗ Branch 1453 not taken.
✗ Branch 1454 not taken.
✗ Branch 1455 not taken.
✗ Branch 1456 not taken.
✗ Branch 1457 not taken.
✗ Branch 1458 not taken.
✗ Branch 1459 not taken.
✗ Branch 1460 not taken.
✗ Branch 1461 not taken.
✗ Branch 1462 not taken.
✗ Branch 1463 not taken.
✗ Branch 1464 not taken.
✗ Branch 1465 not taken.
✗ Branch 1466 not taken.
✗ Branch 1467 not taken.
✗ Branch 1468 not taken.
✗ Branch 1469 not taken.
✗ Branch 1470 not taken.
✗ Branch 1471 not taken.
✗ Branch 1472 not taken.
✗ Branch 1473 not taken.
✗ Branch 1474 not taken.
✗ Branch 1475 not taken.
✗ Branch 1476 not taken.
✗ Branch 1477 not taken.
✗ Branch 1478 not taken.
✗ Branch 1479 not taken.
✗ Branch 1480 not taken.
✗ Branch 1481 not taken.
✗ Branch 1482 not taken.
✗ Branch 1483 not taken.
✗ Branch 1484 not taken.
✗ Branch 1485 not taken.
✗ Branch 1486 not taken.
✗ Branch 1487 not taken.
✗ Branch 1488 not taken.
✗ Branch 1489 not taken.
✗ Branch 1490 not taken.
✗ Branch 1491 not taken.
✗ Branch 1492 not taken.
✗ Branch 1493 not taken.
✗ Branch 1494 not taken.
✗ Branch 1495 not taken.
✗ Branch 1496 not taken.
✗ Branch 1497 not taken.
✗ Branch 1498 not taken.
✗ Branch 1499 not taken.
✗ Branch 1500 not taken.
✗ Branch 1501 not taken.
✗ Branch 1502 not taken.
✗ Branch 1503 not taken.
✗ Branch 1504 not taken.
✗ Branch 1505 not taken.
✗ Branch 1506 not taken.
✗ Branch 1507 not taken.
✗ Branch 1508 not taken.
✗ Branch 1509 not taken.
✗ Branch 1510 not taken.
✗ Branch 1511 not taken.
✗ Branch 1512 not taken.
✗ Branch 1513 not taken.
✗ Branch 1514 not taken.
✗ Branch 1515 not taken.
✗ Branch 1516 not taken.
✗ Branch 1517 not taken.
✗ Branch 1518 not taken.
✗ Branch 1519 not taken.
✗ Branch 1520 not taken.
✗ Branch 1521 not taken.
✗ Branch 1522 not taken.
✗ Branch 1523 not taken.
✗ Branch 1524 not taken.
✗ Branch 1525 not taken.
✗ Branch 1526 not taken.
✗ Branch 1527 not taken.
✗ Branch 1528 not taken.
✗ Branch 1529 not taken.
✗ Branch 1530 not taken.
✗ Branch 1531 not taken.
✗ Branch 1532 not taken.
✗ Branch 1533 not taken.
✗ Branch 1534 not taken.
✗ Branch 1535 not taken.
✗ Branch 1536 not taken.
✗ Branch 1537 not taken.
✗ Branch 1538 not taken.
✗ Branch 1539 not taken.
✗ Branch 1540 not taken.
✗ Branch 1541 not taken.
✗ Branch 1542 not taken.
✗ Branch 1543 not taken.
✗ Branch 1544 not taken.
✗ Branch 1545 not taken.
✗ Branch 1546 not taken.
✗ Branch 1547 not taken.
✗ Branch 1548 not taken.
✗ Branch 1549 not taken.
✗ Branch 1550 not taken.
✗ Branch 1551 not taken.
✗ Branch 1552 not taken.
✗ Branch 1553 not taken.
✗ Branch 1554 not taken.
✗ Branch 1555 not taken.
✗ Branch 1556 not taken.
✗ Branch 1557 not taken.
✗ Branch 1558 not taken.
✗ Branch 1559 not taken.
✗ Branch 1560 not taken.
✗ Branch 1561 not taken.
✗ Branch 1562 not taken.
✗ Branch 1563 not taken.
✗ Branch 1564 not taken.
✗ Branch 1565 not taken.
✗ Branch 1566 not taken.
✗ Branch 1567 not taken.
✗ Branch 1568 not taken.
✗ Branch 1569 not taken.
✗ Branch 1570 not taken.
✗ Branch 1571 not taken.
✗ Branch 1572 not taken.
✗ Branch 1573 not taken.
✗ Branch 1574 not taken.
✗ Branch 1575 not taken.
✗ Branch 1576 not taken.
✗ Branch 1577 not taken.
✗ Branch 1578 not taken.
✗ Branch 1579 not taken.
✗ Branch 1580 not taken.
✗ Branch 1581 not taken.
✗ Branch 1582 not taken.
✗ Branch 1583 not taken.
✗ Branch 1584 not taken.
✗ Branch 1585 not taken.
✗ Branch 1586 not taken.
✗ Branch 1587 not taken.
✗ Branch 1588 not taken.
✗ Branch 1589 not taken.
✗ Branch 1590 not taken.
✗ Branch 1591 not taken.
✗ Branch 1592 not taken.
✗ Branch 1593 not taken.
✗ Branch 1594 not taken.
✗ Branch 1595 not taken.
✗ Branch 1596 not taken.
✗ Branch 1597 not taken.
✗ Branch 1598 not taken.
✗ Branch 1599 not taken.
✗ Branch 1600 not taken.
✗ Branch 1601 not taken.
✗ Branch 1602 not taken.
✗ Branch 1603 not taken.
✗ Branch 1604 not taken.
✗ Branch 1605 not taken.
✗ Branch 1606 not taken.
✗ Branch 1607 not taken.
✗ Branch 1608 not taken.
✗ Branch 1609 not taken.
✗ Branch 1610 not taken.
✗ Branch 1611 not taken.
✗ Branch 1612 not taken.
✗ Branch 1613 not taken.
✗ Branch 1614 not taken.
✗ Branch 1615 not taken.
✗ Branch 1616 not taken.
✗ Branch 1617 not taken.
✗ Branch 1618 not taken.
✗ Branch 1619 not taken.
✗ Branch 1620 not taken.
✗ Branch 1621 not taken.
✗ Branch 1622 not taken.
✗ Branch 1623 not taken.
✗ Branch 1624 not taken.
✗ Branch 1625 not taken.
✗ Branch 1626 not taken.
✗ Branch 1627 not taken.
✗ Branch 1628 not taken.
✗ Branch 1629 not taken.
✗ Branch 1630 not taken.
✗ Branch 1631 not taken.
✗ Branch 1632 not taken.
✗ Branch 1633 not taken.
✗ Branch 1634 not taken.
✗ Branch 1635 not taken.
✗ Branch 1636 not taken.
✗ Branch 1637 not taken.
✗ Branch 1638 not taken.
✗ Branch 1639 not taken.
✗ Branch 1640 not taken.
✗ Branch 1641 not taken.
✗ Branch 1642 not taken.
✗ Branch 1643 not taken.
✗ Branch 1644 not taken.
✗ Branch 1645 not taken.
✗ Branch 1646 not taken.
✗ Branch 1647 not taken.
✗ Branch 1648 not taken.
✗ Branch 1649 not taken.
✗ Branch 1650 not taken.
✗ Branch 1651 not taken.
✗ Branch 1652 not taken.
✗ Branch 1653 not taken.
✗ Branch 1654 not taken.
✗ Branch 1655 not taken.
✗ Branch 1656 not taken.
✗ Branch 1657 not taken.
✗ Branch 1658 not taken.
✗ Branch 1659 not taken.
✗ Branch 1660 not taken.
✗ Branch 1661 not taken.
✗ Branch 1662 not taken.
✗ Branch 1663 not taken.
✗ Branch 1664 not taken.
✗ Branch 1665 not taken.
✗ Branch 1666 not taken.
✗ Branch 1667 not taken.
✗ Branch 1668 not taken.
✗ Branch 1669 not taken.
✗ Branch 1670 not taken.
✗ Branch 1671 not taken.
✗ Branch 1672 not taken.
✗ Branch 1673 not taken.
✗ Branch 1674 not taken.
✗ Branch 1675 not taken.
✗ Branch 1676 not taken.
✗ Branch 1677 not taken.
✗ Branch 1678 not taken.
✗ Branch 1679 not taken.
✗ Branch 1680 not taken.
✓ Branch 1681 taken 160 times.
✗ Branch 1682 not taken.
✗ Branch 1683 not taken.
✗ Branch 1684 not taken.
✗ Branch 1685 not taken.
✗ Branch 1686 not taken.
✗ Branch 1687 not taken.
✗ Branch 1688 not taken.
✗ Branch 1689 not taken.
✗ Branch 1690 not taken.
✗ Branch 1691 not taken.
✗ Branch 1692 not taken.
✗ Branch 1693 not taken.
✗ Branch 1694 not taken.
✗ Branch 1695 not taken.
✗ Branch 1696 not taken.
✗ Branch 1697 not taken.
✗ Branch 1698 not taken.
✗ Branch 1699 not taken.
✗ Branch 1700 not taken.
✗ Branch 1701 not taken.
✗ Branch 1702 not taken.
✗ Branch 1703 not taken.
✗ Branch 1704 not taken.
✗ Branch 1705 not taken.
✗ Branch 1706 not taken.
✗ Branch 1707 not taken.
✗ Branch 1708 not taken.
✗ Branch 1709 not taken.
✗ Branch 1710 not taken.
✗ Branch 1711 not taken.
✗ Branch 1712 not taken.
✗ Branch 1713 not taken.
✗ Branch 1714 not taken.
✗ Branch 1715 not taken.
✗ Branch 1716 not taken.
✗ Branch 1717 not taken.
✗ Branch 1718 not taken.
✗ Branch 1719 not taken.
✗ Branch 1720 not taken.
✗ Branch 1721 not taken.
✗ Branch 1722 not taken.
✗ Branch 1723 not taken.
✗ Branch 1724 not taken.
✗ Branch 1725 not taken.
✗ Branch 1726 not taken.
✗ Branch 1727 not taken.
✗ Branch 1728 not taken.
✗ Branch 1729 not taken.
✗ Branch 1730 not taken.
✗ Branch 1731 not taken.
✗ Branch 1732 not taken.
✗ Branch 1733 not taken.
✗ Branch 1734 not taken.
✗ Branch 1735 not taken.
✗ Branch 1736 not taken.
✗ Branch 1737 not taken.
✗ Branch 1738 not taken.
✗ Branch 1739 not taken.
✗ Branch 1740 not taken.
✗ Branch 1741 not taken.
✗ Branch 1742 not taken.
✗ Branch 1743 not taken.
✗ Branch 1744 not taken.
✗ Branch 1745 not taken.
✗ Branch 1746 not taken.
✗ Branch 1747 not taken.
✗ Branch 1748 not taken.
✗ Branch 1749 not taken.
✗ Branch 1750 not taken.
✗ Branch 1751 not taken.
✗ Branch 1752 not taken.
✗ Branch 1753 not taken.
✗ Branch 1754 not taken.
✗ Branch 1755 not taken.
✗ Branch 1756 not taken.
✗ Branch 1757 not taken.
✗ Branch 1758 not taken.
✗ Branch 1759 not taken.
✗ Branch 1760 not taken.
✗ Branch 1761 not taken.
✗ Branch 1762 not taken.
✗ Branch 1763 not taken.
✗ Branch 1764 not taken.
✗ Branch 1765 not taken.
✗ Branch 1766 not taken.
✗ Branch 1767 not taken.
✗ Branch 1768 not taken.
✗ Branch 1769 not taken.
✗ Branch 1770 not taken.
✗ Branch 1771 not taken.
✗ Branch 1772 not taken.
✗ Branch 1773 not taken.
✗ Branch 1774 not taken.
✗ Branch 1775 not taken.
✗ Branch 1776 not taken.
✗ Branch 1777 not taken.
✗ Branch 1778 not taken.
✗ Branch 1779 not taken.
✗ Branch 1780 not taken.
✗ Branch 1781 not taken.
✗ Branch 1782 not taken.
✗ Branch 1783 not taken.
✗ Branch 1784 not taken.
✗ Branch 1785 not taken.
✗ Branch 1786 not taken.
✗ Branch 1787 not taken.
✗ Branch 1788 not taken.
✗ Branch 1789 not taken.
✗ Branch 1790 not taken.
✗ Branch 1791 not taken.
✗ Branch 1792 not taken.
✗ Branch 1793 not taken.
✗ Branch 1794 not taken.
✗ Branch 1795 not taken.
✗ Branch 1796 not taken.
✗ Branch 1797 not taken.
✗ Branch 1798 not taken.
✗ Branch 1799 not taken.
✗ Branch 1800 not taken.
✗ Branch 1801 not taken.
✗ Branch 1802 not taken.
✗ Branch 1803 not taken.
✗ Branch 1804 not taken.
✗ Branch 1805 not taken.
✗ Branch 1806 not taken.
✗ Branch 1807 not taken.
✗ Branch 1808 not taken.
✗ Branch 1809 not taken.
✗ Branch 1810 not taken.
✗ Branch 1811 not taken.
✗ Branch 1812 not taken.
✗ Branch 1813 not taken.
✗ Branch 1814 not taken.
✗ Branch 1815 not taken.
✗ Branch 1816 not taken.
✗ Branch 1817 not taken.
✗ Branch 1818 not taken.
✗ Branch 1819 not taken.
✗ Branch 1820 not taken.
✗ Branch 1821 not taken.
✗ Branch 1822 not taken.
✗ Branch 1823 not taken.
✗ Branch 1824 not taken.
✗ Branch 1825 not taken.
✗ Branch 1826 not taken.
✗ Branch 1827 not taken.
✗ Branch 1828 not taken.
✗ Branch 1829 not taken.
✗ Branch 1830 not taken.
✗ Branch 1831 not taken.
✗ Branch 1832 not taken.
✗ Branch 1833 not taken.
✗ Branch 1834 not taken.
✗ Branch 1835 not taken.
✗ Branch 1836 not taken.
✗ Branch 1837 not taken.
✗ Branch 1838 not taken.
✗ Branch 1839 not taken.
✗ Branch 1840 not taken.
✗ Branch 1841 not taken.
✗ Branch 1842 not taken.
✗ Branch 1843 not taken.
✗ Branch 1844 not taken.
✗ Branch 1845 not taken.
✗ Branch 1846 not taken.
✗ Branch 1847 not taken.
✗ Branch 1848 not taken.
✗ Branch 1849 not taken.
✗ Branch 1850 not taken.
✗ Branch 1851 not taken.
✗ Branch 1852 not taken.
✗ Branch 1853 not taken.
✗ Branch 1854 not taken.
✗ Branch 1855 not taken.
✗ Branch 1856 not taken.
✗ Branch 1857 not taken.
✗ Branch 1858 not taken.
✗ Branch 1859 not taken.
✗ Branch 1860 not taken.
✗ Branch 1861 not taken.
✗ Branch 1862 not taken.
✗ Branch 1863 not taken.
✗ Branch 1864 not taken.
✗ Branch 1865 not taken.
✗ Branch 1866 not taken.
✗ Branch 1867 not taken.
✗ Branch 1868 not taken.
✗ Branch 1869 not taken.
✗ Branch 1870 not taken.
✗ Branch 1871 not taken.
✗ Branch 1872 not taken.
✗ Branch 1873 not taken.
✗ Branch 1874 not taken.
✗ Branch 1875 not taken.
✗ Branch 1876 not taken.
✗ Branch 1877 not taken.
✗ Branch 1878 not taken.
✗ Branch 1879 not taken.
✗ Branch 1880 not taken.
✗ Branch 1881 not taken.
✗ Branch 1882 not taken.
✗ Branch 1883 not taken.
✗ Branch 1884 not taken.
✗ Branch 1885 not taken.
✗ Branch 1886 not taken.
✗ Branch 1887 not taken.
✗ Branch 1888 not taken.
✗ Branch 1889 not taken.
✗ Branch 1890 not taken.
✗ Branch 1891 not taken.
✗ Branch 1892 not taken.
✗ Branch 1893 not taken.
✗ Branch 1894 not taken.
✗ Branch 1895 not taken.
✗ Branch 1896 not taken.
✗ Branch 1897 not taken.
✗ Branch 1898 not taken.
✗ Branch 1899 not taken.
✗ Branch 1900 not taken.
✗ Branch 1901 not taken.
✗ Branch 1902 not taken.
✗ Branch 1903 not taken.
✗ Branch 1904 not taken.
✗ Branch 1905 not taken.
✗ Branch 1906 not taken.
✗ Branch 1907 not taken.
✗ Branch 1908 not taken.
✗ Branch 1909 not taken.
✗ Branch 1910 not taken.
✗ Branch 1911 not taken.
✗ Branch 1912 not taken.
✗ Branch 1913 not taken.
✗ Branch 1914 not taken.
✗ Branch 1915 not taken.
✗ Branch 1916 not taken.
✗ Branch 1917 not taken.
✗ Branch 1918 not taken.
✗ Branch 1919 not taken.
✗ Branch 1920 not taken.
✗ Branch 1921 not taken.
✗ Branch 1922 not taken.
✗ Branch 1923 not taken.
✗ Branch 1924 not taken.
✗ Branch 1925 not taken.
✗ Branch 1926 not taken.
✗ Branch 1927 not taken.
✗ Branch 1928 not taken.
✗ Branch 1929 not taken.
✗ Branch 1930 not taken.
✗ Branch 1931 not taken.
✗ Branch 1932 not taken.
✗ Branch 1933 not taken.
✗ Branch 1934 not taken.
✗ Branch 1935 not taken.
✗ Branch 1936 not taken.
✗ Branch 1937 not taken.
✗ Branch 1938 not taken.
✗ Branch 1939 not taken.
✗ Branch 1940 not taken.
✗ Branch 1941 not taken.
✗ Branch 1942 not taken.
✗ Branch 1943 not taken.
✗ Branch 1944 not taken.
✗ Branch 1945 not taken.
✗ Branch 1946 not taken.
✗ Branch 1947 not taken.
✗ Branch 1948 not taken.
✗ Branch 1949 not taken.
✗ Branch 1950 not taken.
✗ Branch 1951 not taken.
✗ Branch 1952 not taken.
✗ Branch 1953 not taken.
✗ Branch 1954 not taken.
✗ Branch 1955 not taken.
✗ Branch 1956 not taken.
✗ Branch 1957 not taken.
✗ Branch 1958 not taken.
✗ Branch 1959 not taken.
✗ Branch 1960 not taken.
✗ Branch 1961 not taken.
✗ Branch 1962 not taken.
✗ Branch 1963 not taken.
✗ Branch 1964 not taken.
✗ Branch 1965 not taken.
✗ Branch 1966 not taken.
✗ Branch 1967 not taken.
✗ Branch 1968 not taken.
✗ Branch 1969 not taken.
✗ Branch 1970 not taken.
✗ Branch 1971 not taken.
✗ Branch 1972 not taken.
✗ Branch 1973 not taken.
✗ Branch 1974 not taken.
✗ Branch 1975 not taken.
✗ Branch 1976 not taken.
✗ Branch 1977 not taken.
✗ Branch 1978 not taken.
✗ Branch 1979 not taken.
✗ Branch 1980 not taken.
✗ Branch 1981 not taken.
✗ Branch 1982 not taken.
✗ Branch 1983 not taken.
✗ Branch 1984 not taken.
✗ Branch 1985 not taken.
✗ Branch 1986 not taken.
✗ Branch 1987 not taken.
✗ Branch 1988 not taken.
✗ Branch 1989 not taken.
✗ Branch 1990 not taken.
✗ Branch 1991 not taken.
✗ Branch 1992 not taken.
✗ Branch 1993 not taken.
✗ Branch 1994 not taken.
✗ Branch 1995 not taken.
✗ Branch 1996 not taken.
✗ Branch 1997 not taken.
✗ Branch 1998 not taken.
✗ Branch 1999 not taken.
✗ Branch 2000 not taken.
✗ Branch 2001 not taken.
✗ Branch 2002 not taken.
✗ Branch 2003 not taken.
✗ Branch 2004 not taken.
✗ Branch 2005 not taken.
✗ Branch 2006 not taken.
✗ Branch 2007 not taken.
✗ Branch 2008 not taken.
✗ Branch 2009 not taken.
✗ Branch 2010 not taken.
✗ Branch 2011 not taken.
✗ Branch 2012 not taken.
✗ Branch 2013 not taken.
✗ Branch 2014 not taken.
✗ Branch 2015 not taken.
✗ Branch 2016 not taken.
✗ Branch 2017 not taken.
✗ Branch 2018 not taken.
✗ Branch 2019 not taken.
✗ Branch 2020 not taken.
✗ Branch 2021 not taken.
✗ Branch 2022 not taken.
✗ Branch 2023 not taken.
✗ Branch 2024 not taken.
✗ Branch 2025 not taken.
✗ Branch 2026 not taken.
✗ Branch 2027 not taken.
✗ Branch 2028 not taken.
✗ Branch 2029 not taken.
✗ Branch 2030 not taken.
✗ Branch 2031 not taken.
✗ Branch 2032 not taken.
✗ Branch 2033 not taken.
✗ Branch 2034 not taken.
✗ Branch 2035 not taken.
✗ Branch 2036 not taken.
✗ Branch 2037 not taken.
✗ Branch 2038 not taken.
✗ Branch 2039 not taken.
✗ Branch 2040 not taken.
✗ Branch 2041 not taken.
✗ Branch 2042 not taken.
✗ Branch 2043 not taken.
✗ Branch 2044 not taken.
✗ Branch 2045 not taken.
✗ Branch 2046 not taken.
✗ Branch 2047 not taken.
✗ Branch 2048 not taken.
✗ Branch 2049 not taken.
✗ Branch 2050 not taken.
✗ Branch 2051 not taken.
✗ Branch 2052 not taken.
✗ Branch 2053 not taken.
✗ Branch 2054 not taken.
✗ Branch 2055 not taken.
✗ Branch 2056 not taken.
✗ Branch 2057 not taken.
✗ Branch 2058 not taken.
✗ Branch 2059 not taken.
✗ Branch 2060 not taken.
✗ Branch 2061 not taken.
✗ Branch 2062 not taken.
✗ Branch 2063 not taken.
✗ Branch 2064 not taken.
✗ Branch 2065 not taken.
✗ Branch 2066 not taken.
✗ Branch 2067 not taken.
✗ Branch 2068 not taken.
✗ Branch 2069 not taken.
✗ Branch 2070 not taken.
✗ Branch 2071 not taken.
✗ Branch 2072 not taken.
✗ Branch 2073 not taken.
✗ Branch 2074 not taken.
✗ Branch 2075 not taken.
✗ Branch 2076 not taken.
✗ Branch 2077 not taken.
✗ Branch 2078 not taken.
✗ Branch 2079 not taken.
✗ Branch 2080 not taken.
✗ Branch 2081 not taken.
✗ Branch 2082 not taken.
✗ Branch 2083 not taken.
✗ Branch 2084 not taken.
✗ Branch 2085 not taken.
✗ Branch 2086 not taken.
✗ Branch 2087 not taken.
✗ Branch 2088 not taken.
✗ Branch 2089 not taken.
✗ Branch 2090 not taken.
✗ Branch 2091 not taken.
✗ Branch 2092 not taken.
✗ Branch 2093 not taken.
✗ Branch 2094 not taken.
✗ Branch 2095 not taken.
✗ Branch 2096 not taken.
✗ Branch 2097 not taken.
✗ Branch 2098 not taken.
✗ Branch 2099 not taken.
✗ Branch 2100 not taken.
✗ Branch 2101 not taken.
✗ Branch 2102 not taken.
✗ Branch 2103 not taken.
✗ Branch 2104 not taken.
✗ Branch 2105 not taken.
✗ Branch 2106 not taken.
✗ Branch 2107 not taken.
✗ Branch 2108 not taken.
✗ Branch 2109 not taken.
✗ Branch 2110 not taken.
✗ Branch 2111 not taken.
✗ Branch 2112 not taken.
✗ Branch 2113 not taken.
✗ Branch 2114 not taken.
✗ Branch 2115 not taken.
✗ Branch 2116 not taken.
✗ Branch 2117 not taken.
✗ Branch 2118 not taken.
✗ Branch 2119 not taken.
✗ Branch 2120 not taken.
✗ Branch 2121 not taken.
✗ Branch 2122 not taken.
✗ Branch 2123 not taken.
✗ Branch 2124 not taken.
✗ Branch 2125 not taken.
✗ Branch 2126 not taken.
✗ Branch 2127 not taken.
✗ Branch 2128 not taken.
✗ Branch 2129 not taken.
✗ Branch 2130 not taken.
✗ Branch 2131 not taken.
✗ Branch 2132 not taken.
✗ Branch 2133 not taken.
✗ Branch 2134 not taken.
✗ Branch 2135 not taken.
✗ Branch 2136 not taken.
✗ Branch 2137 not taken.
✗ Branch 2138 not taken.
✗ Branch 2139 not taken.
✗ Branch 2140 not taken.
✗ Branch 2141 not taken.
✗ Branch 2142 not taken.
✗ Branch 2143 not taken.
✗ Branch 2144 not taken.
✗ Branch 2145 not taken.
✗ Branch 2146 not taken.
✗ Branch 2147 not taken.
✗ Branch 2148 not taken.
✗ Branch 2149 not taken.
✗ Branch 2150 not taken.
✗ Branch 2151 not taken.
✗ Branch 2152 not taken.
✗ Branch 2153 not taken.
✗ Branch 2154 not taken.
✗ Branch 2155 not taken.
✗ Branch 2156 not taken.
✗ Branch 2157 not taken.
✗ Branch 2158 not taken.
✗ Branch 2159 not taken.
✗ Branch 2160 not taken.
✗ Branch 2161 not taken.
✗ Branch 2162 not taken.
✗ Branch 2163 not taken.
✗ Branch 2164 not taken.
✗ Branch 2165 not taken.
✗ Branch 2166 not taken.
✗ Branch 2167 not taken.
✗ Branch 2168 not taken.
✗ Branch 2169 not taken.
✗ Branch 2170 not taken.
✗ Branch 2171 not taken.
✗ Branch 2172 not taken.
✗ Branch 2173 not taken.
✗ Branch 2174 not taken.
✗ Branch 2175 not taken.
✗ Branch 2176 not taken.
✗ Branch 2177 not taken.
✗ Branch 2178 not taken.
✗ Branch 2179 not taken.
✗ Branch 2180 not taken.
✗ Branch 2181 not taken.
✗ Branch 2182 not taken.
✗ Branch 2183 not taken.
✗ Branch 2184 not taken.
✗ Branch 2185 not taken.
✗ Branch 2186 not taken.
✗ Branch 2187 not taken.
✗ Branch 2188 not taken.
✗ Branch 2189 not taken.
✗ Branch 2190 not taken.
✗ Branch 2191 not taken.
✗ Branch 2192 not taken.
✗ Branch 2193 not taken.
✗ Branch 2194 not taken.
✗ Branch 2195 not taken.
✗ Branch 2196 not taken.
✗ Branch 2197 not taken.
✗ Branch 2198 not taken.
✗ Branch 2199 not taken.
✗ Branch 2200 not taken.
✗ Branch 2201 not taken.
✗ Branch 2202 not taken.
✗ Branch 2203 not taken.
✗ Branch 2204 not taken.
✗ Branch 2205 not taken.
✗ Branch 2206 not taken.
✗ Branch 2207 not taken.
✗ Branch 2208 not taken.
✗ Branch 2209 not taken.
✗ Branch 2210 not taken.
✗ Branch 2211 not taken.
✗ Branch 2212 not taken.
✗ Branch 2213 not taken.
✗ Branch 2214 not taken.
✗ Branch 2215 not taken.
✗ Branch 2216 not taken.
✗ Branch 2217 not taken.
✗ Branch 2218 not taken.
✗ Branch 2219 not taken.
✗ Branch 2220 not taken.
✗ Branch 2221 not taken.
✗ Branch 2222 not taken.
✗ Branch 2223 not taken.
✗ Branch 2224 not taken.
✗ Branch 2225 not taken.
✗ Branch 2226 not taken.
✗ Branch 2227 not taken.
✗ Branch 2228 not taken.
✗ Branch 2229 not taken.
✗ Branch 2230 not taken.
✗ Branch 2231 not taken.
✗ Branch 2232 not taken.
✗ Branch 2233 not taken.
✗ Branch 2234 not taken.
✗ Branch 2235 not taken.
✗ Branch 2236 not taken.
✗ Branch 2237 not taken.
✗ Branch 2238 not taken.
✗ Branch 2239 not taken.
✗ Branch 2240 not taken.
✗ Branch 2241 not taken.
✗ Branch 2242 not taken.
✗ Branch 2243 not taken.
✗ Branch 2244 not taken.
✗ Branch 2245 not taken.
✗ Branch 2246 not taken.
✗ Branch 2247 not taken.
✗ Branch 2248 not taken.
✗ Branch 2249 not taken.
✗ Branch 2250 not taken.
✗ Branch 2251 not taken.
✗ Branch 2252 not taken.
✗ Branch 2253 not taken.
✗ Branch 2254 not taken.
✗ Branch 2255 not taken.
✗ Branch 2256 not taken.
✗ Branch 2257 not taken.
✗ Branch 2258 not taken.
✗ Branch 2259 not taken.
✗ Branch 2260 not taken.
✗ Branch 2261 not taken.
✗ Branch 2262 not taken.
✗ Branch 2263 not taken.
✗ Branch 2264 not taken.
✗ Branch 2265 not taken.
✗ Branch 2266 not taken.
✗ Branch 2267 not taken.
✗ Branch 2268 not taken.
✗ Branch 2269 not taken.
✗ Branch 2270 not taken.
✗ Branch 2271 not taken.
✗ Branch 2272 not taken.
✗ Branch 2273 not taken.
✗ Branch 2274 not taken.
✗ Branch 2275 not taken.
✗ Branch 2276 not taken.
✗ Branch 2277 not taken.
✗ Branch 2278 not taken.
✗ Branch 2279 not taken.
✗ Branch 2280 not taken.
✗ Branch 2281 not taken.
✗ Branch 2282 not taken.
✗ Branch 2283 not taken.
✗ Branch 2284 not taken.
✗ Branch 2285 not taken.
✗ Branch 2286 not taken.
✗ Branch 2287 not taken.
✗ Branch 2288 not taken.
✗ Branch 2289 not taken.
✗ Branch 2290 not taken.
✗ Branch 2291 not taken.
✗ Branch 2292 not taken.
✗ Branch 2293 not taken.
✗ Branch 2294 not taken.
✗ Branch 2295 not taken.
✗ Branch 2296 not taken.
✗ Branch 2297 not taken.
✗ Branch 2298 not taken.
✗ Branch 2299 not taken.
✗ Branch 2300 not taken.
✗ Branch 2301 not taken.
✗ Branch 2302 not taken.
✗ Branch 2303 not taken.
✗ Branch 2304 not taken.
✗ Branch 2305 not taken.
✗ Branch 2306 not taken.
✗ Branch 2307 not taken.
✗ Branch 2308 not taken.
✗ Branch 2309 not taken.
✗ Branch 2310 not taken.
✗ Branch 2311 not taken.
✗ Branch 2312 not taken.
✗ Branch 2313 not taken.
✗ Branch 2314 not taken.
✗ Branch 2315 not taken.
✗ Branch 2316 not taken.
✗ Branch 2317 not taken.
✗ Branch 2318 not taken.
✗ Branch 2319 not taken.
✗ Branch 2320 not taken.
✗ Branch 2321 not taken.
✗ Branch 2322 not taken.
✗ Branch 2323 not taken.
✗ Branch 2324 not taken.
✗ Branch 2325 not taken.
✗ Branch 2326 not taken.
✗ Branch 2327 not taken.
✗ Branch 2328 not taken.
✗ Branch 2329 not taken.
✗ Branch 2330 not taken.
✗ Branch 2331 not taken.
✗ Branch 2332 not taken.
✗ Branch 2333 not taken.
✗ Branch 2334 not taken.
✗ Branch 2335 not taken.
✗ Branch 2336 not taken.
✗ Branch 2337 not taken.
✗ Branch 2338 not taken.
✗ Branch 2339 not taken.
✗ Branch 2340 not taken.
✗ Branch 2341 not taken.
✗ Branch 2342 not taken.
✗ Branch 2343 not taken.
✗ Branch 2344 not taken.
✗ Branch 2345 not taken.
✗ Branch 2346 not taken.
✗ Branch 2347 not taken.
✗ Branch 2348 not taken.
✗ Branch 2349 not taken.
✗ Branch 2350 not taken.
✗ Branch 2351 not taken.
✗ Branch 2352 not taken.
✗ Branch 2353 not taken.
✗ Branch 2354 not taken.
✗ Branch 2355 not taken.
✗ Branch 2356 not taken.
✗ Branch 2357 not taken.
✗ Branch 2358 not taken.
✗ Branch 2359 not taken.
✗ Branch 2360 not taken.
✗ Branch 2361 not taken.
✗ Branch 2362 not taken.
✗ Branch 2363 not taken.
✗ Branch 2364 not taken.
✗ Branch 2365 not taken.
✗ Branch 2366 not taken.
✗ Branch 2367 not taken.
✗ Branch 2368 not taken.
✗ Branch 2369 not taken.
✗ Branch 2370 not taken.
✗ Branch 2371 not taken.
✗ Branch 2372 not taken.
✗ Branch 2373 not taken.
✗ Branch 2374 not taken.
✗ Branch 2375 not taken.
✗ Branch 2376 not taken.
✗ Branch 2377 not taken.
✗ Branch 2378 not taken.
✗ Branch 2379 not taken.
✗ Branch 2380 not taken.
✗ Branch 2381 not taken.
✗ Branch 2382 not taken.
✗ Branch 2383 not taken.
✗ Branch 2384 not taken.
✗ Branch 2385 not taken.
✗ Branch 2386 not taken.
✗ Branch 2387 not taken.
✗ Branch 2388 not taken.
✗ Branch 2389 not taken.
✗ Branch 2390 not taken.
✗ Branch 2391 not taken.
✗ Branch 2392 not taken.
✗ Branch 2393 not taken.
✗ Branch 2394 not taken.
✗ Branch 2395 not taken.
✗ Branch 2396 not taken.
✗ Branch 2397 not taken.
✗ Branch 2398 not taken.
✗ Branch 2399 not taken.
✗ Branch 2400 not taken.
✗ Branch 2401 not taken.
✗ Branch 2402 not taken.
✗ Branch 2403 not taken.
✗ Branch 2404 not taken.
✗ Branch 2405 not taken.
✗ Branch 2406 not taken.
✗ Branch 2407 not taken.
✗ Branch 2408 not taken.
✗ Branch 2409 not taken.
✗ Branch 2410 not taken.
✗ Branch 2411 not taken.
✗ Branch 2412 not taken.
✗ Branch 2413 not taken.
✗ Branch 2414 not taken.
✗ Branch 2415 not taken.
✗ Branch 2416 not taken.
✗ Branch 2417 not taken.
✗ Branch 2418 not taken.
✗ Branch 2419 not taken.
✗ Branch 2420 not taken.
✗ Branch 2421 not taken.
✗ Branch 2422 not taken.
✗ Branch 2423 not taken.
✗ Branch 2424 not taken.
✗ Branch 2425 not taken.
✗ Branch 2426 not taken.
✗ Branch 2427 not taken.
✗ Branch 2428 not taken.
✗ Branch 2429 not taken.
✗ Branch 2430 not taken.
✗ Branch 2431 not taken.
✗ Branch 2432 not taken.
✗ Branch 2433 not taken.
✗ Branch 2434 not taken.
✗ Branch 2435 not taken.
✗ Branch 2436 not taken.
✗ Branch 2437 not taken.
✗ Branch 2438 not taken.
✗ Branch 2439 not taken.
✗ Branch 2440 not taken.
✗ Branch 2441 not taken.
✗ Branch 2442 not taken.
✗ Branch 2443 not taken.
✗ Branch 2444 not taken.
✗ Branch 2445 not taken.
✗ Branch 2446 not taken.
✗ Branch 2447 not taken.
✗ Branch 2448 not taken.
✗ Branch 2449 not taken.
✗ Branch 2450 not taken.
✗ Branch 2451 not taken.
✗ Branch 2452 not taken.
✗ Branch 2453 not taken.
✗ Branch 2454 not taken.
✗ Branch 2455 not taken.
✗ Branch 2456 not taken.
✗ Branch 2457 not taken.
✗ Branch 2458 not taken.
✗ Branch 2459 not taken.
✗ Branch 2460 not taken.
✗ Branch 2461 not taken.
✗ Branch 2462 not taken.
✗ Branch 2463 not taken.
✗ Branch 2464 not taken.
✗ Branch 2465 not taken.
✗ Branch 2466 not taken.
✗ Branch 2467 not taken.
✗ Branch 2468 not taken.
✗ Branch 2469 not taken.
✗ Branch 2470 not taken.
✗ Branch 2471 not taken.
✗ Branch 2472 not taken.
✓ Branch 2473 taken 768 times.
✗ Branch 2474 not taken.
✗ Branch 2475 not taken.
✗ Branch 2476 not taken.
✓ Branch 2477 taken 916 times.
✗ Branch 2478 not taken.
✗ Branch 2479 not taken.
✗ Branch 2480 not taken.
✓ Branch 2481 taken 768 times.
✗ Branch 2482 not taken.
✗ Branch 2483 not taken.
✗ Branch 2484 not taken.
✗ Branch 2485 not taken.
✗ Branch 2486 not taken.
✗ Branch 2487 not taken.
✗ Branch 2488 not taken.
✓ Branch 2489 taken 768 times.
✗ Branch 2490 not taken.
✗ Branch 2491 not taken.
✗ Branch 2492 not taken.
✓ Branch 2493 taken 14680 times.
✗ Branch 2494 not taken.
✗ Branch 2495 not taken.
✗ Branch 2496 not taken.
✓ Branch 2497 taken 768 times.
✗ Branch 2498 not taken.
✗ Branch 2499 not taken.
✗ Branch 2500 not taken.
✗ Branch 2501 not taken.
✗ Branch 2502 not taken.
✗ Branch 2503 not taken.
✗ Branch 2504 not taken.
✗ Branch 2505 not taken.
✗ Branch 2506 not taken.
✗ Branch 2507 not taken.
✗ Branch 2508 not taken.
✗ Branch 2509 not taken.
✗ Branch 2510 not taken.
✗ Branch 2511 not taken.
✗ Branch 2512 not taken.
✗ Branch 2513 not taken.
✗ Branch 2514 not taken.
✗ Branch 2515 not taken.
✗ Branch 2516 not taken.
✗ Branch 2517 not taken.
✗ Branch 2518 not taken.
✗ Branch 2519 not taken.
✗ Branch 2520 not taken.
✗ Branch 2521 not taken.
✗ Branch 2522 not taken.
✗ Branch 2523 not taken.
✗ Branch 2524 not taken.
✗ Branch 2525 not taken.
✗ Branch 2526 not taken.
✗ Branch 2527 not taken.
✗ Branch 2528 not taken.
✓ Branch 2529 taken 1 times.
✗ Branch 2530 not taken.
✗ Branch 2531 not taken.
✗ Branch 2532 not taken.
✓ Branch 2533 taken 2 times.
✗ Branch 2534 not taken.
✗ Branch 2535 not taken.
✗ Branch 2536 not taken.
✓ Branch 2537 taken 1 times.
✗ Branch 2538 not taken.
✗ Branch 2539 not taken.
✗ Branch 2540 not taken.
✗ Branch 2541 not taken.
✗ Branch 2542 not taken.
✗ Branch 2543 not taken.
✗ Branch 2544 not taken.
✓ Branch 2545 taken 1 times.
✗ Branch 2546 not taken.
✗ Branch 2547 not taken.
✗ Branch 2548 not taken.
✓ Branch 2549 taken 4 times.
✗ Branch 2550 not taken.
✗ Branch 2551 not taken.
✗ Branch 2552 not taken.
✓ Branch 2553 taken 1 times.
✗ Branch 2554 not taken.
✗ Branch 2555 not taken.
✗ Branch 2556 not taken.
✗ Branch 2557 not taken.
✗ Branch 2558 not taken.
✗ Branch 2559 not taken.
✗ Branch 2560 not taken.
✗ Branch 2561 not taken.
✗ Branch 2562 not taken.
✗ Branch 2563 not taken.
✗ Branch 2564 not taken.
✗ Branch 2565 not taken.
✗ Branch 2566 not taken.
✗ Branch 2567 not taken.
✗ Branch 2568 not taken.
✗ Branch 2569 not taken.
✗ Branch 2570 not taken.
✗ Branch 2571 not taken.
✗ Branch 2572 not taken.
✗ Branch 2573 not taken.
✗ Branch 2574 not taken.
✗ Branch 2575 not taken.
✗ Branch 2576 not taken.
✗ Branch 2577 not taken.
✗ Branch 2578 not taken.
✗ Branch 2579 not taken.
✗ Branch 2580 not taken.
✗ Branch 2581 not taken.
✗ Branch 2582 not taken.
✗ Branch 2583 not taken.
✗ Branch 2584 not taken.
✗ Branch 2585 not taken.
✗ Branch 2586 not taken.
✗ Branch 2587 not taken.
✗ Branch 2588 not taken.
✓ Branch 2589 taken 1 times.
✗ Branch 2590 not taken.
✗ Branch 2591 not taken.
✗ Branch 2592 not taken.
✗ Branch 2593 not taken.
✗ Branch 2594 not taken.
✗ Branch 2595 not taken.
✗ Branch 2596 not taken.
✗ Branch 2597 not taken.
✗ Branch 2598 not taken.
✗ Branch 2599 not taken.
✗ Branch 2600 not taken.
✓ Branch 2601 taken 1 times.
✗ Branch 2602 not taken.
✗ Branch 2603 not taken.
✗ Branch 2604 not taken.
✗ Branch 2605 not taken.
✗ Branch 2606 not taken.
✗ Branch 2607 not taken.
✗ Branch 2608 not taken.
✗ Branch 2609 not taken.
✗ Branch 2610 not taken.
✗ Branch 2611 not taken.
✗ Branch 2612 not taken.
✓ Branch 2613 taken 1 times.
✗ Branch 2614 not taken.
✗ Branch 2615 not taken.
✗ Branch 2616 not taken.
✗ Branch 2617 not taken.
✗ Branch 2618 not taken.
✗ Branch 2619 not taken.
✗ Branch 2620 not taken.
✗ Branch 2621 not taken.
✗ Branch 2622 not taken.
✗ Branch 2623 not taken.
✗ Branch 2624 not taken.
✓ Branch 2625 taken 1 times.
✗ Branch 2626 not taken.
✗ Branch 2627 not taken.
✗ Branch 2628 not taken.
✗ Branch 2629 not taken.
✗ Branch 2630 not taken.
✗ Branch 2631 not taken.
✗ Branch 2632 not taken.
✗ Branch 2633 not taken.
✗ Branch 2634 not taken.
✗ Branch 2635 not taken.
✗ Branch 2636 not taken.
✗ Branch 2637 not taken.
✗ Branch 2638 not taken.
✗ Branch 2639 not taken.
✗ Branch 2640 not taken.
✗ Branch 2641 not taken.
✗ Branch 2642 not taken.
✗ Branch 2643 not taken.
✗ Branch 2644 not taken.
✗ Branch 2645 not taken.
✗ Branch 2646 not taken.
✗ Branch 2647 not taken.
✗ Branch 2648 not taken.
✗ Branch 2649 not taken.
✗ Branch 2650 not taken.
✗ Branch 2651 not taken.
✗ Branch 2652 not taken.
✗ Branch 2653 not taken.
✗ Branch 2654 not taken.
✗ Branch 2655 not taken.
✗ Branch 2656 not taken.
✗ Branch 2657 not taken.
✗ Branch 2658 not taken.
✗ Branch 2659 not taken.
✗ Branch 2660 not taken.
✗ Branch 2661 not taken.
✗ Branch 2662 not taken.
✗ Branch 2663 not taken.
✗ Branch 2664 not taken.
✗ Branch 2665 not taken.
✗ Branch 2666 not taken.
✗ Branch 2667 not taken.
✗ Branch 2668 not taken.
✗ Branch 2669 not taken.
✗ Branch 2670 not taken.
✗ Branch 2671 not taken.
✗ Branch 2672 not taken.
✗ Branch 2673 not taken.
✗ Branch 2674 not taken.
✗ Branch 2675 not taken.
✗ Branch 2676 not taken.
✗ Branch 2677 not taken.
✗ Branch 2678 not taken.
✓ Branch 2679 taken 36 times.
✗ Branch 2680 not taken.
✗ Branch 2681 not taken.
✗ Branch 2682 not taken.
✗ Branch 2683 not taken.
✗ Branch 2684 not taken.
✗ Branch 2685 not taken.
✗ Branch 2686 not taken.
✗ Branch 2687 not taken.
8358466 return (store_ != nullptr && !disconnected_);
1278 }
1279
1280 /**
1281 * \brief Tests whether the latest bound attribute existed already
1282 * \retval true if the latest bound attribute existed already in the
1283 * AttributeManager
1284 * \retval false if the latest bound attribute was created in the
1285 * AttributeManager when bound
1286 */
1287 bool existed_already() const {
1288 return existed_already_;
1289 }
1290
1291 /**
1292 * \brief Unbinds this Attribute.
1293 * \pre is_bound()
1294 */
1295
1/2
✓ Branch 0 taken 3372 times.
✗ Branch 1 not taken.
6743 void unbind() {
1296 geo_assert(is_bound());
1297 // If the AttributesManager was destroyed before, do not
1298 // do anything. This can occur in Lua scripting when using
1299 // Attribute wrapper objects.
1300 if(!disconnected_) {
1301 6743 unregister_me(store_);
1302 }
1303 6743 manager_ = nullptr;
1304 6743 store_ = nullptr;
1305 6743 existed_already_ = false;
1306 6743 }
1307
1308 /**
1309 * \brief Binds this Attribute to an AttributesManager.
1310 * \details If the attribute already exists with the specified
1311 * name in the AttributesManager then it is retrieved, else
1312 * it is created and bound to the name.
1313 * \param[in] manager a reference to the AttributesManager
1314 * \param[in] name name of the attribute
1315 * \pre !is_bound()
1316 */
1317
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2343 times.
2537 void bind(AttributesManager& manager, const std::string& name) {
1318 geo_assert(!is_bound());
1319 2537 manager_ = &manager;
1320 2537 store_ = manager_->find_attribute_store(name);
1321
2/2
✓ Branch 0 taken 831 times.
✓ Branch 1 taken 1512 times.
2537 if(store_ == nullptr) {
1322
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
911 store_ = new TypedAttributeStore<ST>(1,typeid(UT));
1323 911 manager_->bind_attribute_store(name,store_);
1324 911 existed_already_ = false;
1325 } else {
1326
1/6
✗ Branch 1 not taken.
✓ Branch 2 taken 1512 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
1626 geo_assert(can_bind_to(store_));
1327 1626 existed_already_ = true;
1328 }
1329 2537 register_me(store_);
1330 2537 }
1331
1332
1333 /**
1334 * \brief Binds this Attribute to an AttributesManager if it
1335 * already exists in the AttributesManager.
1336 * \param[in] manager a reference to the AttributesManager
1337 * \param[in] name name of the attribute
1338 * \pre !is_bound()
1339 * \return \c true if this Attribute was successfully bound
1340 */
1341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2728 times.
3490 bool bind_if_is_defined(
1342 AttributesManager& manager, const std::string& name
1343 ) {
1344 geo_assert(!is_bound());
1345 3490 manager_ = &manager;
1346 3490 store_ = manager_->find_attribute_store(name);
1347
2/2
✓ Branch 0 taken 331 times.
✓ Branch 1 taken 2397 times.
3490 if(store_ != nullptr) {
1348
1/6
✗ Branch 1 not taken.
✓ Branch 2 taken 331 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
480 geo_assert(can_bind_to(store_));
1349 480 register_me(store_);
1350 480 existed_already_ = true;
1351 480 return true;
1352 }
1353 3010 existed_already_ = false;
1354 3010 return false;
1355 }
1356
1357 /**
1358 * \brief Binds this Attribute to an AttributesManager if it
1359 * already exists in the AttributesManager and types are compatible.
1360 * \param[in] manager a reference to the AttributesManager
1361 * \param[in] name name of the attribute
1362 * \pre !is_bound()
1363 * \return \c true if this Attribute was successfully bound
1364 */
1365 bool bind_if_is_compatible(
1366 AttributesManager& manager, const std::string& name
1367 ) {
1368 if( is_bound() ) {
1369 unbind();
1370 }
1371 store_ = manager.find_attribute_store(name);
1372 if(store_ != nullptr) {
1373 existed_already_ = true;
1374 if(!can_bind_to(store_)) {
1375 store_ = nullptr;
1376 return false;
1377 }
1378 manager_ = &manager;
1379 register_me(store_);
1380 return true;
1381 }
1382 existed_already_ = false;
1383 return false;
1384 }
1385
1386 /**
1387 * \brief Creates and binds a new vector attribute.
1388 * \param[in] manager the attribute manager
1389 * \param[in] name the name of the attribute
1390 * \param[in] dimension the number of elements per item
1391 */
1392
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 932 times.
1864 void create_vector_attribute(
1393 AttributesManager& manager,
1394 const std::string& name,
1395 index_t dimension
1396 ) {
1397 geo_assert(!is_bound());
1398 1864 manager_ = &manager;
1399
1/6
✗ Branch 1 not taken.
✓ Branch 2 taken 932 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
1864 geo_assert(manager_->find_attribute_store(name) == nullptr);
1400 1864 store_ = new TypedAttributeStore<ST>(dimension,typeid(UT));
1401 1864 manager_->bind_attribute_store(name,store_);
1402 1864 register_me(store_);
1403 1864 }
1404
1405 /**
1406 * \brief Destroys this attribute in the AttributesManager.
1407 * \details On exit, the attribute is no-longer accessible in
1408 * the AttributesManager, its name is available again, and
1409 * this attribute is in the unbound state.
1410 */
1411
1/2
✓ Branch 0 taken 234 times.
✗ Branch 1 not taken.
468 void destroy() {
1412 geo_assert(is_bound());
1413 468 unregister_me(store_);
1414 468 manager_->delete_attribute_store(store_);
1415 468 store_ = nullptr;
1416 468 manager_ = nullptr;
1417 468 }
1418
1419 /**
1420 * \brief Sets the dimension.
1421 * \details The dimension is 1 for standard attributes and
1422 * can be greater for vector attributes. The existing
1423 * fields are kept. If the new dimension is greater than
1424 * the old one, then new fields are initialized to the default
1425 * value for the attribute type.
1426 * \param[in] new_dim the new dimension
1427 */
1428
1/2
✓ Branch 0 taken 700 times.
✗ Branch 1 not taken.
1400 void redim(index_t new_dim) {
1429 geo_assert(is_bound());
1430 1400 store_->redim(new_dim);
1431 1400 }
1432
1433 /**
1434 * \brief Attribute destructor
1435 * \details
1436 * The attribute is not destroyed, it can be retrieved later
1437 * by binding with the same name. To destroy the attribute,
1438 * use destroy() instead.
1439 */
1440 ~AttributeBase() {
1441 if(is_bound()) {
1442 1067 unbind();
1443 }
1444 }
1445
1446
1447 /**
1448 * \brief Tests whether an attribute with the specified name and with
1449 * corresponding type exists in an AttributesManager.
1450 * \param[in] manager a reference to the AttributesManager
1451 * \param[in] name the name of the attribute
1452 * \param[in] dim dimension, or 0 if any dimension can match
1453 */
1454 106 static bool is_defined(
1455 AttributesManager& manager, const std::string& name,
1456 index_t dim = 0
1457 ) {
1458 106 AttributeStore* store = manager.find_attribute_store(name);
1459 return (
1460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106 times.
106 store != nullptr &&
1461
2/4
✓ Branch 0 taken 106 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 106 times.
212 can_bind_to(store) &&
1462 ((dim == 0) || (store->dimension() == dim))
1463 106 );
1464 }
1465
1466 /**
1467 * \brief Gets the size.
1468 * \return The number of items in this attribute.
1469 */
1470 index_t size() const {
1471 return size_;
1472 }
1473
1474 /**
1475 * \brief Sets all the elements of this Attribute to
1476 * zero.
1477 */
1478 void zero() {
1479 geo_debug_assert(is_bound());
1480 store_->zero();
1481 }
1482
1483 /**
1484 * \brief Tests whether get_vector() can be called on this
1485 * Attribute.
1486 * \details get_vector() can be called if this attribute is
1487 * bound and if type T corresponds to the type used to create
1488 * the attribute.
1489 * \note Advanced users only. Most client code will not need
1490 * to use this function.
1491 */
1492 bool can_get_vector() {
1493 return(
1494 dynamic_cast<TypedAttributeStore<ST>*>(store_) != nullptr
1495 );
1496 }
1497
1498 /**
1499 * \brief Gets a reference to the internal vector<T> used to
1500 * store the attribute.
1501 * \details It is forbidden to modify the size of the returned
1502 * vector.
1503 * \return a reference to the vector<T> used to store the
1504 * attribute.
1505 * \note Advanced users only. Most client code will not need
1506 * to use this function.
1507 */
1508 vector<ST>& get_vector() {
1509 TypedAttributeStore<ST>* typed_store =
1510 dynamic_cast<TypedAttributeStore<ST>*>(store_);
1511 geo_assert(typed_store != nullptr);
1512 return typed_store->get_vector();
1513 }
1514
1515 /**
1516 * \brief Gets a const reference to the internal vector<T> used to
1517 * store the attribute.
1518 * \return a const reference to the vector<T> used to store the
1519 * attribute.
1520 */
1521 const vector<ST>& get_vector() const {
1522 TypedAttributeStore<ST>* typed_store =
1523 dynamic_cast<TypedAttributeStore<ST>*>(store_);
1524 geo_assert(typed_store != nullptr);
1525 return typed_store->get_vector();
1526 }
1527
1528 /**
1529 * \brief Gets the AttributesManager this Attribute is bound to.
1530 * \return a pointer to the attributes manager.
1531 */
1532 AttributesManager* manager() const {
1533 return manager_;
1534 }
1535
1536 protected:
1537
1538 /**
1539 * \brief Tests whether this Attribute can be bound to an AttributeStore
1540 * \param[in] store the AttributeStore
1541 * \retval true if \p store has elements with a compatible type
1542 * \retval false otherwise
1543 */
1544 2865 static bool can_bind_to(const AttributeStore* store) {
1545 return (
1546
4/10
✗ Branch 0 not taken.
✓ Branch 1 taken 1949 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1949 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1949 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1949 times.
2865 store->elements_type_matches(typeid(UT).name()) ||
1547
1/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1949 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2865 store->elements_type_matches(typeid(ST).name())
1548 2865 );
1549 }
1550
1551 protected:
1552 AttributesManager* manager_;
1553 AttributeStore* store_;
1554 bool existed_already_;
1555 } ;
1556
1557 /*********************************************************************/
1558
1559 /**
1560 * \brief Manages an attribute attached to a set of object.
1561 * \tparam T type of the attributes. Needs to be a basic type
1562 * or a plain ordinary datatype (classes that do dynamic
1563 * memory allocation are not allowed here).
1564 */
1565
21/376
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 1269 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1240 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 432 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 451 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 30 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 34 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 57 times.
✓ Branch 17 taken 3 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 285 times.
✓ Branch 20 taken 1 times.
✓ Branch 21 taken 224 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✓ Branch 76 taken 36 times.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✓ Branch 90 taken 2 times.
✗ Branch 91 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✓ Branch 132 taken 320 times.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✗ Branch 141 not taken.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✗ Branch 148 not taken.
✗ Branch 149 not taken.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✗ Branch 159 not taken.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 174 not taken.
✗ Branch 175 not taken.
✗ Branch 176 not taken.
✗ Branch 177 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✗ Branch 182 not taken.
✗ Branch 183 not taken.
✗ Branch 184 not taken.
✗ Branch 185 not taken.
✗ Branch 186 not taken.
✗ Branch 187 not taken.
✗ Branch 188 not taken.
✗ Branch 189 not taken.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✗ Branch 196 not taken.
✗ Branch 197 not taken.
✗ Branch 198 not taken.
✗ Branch 199 not taken.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✗ Branch 203 not taken.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✗ Branch 207 not taken.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✗ Branch 211 not taken.
✗ Branch 212 not taken.
✗ Branch 213 not taken.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✗ Branch 219 not taken.
✗ Branch 224 not taken.
✗ Branch 225 not taken.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✗ Branch 228 not taken.
✗ Branch 229 not taken.
✓ Branch 230 taken 4 times.
✗ Branch 231 not taken.
✗ Branch 234 not taken.
✗ Branch 235 not taken.
✗ Branch 236 not taken.
✗ Branch 237 not taken.
✗ Branch 244 not taken.
✗ Branch 245 not taken.
✗ Branch 246 not taken.
✗ Branch 247 not taken.
✗ Branch 248 not taken.
✗ Branch 249 not taken.
✗ Branch 250 not taken.
✗ Branch 251 not taken.
✗ Branch 252 not taken.
✗ Branch 253 not taken.
✗ Branch 254 not taken.
✗ Branch 255 not taken.
✗ Branch 256 not taken.
✗ Branch 257 not taken.
✗ Branch 258 not taken.
✗ Branch 259 not taken.
✗ Branch 264 not taken.
✗ Branch 265 not taken.
✗ Branch 266 not taken.
✗ Branch 267 not taken.
✗ Branch 268 not taken.
✗ Branch 269 not taken.
✗ Branch 270 not taken.
✗ Branch 271 not taken.
✓ Branch 272 taken 640 times.
✗ Branch 273 not taken.
✗ Branch 274 not taken.
✗ Branch 275 not taken.
✗ Branch 276 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✗ Branch 279 not taken.
✗ Branch 280 not taken.
✗ Branch 281 not taken.
✗ Branch 282 not taken.
✗ Branch 283 not taken.
✗ Branch 286 not taken.
✗ Branch 287 not taken.
✗ Branch 288 not taken.
✗ Branch 289 not taken.
✗ Branch 294 not taken.
✗ Branch 295 not taken.
✗ Branch 296 not taken.
✗ Branch 297 not taken.
✗ Branch 298 not taken.
✗ Branch 299 not taken.
✗ Branch 300 not taken.
✗ Branch 301 not taken.
✗ Branch 304 not taken.
✗ Branch 305 not taken.
✗ Branch 306 not taken.
✗ Branch 307 not taken.
✗ Branch 314 not taken.
✗ Branch 315 not taken.
✗ Branch 316 not taken.
✗ Branch 317 not taken.
✗ Branch 318 not taken.
✗ Branch 319 not taken.
✗ Branch 320 not taken.
✗ Branch 321 not taken.
✗ Branch 322 not taken.
✗ Branch 323 not taken.
✗ Branch 324 not taken.
✗ Branch 325 not taken.
✗ Branch 326 not taken.
✗ Branch 327 not taken.
✗ Branch 328 not taken.
✗ Branch 329 not taken.
✗ Branch 334 not taken.
✗ Branch 335 not taken.
✗ Branch 336 not taken.
✗ Branch 337 not taken.
✗ Branch 338 not taken.
✗ Branch 339 not taken.
✗ Branch 340 not taken.
✗ Branch 341 not taken.
✗ Branch 342 not taken.
✗ Branch 343 not taken.
✗ Branch 344 not taken.
✗ Branch 345 not taken.
✗ Branch 346 not taken.
✗ Branch 347 not taken.
✗ Branch 348 not taken.
✗ Branch 349 not taken.
✗ Branch 350 not taken.
✗ Branch 351 not taken.
✗ Branch 352 not taken.
✗ Branch 353 not taken.
✗ Branch 356 not taken.
✗ Branch 357 not taken.
✗ Branch 358 not taken.
✗ Branch 359 not taken.
✗ Branch 364 not taken.
✗ Branch 365 not taken.
✗ Branch 366 not taken.
✗ Branch 367 not taken.
✗ Branch 368 not taken.
✗ Branch 369 not taken.
✗ Branch 370 not taken.
✗ Branch 371 not taken.
✗ Branch 374 not taken.
✗ Branch 375 not taken.
✗ Branch 376 not taken.
✗ Branch 377 not taken.
✗ Branch 384 not taken.
✗ Branch 385 not taken.
✗ Branch 386 not taken.
✗ Branch 387 not taken.
✗ Branch 388 not taken.
✗ Branch 389 not taken.
✗ Branch 390 not taken.
✗ Branch 391 not taken.
✗ Branch 392 not taken.
✗ Branch 393 not taken.
✗ Branch 394 not taken.
✗ Branch 395 not taken.
✗ Branch 396 not taken.
✗ Branch 397 not taken.
✗ Branch 398 not taken.
✗ Branch 399 not taken.
✗ Branch 404 not taken.
✗ Branch 405 not taken.
✗ Branch 406 not taken.
✗ Branch 407 not taken.
✗ Branch 408 not taken.
✗ Branch 409 not taken.
✗ Branch 410 not taken.
✗ Branch 411 not taken.
✗ Branch 412 not taken.
✗ Branch 413 not taken.
✗ Branch 414 not taken.
✗ Branch 415 not taken.
✗ Branch 416 not taken.
✗ Branch 417 not taken.
✗ Branch 418 not taken.
✗ Branch 419 not taken.
✗ Branch 420 not taken.
✗ Branch 421 not taken.
✗ Branch 422 not taken.
✗ Branch 423 not taken.
✗ Branch 426 not taken.
✗ Branch 427 not taken.
✗ Branch 428 not taken.
✗ Branch 429 not taken.
✗ Branch 434 not taken.
✗ Branch 435 not taken.
✗ Branch 436 not taken.
✗ Branch 437 not taken.
✗ Branch 438 not taken.
✗ Branch 439 not taken.
✗ Branch 440 not taken.
✗ Branch 441 not taken.
✗ Branch 444 not taken.
✗ Branch 445 not taken.
✗ Branch 446 not taken.
✗ Branch 447 not taken.
✗ Branch 454 not taken.
✗ Branch 455 not taken.
✗ Branch 456 not taken.
✗ Branch 457 not taken.
✗ Branch 458 not taken.
✗ Branch 459 not taken.
✗ Branch 460 not taken.
✗ Branch 461 not taken.
✗ Branch 462 not taken.
✗ Branch 463 not taken.
✗ Branch 464 not taken.
✗ Branch 465 not taken.
✗ Branch 466 not taken.
✗ Branch 467 not taken.
✗ Branch 468 not taken.
✗ Branch 469 not taken.
✗ Branch 474 not taken.
✗ Branch 475 not taken.
✗ Branch 476 not taken.
✗ Branch 477 not taken.
✗ Branch 478 not taken.
✗ Branch 479 not taken.
✗ Branch 480 not taken.
✗ Branch 481 not taken.
✗ Branch 482 not taken.
✗ Branch 483 not taken.
✗ Branch 484 not taken.
✗ Branch 485 not taken.
✗ Branch 486 not taken.
✗ Branch 487 not taken.
✗ Branch 488 not taken.
✗ Branch 489 not taken.
✗ Branch 490 not taken.
✗ Branch 491 not taken.
✗ Branch 492 not taken.
✓ Branch 493 taken 86 times.
✗ Branch 495 not taken.
✗ Branch 496 not taken.
3674 template <class T> class Attribute : public AttributeBase<T> {
1566 public:
1567 typedef AttributeBase<T> superclass;
1568
1569 /**
1570 * \brief Creates an uninitialized (unbound) Attribute.
1571 */
1572 Attribute() : superclass() {
1573 }
1574
1575 /**
1576 * \brief Creates or retrieves a persistent attribute attached to
1577 * a given AttributesManager.
1578 * \details If the attribute already exists with the specified
1579 * name in the AttributesManager then it is retrieved, else
1580 * it is created and bound to the name.
1581 * \param[in] manager a reference to the AttributesManager
1582 * \param[in] name name of the attribute
1583 */
1584 Attribute(AttributesManager& manager, const std::string& name) :
1585
1/2
✓ Branch 1 taken 345 times.
✗ Branch 2 not taken.
345 superclass(manager, name) {
1586 766 }
1587
1588 /**
1589 * \brief Gets a modifiable element by index
1590 * \param [in] i index of the element
1591 * \return a modifiable reference to the \p i%th element
1592 */
1593 T& operator[](index_t i) {
1594 geo_debug_assert(superclass::is_bound());
1595 geo_debug_assert(i < superclass::nb_elements());
1596
44/59
✓ Branch 0 taken 82339 times.
✓ Branch 1 taken 1076592 times.
✓ Branch 2 taken 831639 times.
✓ Branch 3 taken 1626485 times.
✓ Branch 4 taken 3232 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 146826 times.
✓ Branch 7 taken 35314 times.
✓ Branch 8 taken 100192 times.
✓ Branch 9 taken 30633 times.
✓ Branch 10 taken 453985 times.
✓ Branch 11 taken 6 times.
✓ Branch 12 taken 441 times.
✓ Branch 13 taken 4635 times.
✓ Branch 14 taken 3500 times.
✓ Branch 15 taken 1234 times.
✓ Branch 16 taken 60507 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1052 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 36 times.
✓ Branch 21 taken 175956 times.
✓ Branch 22 taken 36 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 55809 times.
✓ Branch 25 taken 120183 times.
✓ Branch 26 taken 54962 times.
✓ Branch 27 taken 847 times.
✓ Branch 28 taken 120147 times.
✓ Branch 29 taken 407829 times.
✓ Branch 30 taken 118286 times.
✓ Branch 31 taken 1861 times.
✓ Branch 32 taken 175992 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 76264 times.
✓ Branch 35 taken 99729 times.
✓ Branch 36 taken 49804 times.
✓ Branch 37 taken 126188 times.
✓ Branch 38 taken 49039 times.
✓ Branch 39 taken 766 times.
✓ Branch 40 taken 81288 times.
✓ Branch 41 taken 1 times.
✓ Branch 42 taken 94704 times.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✓ Branch 48 taken 104878 times.
✓ Branch 49 taken 112188 times.
✓ Branch 50 taken 210409 times.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✓ Branch 54 taken 57599 times.
✓ Branch 55 taken 24897 times.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✓ Branch 62 taken 64430 times.
✗ Branch 63 not taken.
228552238 return ((T*)(void*)superclass::base_addr_)[i];
1597 }
1598
1599 /**
1600 * \brief Gets an element by index
1601 * \param [in] i index of the element
1602 * \return a const reference to the \p i%th element
1603 */
1604 const T& operator[](index_t i) const {
1605 geo_debug_assert(superclass::is_bound());
1606 geo_debug_assert(i < superclass::nb_elements());
1607
106/240
✓ Branch 0 taken 31357 times.
✓ Branch 1 taken 153892 times.
✓ Branch 2 taken 55809 times.
✓ Branch 3 taken 885542 times.
✓ Branch 4 taken 629922 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 23877 times.
✓ Branch 9 taken 152115 times.
✓ Branch 10 taken 94704 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 69653 times.
✓ Branch 14 taken 147413 times.
✓ Branch 15 taken 5353 times.
✓ Branch 16 taken 27074 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 3493 times.
✓ Branch 19 taken 23581 times.
✓ Branch 20 taken 300 times.
✓ Branch 21 taken 150739 times.
✓ Branch 22 taken 657051 times.
✓ Branch 23 taken 74430 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 300 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✓ Branch 32 taken 300 times.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✓ Branch 35 taken 20000 times.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 300 times.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✓ Branch 50 taken 80 times.
✓ Branch 51 taken 444 times.
✓ Branch 52 taken 2045 times.
✓ Branch 53 taken 2050 times.
✓ Branch 54 taken 2121 times.
✓ Branch 55 taken 2050 times.
✓ Branch 56 taken 356 times.
✓ Branch 57 taken 320 times.
✓ Branch 58 taken 159 times.
✓ Branch 59 taken 197 times.
✓ Branch 60 taken 102 times.
✓ Branch 61 taken 218 times.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✓ Branch 136 taken 518 times.
✓ Branch 137 taken 444 times.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✓ Branch 140 taken 108 times.
✓ Branch 141 taken 528 times.
✓ Branch 142 taken 5713 times.
✓ Branch 143 taken 3929 times.
✓ Branch 144 taken 4692 times.
✓ Branch 145 taken 3929 times.
✓ Branch 146 taken 392 times.
✓ Branch 147 taken 429 times.
✓ Branch 148 taken 165 times.
✓ Branch 149 taken 227 times.
✓ Branch 150 taken 124 times.
✓ Branch 151 taken 305 times.
✓ Branch 152 taken 93 times.
✓ Branch 153 taken 501 times.
✓ Branch 154 taken 4730 times.
✓ Branch 155 taken 3792 times.
✓ Branch 156 taken 4400 times.
✓ Branch 157 taken 3792 times.
✓ Branch 158 taken 378 times.
✓ Branch 159 taken 427 times.
✓ Branch 160 taken 135 times.
✓ Branch 161 taken 243 times.
✓ Branch 162 taken 156 times.
✓ Branch 163 taken 271 times.
✓ Branch 164 taken 93 times.
✓ Branch 165 taken 462 times.
✓ Branch 166 taken 3783 times.
✓ Branch 167 taken 3949 times.
✓ Branch 168 taken 4965 times.
✓ Branch 169 taken 3949 times.
✓ Branch 170 taken 358 times.
✓ Branch 171 taken 409 times.
✓ Branch 172 taken 130 times.
✓ Branch 173 taken 228 times.
✓ Branch 174 taken 135 times.
✓ Branch 175 taken 274 times.
✓ Branch 176 taken 85 times.
✓ Branch 177 taken 468 times.
✓ Branch 178 taken 4331 times.
✓ Branch 179 taken 3886 times.
✓ Branch 180 taken 4432 times.
✓ Branch 181 taken 3886 times.
✓ Branch 182 taken 338 times.
✓ Branch 183 taken 407 times.
✓ Branch 184 taken 141 times.
✓ Branch 185 taken 197 times.
✓ Branch 186 taken 126 times.
✓ Branch 187 taken 281 times.
✓ Branch 188 taken 89 times.
✓ Branch 189 taken 508 times.
✓ Branch 190 taken 6464 times.
✓ Branch 191 taken 5264 times.
✓ Branch 192 taken 6826 times.
✓ Branch 193 taken 5264 times.
✓ Branch 194 taken 376 times.
✓ Branch 195 taken 471 times.
✓ Branch 196 taken 143 times.
✓ Branch 197 taken 233 times.
✓ Branch 198 taken 154 times.
✓ Branch 199 taken 317 times.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✗ Branch 203 not taken.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✗ Branch 207 not taken.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✗ Branch 211 not taken.
✗ Branch 212 not taken.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✗ Branch 215 not taken.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✗ Branch 219 not taken.
✓ Branch 220 taken 521 times.
✓ Branch 221 taken 528 times.
✗ Branch 222 not taken.
✗ Branch 223 not taken.
✓ Branch 224 taken 470 times.
✓ Branch 225 taken 501 times.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✓ Branch 228 taken 518 times.
✓ Branch 229 taken 462 times.
✗ Branch 230 not taken.
✗ Branch 231 not taken.
✓ Branch 232 taken 540 times.
✓ Branch 233 taken 468 times.
✗ Branch 234 not taken.
✗ Branch 235 not taken.
✓ Branch 236 taken 540 times.
✓ Branch 237 taken 508 times.
✗ Branch 238 not taken.
✗ Branch 239 not taken.
73460883 return ((const T*)(void*)superclass::base_addr_)[i];
1608 }
1609
1610 /**
1611 * \brief Sets all the elements in this attribute
1612 * to a specified value.
1613 * \param[in] val the value
1614 */
1615 void fill(const T& val) {
1616 geo_debug_assert(superclass::is_bound());
1617 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1618 (*this)[i] = val;
1619 }
1620 }
1621
1622 /**
1623 * \brief Copies all the values from another attribute.
1624 * \param[in] rhs the attribute to be copied.
1625 * \details rhs needs to have the same size and dimension
1626 * as this Attribute.
1627 */
1628 void copy(const Attribute<T>& rhs) {
1629 geo_assert(rhs.size() == superclass::size());
1630 geo_assert(rhs.dimension() == superclass::dimension());
1631 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1632 (*this)[i] = rhs[i];
1633 }
1634 }
1635
1636 /**
1637 * \brief Gets the pointer to the data.
1638 * \return a pointer to the stored array.
1639 */
1640 T* data() {
1641 return (T*)AttributeStoreObserver::base_addr_;
1642 }
1643
1644 /**
1645 * \brief Gets the pointer to the data.
1646 * \return a const pointer to the stored array.
1647 */
1648 const T* data() const {
1649 return (const T*)AttributeStoreObserver::base_addr_;
1650 }
1651
1652
1653 private:
1654 /**
1655 * \brief Forbids copy.
1656 */
1657 Attribute(const Attribute<T>& rhs) = delete;
1658 /**
1659 * \brief Forbids copy.
1660 */
1661 Attribute<T>& operator=(const Attribute<T>& rhs) = delete;
1662 };
1663
1664 /*********************************************************************/
1665
1666 /**
1667 * \brief Specialization of Attribute for booleans
1668 * \details Attribute needs a specialization for bool, since
1669 * vector<bool> uses compressed storage (1 bit per boolean),
1670 * that is not compatible with the attribute management
1671 * mechanism. This wrapper class uses an Attribute<Numeric::uint8>
1672 * and does the appropriate conversions, using an accessor class.
1673 */
1674
4/8
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 5 taken 57 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 60 times.
✗ Branch 8 not taken.
233 template <> class Attribute<bool> :
1675 public AttributeBase<bool,Numeric::uint8> {
1676 public:
1677 typedef AttributeBase<bool,Numeric::uint8> superclass;
1678
1679 Attribute() : superclass() {
1680 }
1681
1682 Attribute(AttributesManager& manager, const std::string& name) :
1683
3/6
✓ Branch 1 taken 285 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 285 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 285 times.
✗ Branch 8 not taken.
855 superclass(manager,name) {
1684 1028 }
1685
1686 class BoolAttributeAccessor;
1687
1688 /**
1689 * \brief Accessor class for adapting Attribute<bool>
1690 * indexing.
1691 */
1692 class ConstBoolAttributeAccessor {
1693 public:
1694 /**
1695 * \brief ConstBoolAttributeAccessor constructor.
1696 */
1697 ConstBoolAttributeAccessor(
1698 const Attribute<bool>& attribute,
1699 index_t index
1700 ) :
1701 attribute_(&attribute),
1702 index_(index) {
1703 }
1704
1705 /**
1706 * \brief Converts a BoolAttributeAccessor to a bool.
1707 * \details Performs the actual lookup.
1708 */
1709 operator bool() const {
1710 518360 return (attribute_->element(index_) != 0);
1711 }
1712
1713 private:
1714 const Attribute<bool>* attribute_;
1715 index_t index_;
1716
1717 friend class BoolAttributeAccessor;
1718 };
1719
1720 /**
1721 * \brief Accessor class for adapting Attribute<bool>
1722 * indexing.
1723 */
1724 class BoolAttributeAccessor {
1725 public:
1726 /**
1727 * \brief BoolAttributeAccessor constructor.
1728 */
1729 BoolAttributeAccessor(
1730 Attribute<bool>& attribute,
1731 index_t index
1732 ) :
1733 attribute_(&attribute),
1734 index_(index) {
1735 }
1736
1737 /**
1738 * \brief Converts a BoolAttributeAccessor to a bool.
1739 * \details Performs the actual lookup.
1740 */
1741 operator bool() const {
1742 2065086 return (attribute_->element(index_) != 0);
1743 }
1744
1745 /**
1746 * \brief Copy-constructor.
1747 * \param[in] rhs a const reference to the
1748 * BoolAttributeAccessor to be copied.
1749 */
1750 BoolAttributeAccessor(const BoolAttributeAccessor& rhs) {
1751 attribute_ = rhs.attribute_;
1752 index_ = rhs.index_;
1753 }
1754
1755 /**
1756 * \brief Assigns a bool to a BoolAttributeAccessor.
1757 * \details Stores the boolean into the Attribute.
1758 */
1759 BoolAttributeAccessor& operator=(bool x) {
1760 1776874 attribute_->element(index_) = Numeric::uint8(x);
1761 return *this;
1762 }
1763
1764 /**
1765 * \brief Copies a bool from another attribute.
1766 * \param[in] rhs a const reference to the BoolAttributeAccessor
1767 * to be copied.
1768 */
1769 BoolAttributeAccessor& operator=(
1770 const BoolAttributeAccessor& rhs
1771 ) {
1772 if(&rhs != this) {
1773 attribute_->element(index_) =
1774 rhs.attribute_->element(rhs.index_);
1775 }
1776 return *this;
1777 }
1778
1779 /**
1780 * \brief Copies a bool from another attribute.
1781 * \param[in] rhs a const reference to the
1782 * ConstBoolAttributeAccessor to be copied.
1783 */
1784 BoolAttributeAccessor& operator=(
1785 const ConstBoolAttributeAccessor& rhs
1786 ) {
1787 attribute_->element(index_) =
1788 rhs.attribute_->element(rhs.index_);
1789 return *this;
1790 }
1791
1792 private:
1793 Attribute<bool>* attribute_;
1794 index_t index_;
1795 };
1796
1797
1798 BoolAttributeAccessor operator[](index_t i) {
1799 return BoolAttributeAccessor(*this,i);
1800 }
1801
1802 ConstBoolAttributeAccessor operator[](index_t i) const {
1803 return ConstBoolAttributeAccessor(*this,i);
1804 }
1805
1806 /**
1807 * \brief Sets all the elements in this attribute
1808 * to a specified value.
1809 * \param[in] val the value
1810 */
1811 void fill(bool val) {
1812 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1813 element(i) = Numeric::uint8(val);
1814 }
1815 }
1816
1817 /**
1818 * \brief Copies all the values from another attribute.
1819 * \param[in] rhs the attribute to be copied.
1820 * \details rhs needs to have the same size and dimension
1821 * as this Attribute.
1822 */
1823 void copy(const Attribute<bool>& rhs) {
1824 geo_assert(rhs.size() == superclass::size());
1825 geo_assert(rhs.dimension() == superclass::dimension());
1826 for(index_t i=0; i<superclass::nb_elements(); ++i) {
1827 element(i) = rhs.element(i);
1828 }
1829 }
1830
1831 protected:
1832
1833 friend class BoolAttributeAccessor;
1834 friend class ConstBoolAttributeAccessor;
1835
1836 /**
1837 * \brief Gets a modifiable element by index
1838 * \param [in] i index of the element
1839 * \return a modifiable reference to the \p i%th element
1840 */
1841 Numeric::uint8& element(index_t i) {
1842 geo_debug_assert(i < superclass::nb_elements());
1843
13/14
✓ Branch 0 taken 43473 times.
✓ Branch 1 taken 8386 times.
✓ Branch 2 taken 7213 times.
✓ Branch 3 taken 957 times.
✓ Branch 4 taken 43475 times.
✓ Branch 5 taken 8386 times.
✓ Branch 6 taken 100816 times.
✓ Branch 7 taken 493824 times.
✓ Branch 8 taken 247128 times.
✓ Branch 9 taken 493824 times.
✓ Branch 10 taken 71166 times.
✓ Branch 11 taken 175962 times.
✓ Branch 12 taken 370476 times.
✗ Branch 13 not taken.
3594832 return ((Numeric::uint8*)superclass::base_addr_)[i];
1844 }
1845
1846 /**
1847 * \brief Gets an element by index
1848 * \param [in] i index of the element
1849 * \return a const reference to the \p i%th element
1850 */
1851 const Numeric::uint8& element(index_t i) const {
1852 geo_debug_assert(i < superclass::nb_elements());
1853
2/2
✓ Branch 0 taken 374065 times.
✓ Branch 1 taken 144295 times.
518360 return ((const Numeric::uint8*)superclass::base_addr_)[i];
1854 }
1855
1856 private:
1857 /**
1858 * \brief Forbids copy.
1859 */
1860 Attribute(const Attribute<bool>& rhs) = delete;
1861 /**
1862 * \brief Forbids copy.
1863 */
1864 Attribute<bool>& operator=(const Attribute<bool>& rhs) = delete;
1865 } ;
1866
1867 /***********************************************************/
1868
1869 /**
1870 * \brief Access to an attribute as a double regardless its type.
1871 * \details The attribute can be an element of a vector attribute.
1872 */
1873 class GEOGRAM_API ScalarAttributeAdapterBase :
1874 public AttributeStoreObserver {
1875
1876 public:
1877 /**
1878 * \brief Internal representation of the attribute.
1879 */
1880 enum ElementType {
1881 ET_NONE=0,
1882 ET_UINT8=1,
1883 ET_INT8=2,
1884 ET_UINT32=3,
1885 ET_INT32=4,
1886 ET_FLOAT32=5,
1887 ET_FLOAT64=6,
1888 ET_VEC2=7,
1889 ET_VEC3=8
1890 };
1891
1892
1893 /**
1894 * \brief Accessor class used by ScalarAttributeAdapter to
1895 * implement indexing operator.
1896 */
1897 class Accessor {
1898 public:
1899 Accessor(
1900 ScalarAttributeAdapterBase& attribute,
1901 index_t index
1902 ) : attribute_(attribute), index_(index) {
1903 }
1904
1905 operator double() const {
1906 return attribute_.get_element_as_double(index_);
1907 }
1908
1909 void operator=(double x) {
1910 attribute_.set_element_as_double(index_, x);
1911 }
1912
1913 private:
1914 ScalarAttributeAdapterBase& attribute_;
1915 index_t index_;
1916 };
1917
1918 /**
1919 * \brief Accessor class used by ScalarAttributeAdapter to
1920 * implement indexing operator (const version).
1921 */
1922 class ConstAccessor {
1923 public:
1924 ConstAccessor(
1925 const ScalarAttributeAdapterBase& attribute,
1926 index_t index
1927 ) : attribute_(attribute), index_(index) {
1928 }
1929
1930 operator double() const {
1931 return attribute_.get_element_as_double(index_);
1932 }
1933
1934 private:
1935 const ScalarAttributeAdapterBase& attribute_;
1936 index_t index_;
1937 };
1938
1939 /**
1940 * \brief ScalarAttributeAdapterBase constructor.
1941 */
1942 ScalarAttributeAdapterBase() :
1943 manager_(nullptr),
1944 store_(nullptr),
1945 element_type_(ET_NONE),
1946 element_index_(index_t(-1)) {
1947 }
1948
1949 /**
1950 * \brief ScalarAttributeAdapterBase constructor.
1951 * \details Retrieves a persistent attribute attached to
1952 * a given AttributesManager.
1953 * \param[in] manager a reference to the AttributesManager
1954 * \param[in] name name of the attribute with an optional index,
1955 * for instance, "foobar[5]" refers to the 5th coordinate of
1956 * the "foobar" vector attribute.
1957 */
1958 ScalarAttributeAdapterBase(
1959 const AttributesManager& manager, const std::string& name
1960 ) :
1961 manager_(nullptr),
1962 store_(nullptr) {
1963 bind_if_is_defined(manager, name);
1964 }
1965
1966 /**
1967 * \brief Tests whether an Attribute is bound.
1968 * \retval true if this Attribute is bound
1969 * \retval false otherwise
1970 */
1971 bool is_bound() const {
1972 return (store_ != nullptr);
1973 }
1974
1975 /**
1976 * \brief Unbinds this Attribute.
1977 * \pre is_bound()
1978 */
1979 void unbind() {
1980 geo_assert(is_bound());
1981 unregister_me(const_cast<AttributeStore*>(store_));
1982 manager_ = nullptr;
1983 store_ = nullptr;
1984 element_type_ = ET_NONE;
1985 element_index_ = index_t(-1);
1986 }
1987
1988 /**
1989 * \brief Binds this Attribute to an AttributesManager if it
1990 * already exists in the AttributesManager.
1991 * \param[in] manager a reference to the AttributesManager
1992 * \param[in] name name of the attribute with an optional index,
1993 * for instance, "foobar[5]" refers to the 5th coordinate of
1994 * the "foobar" vector attribute.
1995 * \pre !is_bound()
1996 */
1997 void bind_if_is_defined(
1998 const AttributesManager& manager, const std::string& name
1999 );
2000
2001 /**
2002 * \brief ReadonlyScalarAttributeAdapterBase destructor
2003 * \details
2004 * The attribute is not destroyed, it can be retrieved later
2005 * by binding with the same name. To destroy the attribute,
2006 * use destroy() instead.
2007 */
2008 ~ScalarAttributeAdapterBase() {
2009 if(is_bound()) {
2010 unbind();
2011 }
2012 }
2013
2014 /**
2015 * \brief Tests whether an attribute with the specified name and with
2016 * a type that can be converted to double exists in an
2017 * AttributesManager.
2018 * \param[in] manager a reference to the AttributesManager
2019 * \param[in] name the name of the attribute with an optional index,
2020 * for instance, "foobar[5]" refers to the 5th coordinate of
2021 * the "foobar" vector attribute.
2022 */
2023 static bool is_defined(
2024 const AttributesManager& manager, const std::string& name
2025 );
2026
2027 /**
2028 * \brief Gets the size.
2029 * \return The number of items in this attribute.
2030 */
2031 index_t size() const {
2032 return (store_ == nullptr) ? 0 : store_->size();
2033 }
2034
2035 /**
2036 * \brief Gets the internal representation of the
2037 * elements.
2038 * \return one of ET_NONE (if unbound), ET_UINT8,
2039 * ET_INT8, ET_UINT32, ET_INT32, ET_FLOAT32,
2040 * ET_FLOAT64, ET_VEC2, ET_VEC3
2041 */
2042 ElementType element_type() const {
2043 return element_type_;
2044 }
2045
2046 /**
2047 * \brief Gets the element index.
2048 * \return the index of the elements accessed in
2049 * the bound attribute, or 0 if the bound attribute
2050 * is scalar.
2051 */
2052 index_t element_index() const {
2053 return element_index_;
2054 }
2055
2056 /**
2057 * \brief Gets the AttributeStore.
2058 * \return a const pointer to the AttributeStore.
2059 */
2060 const AttributeStore* attribute_store() const {
2061 return store_;
2062 }
2063
2064
2065 /**
2066 * \brief Tests whether a ScalarAttributeAdapterBase can
2067 * be bound to a given attribute store.
2068 * \param[in] store a pointer to the attribute store.
2069 * \retval true if it can be bound
2070 * \retval false otherwise
2071 */
2072 static bool can_be_bound_to(const AttributeStore* store) {
2073 return element_type(store) != ET_NONE;
2074 }
2075
2076 /**
2077 * \brief Gets the number of scalar components per item in an
2078 * AttributeStore.
2079 * \param[in] store a pointer to the attribute store.
2080 * \return the number of scalar components per item in an
2081 * AttributeStore.
2082 */
2083 static index_t nb_scalar_elements_per_item(const AttributeStore* store);
2084
2085 protected:
2086 /**
2087 * \brief Gets the base attribute name from a compound name.
2088 * \param[in] name the string with the attribute name and optional
2089 * index. For instance, "foobar[5]" refers to the 5th coordinate of
2090 * the "foobar" vector attribute.
2091 * \return the attribute name. For instance, for "foobar[5]", it
2092 * returns "foobar".
2093 */
2094 static std::string attribute_base_name(const std::string& name);
2095
2096 /**
2097 * \brief Gets the base attribute name from a compound name.
2098 * \param[in] name the string with the attribute name and optional
2099 * index. For instance, "foobar[5]" refers to the 5th coordinate of
2100 * the "foobar" vector attribute.
2101 * \return the index or zero if no index was specified. For instance,
2102 * for "foobar[5]" it returns 5, and for "foobar" it returns 0
2103 */
2104 static index_t attribute_element_index(const std::string& name);
2105
2106 /**
2107 * \brief Gets the element type stored in an AttributeStore.
2108 * \param[in] store a const pointer to the AttributeStore
2109 * \return one of ET_UINT8, ET_INT8, ET_UINT32, ET_INT32,
2110 * ET_FLOAT32, ET_FLOAT64 if the type of the attribute is
2111 * compatible with those types, or ET_NONE if it is incompatible.
2112 */
2113 static ElementType element_type(const AttributeStore* store);
2114
2115 /**
2116 * \brief Gets an attribute value
2117 * \param[in] i the index of the item
2118 * \return the value of the property, convertex
2119 * into a double
2120 * \pre is_bound() && i < size()
2121 */
2122 double get_element_as_double(index_t i) const {
2123 double result = 0.0;
2124 switch(element_type()) {
2125 case ET_UINT8:
2126 result = double(get_element<Numeric::uint8>(i));
2127 break;
2128 case ET_INT8:
2129 result = double(get_element<Numeric::int8>(i));
2130 break;
2131 case ET_UINT32:
2132 result = double(get_element<Numeric::uint32>(i));
2133 break;
2134 case ET_INT32:
2135 result = double(get_element<Numeric::int32>(i));
2136 break;
2137 case ET_FLOAT32:
2138 result = double(get_element<Numeric::float32>(i));
2139 break;
2140 case ET_FLOAT64:
2141 result = double(get_element<Numeric::float64>(i));
2142 break;
2143 case ET_VEC2:
2144 result = double(get_element<Numeric::float64>(i,2));
2145 break;
2146 case ET_VEC3:
2147 result = double(get_element<Numeric::float64>(i,3));
2148 break;
2149 case ET_NONE:
2150 geo_assert_not_reached;
2151 }
2152 return result;
2153 }
2154
2155 /**
2156 * \brief Gets an element.
2157 * \details Stored element type needs to match T,
2158 * no verification is made
2159 * \param[in] i index of the element
2160 * \param[in] multiplier multiplier applied to the index before fetching
2161 * the raw pointer.
2162 */
2163 template <class T> T get_element(index_t i,index_t multiplier=1) const {
2164 geo_debug_assert(is_bound());
2165 geo_debug_assert(i < size());
2166 return static_cast<const T*>(store_->data())[
2167 (i * store_->dimension() * multiplier) +
2168 element_index_
2169 ];
2170 }
2171
2172 /**
2173 * \brief Sets an attribute value
2174 * \param[in] i the index of the element
2175 * \param[in] value the new value of the element
2176 * \pre is_bound() && i < size()
2177 */
2178 double set_element_as_double(index_t i, double value) {
2179 double result = 0.0;
2180 switch(element_type()) {
2181 case ET_UINT8:
2182 set_element<Numeric::uint8>(Numeric::uint8(value), i);
2183 break;
2184 case ET_INT8:
2185 set_element<Numeric::int8>(Numeric::int8(value),i);
2186 break;
2187 case ET_UINT32:
2188 set_element<Numeric::uint32>(Numeric::uint32(value),i);
2189 break;
2190 case ET_INT32:
2191 set_element<Numeric::int32>(Numeric::int32(value),i);
2192 break;
2193 case ET_FLOAT32:
2194 set_element<Numeric::float32>(Numeric::float32(value),i);
2195 break;
2196 case ET_FLOAT64:
2197 set_element<Numeric::float64>(Numeric::float64(value),i);
2198 break;
2199 case ET_VEC2:
2200 set_element<Numeric::float64>(Numeric::float64(value),i,2);
2201 break;
2202 case ET_VEC3:
2203 set_element<Numeric::float64>(Numeric::float64(value),i,3);
2204 break;
2205 case ET_NONE:
2206 geo_assert_not_reached;
2207 }
2208 return result;
2209 }
2210
2211 /**
2212 * \brief Sets an element.
2213 * \details Stored element type needs to match T,
2214 * no verification is made
2215 * \param[in] value the value of the element to be stored
2216 * \param[in] i index of the element
2217 * \param[in] multiplier multiplier applied to the index before fetching
2218 * the raw pointer.
2219 */
2220 template <class T> void set_element(
2221 T value, index_t i, index_t multiplier=1
2222 ) const {
2223 geo_debug_assert(is_bound());
2224 geo_debug_assert(i < size());
2225 const_cast<T*>(static_cast<const T*>(store_->data()))[
2226 (i * store_->dimension() * multiplier) +
2227 element_index_
2228 ] = value;
2229 }
2230
2231 protected:
2232 const AttributesManager* manager_;
2233 const AttributeStore* store_;
2234 ElementType element_type_;
2235 index_t element_index_;
2236 };
2237
2238 /***********************************************************/
2239
2240 /**
2241 * \brief Readonly access to an attribute as a double regardless its type.
2242 * \details The attribute can be an element of a vector attribute.
2243 */
2244 class ReadOnlyScalarAttributeAdapter : public ScalarAttributeAdapterBase {
2245 public:
2246 ReadOnlyScalarAttributeAdapter() : ScalarAttributeAdapterBase() {
2247 }
2248
2249 ReadOnlyScalarAttributeAdapter(
2250 const AttributesManager& manager, const std::string& name
2251 ) : ScalarAttributeAdapterBase(manager, name) {
2252 }
2253
2254 /**
2255 * \brief Gets a property value
2256 * \param[in] i the index of the item
2257 * \return the value of the property, convertex
2258 * into a double
2259 * \pre is_bound() && i < size()
2260 */
2261 double operator[](index_t i) {
2262 return get_element_as_double(i);
2263 }
2264 };
2265
2266 /***********************************************************/
2267
2268 /**
2269 * \brief Readwrite access to an attribute as a double regardless its type.
2270 * \details The attribute can be an element of a vector attribute.
2271 */
2272 class ReadWriteScalarAttributeAdapter : public ScalarAttributeAdapterBase {
2273 public:
2274 ReadWriteScalarAttributeAdapter() : ScalarAttributeAdapterBase() {
2275 }
2276
2277 ReadWriteScalarAttributeAdapter(
2278 const AttributesManager& manager, const std::string& name
2279 ) : ScalarAttributeAdapterBase(manager, name) {
2280 }
2281
2282 Accessor operator[](index_t i) {
2283 return Accessor(*this, i);
2284 }
2285
2286 ConstAccessor operator[](index_t i) const {
2287 return ConstAccessor(*this, i);
2288 }
2289
2290 protected:
2291 };
2292
2293
2294 }
2295
2296 #endif
2297