Skip to content
Merged
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions source/cppassist/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ set(headers

${include_path}/threading/parallelfor.h
${include_path}/threading/parallelfor.inl

${include_path}/typelist/TypeList.h
${include_path}/typelist/TypeList.inl

${include_path}/cmdline/ArgumentParser.h
${include_path}/cmdline/ArgumentParser.inl
Expand Down
68 changes: 68 additions & 0 deletions source/cppassist/include/cppassist/typelist/TypeList.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@

#pragma once


namespace cppassist
{


/**
* @brief
* A compile-time list of types.
*
* This is the default template for template specializations.
*/
template <typename... Types>
class TypeList;

/**
* @brief
* A compile-time list of types.
*
* This is the template specialization for non-zero type lists.
* There is an interface to call a template operator() on a Functor for each type in the type list.
*/
template <typename T, typename... Types>
class TypeList<T, Types...>
{
public:
/**
* @brief
* Call the template operator() on the Functor for each type.
*
* @param[in] callback
* The functor, supporting a templated operator()
*/
template <typename Functor>
static void apply(Functor && callback);
};

/**
* @brief
* A compile-time list of types.
*
* This is the template specialization for a zero type list.
* It is used as the recursion break condition.
*/
template <>
class TypeList<>
{
public:
/**
* @brief
* Call the template operator() on the Functor for each type.
*
* As this is the empty type list, no operator is called.
*
* @param[in] callback
* The functor, supporting a templated operator()
*/
template <typename Functor>
static void apply(Functor && callback);
};


} // namespace cppassist


#include <cppassist/typelist/TypeList.inl>
27 changes: 27 additions & 0 deletions source/cppassist/include/cppassist/typelist/TypeList.inl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

#pragma once


#include <utility>


namespace cppassist
{


template <typename T, typename... Types>
template <typename Functor>
void TypeList<T, Types...>::apply(Functor && callback)
{
(callback.template operator()<T>)();

TypeList<Types...>::apply(std::forward<Functor>(callback));
}

template <typename Functor>
void TypeList<>::apply(Functor && /*callback*/)
{
}


} // namespace cppassist
3 changes: 3 additions & 0 deletions source/tests/cppassist-test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ set(sources

# flags
flags_test.cpp

# typelist
typelist_test.cpp

# memory
make_unique_test.cpp
Expand Down
51 changes: 51 additions & 0 deletions source/tests/cppassist-test/typelist_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@

#include <gmock/gmock.h>

#include <cppassist/typelist/TypeList.h>


class typelist_test : public testing::Test
{
public:
typelist_test()
: intCallcount(0)
, floatCallcount(0)
, boolCallcount(0)
{
}

template <typename T>
void operator()()
{
if (typeid(T) == typeid(int))
{
++intCallcount;
}

if (typeid(T) == typeid(float))
{
++floatCallcount;
}

if (typeid(T) == typeid(bool))
{
++boolCallcount;
}
}
protected:
int intCallcount;
int floatCallcount;
int boolCallcount;
};


TEST_F(typelist_test, ListApply)
{
using list = cppassist::TypeList<int, float, bool>;

list::apply(*this);

ASSERT_EQ(intCallcount, 1);
ASSERT_EQ(floatCallcount, 1);
ASSERT_EQ(boolCallcount, 1);
}