-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
system_type_tag.h
37 lines (32 loc) · 1.11 KB
/
system_type_tag.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#pragma once
#include <type_traits>
namespace drake {
namespace systems {
template <typename T> class System;
/// A tag object that denotes a System subclass `S` in function signatures.
///
/// For example, `SystemTypeTag<MySystem>{}` will create a dummy object that
/// can be used to call functions that look like:
///
/// @code
/// template <template <typename> class S>
/// const char* get_foo(SystemTypeTag<S>) { return S<double>::get_foo(); }
///
/// int main() {
/// std::cout << get_foo(SystemTypeTag<MySystem>{});
/// }
/// @endcode
///
/// In this case, we could directly call get_foo<MySystem>() by specifying the
/// template argument, but that is not always possible. In particular, tag
/// objects are acutely useful when calling templated constructors, because
/// there is no other mechanism for the caller to specify the template type.
template <template <typename> class S>
struct SystemTypeTag {
SystemTypeTag() {
static_assert(std::is_base_of_v<System<double>, S<double>>,
"The type argument to SystemTypeTag must be a System");
}
};
} // namespace systems
} // namespace drake