|
|
- // This file is under GNU General Public License 3.0
- // see LICENSE.txt
-
- #ifndef LIBPEPDATATYPES_WRAPPER_HH
- #define LIBPEPDATATYPES_WRAPPER_HH
-
- #include <initializer_list>
- #include <iterator>
-
- namespace pEp
- {
-
- template<class T>
- class Wrapper
- {
- public:
- typedef T c_type;
-
- template<class... Args>
- Wrapper(Args... args) : value{ this->_new(args...) } {}
-
- // no implicit copying... (yet?)
- Wrapper(const Wrapper<T>&) = delete;
- void operator=(const Wrapper<T>&) = delete;
-
- // must be implemented separately for each T
- Wrapper(Wrapper<T>&& victim);
- Wrapper<T>& operator=(Wrapper<T>&& victim);
-
- ~Wrapper();
-
- Wrapper<T> copy() const;
-
- bool operator==(const Wrapper<T>& b) const
- {
- return value==b.value;
- }
-
- bool operator!=(const Wrapper<T>& b) const
- {
- return value!=b.value;
- }
-
- private:
- // must be defined for each wrapped type:
- template<class... Args>
- T _new(Args...);
-
- T value;
- };
-
-
- // many wrapped datatypes are pointers, we can generalize a lot for them:
- template<class T>
- class Wrapper<T*>
- {
- public:
- typedef T* c_type;
-
- Wrapper() : value{nullptr} {}
-
- template<class... Args>
- Wrapper(Args... args) : value{ this->_new(args...) } {}
-
- // move is easy, efficient and generic:
- Wrapper(Wrapper<T*>&& victim) noexcept
- : value{ victim.value}
- {
- victim.value = nullptr;
- }
-
- Wrapper<T*>& operator=(Wrapper<T*>&& victim) noexcept
- {
- _free(value);
- value = victim.value;
- victim.value = nullptr;
- return *this;
- }
-
- Wrapper(const Wrapper<T*>& orig)
- : value{ orig.copy_out() }
- {}
-
- Wrapper<T*>& operator=(const Wrapper<T*>& orig)
- {
- if(&orig == this) return *this;
- _free(value);
- value = orig.copy_out();
- return *this;
- }
-
- ~Wrapper()
- {
- _free(value);
- }
-
- bool operator==(const Wrapper<T*>& b) const
- {
- return value==b.value;
- }
-
- bool operator!=(const Wrapper<T*>& b) const
- {
- return value!=b.value;
- }
-
- const T* operator->() const { return value; }
- const T* get() const { return value; }
-
- // dangerous!
- T* operator->() { return value; }
- T* get() { return value;}
-
- T* move_out() { T* r = value; value=nullptr; return r;}
-
- // only implemented for the datatypes where necessay.
- // other implementations can follow if necessary.
- T* copy_out() const;
-
- protected:
-
- Wrapper(T* _value) : value{_value} {}
-
- // must be defined for each wrapped type:
- template<class... Args>
- T* _new(Args...);
-
- void _free(T*);
-
- T* value;
- };
-
-
-
- // Wraps single-linked lists and provides an interface compatible
- // to std::forward_list
- template<class T, class Element>
- class ListWrapper;
-
-
- template<class T, class Element>
- class ListWrapper<T*, Element> : public Wrapper<T*>
- {
- public:
- typedef Wrapper<T*> Base;
- typedef ListWrapper<T*, Element> LW;
-
- static Element T::* const Value; // to access the current value
-
- // does not own the *value
- class iterator : public std::iterator< std::forward_iterator_tag, Element, ptrdiff_t>
- {
- public:
-
- iterator() = default;
-
- iterator operator++() { return (value ? value = value->next : value); }
- Element operator*() { return value->*LW::Value; }
- Element operator->() { return value->*LW::Value; }
- bool operator==(const iterator& other) const { return value == other.value; }
- bool operator!=(const iterator& other) const { return value != other.value; }
-
- private:
- iterator(T* _t) : value{_t} {}
- T* value = nullptr;
- friend class ListWrapper<T*, Element>;
- };
-
-
- using Base::value;
-
- ListWrapper() : Base() {}
-
- ListWrapper(const std::initializer_list<pEp::Wrapper<Element>>& i);
- ListWrapper(const std::initializer_list<Element>& i);
-
- iterator begin() { return iterator{value}; }
- iterator end() const { return iterator{}; }
- int size() const;
- bool empty() const;
-
- void erase(const iterator& it);
- void clear();
- void push_back(Element&&);
- void push_back(Wrapper<Element>&&);
- };
-
- } // end of namespace pEp
-
- #endif // LIBPEPDATATYPES_WRAPPER_HH
|