Some work on pointers
This commit is contained in:
8
MODULE.bazel.lock
generated
8
MODULE.bazel.lock
generated
@ -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": {
|
||||||
|
@ -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"]]
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
51
asl/meta.hpp
51
asl/meta.hpp
@ -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
|
||||||
|
@ -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
10
asl/object.hpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace asl {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class object final
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace asl
|
1
asl/object_tests.cpp
Normal file
1
asl/object_tests.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
int main() { return 0; }
|
106
asl/ptr.hpp
Normal file
106
asl/ptr.hpp
Normal 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
12
asl/ptr_tests.cpp
Normal 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
4
asl/utility.hpp
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ASL_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
|
||||||
|
|
Reference in New Issue
Block a user