1 #pragma once
2 
3 #ifndef TCG_PTR_WRAPPER
4 #define TCG_PTR_WRAPPER
5 
6 // STD includes
7 #include <iterator>
8 
9 namespace tcg {
10 
11 /*!
12   \brief    The ptr_wrapper class implements the basic functions necessary
13             to wrap a generic pointer object. The use case for this class
14             is to allow pointer inheritance.
15 */
16 
17 template <typename T>
18 class ptr {
19 public:
20   typedef T *ptr_type;
21 
22   typedef typename std::iterator_traits<ptr_type>::iterator_category
23       iterator_category;
24   typedef typename std::iterator_traits<ptr_type>::value_type value_type;
25   typedef
26       typename std::iterator_traits<ptr_type>::difference_type difference_type;
27   typedef typename std::iterator_traits<ptr_type>::pointer pointer;
28   typedef typename std::iterator_traits<ptr_type>::reference reference;
29 
30 public:
m_ptr(p)31   explicit ptr(ptr_type p = ptr_type()) : m_ptr(p) {}
32 
33   operator bool() const { return m_ptr; }  // There should be no need to use
34                                            // the Safe Bool idiom
35   bool operator==(const ptr &other) const { return (m_ptr == other.m_ptr); }
36   bool operator!=(const ptr &other) const { return (m_ptr != other.m_ptr); }
37 
38   bool operator<(const ptr &other) const { return (m_ptr < other.m_ptr); }
39   bool operator>(const ptr &other) const { return (m_ptr > other.m_ptr); }
40   bool operator<=(const ptr &other) const { return (m_ptr <= other.m_ptr); }
41   bool operator>=(const ptr &other) const { return (m_ptr >= other.m_ptr); }
42 
43   ptr &operator++() {
44     ++m_ptr;
45     return *this;
46   }
47   ptr operator++(int) { return ptr(m_ptr++, *this); }
48 
49   ptr &operator--() {
50     --m_ptr;
51     return *this;
52   }
53   ptr operator--(int) { return ptr(m_ptr--, *this); }
54 
55   ptr operator+(difference_type d) const { return ptr(m_ptr + d, *this); }
56   ptr &operator+=(difference_type d) {
57     m_ptr += d;
58     return *this;
59   }
60 
61   ptr operator-(difference_type d) const { return ptr(m_ptr - d, *this); }
62   ptr &operator-=(difference_type d) {
63     m_ptr -= d;
64     return *this;
65   }
66 
67   difference_type operator-(const ptr &other) const {
68     return m_ptr - other.m_ptr;
69   }
70 
71   pointer operator->() const { return m_ptr; }
72   reference operator*() const { return *m_ptr; }
73   reference operator[](difference_type d) const { return m_ptr[d]; }
74 
75 protected:
76   ptr_type m_ptr;
77 };
78 
79 //=======================================================
80 
81 template <typename T>
make_ptr(T * p)82 ptr<T> make_ptr(T *p) {
83   return ptr<T>(p);
84 }
85 
86 }  // namespace tcg
87 
88 #endif  // TCG_PTR_WRAPPER
89