summaryrefslogtreecommitdiffstats
path: root/src/third-party/scnlib/include/scn/util/unique_ptr.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/third-party/scnlib/include/scn/util/unique_ptr.h')
-rw-r--r--src/third-party/scnlib/include/scn/util/unique_ptr.h118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/third-party/scnlib/include/scn/util/unique_ptr.h b/src/third-party/scnlib/include/scn/util/unique_ptr.h
new file mode 100644
index 0000000..4723de8
--- /dev/null
+++ b/src/third-party/scnlib/include/scn/util/unique_ptr.h
@@ -0,0 +1,118 @@
+// Copyright 2017 Elias Kosunen
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// This file is a part of scnlib:
+// https://github.com/eliaskosunen/scnlib
+
+#ifndef SCN_UTIL_UNIQUE_PTR_H
+#define SCN_UTIL_UNIQUE_PTR_H
+
+#include "../detail/fwd.h"
+
+#include <type_traits>
+
+namespace scn {
+ SCN_BEGIN_NAMESPACE
+
+ namespace detail {
+ /**
+ * `std::unique_ptr` implementation with [[clang::trivial_abi]], without
+ * including `<memory>`
+ */
+ template <typename T>
+ class SCN_TRIVIAL_ABI unique_ptr {
+ public:
+ using element_type = T;
+ using pointer = T*;
+
+ constexpr unique_ptr() noexcept = default;
+ constexpr unique_ptr(std::nullptr_t) noexcept {}
+
+ constexpr explicit unique_ptr(pointer p) noexcept : m_ptr(p) {}
+
+ template <
+ typename U,
+ typename std::enable_if<
+ std::is_convertible<U*, pointer>::value>::type* = nullptr>
+ SCN_CONSTEXPR14 unique_ptr(unique_ptr<U>&& u) noexcept
+ : m_ptr(SCN_MOVE(u.get()))
+ {
+ u.reset();
+ }
+
+ unique_ptr(const unique_ptr&) = delete;
+ unique_ptr& operator=(const unique_ptr&) = delete;
+
+ SCN_CONSTEXPR14 unique_ptr(unique_ptr&& p) noexcept
+ : m_ptr(SCN_MOVE(p.m_ptr))
+ {
+ p.m_ptr = nullptr;
+ }
+ unique_ptr& operator=(unique_ptr&& p) noexcept
+ {
+ delete m_ptr;
+ m_ptr = p.m_ptr;
+ p.m_ptr = nullptr;
+ return *this;
+ }
+
+ ~unique_ptr() noexcept
+ {
+ SCN_CLANG_PUSH_IGNORE_UNDEFINED_TEMPLATE
+ delete m_ptr;
+ SCN_CLANG_POP_IGNORE_UNDEFINED_TEMPLATE
+ }
+
+ constexpr explicit operator bool() const noexcept
+ {
+ return get() != nullptr;
+ }
+
+ constexpr pointer get() const noexcept
+ {
+ return m_ptr;
+ }
+
+ constexpr pointer operator->() const noexcept
+ {
+ return m_ptr;
+ }
+ constexpr typename std::add_lvalue_reference<T>::type operator*()
+ const
+ {
+ return *m_ptr;
+ }
+
+ SCN_CONSTEXPR14 void reset()
+ {
+ m_ptr = nullptr;
+ }
+
+ private:
+ pointer m_ptr{nullptr};
+ };
+
+ template <typename T, typename... Args>
+ unique_ptr<T> make_unique(Args&&... a)
+ {
+ SCN_CLANG_PUSH_IGNORE_UNDEFINED_TEMPLATE
+ return unique_ptr<T>(new T(SCN_FWD(a)...));
+ SCN_CLANG_POP_IGNORE_UNDEFINED_TEMPLATE
+ }
+ } // namespace detail
+
+ SCN_END_NAMESPACE
+} // namespace scn
+
+#endif