C++ Device API Reference Manual
Reference documentation for the Simics C++ Device API.
 
Loading...
Searching...
No Matches
connect.h
Go to the documentation of this file.
1// -*- mode: C++; c-file-style: "virtutech-c++" -*-
2
3/*
4 © 2021 Intel Corporation
5
6 This software and the related documents are Intel copyrighted materials, and
7 your use of them is governed by the express license under which they were
8 provided to you ("License"). Unless the License provides otherwise, you may
9 not use, modify, copy, publish, distribute, disclose or transmit this software
10 or the related documents without Intel's prior written permission.
11
12 This software and the related documents are provided as is, with no express or
13 implied warranties, other than those that are expressly stated in the License.
14*/
15
16#ifndef SIMICS_CONNECT_H
17#define SIMICS_CONNECT_H
18
19#include <simics/base/log.h> // SIM_LOG_INFO
20
21#include <set>
22#include <string>
23#include <tuple>
24
25#include "simics/conf-object.h"
26#include "simics/detail/attribute-exceptions.h" // InterfaceNotFound
27
28namespace simics {
29
37 public:
38 ConnectBase() : obj_(nullptr) {}
39 virtual ~ConnectBase() = default;
40
47 virtual bool set(const ConfObjectRef &o) = 0;
48
54 ConfObjectRef get() const { return obj_; }
55
61 operator conf_object_t*() const { return obj_.object(); }
62
63 protected:
65};
66
75 public:
76 ConnectConfig() = default;
77
78 bool is_optional(const std::string &iface_name) const {
79 return optional_ifaces_.find(iface_name) \
80 != optional_ifaces_.end();
81 }
82
83 template<typename FirstIface, typename... RestIfaces>
85 ConnectConfig config;
86 config.mark_optional<FirstIface, RestIfaces...>();
87 return config;
88 }
89
90 private:
91 template<typename T>
92 void mark_optional() {
93 optional_ifaces_.insert(typename T::Info().name());
94 }
95
96 // The variadic template
97 template<typename FirstIface, typename... RestIfaces>
98 typename std::enable_if<sizeof...(RestIfaces) != 0, void>::type
99 mark_optional() {
100 optional_ifaces_.insert(typename FirstIface::Info().name());
101 mark_optional<RestIfaces...>();
102 }
103
104 std::set<std::string> optional_ifaces_;
105};
106
117template<typename FirstIface, typename... RestIfaces>
118class Connect : public ConnectBase {
119 public:
120 using ifaces_type = std::tuple<typename FirstIface::ToC,
121 typename RestIfaces::ToC...>;
122 Connect() = default;
123 explicit Connect(const ConnectConfig &config) : config_(config) {}
124
125 explicit Connect(const ConfObjectRef &device) : device_(device) {}
127 : device_(device), config_(config) {}
128
129 // ConnectBase
130 bool set(const ConfObjectRef &o) override {
131 if (obj_ == o) {
132 return true;
133 }
134
135 if (!o) {
136 ifaces_ = ifaces_type();
137 obj_ = o;
138 return true;
139 }
140
141 try {
142 set_ifaces<FirstIface, RestIfaces...>(o);
143 } catch (const detail::SetInterfaceNotFound &e) {
144 if (device_) {
145 SIM_LOG_INFO(1, device_, 0, "%s", e.what());
146 } else {
147 SIM_LOG_INFO(1, SIM_get_object("sim"), 0, "%s", e.what());
148 }
149 ifaces_ = ifaces_type();
150 return false;
151 }
152
153 obj_ = o;
154 return true;
155 }
156
164 template<typename T>
165 typename std::enable_if<sizeof...(RestIfaces) != 0,
166 const typename T::ToC>::type
167 iface() const {
168 return std::get<typename T::ToC>(ifaces_);
169 }
170
171 const typename FirstIface::ToC &iface() const {
172 return std::get<typename FirstIface::ToC>(ifaces_);
173 }
174
175 protected:
177 conf_object_t *device() const {
178 if (device_ == nullptr) {
179 SIM_LOG_ERROR(SIM_get_object("sim"), 0,
180 "Device is not set, should be set from the CTOR");
181 }
182 return device_;
183 }
184
187 conf_object_t *dev() const {
188 return device();
189 }
190
191 private:
192 template<typename T>
193 const typename T::ctype *interface_(const ConfObjectRef &o) const {
194 std::string iface_name = typename T::Info().name();
195 auto iface = static_cast<const typename T::ctype *>(
196 o.get_interface(iface_name));
197 if (!iface && !config_.is_optional(iface_name)) {
199 "Interface " + iface_name + " not found in " + o.name()
200 };
201 }
202 return iface;
203 }
204
205 template<typename T>
206 void set_ifaces(const ConfObjectRef &o) {
207 std::get<typename T::ToC>(ifaces_) = \
208 typename T::ToC(o.object(), interface_<T>(o));
209 }
210
211 // The variadic template
212 template<typename First, typename... Rest>
213 typename std::enable_if<sizeof...(Rest) != 0, void>::type
214 set_ifaces(const ConfObjectRef &o) {
215 std::get<typename First::ToC>(ifaces_) = \
216 typename First::ToC(o.object(), interface_<First>(o));
217 set_ifaces<Rest...>(o);
218 }
219
220 ifaces_type ifaces_;
221 conf_object_t *device_ {nullptr};
222 ConnectConfig config_;
223};
224
225} // namespace simics
226
227#endif
Represents Simics C type conf_object_t.
Definition: conf-object.h:38
conf_object_t * object() const
Get a pointer to the configuration object represented by this ConfObjectRef.
Definition: conf-object.h:54
std::string name() const
Get the name of the underlying configuration object.
const interface_t * get_interface(const std::string &name) const
Return an interface implemented by the underlying configuration object.
A base class for Simics C++ interface connect class.
Definition: connect.h:36
ConfObjectRef get() const
Get the connected configuration object.
Definition: connect.h:54
virtual ~ConnectBase()=default
ConfObjectRef obj_
Definition: connect.h:64
ConnectBase()
Definition: connect.h:38
virtual bool set(const ConfObjectRef &o)=0
Set the connected configuration object.
By default, all interfaces in the Connect class are required.
Definition: connect.h:74
static ConnectConfig optional()
Definition: connect.h:84
bool is_optional(const std::string &iface_name) const
Definition: connect.h:78
A class for connecting with another Simics object.
Definition: connect.h:118
conf_object_t * dev() const
Return the device object which can be used for logging purpose This is an alias for device() and foll...
Definition: connect.h:187
std::tuple< typename FirstIface::ToC, typename RestIfaces::ToC... > ifaces_type
Definition: connect.h:121
conf_object_t * device() const
Return the device object which can be used for logging purpose.
Definition: connect.h:177
Connect(const ConnectConfig &config)
Definition: connect.h:123
Connect(const ConfObjectRef &device, const ConnectConfig &config)
Definition: connect.h:126
std::enable_if< sizeof...(RestIfaces)!=0, consttypenameT::ToC >::type iface() const
Return the Simics C++ interface struct implemented on obj_.
Definition: connect.h:167
const FirstIface::ToC & iface() const
Definition: connect.h:171
Connect()=default
bool set(const ConfObjectRef &o) override
Set the connected configuration object.
Definition: connect.h:130
Connect(const ConfObjectRef &device)
Definition: connect.h:125
Definition: attribute-exceptions.h:25
const char * what() const noexcept override
Definition: attribute-exceptions.h:30
Definition: after-bank.h:33