41 #ifndef GEOGRAM_BASIC_ATTRIBUTES
42 #define GEOGRAM_BASIC_ATTRIBUTES
50 #include <geogram/basic/logger.h>
55 #include <type_traits>
77 base_addr_(nullptr), size_(0), dimension_(0),
78 disconnected_(false) {
91 base_addr_ = base_addr;
119 return size_ * dimension_;
142 base_addr_ =
nullptr;
145 disconnected_ =
true;
180 std::string element_type_name_;
181 std::string element_typeid_name_;
224 const std::string& type_name
248 return cached_capacity_;
269 virtual void clear(
bool keep_memory =
false) = 0;
277 return !observers_.empty();
366 index_t item_size = element_size_ * dimension_;
368 cached_base_addr_+to*item_size,
369 cached_base_addr_+from*item_size,
380 index_t item_size = element_size_ * dimension_;
382 cached_base_addr_+to*item_size,
417 return cached_base_addr_;
425 return cached_base_addr_;
433 return size_t(element_size_);
445 const std::string& element_type_name
448 type_name_to_creator_.find(element_type_name) !=
449 type_name_to_creator_.end()
462 const std::string& element_typeid_name
465 typeid_name_to_type_name_.find(element_typeid_name) !=
466 typeid_name_to_type_name_.end()
477 const std::string& element_type_name,
480 geo_assert(element_type_name_is_known(element_type_name));
481 return type_name_to_creator_[element_type_name]->
482 create_attribute_store(dimension);
493 const std::string& element_typeid_name
495 geo_assert(element_typeid_name_is_known(element_typeid_name));
496 return typeid_name_to_type_name_[element_typeid_name];
508 const std::string& element_type_name
510 geo_assert(element_type_name_is_known(element_type_name));
511 return type_name_to_typeid_name_[element_type_name];
526 const std::string& element_type_name,
527 const std::string& element_typeid_name
529 if(element_type_name_is_known(element_type_name)) {
530 Logger::warn(
"Attributes") << element_type_name
531 <<
" already registered"
533 if(element_typeid_name_is_known(element_typeid_name)) {
534 bool already_registered_attribute_has_same_type = (
535 type_name_to_typeid_name_[element_type_name] ==
538 geo_assert(already_registered_attribute_has_same_type);
541 type_name_to_creator_[element_type_name] = creator;
542 typeid_name_to_type_name_[element_typeid_name] = element_type_name;
543 type_name_to_typeid_name_[element_type_name] = element_typeid_name;
585 std::set<AttributeStoreObserver*> observers_;
588 static std::map<std::string, AttributeStoreCreator_var>
589 type_name_to_creator_;
591 static std::map<std::string, std::string>
592 typeid_name_to_type_name_;
594 static std::map<std::string, std::string>
595 type_name_to_typeid_name_;
621 store_.resize(new_size*dimension_);
631 store_.reserve(new_capacity*dimension_);
632 cached_capacity_ = new_capacity;
641 void clear(
bool keep_memory=
false)
override {
647 notify(
nullptr, 0, dimension_);
659 for(
index_t c = 0; c < copy_dim; ++c) {
660 new_store[dim * i + c] = store_[dimension_ * i + c];
663 store_.swap(new_store);
672 const std::string& type_name
674 return type_name ==
typeid(T).name();
678 return typeid(T).name();
685 result->store_ = store_;
695 for(
index_t i=0; i<dimension_; ++i) {
696 scale_value(store_[to*dimension_+i], s);
703 for(
index_t i=0; i<dimension_; ++i) {
705 store_[to*dimension_+i], s, store_[from*dimension_+i]
718 template<
class TT>
static void scale_value(TT& to,
double s) {
723 static void scale_value(uint8_t& to,
double s) {
724 to = uint8_t(
double(to)*s != 0.0);
727 static void scale_value(int32_t& to,
double s) {
728 to = int32_t(
double(to)*s);
731 static void scale_value(uint32_t& to,
double s) {
732 to = uint32_t(
double(to)*s);
735 static void scale_value(
float& to,
double s) {
736 to = float(
double(to)*s);
739 static void scale_value(
double& to,
double s) {
743 template<
class TT>
static void madd_value(TT& to,
double s, TT& from) {
749 static void madd_value(uint8_t& to,
double s, uint8_t& from) {
750 to = uint8_t(
double(to) + s*
double(from) != 0.0);
753 static void madd_value(int32_t& to,
double s, int32_t& from) {
754 to = int32_t(
double(to) + s*
double(from));
757 static void madd_value(uint32_t& to,
double s, uint32_t& from) {
758 to = uint32_t(
double(to) + s*
double(from));
761 static void madd_value(
float& to,
double s,
float& from) {
762 to = float(
double(to) + s*
double(from));
765 static void madd_value(
double& to,
double s,
double& from) {
812 if(type_name ==
"bool") {
821 read_ascii_attribute<T>,
822 write_ascii_attribute<T>
853 return index_t(attributes_.size());
906 void clear(
bool keep_attributes,
bool keep_memory =
false);
939 const std::string& name
950 return (find_attribute_store(name) !=
nullptr);
1060 const std::string& name,
const std::string& new_name
1072 const std::string& old_name,
const std::string& new_name
1097 std::map<std::string, AttributeStore*> attributes_;
1140 return (store_ !=
nullptr && !disconnected_);
1152 if(!disconnected_) {
1172 if(store_ ==
nullptr) {
1196 if(store_ !=
nullptr) {
1219 if(store_ !=
nullptr) {
1239 const std::string& name,
1275 store_->
redim(new_dim);
1307 ((dim == 0) || (store->
dimension() == dim))
1357 return typed_store->get_vector();
1370 return typed_store->get_vector();
1407 #if __GNUG__ && __GNUC__ < 5 && !__clang__
1409 __has_trivial_copy(T),
1410 "Attribute only implemented for types that can be copied with memcpy()"
1414 std::is_trivially_copyable<T>::value,
1415 "Attribute only implemented for types that can be copied with memcpy()"
1448 return ((T*)(
void*)superclass::base_addr_)[i];
1458 return ((
const T*)(
void*)superclass::base_addr_)[i];
1482 (*this)[i] = rhs[i];
1491 return (T*)AttributeStoreObserver::base_addr_;
1499 return (
const T*)AttributeStoreObserver::base_addr_;
1535 class BoolAttributeAccessor;
1542 class ConstBoolAttributeAccessor {
1551 attribute_(&attribute),
1559 operator bool()
const {
1560 return (attribute_->element(index_) != 0);
1567 friend class BoolAttributeAccessor;
1574 class BoolAttributeAccessor {
1583 attribute_(&attribute),
1591 operator bool()
const {
1592 return (attribute_->element(index_) != 0);
1601 attribute_ = rhs.attribute_;
1602 index_ = rhs.index_;
1620 const BoolAttributeAccessor& rhs
1623 attribute_->element(index_) =
1624 rhs.attribute_->element(rhs.index_);
1635 const ConstBoolAttributeAccessor& rhs
1637 attribute_->element(index_) =
1638 rhs.attribute_->element(rhs.index_);
1649 return BoolAttributeAccessor(*
this,i);
1653 return ConstBoolAttributeAccessor(*
this,i);
1669 friend class BoolAttributeAccessor;
1670 friend class ConstBoolAttributeAccessor;
1738 ) : attribute_(attribute), index_(index) {
1741 operator double()
const {
1742 return attribute_.get_element_as_double(index_);
1745 void operator=(
double x) {
1746 attribute_.set_element_as_double(index_, x);
1763 ) : attribute_(attribute), index_(index) {
1766 operator double()
const {
1767 return attribute_.get_element_as_double(index_);
1781 element_type_(ET_NONE),
1799 bind_if_is_defined(manager, name);
1808 return (store_ !=
nullptr);
1820 element_type_ = ET_NONE;
1868 return (store_ ==
nullptr) ? 0 : store_->size();
1879 return element_type_;
1889 return element_index_;
1909 return element_type(store) != ET_NONE;
1959 double result = 0.0;
1960 switch(element_type()) {
1962 result = double(get_element<Numeric::uint8>(i));
1965 result = double(get_element<Numeric::int8>(i));
1968 result = double(get_element<Numeric::uint32>(i));
1971 result = double(get_element<Numeric::int32>(i));
1974 result = double(get_element<Numeric::float32>(i));
1977 result = double(get_element<Numeric::float64>(i));
1980 result = double(get_element<Numeric::float64>(i,2));
1983 result = double(get_element<Numeric::float64>(i,3));
2002 return static_cast<const T*
>(store_->data())[
2003 (i * store_->dimension() * multiplier) +
2015 double result = 0.0;
2016 switch(element_type()) {
2061 const_cast<T*
>(
static_cast<const T*
>(store_->data()))[
2062 (i * store_->dimension() * multiplier) +
2070 ElementType element_type_;
#define geo_assert_not_reached
Sets a non reachable point in the program.
#define geo_assert(x)
Verifies that a condition is met.
#define geo_debug_assert(x)
Verifies that a condition is met.
Base class for Attributes, that manipulates an attribute stored in an AttributesManager.
void create_vector_attribute(AttributesManager &manager, const std::string &name, index_t dimension)
Creates and binds a new vector attribute.
~AttributeBase()
Attribute destructor.
index_t size() const
Gets the size.
AttributeBase(AttributesManager &manager, const std::string &name)
Creates or retrieves a persistent attribute attached to a given AttributesManager.
void zero()
Sets all the elements of this Attribute to zero.
bool is_bound() const
Tests whether an Attribute is bound.
void unbind()
Unbinds this Attribute.
void redim(index_t new_dim)
Sets the dimension.
void destroy()
Destroys this attribute in the AttributesManager.
bool bind_if_is_compatible(AttributesManager &manager, const std::string &name)
Binds this Attribute to an AttributesManager if it already exists in the AttributesManager and tyopes...
static bool is_defined(AttributesManager &manager, const std::string &name, index_t dim=0)
Tests whether an attribute with the specified name and with corresponding type exists in an Attribute...
bool can_get_vector()
Tests whether get_vector() can be called on this Attribute.
AttributesManager * manager() const
Gets the AttributesManager this Attribute is bound to.
const vector< T > & get_vector() const
Gets a const reference to the internal vector<T> used to store the attribute.
vector< T > & get_vector()
Gets a reference to the internal vector<T> used to store the attribute.
AttributeBase()
Creates an uninitialized (unbound) Attribute.
void bind(AttributesManager &manager, const std::string &name)
Binds this Attribute to an AttributesManager.
bool bind_if_is_defined(AttributesManager &manager, const std::string &name)
Binds this Attribute to an AttributesManager if it already exists in the AttributesManager.
Internal class for creating an AttributeStore from the type name of its elements.
~AttributeStoreCreator() override
AttributeStoreCreator destructor.
virtual AttributeStore * create_attribute_store(index_t dimension)=0
Creates a new attribute store.
Base class for attributes. They are notified whenever the AttributeStore is modified.
AttributeStoreObserver()
Creates a new uninitialied AttributeStore.
void register_me(AttributeStore *store)
Registers this observer to an AttributeStore.
index_t size() const
Gets the size.
void notify(Memory::pointer base_addr, index_t size, index_t dim)
Callback function, called by the AttributeStore whenever it is modified.
index_t nb_elements() const
Gets the total number of elements.
void disconnect()
Disconnects this AttributeStoreObserver from its AttributeStore.
void unregister_me(AttributeStore *store)
Unregisters this observer from an AttributeStore.
index_t dimension() const
Gets the dimension.
Notifies a set of AttributeStoreObservers each time the stored array changes size and/or base address...
AttributeStore(index_t elemsize, index_t dim=1)
AttributeStore constructor.
bool has_observers() const
Tests whether observers listen to this AttributeStore.
void zero_item(index_t to)
Sets an item to zero.
virtual ~AttributeStore()
AttributeStore destructor.
static std::string element_typeid_name_by_element_type_name(const std::string &element_type_name)
Gets an element mangled type name from its C++ name.
static void register_attribute_creator(AttributeStoreCreator *creator, const std::string &element_type_name, const std::string &element_typeid_name)
Registers a new element type.
const void * data() const
Gets a pointer to the stored data.
index_t size() const
Gets the size.
virtual void clear(bool keep_memory=false)=0
Resizes this AttributeStore to 0.
virtual void notify(Memory::pointer base_addr, index_t size, index_t dim)
If size or base address differ from the cached values, notify all the observers, and update the cache...
index_t capacity() const
Gets the capacity.
virtual void madd_item(index_t to, double s, index_t from)
Adds a scaled item to another item \detais item[to] += s * item[from].
static bool element_type_name_is_known(const std::string &element_type_name)
Tests whether a given element type is registered in the system.
virtual void compress(const vector< index_t > &old2new)
Compresses the stored attributes, by applying an index mapping that fills-in the gaps.
virtual std::string element_typeid_name() const =0
Gets the typeid name of the element type stored in this AttributeStore.
void copy_item(index_t to, index_t from)
Copies an item.
static bool element_typeid_name_is_known(const std::string &element_typeid_name)
Tests whether a given element type is registered in the system.
void register_observer(AttributeStoreObserver *observer)
Registers an observer.
virtual void apply_permutation(const vector< index_t > &permutation)
Applies a permutation to the stored attributes.
virtual void resize(index_t new_size)=0
Resizes this AttributeStore.
virtual AttributeStore * clone() const =0
Creates a new AttributeStore that is a carbon copy of this AttributeStore.
virtual void scale_item(index_t to, double s)
Scales an item.
static AttributeStore * create_attribute_store_by_element_type_name(const std::string &element_type_name, index_t dimension)
Creates an attribute store of a given type.
void unregister_observer(AttributeStoreObserver *observer)
Unregisters an observer.
virtual void redim(index_t dim)=0
Sets the dimension.
index_t dimension() const
Gets the dimension.
static std::string element_type_name_by_element_typeid_name(const std::string &element_typeid_name)
Gets an element type name from its mangled name.
virtual bool elements_type_matches(const std::string &type_name) const =0
Tests whether this AttributeStore stores elements of a given type.
void swap_items(index_t i, index_t j)
Swaps two items.
void * data()
Gets a pointer to the stored data.
size_t element_size() const
Gets the element size.
virtual void reserve(index_t new_capacity)=0
Reserves memory.
virtual void zero()
Zeroes all the memory associated with this AttributeStore.
BoolAttributeAccessor(Attribute< bool > &attribute, index_t index)
BoolAttributeAccessor constructor.
BoolAttributeAccessor & operator=(const ConstBoolAttributeAccessor &rhs)
Copies a bool from another attribute.
BoolAttributeAccessor & operator=(bool x)
Assigns a bool to a BoolAttributeAccessor.
BoolAttributeAccessor(const BoolAttributeAccessor &rhs)
Copy-constructor.
BoolAttributeAccessor & operator=(const BoolAttributeAccessor &rhs)
Copies a bool from another attribute.
ConstBoolAttributeAccessor(const Attribute< bool > &attribute, index_t index)
ConstBoolAttributeAccessor constructor.
Specialization of Attribute for booleans.
Numeric::uint8 & element(index_t i)
Gets a modifiable element by index.
const Numeric::uint8 & element(index_t i) const
Gets an element by index.
void fill(bool val)
Sets all the elements in this attribute to a specified value.
Manages an attribute attached to a set of object.
T & operator[](index_t i)
Gets a modifiable element by index.
Attribute(AttributesManager &manager, const std::string &name)
Creates or retrieves a persistent attribute attached to a given AttributesManager.
Attribute()
Creates an uninitialized (unbound) Attribute.
const T & operator[](index_t i) const
Gets an element by index.
void fill(const T &val)
Sets all the elements in this attribute to a specified value.
T * data()
Gets the pointer to the data.
void copy(const Attribute< T > &rhs)
Copies all the values from another attribute.
const T * data() const
Gets the pointer to the data.
static void static_test_type()
Tests at compile time whether type can be used in an Attribute. If not the case generates a compile-t...
Managers a set of attributes attached to an object.
void delete_attribute_store(AttributeStore *as)
Deletes an AttributeStore.
AttributeStore * find_attribute_store(const std::string &name)
Finds an AttributeStore by name.
void compress(const vector< index_t > &old2new)
Compresses the stored attributes, by applying an index mapping that fills-in the gaps.
void zero_item(index_t to)
Sets an item to zero.
void copy(const AttributesManager &rhs)
Copies all the attributes from another AttributesManager.
AttributesManager()
Constructs a new empty AttributesManager.
index_t nb() const
Gets the number of attributes.
bool rename_attribute(const std::string &old_name, const std::string &new_name)
Renames an attribute.
void scale_item(index_t to, double s)
Scales an item.
void apply_permutation(const vector< index_t > &permutation)
Applies a permutation to the stored attributes.
void bind_attribute_store(const std::string &name, AttributeStore *as)
Binds an AttributeStore with the specified name. Ownership of this AttributeStore is transferred to t...
void list_attribute_names(vector< std::string > &names) const
Gets the names of all the attributes in this AttributeStore.
~AttributesManager()
AttributesManager destructor.
void copy_item(index_t to, index_t from)
Copies all the attributes of an item into another one.
void madd_item(index_t to, double s, index_t from)
Adds a scaled item to another item \detais item[to] += s * item[from].
bool is_defined(const std::string &name) const
Tests whether an attribute is defined.
void swap_items(index_t i, index_t j)
Swaps all the attributes of two items.
index_t size() const
Gets the size.
void clear(bool keep_attributes, bool keep_memory=false)
Clears this AttributesManager.
index_t capacity() const
Gets the capacity.
void delete_attribute_store(const std::string &name)
Deletes an AttributeStore by name.
bool copy_attribute(const std::string &name, const std::string &new_name)
Copies an attribute.
const AttributeStore * find_attribute_store(const std::string &name) const
Finds an AttributeStore by name.
void zero()
Zeroes all the attributes.
void reserve(index_t new_capacity)
Pre-allocates memory for a number of items.
void resize(index_t new_size)
Resizes all the attributes managed by this AttributesManager.
Base class for reference-counted objects.
static void register_ascii_attribute_serializer(const std::string &type_name, AsciiAttributeSerializer read, AsciiAttributeSerializer write)
Declares a new attribute type that can be read from and written to ascii files.
Readonly access to an attribute as a double regardless its type.
double operator[](index_t i)
Gets a property value.
Readwrite access to an attribute as a double regardless its type.
Accessor class used by ScalarAttributeAdapter to implement indexing operator.
Accessor class used by ScalarAttributeAdapter to implement indexing operator (const version).
Access to an attribute as a double regardless its type.
index_t element_index() const
Gets the element index.
T get_element(index_t i, index_t multiplier=1) const
Gets an element.
ElementType
Internal representation of the attribute.
static std::string attribute_base_name(const std::string &name)
Gets the base attribute name from a compound name.
void bind_if_is_defined(const AttributesManager &manager, const std::string &name)
Binds this Attribute to an AttributesManager if it already exists in the AttributesManager.
bool is_bound() const
Tests whether an Attribute is bound.
static index_t nb_scalar_elements_per_item(const AttributeStore *store)
Gets the number of scalar components per item in an AttributeStore.
double get_element_as_double(index_t i) const
Gets an attribute value.
~ScalarAttributeAdapterBase()
ReadonlyScalarAttributeAdapterBase destructor.
static ElementType element_type(const AttributeStore *store)
Gets the element type stored in an AttributeStore.
ScalarAttributeAdapterBase()
ScalarAttributeAdapterBase constructor.
static bool can_be_bound_to(const AttributeStore *store)
Tests whether a ScalarAttributeAdapterBase can be bound to a given attribute store.
void unbind()
Unbinds this Attribute.
static bool is_defined(const AttributesManager &manager, const std::string &name)
Tests whether an attribute with the specified name and with a type that can be converted to double ex...
ScalarAttributeAdapterBase(const AttributesManager &manager, const std::string &name)
ScalarAttributeAdapterBase constructor.
double set_element_as_double(index_t i, double value)
Sets an attribute value.
void set_element(T value, index_t i, index_t multiplier=1) const
Sets an element.
const AttributeStore * attribute_store() const
Gets the AttributeStore.
static index_t attribute_element_index(const std::string &name)
Gets the base attribute name from a compound name.
index_t size() const
Gets the size.
ElementType element_type() const
Gets the internal representation of the elements.
A smart pointer with reference-counted copy semantics.
Implementation of AttributeStoreCreator for a specific type.
AttributeStore * create_attribute_store(index_t dim) override
Creates a new attribute store.
Stores an array of elements of a given type, and notifies a set of AttributeStoreObservers each time ...
void scale_item(index_t to, double s) override
Scales an item.
TypedAttributeStore(index_t dim=1)
Creates a new empty attribute store.
void notify(Memory::pointer base_addr, index_t size, index_t dim) override
If size or base address differ from the cached values, notify all the observers, and update the cache...
void clear(bool keep_memory=false) override
Resizes this AttributeStore to 0.
void resize(index_t new_size) override
Resizes this AttributeStore.
std::string element_typeid_name() const override
Gets the typeid name of the element type stored in this AttributeStore.
void reserve(index_t new_capacity) override
Reserves memory.
bool elements_type_matches(const std::string &type_name) const override
Tests whether this AttributeStore stores elements of a given type.
void madd_item(index_t to, double s, index_t from) override
Adds a scaled item to another item \detais item[to] += s * item[from].
void redim(index_t dim) override
Sets the dimension.
AttributeStore * clone() const override
Creates a new AttributeStore that is a carbon copy of this AttributeStore.
Helper class to register new attribute types.
geo_register_attribute_type(const std::string &type_name)
geo_register_attribute_type constructor
Common include file, providing basic definitions. Should be included before anything else by all head...
Functions to read and write structured files.
Types and functions for memory manipulation.
byte * pointer
Pointer to unsigned byte(s)
void clear(void *addr, size_t size)
Clears a memory block.
void copy(void *to, const void *from, size_t size)
Copies a memory block.
std::atomic_flag spinlock
A lightweight synchronization structure.
Global Vorpaline namespace.
bool write_ascii_attribute< bool >(FILE *file, Memory::pointer base_addr, index_t nb_elements)
Writes an ASCII attribute to a file.
void geo_argused(const T &)
Suppresses compiler warnings about unused parameters.
geo_index_t index_t
The type for storing and manipulating indices.
SmartPointer< AttributeStoreCreator > AttributeStoreCreator_var
An automatic reference-counted pointer to an AttributeStoreCreator.
bool read_ascii_attribute< bool >(FILE *file, Memory::pointer base_addr, index_t nb_elements)
Reads an ASCII attribute from a file.
Types and functions for numbers manipulation.
Function and classes for process manipulation.