Some work on pointers

This commit is contained in:
2024-08-15 00:58:37 +02:00
parent 75b10758ba
commit 298ee421d9
10 changed files with 226 additions and 14 deletions

8
MODULE.bazel.lock generated
View File

@ -34,8 +34,8 @@
"https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
"https://bcr.bazel.build/modules/rules_cc/0.0.9/source.json": "1f1ba6fea244b616de4a554a0f4983c91a9301640c8fe0dd1d410254115c8430", "https://bcr.bazel.build/modules/rules_cc/0.0.9/source.json": "1f1ba6fea244b616de4a554a0f4983c91a9301640c8fe0dd1d410254115c8430",
"https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
"https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", "https://bcr.bazel.build/modules/rules_java/7.6.5/MODULE.bazel": "481164be5e02e4cab6e77a36927683263be56b7e36fef918b458d7a8a1ebadb1",
"https://bcr.bazel.build/modules/rules_java/7.6.1/source.json": "8f3f3076554e1558e8e468b2232991c510ecbcbed9e6f8c06ac31c93bcf38362", "https://bcr.bazel.build/modules/rules_java/7.6.5/source.json": "a805b889531d1690e3c72a7a7e47a870d00323186a9904b36af83aa3d053ee8d",
"https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
"https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/source.json": "a075731e1b46bc8425098512d038d416e966ab19684a10a34f4741295642fc35", "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/source.json": "a075731e1b46bc8425098512d038d416e966ab19684a10a34f4741295642fc35",
"https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
@ -56,8 +56,8 @@
"https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/source.json": "f1ef7d3f9e0e26d4b23d1c39b5f5de71f584dd7d1b4ef83d9bbba6ec7a6a6459", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/source.json": "f1ef7d3f9e0e26d4b23d1c39b5f5de71f584dd7d1b4ef83d9bbba6ec7a6a6459",
"https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
"https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27",
"https://bcr.bazel.build/modules/zlib/1.3/MODULE.bazel": "6a9c02f19a24dcedb05572b2381446e27c272cd383aed11d41d99da9e3167a72", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79",
"https://bcr.bazel.build/modules/zlib/1.3/source.json": "b6b43d0737af846022636e6e255fd4a96fee0d34f08f3830e6e0bac51465c37c" "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d"
}, },
"selectedYankedVersions": {}, "selectedYankedVersions": {},
"moduleExtensions": { "moduleExtensions": {

View File

@ -3,6 +3,9 @@ cc_library(
hdrs = [ hdrs = [
"integers.hpp", "integers.hpp",
"meta.hpp", "meta.hpp",
"object.hpp",
"ptr.hpp",
"utility.hpp",
], ],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
@ -15,4 +18,4 @@ cc_library(
deps = [ deps = [
":asl", ":asl",
], ],
) for name in ["integers", "meta"]] ) for name in ["integers", "meta", "object", "ptr"]]

View File

@ -10,3 +10,5 @@ using uint16_t = unsigned short;
using uint32_t = unsigned int; using uint32_t = unsigned int;
using uint64_t = unsigned long long; using uint64_t = unsigned long long;
using isize_t = int64_t;

View File

