summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MODULE.bazel.lock8
-rw-r--r--asl/BUILD.bazel5
-rw-r--r--asl/integers.hpp2
-rw-r--r--asl/meta.hpp51
-rw-r--r--asl/meta_tests.cpp41
-rw-r--r--asl/object.hpp10
-rw-r--r--asl/object_tests.cpp1
-rw-r--r--asl/ptr.hpp106
-rw-r--r--asl/ptr_tests.cpp12
-rw-r--r--asl/utility.hpp4
10 files changed, 226 insertions, 14 deletions
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
index f5cd531..21b358e 100644
--- a/MODULE.bazel.lock
+++ b/MODULE.bazel.lock
@@ -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/source.json": "1f1ba6fea244b616de4a554a0f4983c91a9301640c8fe0dd1d410254115c8430",
"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.1/source.json": "8f3f3076554e1558e8e468b2232991c510ecbcbed9e6f8c06ac31c93bcf38362",
+ "https://bcr.bazel.build/modules/rules_java/7.6.5/MODULE.bazel": "481164be5e02e4cab6e77a36927683263be56b7e36fef918b458d7a8a1ebadb1",
+ "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/source.json": "a075731e1b46bc8425098512d038d416e966ab19684a10a34f4741295642fc35",
"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/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.3/MODULE.bazel": "6a9c02f19a24dcedb05572b2381446e27c272cd383aed11d41d99da9e3167a72",
- "https://bcr.bazel.build/modules/zlib/1.3/source.json": "b6b43d0737af846022636e6e255fd4a96fee0d34f08f3830e6e0bac51465c37c"
+ "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79",
+ "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d"
},
"selectedYankedVersions": {},
"moduleExtensions": {
diff --git a/asl/BUILD.bazel b/asl/BUILD.bazel
index dc0aef8..710eaa8 100644
--- a/asl/BUILD.bazel
+++ b/asl/BUILD.bazel
@@ -3,6 +3,9 @@ cc_library(
hdrs = [
"integers.hpp",
"meta.hpp",
+ "object.hpp",
+ "ptr.hpp",
+ "utility.hpp",
],
visibility = ["//visibility:public"],
)
@@ -15,4 +18,4 @@ cc_library(
deps = [
":asl",
],
-) for name in ["integers", "meta"]]
+) for name in ["integers", "meta", "object", "ptr"]]
diff --git a/asl/integers.hpp b/asl/integers.hpp
index 07fa11e..b5d3e99 100644
--- a/asl/integers.hpp
+++ b/asl/integers.hpp
@@ -10,3 +10,5 @@ using uint16_t = unsigned short;
using uint32_t = unsigned int;
using uint64_t = unsigned long long;
+using isize_t = int64_t;
+
diff --git a/asl/meta.hpp b/asl/meta.hpp
index 15f7790..c55500a 100644
--- a/asl/meta.hpp
+++ b/asl/meta.hpp
@@ -8,6 +8,11 @@ template<bool B> using bool_constant = integral_constant<bool, B>;
using true_type = bool_constant<true>;
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);
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_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_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
diff --git a/asl/meta_tests.cpp b/asl/meta_tests.cpp
index f3d31f4..34603e6 100644
--- a/asl/meta_tests.cpp
+++ b/asl/meta_tests.cpp
@@ -1,5 +1,6 @@
#include "asl/meta.hpp"
+struct EmptyStruct {};
struct Struct { int b: 4; };
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&>);
static_assert(!asl::is_object<int&&>);
-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[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<Struct[4]>);
-static_assert(asl::is_object<Union[]>);
-static_assert(asl::is_object<Enum[]>);
+static_assert(!asl::is_object<int[]>);
+static_assert(!asl::is_object<Struct[4]>);
+static_assert(!asl::is_object<Union[]>);
+static_assert(!asl::is_object<Enum[]>);
static_assert(!asl::is_object<int()>);
static_assert(asl::is_object<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<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; }
diff --git a/asl/object.hpp b/asl/object.hpp
new file mode 100644
index 0000000..17e9ce4
--- /dev/null
+++ b/asl/object.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace asl {
+
+template<typename T>
+class object final
+{
+};
+
+} // namespace asl
diff --git a/asl/object_tests.cpp b/asl/object_tests.cpp
new file mode 100644
index 0000000..2f38372
--- /dev/null
+++ b/asl/object_tests.cpp
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/asl/ptr.hpp b/asl/ptr.hpp
new file mode 100644
index 0000000..70dfa7b
--- /dev/null
+++ b/asl/ptr.hpp
@@ -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
diff --git a/asl/ptr_tests.cpp b/asl/ptr_tests.cpp
new file mode 100644
index 0000000..316ae1d
--- /dev/null
+++ b/asl/ptr_tests.cpp
@@ -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; }
diff --git a/asl/utility.hpp b/asl/utility.hpp
new file mode 100644
index 0000000..e8b9d86
--- /dev/null
+++ b/asl/utility.hpp
@@ -0,0 +1,4 @@
+#pragma once
+
+#define ASL_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
+