From: Jacob Lifshay Date: Sat, 28 Oct 2017 08:02:06 +0000 (-0700) Subject: add observer_ptr.h X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=109e20bcf83651a890f82422cf98be0fb563e382;p=kazan.git add observer_ptr.h --- diff --git a/src/util/observer_ptr.h b/src/util/observer_ptr.h new file mode 100644 index 0000000..39f33c9 --- /dev/null +++ b/src/util/observer_ptr.h @@ -0,0 +1,183 @@ +/* + * Copyright 2017 Jacob Lifshay + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ +#ifndef UTIL_OBSERVER_PTR_H_ +#define UTIL_OBSERVER_PTR_H_ + +#include +#include +#include +#include + +namespace kazan +{ +namespace util +{ +template +class observer_ptr +{ +public: + typedef T element_type; + +private: + T *value; + +public: + constexpr observer_ptr() noexcept : value(nullptr) + { + } + constexpr observer_ptr(std::nullptr_t) noexcept : value(nullptr) + { + } + explicit constexpr observer_ptr(T *value) noexcept : value(value) + { + } + template ::value>::type> + observer_ptr(observer_ptr rt) noexcept : value(rt.get()) + { + } + constexpr T *release() noexcept + { + T *retval = value; + value = nullptr; + return retval; + } + constexpr void reset(T *new_value = nullptr) noexcept + { + value = new_value; + } + constexpr void swap(observer_ptr &other) noexcept + { + T *temp = value; + value = other.value; + other.value = temp; + } + constexpr T *get() const noexcept + { + return value; + } + constexpr explicit operator bool() const noexcept + { + return value != nullptr; + } + constexpr typename std::add_lvalue_reference operator*() const noexcept + { + return *value; + } + constexpr T *operator->() const noexcept + { + return value; + } + constexpr explicit operator T *() const noexcept + { + return value; + } +}; + +template +constexpr observer_ptr make_observer(T *value) noexcept +{ + return observer_ptr(value); +} + +template +constexpr bool operator==(const observer_ptr &l, const observer_ptr &r) noexcept +{ + return l.get() == r.get(); +} + +template +constexpr bool operator!=(const observer_ptr &l, const observer_ptr &r) noexcept +{ + return !(l == r); +} + +template +constexpr bool operator==(const observer_ptr &p, std::nullptr_t) noexcept +{ + return !p; +} + +template +constexpr bool operator==(std::nullptr_t, const observer_ptr &p) noexcept +{ + return !p; +} + +template +constexpr bool operator!=(const observer_ptr &p, std::nullptr_t) noexcept +{ + return static_cast(p); +} + +template +constexpr bool operator!=(std::nullptr_t, const observer_ptr &p) noexcept +{ + return static_cast(p); +} + +template +constexpr bool operator<(const observer_ptr &l, const observer_ptr &r) noexcept +{ + return std::less::type>()(l.get(), r.get()); +} + +template +constexpr bool operator>(const observer_ptr &l, const observer_ptr &r) noexcept +{ + return r < l; +} + +template +constexpr bool operator<=(const observer_ptr &l, const observer_ptr &r) noexcept +{ + return !(r < l); +} + +template +constexpr bool operator>=(const observer_ptr &l, const observer_ptr &r) noexcept +{ + return !(l < r); +} +} +} + +namespace std +{ +template +constexpr void swap(kazan::util::observer_ptr &l, kazan::util::observer_ptr &r) noexcept +{ + l.swap(r); +} + +template +struct hash> +{ + constexpr std::size_t operator()(kazan::util::observer_ptr v) const noexcept + { + return std::hash()(v); + } +}; +} + +#endif // UTIL_OBSERVER_PTR_H_