/* */ #ifndef D_VALUE_BASE_H #define D_VALUE_BASE_H #include "common.h" #include #include #include #include #include "a2functional.h" namespace aria2 { class ValueBaseVisitor; class ValueBase { public: virtual ~ValueBase() {} virtual void accept(ValueBaseVisitor& visitor) const = 0; }; class String; class Integer; class Bool; class Null; class List; class Dict; class ValueBaseVisitor { public: virtual ~ValueBaseVisitor() {} virtual void visit(const String& string) = 0; virtual void visit(const Integer& integer) = 0; virtual void visit(const Bool& boolValue) = 0; virtual void visit(const Null& nullValue) = 0; virtual void visit(const List& list) = 0; virtual void visit(const Dict& dict) = 0; }; class String : public ValueBase { public: typedef std::string ValueType; String(const ValueType& string); String(ValueType&& string); explicit String(const char* cstring); String(const char* data, size_t length); String(const unsigned char* data, size_t length); template String(InputIterator first, InputIterator last) : str_(first, last) { } String(); // Don't allow copying String(const String&) = delete; String& operator=(const String&) = delete; const ValueType& s() const; ValueType popValue() const; // Returns std::string.data() cast to unsigned char*. // Use s().size() to get length. const unsigned char* uc() const; static std::unique_ptr g(const ValueType& string); static std::unique_ptr g(ValueType&& string); static std::unique_ptr g(const unsigned char* data, size_t length); template static std::unique_ptr g(InputIterator first, InputIterator last) { return make_unique(first, last); } virtual void accept(ValueBaseVisitor& visitor) const CXX11_OVERRIDE; private: ValueType str_; }; class Integer : public ValueBase { public: typedef int64_t ValueType; Integer(ValueType integer); Integer(); // Don't allow copying Integer(const Integer&) = delete; Integer& operator=(const Integer&) = delete; // Returns Integer. ValueType i() const; static std::unique_ptr g(ValueType integer); virtual void accept(ValueBaseVisitor& visitor) const CXX11_OVERRIDE; private: ValueType integer_; }; class Bool : public ValueBase { public: static std::unique_ptr gTrue(); static std::unique_ptr gFalse(); Bool(bool val); bool val() const; virtual void accept(ValueBaseVisitor& visitor) const CXX11_OVERRIDE; private: // Don't allow copying Bool(const Bool&) = delete; Bool& operator=(const Bool&) = delete; bool val_; }; class Null : public ValueBase { public: static std::unique_ptr g(); Null(); virtual void accept(ValueBaseVisitor& visitor) const CXX11_OVERRIDE; private: // Don't allow copying Null(const Null&); Null& operator=(const Null&); }; class List : public ValueBase { public: typedef std::deque> ValueType; List(); // Don't allow copying List(const List&) = delete; List& operator=(const List&) = delete; // Appends given v to list. void append(std::unique_ptr v); // Appending string is so common that we provide shortcut function. void append(String::ValueType string); // Alias for append() List& operator<<(std::unique_ptr v); // Returns the object at given index. ValueBase* get(size_t index) const; // Set the object at given index. void set(size_t index, std::unique_ptr v); // Returns the const reference of the object at the given index. ValueBase* operator[](size_t index) const; // Pops the value in the front of the list. void pop_front(); // Pops the value in the back of the list. void pop_back(); // Returns a read/write iterator that points to the first object in // list. ValueType::iterator begin(); // Returns a read/write iterator that points to the one past the // last object in list. ValueType::iterator end(); // Returns a read/write read-only iterator that points to the first // object in list. ValueType::const_iterator begin() const; // Returns a read/write read-only iterator that points to the one // past the last object in list. ValueType::const_iterator end() const; // Returns a read/write read-only iterator that points to the first // object in list. ValueType::const_iterator cbegin() const; // Returns a read/write read-only iterator that points to the one // past the last object in list. ValueType::const_iterator cend() const; // Returns size of list. size_t size() const; // Returns true if size of list is 0. bool empty() const; static std::unique_ptr g(); virtual void accept(ValueBaseVisitor& visitor) const CXX11_OVERRIDE; private: ValueType list_; }; class Dict : public ValueBase { public: typedef std::map> ValueType; Dict(); // Don't allow copying Dict(const Dict&) = delete; Dict& operator=(const Dict&) = delete; void put(std::string key, std::unique_ptr vlb); // Putting string is so common that we provide shortcut function. void put(std::string key, String::ValueType string); ValueBase* get(const std::string& key) const; // Returns the reference to object associated with given key. If // the key is not found, nullptr is returned. ValueBase* operator[](const std::string& key) const; // Returns true if the given key is found in dict. bool containsKey(const std::string& key) const; // Removes specified key from dict. void removeKey(const std::string& key); // Removes specified key from dict and return its associated value. std::unique_ptr popValue(const std::string& key); // Returns a read/write iterator that points to the first pair in // the dict. ValueType::iterator begin(); // Returns a read/write read-only iterator that points to one past // the last pair in the dict. ValueType::iterator end(); // Returns a read/write read-only iterator that points to the first // pair in the dict. ValueType::const_iterator begin() const; // Returns a read/write read-only iterator that points to one past // the last pair in the dict. ValueType::const_iterator end() const; // Returns a read/write read-only iterator that points to the first // pair in the dict. ValueType::const_iterator cbegin() const; // Returns a read/write read-only iterator that points to one past // the last pair in the dict. ValueType::const_iterator cend() const; // Returns size of Dict. size_t size() const; // Returns true if size of Dict is 0. bool empty() const; static std::unique_ptr g(); virtual void accept(ValueBaseVisitor& visitor) const CXX11_OVERRIDE; private: ValueType dict_; }; class EmptyDowncastValueBaseVisitor : public ValueBaseVisitor { public: EmptyDowncastValueBaseVisitor() {} virtual void visit(const String& v) CXX11_OVERRIDE {} virtual void visit(const Integer& v) CXX11_OVERRIDE {} virtual void visit(const Bool& v) CXX11_OVERRIDE {} virtual void visit(const Null& v) CXX11_OVERRIDE {} virtual void visit(const List& v) CXX11_OVERRIDE {} virtual void visit(const Dict& v) CXX11_OVERRIDE {} }; template class DowncastValueBaseVisitor : public EmptyDowncastValueBaseVisitor { public: DowncastValueBaseVisitor() : result_{nullptr} {} virtual void visit(const T& t) { result_ = &t; } const T* getResult() const { return result_; } void setResult(const T* r) { result_ = r; } private: const T* result_; }; template T* downcast(const VPtr& v) { if (v) { DowncastValueBaseVisitor visitor; v->accept(visitor); return const_cast(visitor.getResult()); } else { return 0; } } } // namespace aria2 #endif // D_VALUE_BASE_H