Drake
is_cloneable.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <memory>
4 #include <type_traits>
5 
6 namespace drake {
7 
8 /** @cond */
9 
10 namespace is_cloneable_detail {
11 
12 // Default case; assumes that a class is *not* cloneable.
13 template <typename T, class>
14 struct is_cloneable_helper : std::false_type {};
15 
16 // Special sauce for SFINAE. Only compiles if it can finds the method
17 // `unique_ptr<T> T::Clone() const`. If this exists, the is_cloneable implicitly
18 // prefers this overload over the default overload.
19 template <typename T>
20 struct is_cloneable_helper<
21  T,
22  typename std::enable_if<std::is_same<
23  decltype(std::declval<const T>().Clone().release()),
24  typename std::remove_const<T>::type*>::value>::type>
25  : std::true_type {};
26 
27 } // namespace is_cloneable_detail
28 
29 /** @endcond */
30 
31 /**
32  @anchor is_cloneable_doc
33  Provides method for determining at run time if a class is "cloneable".
34 
35  __Usage__
36 
37  This gets used like `type_traits` functions (e.g., `is_copy_constructible`,
38  `is_same`, etc.) To determine if a class is cloneable simply invoke:
39 
40  @code
41  bool value = drake::is_cloneable<Foo>::value;
42  @endcode
43 
44  If `Foo` is cloneable, it will evaluate to true. It can also be used in
45  compile-time tests (e.g., SFINAE and `static_assert`s):
46 
47  @code
48  static_assert(is_cloneable<Foo>::value, "This method requires its classes to "
49  "be cloneable.");
50  @endcode
51 
52  __Definition of "cloneability"__
53 
54  To be cloneable, the class `Foo` must have a _public_ method of the form:
55  @code
56  unique_ptr<Foo> Foo::Clone() const;
57  @endcode
58  Note that "friend" access for the %is_cloneable-using class is not sufficient.
59  The `Foo::Clone()` method must actually be public.
60 
61  <!-- Developer note: if you change or extend the definition of an acceptable
62  clone method here, be sure to consider whether
63  copyable_unique_ptr::can_clone() should be changed as well. -->
64 
65  The pointer contained in the returned `unique_ptr` must point to a
66  heap-allocated deep copy of the _concrete_ object. This test can confirm the
67  proper signature, but cannot confirm the heap-allocated deep copy. A Clone()
68  method that doesn't return such a copy of the _concrete_ object should be
69  considered a malformed function.
70 
71  @warning It is important to note, that a `Clone()` method that returns a
72  `unique_ptr` to a _super_ class is _not_ sufficient to be cloneable. In other
73  words the presence of:
74  @code
75  unique_ptr<Base> Derived::Clone() const;
76  @endcode
77  will not make the `Derived` class cloneable.
78 
79  @tparam T The class to test for cloneability.
80  */
81 template <typename T>
82 using is_cloneable =
83  is_cloneable_detail::is_cloneable_helper<T, void>;
84 
85 } // namespace drake
is_cloneable_detail::is_cloneable_helper< T, void > is_cloneable
Definition: is_cloneable.h:83
Definition: automotive_demo.cc:105
STL namespace.
ReferenceType type
Definition: loader.cc:34