LINUX.ORG.RU

История изменений

Исправление PRN, (текущая версия) :

А как ты список тегов в темплейт передашь?

Списком типов. На C++17 приблизительно так:

#include <type_traits>
#include <tuple>
#include <iostream>

template <typename T, typename Tuple>
struct has_type: std::false_type {};

template <typename T, typename... Us>
struct has_type<T, std::tuple<Us...>> : std::disjunction<std::is_same<T, Us>...> {};

template <typename T, typename... Us>
inline constexpr bool has_type_v = has_type<T, Us...>::value;

struct foo_tag{};
struct bar_tag{};

struct AllGroup
{
    using List = std::tuple<foo_tag, bar_tag>;
};

struct FooGroup
{
    using List = std::tuple<foo_tag>;
};

template<class Group>
class log
{
public:
    template<typename T = foo_tag>
    std::enable_if_t<std::is_same_v<T, foo_tag> && has_type_v<foo_tag, typename Group::List>>
    foo() { std::cout << "do foo\n"; }

    template<typename T = foo_tag>
    std::enable_if_t<std::is_same_v<T, foo_tag> && !has_type_v<foo_tag, typename Group::List>>
    foo() { std::cout << "do nothing instead foo\n"; }

    template<typename T = bar_tag>
    std::enable_if_t<std::is_same_v<T, bar_tag> && has_type_v<bar_tag, typename Group::List>>
    bar() { std::cout << "do bar\n"; }

    template<typename T = bar_tag>
    std::enable_if_t<std::is_same_v<T, bar_tag> && !has_type_v<bar_tag, typename Group::List>>
    bar() { std::cout << "do nothing instead bar\n"; }
};

int main()
{
    log<FooGroup> foo;
    foo.foo();
    foo.bar();

    log<AllGroup> all;
    all.foo();
    all.bar();
}

Выведет:

do foo
do nothing instead bar
do foo
do bar

Про C++11 я забыл как про страшный сон))). По крайней мере большую часть того что выше написано на C++17, в C++11 можно заменить с помощью boost::mpl, boost::tuple и т.д.

Идея в том, чтобы можно было задать фильтры, и вызовы логера с ненужными тегами превратились в пустые функции

Еще условия в enable_if_t поменять на противоположные)

Статик в теге пробовал. Та же фигня с линкером.

Юзай наследование:

class LogFooGroup : public log<FooGroup> ...

Оно должно помочь. Дальше везде LogFooGroup вместо шаблона.

Исправление PRN, :

А как ты список тегов в темплейт передашь?

Списком типов. На C++17 приблизительно так:

#include <type_traits>
#include <tuple>
#include <iostream>

template <typename T, typename Tuple>
struct has_type: std::false_type {};

template <typename T, typename... Us>
struct has_type<T, std::tuple<Us...>> : std::disjunction<std::is_same<T, Us>...> {};

template <typename T, typename... Us>
inline constexpr bool has_type_v = has_type<T, Us...>::value;

struct foo_tag{};
struct bar_tag{};

struct AllGroup
{
    using List = std::tuple<foo_tag, bar_tag>;
};

struct FooGroup
{
    using List = std::tuple<foo_tag>;
};

template<class Group>
class log
{
public:
    template<typename T = foo_tag>
    std::enable_if_t<std::is_same_v<T, foo_tag> && has_type_v<foo_tag, typename Group::List>>
    foo() { std::cout << "do foo\n"; }

    template<typename T = foo_tag>
    std::enable_if_t<std::is_same_v<T, foo_tag> && !has_type_v<foo_tag, typename Group::List>>
    foo() { std::cout << "do nothing instead foo\n"; }

    template<typename T = bar_tag>
    std::enable_if_t<std::is_same_v<T, bar_tag> && has_type_v<bar_tag, typename Group::List>>
    bar() { std::cout << "do bar\n"; }

    template<typename T = bar_tag>
    std::enable_if_t<std::is_same_v<T, bar_tag> && !has_type_v<bar_tag, typename Group::List>>
    bar() { std::cout << "do nothing instead bar\n"; }
};

int main()
{
    log<FooGroup> foo;
    foo.foo();
    foo.bar();

    log<AllGroup> all;
    all.foo();
    all.bar();
}

Выведет:

do foo
do nothing instead bar
do foo
do bar

Про C++11 я забыл как про страшный сон))). По крайней мере большую часть того что выше написано, в C++11 можно заменить с помощью boost::mpl

Идея в том, чтобы можно было задать фильтры, и вызовы логера с ненужными тегами превратились в пустые функции

Еще условия в enable_if_t поменять на противоположные)

Статик в теге пробовал. Та же фигня с линкером.

Юзай наследование:

class LogFooGroup : public log<FooGroup> ...

Оно должно помочь. Дальше везде LogFooGroup вместо шаблона.

Исходная версия PRN, :

А как ты список тегов в темплейт передашь?

Списком типов. На C++17 приблизительно так:

#include <type_traits>
#include <tuple>
#include <iostream>

template <typename T, typename Tuple>
struct has_type: std::false_type {};

template <typename T, typename... Us>
struct has_type<T, std::tuple<Us...>> : std::disjunction<std::is_same<T, Us>...> {};

template <typename T, typename... Us>
inline constexpr bool has_type_v = has_type<T, Us...>::value;

struct foo_tag{};
struct bar_tag{};

struct AllGroup
{
    using List = std::tuple<foo_tag, bar_tag>;
};

struct FooGroup
{
    using List = std::tuple<foo_tag>;
};

template<class Group>
class log
{
public:
    template<typename T = foo_tag>
    std::enable_if_t<std::is_same_v<T, foo_tag> && has_type_v<foo_tag, typename Group::List>>
    foo() { std::cout << "do foo\n"; }

    template<typename T = foo_tag>
    std::enable_if_t<std::is_same_v<T, foo_tag> && !has_type_v<foo_tag, typename Group::List>>
    foo() { std::cout << "do nothing instead foo\n"; }

    template<typename T = bar_tag>
    std::enable_if_t<std::is_same_v<T, bar_tag> && has_type_v<bar_tag, typename Group::List>>
    bar() { std::cout << "do bar\n"; }

    template<typename T = bar_tag>
    std::enable_if_t<std::is_same_v<T, bar_tag> && !has_type_v<bar_tag, typename Group::List>>
    bar() { std::cout << "do nothing instead bar\n"; }
};

int main()
{
    log<FooGroup> foo;
    foo.foo();
    foo.bar();

    log<AllGroup> all;
    all.foo();
    all.bar();
}

Выведет:

do foo
do nothing instead bar
do foo
do bar

Про C++11 я забыл как про страшный сон))). По крайней мере большую часть того что выше написано, в C++11 можно заменить с помощью boost::mpl

Идея в том, чтобы можно было задать фильтры, и вызовы логера с ненужными тегами превратились в пустые функции

Еще условия в enable_if_t поменять на противоположные)

Статик в теге пробовал. Та же фигня с линкером.

Юзай наследование:

class LogFooGroup : public log<FooGroup> ...

Оно должно помочь.