From df1ef68cd8e8582724ce1192bfc202e0b9aeaf0c Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 28 Sep 2021 19:24:31 +0300 Subject: Get rid of C++ modules related code and rename *.mxx files to *.hxx --- libbutl/const-ptr.hxx | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 libbutl/const-ptr.hxx (limited to 'libbutl/const-ptr.hxx') diff --git a/libbutl/const-ptr.hxx b/libbutl/const-ptr.hxx new file mode 100644 index 0000000..f0ff706 --- /dev/null +++ b/libbutl/const-ptr.hxx @@ -0,0 +1,78 @@ +// file : libbutl/const-ptr.hxx -*- C++ -*- +// license : MIT; see accompanying LICENSE file + +#pragma once + +#include // nullptr_t + +#include + +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 left; + // const_ptr 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 (x.left). + // + template + 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 explicit const_ptr (T1* p): p_ (p) {} + template const_ptr (const_ptr& p): p_ (p.p_) {} + + template const_ptr& operator= (T1* p) {p_ = p; return *this;} + template const_ptr& operator= (const_ptr& 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_; + }; +} -- cgit v1.1