Skip to content

Commit

Permalink
final classes can't be empty-base-optimized
Browse files Browse the repository at this point in the history
For that we need [[no_unique_address]].

Actually wait, I think maybe we have [[no_unique_address]]! Maybe we can
get rid of compressed_pair entirely...
  • Loading branch information
mrdomino committed Jun 16, 2024
1 parent 5b242f6 commit 393f024
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
5 changes: 3 additions & 2 deletions ctl/compressed_pair.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#ifndef COSMOPOLITAN_CTL_COMPRESSED_PAIR_H_
#define COSMOPOLITAN_CTL_COMPRESSED_PAIR_H_
#include <__type_traits/is_empty.h>
#include <__type_traits/is_final.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/swap.h>
Expand All @@ -12,7 +13,7 @@ namespace ctl {
namespace __ {

template<typename T>
concept Empty = std::is_empty_v<T>;
concept EmptyBase = std::is_empty_v<T> && !std::is_final_v<T>;

template<typename T, int I>
struct pair_elem
Expand All @@ -37,7 +38,7 @@ struct pair_elem
T t;
};

template<Empty T, int I>
template<EmptyBase T, int I>
struct pair_elem<T, I> : private T
{
using value_type = T;
Expand Down
22 changes: 22 additions & 0 deletions test/ctl/unique_ptr_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,21 @@ struct SetsGDeleter
}
};

struct FinalDeleter final
{
void operator()(auto*) const noexcept
{
}
};

struct StatefulDeleter
{
char state;
void operator()(auto*) const noexcept
{
}
};

static_assert(sizeof(Ptr<int, SetsGDeleter>) == sizeof(int*));

struct SetsGCtor
Expand Down Expand Up @@ -185,6 +200,13 @@ main()
}
#endif

{
int a;
// Should compile.
Ptr<int, FinalDeleter> x(&a);
Ptr<int, StatefulDeleter> y(&a);
}

// next is 18

return 0;
Expand Down

0 comments on commit 393f024

Please sign in to comment.