Skip to content

Commit

Permalink
add missing functions
Browse files Browse the repository at this point in the history
  • Loading branch information
KRM7 committed Jan 30, 2024
1 parent 1ea3dc8 commit 9cf29cc
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 4 deletions.
39 changes: 36 additions & 3 deletions src/small_unique_ptr.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
/* Copyright (c) 2024 Krisztián Rugási. Subject to the MIT License. */

#ifndef SMALL_UNIQUE_PTR_SMALL_UNIQUE_PTR_HPP
#define SMALL_UNIQUE_PTR_SMALL_UNIQUE_PTR_HPP
#ifndef SMALL_UNIQUE_PTR_HPP
#define SMALL_UNIQUE_PTR_HPP

#include <compare>
#include <memory>
#include <iosfwd>
#include <functional>
#include <new>
#include <type_traits>
#include <utility>
Expand Down Expand Up @@ -288,6 +290,18 @@ class small_unique_ptr : private detail::small_unique_ptr_base<T>
}
}

[[nodiscard]]
constexpr static bool is_always_heap_allocated() noexcept
{
return detail::always_heap_allocated_v<T>;
}

[[nodiscard]]
constexpr bool is_stack_allocated() const noexcept
{
return small_unique_ptr_base::is_stack_allocated();
}

[[nodiscard]]
constexpr pointer get() const noexcept
{
Expand Down Expand Up @@ -336,6 +350,12 @@ class small_unique_ptr : private detail::small_unique_ptr_base<T>
return this->data_ <=> rhs.data_;
}

template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const small_unique_ptr& p)
{
return os << p.get();
}

private:
template<typename B = T>
constexpr std::ptrdiff_t offsetof_base() const noexcept
Expand All @@ -362,6 +382,19 @@ constexpr void swap(small_unique_ptr<T>& lhs, small_unique_ptr<T>& rhs) noexcept
lhs.swap(rhs);
}

namespace std
{
template<typename T>
struct hash<small_unique_ptr<T>>
{
std::size_t operator()(const small_unique_ptr<T>& p) const noexcept
{
return std::hash<typename small_unique_ptr<T>::pointer>{}(p.get());
}
};

} // namespace std

template<typename T, typename... Args>
[[nodiscard]] constexpr small_unique_ptr<T> make_unique_small(Args&&... args)
noexcept(!detail::always_heap_allocated_v<T> && std::is_nothrow_constructible_v<T, Args...>)
Expand All @@ -385,4 +418,4 @@ noexcept(!detail::always_heap_allocated_v<T> && std::is_nothrow_constructible_v<
return ptr;
}

#endif // !SMALL_UNIQUE_PTR_SMALL_UNIQUE_PTR_HPP
#endif // !SMALL_UNIQUE_PTR_HPP
31 changes: 30 additions & 1 deletion test/small_unique_ptr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,36 @@ TEST_CASE("construction", "[small_unique_ptr]")
REQUIRE_NOTHROW(make_unique_small<LargePOD>());
}

TEST_CASE("is_always_heap_allocated", "[small_unique_ptr]")
{
STATIC_REQUIRE(!small_unique_ptr<SmallDerived>::is_always_heap_allocated());
STATIC_REQUIRE(small_unique_ptr<LargeDerived>::is_always_heap_allocated());

STATIC_REQUIRE(!small_unique_ptr<SmallPOD>::is_always_heap_allocated());
STATIC_REQUIRE(small_unique_ptr<LargePOD>::is_always_heap_allocated());
}

TEST_CASE("is_stack_allocated", "[small_unique_ptr]")
{
STATIC_REQUIRE( !std::invoke([]{ return make_unique_small<SmallDerived>().is_stack_allocated(); }) );
STATIC_REQUIRE( !std::invoke([]{ return make_unique_small<LargeDerived>().is_stack_allocated(); }) );

STATIC_REQUIRE( !std::invoke([]{ return make_unique_small<SmallPOD>().is_stack_allocated(); }) );
STATIC_REQUIRE( !std::invoke([]{ return make_unique_small<LargePOD>().is_stack_allocated(); }) );

small_unique_ptr<Base> p1 = make_unique_small<SmallDerived>();
small_unique_ptr<Base> p2 = make_unique_small<LargeDerived>();

REQUIRE(p1.is_stack_allocated());
REQUIRE(!p2.is_stack_allocated());

small_unique_ptr<SmallPOD> p3 = make_unique_small<SmallPOD>();
small_unique_ptr<LargePOD> p4 = make_unique_small<LargePOD>();

REQUIRE(p3.is_stack_allocated());
REQUIRE(!p4.is_stack_allocated());
}

TEST_CASE("comparisons", "[small_unique_ptr]")
{
STATIC_REQUIRE(small_unique_ptr<SmallPOD>(nullptr) == nullptr);
Expand Down Expand Up @@ -423,7 +453,6 @@ TEST_CASE("poly_alignment", "[small_unique_ptr]")
TEST_CASE("const_unique_ptr", "[small_unique_ptr]")
{
const small_unique_ptr<int> p = make_unique_small<int>(3);

*p = 2;

REQUIRE(*p == 2);
Expand Down

0 comments on commit 9cf29cc

Please sign in to comment.