Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
dumux-repositories
dumux
Commits
33fd8647
Commit
33fd8647
authored
Oct 17, 2020
by
Timo Koch
Browse files
[common] Add a helper to create named equality-comparable tags
parent
b79d7cdd
Changes
4
Hide whitespace changes
Inline
Side-by-side
dumux/common/CMakeLists.txt
View file @
33fd8647
...
...
@@ -40,6 +40,7 @@ splinecommon_.hh
staggeredfvproblem.hh
start.hh
tabulated2dfunction.hh
tag.hh
timeloop.hh
timemanager.hh
valgrind.hh
...
...
dumux/common/tag.hh
0 → 100644
View file @
33fd8647
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \ingroup Common
* \brief Helper class to create (named and comparable) tagged types
*/
#ifndef DUMUX_COMMON_TAG_HH
#define DUMUX_COMMON_TAG_HH
#include
<sstream>
#include
<ostream>
#include
<type_traits>
#include
<dune/common/classname.hh>
#include
<dumux/common/typetraits/isvalid.hh>
namespace
Dumux
::
Utility
{
/*!
* \ingroup Common
* \brief Helper class to create (named and comparable) tagged types
* Tags any given type. The tagged type is equality comparable and can be written to streams.
* A custom name can be provided by implementing the `name()` member function.
*/
template
<
class
T
>
struct
Tag
{};
//! Tags are equality comparable and return true if the tagged types are equal
template
<
class
T1
,
class
T2
>
inline
constexpr
bool
operator
==
(
Tag
<
T1
>
,
Tag
<
T2
>
)
{
return
std
::
is_same_v
<
T1
,
T2
>
;
}
template
<
class
T1
,
class
T2
>
inline
constexpr
bool
operator
!=
(
Tag
<
T1
>
,
Tag
<
T2
>
)
{
return
!
std
::
is_same_v
<
T1
,
T2
>
;
}
namespace
Detail
{
constexpr
auto
hasName
=
isValid
([](
auto
&&
t
)
->
decltype
(
t
.
name
(),
void
())
{});
}
// end namespace Detail
//! Return the class name of the tagged type calling t.name()
template
<
class
T
,
std
::
enable_if_t
<
std
::
is_base_of_v
<
Tag
<
T
>,
T
>
,
int
>
=
0
>
auto
operator
<<
(
std
::
ostream
&
os
,
const
T
&
t
)
->
std
::
enable_if_t
<
decltype
(
Detail
::
hasName
(
t
))
::
value
,
std
::
ostream
&>
{
os
<<
t
.
name
();
return
os
;
}
//! Return the class name of the tagged type calling Dune::className if t.name() doesn't exist
template
<
class
T
,
std
::
enable_if_t
<
std
::
is_base_of_v
<
Tag
<
T
>,
T
>
,
int
>
=
0
>
auto
operator
<<
(
std
::
ostream
&
os
,
const
T
&
t
)
->
std
::
enable_if_t
<!
decltype
(
Detail
::
hasName
(
t
))
::
value
,
std
::
ostream
&>
{
const
auto
fullName
=
Dune
::
className
<
T
>
();
// strip all namespace qualifiers
const
auto
pos
=
fullName
.
rfind
(
"::"
);
const
auto
name
=
pos
!=
std
::
string
::
npos
?
fullName
.
substr
(
pos
+
2
)
:
fullName
;
os
<<
name
;
return
os
;
}
}
// end namespace Dumux::Utility
#endif
test/common/CMakeLists.txt
View file @
33fd8647
...
...
@@ -9,3 +9,4 @@ add_subdirectory(typetraits)
dumux_add_test
(
SOURCES test_partial.cc LABELS unit
)
dumux_add_test
(
SOURCES test_enumerate.cc LABELS unit
)
dumux_add_test
(
SOURCES test_tag.cc LABELS unit
)
test/common/test_tag.cc
0 → 100644
View file @
33fd8647
#include
<config.h>
#include
<iostream>
#include
<dune/common/exceptions.hh>
#include
<dumux/common/tag.hh>
namespace
Dumux
{
struct
T1
:
public
Utility
::
Tag
<
T1
>
{};
struct
T2
:
public
Utility
::
Tag
<
T2
>
{
std
::
string
name
()
const
{
return
"customname_t2"
;
}};
}
// end namespace Dumux
int
main
(
int
argc
,
char
*
argv
[])
{
using
namespace
Dumux
;
T1
t11
,
t12
;
T2
t2
;
static_assert
(
t11
==
t12
,
"Same tags not equal!"
);
static_assert
(
t11
!=
t2
,
"Different tags should not be equal!"
);
{
std
::
stringstream
s
;
s
<<
t11
;
if
(
s
.
str
()
!=
"T1"
)
DUNE_THROW
(
Dune
::
Exception
,
"Wrong name: "
<<
s
.
str
()
<<
", expected: T1."
);
}{
std
::
stringstream
s
;
s
<<
t2
;
if
(
s
.
str
()
!=
"customname_t2"
)
DUNE_THROW
(
Dune
::
Exception
,
"Wrong name: "
<<
s
.
str
()
<<
", expected: customname_t2."
);
}
return
0
;
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment