/** * @file * @author Caleb Fangmeier * @version 0.1 * * @section LICENSE * * * MIT License * * Copyright (c) 2017 Caleb Fangmeier * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef container_hpp #define container_hpp #include #include #include #include "value.hpp" template class std::vector >; template class std::vector >; namespace fv::util { std::string get_type_name(const std::type_index &index) { std::map _map; // Add to this list as needed :) _map[typeid(int)] = "int"; _map[typeid(unsigned int)] = "unsigned int"; _map[typeid(float)] = "float"; _map[typeid(double)] = "double"; _map[typeid(std::vector)] = "std::vector"; _map[typeid(std::vector)] = "std::vector"; _map[typeid(std::pair, std::vector>)] = "std::pair,std::vector>"; _map[typeid(std::vector>)] = "std::vector>"; _map[typeid(std::map)] = "std::map"; if (_map[index] == "") { CRITICAL("Cannot lookup type name of \"" << index.name() << "\"", -1); } return _map[index]; } } namespace fv { /** * Enumeration of different options that can be used to save Containers. Not * all options are allowed for all Containers. */ enum SaveOption { PNG = 0, PDF = 1, ROOT = 2 }; /** * Generic, untyped parent class of Container. Used to allow for placing * Containers of disparate types in common data structures. */ class GenContainer { private: std::string name; std::string desc; public: GenContainer(const std::string name, const std::string &desc) : name(name), desc(desc) {} GenContainer(const std::string name) : GenContainer(name, "N/A") {} void set_description(const std::string &description) { desc = description; } const std::string &get_name() { return name; } virtual const std::string get_value_name() { return "N/A"; } virtual GenContainer *clone_as(const std::string &new_name) = 0; virtual void save_as(const std::string &fname, const SaveOption &option) = 0; virtual void save(const SaveOption &option = SaveOption::PNG) { save_as(get_name(), option); } }; /** * A class that is used to "hold" values. When an event is loaded the * \c fill() method is called and the Container can access the stored Value * object to process it. For example, if the Container is a ROOT Histogram * object, it may call container->Fill(value->get_value()). */ template class Container : public GenContainer { protected: H *container; public: Container(const std::string &name) : GenContainer(name), container(nullptr) {} virtual ~Container() { if (container != nullptr) delete container; } virtual H *get_container() { return container; } }; /** * Prints out the value registered to it */ template class Logger : public Container { private: using to_str_t = std::function; to_str_t value_to_string; std::string logger_name; static void default_to_string(T &t, std::ostream &os) { os << t; } public: void fill(const T& the_value) { auto &os = (*this->container); std::stringstream vs; os << this->get_name() << std::endl; if (value_to_string != nullptr) value_to_string(the_value, vs); else default_to_string(the_value, vs); for (const char &c : vs.str()) { if (c == '\n') os << std::endl << " "; else os << c; } os << std::endl; } Logger(std::ostream *out, const std::string& logger_name, to_str_t value_to_string = nullptr) : Container("Logger:" + logger_name), value_to_string(value_to_string), logger_name(logger_name) { this->container = out; } std::ostream *get_container() { return this->container; } GenContainer *clone_as(const std::string &new_name) { return new Logger(this->container, logger_name, value_to_string); } void save_as(const std::string &, const SaveOption &) {} }; } #endif // container_hpp