GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/common/tag.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 6 8 75.0%
Functions: 1 6 16.7%
Branches: 5 22 22.7%

Line Branch Exec Source
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 //
7 /*!
8 * \file
9 * \ingroup Core
10 * \brief Helper class to create (named and comparable) tagged types
11 */
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>
19 #include <dumux/common/typetraits/isvalid.hh>
20
21 namespace Dumux::Utility {
22
23 /*!
24 * \ingroup Core
25 * \brief Helper class to create (named and comparable) tagged types
26 * Tags any given type. The tagged type is equality comparable and can be written to streams.
27 * A custom name can be provided by implementing the `name()` member function.
28 */
29 template<class T>
30 struct Tag {};
31
32 //! Tags are equality comparable and return true if the tagged types are equal
33 template<class T1, class T2>
34 inline constexpr bool operator==(Tag<T1>, Tag<T2>)
35 { return std::is_same_v<T1, T2>; }
36
37 template<class T1, class T2>
38 inline constexpr bool operator!=(Tag<T1>, Tag<T2>)
39 { return !std::is_same_v<T1, T2>; }
40
41 namespace Detail {
42 // cppcheck-suppress internalAstError
43 constexpr auto hasName = isValid([](auto&& t) -> decltype(t.name(), void()) {});
44 } // end namespace Detail
45
46 //! Return the class name of the tagged type calling t.name()
47 template<class T, std::enable_if_t<std::is_base_of_v<Tag<T>, T>, int> = 0>
48 auto 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
52 //! Return the class name of the tagged type calling Dune::className if t.name() doesn't exist
53 template<class T, std::enable_if_t<std::is_base_of_v<Tag<T>, T>, int> = 0>
54 1 auto operator<<(std::ostream& os, const T& t)
55 -> std::enable_if_t<!decltype(Detail::hasName(t))::value, std::ostream&>
56 {
57
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
1 const auto fullName = Dune::className<T>();
58
59 // strip all namespace qualifiers
60 1 const auto pos = fullName.rfind("::");
61
3/10
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2 const auto name = pos != std::string::npos ? fullName.substr(pos+2) : fullName;
62
63
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 os << name;
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
2 return os;
65 }
66
67 } // end namespace Dumux::Utility
68
69 #endif
70