@ -8,6 +8,11 @@ template<bool B> using bool_constant = integral_constant<bool, B>;
using true_type = bool_constant<true>; using true_type = bool_constant<true>;
using false_type = bool_constant<false>; using false_type = bool_constant<false>;
template<bool kSelect, typename U, typename V> struct _select_helper { using type = V; };
template<typename U, typename V> struct _select_helper<true, U, V> { using type = U; };
template<bool kSelect, typename U, typename V> using select_t = _select_helper<kSelect, U, V>::type;
using nullptr_t = decltype(nullptr); using nullptr_t = decltype(nullptr);
template<typename T> struct un_ref { using type = T; }; template<typename T> struct un_ref { using type = T; };
@ -84,6 +89,50 @@ template<typename T> concept is_member_object_ptr = is_member_ptr<T> && !is_memb
template<typename T> concept is_fundamental = is_arithmetic<T> || is_void<T> || is_nullptr<T>; template<typename T> concept is_fundamental = is_arithmetic<T> || is_void<T> || is_nullptr<T>;
template<typename T> concept is_compound = !is_fundamental<T>; template<typename T> concept is_compound = !is_fundamental<T>;
template<typename T> concept is_scalar = (is_fundamental<T> && !is_void<T>) || is_enum<T> || is_ptr<T> || is_member_ptr<T>; template<typename T> concept is_scalar = (is_fundamental<T> && !is_void<T>) || is_enum<T> || is_ptr<T> || is_member_ptr<T>;
template<typename T> concept is_object = is_scalar<T> || is_array<T> || is_class<T> || is_union<T>; template<typename T> concept is_object = is_scalar<T> || is_class<T> || is_union<T>;
template<typename T> concept is_empty = is_void<T> || __is_empty(T);
struct empty {};
template<typename T> using devoid_t = select_t<is_void<T>, empty, T>;
template<typename F> struct _tame_helper { using type = F; };
#define ASL_TAME_IMPL(SUFFIX) \
template<typename Ret, typename... Args> \
struct _tame_helper<Ret(Args...) SUFFIX> { using type = Ret(Args...); }
ASL_TAME_IMPL();
ASL_TAME_IMPL(const);
ASL_TAME_IMPL(volatile);
ASL_TAME_IMPL(volatile const);
ASL_TAME_IMPL(&&);
ASL_TAME_IMPL(const &&);
ASL_TAME_IMPL(volatile &&);
ASL_TAME_IMPL(volatile const &&);
ASL_TAME_IMPL(&);
ASL_TAME_IMPL(const &);
ASL_TAME_IMPL(volatile &);
ASL_TAME_IMPL(volatile const &);
ASL_TAME_IMPL(noexcept);
ASL_TAME_IMPL(const noexcept);
ASL_TAME_IMPL(volatile noexcept);
ASL_TAME_IMPL(volatile const noexcept);
ASL_TAME_IMPL(&& noexcept);
ASL_TAME_IMPL(const && noexcept);
ASL_TAME_IMPL(volatile && noexcept);
ASL_TAME_IMPL(volatile const && noexcept);
ASL_TAME_IMPL(& noexcept);
ASL_TAME_IMPL(const & noexcept);
ASL_TAME_IMPL(volatile & noexcept);
ASL_TAME_IMPL(volatile const & noexcept);
#undef ASL_TAME_IMPL
template<typename T> using tame_t = _tame_helper<T>::type;
template<typename T> using as_raw_ptr_t = un_ref_t<tame_t<T>>*;
} // namespace asl } // namespace asl

View File

@ -1,5 +1,6 @@
#include "asl/meta.hpp" #include "asl/meta.hpp"
struct EmptyStruct {};
struct Struct { int b: 4; }; struct Struct { int b: 4; };
union Union {}; union Union {};
@ -550,15 +551,15 @@ static_assert(asl::is_object<int Struct::*>);
static_assert(asl::is_object<int (Struct::*)()>); static_assert(asl::is_object<int (Struct::*)()>);
static_assert(!asl::is_object<int&>); static_assert(!asl::is_object<int&>);
static_assert(!asl::is_object<int&&>); static_assert(!asl::is_object<int&&>);
static_assert(asl::is_object<int[25]>); static_assert(!asl::is_object<int[25]>);
static_assert(asl::is_object<int[]>); static_assert(!asl::is_object<int[]>);
static_assert(asl::is_object<int*[]>); static_assert(!asl::is_object<int*[]>);
static_assert(!asl::is_object<int(&)[]>); static_assert(!asl::is_object<int(&)[]>);
static_assert(asl::is_object<int(*)[]>); static_assert(asl::is_object<int(*)[]>);
static_assert(asl::is_object<int[]>); static_assert(!asl::is_object<int[]>);
static_assert(asl::is_object<Struct[4]>); static_assert(!asl::is_object<Struct[4]>);
static_assert(asl::is_object<Union[]>); static_assert(!asl::is_object<Union[]>);
static_assert(asl::is_object<Enum[]>); static_assert(!asl::is_object<Enum[]>);
static_assert(!asl::is_object<int()>); static_assert(!asl::is_object<int()>);
static_assert(asl::is_object<Struct>); static_assert(asl::is_object<Struct>);
static_assert(asl::is_object<const Struct>); static_assert(asl::is_object<const Struct>);
@ -568,5 +569,29 @@ static_assert(asl::is_object<Union>);
static_assert(asl::is_object<Enum>); static_assert(asl::is_object<Enum>);
static_assert(asl::is_object<EnumClass>); static_assert(asl::is_object<EnumClass>);
int main() { return 0; } static_assert(asl::is_empty<void>);
static_assert(!asl::is_empty<int>);
static_assert(asl::is_empty<EmptyStruct>);
static_assert(!asl::is_empty<Union>);
static_assert(asl::is_empty<asl::empty>);
static_assert(asl::is_same<asl::select_t<false, int, float>, float>);
static_assert(asl::is_same<asl::select_t<true, int, float>, int>);
static_assert(asl::is_same<asl::devoid_t<int>, int>);
static_assert(asl::is_same<asl::devoid_t<void>, asl::empty>);
static_assert(asl::is_same<asl::devoid_t<const void>, asl::empty>);
static_assert(asl::is_same<asl::tame_t<int(float)>, int(float)>);
static_assert(asl::is_same<asl::tame_t<int(float) &>, int(float)>);
static_assert(asl::is_same<asl::tame_t<int(float) const &&>, int(float)>);
static_assert(asl::is_same<asl::tame_t<int(float) volatile noexcept>, int(float)>);
static_assert(asl::is_same<asl::tame_t<int(float) const>, int(float)>);
static_assert(asl::is_same<asl::tame_t<int(float) const volatile & noexcept>, int(float)>);
static_assert(asl::is_same<asl::as_raw_ptr_t<int>, int*>);
static_assert(asl::is_same<asl::as_raw_ptr_t<const int>, const int*>);
static_assert(asl::is_same<asl::as_raw_ptr_t<int(float)>, int(*)(float)>);
static_assert(asl::is_same<asl::as_raw_ptr_t<int&>, int*>);
int main() { return 0; }

