-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
model_values.h
98 lines (84 loc) · 3.17 KB
/
model_values.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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#pragma once
#include <memory>
#include <utility>
#include <vector>
#include "drake/common/drake_assert.h"
#include "drake/common/drake_copyable.h"
#include "drake/systems/framework/basic_vector.h"
#include "drake/systems/framework/value.h"
namespace drake {
namespace systems {
namespace detail {
/// Represents models for a sequence of AbstractValues (usually a sequence of
/// either input or output ports). The models are the "prototype" design
/// pattern (https://en.wikipedia.org/wiki/Prototype_pattern). When creating
/// elements in new Context, these models' values are cloned to establish the
/// subtype and default values of the, e.g. input port.
///
/// Conceptually, the %ModelValues form an infinite sequence. The value at a
/// given index is allowed to be absent, in which case the CloneModel method
/// will return nullptr. Adding new values must be monotonic; new values must
/// use strictly larger indices; the model value for a given index cannot be
/// reset.
class ModelValues {
public:
DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(ModelValues);
ModelValues() = default;
/// Returns one greater than the largest index passed to AddModel or
/// AddVectorModel.
int size() const;
/// Sets @p model_value to be the model value for @p index.
///
/// @pre index >= size()
void AddModel(int index, std::unique_ptr<AbstractValue> model_value);
/// Wraps @p model_vector in a Value and sets that to be the model value for
/// @p index.
///
/// @pre index >= size()
template <typename T>
void AddVectorModel(int index, std::unique_ptr<BasicVector<T>> model_vector);
/// Returns a clone of the model value at @p index, which may be nullptr.
std::unique_ptr<AbstractValue> CloneModel(int index) const;
/// Returns a vector of all the cloned model values. Some may be nullptr.
std::vector<std::unique_ptr<AbstractValue>> CloneAllModels() const {
std::vector<std::unique_ptr<AbstractValue>> ret(size());
for (int i = 0; i < size(); ++i) {
ret[i] = CloneModel(i);
}
return ret;
}
/// Returns a clone of the vector within the model value at @p index, which
/// may be nullptr.
///
/// @throw exception if the index has a model but the model's type does not
/// match the given @p T
template <typename T>
std::unique_ptr<BasicVector<T>> CloneVectorModel(int index) const;
private:
// Elements here are allowed to be nullptr.
std::vector<std::unique_ptr<const AbstractValue>> values_;
};
template <typename T>
void ModelValues::AddVectorModel(
int index, std::unique_ptr<BasicVector<T>> model_vector) {
if (model_vector.get() != nullptr) {
AddModel(index, std::make_unique<Value<BasicVector<T>>>(
std::move(model_vector)));
} else {
AddModel(index, std::unique_ptr<AbstractValue>{});
}
}
template <typename T>
std::unique_ptr<BasicVector<T>>
ModelValues::CloneVectorModel(int index) const {
std::unique_ptr<AbstractValue> abstract_result = CloneModel(index);
if (abstract_result.get() == nullptr) {
return nullptr;
}
const BasicVector<T>& basic_vector =
abstract_result->GetValueOrThrow<BasicVector<T>>();
return basic_vector.Clone();
}
} // namespace detail
} // namespace systems
} // namespace drake