Skip to content

Commit

Permalink
feat: add small object optimize for AnyFunction
Browse files Browse the repository at this point in the history
  • Loading branch information
OEOTYAN committed Sep 2, 2024
1 parent 0ac8c17 commit 773efc8
Show file tree
Hide file tree
Showing 11 changed files with 222 additions and 88 deletions.
4 changes: 2 additions & 2 deletions src-test/common/AnyFnTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ static bool run = [] {

auto vec = std::vector<float>{0.7f, 0.7f, 0.7f};

fn = AnyFunction([](std::string const& par, int i, std::vector<float>&& fs) {
fn = [](std::string const& par, int i, std::vector<float>&& fs) {
ll::getLogger().info("{} | {} | {}", par, i, fs);
});
};

fn(std::string{"hmmmmm"}, 17, std::ref(vec));

Expand Down
2 changes: 1 addition & 1 deletion src/ll/api/base/Concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ template <class T, template <class...> class Z>
concept Specializes = traits::is_specialization_of_v<T, Z>;

template <class T>
inline constexpr bool tuple_like_impl =
constexpr bool tuple_like_impl =
traits::is_specialization_of_v<T, ::std::tuple> || traits::is_specialization_of_v<T, ::std::pair>
|| traits::is_std_array_v<T> || traits::is_subrange_v<T>;

Expand Down
88 changes: 46 additions & 42 deletions src/ll/api/base/TypeTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,34 +53,39 @@ struct function_signature<Ret (*)(Args...)> : function_signature<Ret(Args...)> {
template <class F>
struct function_signature : function_signature<decltype(&F::operator())> {};

#define LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(...) \
template <class Ret, class Cls, class... Args>
struct function_signature<Ret (Cls::*)(Args...)> : function_signature<Ret(Args...)> {};

#define LL_BUILD_FUNCTION_SIGNATURE(...) \
template <class Ret, class Cls, class... Args> \
struct function_signature<Ret (Cls::*)(Args...) __VA_ARGS__> : function_signature<Ret(Args...)> {};
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE()
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(const)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(volatile)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(const volatile)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(noexcept)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(const noexcept)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(volatile noexcept)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(const volatile noexcept)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(&)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(const&)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(volatile&)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(const volatile&)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(& noexcept)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(const& noexcept)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(volatile& noexcept)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(const volatile& noexcept)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(&&)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(const&&)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(volatile&&)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(const volatile&&)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(&& noexcept)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(const&& noexcept)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(volatile&& noexcept)
LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE(const volatile&& noexcept)
#undef LL_BUILD_FUNCTOR_FUNCTION_SIGNATURE
struct function_signature<Ret (Cls::*)(Args...) __VA_ARGS__> : function_signature<Ret(Args...) __VA_ARGS__> {}; \
template <class Ret, class... Args> \
struct function_signature<Ret(Args...) __VA_ARGS__> : function_signature<Ret(Args...)> {};

LL_BUILD_FUNCTION_SIGNATURE(const)
LL_BUILD_FUNCTION_SIGNATURE(volatile)
LL_BUILD_FUNCTION_SIGNATURE(const volatile)
LL_BUILD_FUNCTION_SIGNATURE(noexcept)
LL_BUILD_FUNCTION_SIGNATURE(const noexcept)
LL_BUILD_FUNCTION_SIGNATURE(volatile noexcept)
LL_BUILD_FUNCTION_SIGNATURE(const volatile noexcept)
LL_BUILD_FUNCTION_SIGNATURE(&)
LL_BUILD_FUNCTION_SIGNATURE(const&)
LL_BUILD_FUNCTION_SIGNATURE(volatile&)
LL_BUILD_FUNCTION_SIGNATURE(const volatile&)
LL_BUILD_FUNCTION_SIGNATURE(& noexcept)
LL_BUILD_FUNCTION_SIGNATURE(const& noexcept)
LL_BUILD_FUNCTION_SIGNATURE(volatile& noexcept)
LL_BUILD_FUNCTION_SIGNATURE(const volatile& noexcept)
LL_BUILD_FUNCTION_SIGNATURE(&&)
LL_BUILD_FUNCTION_SIGNATURE(const&&)
LL_BUILD_FUNCTION_SIGNATURE(volatile&&)
LL_BUILD_FUNCTION_SIGNATURE(const volatile&&)
LL_BUILD_FUNCTION_SIGNATURE(&& noexcept)
LL_BUILD_FUNCTION_SIGNATURE(const&& noexcept)
LL_BUILD_FUNCTION_SIGNATURE(volatile&& noexcept)
LL_BUILD_FUNCTION_SIGNATURE(const volatile&& noexcept)
#undef LL_BUILD_FUNCTION_SIGNATURE

template <class T>
using function_signature_t = typename function_signature<T>::type;
Expand All @@ -92,46 +97,46 @@ template <class T, template <class...> class U, class... Ts>
struct is_in_types<T, U<Ts...>> : std::bool_constant<(std::is_same_v<T, Ts> || ...)> {};

template <class T, class U>
inline constexpr bool is_in_types_v = is_in_types<T, U>::value;
constexpr bool is_in_types_v = is_in_types<T, U>::value;

template <class T, class... Ts>
inline constexpr bool is_one_of_v = (std::is_same_v<T, Ts> || ...);
constexpr bool is_one_of_v = (std::is_same_v<T, Ts> || ...);

template <class T, class... Ts>
struct is_one_of : std::bool_constant<is_one_of_v<T, Ts...>> {};

template <class T, class... Ts>
inline constexpr bool is_all_same_v = (std::is_same_v<T, Ts> && ...);
constexpr bool is_all_same_v = (std::is_same_v<T, Ts> && ...);

template <class T, class... Ts>
struct is_all_same : std::bool_constant<is_all_same_v<T, Ts...>> {};

template <class T>
inline constexpr bool is_string_v = std::is_constructible_v<std::string, T>;
constexpr bool is_string_v = std::is_constructible_v<std::string, T>;

template <class T>
inline constexpr bool is_char_v = is_one_of_v<T, char, wchar_t, char8_t, char16_t, char32_t>;
constexpr bool is_char_v = is_one_of_v<T, char, wchar_t, char8_t, char16_t, char32_t>;

template <class T>
inline constexpr bool is_non_char_integral_v = std::is_integral_v<T> && !is_char_v<T>;
constexpr bool is_non_char_integral_v = std::is_integral_v<T> && !is_char_v<T>;

template <class T, template <class...> class Z>
inline constexpr bool is_specialization_of_v = false;
constexpr bool is_specialization_of_v = false;

template <template <class...> class Z, class... Args>
inline constexpr bool is_specialization_of_v<Z<Args...>, Z> = true;
constexpr bool is_specialization_of_v<Z<Args...>, Z> = true;

template <class T, template <class...> class Z>
struct is_specialization_of : std::bool_constant<is_specialization_of_v<T, Z>> {};

template <class>
inline constexpr bool is_std_array_v = false;
constexpr bool is_std_array_v = false;

template <class T, size_t N>
inline constexpr bool is_std_array_v<::std::array<T, N>> = true;
constexpr bool is_std_array_v<::std::array<T, N>> = true;

template <class>
inline constexpr bool is_subrange_v = false;
constexpr bool is_subrange_v = false;

template <class I, class S, ::std::ranges::subrange_kind K>
constexpr bool is_subrange_v<::std::ranges::subrange<I, S, K>> = true;
Expand All @@ -140,17 +145,16 @@ template <template <class...> class T, class... Ts>
void derivedFromSpecializationImpl(T<Ts...> const&);

template <class T, template <class...> class Z>
inline constexpr bool is_derived_from_specialization_of_v =
requires(T const& t) { derivedFromSpecializationImpl<Z>(t); };
constexpr bool is_derived_from_specialization_of_v = requires(T const& t) { derivedFromSpecializationImpl<Z>(t); };

template <class T, template <class...> class Z>
struct is_derived_from_specialization_of : std::bool_constant<is_derived_from_specialization_of_v<T, Z>> {};

template <class...>
inline constexpr bool always_false = false;
constexpr bool always_false = false;

template <class T>
inline constexpr bool is_virtual_cloneable_v =
constexpr bool is_virtual_cloneable_v =
std::is_polymorphic_v<T> && requires(T const& t) { static_cast<T*>(t.clone().release()); };

} // namespace ll::traits
30 changes: 30 additions & 0 deletions src/ll/api/data/AnyBase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include <memory>
#include <type_traits>

namespace ll::data {
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4265)
#endif
class AnyBase {
public:
static constexpr inline size_t smallObjectNumPtrs = 8;
static constexpr inline size_t smallObjectSize = ((smallObjectNumPtrs - 1) * sizeof(void*));
template <class Data>
static constexpr bool isLarge = sizeof(Data) > smallObjectSize || alignof(Data) > alignof(std::max_align_t)
|| !Data::nothrowMove;

AnyBase() = default;
AnyBase(const AnyBase&) = delete;
AnyBase& operator=(const AnyBase&) = delete;

virtual AnyBase* copy(void* to) const = 0;
virtual AnyBase* move(void* to) noexcept = 0;
virtual void tidy() noexcept = 0;
};
#ifdef _MSC_VER
#pragma warning(pop)
#endif
} // namespace ll::data
Loading

0 comments on commit 773efc8

Please sign in to comment.