10
asl/object.hpp Normal file
View File

@ -0,0 +1,10 @@
#pragma once
namespace asl {
template<typename T>
class object final
{
};
} // namespace asl

1
asl/object_tests.cpp Normal file
View File

@ -0,0 +1 @@
int main() { return 0; }

106
asl/ptr.hpp Normal file
View File

@ -0,0 +1,106 @@
#pragma once
#include "asl/integers.hpp"
#include "asl/meta.hpp"
#include "asl/utility.hpp"
namespace asl {
namespace ptr_internal {
template<is_object T>
class object_meta
{
public:
using pointee = T;
using metadata = empty;
};
template<is_void T>
class void_meta
{
public:
using pointee = T;
using metadata = empty;
};
template<typename T>
class array_meta;
template<is_object T, isize_t N>
class array_meta<T[N]>
{
public:
using pointee = T[N];
using metadata = empty;
};
template<is_object T>
class array_meta<T[]>
{
public:
using pointee = T;
using metadata = isize_t;
};
template<typename T>
class ptr_like_meta
{
static_assert(is_func<T> || is_ref<T>);
public:
using pointee = as_raw_ptr_t<T>;
using metadata = empty;
};
template<typename T>
constexpr auto get_meta()
{
if constexpr (is_object<T>)
{
return object_meta<T>{};
}
else if constexpr (is_void<T>)
{
return void_meta<T>{};
}
else if constexpr (is_array<T>)
{
return array_meta<T>{};
}
else if constexpr (is_ref<T> || is_func<T>)
{
return ptr_like_meta<T>{};
}
}
template<typename T>
using meta = decltype(get_meta<T>());
} // namespace ptr_internal
template<typename T>
concept is_ptr_metadata = requires
{
requires is_object<typename T::pointee> || is_void<typename T::pointee> || is_array<typename T::pointee>;
requires is_object<typename T::metadata>;
};
template<typename T>
class ptr final
{
using meta = ptr_internal::meta<T>;
static_assert(is_ptr_metadata<meta>);
public:
using pointee = meta::pointee;
using metadata = meta::metadata;
private:
pointee* m_ptr = nullptr;
ASL_NO_UNIQUE_ADDRESS metadata m_metadata;
public:
};
} // namespace asl

12
asl/ptr_tests.cpp Normal file
View File

@ -0,0 +1,12 @@
#include "asl/ptr.hpp"
static_assert(sizeof(asl::ptr<int>) == sizeof(int*));
static_assert(sizeof(asl::ptr<void>) == sizeof(void*));
static_assert(sizeof(asl::ptr<int[]>) == 2 * sizeof(int*));
static_assert(sizeof(asl::ptr<int[25]>) == sizeof(int*));
static_assert(sizeof(asl::ptr<int*>) == sizeof(int**));
static_assert(sizeof(asl::ptr<void(*)()>) == sizeof(void*));
static_assert(sizeof(asl::ptr<void()>) == sizeof(void*));
static_assert(sizeof(asl::ptr<int&>) == sizeof(int*));
int main() { return 0; }

4
asl/utility.hpp Normal file
View File

@ -0,0 +1,4 @@
#pragma once
#define ASL_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]