dart
EmbeddedAspect.hpp
1 /*
2  * Copyright (c) 2011-2021, The DART development contributors
3  * All rights reserved.
4  *
5  * The list of contributors can be found at:
6  * https://github.com/dartsim/dart/blob/master/LICENSE
7  *
8  * This file is provided under the following "BSD-style" License:
9  * Redistribution and use in source and binary forms, with or
10  * without modification, are permitted provided that the following
11  * conditions are met:
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef DART_COMMON_EMBEDDEDASPECT_HPP_
34 #define DART_COMMON_EMBEDDEDASPECT_HPP_
35 
36 #include "dart/common/CompositeJoiner.hpp"
37 #include "dart/common/RequiresAspect.hpp"
38 #include "dart/common/detail/EmbeddedAspect.hpp"
39 
40 namespace dart {
41 namespace common {
42 
43 //==============================================================================
50 template <class CompositeT, typename StateDataT>
52  CompositeTrackingAspect<CompositeT>,
53  EmbeddedStateAspect<CompositeT, StateDataT>,
54  StateDataT>
55 {
56 public:
60  using State = typename Impl::State;
61  using StateData = typename Impl::StateData;
62 
63  template <typename... Args>
64  EmbeddedStateAspect(Args&&... args) : Impl(std::forward<Args>(args)...)
65  {
66  // Do nothing
67  }
68 
69  virtual ~EmbeddedStateAspect() = default;
70 };
71 
72 //==============================================================================
88 DART_DECLARE_CLASS_WITH_VIRTUAL_BASE_BEGIN
89 
90 template <class DerivedT, typename StateDataT>
91 class EmbedState : public virtual common::RequiresAspect<
92  common::EmbeddedStateAspect<DerivedT, StateDataT> >
93 {
94 public:
95  using Derived = DerivedT;
97  using AspectState = typename Aspect::State;
98  using AspectStateData = typename Aspect::StateData;
100 
101  // Forwarding constructor
102  template <typename... Args>
103  EmbedState(Args&&... args) : Base(std::forward<Args>(args)...)
104  {
105  // Do nothing
106  }
107 
108  virtual ~EmbedState() = default;
109 
110  const AspectState& getAspectState() const
111  {
112  return mAspectState;
113  }
114 
115 protected:
117  AspectState mAspectState;
118 };
119 DART_DECLARE_CLASS_WITH_VIRTUAL_BASE_END
120 
121 //==============================================================================
125 template <class DerivedT, typename StateDataT, typename... BaseComposites>
127  : public CompositeJoiner<EmbedState<DerivedT, StateDataT>, BaseComposites...>
128 {
129 public:
131  using Derived = typename Impl::Derived;
132  using AspectStateData = typename Impl::AspectStateData;
133  using AspectState = typename Impl::AspectState;
134  using Aspect = typename Impl::Aspect;
135  using Base = CompositeJoiner<Impl, BaseComposites...>;
136  using Impl::getAspectState;
137 
138  // Forwarding constructor
139  template <typename... Args>
140  EmbedStateOnTopOf(Args&&... args) : Base(NoArg, std::forward<Args>(args)...)
141  {
142  // Do nothing
143  }
144 
145  virtual ~EmbedStateOnTopOf() = default;
146 
147 protected:
148  using Impl::mAspectState;
149 };
150 
151 //==============================================================================
158 template <class CompositeT, typename PropertiesDataT>
161  CompositeTrackingAspect<CompositeT>,
162  EmbeddedPropertiesAspect<CompositeT, PropertiesDataT>,
163  PropertiesDataT>
164 {
165 public:
169  using Properties = typename Impl::Properties;
170  using PropertiesData = typename Impl::PropertiesData;
171 
172  // Forwarding constructor
173  template <typename... Args>
174  EmbeddedPropertiesAspect(Args&&... args) : Impl(std::forward<Args>(args)...)
175  {
176  // Do nothing
177  }
178 
179  virtual ~EmbeddedPropertiesAspect() = default;
180 };
181 
182 //==============================================================================
199 DART_DECLARE_CLASS_WITH_VIRTUAL_BASE_BEGIN
200 template <class DerivedT, typename PropertiesDataT>
202  : public virtual common::RequiresAspect<
203  common::EmbeddedPropertiesAspect<DerivedT, PropertiesDataT> >
204 {
205 public:
206  using Derived = DerivedT;
208  using AspectProperties = typename Aspect::Properties;
209  using AspectPropertiesData = typename Aspect::PropertiesData;
211 
212  // Forwarding constructor
213  template <typename... Args>
214  EmbedProperties(Args&&... args) : Base(std::forward<Args>(args)...)
215  {
216  // Do nothing
217  }
218 
219  virtual ~EmbedProperties() = default;
220 
221  const AspectProperties& getAspectProperties() const
222  {
223  return mAspectProperties;
224  }
225 
226 protected:
228  AspectProperties mAspectProperties;
229 };
230 DART_DECLARE_CLASS_WITH_VIRTUAL_BASE_END
231 
232 //==============================================================================
236 template <class DerivedT, typename PropertiesDataT, typename... CompositeBases>
238  EmbedProperties<DerivedT, PropertiesDataT>,
239  CompositeBases...>
240 {
241 public:
243  using Derived = typename Impl::Derived;
244  using AspectPropertiesData = typename Impl::AspectPropertiesData;
245  using AspectProperties = typename Impl::AspectProperties;
246  using Aspect = typename Impl::Aspect;
247  using Base = CompositeJoiner<Impl, CompositeBases...>;
248  using Impl::getAspectProperties;
249 
250  // Forwarding constructor
251  template <typename... Args>
252  EmbedPropertiesOnTopOf(Args&&... args)
253  : Base(NoArg, std::forward<Args>(args)...)
254  {
255  // Do nothing
256  }
257 
258  virtual ~EmbedPropertiesOnTopOf() = default;
259 
260 protected:
261  using Impl::mAspectProperties;
262 };
263 
264 //==============================================================================
268 //
269 // Dev Note: We achieve "multiple inheritance" without the diamond of death
270 // issue by specifying detail::EmbeddedStateAspect as the base class of
271 // detail::EmbeddedPropertiesAspect. This allows their implementations to stack
272 // on top of each other without the conflict that would arise from both of them
273 // inheriting from common::Aspect.
274 template <class CompositeT, typename StateDataT, typename PropertiesDataT>
277  detail::EmbeddedStateAspect<
278  CompositeTrackingAspect<CompositeT>,
279  EmbeddedStateAndPropertiesAspect<
280  CompositeT,
281  StateDataT,
282  PropertiesDataT>,
283  StateDataT>,
284  EmbeddedStateAndPropertiesAspect<
285  CompositeT,
286  StateDataT,
287  PropertiesDataT>,
288  PropertiesDataT>
289 {
290 public:
292  CompositeT,
293  StateDataT,
294  PropertiesDataT>;
295 
298  Derived,
299  StateDataT>;
300 
301  using AspectPropertiesImpl = detail::
302  EmbeddedPropertiesAspect<AspectStateImpl, Derived, PropertiesDataT>;
303 
304  using AspectImpl = Derived;
305 
306  using State = typename AspectStateImpl::State;
307  using StateData = typename AspectStateImpl::StateData;
308 
309  using Properties = typename AspectPropertiesImpl::Properties;
310  using PropertiesData = typename AspectPropertiesImpl::PropertiesData;
311 
312  using CompositeType = CompositeT;
313 
315  = delete;
316 
317  virtual ~EmbeddedStateAndPropertiesAspect() = default;
318 
321  {
322  // Do nothing
323  }
324 
326  EmbeddedStateAndPropertiesAspect(const StateData& state)
327  : AspectPropertiesImpl(state)
328  {
329  // Do nothing
330  }
331 
333  EmbeddedStateAndPropertiesAspect(const PropertiesData& properties)
334  : AspectPropertiesImpl(properties)
335  {
336  // Do nothing
337  }
338 
341  const StateData& state, const PropertiesData& properties)
342  : AspectPropertiesImpl(properties, state)
343  {
344  // Do nothing
345  }
346 
349  const PropertiesData& properties, const StateData& state)
350  : AspectPropertiesImpl(properties, state)
351  {
352  // Do nothing
353  }
354 
355  // Documentation inherited
356  std::unique_ptr<Aspect> cloneAspect() const override
357  {
358  return std::make_unique<Derived>(this->getState(), this->getProperties());
359  }
360 };
361 
362 //==============================================================================
374 DART_DECLARE_CLASS_WITH_VIRTUAL_BASE_BEGIN
375 template <class DerivedT, typename StateDataT, typename PropertiesDataT>
377  common::EmbeddedStateAndPropertiesAspect<
378  DerivedT,
379  StateDataT,
380  PropertiesDataT> >
381 {
382 public:
383  using Derived = DerivedT;
384  using Aspect = common::
385  EmbeddedStateAndPropertiesAspect<DerivedT, StateDataT, PropertiesDataT>;
386 
387  using AspectState = typename Aspect::State;
388  using AspectStateData = typename Aspect::StateData;
389 
390  using AspectProperties = typename Aspect::Properties;
391  using AspectPropertiesData = typename Aspect::PropertiesData;
393 
394  // Forwarding constructor
395  template <typename... Args>
396  EmbedStateAndProperties(Args&&... args) : Base(std::forward<Args>(args)...)
397  {
398  // Do nothing
399  }
400 
401  virtual ~EmbedStateAndProperties() = default;
402 
403  const AspectState& getAspectState() const
404  {
405  return mAspectState;
406  }
407 
408  const AspectProperties& getAspectProperties() const
409  {
410  return mAspectProperties;
411  }
412 
413 protected:
415  AspectState mAspectState;
416 
418  AspectProperties mAspectProperties;
419 };
420 DART_DECLARE_CLASS_WITH_VIRTUAL_BASE_END
421 
422 //==============================================================================
426 template <
427  class DerivedT,
428  typename StateDataT,
429  typename PropertiesDataT,
430  typename... CompositeBases>
432  : public CompositeJoiner<
433  EmbedStateAndProperties<DerivedT, StateDataT, PropertiesDataT>,
434  CompositeBases...>
435 {
436 public:
438  using Derived = typename Impl::Derived;
439  using AspectStateData = typename Impl::AspectStateData;
440  using AspectState = typename Impl::AspectState;
441  using AspectPropertiesData = typename Impl::AspectPropertiesData;
442  using AspectProperties = typename Impl::AspectProperties;
443  using Aspect = typename Impl::Aspect;
444  using Impl::getAspectProperties;
445  using Impl::getAspectState;
446  using Base = CompositeJoiner<Impl, CompositeBases...>;
447 
448  // Forwarding constructor
449  template <typename... Args>
450  EmbedStateAndPropertiesOnTopOf(Args&&... args)
451  : Base(NoArg, std::forward<Args>(args)...)
452  {
453  // Do nothing
454  }
455 
456  virtual ~EmbedStateAndPropertiesOnTopOf() = default;
457 
458 protected:
459  using Impl::mAspectProperties;
460  using Impl::mAspectState;
461 };
462 
463 } // namespace common
464 } // namespace dart
465 
466 #endif // DART_COMMON_EMBEDDEDASPECT_HPP_
Inherit this class to embed a State into your Composite object.
Definition: EmbeddedAspect.hpp:91
RequiresAspect allows classes that inherit Composite to know which Aspects are required for their ope...
Definition: RequiresAspect.hpp:49
Inherit this class to embed both State and Properties into your Composite object. ...
Definition: EmbeddedAspect.hpp:376
This is an alternative to EmbedStateAndProperties which allows your class to also inherit other Compo...
Definition: EmbeddedAspect.hpp:431
EmbeddedStateAndPropertiesAspect(const StateData &state)
Construct using a State. The object&#39;s Properties will remain unaffected.
Definition: EmbeddedAspect.hpp:326
Definition: Aspect.cpp:40
Definition: EmbeddedAspect.hpp:252
Terminator for the variadic template.
Definition: CompositeJoiner.hpp:44
AspectState mAspectState
Aspect::State data, directly accessible to your derived class.
Definition: EmbeddedAspect.hpp:117
virtual const Properties * getAspectProperties() const
Get the Properties of this Aspect.
Definition: Aspect.cpp:62
This is the implementation of a standard embedded-properties Aspect.
Definition: EmbeddedAspect.hpp:159
class State
Definition: State.hpp:65
std::unique_ptr< Aspect > cloneAspect() const override
Clone this Aspect into a new composite.
Definition: EmbeddedAspect.hpp:356
This is an alternative to EmbedState which allows your class to also inherit other Composite objects ...
Definition: EmbeddedAspect.hpp:126
This is the implementation of a standard embedded-state Aspect.
Definition: EmbeddedAspect.hpp:51
This is the implementation of a standard combination of embedded-state and embedded-properties Aspect...
Definition: EmbeddedAspect.hpp:275
AspectProperties mAspectProperties
Aspect::Properties data, directly accessible to your derived class.
Definition: EmbeddedAspect.hpp:418
Inherit this class to embed Properties into your Composite object.
Definition: EmbeddedAspect.hpp:201
AspectState mAspectState
Aspect::State data, directly accessible to your derived class.
Definition: EmbeddedAspect.hpp:415
EmbeddedStateAndPropertiesAspect(const StateData &state, const PropertiesData &properties)
Construct using a State and Properties instance.
Definition: EmbeddedAspect.hpp:340
AspectProperties mAspectProperties
Aspect::Properties data, directly accessible to your derived class.
Definition: EmbeddedAspect.hpp:228
Definition: EmbeddedAspect.hpp:82
EmbeddedStateAndPropertiesAspect(const PropertiesData &properties, const StateData &state)
Construct using a Properties and State instance.
Definition: EmbeddedAspect.hpp:348
This is an alternative to EmbedProperties which allows your class to also inherit other Composite obj...
Definition: EmbeddedAspect.hpp:237
EmbeddedStateAndPropertiesAspect(const PropertiesData &properties)
Construct using Properties. The object&#39;s State will remain unaffected.
Definition: EmbeddedAspect.hpp:333
EmbeddedStateAndPropertiesAspect()
Construct using nothing. The object will remain unaffected.
Definition: EmbeddedAspect.hpp:320