C++ Device API Reference Manual
Reference documentation for the Simics C++ Device API.
 
Loading...
Searching...
No Matches
attribute-traits.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_ATTRIBUTE_TRAITS_H
17#define SIMICS_ATTRIBUTE_TRAITS_H
18
19#include <simics/base/attr-value.h> // SIM_attr_list_item
20
21#include <array>
22#include <deque>
23#include <limits> // numeric_limits
24#include <list>
25#include <map>
26#include <set>
27#include <string>
28#include <type_traits> // is_enum, underlying_type_t, remove_cv_t
29#include <tuple>
30#include <utility> // pair, index_sequence
31#include <vector>
32
33#include "simics/conf-object.h"
34#include "simics/connect.h" // ConnectBase
35
36namespace simics {
37
40inline void checkSizeOverflowSimicsAttribute(size_t size) {
41 if (size > (std::numeric_limits<unsigned>::max)()) {
43 "Size exceeds maximum supported size for a Simics attribute"
44 };
45 }
46}
47
48namespace detail {
49
50template <typename T>
52 static_assert(!std::is_same<T, T>::value,
53 "Specialization of attr_to_std<T> & std_to_attr<T> for "
54 "type T is required.");
55 static attr_value_t f(const T &src);
56};
57
58template <typename T>
60 static_assert(!std::is_same<T, T>::value,
61 "Specialization of attr_to_std<T> & std_to_attr<T> for "
62 "type T is required.");
63 static T f(const attr_value_t &src);
64};
65
66// ConfObjectRef, needed by std_to_attr<T> when T is derived from ConnectBase
67template <>
69 static attr_value_t f(const ConfObjectRef &src) {
70 if (src) {
71 if (src.port_name().empty()) {
72 return SIM_make_attr_object(src);
73 } else {
74 attr_value_t ret = SIM_alloc_attr_list(2);
75 SIM_attr_list_set_item(&ret, 0, SIM_make_attr_object(src));
76 attr_value_t string = SIM_make_attr_string(
77 src.port_name().c_str());
78 SIM_attr_list_set_item(&ret, 1, string);
79 return ret;
80 }
81 } else {
82 return SIM_make_attr_nil();
83 }
84 }
85};
86
87template <>
89 static ConfObjectRef f(const attr_value_t &src) {
90 if (SIM_attr_is_list(src)) {
91 if (SIM_attr_list_size(src) != 2) {
92 throw SetIllegalType {
93 "Expected Simics list type with exactly 2 members"
94 };
95 }
96
97 auto item = SIM_attr_list_item(src, 0);
98 if (!SIM_attr_is_object(item)) {
99 throw SetIllegalType {
100 "The first item should be Simics object type"
101 };
102 }
103 ConfObjectRef r = SIM_attr_object(item);
104
105 item = SIM_attr_list_item(src, 1);
106 if (!SIM_attr_is_string(item)) {
107 throw SetIllegalType {
108 "The second item should be Simics string type"
109 };
110 }
111 r.set_port_name(SIM_attr_string(item));
112 return r;
113 } else {
114 if (!SIM_attr_is_object(src) && !SIM_attr_is_nil(src)) {
115 throw SetIllegalType {
116 "Expected Simics object or NIL type"
117 };
118 }
119 return SIM_attr_object_or_nil(src);
120 }
121 }
122};
123
124template <typename T>
126 public:
127 static constexpr bool value = std::is_base_of<ConnectBase, T>::value
128 && std::is_constructible<T, const ConfObjectRef &>::value;
129};
130
131// Check if T is a variable length container type, and the value_type
132// is derived from ConnectBase
133template <typename T>
134struct is_container_of_connectbase : std::false_type {};
135
136template <typename T, typename Alloc>
137struct is_container_of_connectbase<std::vector<T, Alloc>>
139
140template <typename T, typename Alloc>
141struct is_container_of_connectbase<std::list<T, Alloc>>
143
144template <typename T, typename Alloc>
145struct is_container_of_connectbase<std::deque<T, Alloc>>
147
148// Check if T is a std::array of fixed length, and the value_type
149// is derived from ConnectBase
150template <typename T>
151struct is_array_of_connectbase : std::false_type {};
152
153template <typename T, std::size_t N>
154struct is_array_of_connectbase<std::array<T, N>>
155 : std::is_base_of<ConnectBase, T> {};
156} // namespace detail
157
161template <typename T> inline
162typename std::enable_if<std::is_enum<T>::value, attr_value_t>::type
163std_to_attr(const T &src) {
165 static_cast<std::underlying_type_t<T>>(src));
166}
167
171template <typename T> inline
172typename std::enable_if<std::is_base_of<ConnectBase, T>::value,
173 attr_value_t>::type
174std_to_attr(const T &src) {
176}
177
181template <typename T> inline
182typename std::enable_if<std::is_pointer<T>::value, attr_value_t>::type
183std_to_attr(const T &src) {
184 // const char * is copied to a string attribute
185 static_assert(std::is_same<T, const char *>::value,
186 "Pointer type is not allowed due to not checkpointable");
188}
189
193template <typename T> inline
194typename std::enable_if<!std::is_enum<T>::value
195 && !std::is_base_of<ConnectBase, T>::value
196 && !std::is_pointer<T>::value,
197 attr_value_t>::type
198std_to_attr(const T &src) {
200}
201
205template <typename T> inline
206typename std::enable_if<std::is_enum<T>::value, T>::type
207attr_to_std(attr_value_t src) {
208 return static_cast<T>(
210}
211
215template <typename T> inline
216typename std::enable_if<std::is_base_of<ConnectBase, T>::value, T>::type
217attr_to_std(attr_value_t src) {
218 T c;
220 throw std::runtime_error {
221 "Unable to set to an illegal object"
222 };
223 }
224 return c;
225}
226
230template <typename T> inline
231typename std::enable_if<std::is_pointer<T>::value, T>::type
232attr_to_std(attr_value_t src) {
233 // const char * is copied from a string attribute
234 static_assert(std::is_same<T, const char *>::value,
235 "Pointer type is not allowed due to not checkpointable");
237}
238
242template <typename T> inline
243typename std::enable_if<!std::is_enum<T>::value
244 && !std::is_base_of<ConnectBase, T>::value
245 && !std::is_pointer<T>::value, T>::type
246attr_to_std(attr_value_t src) {
248}
249
250namespace detail {
251
252// Integral
253#define _STD2ATTR_INT_HELPER(type) \
254 template <> \
255 struct attr_from_std_helper<type> { \
256 static attr_value_t f(const type &src) { \
257 return SIM_make_attr_int64(src); \
258 } \
259 };
260#define _STD2ATTR_UINT_HELPER(type) \
261 template <> \
262 struct attr_from_std_helper<type> { \
263 static attr_value_t f(const type &src) { \
264 return SIM_make_attr_uint64(src); \
265 } \
266 };
268_STD2ATTR_INT_HELPER(signed char)
269_STD2ATTR_UINT_HELPER(unsigned char)
270_STD2ATTR_INT_HELPER(short) // NOLINT(runtime/int)
271_STD2ATTR_UINT_HELPER(unsigned short) // NOLINT(runtime/int)
273_STD2ATTR_UINT_HELPER(unsigned int)
274_STD2ATTR_INT_HELPER(long int) // NOLINT(runtime/int)
275_STD2ATTR_UINT_HELPER(unsigned long int) // NOLINT(runtime/int)
276_STD2ATTR_INT_HELPER(long long int) // NOLINT(runtime/int)
277_STD2ATTR_UINT_HELPER(unsigned long long int) // NOLINT(runtime/int)
278#undef _STD2ATTR_INT_HELPER
279#undef _STD2ATTR_UINT_HELPER
280
281#define _ATTR2STD_INT_HELPER(type) \
282 template <> \
283 struct attr_to_std_helper<type> { \
284 static type f(const attr_value_t &src) { \
285 if (!SIM_attr_is_integer(src)) { \
286 throw SetIllegalType { \
287 "Expected Simics integer type" \
288 }; \
289 } \
290 intmax_t i = SIM_attr_integer(src); \
291 if (sizeof(type) != 8 \
292 && (i > (std::numeric_limits<type>::max)() \
293 || i < (std::numeric_limits<type>::min)())) { \
294 throw SetIllegalValue { \
295 "Value does not fit in type" \
296 }; \
297 } \
298 return (type) i; \
299 } \
300 };
301
302#define _ATTR2STD_UINT_HELPER(type) \
303 template <> \
304 struct attr_to_std_helper<type> { \
305 static type f(const attr_value_t &src) { \
306 if (!SIM_attr_is_integer(src)) { \
307 throw SetIllegalType { \
308 "Expected Simics integer type" \
309 }; \
310 } \
311 uintmax_t i = static_cast<uintmax_t>( \
312 SIM_attr_integer(src)); \
313 if (sizeof(type) != 8 \
314 && i > (std::numeric_limits<type>::max)()) { \
315 throw SetIllegalValue { \
316 "Value does not fit in type" \
317 }; \
318 } \
319 return (type) i; \
320 } \
321 };
323_ATTR2STD_INT_HELPER(signed char)
324_ATTR2STD_UINT_HELPER(unsigned char)
325_ATTR2STD_INT_HELPER(short) // NOLINT(runtime/int)
326_ATTR2STD_UINT_HELPER(unsigned short) // NOLINT(runtime/int)
328_ATTR2STD_UINT_HELPER(unsigned int)
329_ATTR2STD_INT_HELPER(long int) // NOLINT(runtime/int)
330_ATTR2STD_UINT_HELPER(unsigned long int) // NOLINT(runtime/int)
331_ATTR2STD_INT_HELPER(long long int) // NOLINT(runtime/int)
332_ATTR2STD_UINT_HELPER(unsigned long long int) // NOLINT(runtime/int)
333#undef _ATTR2STD_INT_HELPER
334#undef _ATTR2STD_UINT_HELPER
335
336
337// Float
338#define _STD2ATTR_FLOAT_HELPER(type) \
339 template <> \
340 struct attr_from_std_helper<type> { \
341 static attr_value_t f(const type &src) { \
342 return SIM_make_attr_floating(src); \
343 } \
344 };
347#undef _STD2ATTR_FLOAT_HELPER
348
349#define _ATTR2STD_FLOAT_HELPER(type) \
350 template <> \
351 struct attr_to_std_helper<type> { \
352 static type f(const attr_value_t &src) { \
353 if (!SIM_attr_is_floating(src)) { \
354 throw SetIllegalType { \
355 "Expected Simics floating type" \
356 }; \
357 } \
358 return (type) SIM_attr_floating(src); \
359 } \
360 };
363#undef _ATTR2STD_FLOAT_HELPER
364
365
366// std::string
367template <>
368struct attr_from_std_helper<std::string> {
369 static attr_value_t f(const std::string &src) {
370 return SIM_make_attr_string(src.c_str());
371 }
372};
373
374template <>
375struct attr_to_std_helper<std::string> {
376 static std::string f(const attr_value_t &src) {
377 if (!SIM_attr_is_string(src)) {
378 throw SetIllegalType {
379 "Expected Simics string type"
380 };
381 }
382 return SIM_attr_string(src);
383 }
384};
385
386template <>
387struct attr_from_std_helper<const char*> {
388 static attr_value_t f(const char *src) {
389 return SIM_make_attr_string(src);
390 }
391};
392
393template <>
394struct attr_to_std_helper<const char*> {
395 static const char *f(const attr_value_t &src) {
396 if (SIM_attr_is_nil(src)) {
397 return nullptr;
398 } else {
399 if (!SIM_attr_is_string(src)) {
400 throw SetIllegalType {
401 "Expected Simics string type"
402 };
403 }
404 return SIM_attr_string(src);
405 }
406 }
407};
408
409
410// bool
411template <>
413 static attr_value_t f(const bool &src) {
414 return SIM_make_attr_boolean(src);
415 }
416};
417
418template <>
419struct attr_to_std_helper<bool> {
420 static bool f(const attr_value_t &src) {
421 if (!SIM_attr_is_boolean(src)) {
422 throw SetIllegalType {
423 "Expected Simics boolean type"
424 };
425 }
426 return SIM_attr_boolean(src);
427 }
428};
429
430
431// attr_value_t
432template <>
433struct attr_from_std_helper<attr_value_t> {
434 static attr_value_t f(const attr_value_t &src) {
435 return src;
436 }
437};
438
439template <>
440struct attr_to_std_helper<attr_value_t> {
441 static attr_value_t f(const attr_value_t &src) {
442 return src;
443 }
444};
445
446
447// Container
448template <typename C, typename T = typename C::value_type>
449attr_value_t from_container(const C &src) {
450 const auto size = src.size();
452 const unsigned size_uint = static_cast<unsigned>(size);
453 attr_value_t dst = SIM_alloc_attr_list(size_uint);
454 auto it = src.cbegin();
455 for (unsigned i = 0; i < size_uint; ++i, ++it) {
456 SIM_attr_list_set_item(&dst, i, std_to_attr(*it));
457 }
458 return dst;
459}
460
461template <typename V, std::size_t N>
462struct attr_from_std_helper<std::array<V, N>> {
463 static attr_value_t f(const std::array<V, N> &src) {
464 return from_container<std::array<V, N>>(src);
465 }
466};
467
468template <typename V, std::size_t N>
470 static attr_value_t f(const V (&src)[N]) {
471 std::array<V, N> std_arr;
472 for (std::size_t i = 0; i < N; ++i) {
473 std_arr[i] = src[i];
474 }
475 return from_container<std::array<V, N>>(std_arr);
476 }
477};
478
479template <std::size_t N>
480struct attr_from_std_helper<char[N]> {
481 static attr_value_t f(const char (&src)[N]) {
482 return SIM_make_attr_string(src);
483 }
484};
485
486template <typename V>
487struct attr_from_std_helper<std::vector<V>> {
488 static attr_value_t f(const std::vector<V> &src) {
489 return from_container<std::vector<V>>(src);
490 }
491};
492
493template <typename V>
494struct attr_from_std_helper<std::list<V>> {
495 static attr_value_t f(const std::list<V> &src) {
496 return from_container<std::list<V>>(src);
497 }
498};
499
500template <typename V>
501struct attr_from_std_helper<std::deque<V>> {
502 static attr_value_t f(const std::deque<V> &src) {
503 return from_container<std::deque<V>>(src);
504 }
505};
506
507template <typename V>
508struct attr_from_std_helper<std::set<V>> {
509 static attr_value_t f(const std::set<V> &src) {
510 return from_container<std::set<V>>(src);
511 }
512};
513
514template <typename X, typename Y>
515struct attr_from_std_helper<std::pair<X, Y>> {
516 static attr_value_t f(const std::pair<X, Y>& src) {
517 attr_value_t dst = SIM_alloc_attr_list(2);
518 SIM_attr_list_set_item(&dst, 0, std_to_attr(src.first));
519 SIM_attr_list_set_item(&dst, 1, std_to_attr(src.second));
520 return dst;
521 }
522};
523
524template <typename X, typename Y>
525struct attr_from_std_helper<std::map<X, Y>> {
526 static attr_value_t f(const std::map<X, Y>& src) {
527 const auto size = src.size();
529 attr_value_t dst = SIM_alloc_attr_list(static_cast<unsigned>(size));
530 unsigned index = 0;
531 for (const auto &p : src) {
532 SIM_attr_list_set_item(&dst, index++,
533 std_to_attr(std::forward_as_tuple(
534 p.first, p.second)));
535 }
536 return dst;
537 }
538};
539
540template <typename... Args>
541struct attr_from_std_helper<std::tuple<Args...>> {
542 static attr_value_t f(const std::tuple<Args...> &src) {
543 attr_value_t dst = SIM_alloc_attr_list(sizeof...(Args));
544 set_items(&dst, src, 0, std::index_sequence_for<Args...>());
545 return dst;
546 }
547
548 private:
549 // Recursive template function to set items in the attribute list
550 template<std::size_t Index, std::size_t... Is>
551 static void set_items(attr_value_t *dst, const std::tuple<Args...> &src,
552 std::size_t current_index,
553 std::index_sequence<Index, Is...>) {
554 SIM_attr_list_set_item(dst, Index, std_to_attr(std::get<Index>(src)));
555 set_items(dst, src, current_index + 1, std::index_sequence<Is...>());
556 }
557
558 // Base case for recursion
559 static void set_items(attr_value_t *, const std::tuple<Args...> &,
560 std::size_t, std::index_sequence<>) {}
561};
562
563template <typename C, typename T = typename C::value_type>
564C to_container(const attr_value_t &src) {
565 if (!SIM_attr_is_list(src)) {
566 throw SetIllegalType {
567 "Expected Simics list type"
568 };
569 }
570 const unsigned size = SIM_attr_list_size(src);
571 std::vector<T> v;
572 for (unsigned i = 0; i < size; ++i) {
573 v.push_back(attr_to_std<T>(SIM_attr_list_item(src, i)));
574 }
575 return {v.begin(), v.end()};
576}
577
578template <typename V>
579struct attr_to_std_helper<std::vector<V>> {
580 static std::vector<V> f(const attr_value_t &src) {
581 return to_container<std::vector<V>>(src);
582 }
583};
584
585template <typename V>
586struct attr_to_std_helper<std::list<V>> {
587 static std::list<V> f(const attr_value_t &src) {
588 return to_container<std::list<V>>(src);
589 }
590};
591
592template <typename V>
593struct attr_to_std_helper<std::deque<V>> {
594 static std::deque<V> f(const attr_value_t &src) {
595 return to_container<std::deque<V>>(src);
596 }
597};
598
599template <typename V>
600struct attr_to_std_helper<std::set<V>> {
601 static std::set<V> f(const attr_value_t &src) {
602 return to_container<std::set<V>>(src);
603 }
604};
605
606template <typename V, std::size_t N>
607struct attr_to_std_helper<std::array<V, N>> {
608 static std::array<V, N> f(const attr_value_t &src) {
609 if (!SIM_attr_is_list(src)) {
610 throw SetIllegalType {
611 "Expected Simics list type"
612 };
613 }
614 const unsigned size = SIM_attr_list_size(src);
615 if (size != N) {
616 throw SetIllegalType {
617 "Size mismatch for std::array"
618 };
619 }
620 std::array<V, N> result;
621 for (unsigned i = 0; i < size; ++i) {
622 result[i] = attr_to_std<V>(SIM_attr_list_item(src, i));
623 }
624 return result;
625 }
626};
627
628template <typename X, typename Y>
629struct attr_to_std_helper<std::pair<X, Y>> {
630 static std::pair<X, Y> f(const attr_value_t& src) {
631 if (!SIM_attr_is_list(src) || SIM_attr_list_size(src) != 2) {
632 throw SetIllegalType {
633 "Expected Simics list type with exactly two members"
634 };
635 }
636 return {attr_to_std<X>(SIM_attr_list_item(src, 0)),
637 attr_to_std<Y>(SIM_attr_list_item(src, 1))};
638 }
639};
640
641template <typename X, typename Y>
642struct attr_to_std_helper<std::map<X, Y>> {
643 static std::map<X, Y> f(const attr_value_t& src) {
644 if (!SIM_attr_is_list(src)) {
645 throw SetIllegalType {
646 "Expected Simics list type"
647 };
648 }
649 std::map<X, Y> ret;
650 for (unsigned i = 0; i < SIM_attr_list_size(src); ++i) {
651 ret.emplace(attr_to_std<std::pair<X, Y>>(
652 SIM_attr_list_item(src, i)));
653 }
654 return ret;
655 }
656};
657
658template <typename... Args>
659struct attr_to_std_helper<std::tuple<Args...>> {
660 static std::tuple<Args...> f(const attr_value_t &src) {
661 if (!SIM_attr_is_list(src)
662 || SIM_attr_list_size(src) != sizeof...(Args)) {
663 throw SetIllegalType{
664 "Expected Simics list type with exactly " + \
665 std::to_string(sizeof...(Args)) + " members"
666 };
667 }
668
669 return convert_tuple(src, std::index_sequence_for<Args...>());
670 }
671
672 private:
673 // Helper function to convert items in the attribute list to a tuple
674 template<std::size_t... Is>
675 static std::tuple<Args...> convert_tuple(const attr_value_t &src,
676 std::index_sequence<Is...>) {
677 return std::make_tuple(convert_item<Args>(src, Is)...);
678 }
679
680 template<typename T>
681 static T convert_item(const attr_value_t &src, std::size_t index) {
682 return attr_to_std<T>(SIM_attr_list_item(src, index));
683 }
684};
685
686// Use this type for Simics "data" type
687using data_attribute = std::vector<uint8>;
688
689template <>
691 static attr_value_t f(const data_attribute& src) {
692 const auto size = src.size();
694 return SIM_make_attr_data(size, src.data());
695 }
696};
697
698template <>
700 static data_attribute f(const attr_value_t& src) {
701 if (!SIM_attr_is_data(src)) {
702 throw SetIllegalType {
703 "Expected Simics data type"
704 };
705 }
706 size_t size = SIM_attr_data_size(src);
707 const uint8 *data = SIM_attr_data(src);
708 return data_attribute(data, data + size);
709 }
710};
711
712} // namespace detail
713} // namespace simics
714
715#endif
#define _STD2ATTR_UINT_HELPER(type)
Definition: attribute-traits.h:260
#define _ATTR2STD_UINT_HELPER(type)
Definition: attribute-traits.h:302
#define _STD2ATTR_INT_HELPER(type)
Definition: attribute-traits.h:253
#define _ATTR2STD_FLOAT_HELPER(type)
Definition: attribute-traits.h:349
#define _ATTR2STD_INT_HELPER(type)
Definition: attribute-traits.h:281
#define _STD2ATTR_FLOAT_HELPER(type)
Definition: attribute-traits.h:338
Represents Simics C type conf_object_t.
Definition: conf-object.h:38
const std::string & port_name() const
Get & set name for the port implements the interface.
Definition: conf-object.h:60
void set_port_name(const std::string &name)
Definition: conf-object.h:61
Definition: attribute-exceptions.h:38
Definition: attribute-exceptions.h:51
std::vector< uint8 > data_attribute
Definition: attribute-traits.h:687
C to_container(const attr_value_t &src)
Definition: attribute-traits.h:564
attr_value_t from_container(const C &src)
Definition: attribute-traits.h:449
Definition: after-bank.h:33
void checkSizeOverflowSimicsAttribute(size_t size)
The maximum supported size for a Simics attribute dictionary/list/data is 2**32-1 bytes.
Definition: attribute-traits.h:40
std::enable_if< std::is_enum< T >::value, attr_value_t >::type std_to_attr(const T &src)
Function transforms C++ enum type T to Simics attr_value_t.
Definition: attribute-traits.h:163
std::enable_if< std::is_enum< T >::value, T >::type attr_to_std(attr_value_t src)
Function transforms Simics attr_value_t to C++ enum type.
Definition: attribute-traits.h:207
Definition: common-types.h:66
static attr_value_t f(const ConfObjectRef &src)
Definition: attribute-traits.h:69
static attr_value_t f(const V(&src)[N])
Definition: attribute-traits.h:470
static attr_value_t f(const attr_value_t &src)
Definition: attribute-traits.h:434
static attr_value_t f(const bool &src)
Definition: attribute-traits.h:413
static attr_value_t f(const char(&src)[N])
Definition: attribute-traits.h:481
static attr_value_t f(const char *src)
Definition: attribute-traits.h:388
static attr_value_t f(const data_attribute &src)
Definition: attribute-traits.h:691
static attr_value_t f(const std::array< V, N > &src)
Definition: attribute-traits.h:463
static attr_value_t f(const std::deque< V > &src)
Definition: attribute-traits.h:502
static attr_value_t f(const std::list< V > &src)
Definition: attribute-traits.h:495
static attr_value_t f(const std::map< X, Y > &src)
Definition: attribute-traits.h:526
static attr_value_t f(const std::pair< X, Y > &src)
Definition: attribute-traits.h:516
static attr_value_t f(const std::set< V > &src)
Definition: attribute-traits.h:509
static attr_value_t f(const std::string &src)
Definition: attribute-traits.h:369
static attr_value_t f(const std::tuple< Args... > &src)
Definition: attribute-traits.h:542
static attr_value_t f(const std::vector< V > &src)
Definition: attribute-traits.h:488
Definition: attribute-traits.h:51
static attr_value_t f(const T &src)
static ConfObjectRef f(const attr_value_t &src)
Definition: attribute-traits.h:89
static attr_value_t f(const attr_value_t &src)
Definition: attribute-traits.h:441
static bool f(const attr_value_t &src)
Definition: attribute-traits.h:420
static const char * f(const attr_value_t &src)
Definition: attribute-traits.h:395
static data_attribute f(const attr_value_t &src)
Definition: attribute-traits.h:700
static std::array< V, N > f(const attr_value_t &src)
Definition: attribute-traits.h:608
static std::deque< V > f(const attr_value_t &src)
Definition: attribute-traits.h:594
static std::list< V > f(const attr_value_t &src)
Definition: attribute-traits.h:587
static std::map< X, Y > f(const attr_value_t &src)
Definition: attribute-traits.h:643
static std::pair< X, Y > f(const attr_value_t &src)
Definition: attribute-traits.h:630
static std::set< V > f(const attr_value_t &src)
Definition: attribute-traits.h:601
static std::string f(const attr_value_t &src)
Definition: attribute-traits.h:376
static std::tuple< Args... > f(const attr_value_t &src)
Definition: attribute-traits.h:660
static std::vector< V > f(const attr_value_t &src)
Definition: attribute-traits.h:580
Definition: attribute-traits.h:59
static T f(const attr_value_t &src)
static constexpr bool value
Definition: attribute-traits.h:127
Definition: attribute-traits.h:151
Definition: attribute-traits.h:134