diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2017-05-01 16:08:43 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2017-05-01 16:59:24 +0300 |
commit | 61377c582e0f2675baa5f5e6e30a35d1a4164b33 (patch) | |
tree | 11cdca992834d7f7f197f72856712fbcb3020e3d /libbutl/const-ptr.hxx | |
parent | 442c1a6790e52baa0c081f310d4d9e9b6f1ff638 (diff) |
Add hxx extension for headers and lib prefix for library dir
Diffstat (limited to 'libbutl/const-ptr.hxx')
-rw-r--r-- | libbutl/const-ptr.hxx | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/libbutl/const-ptr.hxx b/libbutl/const-ptr.hxx new file mode 100644 index 0000000..e50704d --- /dev/null +++ b/libbutl/const-ptr.hxx @@ -0,0 +1,80 @@ +// file : libbutl/const-ptr.hxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef LIBBUTL_CONST_PTR_HXX +#define LIBBUTL_CONST_PTR_HXX + +#include <cstddef> // nullptr_t + +namespace butl +{ + // Const-propagating pointer. + // + // It has the semantics of a raw pointer except that it passes on its own + // const-ness to the pointed-to object. In other words, if you have a const + // instance of this pointer, then you can only obtain a const raw pointer to + // the underlying object. It is normally used as a data member, for example: + // + // struct tree + // { + // const_ptr<tree> left; + // const_ptr<tree> right; + // + // void modify (); + // }; + // + // tree* x = ...; + // const tree* y = ...; + // + // x.left->modify (); // Ok. + // y.left->modify (); // Error. + // + // Note that due to this semantics, copy construction/assignment requires + // a non-const instance of const_ptr. + // + // Note that this type is standard layout (which means we can reinterpret + // it as a raw pointer). + // + // Known drawbacks/issues: + // + // 1. Cannot do static_cast<mytree*> (x.left). + // + template <typename T> + class const_ptr + { + public: + const_ptr () = default; + explicit const_ptr (T* p): p_ (p) {} + const_ptr (std::nullptr_t): p_ (nullptr) {} + + const_ptr& operator= (T* p) {p_ = p; return *this;} + const_ptr& operator= (std::nullptr_t) {p_ = nullptr; return *this;} + + template <class T1> explicit const_ptr (T1* p): p_ (p) {} + template <class T1> const_ptr (const_ptr<T1>& p): p_ (p.p_) {} + + template <class T1> const_ptr& operator= (T1* p) {p_ = p; return *this;} + template <class T1> const_ptr& operator= (const_ptr<T1>& p) { + p_ = p.p_; return *this;} + + T* operator-> () {return p_;} + const T* operator-> () const {return p_;} + + T& operator* () {return *p_;} + const T& operator* () const {return *p_;} + + operator T* () {return p_;} + operator const T* () const {return p_;} + + explicit operator bool () const {return p_ != nullptr;} + + T* get () {return p_;} + const T* get () const {return p_;} + + private: + T* p_; + }; +} + +#endif // LIBBUTL_CONST_PTR_HXX |