TypedDataSegment: add handlers for all tested types

This commit is contained in:
Jake Hillion 2023-04-20 09:52:58 -07:00 committed by Jake Hillion
parent 77667e5741
commit edaf499ced
24 changed files with 616 additions and 0 deletions

View File

@ -35,6 +35,42 @@ This document describes the format of the container definition files contained i
C++ code for the definition of a `getSizeType` function for this container.
- `handler`
C++ code for the definition of a `TypeHandler` class for this container. See
further down for a description.
## Changes introduced with Typed Data Segment
- `decl` and `func` fields are ignored when using `-ftyped-data-segment` and the
`handler` field is used instead.
### TypeHandler Classes
A `TypeHandler` class describes both what a type will write into the data segment
and how to write it. It consists of two major parts:
- `using type = ...;` - describe what it will write into the data segment.
- `static StaticTypes::Unit<DB> getSizeType(...)` - a function which takes a
const reference to a container and a `::type` by value and fills in the type.
Example:
```cpp
template <typename DB, typename T0>
struct TypeHandler<DB, std::string<T0>> {
using type =
StaticTypes::Pair<DB, StaticTypes::VarInt<DB>, StaticTypes::VarInt<DB>>;
static StaticTypes::Unit<DB> getSizeType(
const std::string<T0> & container,
typename TypeHandler<DB, std::string<T0>>::type returnArg) {
bool sso = ((uintptr_t)container.data() <
(uintptr_t)(&container + sizeof(std::string<T0>))) &&
((uintptr_t)container.data() >= (uintptr_t)&container);
return returnArg.write(container.capacity()).write(container.size());
}
};
```
## Changes introduced with TypeGraph
- `typeName` and `matcher` fields have been merged into the single field `type_name`.

View File

@ -28,3 +28,24 @@ void getSizeType(const %1%<T,N> &container, size_t& returnArg)
}
}
"""
handler = """
template<typename DB, typename T0, long unsigned int N>
struct TypeHandler<DB, %1%<T0, N>> {
using type = StaticTypes::List<DB, typename TypeHandler<DB, T0>::type>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0, N> &container,
typename TypeHandler<DB, %1%<T0,N>>::type returnArg) {
auto tail = returnArg.write(container.size());
for (auto & it: container) {
tail = tail.delegate([&it](auto ret) {
return TypeHandler<DB, T0>::getSizeType(it, ret);
});
}
return tail.finish();
}
};
"""

View File

@ -32,3 +32,29 @@ void getSizeType(const %1%<T, Allocator> &container, size_t& returnArg)
}
}
"""
handler = """
template <typename DB, typename T0, typename T1>
struct TypeHandler<DB, %1% <T0, T1>> {
using type = StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::List<DB, typename TypeHandler<DB, T0>::type>>;
static StaticTypes::Unit<DB> getSizeType(
const %1% <T0, T1> & container,
typename TypeHandler<DB, %1% <T0, T1>>::type returnArg) {
auto tail = returnArg.write((uintptr_t)&container)
.write(container.size());
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
});
}
return tail.finish();
}
};
"""

View File

@ -35,3 +35,21 @@ void getSizeType(const %1%<T, Traits, Allocator> &container, size_t& returnArg)
);
}
"""
handler = """
template <typename DB, typename T0>
struct TypeHandler<DB, %1% <T0>> {
using type =
StaticTypes::Pair<DB, StaticTypes::VarInt<DB>, StaticTypes::VarInt<DB>>;
static StaticTypes::Unit<DB> getSizeType(
const %1% <T0> & container,
typename TypeHandler<DB, %1% <T0>>::type returnArg) {
bool sso = ((uintptr_t)container.data() <
(uintptr_t)(&container + sizeof(%1% <T0>))) &&
((uintptr_t)container.data() >= (uintptr_t)&container);
return returnArg.write(container.capacity()).write(container.size());
}
};
"""

View File

@ -32,3 +32,29 @@ void getSizeType(const %1%<T, Allocator> &container, size_t& returnArg)
}
}
"""
handler = """
template <typename DB, typename T0, typename T1>
struct TypeHandler<DB, %1%<T0, T1>> {
using type = StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::List<DB, typename TypeHandler<DB, T0>::type>>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0, T1>& container,
typename TypeHandler<DB, %1%<T0, T1>>::type returnArg) {
auto tail = returnArg.write((uintptr_t)&container)
.write(container.size());
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return TypeHandler<DB, T0>::getSizeType(it, ret);
});
}
return tail.finish();
}
};
"""

