diff --git a/Framework/Core/CMakeLists.txt b/Framework/Core/CMakeLists.txt index b5e1935fa5581..103b559f642e2 100644 --- a/Framework/Core/CMakeLists.txt +++ b/Framework/Core/CMakeLists.txt @@ -52,6 +52,7 @@ o2_add_library(Framework src/ConfigParamDiscovery.cxx src/ConfigParamStore.cxx src/ConfigParamsHelper.cxx + src/ConfigParamRegistry.cxx src/ChannelParamSpec.cxx src/DDSConfigHelpers.cxx src/DataAllocator.cxx diff --git a/Framework/Core/include/Framework/Array2D.h b/Framework/Core/include/Framework/Array2D.h index 5a1ed57408f30..593a50afd91f6 100644 --- a/Framework/Core/include/Framework/Array2D.h +++ b/Framework/Core/include/Framework/Array2D.h @@ -24,6 +24,7 @@ namespace o2::framework // has no range checks template struct Array2D { + void is_array_2d(); using element_t = T; Array2D() @@ -161,6 +162,7 @@ template class LabeledArray : public LabelMap { public: + void is_labeled_array(); using element_t = T; LabeledArray() diff --git a/Framework/Core/include/Framework/ConfigParamRegistry.h b/Framework/Core/include/Framework/ConfigParamRegistry.h index fdd1cad1de477..540581231dde3 100644 --- a/Framework/Core/include/Framework/ConfigParamRegistry.h +++ b/Framework/Core/include/Framework/ConfigParamRegistry.h @@ -11,35 +11,45 @@ #ifndef O2_FRAMEWORK_CONFIGPARAMREGISTRY_H_ #define O2_FRAMEWORK_CONFIGPARAMREGISTRY_H_ -#include "Framework/ParamRetriever.h" #include "Framework/ConfigParamStore.h" +#include #include "Framework/Traits.h" -#include "Framework/VariantPropertyTreeHelpers.h" -#include +#include +#include #include #include #include +#include -namespace -{ template -constexpr auto isSimpleType() -{ - return std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v; -} -} // namespace +concept SimpleConfigValueType = std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as; + +template +concept StringConfigValueType = std::same_as; + +template +concept PtreeConfigValueType = std::same_as || std::constructible_from; + +template +concept Array2DLike = requires(T& t) { t.is_array_2d(); }; + +template +concept LabeledArrayLike = requires(T& t) { t.is_labeled_array(); }; + +template +concept ConfigValueType = SimpleConfigValueType || StringConfigValueType || o2::framework::base_of_template || Array2DLike || LabeledArrayLike; namespace o2::framework { @@ -54,87 +64,43 @@ class ConfigParamStore; class ConfigParamRegistry { public: - ConfigParamRegistry(std::unique_ptr store) - : mStore{std::move(store)} - { - } + ConfigParamRegistry(std::unique_ptr store); - bool isSet(const char* key) const - { - return mStore->store().count(key); - } + bool isSet(const char* key) const; - bool hasOption(const char* key) const - { - return mStore->store().get_child_optional(key).is_initialized(); - } + bool hasOption(const char* key) const; - bool isDefault(const char* key) const - { - return mStore->store().count(key) > 0 && mStore->provenance(key) != "default"; - } + bool isDefault(const char* key) const; - [[nodiscard]] std::vector const& specs() const - { - return mStore->specs(); - } + [[nodiscard]] std::vector const& specs() const; - template - T get(const char* key) const - { - assert(mStore.get()); - try { - if constexpr (isSimpleType()) { - return mStore->store().get(key); - } else if constexpr (std::is_same_v) { - return mStore->store().get(key); - } else if constexpr (std::is_same_v) { - return std::string_view{mStore->store().get(key)}; - } else if constexpr (base_of_template) { - return vectorFromBranch(mStore->store().get_child(key)); - } else if constexpr (base_of_template) { - return array2DFromBranch(mStore->store().get_child(key)); - } else if constexpr (base_of_template) { - return labeledArrayFromBranch(mStore->store().get_child(key)); - } else if constexpr (std::is_same_v) { - return mStore->store().get_child(key); - } else if constexpr (std::is_constructible_v) { - return T{mStore->store().get_child(key)}; - } else if constexpr (std::is_constructible_v == false) { - static_assert(std::is_constructible_v == false, - "Not a basic type and no constructor from ptree provided"); - } - } catch (std::exception& e) { - throw std::invalid_argument(std::string("missing option: ") + key + " (" + e.what() + ")"); - } catch (...) { - throw std::invalid_argument(std::string("error parsing option: ") + key); - } - throw std::invalid_argument(std::string("bad type for option: ") + key); - } + template + T get(const char* key) const; template - void override(const char* key, const T& val) const - { - assert(mStore.get()); - try { - mStore->store().put(key, val); - } catch (std::exception& e) { - throw std::invalid_argument(std::string("failed to store an option: ") + key + " (" + e.what() + ")"); - } catch (...) { - throw std::invalid_argument(std::string("failed to store an option: ") + key); - } - } + T get(const char* key) const; + + void override(const char* key, ConfigValueType auto const& val) const; // Load extra parameters discovered while we process data - void loadExtra(std::vector& extras) - { - mStore->load(extras); - } + void loadExtra(std::vector& extras); private: std::unique_ptr mStore; }; +template +T ConfigParamRegistry::get(const char* key) const +{ + try { + return T{mStore->store().get_child(key)}; + } catch (std::exception& e) { + throw std::invalid_argument(std::string("missing option: ") + key + " (" + e.what() + ")"); + } catch (...) { + throw std::invalid_argument(std::string("error parsing option: ") + key); + } +} + } // namespace o2::framework #endif // O2_FRAMEWORK_CONFIGPARAMREGISTRY_H_ diff --git a/Framework/Core/src/ConfigParamRegistry.cxx b/Framework/Core/src/ConfigParamRegistry.cxx new file mode 100644 index 0000000000000..e6af6eeaebcae --- /dev/null +++ b/Framework/Core/src/ConfigParamRegistry.cxx @@ -0,0 +1,157 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#include "Framework/ConfigParamRegistry.h" +#include "Framework/VariantPropertyTreeHelpers.h" +#include "Framework/Array2D.h" + +namespace o2::framework +{ + +ConfigParamRegistry::ConfigParamRegistry(std::unique_ptr store) + : mStore{std::move(store)} +{ +} + +bool ConfigParamRegistry::isSet(const char* key) const +{ + return mStore->store().count(key); +} + +bool ConfigParamRegistry::hasOption(const char* key) const +{ + return mStore->store().get_child_optional(key).is_initialized(); +} + +bool ConfigParamRegistry::isDefault(const char* key) const +{ + return mStore->store().count(key) > 0 && mStore->provenance(key) != "default"; +} + +namespace +{ +template +T getImpl(boost::property_tree::ptree const& tree, const char* key) +{ + return tree.get(key); +} + +template +T getImpl(boost::property_tree::ptree const& tree, const char* key) +{ + return tree.get(key); +} + +template + requires base_of_template +auto getImpl(boost::property_tree::ptree const& tree, const char* key) +{ + return o2::framework::vectorFromBranch(tree.get_child(key)); +} + +template +auto getImpl(boost::property_tree::ptree& tree, const char* key) +{ + return array2DFromBranch(tree.get_child(key)); +} + +template +auto getImpl(boost::property_tree::ptree& tree, const char* key) +{ + return labeledArrayFromBranch(tree.get_child(key)); +} +} // namespace + +template +T ConfigParamRegistry::get(const char* key) const +{ + try { + return getImpl(this->mStore->store(), key); + } catch (std::exception& e) { + throw std::invalid_argument(std::string("missing option: ") + key + " (" + e.what() + ")"); + } catch (...) { + throw std::invalid_argument(std::string("error parsing option: ") + key); + } +} + +void ConfigParamRegistry::override(const char* key, ConfigValueType auto const& val) const +{ + try { + mStore->store().put(key, val); + } catch (std::exception& e) { + throw std::invalid_argument(std::string("failed to store an option: ") + key + " (" + e.what() + ")"); + } catch (...) { + throw std::invalid_argument(std::string("failed to store an option: ") + key); + } +} + +// Load extra parameters discovered while we process data +void ConfigParamRegistry::loadExtra(std::vector& extras) +{ + mStore->load(extras); +} + +[[nodiscard]] std::vector const& ConfigParamRegistry::specs() const +{ + return mStore->specs(); +} + +template int8_t ConfigParamRegistry::get(const char* key) const; +template short ConfigParamRegistry::get(const char* key) const; +template int ConfigParamRegistry::get(const char* key) const; +template long ConfigParamRegistry::get(const char* key) const; +template long long ConfigParamRegistry::get(const char* key) const; +template uint8_t ConfigParamRegistry::get(const char* key) const; +template uint16_t ConfigParamRegistry::get(const char* key) const; +template uint32_t ConfigParamRegistry::get(const char* key) const; +template uint64_t ConfigParamRegistry::get(const char* key) const; +template LabeledArray ConfigParamRegistry::get>(const char* key) const; +template LabeledArray ConfigParamRegistry::get>(const char* key) const; +template LabeledArray ConfigParamRegistry::get>(const char* key) const; +template LabeledArray ConfigParamRegistry::get>(const char* key) const; +template Array2D ConfigParamRegistry::get>(const char* key) const; +template Array2D ConfigParamRegistry::get>(const char* key) const; +template Array2D ConfigParamRegistry::get>(const char* key) const; +template Array2D ConfigParamRegistry::get>(const char* key) const; +template std::vector ConfigParamRegistry::get>(const char* key) const; +template std::vector ConfigParamRegistry::get>(const char* key) const; +template std::vector ConfigParamRegistry::get>(const char* key) const; +template std::vector ConfigParamRegistry::get>(const char* key) const; +template float ConfigParamRegistry::get(const char* key) const; +template double ConfigParamRegistry::get(const char* key) const; +template std::string ConfigParamRegistry::get(const char* key) const; +template bool ConfigParamRegistry::get(const char* key) const; + +template void ConfigParamRegistry::override(const char* key, int8_t const&) const; +template void ConfigParamRegistry::override(const char* key, int16_t const&) const; +template void ConfigParamRegistry::override(const char* key, int32_t const&) const; +template void ConfigParamRegistry::override(const char* key, int64_t const&) const; +template void ConfigParamRegistry::override(const char* key, uint8_t const&) const; +template void ConfigParamRegistry::override(const char* key, uint16_t const&) const; +template void ConfigParamRegistry::override(const char* key, uint32_t const&) const; +template void ConfigParamRegistry::override(const char* key, uint64_t const&) const; +template void ConfigParamRegistry::override(const char* key, float const&) const; +template void ConfigParamRegistry::override(const char* key, double const&) const; +template void ConfigParamRegistry::override(const char* key, std::string const&) const; +template void ConfigParamRegistry::override(const char* key, bool const&) const; + +//template void ConfigParamRegistry::override(char const* key, LabeledArray const&) const; +//template void ConfigParamRegistry::override(char const* key, LabeledArray const&) const; +//template void ConfigParamRegistry::override(char const* key, LabeledArray const&) const; +//template void ConfigParamRegistry::override(char const* key, LabeledArray const&) const; +//template void ConfigParamRegistry::override(char const* key, Array2D const&) const; +//template void ConfigParamRegistry::override(char const* key, Array2D const&) const; +//template void ConfigParamRegistry::override(char const* key, Array2D const&) const; +//template void ConfigParamRegistry::override(char const* key, Array2D const&) const; +//template void ConfigParamRegistry::override(char const* key, std::vector const&) const; +//template void ConfigParamRegistry::override(char const* key, std::vector const&) const; +//template void ConfigParamRegistry::override(char const* key, std::vector const&) const; +//template void ConfigParamRegistry::override(char const* key, std::vector const&) const; +} // namespace o2::framework