File indexing completed on 2025-01-30 10:22:25
0001
0002
0003
0004
0005
0006
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
0027
0028
0029
0030
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};
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};
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};
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;
0116 public:
0117 StringValue_t(const std::string _v = "") : v(_v) {}
0118 EValuesKind Kind() const final { return kString; }
0119
0120 bool CanConvertFrom(EValuesKind) const final { return true; }
0121
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
0132
0133 std::unordered_map<std::string, std::unique_ptr<Value_t>> m;
0134
0135 void AddBestMatch(const std::string &name, const std::string &value);
0136
0137 public:
0138
0139 RAttrMap() = default;
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
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 }
0229 }
0230
0231 #endif