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#include <tuple>
21#include <string>
22#include <set>
23#include <stdexcept> // runtime_error
24#include <cassert>
25
26#include "conf-object.h"
27#include "detail/attribute-exceptions.h" // InterfaceNotFound
28
29namespace simics {
30
35 public:
36 ConnectBase() : obj_(nullptr) {}
37 virtual ~ConnectBase() = default;
38
39 virtual bool set(const ConfObjectRef &o) = 0;
40 ConfObjectRef get() const { return obj_; }
41 operator conf_object_t*() const { return obj_.object(); }
42
43 protected:
45};
46
55 public:
56 ConnectConfig() = default;
57
58 bool is_optional(const std::string &iface_name) const {
59 return optional_ifaces_.find(iface_name) \
60 != optional_ifaces_.end();
61 }
62
63 template<typename FirstIface, typename... RestIfaces>
65 ConnectConfig config;
66 config.mark_optional<FirstIface, RestIfaces...>();
67 return config;
68 }
69
70 private:
71 template<typename T>
72 void mark_optional() {
73 optional_ifaces_.insert(typename T::Info().name());
74 }
75
76 // The variadic template
77 template<typename FirstIface, typename... RestIfaces>
78 typename std::enable_if<sizeof...(RestIfaces) != 0, void>::type
79 mark_optional() {
80 optional_ifaces_.insert(typename FirstIface::Info().name());
81 mark_optional<RestIfaces...>();
82 }
83
84 std::set<std::string> optional_ifaces_;
85};
86
97template<typename FirstIface, typename... RestIfaces>
98class Connect : public ConnectBase {
99 public:
100 typedef std::tuple<typename FirstIface::ToC,
101 typename RestIfaces::ToC...> ifaces_type;
102 Connect() = default;
103 explicit Connect(const ConnectConfig &config) : config_(config) {}
104
105 explicit Connect(const ConfObjectRef &device) : device_(device) {}
107 : device_(device), config_(config) {}
108
109 // ConnectBase
110 bool set(const ConfObjectRef &o) override {
111 if (obj_ == o) {
112 return true;
113 }
114
115 if (!o) {
116 ifaces_ = ifaces_type();
117 obj_ = o;
118 return true;
119 }
120
121 try {
122 set_ifaces<FirstIface, RestIfaces...>(o);
123 } catch (const detail::SetInterfaceNotFound &e) {
124 if (device_) {
125 SIM_LOG_INFO(1, device_, 0, "%s", e.what());
126 } else {
127 SIM_LOG_INFO(1, SIM_get_object("sim"), 0, "%s", e.what());
128 }
129 ifaces_ = ifaces_type();
130 return false;
131 }
132
133 obj_ = o;
134 return true;
135 }
136
144 template<typename T>
145 typename std::enable_if<sizeof...(RestIfaces) != 0,
146 const typename T::ToC>::type
147 iface() const {
148 return std::get<typename T::ToC>(ifaces_);
149 }
150
151 const typename FirstIface::ToC &iface() const {
152 return std::get<typename FirstIface::ToC>(ifaces_);
153 }
154
155 protected:
158 if (device_ == nullptr) {
159 SIM_LOG_ERROR(SIM_get_object("sim"), 0,
160 "Device is not set, should be set from the CTOR");
161 }
162 return device_;
163 }
164
165 private:
166 template<typename T>
167 const typename T::ctype *interface_(const ConfObjectRef &o) const {
168 std::string iface_name = typename T::Info().name();
169 auto iface = static_cast<const typename T::ctype *>(
170 o.get_interface(iface_name));
171 if (!iface && !config_.is_optional(iface_name)) {
173 "Interface " + iface_name + " not found in " + o.name()
174 };
175 }
176 return iface;
177 }
178
179 template<typename T>
180 void set_ifaces(const ConfObjectRef &o) {
181 std::get<typename T::ToC>(ifaces_) = \
182 typename T::ToC(o.object(), interface_<T>(o));
183 }
184
185 // The variadic template
186 template<typename First, typename... Rest>
187 typename std::enable_if<sizeof...(Rest) != 0, void>::type
188 set_ifaces(const ConfObjectRef &o) {
189 std::get<typename First::ToC>(ifaces_) = \
190 typename First::ToC(o.object(), interface_<First>(o));
191 set_ifaces<Rest...>(o);
192 }
193
194 ifaces_type ifaces_;
195 conf_object_t *device_ {nullptr};
196 ConnectConfig config_;
197};
198
199} // namespace simics
200
201#endif
struct conf_object conf_object_t
Definition: bank-issue-callbacks-interface.h:23
Represents Simics C type conf_object_t.
Definition: conf-object.h:37
conf_object_t * object() const
Get a pointer to the configuration object represented by this ConfObjectRef.
Definition: conf-object.h:57
const interface_t * get_interface(const std::string &name) const
Return an interface implemented by the underlying configuration object.
const std::string & name() const
Get the name of the underlying configuration object.
A virtual base class for Simics C++ interface connect class.
Definition: connect.h:34
ConfObjectRef get() const
Definition: connect.h:40
virtual ~ConnectBase()=default
ConfObjectRef obj_
Definition: connect.h:44
ConnectBase()
Definition: connect.h:36
virtual bool set(const ConfObjectRef &o)=0
By default, all interfaces in the Connect class are required.
Definition: connect.h:54
static ConnectConfig optional()
Definition: connect.h:64
bool is_optional(const std::string &iface_name) const
Definition: connect.h:58
A class for connecting with another Simics object.
Definition: connect.h:98
conf_object_t * device() const
Return the device object which can be used for logging purpose.
Definition: connect.h:157
Connect(const ConnectConfig &config)
Definition: connect.h:103
Connect(const ConfObjectRef &device, const ConnectConfig &config)
Definition: connect.h:106
std::enable_if< sizeof...(RestIfaces)!=0, consttypenameT::ToC >::type iface() const
Return the Simics C++ interface struct implemented on obj_.
Definition: connect.h:147
std::tuple< typename FirstIface::ToC, typename RestIfaces::ToC... > ifaces_type
Definition: connect.h:101
const FirstIface::ToC & iface() const
Definition: connect.h:151
Connect()=default
bool set(const ConfObjectRef &o) override
Definition: connect.h:110
Connect(const ConfObjectRef &device)
Definition: connect.h:105
Definition: attribute-exceptions.h:25
const char * what() const noexcept override
Definition: attribute-exceptions.h:30
Definition: attr-value.h:23