3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
tag.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
24#ifndef DUMUX_COMMON_TAG_HH
25#define DUMUX_COMMON_TAG_HH
26
27#include <sstream>
28#include <ostream>
29#include <type_traits>
30#include <dune/common/classname.hh>
32
33namespace Dumux::Utility {
34
41template<class T>
42struct Tag {};
43
45template<class T1, class T2>
46inline constexpr bool operator==(Tag<T1>, Tag<T2>)
47{ return std::is_same_v<T1, T2>; }
48
49template<class T1, class T2>
50inline constexpr bool operator!=(Tag<T1>, Tag<T2>)
51{ return !std::is_same_v<T1, T2>; }
52
53namespace Detail {
54constexpr auto hasName = isValid([](auto&& t) -> decltype(t.name(), void()) {});
55} // end namespace Detail
56
58template<class T, std::enable_if_t<std::is_base_of_v<Tag<T>, T>, int> = 0>
59auto operator<<(std::ostream& os, const T& t)
60-> std::enable_if_t<decltype(Detail::hasName(t))::value, std::ostream&>
61{ os << t.name(); return os; }
62
64template<class T, std::enable_if_t<std::is_base_of_v<Tag<T>, T>, int> = 0>
65auto operator<<(std::ostream& os, const T& t)
66-> std::enable_if_t<!decltype(Detail::hasName(t))::value, std::ostream&>
67{
68 const auto fullName = Dune::className<T>();
69
70 // strip all namespace qualifiers
71 const auto pos = fullName.rfind("::");
72 const auto name = pos != std::string::npos ? fullName.substr(pos+2) : fullName;
73
74 os << name;
75 return os;
76}
77
78} // end namespace Dumux::Utility
79
80#endif
A helper function for class member function introspection.
constexpr auto isValid(const Expression &t)
A function that creates a test functor to do class member introspection at compile time.
Definition: isvalid.hh:93
Definition: tag.hh:33
constexpr bool operator!=(Tag< T1 >, Tag< T2 >)
Definition: tag.hh:50
auto operator<<(std::ostream &os, const T &t) -> std::enable_if_t< decltype(Detail::hasName(t))::value, std::ostream & >
Return the class name of the tagged type calling t.name()
Definition: tag.hh:59
constexpr bool operator==(Tag< T1 >, Tag< T2 >)
Tags are equality comparable and return true if the tagged types are equal.
Definition: tag.hh:46
constexpr auto hasName
Definition: tag.hh:54
Helper class to create (named and comparable) tagged types Tags any given type. The tagged type is eq...
Definition: tag.hh:42