version 3.8
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// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_COMMON_TAG_HH
13#define DUMUX_COMMON_TAG_HH
14
15#include <sstream>
16#include <ostream>
17#include <type_traits>
18#include <dune/common/classname.hh>
20
21namespace Dumux::Utility {
22
29template<class T>
30struct Tag {};
31
33template<class T1, class T2>
34inline constexpr bool operator==(Tag<T1>, Tag<T2>)
35{ return std::is_same_v<T1, T2>; }
36
37template<class T1, class T2>
38inline constexpr bool operator!=(Tag<T1>, Tag<T2>)
39{ return !std::is_same_v<T1, T2>; }
40
41namespace Detail {
42// cppcheck-suppress internalAstError
43constexpr auto hasName = isValid([](auto&& t) -> decltype(t.name(), void()) {});
44} // end namespace Detail
45
47template<class T, std::enable_if_t<std::is_base_of_v<Tag<T>, T>, int> = 0>
48auto operator<<(std::ostream& os, const T& t)
49-> std::enable_if_t<decltype(Detail::hasName(t))::value, std::ostream&>
50{ os << t.name(); return os; }
51
53template<class T, std::enable_if_t<std::is_base_of_v<Tag<T>, T>, int> = 0>
54auto operator<<(std::ostream& os, const T& t)
55-> std::enable_if_t<!decltype(Detail::hasName(t))::value, std::ostream&>
56{
57 const auto fullName = Dune::className<T>();
58
59 // strip all namespace qualifiers
60 const auto pos = fullName.rfind("::");
61 const auto name = pos != std::string::npos ? fullName.substr(pos+2) : fullName;
62
63 os << name;
64 return os;
65}
66
67} // end namespace Dumux::Utility
68
69#endif
constexpr auto isValid(const Expression &t)
A function that creates a test functor to do class member introspection at compile time.
Definition: isvalid.hh:81
A helper function for class member function introspection.
constexpr auto hasName
Definition: tag.hh:43
Definition: tag.hh:21
constexpr bool operator!=(Tag< T1 >, Tag< T2 >)
Definition: tag.hh:38
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:48
constexpr bool operator==(Tag< T1 >, Tag< T2 >)
Tags are equality comparable and return true if the tagged types are equal.
Definition: tag.hh:34
Helper class to create (named and comparable) tagged types Tags any given type. The tagged type is eq...
Definition: tag.hh:30