Advertisement
rockdrilla

smart_value<T>

Jun 9th, 2015
675
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.34 KB | None | 0 0
  1. ////////////////////////////////////////////
  2. // smart_value<T> definition
  3. ////////////////////////////////////////////
  4.  
  5. template<typename T, T Tdefault = T(), T Tinvalid = Tdefault>
  6. class smart_value final {
  7.     smart_value() {}
  8.  
  9. public:
  10.     class interface {
  11.     public:
  12.         virtual bool smart_value__is_valid(T value) const = 0;
  13.         virtual bool smart_value__is_valid() const = 0;
  14.  
  15.         virtual T smart_value__get() const = 0;
  16.         virtual void smart_value__set(T value) = 0;
  17.  
  18.         virtual operator T() const = 0;
  19.  
  20.         virtual bool operator == (const T& value) const = 0;
  21.         virtual bool operator == (const interface& other) const = 0;
  22.  
  23.         virtual const interface& operator = (const T& value) = 0;
  24.         virtual const interface& operator = (const interface& other) = 0;
  25.  
  26.         static constexpr const T& smart_value__default = Tdefault;
  27.         static constexpr const T& smart_value__invalid = Tinvalid;
  28.     };
  29.  
  30. private:
  31.     class base: public virtual smart_value::interface {
  32.     public:
  33.         base() {}
  34.  
  35.         virtual T smart_value__get() const override = 0;
  36.         virtual void smart_value__set(T value) override = 0;
  37.  
  38.         inline virtual bool smart_value__is_valid(T value) const override {
  39.             return true;
  40.         }
  41.  
  42.         inline virtual bool smart_value__is_valid() const override {
  43.             return true;
  44.         }
  45.  
  46.         inline virtual operator T() const override {
  47.             return smart_value__get();
  48.         }
  49.  
  50.         inline virtual bool operator == (const T& value) const override {
  51.             return (smart_value__get() == value);
  52.         }
  53.  
  54.         inline virtual bool operator == (const smart_value::interface& other) const override {
  55.             return (smart_value__get() == other.smart_value__get());
  56.         }
  57.  
  58.         inline virtual const smart_value::interface& operator = (const T& value) override {
  59.             smart_value__set(value);
  60.             return *this;
  61.         }
  62.  
  63.         inline virtual const smart_value::interface& operator = (const smart_value::interface& other) override {
  64.             smart_value__set(other.smart_value__get());
  65.             return *this;
  66.         }
  67.     };
  68.  
  69. public:
  70.     class container: public smart_value::base, public virtual smart_value::interface {
  71.         T _raw;
  72.  
  73.     public:
  74.         using smart_value::base::operator=;
  75.         using smart_value::base::operator==;
  76.         using smart_value::base::smart_value__is_valid;
  77.  
  78.         container() { smart_value__set(smart_value::interface::smart_value__default); }
  79.         container(T value) { smart_value__set(value); }
  80.  
  81.         // smart_value::interface
  82.         inline virtual T smart_value__get() const override {
  83.             if (!smart_value__is_valid()) return smart_value::interface::smart_value__default;
  84.             return _raw;
  85.         };
  86.         // smart_value::interface
  87.         inline virtual void smart_value__set(T value) override {
  88.             if (!smart_value__is_valid()) return;
  89.             if (!smart_value__is_valid(value)) return;
  90.             _raw = value;
  91.         }
  92.     };
  93.  
  94.     class pointer: public smart_value::base, public virtual smart_value::interface {
  95.         T* _ptr;
  96.  
  97.     public:
  98.         using smart_value::base::operator=;
  99.         using smart_value::base::operator==;
  100.         using smart_value::base::smart_value__is_valid;
  101.  
  102.         pointer() { _ptr = nullptr; }
  103.         pointer(T* ptr) { _ptr = ptr; }
  104.  
  105.         // smart_value::interface
  106.         inline virtual T smart_value__get() const override {
  107.             if (!smart_value__is_valid()) return smart_value::interface::smart_value__default;
  108.             return *(_ptr);
  109.         };
  110.         // smart_value::interface
  111.         inline virtual void smart_value__set(T value) override {
  112.             if (!smart_value__is_valid()) return;
  113.             if (!smart_value__is_valid(value)) return;
  114.             *(_ptr) = value;
  115.         }
  116.         // smart_value::interface
  117.         inline virtual bool smart_value__is_valid() const override {
  118.             return (_ptr == nullptr);
  119.         }
  120.         // smart_value::interface
  121.         inline bool operator == (const T& value) const override {
  122.             if (!smart_value__is_valid()) return false;
  123.             return (*(_ptr) == value);
  124.         }
  125.  
  126.         inline bool operator == (const T* ptr) const {
  127.             return (_ptr == ptr);
  128.         }
  129.  
  130.         inline bool operator == (const smart_value::pointer& other) const {
  131.             return (_ptr == other._ptr);
  132.         }
  133.  
  134.         inline const smart_value::interface& operator = (const T* ptr) {
  135.             _ptr = ptr;
  136.             return *this;
  137.         }
  138.  
  139.         inline const smart_value::interface& operator = (const smart_value::pointer& other) {
  140.             _ptr = other._ptr;
  141.             return *this;
  142.         }
  143.     };
  144.  
  145.     class deep_pointer: public smart_value::base, public virtual smart_value::interface {
  146.         void** _base;
  147.         size_t _offset;
  148.  
  149.         inline const T* _ptr() const {
  150.             return reinterpret_cast<const T*>(reinterpret_cast<size_t>(*_base) + _offset);
  151.         }
  152.  
  153.         inline T* _ptr() {
  154.             return reinterpret_cast<T*>(reinterpret_cast<size_t>(*_base) + _offset);
  155.         }
  156.  
  157.     public:
  158.         using smart_value::base::operator=;
  159.         using smart_value::base::operator==;
  160.         using smart_value::base::smart_value__is_valid;
  161.  
  162.         deep_pointer() {
  163.             _base = nullptr;
  164.             _offset = 0;
  165.         }
  166.  
  167.         template<typename B = void>
  168.         deep_pointer(B** base_ptr, T* offset_ptr): deep_pointer() {
  169.             if (base_ptr == nullptr) return;
  170.  
  171.             long loffset = reinterpret_cast<long>(offset_ptr) - reinterpret_cast<long>(*base_ptr);
  172.             if (loffset < 0) return;
  173.  
  174.             _base = reinterpret_cast<void**>(base_ptr);
  175.             _offset = static_cast<size_t>(loffset);
  176.         }
  177.  
  178.         // smart_value::interface
  179.         inline virtual bool smart_value__is_valid() const override {
  180.             if (_base == nullptr) return false;
  181.             if (*_base == nullptr) return false;
  182.             return true;
  183.         }
  184.         // smart_value::interface
  185.         inline virtual T smart_value__get() const override {
  186.             if (!smart_value__is_valid()) return smart_value::interface::smart_value__default;
  187.             return *(_ptr());
  188.         };
  189.         // smart_value::interface
  190.         inline virtual void smart_value__set(T value) override {
  191.             if (!smart_value__is_valid()) return;
  192.             if (!smart_value__is_valid(value)) return;
  193.             *(_ptr()) = value;
  194.         }
  195.         // smart_value::interface
  196.         inline bool operator == (const T& value) const override {
  197.             if (!smart_value__is_valid()) return false;
  198.             return (*(_ptr()) == value);
  199.         }
  200.  
  201.         inline bool operator == (const T* ptr) const {
  202.             return (_ptr() == ptr);
  203.         }
  204.  
  205.         inline bool operator == (const smart_value::deep_pointer& other) const {
  206.             return (_base == other._base) && (_offset == other._offset);
  207.         }
  208.  
  209.         inline const smart_value::interface& operator = (const smart_value::deep_pointer& other) {
  210.             _base = other._base;
  211.             _offset = other._offset;
  212.             return *this;
  213.         }
  214.     };
  215.  
  216.     template<class Cdst, class Cmid>
  217.     class proxy: public Cdst, public virtual smart_value::interface {
  218.         mutable Cmid _mid;
  219.  
  220.         static void constraints(void) {
  221.             Cdst a1; static_cast<smart_value::interface&>(a1);
  222.             Cmid a2; dynamic_cast<smart_value::interface&>(a2);
  223.         }
  224.  
  225.     public:
  226.         using Cdst::Cdst;
  227.         using Cdst::operator=;
  228.         using Cdst::operator==;
  229.         using Cdst::smart_value__is_valid;
  230.  
  231.         proxy(): Cdst() { void(*p)() = constraints; }
  232.  
  233.         // smart_value::interface
  234.         inline virtual T smart_value__get() const override {
  235.             if (!smart_value__is_valid()) return smart_value::interface::smart_value__default;
  236.  
  237.             _mid.smart_value__set(Cdst::smart_value__get());
  238.             if (!_mid.smart_value__is_valid()) return smart_value::interface::smart_value__default;
  239.  
  240.             return _mid.smart_value__get();
  241.         };
  242.         // smart_value::interface
  243.         inline virtual void smart_value__set(T value) override {
  244.             if (!smart_value__is_valid()) return;
  245.             if (!smart_value__is_valid(value)) return;
  246.  
  247.             if (!_mid.smart_value__is_valid(value)) return;
  248.             _mid.smart_value__set(value);
  249.             Cdst::smart_value__set(_mid.smart_value__get());
  250.         }
  251.     };
  252. };
  253.  
  254. ////////////////////////////////////////////
  255. // smart_value<T> usage examples
  256. ////////////////////////////////////////////
  257.  
  258. ////////////////////////////////////////////
  259. // example #1 : simple
  260. ////////////////////////////////////////////
  261.  
  262. class asn1 final {
  263.     asn1() {}
  264.  
  265. public:
  266.     class value: public smart_value<unsigned char, 0x00, 0xFF>::container {
  267.     public:
  268.         using container::container;
  269.         using container::operator=;
  270.         using container::operator==;
  271.         using container::smart_value__is_valid;
  272.         using container::smart_value__get;
  273.         using container::smart_value__set;
  274.     };
  275.  
  276.     class tag final: public value {
  277.     public:
  278.         using value::value;
  279.         using value::operator=;
  280.         using value::operator==;
  281.         using value::smart_value__is_valid;
  282.         using value::smart_value__get;
  283.         using value::smart_value__set;
  284.  
  285.         static const tag& eoc;               // 0x00
  286.         static const tag& boolean;           // 0x01
  287.         static const tag& integer;           // 0x02
  288.         static const tag& bit_string;        // 0x03
  289.         static const tag& octet_string;      // 0x04
  290.         static const tag& null;              // 0x05
  291.         static const tag& object_id;         // 0x06
  292.         static const tag& object_descriptor; // 0x07
  293.         static const tag& relative_oid;      // 0x0D
  294.         static const tag& sequence;          // 0x10
  295.         static const tag& set;               // 0x11
  296.         static const tag& long_form;         // 0x1F
  297.     };
  298.  
  299.     class type final: public value {
  300.     public:
  301.         using value::value;
  302.         using value::operator=;
  303.         using value::operator==;
  304.         using value::smart_value__is_valid;
  305.         using value::smart_value__get;
  306.         using value::smart_value__set;
  307.  
  308.         static const type& primitive; // 0x00
  309.         static const type& complex;   // 0x20
  310.     };
  311.  
  312.     class typeclass final: public value {
  313.     public:
  314.         using value::value;
  315.         using value::operator=;
  316.         using value::operator==;
  317.         using value::smart_value__is_valid;
  318.         using value::smart_value__get;
  319.         using value::smart_value__set;
  320.  
  321.         static const typeclass& universal;     // 0x00
  322.         static const typeclass& application;   // 0x40
  323.         static const typeclass& context;       // 0x80
  324.         static const typeclass& private_usage; // 0xC0
  325.     };
  326. };
  327.  
  328. const asn1::tag& asn1::tag::eoc(0x00);
  329. const asn1::tag& asn1::tag::boolean(0x01);
  330. const asn1::tag& asn1::tag::integer(0x02);
  331. const asn1::tag& asn1::tag::bit_string(0x03);
  332. const asn1::tag& asn1::tag::octet_string(0x04);
  333. const asn1::tag& asn1::tag::null(0x05);
  334. const asn1::tag& asn1::tag::object_id(0x06);
  335. const asn1::tag& asn1::tag::object_descriptor(0x07);
  336. const asn1::tag& asn1::tag::relative_oid(0x0D);
  337. const asn1::tag& asn1::tag::sequence(0x10);
  338. const asn1::tag& asn1::tag::set(0x11);
  339. const asn1::tag& asn1::tag::long_form(0x1F);
  340.  
  341. const asn1::type& asn1::type::primitive(0x00);
  342. const asn1::type& asn1::type::complex(0x20);
  343.  
  344. const asn1::typeclass& asn1::typeclass::universal(0x00);
  345. const asn1::typeclass& asn1::typeclass::application(0x40);
  346. const asn1::typeclass& asn1::typeclass::context(0x80);
  347. const asn1::typeclass& asn1::typeclass::private_usage(0xC0);
  348.  
  349. ////////////////////////////////////////////
  350. // example #2 : a little bit complex
  351. ////////////////////////////////////////////
  352.  
  353. class pdutype final: public smart_value<int, 0, 0xFFFF>::container {
  354. public:
  355.     using container::container;
  356.     using container::operator=;
  357.     using container::operator==;
  358.     using container::smart_value__is_valid;
  359.     using container::smart_value__get;
  360.     using container::smart_value__set;
  361.  
  362.     inline bool smart_value__is_valid(int value) const override;
  363.  
  364.     static const pdutype& get;      // 160
  365.     static const pdutype& getnext;  // 161
  366.     static const pdutype& response; // 162
  367.     static const pdutype& set;      // 163
  368.     static const pdutype& trap;     // 164
  369.     static const pdutype& getbulk;  // 165
  370.     static const pdutype& inform;   // 166
  371.     static const pdutype& trap2;    // 167
  372.     static const pdutype& report;   // 168
  373. };
  374.  
  375. inline bool pdutype::smart_value__is_valid(int value) const {
  376.     switch(value) {
  377.     case 160:
  378.     case 161:
  379.     case 162:
  380.     case 163:
  381.     case 164:
  382.     case 165:
  383.     case 166:
  384.     case 167:
  385.     case 168:
  386.         return true;
  387.     default:
  388.         return false;
  389.     }
  390. }
  391.  
  392. const pdutype& pdutype::get(160);
  393. const pdutype& pdutype::getnext(161);
  394. const pdutype& pdutype::response(162);
  395. const pdutype& pdutype::set(163);
  396. const pdutype& pdutype::trap(164);
  397. const pdutype& pdutype::getbulk(165);
  398. const pdutype& pdutype::inform(166);
  399. const pdutype& pdutype::trap2(167);
  400. const pdutype& pdutype::report(168);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement