Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:22:25

0001 /*************************************************************************
0002  * Copyright (C) 1995-2020, Rene Brun and Fons Rademakers.               *
0003  * All rights reserved.                                                  *
0004  *                                                                       *
0005  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0006  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0007  *************************************************************************/
0008 
0009 #ifndef ROOT7_RAttrMap
0010 #define ROOT7_RAttrMap
0011 
0012 #include <memory>
0013 #include <string>
0014 #include <type_traits>
0015 #include <unordered_map>
0016 
0017 #include <ROOT/RPadLength.hxx>
0018 #include <ROOT/RColor.hxx>
0019 
0020 namespace ROOT {
0021 namespace Experimental {
0022 
0023 class RAttrBase;
0024 class RStyle;
0025 
0026 /** \class RAttrMap
0027 \ingroup GpadROOT7
0028 \authors Axel Naumann <axel@cern.ch> Sergey Linev <s.linev@gsi.de>
0029 \date 2017-09-26
0030 \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
0031 */
0032 
0033 class RAttrMap {
0034 
0035    friend class RAttrBase;
0036    friend class RStyle;
0037 
0038 public:
0039 
0040    enum EValuesKind { kNoValue, kBool, kInt, kDouble, kString };
0041 
0042    class Value_t {
0043    public:
0044       virtual ~Value_t() = default;
0045       virtual EValuesKind Kind() const = 0;
0046       virtual bool CanConvertFrom(EValuesKind kind) const { return kind == Kind(); }
0047       virtual bool CanConvertTo(EValuesKind kind) const { return kind == Kind(); }
0048       virtual bool GetBool() const { return false; }
0049       virtual int GetInt() const { return 0; }
0050       virtual double GetDouble() const { return 0; }
0051       virtual std::string GetString() const { return ""; }
0052       virtual bool IsEqual(const Value_t &) const { return false; }
0053       virtual std::unique_ptr<Value_t> Copy() const = 0;
0054 
0055       template<typename T> T Get() const;
0056 
0057       template <typename RET_TYPE, typename MATCH_TYPE = void>
0058       static RET_TYPE GetValue(const Value_t *rec);
0059    };
0060 
0061    class NoValue_t : public Value_t {
0062    public:
0063       explicit NoValue_t() {}
0064       EValuesKind Kind() const final { return kNoValue; }
0065       std::unique_ptr<Value_t> Copy() const final { return std::make_unique<NoValue_t>(); }
0066       bool IsEqual(const Value_t &tgt) const final { return (tgt.Kind() == kNoValue); }
0067    };
0068 
0069    class BoolValue_t : public Value_t {
0070       bool v{false}; ///< integer value
0071    public:
0072       explicit BoolValue_t(bool _v = false) : v(_v) {}
0073       EValuesKind Kind() const final { return kBool; }
0074       bool CanConvertFrom(EValuesKind kind) const final { return (kind == kDouble) || (kind == kInt) || (kind == kBool) || (kind == kString); }
0075       bool CanConvertTo(EValuesKind kind) const final { return (kind == kDouble) || (kind == kInt) || (kind == kBool) || (kind == kString); }
0076       bool GetBool() const final { return v; }
0077       int GetInt() const final { return v ? 1 : 0; }
0078       double GetDouble() const final { return v ? 1 : 0; }
0079       std::string GetString() const final { return v ? "true" : "false"; }
0080       std::unique_ptr<Value_t> Copy() const final { return std::make_unique<BoolValue_t>(v); }
0081       bool IsEqual(const Value_t &tgt) const final { return tgt.GetBool() == v; }
0082    };
0083 
0084    class IntValue_t : public Value_t {
0085       int v{0}; ///< integer value
0086    public:
0087       IntValue_t(int _v = 0) : v(_v) {}
0088       EValuesKind Kind() const final { return kInt; }
0089       bool CanConvertFrom(EValuesKind kind) const final { return (kind == kInt) || (kind == kBool); }
0090       bool CanConvertTo(EValuesKind kind) const final { return (kind == kDouble) || (kind == kInt) || (kind == kBool) || (kind == kString); }
0091       bool GetBool() const final { return v ? true : false; }
0092       int GetInt() const final { return v; }
0093       double GetDouble() const final { return v; }
0094       std::string GetString() const final { return std::to_string(v); }
0095       std::unique_ptr<Value_t> Copy() const final { return std::make_unique<IntValue_t>(v); }
0096       bool IsEqual(const Value_t &tgt) const final { return tgt.GetInt() == v; }
0097    };
0098 
0099    class DoubleValue_t : public Value_t {
0100       double v{0}; ///< double value
0101    public:
0102       DoubleValue_t(double _v = 0) : v(_v) {}
0103       EValuesKind Kind() const final { return kDouble; }
0104       bool CanConvertFrom(EValuesKind kind) const final { return (kind == kDouble) || (kind == kInt) || (kind == kBool); }
0105       bool CanConvertTo(EValuesKind kind) const final { return (kind == kDouble) || (kind == kBool) || (kind == kString); }
0106       bool GetBool() const final { return v ? true : false; }
0107       int GetInt() const final { return (int) v; }
0108       double GetDouble() const final { return v; }
0109       std::string GetString() const final { return std::to_string(v); }
0110       std::unique_ptr<Value_t> Copy() const final { return std::make_unique<DoubleValue_t>(v); }
0111       bool IsEqual(const Value_t &tgt) const final { return tgt.GetDouble() == v; }
0112    };
0113 
0114    class StringValue_t : public Value_t {
0115       std::string v; ///< string value
0116    public:
0117       StringValue_t(const std::string _v = "") : v(_v) {}
0118       EValuesKind Kind() const final { return kString; }
0119       // all values can be converted into the string
0120       bool CanConvertFrom(EValuesKind) const final { return true; }
0121       // can convert into string and boolean
0122       bool CanConvertTo(EValuesKind kind) const final { return kind == kString; }
0123       bool GetBool() const final { return v.compare("true") == 0; }
0124       std::string GetString() const final { return v; }
0125       bool IsEqual(const Value_t &tgt) const final { return tgt.GetString() == v; }
0126       std::unique_ptr<Value_t> Copy() const final { return std::make_unique<StringValue_t>(v); }
0127    };
0128 
0129 private:
0130 
0131    // FIXME: due to ROOT-10306 only data member of such kind can be correctly stored by ROOT I/O
0132    // Once problem fixed, one could make this container a base class
0133    std::unordered_map<std::string, std::unique_ptr<Value_t>> m; ///< JSON_object
0134 
0135    void AddBestMatch(const std::string &name, const std::string &value);
0136 
0137 public:
0138 
0139    RAttrMap() = default; ///< JSON_asbase - store as map object
0140 
0141    RAttrMap &Add(const std::string &name, std::unique_ptr<Value_t> &&value) { m[name] = std::move(value); return *this; }
0142    RAttrMap &AddNoValue(const std::string &name) { m[name] = std::make_unique<NoValue_t>(); return *this; }
0143    RAttrMap &AddBool(const std::string &name, bool value) { m[name] = std::make_unique<BoolValue_t>(value); return *this; }
0144    RAttrMap &AddInt(const std::string &name, int value) { m[name] = std::make_unique<IntValue_t>(value); return *this; }
0145    RAttrMap &AddDouble(const std::string &name, double value) { m[name] = std::make_unique<DoubleValue_t>(value); return *this; }
0146    RAttrMap &AddString(const std::string &name, const std::string &value) { m[name] = std::make_unique<StringValue_t>(value); return *this; }
0147    RAttrMap &AddPadLength(const std::string &name, const RPadLength &value)
0148    {
0149       if (value.Empty())
0150          Clear(name);
0151       else
0152          m[name] = std::make_unique<StringValue_t>(value.AsString());
0153       return *this;
0154    }
0155    RAttrMap &AddColor(const std::string &name, const RColor &value)
0156    {
0157       if (value.IsEmpty())
0158          Clear(name);
0159       else
0160          m[name] = std::make_unique<StringValue_t>(value.AsString());
0161       return *this;
0162    }
0163    RAttrMap &AddDefaults(const RAttrBase &vis);
0164 
0165    RAttrMap &AddValue(const std::string &name, bool value) { return AddBool(name, value); }
0166    RAttrMap &AddValue(const std::string &name, int value) { return AddInt(name, value); }
0167    RAttrMap &AddValue(const std::string &name, double value) { return AddDouble(name, value); }
0168    RAttrMap &AddValue(const std::string &name, const std::string &value) { return AddString(name, value); }
0169    RAttrMap &AddValue(const std::string &name, const RPadLength &value) { return AddPadLength(name, value); }
0170    RAttrMap &AddValue(const std::string &name, const RColor &value) { return AddColor(name, value); }
0171 
0172    RAttrMap(const RAttrMap &src)
0173    {
0174       for (const auto &pair : src.m)
0175          m[pair.first] = pair.second->Copy();
0176    }
0177 
0178    RAttrMap &operator=(const RAttrMap &src)
0179    {
0180       m.clear();
0181       for (const auto &pair : src.m)
0182          m[pair.first] = pair.second->Copy();
0183       return *this;
0184    }
0185 
0186    const Value_t *Find(const std::string &name) const
0187    {
0188       auto entry = m.find(name);
0189       return (entry != m.end()) ? entry->second.get() : nullptr;
0190    }
0191 
0192    /** Clear specified attribute */
0193    void Clear(const std::string &name)
0194    {
0195       auto entry = m.find(name);
0196       if (entry != m.end())
0197          m.erase(entry);
0198    }
0199 
0200    bool Change(const std::string &name, Value_t *value = nullptr);
0201 
0202    auto begin() const { return m.begin(); }
0203    auto end() const { return m.end(); }
0204 };
0205 
0206 template<> bool RAttrMap::Value_t::Get<bool>() const;
0207 template<> int RAttrMap::Value_t::Get<int>() const;
0208 template<> double RAttrMap::Value_t::Get<double>() const;
0209 template<> std::string RAttrMap::Value_t::Get<std::string>() const;
0210 template<> RPadLength RAttrMap::Value_t::Get<RPadLength>() const;
0211 template<> RColor RAttrMap::Value_t::Get<RColor>() const;
0212 
0213 template<> bool RAttrMap::Value_t::GetValue<bool,void>(const Value_t *rec);
0214 template<> int RAttrMap::Value_t::GetValue<int,void>(const Value_t *rec);
0215 template<> double RAttrMap::Value_t::GetValue<double,void>(const Value_t *rec);
0216 template<> std::string RAttrMap::Value_t::GetValue<std::string,void>(const Value_t *rec);
0217 template<> RPadLength RAttrMap::Value_t::GetValue<RPadLength,void>(const Value_t *rec);
0218 template<> RColor RAttrMap::Value_t::GetValue<RColor,void>(const Value_t *rec);
0219 
0220 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,void>(const Value_t *rec);
0221 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,bool>(const Value_t *rec);
0222 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,int>(const Value_t *rec);
0223 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,double>(const Value_t *rec);
0224 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,std::string>(const Value_t *rec);
0225 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,RPadLength>(const Value_t *rec);
0226 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,RColor>(const Value_t *rec);
0227 
0228 } // namespace Experimental
0229 } // namespace ROOT
0230 
0231 #endif // ROOT7_RAttrMap