diff --git a/source/tinystl/memory/allocate_at_least.h b/source/tinystl/memory/allocate_at_least.h new file mode 100644 index 0000000..113e146 --- /dev/null +++ b/source/tinystl/memory/allocate_at_least.h @@ -0,0 +1,19 @@ +#pragma once + +#include "tinystl/memory/allocator_traits.h" + +namespace tinystl { + +template +struct allocation_result { + Pointer ptr; + size_t count; +}; + +template +constexpr allocation_result::pointer> +allocate_at_least(Alloc &alloc, size_t n) { + return {alloc.allocate(n), n}; +} + +} // namespace tinystl \ No newline at end of file diff --git a/source/tinystl/memory/temp_value.h b/source/tinystl/memory/temp_value.h new file mode 100644 index 0000000..3957d16 --- /dev/null +++ b/source/tinystl/memory/temp_value.h @@ -0,0 +1,31 @@ +#pragma once + +#include "tinystl/memory/addressof.h" +#include "tinystl/memory/allocator_traits.h" + +namespace tinystl { +template +class temp_value { +public: + template + temp_value(Alloc &alloc, Args &&...args) : m_alloc(alloc) { + tinystl::allocator_traits::construct( + m_alloc, addr(), std::forward(args)... + ); + } + + ~temp_value() { tinystl::allocator_traits::destroy(m_alloc, addr()); } + + T &get() noexcept { return *addr(); } + +private: + T *addr() { return addressof(m_value); } + +private: + union { + T m_value; + }; + + Alloc m_alloc; +}; +} // namespace tinystl \ No newline at end of file diff --git a/source/tinystl/memory/to_address.h b/source/tinystl/memory/to_address.h new file mode 100644 index 0000000..600216c --- /dev/null +++ b/source/tinystl/memory/to_address.h @@ -0,0 +1,20 @@ +#pragma once + +#include "tinystl/memory/pointer_traits.h" +#include "tinystl/type_traits/is_function.h" + +namespace tinystl { +template +constexpr T *to_address(T *p) noexcept { + static_assert(!is_function_v); + return p; +} + +template +constexpr auto to_address(const T &p) noexcept { + if constexpr (requires { pointer_traits::to_address(p); }) + return pointer_traits::to_address(p); + else + return to_address(p.operator->()); +} +} // namespace tinystl \ No newline at end of file diff --git a/source/tinystl/type_traits/is_const.h b/source/tinystl/type_traits/is_const.h new file mode 100644 index 0000000..7207a1f --- /dev/null +++ b/source/tinystl/type_traits/is_const.h @@ -0,0 +1,15 @@ +#pragma once + +#include "tinystl/type_traits/integral_constant.h" + +namespace tinystl { + +template +struct is_const : false_type {}; + +template +struct is_const : true_type {}; + +template +inline constexpr bool is_const_v = is_const::value; +} // namespace tinystl \ No newline at end of file diff --git a/source/tinystl/type_traits/is_function.h b/source/tinystl/type_traits/is_function.h new file mode 100644 index 0000000..68ed486 --- /dev/null +++ b/source/tinystl/type_traits/is_function.h @@ -0,0 +1,19 @@ +#pragma once + +#include "tinystl/type_traits/integral_constant.h" +#include "tinystl/type_traits/is_const.h" +#include "tinystl/type_traits/is_reference.h" + +namespace tinystl { + +// primary template +// template +// struct is_function : bool_constant<__is_function(T)> {}; + +template +struct is_function + : bool_constant && !is_reference_v> {}; + +template +inline constexpr bool is_function_v = is_function::value; +} // namespace tinystl \ No newline at end of file diff --git a/source/tinystl/utility/exception_guard.h b/source/tinystl/utility/exception_guard.h new file mode 100644 index 0000000..c77ebbf --- /dev/null +++ b/source/tinystl/utility/exception_guard.h @@ -0,0 +1,76 @@ +#pragma once + +#include +#include + +namespace tinystl { + +template +class exception_guard_exceptions { +public: + exception_guard_exceptions() = delete; + + explicit exception_guard_exceptions(Roolback roolbaclk) + : m_roolback(std::move(roolbaclk)), m_complete(false) {} + + exception_guard_exceptions(exception_guard_exceptions &&other) noexcept + : m_roolback(std::move(other.m_roolback)), m_complete(other.m_complete) { + other.m_complete = true; + } + exception_guard_exceptions(const exception_guard_exceptions &) = delete; + exception_guard_exceptions & + operator=(const exception_guard_exceptions &) = delete; + exception_guard_exceptions & + operator=(exception_guard_exceptions &&other) = delete; + + ~exception_guard_exceptions() noexcept(false) { + if (!m_complete) { + m_roolback(); + } + } + + void complete() noexcept { m_complete = true; } + +private: + Roolback m_roolback; + bool m_complete; +}; + +template +class exception_guard_nonexceptions { +public: +exception_guard_nonexceptions() = delete; + + explicit exception_guard_nonexceptions(Roolback) + : m_complete(false) {} + + exception_guard_nonexceptions(exception_guard_nonexceptions &&other) noexcept + : m_complete(other.m_complete) { + other.m_complete = true; + } + + exception_guard_nonexceptions(const exception_guard_nonexceptions &) = delete; + exception_guard_nonexceptions & + operator=(const exception_guard_nonexceptions &) = delete; + exception_guard_nonexceptions & + operator=(exception_guard_nonexceptions &&other) = delete; + + ~exception_guard_nonexceptions() noexcept { + assert(!m_complete && "exception_guard not complete with exceptions disabled"); + } + + void complete() noexcept { m_complete = true; } + +private: + bool m_complete; +}; + +template +using exception_guard = exception_guard_exceptions; + +template +exception_guard make_exception_guard(Roolback roolback) { + return exception_guard(std::move(roolback)); +} + +} // namespace tinystl \ No newline at end of file