peary/utils/dictionary.hpp

Peary Dictionary. More…

Namespaces

Name
peary
peary::utils

Classes

Name
class peary::utils::dictionary Dictionary class for storing elements for lookup.

Detailed Description

Peary Dictionary.

Copyright: Copyright (c) 2016-2025 CERN and the Peary Caribou authors. This software is distributed under the terms of the LGPL-3.0-only License, copied verbatim in the file “LICENSE.md”. SPDX-License-Identifier: LGPL-3.0-only

Source code

  
#pragma once

#include <algorithm>
#include <initializer_list>
#include <iostream>
#include <map>
#include <memory>
#include <vector>

#include "peary/log/log.hpp"
#include "peary/utils/constants.hpp"
#include "peary/utils/datatypes.hpp"
#include "peary/utils/exceptions.hpp"

namespace peary::utils {

    template <class T> class dictionary {
    public:
        explicit dictionary(std::string title) : _title(std::move(title)) {};

        virtual ~dictionary() = default;

        template <class C> void add(std::string name, const C elem) {
            std::transform(name.begin(), name.end(), name.begin(), ::tolower);
            auto ptr = std::make_shared<C>(elem);
            try {
                auto result = _elements.insert(std::make_pair(name, std::dynamic_pointer_cast<T>(ptr)));
                if(!result.second) {
                    throw utils::DictionnaryError(_title, "Element with name \"" + name + "\" already exists");
                }
            } catch(...) {
                throw utils::DictionnaryError(_title, "Cannot insert \"" + name + "\"");
            }
        }

        void add(const std::vector<std::pair<std::string, T>> elements) {
            for(const auto& i : elements) {
                add(i.first, i.second);
            }
        }

        template <class C> void add(std::string name, std::shared_ptr<C> elem) {
            std::transform(name.begin(), name.end(), name.begin(), ::tolower);
            try {
                auto result = _elements.insert(std::make_pair(name, elem));
                if(!result.second) {
                    throw utils::DictionnaryError(_title, "Element with name \"" + name + "\" already exists");
                }
            } catch(...) {
                throw utils::DictionnaryError(_title, "Cannot insert \"" + name + "\"");
            }
        }

        void add(const std::vector<std::pair<std::string, std::shared_ptr<T>>> elements) {
            for(const auto& i : elements) {
                add(i.first, i.second);
            }
        }

        T get(std::string name) const {
            std::transform(name.begin(), name.end(), name.begin(), ::tolower);
            try {
                return (*_elements.at(name));
            } catch(...) {
                throw utils::DictionnaryError(_title, "\"" + name + "\" unknown");
            }
        }

        // Return shared pointer to component config for the name in question:

        template <typename C> std::shared_ptr<C> get(std::string name) const {
            try {
                std::transform(name.begin(), name.end(), name.begin(), ::tolower);
                std::shared_ptr<T> ptr = _elements.at(name);
                if(std::dynamic_pointer_cast<C>(ptr)) {
                    return std::dynamic_pointer_cast<C>(ptr);
                } else {
                    throw utils::DictionnaryError(_title,
                                                  "Pointer to component configuration '" + name + "' cannot be cast");
                }
            } catch(...) {
                throw utils::DictionnaryError(_title, "\"" + name + "\" unknown");
            }
        }

        bool has(std::string name) const {
            std::transform(name.begin(), name.end(), name.begin(), ::tolower);
            return !(_elements.find(name) == _elements.end());
        }

        size_t size() const { return _elements.size(); }

        std::vector<std::string> getNames() const {
            std::vector<std::string> names;
            for(const auto& element : _elements) {
                names.push_back(element.first);
            }
            return names;
        }

        template <typename C> std::vector<std::string> getNames() const {
            std::vector<std::string> names;
            for(const auto& name : getNames()) {
                if(std::dynamic_pointer_cast<C>(_elements.at(name))) {
                    names.push_back(name);
                }
            }
            return names;
        }

    private:
        std::map<std::string, std::shared_ptr<T>> _elements;
        std::string _title;
    };

} // namespace peary::utils
  

Updated on 2025-11-14 at 11:31:23 +0100