From 2342ac64337a4455c707d4623cca50d3022fa54a Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Sat, 15 Mar 2014 23:02:13 +0900 Subject: [PATCH] add exempt_ptr --- sprout/exempt_ptr.hpp | 249 +++++++++++++++++++++++++++++++++++++++++ testspr/header_all.hpp | 1 + 2 files changed, 250 insertions(+) create mode 100644 sprout/exempt_ptr.hpp diff --git a/sprout/exempt_ptr.hpp b/sprout/exempt_ptr.hpp new file mode 100644 index 00000000..630c3cfc --- /dev/null +++ b/sprout/exempt_ptr.hpp @@ -0,0 +1,249 @@ +/*============================================================================= + Copyright (c) 2011-2014 Bolero MURAKAMI + https://github.com/bolero-MURAKAMI/Sprout + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef SPROUT_EXEMPT_PTR_HPP +#define SPROUT_EXEMPT_PTR_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // exempt_ptr + // + template + class exempt_ptr { + public: + typedef T value_type; + typedef T* pointer; + typedef T const* const_pointer; + typedef T& reference; + typedef T const& const_reference; + typedef std::ptrdiff_t difference_type; + typedef std::random_access_iterator_tag iterator_category; + private: + pointer p_; + private: + template + static SPROUT_CONSTEXPR bool is_compat() { + return std::is_convertible::value; + } + public: + SPROUT_CONSTEXPR exempt_ptr() SPROUT_NOEXCEPT + : p_() + {} + SPROUT_CONSTEXPR exempt_ptr(std::nullptr_t) SPROUT_NOEXCEPT + : exempt_ptr() + {} + explicit SPROUT_CONSTEXPR exempt_ptr(pointer other) SPROUT_NOEXCEPT + : p_(other) + {} + template< + typename U, + typename sprout::enabler_if::value>::type = sprout::enabler + > + explicit SPROUT_CONSTEXPR exempt_ptr(U* other) SPROUT_NOEXCEPT + : p_(other) + {} + template< + typename U, + typename sprout::enabler_if::value>::type = sprout::enabler + > + SPROUT_CONSTEXPR exempt_ptr(sprout::exempt_ptr const& other) SPROUT_NOEXCEPT + : p_(other.get()) + {} + SPROUT_CXX14_CONSTEXPR exempt_ptr& + operator=(std::nullptr_t) SPROUT_NOEXCEPT { + reset(); + return *this; + } + template< + typename U, + typename sprout::enabler_if::value>::type = sprout::enabler + > + SPROUT_CXX14_CONSTEXPR exempt_ptr& + operator=(U* other) SPROUT_NOEXCEPT { + reset(other); + return *this; + } + template< + typename U, + typename sprout::enabler_if::value>::type = sprout::enabler + > + SPROUT_CXX14_CONSTEXPR exempt_ptr& + operator=(exempt_ptr const& other) SPROUT_NOEXCEPT { + reset(other.get()); + return *this; + } + SPROUT_CONSTEXPR pointer + get() const SPROUT_NOEXCEPT { + return p_; + } + SPROUT_CONSTEXPR reference + operator*() const SPROUT_NOEXCEPT { + return *get(); + } + SPROUT_CONSTEXPR pointer + operator->() const SPROUT_NOEXCEPT { + return get(); + } + SPROUT_EXPLICIT_CONVERSION SPROUT_CONSTEXPR operator bool() const SPROUT_NOEXCEPT { + return get(); + } + SPROUT_CONSTEXPR operator pointer() SPROUT_NOEXCEPT { + return get(); + } + SPROUT_CONSTEXPR operator const_pointer() const SPROUT_NOEXCEPT { + return get(); + } + SPROUT_CXX14_CONSTEXPR pointer + release() SPROUT_NOEXCEPT { + pointer old = get(); + reset(); + return old; + } + SPROUT_CXX14_CONSTEXPR void + reset(pointer t = 0) SPROUT_NOEXCEPT { + p_ = t; + } + SPROUT_CXX14_CONSTEXPR void + swap(exempt_ptr& other) SPROUT_NOEXCEPT { + swap(p_, other.p_); + } + SPROUT_CXX14_CONSTEXPR exempt_ptr& + operator++() { + ++p_; + return *this; + } + SPROUT_CXX14_CONSTEXPR exempt_ptr& + operator--() { + --p_; + return *this; + } + SPROUT_CXX14_CONSTEXPR exempt_ptr operator++(int) { + pointer tmp = p_; ++p_; return exempt_ptr{tmp}; + } + SPROUT_CXX14_CONSTEXPR exempt_ptr operator--(int) { + pointer tmp = p_; --p_; return exempt_ptr{tmp}; + } + SPROUT_CXX14_CONSTEXPR exempt_ptr + operator+() const { + return *this; } + SPROUT_CXX14_CONSTEXPR exempt_ptr + operator+(std::ptrdiff_t d) const { + return exempt_ptr{p_+d}; + } + SPROUT_CXX14_CONSTEXPR exempt_ptr + operator-(std::ptrdiff_t d) const { + return exempt_ptr{p_-d}; + } + SPROUT_CXX14_CONSTEXPR value_type& + operator[](std::ptrdiff_t k) { + return p_[k]; + } + SPROUT_CXX14_CONSTEXPR value_type const& + operator[](std::ptrdiff_t k) const { + return p_[k]; + } + }; + // + // swap + // + template + inline SPROUT_CXX14_CONSTEXPR void + swap(sprout::exempt_ptr& x, sprout::exempt_ptr& y) SPROUT_NOEXCEPT { + x.swap(y); + } + // + // make_exempt + // + template + inline SPROUT_CONSTEXPR sprout::exempt_ptr + make_exempt(T* p) SPROUT_NOEXCEPT { + return sprout::exempt_ptr(p); + } + // + // operator== + // operator!= + // + template + inline SPROUT_CONSTEXPR bool + operator==(sprout::exempt_ptr const& x, sprout::exempt_ptr const& y) SPROUT_NOEXCEPT { + return x.get() == y.get(); + } + template + inline SPROUT_CONSTEXPR bool + operator!=(sprout::exempt_ptr const& x, sprout::exempt_ptr const& y) SPROUT_NOEXCEPT { + return !(x == y); + } + template + inline SPROUT_CONSTEXPR bool + operator==(sprout::exempt_ptr const& x, std::nullptr_t y) SPROUT_NOEXCEPT { + return x.get() == y; + } + template + inline SPROUT_CONSTEXPR bool + operator!=(sprout::exempt_ptr const& x, std::nullptr_t y) SPROUT_NOEXCEPT { + return !(x == y); + } + template + inline SPROUT_CONSTEXPR bool + operator==(std::nullptr_t x, sprout::exempt_ptr const& y) SPROUT_NOEXCEPT { + return x == y.get(); + } + template + inline SPROUT_CONSTEXPR bool + operator!=(std::nullptr_t x, sprout::exempt_ptr const& y) SPROUT_NOEXCEPT { + return !(x == y); + } + // + // operator< + // operator> + // operator=< + // operator=> + // + template + inline SPROUT_CONSTEXPR bool + operator<(sprout::exempt_ptr const& x, sprout::exempt_ptr const& y) { + return x.get() < y.get(); + } + template + inline SPROUT_CONSTEXPR bool + operator>(sprout::exempt_ptr const& x, sprout::exempt_ptr const& y) { + return y < x; + } + template + inline SPROUT_CONSTEXPR bool + operator<=(sprout::exempt_ptr const& x, sprout::exempt_ptr const& y) { + return !(y < x); + } + template + inline SPROUT_CONSTEXPR bool + operator>=(sprout::exempt_ptr const& x, sprout::exempt_ptr const& y) { + return !(x < y); + } + // + // operator+ + // operator- + // + template + inline SPROUT_CONSTEXPR sprout::exempt_ptr + operator+(std::ptrdiff_t d, sprout::exempt_ptr const& p) { + return p + d; + } + template + inline SPROUT_CONSTEXPR std::ptrdiff_t + operator-(sprout::exempt_ptr const& x, sprout::exempt_ptr const& y) { + return x.get() - y.get(); + } +} // namespace sprout + +#endif // #ifndef SPROUT_EXEMPT_PTR_HPP diff --git a/testspr/header_all.hpp b/testspr/header_all.hpp index 6e7ce971..29cfd635 100644 --- a/testspr/header_all.hpp +++ b/testspr/header_all.hpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include