value.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #pragma once
  2. #include <typeinfo>
  3. #include <util/generic/ptr.h>
  4. #include <util/generic/cast.h>
  5. #include <util/generic/string.h>
  6. #include <util/generic/typetraits.h>
  7. class IOutputStream;
  8. namespace NConfig {
  9. class IValue: public TAtomicRefCount<IValue> {
  10. public:
  11. virtual ~IValue() = default;
  12. virtual bool IsA(const std::type_info& info) const = 0;
  13. virtual TString TypeName() const = 0;
  14. virtual void* Ptr() const = 0;
  15. virtual ui64 AsUInt() const = 0;
  16. virtual i64 AsInt() const = 0;
  17. virtual double AsDouble() const = 0;
  18. virtual bool AsBool() const = 0;
  19. virtual TString AsString() const = 0;
  20. virtual void ToJson(IOutputStream& out) const = 0;
  21. };
  22. namespace NCfgPrivate {
  23. struct TDummy {
  24. };
  25. template <class T>
  26. inline IValue* ConstructValueImpl(const T& t, ...) {
  27. extern IValue* ConstructValueImpl(const T& t);
  28. return ConstructValueImpl(t);
  29. }
  30. template <class T, std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
  31. inline IValue* ConstructValueImpl(const T& t, TDummy) {
  32. extern IValue* ConstructValueImpl(const double& t);
  33. return ConstructValueImpl(t);
  34. }
  35. template <class T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
  36. inline IValue* ConstructValueImpl(const T& t, TDummy) {
  37. typedef std::conditional_t<std::is_signed<T>::value, i64, ui64> Type;
  38. extern IValue* ConstructValueImpl(const Type& t);
  39. return ConstructValueImpl(t);
  40. }
  41. template <class T, std::enable_if_t<std::is_convertible<T, TString>::value>* = nullptr>
  42. inline IValue* ConstructValueImpl(const T& t, TDummy) {
  43. extern IValue* ConstructValueImpl(const TString& t);
  44. return ConstructValueImpl(t);
  45. }
  46. inline IValue* ConstructValueImpl(const bool& t, TDummy) {
  47. extern IValue* ConstructValueImpl(const bool& t);
  48. return ConstructValueImpl(t);
  49. }
  50. }
  51. template <class T>
  52. inline IValue* ConstructValue(const T& t) {
  53. return NCfgPrivate::ConstructValueImpl(t, NCfgPrivate::TDummy());
  54. }
  55. IValue* Null();
  56. namespace NCfgPrivate {
  57. template <bool Unsigned>
  58. struct TSelector {
  59. static inline ui64 Cvt(const IValue* v) {
  60. return v->AsUInt();
  61. }
  62. };
  63. template <>
  64. struct TSelector<false> {
  65. static inline i64 Cvt(const IValue* v) {
  66. return v->AsInt();
  67. }
  68. };
  69. [[noreturn]] void ReportTypeMismatch(TStringBuf realType, TStringBuf expectedType);
  70. }
  71. template <class T>
  72. inline T ValueAs(const IValue* val) {
  73. typedef NCfgPrivate::TSelector<std::is_unsigned<T>::value> TCvt;
  74. return SafeIntegerCast<T>(TCvt::Cvt(val));
  75. }
  76. template <>
  77. inline double ValueAs(const IValue* val) {
  78. return val->AsDouble();
  79. }
  80. template <>
  81. inline float ValueAs(const IValue* val) {
  82. return (float)val->AsDouble();
  83. }
  84. template <>
  85. inline bool ValueAs(const IValue* val) {
  86. return val->AsBool();
  87. }
  88. template <>
  89. inline TString ValueAs(const IValue* val) {
  90. return val->AsString();
  91. }
  92. }