Skip to content

Commit

Permalink
force inlining to reduce final object size (yes **reduce**, with clan…
Browse files Browse the repository at this point in the history
…g++ at least)
  • Loading branch information
Dane Springmeyer committed Feb 12, 2014
1 parent 23f112a commit c65aa11
Showing 1 changed file with 29 additions and 23 deletions.
52 changes: 29 additions & 23 deletions variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
#include <new> // operator new
#include <cstddef> // size_t

#ifdef NDEBUG
#define VARIANT_INLINE inline __attribute__((always_inline))
#else
#define VARIANT_INLINE __attribute__((noinline))
#endif

namespace util {

namespace detail {
Expand Down Expand Up @@ -65,7 +71,7 @@ struct variant_helper;
template<typename T, typename... Types>
struct variant_helper<T, Types...>
{
inline static void destroy(std::size_t id, void * data)
VARIANT_INLINE static void destroy(std::size_t id, void * data)
{
if (id == sizeof...(Types))
{
Expand All @@ -77,7 +83,7 @@ struct variant_helper<T, Types...>
}
}

inline static void move(std::size_t old_t, void * old_v, void * new_v)
VARIANT_INLINE static void move(std::size_t old_t, void * old_v, void * new_v)
{
if (old_t == sizeof...(Types))
{
Expand All @@ -89,7 +95,7 @@ struct variant_helper<T, Types...>
}
}

inline static void copy(std::size_t old_t, const void * old_v, void * new_v)
VARIANT_INLINE static void copy(std::size_t old_t, const void * old_v, void * new_v)
{
if (old_t == sizeof...(Types))
{
Expand All @@ -104,9 +110,9 @@ struct variant_helper<T, Types...>

template<> struct variant_helper<>
{
inline static void destroy(std::size_t, void *) {}
inline static void move(std::size_t, void *, void *) {}
inline static void copy(std::size_t, const void *, void *) {}
VARIANT_INLINE static void destroy(std::size_t, void *) {}
VARIANT_INLINE static void move(std::size_t, void *, void *) {}
VARIANT_INLINE static void copy(std::size_t, const void *, void *) {}
};

namespace detail {
Expand All @@ -118,7 +124,7 @@ template <typename F, typename V, typename T, typename...Types>
struct dispatcher<F,V,T,Types...>
{
typedef typename std::result_of<F(V const&)>::type result_type;
static result_type apply(V const& v, F f)
VARIANT_INLINE static result_type apply(V const& v, F f)
{
if (v.get_type_id() == sizeof...(Types))
{
Expand All @@ -135,7 +141,7 @@ template<typename F,typename V>
struct dispatcher<F,V>
{
typedef typename std::result_of<F(V const&)>::type result_type;
static result_type apply(V const&, F)
VARIANT_INLINE static result_type apply(V const&, F)
{
throw std::runtime_error("dispatch: FAIL");
}
Expand All @@ -156,7 +162,7 @@ struct variant

using helper_t = variant_helper<Types...>;

static inline std::size_t invalid_type()
VARIANT_INLINE static std::size_t invalid_type()
{
return std::size_t(-1);
}
Expand All @@ -166,65 +172,65 @@ struct variant

public:

variant()
VARIANT_INLINE variant()
: type_id(invalid_type()) {}

template <typename T>
explicit variant(T const& val) noexcept
VARIANT_INLINE explicit variant(T const& val) noexcept
: type_id(detail::type_traits<T, Types...>::id)
{
static_assert(detail::is_valid_type<T,Types...>::value, "Not a valid type for this variant");
new (&data) T(val);
}

template <typename T>
variant(T && val) noexcept
VARIANT_INLINE variant(T && val) noexcept
: type_id(detail::type_traits<T,Types...>::id)
{
static_assert(detail::is_valid_type<T,Types...>::value, "Not a valid type for this variant");
new (&data) T(std::forward<T>(val)); // nothrow
}

variant(variant<Types...> const& old)
VARIANT_INLINE variant(variant<Types...> const& old)
: type_id(old.type_id)
{
helper_t::copy(old.type_id, &old.data, &data);
}

variant(variant<Types...>&& old) noexcept
VARIANT_INLINE variant(variant<Types...>&& old) noexcept
: type_id(old.type_id)
{
helper_t::move(old.type_id, &old.data, &data);
}

variant<Types...>& operator= (variant<Types...> old)
VARIANT_INLINE variant<Types...>& operator= (variant<Types...> old)
{
std::swap(type_id, old.type_id);
std::swap(data, old.data);
return *this;
}

template<typename T>
void is()
VARIANT_INLINE void is()
{
return (type_id == detail::type_traits<T, Types...>::id);
}

void valid()
VARIANT_INLINE void valid()
{
return (type_id != invalid_type());
}

template<typename T, typename... Args>
void set(Args&&... args)
VARIANT_INLINE void set(Args&&... args)
{
helper_t::destroy(type_id, &data);
new (&data) T(std::forward<Args>(args)...);
type_id = detail::type_traits<T,Types...>::id;
}

template<typename T>
T& get()
VARIANT_INLINE T& get()
{
if (type_id == detail::type_traits<T,Types...>::id)
{
Expand All @@ -237,7 +243,7 @@ struct variant
}

template<typename T>
T const& get() const
VARIANT_INLINE T const& get() const
{
if (type_id == detail::type_traits<T,Types...>::id)
{
Expand All @@ -249,15 +255,15 @@ struct variant
}
}

std::size_t get_type_id() const
VARIANT_INLINE std::size_t get_type_id() const
{
return type_id;
}

// visitor
template <typename F, typename V>
typename std::result_of<F(V const&)>::type
static visit(V const& v, F f)
VARIANT_INLINE static visit(V const& v, F f)
{
return detail::dispatcher<F, V, Types...>::apply(v, f);
}
Expand All @@ -271,7 +277,7 @@ struct variant
// unary visitor interface
template <typename V, typename F>
typename std::result_of<F(V const&)>::type
static apply_visitor(V const& v, F f)
VARIANT_INLINE static apply_visitor(V const& v, F f)
{
return V::visit(v,f);
}
Expand Down

0 comments on commit c65aa11

Please sign in to comment.