Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add __declspec(empty_bases) to derived structs for size optimization #128

Merged
merged 2 commits into from
Jan 3, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 40 additions & 31 deletions include/type_safe/strong_typedef.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
#include <type_safe/config.hpp>
#include <type_safe/detail/all_of.hpp>

#ifdef _MSC_VER
# define TYPE_SAFE_MSC_EMPTY_BASES __declspec(empty_bases)
#else
# define TYPE_SAFE_MSC_EMPTY_BASES
#endif

namespace type_safe
{
/// A strong typedef emulation.
Expand Down Expand Up @@ -198,7 +204,7 @@ namespace strong_typedef_op
using void_t = typename make_void<Ts...>::type;

template <class T, typename = void_t<>>
struct is_strong_typedef : std::false_type
struct TYPE_SAFE_MSC_EMPTY_BASES is_strong_typedef : std::false_type
{};

template <class T>
Expand Down Expand Up @@ -547,24 +553,24 @@ namespace strong_typedef_op
}

template <class StrongTypedef>
struct integer_arithmetic : unary_plus<StrongTypedef>,
unary_minus<StrongTypedef>,
addition<StrongTypedef>,
subtraction<StrongTypedef>,
multiplication<StrongTypedef>,
division<StrongTypedef>,
modulo<StrongTypedef>,
increment<StrongTypedef>,
decrement<StrongTypedef>
struct TYPE_SAFE_MSC_EMPTY_BASES integer_arithmetic : unary_plus<StrongTypedef>,
unary_minus<StrongTypedef>,
addition<StrongTypedef>,
subtraction<StrongTypedef>,
multiplication<StrongTypedef>,
division<StrongTypedef>,
modulo<StrongTypedef>,
increment<StrongTypedef>,
decrement<StrongTypedef>
{};

template <class StrongTypedef>
struct floating_point_arithmetic : unary_plus<StrongTypedef>,
unary_minus<StrongTypedef>,
addition<StrongTypedef>,
subtraction<StrongTypedef>,
multiplication<StrongTypedef>,
division<StrongTypedef>
struct TYPE_SAFE_MSC_EMPTY_BASES floating_point_arithmetic : unary_plus<StrongTypedef>,
unary_minus<StrongTypedef>,
addition<StrongTypedef>,
subtraction<StrongTypedef>,
multiplication<StrongTypedef>,
division<StrongTypedef>
{};

template <class StrongTypedef>
Expand All @@ -589,10 +595,10 @@ namespace strong_typedef_op
TYPE_SAFE_DETAIL_MAKE_STRONG_TYPEDEF_OP(bitwise_and, &)

template <class StrongTypedef>
struct bitmask : complement<StrongTypedef>,
bitwise_or<StrongTypedef>,
bitwise_xor<StrongTypedef>,
bitwise_and<StrongTypedef>
struct TYPE_SAFE_MSC_EMPTY_BASES bitmask : complement<StrongTypedef>,
bitwise_or<StrongTypedef>,
bitwise_xor<StrongTypedef>,
bitwise_and<StrongTypedef>
{};

template <class StrongTypedef, typename IntT>
Expand Down Expand Up @@ -655,7 +661,8 @@ namespace strong_typedef_op
};

template <class StrongTypedef, class Category, typename T, typename Distance = std::ptrdiff_t>
struct iterator : dereference<StrongTypedef, T, T*, const T*>, increment<StrongTypedef>
struct TYPE_SAFE_MSC_EMPTY_BASES iterator : dereference<StrongTypedef, T, T*, const T*>,
increment<StrongTypedef>
{
using iterator_category = Category;
using value_type = typename std::remove_cv<T>::type;
Expand All @@ -665,31 +672,31 @@ namespace strong_typedef_op
};

template <class StrongTypedef, typename T, typename Distance = std::ptrdiff_t>
struct input_iterator : iterator<StrongTypedef, std::input_iterator_tag, T, Distance>,
equality_comparison<StrongTypedef>
struct TYPE_SAFE_MSC_EMPTY_BASES input_iterator : iterator<StrongTypedef, std::input_iterator_tag, T, Distance>,
equality_comparison<StrongTypedef>
{};

template <class StrongTypedef, typename T, typename Distance = std::ptrdiff_t>
struct output_iterator : iterator<StrongTypedef, std::output_iterator_tag, T, Distance>
struct TYPE_SAFE_MSC_EMPTY_BASES output_iterator : iterator<StrongTypedef, std::output_iterator_tag, T, Distance>
{};

template <class StrongTypedef, typename T, typename Distance = std::ptrdiff_t>
struct forward_iterator : input_iterator<StrongTypedef, T, Distance>
struct TYPE_SAFE_MSC_EMPTY_BASES forward_iterator : input_iterator<StrongTypedef, T, Distance>
{
using iterator_category = std::forward_iterator_tag;
};

template <class StrongTypedef, typename T, typename Distance = std::ptrdiff_t>
struct bidirectional_iterator : forward_iterator<StrongTypedef, T, Distance>,
decrement<StrongTypedef>
struct TYPE_SAFE_MSC_EMPTY_BASES bidirectional_iterator : forward_iterator<StrongTypedef, T, Distance>,
decrement<StrongTypedef>
{
using iterator_category = std::bidirectional_iterator_tag;
};

template <class StrongTypedef, typename T, typename Distance = std::ptrdiff_t>
struct random_access_iterator : bidirectional_iterator<StrongTypedef, T, Distance>,
array_subscript<StrongTypedef, T, Distance>,
relational_comparison<StrongTypedef>
struct TYPE_SAFE_MSC_EMPTY_BASES random_access_iterator : bidirectional_iterator<StrongTypedef, T, Distance>,
array_subscript<StrongTypedef, T, Distance>,
relational_comparison<StrongTypedef>
{
using iterator_category = std::random_access_iterator_tag;

Expand Down Expand Up @@ -774,7 +781,7 @@ namespace strong_typedef_op
/// Inherit from it in the `std::hash<StrongTypedef>` specialization to make
/// it hashable like the underlying type. See example/strong_typedef.cpp.
template <class StrongTypedef>
struct hashable : std::hash<type_safe::underlying_type<StrongTypedef>>
struct TYPE_SAFE_MSC_EMPTY_BASES hashable : std::hash<type_safe::underlying_type<StrongTypedef>>
{
using underlying_type = type_safe::underlying_type<StrongTypedef>;
using underlying_hash = std::hash<underlying_type>;
Expand All @@ -787,4 +794,6 @@ struct hashable : std::hash<type_safe::underlying_type<StrongTypedef>>
};
} // namespace type_safe

#undef TYPE_SAFE_MSC_EMPTY_BASES

#endif // TYPE_SAFE_STRONG_TYPEDEF_HPP_INCLUDED