View File

@ -37,3 +37,35 @@ void getSizeType(const %1%<E, T, A, Storage> &container, size_t& returnArg)
}
}
"""
handler = """
template <typename DB, typename T0, typename T1, typename T2, typename T3>
struct TypeHandler<DB, %1%<T0, T1, T2, T3>> {
using type = StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::VarInt<DB>
>>>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0, T1, T2, T3>& container,
typename TypeHandler<DB, %1%<T0, T1, T2, T3>>::type returnArg) {
auto last = returnArg.write((uintptr_t)container.data())
.write(container.capacity())
.write(container.size());
bool inlined = ((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%<T0, T1, T2, T3>)))
&&
((uintptr_t)container.data() >= (uintptr_t)&container);
if (!inlined && pointers.add((uintptr_t)container.data())) {
return last.write(1);
} else {
return last.write(0);
}
}
};
"""

View File

@ -32,3 +32,29 @@ void getSizeType(const %1%<T, Allocator> &container, size_t& returnArg)
}
}
"""
handler = """
template <typename DB, typename T0, typename T1>
struct TypeHandler<DB, %1% <T0, T1>> {
using type = StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::List<DB, typename TypeHandler<DB, T0>::type>>;
static StaticTypes::Unit<DB> getSizeType(
const %1% <T0, T1> & container,
typename TypeHandler<DB, %1% <T0, T1>>::type returnArg) {
auto tail = returnArg.write((uintptr_t)&container)
.write(container.size());
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
});
}
return tail.finish();
}
};
"""

View File

@ -32,3 +32,31 @@ void getSizeType(const %1%<Key,T,Compare,Allocator> &container, size_t& returnAr
}
}
"""
handler = """
template <typename DB, typename T0, typename T1, typename T2, typename T3>
struct TypeHandler<DB, %1%<T0, T1, T2, T3>> {
using type = StaticTypes::List<DB, StaticTypes::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type
>>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0, T1, T2, T3>& container,
typename TypeHandler<DB, %1%<T0, T1, T2, T3>>::type returnArg) {
auto tail = returnArg.write(container.size());
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it.second, ret.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it.first, ret);
}));
});
}
return tail.finish();
}
};
"""

View File

@ -27,3 +27,25 @@ void getSizeType(const %1%<T>& container, size_t& returnArg) {
}
}
"""
handler = """
template <typename DB, typename T0>
struct TypeHandler<DB, %1%<T0>> {
using type = StaticTypes::Sum<DB,
StaticTypes::Unit<DB>,
typename TypeHandler<DB, T0>::type
>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0>& container,
typename TypeHandler<DB, %1%<T0>>::type returnArg) {
if (container) {
return returnArg.template delegate<1>([&container](auto ret) {
return OIInternal::getSizeType<DB>(*container, ret);
});
} else {
return returnArg.template delegate<0>(std::identity());
}
}
};
"""

View File

