Logo ROOT  
Reference Guide
RAttrMap.cxx
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
3  * All rights reserved. *
4  * *
5  * For the licensing terms see $ROOTSYS/LICENSE. *
6  * For the list of contributors see $ROOTSYS/README/CREDITS. *
7  *************************************************************************/
8 
9 #include "ROOT/RAttrMap.hxx"
10 
11 #include "ROOT/RAttrBase.hxx"
12 #include "ROOT/RLogger.hxx"
13 
14 #include <string>
15 #include <algorithm>
16 #include <limits>
17 
18 using namespace ROOT::Experimental;
19 
20 using namespace std::string_literals;
21 
22 template<> bool RAttrMap::Value_t::Get<bool>() const { return GetBool(); }
23 template<> int RAttrMap::Value_t::Get<int>() const { return GetInt(); }
24 template<> double RAttrMap::Value_t::Get<double>() const { return GetDouble(); }
25 template<> std::string RAttrMap::Value_t::Get<std::string>() const { return GetString(); }
26 template<> RPadLength RAttrMap::Value_t::Get<RPadLength>() const { return GetString(); }
27 
28 template<> bool RAttrMap::Value_t::GetValue<bool,void>(const Value_t *rec) { return rec ? rec->GetBool() : false; }
29 template<> int RAttrMap::Value_t::GetValue<int,void>(const Value_t *rec) { return rec ? rec->GetInt() : 0; }
30 template<> double RAttrMap::Value_t::GetValue<double,void>(const Value_t *rec) { return rec ? rec->GetDouble() : 0.; }
31 template<> std::string RAttrMap::Value_t::GetValue<std::string,void>(const Value_t *rec) { return rec ? rec->GetString() : ""s; }
32 template<> RPadLength RAttrMap::Value_t::GetValue<RPadLength,void>(const Value_t *rec) { return rec ? rec->GetString() : ""s; }
33 
34 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,void>(const Value_t *rec) { return rec; }
35 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,bool>(const Value_t *rec) { return rec && rec->CanConvertTo(RAttrMap::kBool) ? rec : nullptr; }
36 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,int>(const Value_t *rec) { return rec && rec->CanConvertTo(RAttrMap::kInt) ? rec : nullptr; }
37 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,double>(const Value_t *rec) { return rec && rec->CanConvertTo(RAttrMap::kDouble) ? rec : nullptr; }
38 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,std::string>(const Value_t *rec) { return rec && rec->CanConvertTo(RAttrMap::kString) ? rec : nullptr; }
39 template<> const RAttrMap::Value_t *RAttrMap::Value_t::GetValue<const RAttrMap::Value_t *,RPadLength>(const Value_t *rec) { return rec && rec->CanConvertTo(RAttrMap::kString) ? rec : nullptr; }
40 
41 
42 /////////////////////////////////////////////////////////////////////////////////////////////////
43 /// Add defaults values form sub attribute
44 
46 {
47  auto prefix = vis.GetPrefix();
48 
49  for (const auto &entry : vis.GetDefaults())
50  m[prefix+entry.first] = entry.second->Copy();
51 
52  return *this;
53 }
54 
55 /////////////////////////////////////////////////////////////////////////////////////////////////
56 /// Add attribute, converting to best possible type
57 /// Tested boolean, int, double. If none works - store as a string
58 
59 void RAttrMap::AddBestMatch(const std::string &name, const std::string &value)
60 {
61  if ((value == "none"s) || (value == "null"s) || value.empty()) {
62  AddNoValue(name);
63  return;
64  }
65 
66  if (value == "true"s) {
67  AddBool(name, true);
68  return;
69  }
70 
71  if (value == "false"s) {
72  AddBool(name, false);
73  return;
74  }
75 
76  auto beg = value.begin();
77  int base = 10;
78  bool int_conversion_fails = false;
79 
80  if (*beg == '-') {
81  ++beg;
82  } else if ((value.length() > 2) && (*beg == '0') && (value[1] == 'x')) {
83  beg += 2;
84  base = 16;
85  }
86 
87  // check if only digits are present
88  if (std::find_if(beg, value.end(), [](unsigned char c) { return !std::isdigit(c); }) == value.end()) {
89 
90  try {
91 
92  auto ivalue = std::stoll(base == 16 ? value.substr(2) : value, nullptr, base);
93 
94  if ((ivalue >= std::numeric_limits<int>::min()) && (ivalue <= std::numeric_limits<int>::max()))
95  AddInt(name, ivalue);
96  else
97  AddDouble(name, ivalue);
98 
99  return;
100  } catch (...) {
101  // int conversion fails
102  int_conversion_fails = true;
103  }
104  }
105 
106  // check if characters for double is present
107  if (!int_conversion_fails && std::find_if(beg, value.end(), [](unsigned char c) {
108  return !std::isdigit(c) && (c != '.') && (c != '-') && (c != '+') && (c != 'e');
109  }) == value.end()) {
110  try {
111  double dvalue = std::stod(value);
112  AddDouble(name, dvalue);
113  return;
114  } catch (...) {
115  // do nothing
116  }
117  }
118 
119  AddString(name, value);
120 }
121 
122 /////////////////////////////////////////////////////////////////////////////////////////////////
123 /// Change attribute using string value and kind
124 /// Used to change attributes from JS side
125 /// Returns true if value was really changed
126 
127 bool RAttrMap::Change(const std::string &name, Value_t *value)
128 {
129  auto entry = m.find(name);
130  if ((entry == m.end()) || (entry->second->Kind() == kNoValue)) {
131  if (!value) return false;
132  m[name] = value->Copy();
133  return true;
134  }
135 
136  // specify nullptr means clear attribute
137  if (!value) {
138  m.erase(entry);
139  return true;
140  }
141 
142  // error situation - conversion cannot be performed
143  if(!value->CanConvertTo(entry->second->Kind())) {
144  R__ERROR_HERE("gpadv7") << "Wrong data type provided for attribute " << name;
145  return false;
146  }
147 
148  // no need to change something
149  if (entry->second->IsEqual(*value))
150  return false;
151 
152  switch (entry->second->Kind()) {
153  case kNoValue: break; // just to avoid compiler warnings
154  case kBool: AddBool(name, value->GetBool()); break;
155  case kInt: AddInt(name, value->GetInt()); break;
156  case kDouble: AddDouble(name, value->GetDouble()); break;
157  case kString: AddString(name, value->GetString()); break;
158  }
159 
160  return true;
161 }
c
#define c(i)
Definition: RSha256.hxx:101
m
auto * m
Definition: textangle.C:8
ROOT::Experimental::RAttrMap::kString
@ kString
Definition: RAttrMap.hxx:40
RAttrBase.hxx
ROOT::Experimental::RAttrMap::Value_t
Definition: RAttrMap.hxx:42
ROOT::Experimental::RAttrMap
Definition: RAttrMap.hxx:33
TGeant4Unit::s
static constexpr double s
Definition: TGeant4SystemOfUnits.h:162
ROOT::Experimental::RAttrBase
Base class for all attributes, used with RDrawable.
Definition: RAttrBase.hxx:27
ROOT::Experimental::RAttrMap::AddDefaults
RAttrMap & AddDefaults(const RAttrBase &vis)
Add defaults values form sub attribute.
Definition: RAttrMap.cxx:45
ROOT::Experimental::RAttrMap::kDouble
@ kDouble
Definition: RAttrMap.hxx:40
ROOT::Experimental::RPadLength
A length in RPad.
Definition: RPadLength.hxx:31
RLogger.hxx
ROOT::Experimental::RAttrMap::Value_t::GetString
virtual std::string GetString() const
Definition: RAttrMap.hxx:51
R__ERROR_HERE
#define R__ERROR_HERE(GROUP)
Definition: RLogger.hxx:183
ROOT::Experimental::RAttrMap::Value_t::CanConvertTo
virtual bool CanConvertTo(EValuesKind kind) const
Definition: RAttrMap.hxx:47
RAttrMap.hxx
ROOT::Experimental::RAttrMap::Value_t::GetBool
virtual bool GetBool() const
Definition: RAttrMap.hxx:48
ROOT::Experimental::RAttrBase::GetDefaults
virtual const RAttrMap & GetDefaults() const
Return default values for attributes, empty for base class.
Definition: RAttrBase.cxx:22
ROOT::Experimental::RAttrMap::Value_t::Copy
virtual std::unique_ptr< Value_t > Copy() const =0
ROOT::Experimental::RAttrMap::AddBestMatch
void AddBestMatch(const std::string &name, const std::string &value)
Add attribute, converting to best possible type Tested boolean, int, double.
Definition: RAttrMap.cxx:59
ROOT::Experimental::RAttrMap::Value_t::GetInt
virtual int GetInt() const
Definition: RAttrMap.hxx:49
ROOT::Experimental::RAttrMap::kInt
@ kInt
Definition: RAttrMap.hxx:40
ROOT::Experimental::RAttrMap::Change
bool Change(const std::string &name, Value_t *value=nullptr)
Change attribute using string value and kind Used to change attributes from JS side Returns true if v...
Definition: RAttrMap.cxx:127
name
char name[80]
Definition: TGX11.cxx:110
ROOT::Experimental::RAttrMap::kBool
@ kBool
Definition: RAttrMap.hxx:40
ROOT::Experimental::RAttrMap::Value_t::GetDouble
virtual double GetDouble() const
Definition: RAttrMap.hxx:50
ROOT::Experimental
Definition: RDirectory.hxx:30
ROOT::Experimental::RAttrBase::GetPrefix
const std::string & GetPrefix() const
Definition: RAttrBase.hxx:156