Skip to content

Commit d3f57d8

Browse files
committed
Support Ref<POD> and Optional<>
1 parent 2da2e0b commit d3f57d8

31 files changed

+1421
-482
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.15)
22

33
project(
44
mlc
5-
VERSION 0.0.6
5+
VERSION 0.0.7
66
DESCRIPTION "MLC-Python"
77
LANGUAGES C CXX
88
)

cpp/registry.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,8 @@ inline TypeTable *TypeTable::New() {
356356
self->num_types = static_cast<int32_t>(MLCTypeIndex::kMLCDynObjectBegin);
357357
#define MLC_TYPE_TABLE_INIT_TYPE(UnderlyingType, Self) \
358358
{ \
359-
MLCTypeInfo *info = Self->TypeRegister(-1, ::mlc::base::TypeTraits<UnderlyingType>::default_type_index, \
360-
::mlc::base::TypeTraits<UnderlyingType>::type_str); \
359+
using Traits = ::mlc::base::TypeTraits<UnderlyingType>; \
360+
MLCTypeInfo *info = Self->TypeRegister(-1, Traits::type_index, Traits::type_str); \
361361
info->setter = PODGetterSetter<UnderlyingType>::Setter; \
362362
info->getter = PODGetterSetter<UnderlyingType>::Getter; \
363363
}

include/mlc/all.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#ifndef MLC_ALL_H
22
#define MLC_ALL_H
3-
#include "./base/all.h"
4-
#include "./core/all.h"
5-
#endif // MLC_ALL_H
3+
#include "./base/all.h" // IWYU pragma: export
4+
#include "./core/all.h" // IWYU pragma: export
5+
#endif // MLC_ALL_H

include/mlc/base/all.h

Lines changed: 12 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
#ifndef MLC_BASE_ALL_H_
22
#define MLC_BASE_ALL_H_
33

4-
#include "./any.h"
5-
#include "./ref.h"
6-
#include "./traits_device.h"
7-
#include "./traits_dtype.h"
8-
#include "./traits_object.h"
9-
#include "./traits_scalar.h"
10-
#include "./traits_str.h"
11-
#include <cstring>
4+
#include "./alloc.h" // IWYU pragma: export
5+
#include "./any.h" // IWYU pragma: export
6+
#include "./base_traits.h" // IWYU pragma: export
7+
#include "./optional.h" // IWYU pragma: export
8+
#include "./ref.h" // IWYU pragma: export
9+
#include "./traits_device.h" // IWYU pragma: export
10+
#include "./traits_dtype.h" // IWYU pragma: export
11+
#include "./traits_object.h" // IWYU pragma: export
12+
#include "./traits_scalar.h" // IWYU pragma: export
13+
#include "./traits_str.h" // IWYU pragma: export
14+
#include <mlc/c_api.h> // IWYU pragma: export
1215

1316
namespace mlc {
1417

@@ -26,14 +29,6 @@ MLC_INLINE Any::Any(AnyView &&src) : MLCAny(static_cast<const MLCAny &>(src)) {
2629
this->SwitchFromRawStr();
2730
this->IncRef();
2831
}
29-
MLC_INLINE AnyView &AnyView::operator=(const Any &src) {
30-
*static_cast<MLCAny *>(this) = static_cast<const MLCAny &>(src);
31-
return *this;
32-
}
33-
MLC_INLINE AnyView &AnyView::operator=(Any &&src) {
34-
*static_cast<MLCAny *>(this) = static_cast<const MLCAny &>(src);
35-
return *this;
36-
}
3732
MLC_INLINE Any &Any::operator=(const Any &src) {
3833
Any(src).Swap(*this);
3934
return *this;
@@ -42,14 +37,6 @@ MLC_INLINE Any &Any::operator=(Any &&src) {
4237
Any(std::move(src)).Swap(*this);
4338
return *this;
4439
}
45-
MLC_INLINE Any &Any::operator=(const AnyView &src) {
46-
Any(src).Swap(*this);
47-
return *this;
48-
}
49-
MLC_INLINE Any &Any::operator=(AnyView &&src) {
50-
Any(std::move(src)).Swap(*this);
51-
return *this;
52-
}
5340

5441
/*********** Section 2. Conversion between Any/AnyView <=> POD ***********/
5542

@@ -101,41 +88,7 @@ template <typename T> MLC_INLINE_NO_MSVC T Any::CastWithStorage(Any *storage) co
10188
MLC_TRY_CONVERT(TypeTraits<T>::AnyToTypeWithStorage(this, storage), this->type_index, Type2Str<T>::Run());
10289
}
10390

104-
/*********** Section 3. Conversion between Any/AnyView <=> Ref ***********/
105-
106-
template <typename T> MLC_INLINE Ref<T>::Ref(const AnyView &src) : TBase() { TBase::_Init<T>(src); }
107-
template <typename T> MLC_INLINE Ref<T>::Ref(const Any &src) : TBase() { TBase::_Init<T>(src); }
108-
template <typename T> MLC_INLINE Ref<T>::operator AnyView() const {
109-
if (this->ptr != nullptr) {
110-
AnyView ret;
111-
ret.type_index = this->ptr->type_index;
112-
ret.v_obj = this->ptr;
113-
return ret;
114-
}
115-
return AnyView();
116-
}
117-
template <typename T> MLC_INLINE Ref<T>::operator Any() const & {
118-
if (this->ptr != nullptr) {
119-
Any ret;
120-
ret.type_index = this->ptr->type_index;
121-
ret.v_obj = this->ptr;
122-
::mlc::base::IncRef(this->ptr);
123-
return ret;
124-
}
125-
return Any();
126-
}
127-
template <typename T> MLC_INLINE Ref<T>::operator Any() && {
128-
if (this->ptr != nullptr) {
129-
Any ret;
130-
ret.type_index = this->ptr->type_index;
131-
ret.v_obj = this->ptr;
132-
this->ptr = nullptr;
133-
return ret;
134-
}
135-
return Any();
136-
}
137-
138-
/*********** Section 4. AnyViewArray ***********/
91+
/*********** Section 3. AnyViewArray ***********/
13992

14093
template <std::size_t N> template <typename... Args> MLC_INLINE void AnyViewArray<N>::Fill(Args &&...args) {
14194
static_assert(sizeof...(args) == N, "Invalid number of arguments");

include/mlc/base/alloc.h

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#ifndef MLC_BASE_ALLOC_H_
2+
#define MLC_BASE_ALLOC_H_
3+
4+
#include "./utils.h"
5+
#include <type_traits>
6+
7+
namespace mlc {
8+
9+
template <typename T> struct DefaultObjectAllocator {
10+
using Storage = typename std::aligned_storage<sizeof(T), alignof(T)>::type;
11+
template <typename... Args> static constexpr bool CanConstruct = std::is_constructible_v<T, Args...>;
12+
13+
template <typename... Args, typename = std::enable_if_t<CanConstruct<Args...>>>
14+
MLC_INLINE_NO_MSVC static T *New(Args &&...args) {
15+
Storage *data = new Storage;
16+
try {
17+
new (data) T(std::forward<Args>(args)...);
18+
} catch (...) {
19+
delete data;
20+
throw;
21+
}
22+
T *ret = reinterpret_cast<T *>(data);
23+
ret->_mlc_header.type_index = T::_type_index;
24+
ret->_mlc_header.ref_cnt = 0;
25+
ret->_mlc_header.deleter = DefaultObjectAllocator<T>::Deleter;
26+
return ret;
27+
}
28+
29+
template <typename PadType, typename... Args, typename = std::enable_if_t<CanConstruct<Args...>>>
30+
MLC_INLINE_NO_MSVC static T *NewWithPad(size_t pad_size, Args &&...args) {
31+
size_t num_storages = (sizeof(T) + pad_size * sizeof(PadType) + sizeof(Storage) - 1) / sizeof(Storage);
32+
Storage *data = new Storage[num_storages];
33+
try {
34+
new (data) T(std::forward<Args>(args)...);
35+
} catch (...) {
36+
delete[] data;
37+
throw;
38+
}
39+
T *ret = reinterpret_cast<T *>(data);
40+
ret->_mlc_header.type_index = T::_type_index;
41+
ret->_mlc_header.ref_cnt = 0;
42+
ret->_mlc_header.deleter = DefaultObjectAllocator<T>::DeleterArray;
43+
return ret;
44+
}
45+
46+
static void Deleter(void *objptr) {
47+
T *tptr = static_cast<T *>(objptr);
48+
tptr->T::~T();
49+
delete reinterpret_cast<Storage *>(tptr);
50+
}
51+
52+
static void DeleterArray(void *objptr) {
53+
T *tptr = static_cast<T *>(objptr);
54+
tptr->T::~T();
55+
delete[] reinterpret_cast<Storage *>(tptr);
56+
}
57+
};
58+
59+
template <typename T> struct PODAllocator {
60+
static_assert(std::is_trivial_v<T> && std::is_standard_layout_v<T>, "PODAllocator can only be used with POD types");
61+
struct Storage {
62+
MLCAny _mlc_header;
63+
T data;
64+
};
65+
66+
MLC_INLINE_NO_MSVC static MLCAny *New(T data) {
67+
Storage *ret = new Storage;
68+
ret->_mlc_header.type_index = ::mlc::base::TypeTraits<T>::type_index;
69+
ret->_mlc_header.ref_cnt = 0;
70+
ret->_mlc_header.deleter = PODAllocator::Deleter;
71+
ret->data = data;
72+
return reinterpret_cast<MLCAny *>(ret);
73+
}
74+
75+
static void Deleter(void *objptr) { delete reinterpret_cast<Storage *>(objptr); }
76+
};
77+
78+
} // namespace mlc
79+
80+
#endif // MLC_BASE_ALLOC_H_

include/mlc/base/any.h

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,27 @@ struct AnyView : public MLCAny {
1313
MLC_INLINE AnyView() : MLCAny() {}
1414
MLC_INLINE AnyView(std::nullptr_t) : MLCAny() {}
1515
MLC_INLINE AnyView(NullType) : MLCAny() {}
16-
MLC_INLINE AnyView &operator=(std::nullptr_t) { return this->Reset(); }
17-
MLC_INLINE AnyView &operator=(NullType) { return this->Reset(); }
1816
MLC_INLINE AnyView &Reset() {
1917
*(static_cast<MLCAny *>(this)) = MLCAny();
2018
return *this;
2119
}
2220
/***** Section 2. Conversion between Any/AnyView *****/
2321
MLC_INLINE AnyView(const AnyView &src) = default;
2422
MLC_INLINE AnyView(AnyView &&src) = default;
25-
MLC_INLINE AnyView(const Any &src);
26-
MLC_INLINE AnyView(Any &&src);
2723
MLC_INLINE AnyView &operator=(const AnyView &src) = default;
2824
MLC_INLINE AnyView &operator=(AnyView &&src) = default;
29-
MLC_INLINE AnyView &operator=(const Any &src);
30-
MLC_INLINE AnyView &operator=(Any &&src);
25+
MLC_INLINE AnyView(const Any &src);
26+
MLC_INLINE AnyView(Any &&src);
3127
/***** Section 3. Conversion between POD and object pointers *****/
3228
template <typename T> MLC_INLINE_NO_MSVC T Cast() const;
3329
template <typename T> MLC_INLINE_NO_MSVC T CastWithStorage(Any *storage) const;
3430
template <typename T> MLC_INLINE operator T() const { return this->Cast<T>(); }
3531
template <typename T> MLC_INLINE AnyView(const T &src);
36-
template <typename T> MLC_INLINE AnyView &operator=(const T &src) {
37-
AnyView(src).Swap(*this);
32+
/***** Misc *****/
33+
template <typename T> MLC_INLINE AnyView &operator=(T &&src) { // Forward everything
34+
AnyView(std::forward<T>(src)).Swap(*this);
3835
return *this;
3936
}
40-
/***** Misc *****/
4137
Str str() const;
4238
friend std::ostream &operator<<(std::ostream &os, const AnyView &src);
4339

@@ -56,8 +52,6 @@ struct Any : public MLCAny {
5652
MLC_INLINE Any() : MLCAny() {}
5753
MLC_INLINE Any(std::nullptr_t) : MLCAny() {}
5854
MLC_INLINE Any(NullType) : MLCAny() {}
59-
MLC_INLINE Any &operator=(std::nullptr_t) { return this->Reset(); }
60-
MLC_INLINE Any &operator=(NullType) { return this->Reset(); }
6155
MLC_INLINE Any &Reset() {
6256
this->DecRef();
6357
*(static_cast<MLCAny *>(this)) = MLCAny();
@@ -66,19 +60,17 @@ struct Any : public MLCAny {
6660
/***** Section 2. Conversion between Any/AnyView *****/
6761
MLC_INLINE Any(const Any &src);
6862
MLC_INLINE Any(Any &&src);
69-
MLC_INLINE Any(const AnyView &src);
70-
MLC_INLINE Any(AnyView &&src);
7163
MLC_INLINE Any &operator=(const Any &src);
7264
MLC_INLINE Any &operator=(Any &&src);
73-
MLC_INLINE Any &operator=(const AnyView &src);
74-
MLC_INLINE Any &operator=(AnyView &&src);
65+
MLC_INLINE Any(const AnyView &src);
66+
MLC_INLINE Any(AnyView &&src);
7567
/***** Section 3. Conversion between POD and object pointers *****/
7668
template <typename T> MLC_INLINE_NO_MSVC T Cast() const;
7769
template <typename T> MLC_INLINE_NO_MSVC T CastWithStorage(Any *storage) const;
7870
template <typename T> MLC_INLINE operator T() const { return this->Cast<T>(); }
7971
template <typename T> MLC_INLINE Any(const T &src);
80-
template <typename T> MLC_INLINE Any &operator=(const T &src) {
81-
Any(src).Swap(*this);
72+
template <typename T> MLC_INLINE Any &operator=(T &&src) { // Forward everything
73+
Any(std::forward<T>(src)).Swap(*this);
8274
return *this;
8375
}
8476
/***** Misc *****/
@@ -132,6 +124,8 @@ template <typename... Args> struct AnyViewArrayFill {
132124
(void)TExpander{0, (Apply<I>(v, std::forward<Args>(args)), 0)...};
133125
}
134126
};
127+
template <typename T> inline AnyView AnyViewFromPODPtr(const T *src) { return src ? AnyView(*src) : AnyView(); }
128+
template <typename T> inline Any AnyFromPODPtr(const T *src) { return src ? Any(*src) : Any(); }
135129
} // namespace base
136130
} // namespace mlc
137131

0 commit comments

Comments
 (0)