@ -25,3 +25,23 @@ void getSizeType(const %1%<P,Q> &container, size_t& returnArg)
getSizeType(container.second, returnArg);
}
"""
handler = """
template <typename DB, typename T0, typename T1>
struct TypeHandler<DB, %1%<T0, T1>> {
using type = StaticTypes::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0, T1> & container,
typename TypeHandler<DB, %1%<T0, T1>>::type returnArg) {
return OIInternal::getSizeType<DB>(
container.second,
returnArg.delegate([&container](auto ret) {
return OIInternal::getSizeType<DB>(container.first, ret);
})
);
}
};
"""

View File

@ -32,3 +32,21 @@ void getSizeType(const %1%<T, Container, Cmp> &containerAdapter, size_t& returnA
getSizeType(container, returnArg);
}
"""
handler = """
template <typename DB, typename T0, typename T1, typename T2>
struct TypeHandler<DB, %1%<T0, T1, T2>> {
using type = StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
typename TypeHandler<DB, T1>::type>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0, T1, T2>& container,
typename TypeHandler<DB, %1%<T0, T1, T2>>::type returnArg) {
auto tail = returnArg.write((uintptr_t)&container);
const T1 &underlyingContainer = get_container(container);
return OIInternal::getSizeType<DB>(underlyingContainer, tail);
}
};
"""

View File

@ -31,3 +31,21 @@ void getSizeType(const %1%<T, Container> &containerAdapter, size_t& returnArg)
getSizeType(container, returnArg);
}
"""
handler = """
template <typename DB, typename T0, typename T1>
struct TypeHandler<DB, %1%<T0, T1>> {
using type = StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
typename TypeHandler<DB, T1>::type>;
static StaticTypes::Unit<DB> getSizeType(
const %1% <T0, T1> & container,
typename TypeHandler<DB, %1% <T0, T1>>::type returnArg) {
auto tail = returnArg.write((uintptr_t)&container);
const T1 &underlyingContainer = get_container(container);
return OIInternal::getSizeType<DB>(underlyingContainer, tail);
}
};
"""

View File

@ -29,3 +29,29 @@ void getSizeType(const %1%<T> &ref, size_t& returnArg)
}
}
"""
handler = """
template <typename DB, typename T0>
struct TypeHandler<DB, %1%<T0>> {
using type = StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::Sum<DB,
StaticTypes::Unit<DB>,
typename TypeHandler<DB, T0>::type
>>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0>& container,
typename TypeHandler<DB, %1%<T0>>::type returnArg) {
auto r0 = returnArg.write((uintptr_t)&(container.get()));
if (pointers.add((uintptr_t)&container.get())) {
return r0.template delegate<1>([&container](auto ret) {
return OIInternal::getSizeType<DB>(container.get(), ret);
});
} else {
return r0.template delegate<0>(std::identity());
}
}
};
"""

View File

@ -34,3 +34,32 @@ void getSizeType(const %1%<T, Allocator> &container, size_t& returnArg)
}
}
"""
handler = """
template <typename DB, typename T0>
struct TypeHandler<DB, %1% <T0>> {
using type = StaticTypes::Pair<
DB, StaticTypes::VarInt<DB>,
StaticTypes::Pair<
DB, StaticTypes::VarInt<DB>,
StaticTypes::List<DB, typename TypeHandler<DB, T0>::type>>>;
static StaticTypes::Unit<DB> getSizeType(
const %1% <T0> & container,
typename TypeHandler<DB, %1% <T0>>::type returnArg) {
auto tail = returnArg.write((uintptr_t)&container)
.write(container.capacity())
.write(container.size());
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
});
}
return tail.finish();
}
};
"""

View File

@ -35,3 +35,31 @@ void getSizeType(const %1%<Key, Compare, Alloc> &container, size_t& returnArg)
}
}
"""
handler = """
template <typename DB, typename T0, typename T1, typename T2>
struct TypeHandler<DB, %1% <T0, T1, T2>> {
using type = StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::List<DB, typename TypeHandler<DB, T0>::type>>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0, T1, T2>& container,
typename TypeHandler<DB, %1%<T0, T1, T2>>::type returnArg) {
constexpr size_t nodeSize = sizeof(typename %1%<T0, T1, T2>::node_type);
auto tail = returnArg.write(nodeSize)
.write(container.size());
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
});
}
return tail.finish();
}
};
"""

View File

