X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/dccf1b41e9c7b5a696f01abceaa2779fe65f154f..e76db741f886560cbf49a0dd833b35489c778ac1:/include/xbt/Extendable.hpp diff --git a/include/xbt/Extendable.hpp b/include/xbt/Extendable.hpp index 99c981d947..698e80c4f0 100644 --- a/include/xbt/Extendable.hpp +++ b/include/xbt/Extendable.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015. The SimGrid Team. +/* Copyright (c) 2015-2022. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -7,7 +7,9 @@ #ifndef SIMGRID_XBT_LIB_HPP #define SIMGRID_XBT_LIB_HPP +#include "xbt/base.h" // XBT_ATTRIB_DEPRECATED_v334 #include +#include #include #include @@ -19,14 +21,14 @@ template class Extendable; template class Extension { - static const std::size_t INVALID_ID = std::numeric_limits::max(); - std::size_t id_; + static constexpr std::size_t INVALID_ID = std::numeric_limits::max(); + std::size_t id_ = INVALID_ID; friend class Extendable; - constexpr Extension(std::size_t id) : id_(id) {} + explicit constexpr Extension(std::size_t id) : id_(id) {} public: - constexpr Extension() : id_(INVALID_ID) {} + explicit constexpr Extension() = default; std::size_t id() const { return id_; } - bool valid() { return id_ != INVALID_ID; } + bool valid() const { return id_ != INVALID_ID; } }; /** An Extendable is an object that you can extend with external elements. @@ -47,27 +49,27 @@ public: template class Extendable { private: - static std::vector deleters_; -protected: - std::vector extensions_; + static std::vector> deleters_; + std::vector extensions_{deleters_.size(), nullptr}; + public: - static size_t extension_create(void (*deleter)(void*)) + static size_t extension_create(const std::function& deleter) { - std::size_t res = deleters_.size(); - deleters_.push_back(deleter); - return res; + deleters_.emplace_back(deleter); + return deleters_.size() - 1; } - template - static Extension extension_create(void (*deleter)(void*)) + template static Extension extension_create(const std::function& deleter) { return Extension(extension_create(deleter)); } template static Extension extension_create() { - return extension_create([](void* p){ delete static_cast(p); }); + return Extension(extension_create([](void* p) { delete static_cast(p); })); } - Extendable() : extensions_(deleters_.size(), nullptr) {} + Extendable() = default; + Extendable(const Extendable&) = delete; + Extendable& operator=(const Extendable&) = delete; ~Extendable() { /* Call destructors in reverse order of their registrations @@ -76,50 +78,49 @@ public: * an extension A, the subsystem of B might depend on the subsystem on A and * an extension of B might need to have the extension of A around when executing * its cleanup function/destructor. */ - for (std::size_t i = extensions_.size(); i > 0; --i) - if (extensions_[i - 1] != nullptr) + for (std::size_t i = extensions_.size(); i > 1; --i) // rank=0 is the spot of user's void* + if (extensions_[i - 1] != nullptr && deleters_[i - 1]) deleters_[i - 1](extensions_[i - 1]); } // Type-unsafe versions of the facet access methods: - void* extension(std::size_t rank) + void* extension(std::size_t rank) const { - if (rank >= extensions_.size()) - return nullptr; - else - return extensions_.at(rank); + return rank < extensions_.size() ? extensions_[rank] : nullptr; } void extension_set(std::size_t rank, void* value, bool use_dtor = true) { if (rank >= extensions_.size()) extensions_.resize(rank + 1, nullptr); void* old_value = this->extension(rank); - extensions_.at(rank) = value; + extensions_[rank] = value; if (use_dtor && old_value != nullptr && deleters_[rank]) deleters_[rank](old_value); } // Type safe versions of the facet access methods: - template - U* extension(Extension rank) - { - return static_cast(extension(rank.id())); - } + template U* extension(Extension rank) const { return static_cast(extension(rank.id())); } template void extension_set(Extension rank, U* value, bool use_dtor = true) { extension_set(rank.id(), value, use_dtor); } - -public: - // Convenience extension access when the type has a associated EXTENSION ID: - template U* extension() { return extension(U::EXTENSION_ID); } + // void* version, for C users and nostalgics + void set_data(void* data){ + extensions_[0]=data; + } + template D* get_data() const { return static_cast(extensions_[0]); } + XBT_ATTRIB_DEPRECATED_v334("Please use typed template Extendable::get_data<>()") void* get_data() const + { + return get_data(); + } + // Convenience extension access when the type has an associated EXTENSION ID: + template U* extension() const { return extension(U::EXTENSION_ID); } template void extension_set(U* p) { extension_set(U::EXTENSION_ID, p); } }; -template -std::vector Extendable::deleters_ = {}; - +// Initialized with a first element, to save space for void* user data +template std::vector> Extendable::deleters_{1}; } }