ArkScript
A small, lisp-inspired, functional scripting language
UserType.hpp
Go to the documentation of this file.
1/**
2 * @file UserType.hpp
3 * @author Lex Plateau (lexplt.dev@gmail.com)
4 * @brief Subtype of the value, capable of handling any C++ type
5 * @date 2020-10-27
6 *
7 * @copyright Copyright (c) 2020-2025
8 *
9 */
10
11#ifndef ARK_VM_VALUE_USERTYPE_HPP
12#define ARK_VM_VALUE_USERTYPE_HPP
13
14#include <iostream>
15#include <cinttypes>
16#include <functional>
17
19
20namespace Ark
21{
22 namespace internal
23 {
25 {
26 static inline uint16_t id = 0;
27 static uint16_t next()
28 {
29 return id++;
30 }
31 };
32
33 template <typename T>
34 struct type_uid
35 {
36 static inline const uint16_t value = type_uid_impl::next();
37 };
38 }
39
40 /**
41 * @brief A class to be use C++ objects in ArkScript
42 *
43 * A pointer to the value you want to store
44 * must be sent, thus the value must not be destroyed while the UserType lives,
45 * otherwise it would result in an UB when trying to use the object
46 */
48 {
49 public:
50 /**
51 * @brief A structure holding a bunch of pointers to different useful functions related to this usertype
52 *
53 */
55 {
56 std::function<std::ostream&(std::ostream&, const UserType&)> ostream_func = nullptr;
57 std::function<void(void*)> deleter = nullptr;
58 };
59
60 /**
61 * @brief Construct a new User Type object
62 *
63 * @tparam T the type of the pointer
64 * @param data a pointer to the data to store in the object
65 * @param block control function block for the usertype, can be nullptr
66 */
67 template <typename T>
68 explicit UserType(T* data = nullptr, ControlFuncs* block = nullptr) noexcept :
69 m_type_id(internal::type_uid<T>::value),
70 m_data(reinterpret_cast<void*>(data)),
71 m_funcs(block)
72 {}
73
74 /**
75 * @brief Free memory through the control functions block
76 *
77 */
78 void del() const;
79
80 /**
81 * @brief Get the pointer to the object
82 *
83 * @return void*
84 */
85 [[nodiscard]] void* data() const noexcept
86 {
87 return m_data;
88 }
89
90 /**
91 * @brief Check if the object held is of a given type
92 * @details Usage example:
93 * @code
94 * MyType object;
95 * UserType a(&object);
96 * if (a.is<MyType>())
97 * // then ...
98 * else
99 * // otherwise...
100 * @endcode
101 *
102 * @tparam T the type to use for the test
103 * @return true
104 * @return false
105 */
106 template <typename T>
107 [[nodiscard]] bool is() const noexcept
108 {
110 }
111
112 /**
113 * @brief Return the underlying object as a given type
114 *
115 * @tparam T the type in which the underlying data pointer should be converted to
116 * @return T&
117 */
118 template <typename T>
119 T& as() noexcept
120 {
121 return *static_cast<T*>(m_data);
122 }
123
124 /**
125 * @brief Return the underlying object as a given type
126 *
127 * @tparam T the type in which the underlying data pointer should be converted to
128 * @return T&
129 */
130 template <typename T>
131 const T& as() const noexcept
132 {
133 return *static_cast<T*>(m_data);
134 }
135
136 friend ARK_API bool operator==(const UserType& A, const UserType& B) noexcept;
137 friend ARK_API bool operator<(const UserType& A, const UserType& B) noexcept;
138 friend ARK_API std::ostream& operator<<(std::ostream& os, const UserType& A) noexcept;
139 friend struct std::hash<Ark::UserType>;
140
141 private:
142 uint16_t m_type_id;
143 void* m_data;
145 };
146}
147
148template <>
149struct std::hash<Ark::UserType>
150{
151 [[nodiscard]] std::size_t operator()(const Ark::UserType& s) const noexcept
152 {
153 return std::hash<void*> {}(s.m_data);
154 }
155};
156
157#endif
#define ARK_API
Definition Module.hpp:22
ArkScript configuration macros.
A class to be use C++ objects in ArkScript.
Definition UserType.hpp:48
UserType(T *data=nullptr, ControlFuncs *block=nullptr) noexcept
Construct a new User Type object.
Definition UserType.hpp:68
const T & as() const noexcept
Return the underlying object as a given type.
Definition UserType.hpp:131
friend ARK_API std::ostream & operator<<(std::ostream &os, const UserType &A) noexcept
Definition UserType.cpp:21
uint16_t m_type_id
Definition UserType.hpp:142
ControlFuncs * m_funcs
Definition UserType.hpp:144
T & as() noexcept
Return the underlying object as a given type.
Definition UserType.hpp:119
void * data() const noexcept
Get the pointer to the object.
Definition UserType.hpp:85
bool is() const noexcept
Check if the object held is of a given type.
Definition UserType.hpp:107
void del() const
Free memory through the control functions block.
Definition UserType.cpp:5
friend ARK_API bool operator==(const UserType &A, const UserType &B) noexcept
Definition UserType.cpp:11
friend ARK_API bool operator<(const UserType &A, const UserType &B) noexcept
Definition UserType.cpp:16
A structure holding a bunch of pointers to different useful functions related to this usertype.
Definition UserType.hpp:55
std::function< void(void *)> deleter
Definition UserType.hpp:57
std::function< std::ostream &(std::ostream &, const UserType &)> ostream_func
Definition UserType.hpp:56
static uint16_t next()
Definition UserType.hpp:27
static const uint16_t value
Definition UserType.hpp:36
std::size_t operator()(const Ark::UserType &s) const noexcept
Definition UserType.hpp:151