@ -33,3 +33,35 @@ void getSizeType(const %1%<T> &s_ptr, size_t& returnArg)
}
}
"""
handler = """
template <typename DB, typename T0>
struct TypeHandler<DB, %1%<T0>> {
using type = typename std::conditional<
std::is_void<T0>::value,
StaticTypes::Unit<DB>,
StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::Sum<DB,
StaticTypes::Unit<DB>,
typename TypeHandler<DB, T0>::type
>>>::type;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0>& container,
typename TypeHandler<DB, %1%<T0>>::type returnArg) {
if constexpr (!std::is_void<T0>::value) {
auto r0 = returnArg.write((uintptr_t)(container.get()));
if (container && pointers.add((uintptr_t)(container.get()))) {
return r0.template delegate<1>([&container](auto ret) {
return OIInternal::getSizeType<DB>(*(container.get()), ret);
});
} else {
return r0.template delegate<0>(std::identity());
}
} else {
return returnArg;
}
}
};
"""

View File

@ -30,3 +30,20 @@ void getSizeType(const %1%<T,Compare, Allocator, GrowthPolicy, Container> &conta
getSizeType(container, returnArg);
}
"""
handler = """
template <typename DB, typename T0, typename T1, typename T2, typename T3, typename T4>
struct TypeHandler<DB, %1%<T0, T1, T2, T3, T4>> {
using type = StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
typename TypeHandler<DB, T4>::type>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0, T1, T2, T3, T4>& container,
typename TypeHandler<DB, %1%<T0, T1, T2, T3, T4>>::type returnArg) {
auto tail = returnArg.write((uintptr_t)&container);
const T4 &underlyingContainer = container.get_container();
return OIInternal::getSizeType<DB>(underlyingContainer, tail);
}
};
"""

View File

@ -31,3 +31,21 @@ void getSizeType(const %1%<T, Container> &containerAdapter, size_t& returnArg)
getSizeType(container, returnArg);
}
"""
handler = """
template <typename DB, typename T0, typename T1>
struct TypeHandler<DB, %1%<T0, T1>> {
using type = StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
typename TypeHandler<DB, T1>::type>;
static StaticTypes::Unit<DB> getSizeType(
const %1% <T0, T1> & container,
typename TypeHandler<DB, %1% <T0, T1>>::type returnArg) {
auto tail = returnArg.write((uintptr_t)&container);
const T1 &underlyingContainer = get_container(container);
return OIInternal::getSizeType<DB>(underlyingContainer, tail);
}
};
"""

View File

@ -36,3 +36,35 @@ void getSizeType(const %1%<K, T, C, A> &container, size_t& returnArg)
}
}
"""
handler = """
template <typename DB, typename T0, typename T1, typename T2, typename T3>
struct TypeHandler<DB, %1%<T0, T1, T2, T3>> {
using type = StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::List<DB, StaticTypes::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type
>>>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0, T1, T2, T3>& container,
typename TypeHandler<DB, %1%<T0, T1, T2, T3>>::type returnArg) {
constexpr size_t nodeSize = sizeof(typename %1%<T0, T1, T2, T3>::node_type);
auto tail = returnArg.write(nodeSize).write(container.size());
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (const auto& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it.second, ret.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it.first, ret);
}));
});
}
return tail.finish();
}
};
"""

View File

@ -38,3 +38,39 @@ void getSizeType(const %1%<K, T, H, KE, A> &container, size_t& returnArg)
}
}
"""
handler = """
template <typename DB, typename T0, typename T1, typename T2, typename T3, typename T4>
struct TypeHandler<DB, %1%<T0, T1, T2, T3, T4>> {
using type = StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::List<DB, StaticTypes::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type
>>>>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0, T1, T2, T3, T4>& container,
typename TypeHandler<DB, %1%<T0, T1, T2, T3, T4>>::type returnArg) {
constexpr size_t nodeSize = sizeof(typename %1%<T0, T1, T2, T3, T4>::node_type);
auto tail = returnArg.write(nodeSize)
.write(container.bucket_count())
.write(container.size());
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (const auto& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it.second, ret.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it.first, ret);
}));
});
}
return tail.finish();
}
};
"""

View File

@ -35,3 +35,34 @@ void getSizeType(const %1%<Types...> &container, size_t& returnArg)
}, container);
}
"""
handler = """
template <typename DB, typename... Types>
struct TypeHandler<DB, %1%<Types...>> {
using type = StaticTypes::Sum<DB, typename TypeHandler<DB, Types>::type..., StaticTypes::Unit<DB>>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<Types...>& container,
typename TypeHandler<DB, %1%<Types...>>::type returnArg) {
return getSizeTypeRecursive(container, returnArg);
}
private:
template <size_t I = 0>
static StaticTypes::Unit<DB> getSizeTypeRecursive(
const %1%<Types...>& container,
typename TypeHandler<DB, %1%<Types...>>::type returnArg) {
if constexpr (I < sizeof...(Types)) {
if (I == container.index()) {
return returnArg.template delegate<I>([&container](auto ret) {
return OIInternal::getSizeType<DB>(std::get<I>(container), ret);
});
} else {
return getSizeTypeRecursive<I+1>(container, returnArg);
}
} else {
return returnArg.template delegate<sizeof...(Types)>(std::identity());
}
}
};
"""

View File

@ -34,3 +34,35 @@ void getSizeType(const %1%<T,Deleter> &u_ptr, size_t& returnArg)
}
}
"""
handler = """
template <typename DB, typename T0, typename T1>
struct TypeHandler<DB, %1%<T0,T1>> {
using type = typename std::conditional<
std::is_void<T0>::value,
StaticTypes::Unit<DB>,
StaticTypes::Pair<DB,
StaticTypes::VarInt<DB>,
StaticTypes::Sum<DB,
StaticTypes::Unit<DB>,
typename TypeHandler<DB, T0>::type
>>>::type;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0,T1>& container,
typename TypeHandler<DB, %1%<T0,T1>>::type returnArg) {
if constexpr (!std::is_void<T0>::value) {
auto r0 = returnArg.write((uintptr_t)(container.get()));
if (container && pointers.add((uintptr_t)(container.get()))) {
return r0.template delegate<1>([&container](auto ret) {
return OIInternal::getSizeType<DB>(*(container.get()), ret);
});
} else {
return r0.template delegate<0>(std::identity());
}
} else {
return returnArg;
}
}
};
"""

View File

@ -36,3 +36,34 @@ void getSizeType(const %1%<Key, Hasher, KeyEqual, Alloc> &container, size_t& ret
}
}
"""
handler = """
template <typename DB, typename T0, typename T1, typename T2, typename T3>
struct TypeHandler<DB, %1%<T0, T1, T2, T3>> {
using type = StaticTypes::Pair<
DB, StaticTypes::VarInt<DB>,
StaticTypes::Pair<
DB, StaticTypes::VarInt<DB>,
StaticTypes::List<DB, typename TypeHandler<DB, T0>::type>>>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0, T1, T2, T3>& container,
typename TypeHandler<DB, %1%<T0, T1, T2, T3>>::type returnArg) {
constexpr size_t nodeSize = sizeof(typename %1%<T0, T1, T2, T3>::node_type);
auto tail = returnArg.write(nodeSize)
.write(container.bucket_count())
.write(container.size());
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
});
}
return tail.finish();
}
};
"""

View File

@ -23,3 +23,16 @@ void getSizeType(const %1%<T> &s_ptr, size_t& returnArg)
SAVE_SIZE(sizeof(%1%<T>));
}
"""
handler = """
template <typename DB, typename T0>
struct TypeHandler<DB, %1%<T0>> {
using type = StaticTypes::Unit<DB>;
static StaticTypes::Unit<DB> getSizeType(
const %1%<T0>& container,
typename TypeHandler<DB, %1%<T0>>::type returnArg) {
return returnArg;
}
};
"""