pvxslibs 1.5.0__cp310-cp310-manylinux2014_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. pvxslibs/__init__.py +0 -0
  2. pvxslibs/dbd/pvxsIoc.dbd +8 -0
  3. pvxslibs/include/pvxs/client.h +1094 -0
  4. pvxslibs/include/pvxs/data.h +948 -0
  5. pvxslibs/include/pvxs/iochooks.h +170 -0
  6. pvxslibs/include/pvxs/log.h +148 -0
  7. pvxslibs/include/pvxs/netcommon.h +82 -0
  8. pvxslibs/include/pvxs/nt.h +208 -0
  9. pvxslibs/include/pvxs/server.h +238 -0
  10. pvxslibs/include/pvxs/sharedArray.h +748 -0
  11. pvxslibs/include/pvxs/sharedpv.h +121 -0
  12. pvxslibs/include/pvxs/source.h +290 -0
  13. pvxslibs/include/pvxs/srvcommon.h +148 -0
  14. pvxslibs/include/pvxs/unittest.h +327 -0
  15. pvxslibs/include/pvxs/util.h +354 -0
  16. pvxslibs/include/pvxs/version.h +97 -0
  17. pvxslibs/include/pvxs/versionNum.h +6 -0
  18. pvxslibs/ioc.py +10 -0
  19. pvxslibs/lib/__init__.py +0 -0
  20. pvxslibs/lib/event_core_dsoinfo.py +14 -0
  21. pvxslibs/lib/event_pthread_dsoinfo.py +14 -0
  22. pvxslibs/lib/libevent_core.so +0 -0
  23. pvxslibs/lib/libevent_core.so.2.2.0 +0 -0
  24. pvxslibs/lib/libevent_pthread.so +0 -0
  25. pvxslibs/lib/libevent_pthread.so.2.2.0 +0 -0
  26. pvxslibs/lib/libpvxs.so +0 -0
  27. pvxslibs/lib/libpvxs.so.1.5 +0 -0
  28. pvxslibs/lib/libpvxsIoc.so +0 -0
  29. pvxslibs/lib/libpvxsIoc.so.1.5 +0 -0
  30. pvxslibs/lib/pvxsIoc_dsoinfo.py +14 -0
  31. pvxslibs/lib/pvxs_dsoinfo.py +14 -0
  32. pvxslibs/path.py +12 -0
  33. pvxslibs/test/__init__.py +0 -0
  34. pvxslibs/test/test_load.py +30 -0
  35. pvxslibs/version.py +32 -0
  36. pvxslibs-1.5.0.dist-info/METADATA +44 -0
  37. pvxslibs-1.5.0.dist-info/RECORD +40 -0
  38. pvxslibs-1.5.0.dist-info/WHEEL +5 -0
  39. pvxslibs-1.5.0.dist-info/licenses/LICENSE +26 -0
  40. pvxslibs-1.5.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,170 @@
1
+ /*
2
+ * Copyright - See the COPYRIGHT that is included with this distribution.
3
+ * pvxs is distributed subject to a Software License Agreement found
4
+ * in file LICENSE that is included with this distribution.
5
+ */
6
+ #ifndef PVXS_IOCHOOKS_H
7
+ #define PVXS_IOCHOOKS_H
8
+
9
+ #include <pvxs/version.h>
10
+
11
+ #if defined(_WIN32) || defined(__CYGWIN__)
12
+
13
+ # if defined(PVXS_IOC_API_BUILDING) && defined(EPICS_BUILD_DLL)
14
+ /* building library as dll */
15
+ # define PVXS_IOC_API __declspec(dllexport)
16
+ # elif !defined(PVXS_IOC_API_BUILDING) && defined(EPICS_CALL_DLL)
17
+ /* calling library in dll form */
18
+ # define PVXS_IOC_API __declspec(dllimport)
19
+ # endif
20
+
21
+ #elif __GNUC__ >= 4
22
+ # define PVXS_IOC_API __attribute__ ((visibility("default")))
23
+ #endif
24
+
25
+ #ifndef PVXS_IOC_API
26
+ # define PVXS_IOC_API
27
+ #endif
28
+
29
+ namespace pvxs {
30
+ namespace server {
31
+ class Server;
32
+ }
33
+ namespace ioc {
34
+
35
+ /** Return the singleton Server instance which is setup
36
+ * for use in an IOC process.
37
+ *
38
+ * This Server instance is created during a registrar function,
39
+ * started by the initHookAfterCaServerRunning phase of iocInit().
40
+ * It is stopped and destroyed during an epicsAtExit() hook added
41
+ * during an initHookAfterInitDatabase hook..
42
+ *
43
+ * Any configuration changes via. epicsEnvSet() must be made before registrars are run
44
+ * by \*_registerRecordDeviceDriver(pdbbase).
45
+ *
46
+ * server::SharedPV and server::Source added before iocInit() will be available immediately.
47
+ * Others may be added (or removed) later.
48
+ *
49
+ * @throws std::logic_error if called before instance is created, or after instance is destroyed.
50
+ *
51
+ * @code
52
+ * static void myinitHook(initHookState state) {
53
+ * if(state!=initHookAfterIocBuilt)
54
+ * return;
55
+ *
56
+ * server::SharedPV mypv(...);
57
+ * ioc::server()
58
+ * .addPV("my:pv:name", mypv);
59
+ * }
60
+ * static void myregistrar() {
61
+ * initHookRegister(&myinitHook);
62
+ * }
63
+ * extern "C" {
64
+ * // needs matching "registrar(myregistrar)" in .dbd
65
+ * epicsExportRegistrar(myregistrar);
66
+ * }
67
+ * @endcode
68
+ */
69
+ PVXS_IOC_API
70
+ server::Server server();
71
+
72
+ /**
73
+ * Load JSON group definition file.
74
+ * This function does not actually parse the given file, but adds it to the list of files to be loaded,
75
+ * at the appropriate time in the startup process.
76
+ *
77
+ * @param jsonFilename the json file containing the group definitions
78
+ * @param macros NULL, or a comma separated list of macro definitions. eg. "KEY=VAL,OTHER=SECOND"
79
+ * @return 0 for success, 1 for failure
80
+ * @since 1.2.0
81
+ */
82
+ PVXS_IOC_API
83
+ long dbLoadGroup(const char* jsonFilename, const char* macros=nullptr);
84
+
85
+ /** Call just after testdbPrepare()
86
+ *
87
+ * Prepare QSRV for re-test. Optional if testdbPrepare() called only once.
88
+ * Required after subsequent calls.
89
+ * @since 1.2.3
90
+ */
91
+ PVXS_IOC_API
92
+ void testPrepare();
93
+
94
+ /** Call just before testIocShutdownOk()
95
+ *
96
+ * Shutdown QSRV. Only needed with Base <= 7.0.4 .
97
+ * Since 7.0.4, QSRV shutdown occurs during testIocShutdownOk() .
98
+ * @since 1.2.0
99
+ */
100
+ PVXS_IOC_API
101
+ void testShutdown();
102
+
103
+ /** Call just after testIocShutdownOk()
104
+ * @since 1.3.0
105
+ */
106
+ PVXS_IOC_API
107
+ void testAfterShutdown();
108
+
109
+ /** Call just before testdbCleanup()
110
+ * @since 1.3.0
111
+ */
112
+ PVXS_IOC_API
113
+ void testCleanupPrepare();
114
+
115
+ #if _DOXYGEN_ || EPICS_VERSION_INT >= VERSION_INT(3, 15, 0 ,0)
116
+
117
+ /** Manage Test IOC life-cycle calls.
118
+ *
119
+ * Makes necessary calls to dbUnitTest.h API
120
+ * as well as any added calls needed by PVXS components.
121
+ *
122
+ @code
123
+ * MAIN(mytest) {
124
+ * testPlan(0); // TODO: Set actual number of tests
125
+ * pvxs::testSetup();
126
+ * pvxs::logger_config_env(); // (optional)
127
+ * {
128
+ * TestIOC ioc; // testdbPrepare()
129
+ *
130
+ * // mytestioc.dbd must include pvxsIoc.dbd
131
+ * testdbReadDatabase("mytestioc.dbd", NULL, NULL);
132
+ * mytestioc_registerRecordDeviceDriver(pdbbase);
133
+ * testdbReadDatabase("sometest.db", NULL, NULL);
134
+ *
135
+ * // tests before iocInit()
136
+ *
137
+ * ioc.init();
138
+ *
139
+ * // tests after iocInit()
140
+ *
141
+ * ioc.shutdown(); // (optional) in ~TestIOC if omitted
142
+ * }
143
+ * {
144
+ * ... repeat ...
145
+ * }
146
+ * epicsExitCallAtExits();
147
+ * pvxs::cleanup_for_valgrind();
148
+ * }
149
+ @endcode
150
+ *
151
+ * @since 1.3.0
152
+ */
153
+ class PVXS_IOC_API TestIOC final {
154
+ bool isRunning = false;
155
+ public:
156
+ TestIOC();
157
+ ~TestIOC();
158
+ //! iocInit()
159
+ void init();
160
+ //! iocShutdown()
161
+ void shutdown();
162
+ //! between iocInit() and iocShutdown() ?
163
+ inline
164
+ bool running() const { return isRunning; }
165
+ };
166
+
167
+ #endif // base >= 3.15
168
+
169
+ }} // namespace pvxs::ioc
170
+ #endif // PVXS_IOCHOOKS_H
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Copyright - See the COPYRIGHT that is included with this distribution.
3
+ * pvxs is distributed subject to a Software License Agreement found
4
+ * in file LICENSE that is included with this distribution.
5
+ */
6
+ #ifndef PVXS_LOG_H
7
+ #define PVXS_LOG_H
8
+
9
+ #include <atomic>
10
+
11
+ #include <cstddef>
12
+ #include <stdarg.h>
13
+
14
+ #include <compilerDependencies.h>
15
+ #include <errlog.h>
16
+
17
+ #include <pvxs/version.h>
18
+
19
+ // MSVC specific function parameter annotation for printf() spec. validation.
20
+ #ifndef _MSC_VER
21
+ # define _Printf_format_string_
22
+ #elif defined(PVXS_API_BUILDING)
23
+ // Internally, treat some printf() related warnings as errors.
24
+ # pragma warning(error:6302; error:6303; error:6306)
25
+ #endif
26
+
27
+ namespace pvxs {
28
+
29
+ //! Importance of message
30
+ enum struct Level {
31
+ Debug = 50,
32
+ Info = 40,
33
+ Warn = 30,
34
+ Err = 20,
35
+ Crit = 10,
36
+ };
37
+
38
+ //! A logger
39
+ struct logger {
40
+ //! global name of this logger. Need not be unique
41
+ const char * const name;
42
+ //! Current logging level. See logger_level_set().
43
+ std::atomic<Level> lvl;
44
+ constexpr logger(const char *name) :name(name), lvl{Level(-1)} {}
45
+
46
+ private:
47
+ PVXS_API Level init();
48
+ public:
49
+
50
+ //! @returns true if the logger currently allows a message at level LVL.
51
+ inline bool test(Level lvl) {
52
+ Level cur = this->lvl.load(std::memory_order_relaxed);
53
+ if(cur==Level(-1)) cur = init();
54
+ return cur>=lvl;
55
+ }
56
+ };
57
+
58
+ namespace detail {
59
+
60
+ PVXS_API
61
+ const char *log_prep(logger& log, unsigned lvl);
62
+
63
+ PVXS_API
64
+ void _log_printf(unsigned rawlvl, _Printf_format_string_ const char *fmt, ...) EPICS_PRINTF_STYLE(2,3);
65
+
66
+ PVXS_API
67
+ void _log_printf_hex(unsigned rawlvl, _Printf_format_string_ const void *buf, size_t buflen, const char *fmt, ...) EPICS_PRINTF_STYLE(4,5);
68
+
69
+ } // namespace detail
70
+
71
+ //! Define a new logger global.
72
+ //! @param VAR The (static) variable name passed to log_printf() and friends.
73
+ //! @param NAME A name string in "A.B.C" form.
74
+ #define DEFINE_LOGGER(VAR, NAME) static ::pvxs::logger VAR{NAME}
75
+
76
+ PVXS_API
77
+ void xerrlogHexPrintf(const void *buf, size_t buflen);
78
+
79
+ /** Try to log a message at the defined level.
80
+ *
81
+ * Due to portability issues with MSVC, log formats must have at least one argument.
82
+ *
83
+ * @code
84
+ * DEFINE_LOGGER(blah, "myapp.blah");
85
+ * void blahfn(int x) {
86
+ * log_info_printf(blah, "blah happened with %d\n", x);
87
+ * @endcode
88
+ */
89
+ #define log_printf(LOGGER, LVL, FMT, ...) do{ \
90
+ if(auto _log_prefix = ::pvxs::detail::log_prep(LOGGER, unsigned(LVL))) \
91
+ ::pvxs::detail:: _log_printf(unsigned(LVL), "%s " FMT, _log_prefix, __VA_ARGS__); \
92
+ }while(0)
93
+
94
+ /* A note about MSVC (legacy) pre-processor weirdness.
95
+ * Care needs to be taken when expanding nested macros w/ __VA_ARGS__.
96
+ * Expansion of __VA_ARGS__ for the outer macro seems to result in
97
+ * all of the contents, including commas, being treated as a single
98
+ * token. Which won't be split during expansion of the inner macro!
99
+ *
100
+ * #define inner(FMT, ...) printf("%s " FMT, "prefix", __VA_ARGS__)
101
+ * #define outer(...) inner(__VA_ARGS__)
102
+ * outer("%d", 42);
103
+ * expands to
104
+ * printf("%s " "%d", 42, "prefix");
105
+ *
106
+ * The prefix string has jumped to the end because FMT has expanded
107
+ * with all of the arguments of outer(...). Surprise!
108
+ *
109
+ * Thus FMT is explicitly matched in the following "outer" macros.
110
+ */
111
+
112
+ #define log_exc_printf(LOGGER, FMT, ...) log_printf(LOGGER, unsigned(::pvxs::Level::Crit)|0x1000, FMT, __VA_ARGS__)
113
+ #define log_crit_printf(LOGGER, FMT, ...) log_printf(LOGGER, ::pvxs::Level::Crit, FMT, __VA_ARGS__)
114
+ #define log_err_printf(LOGGER, FMT, ...) log_printf(LOGGER, ::pvxs::Level::Err, FMT, __VA_ARGS__)
115
+ #define log_warn_printf(LOGGER, FMT, ...) log_printf(LOGGER, ::pvxs::Level::Warn, FMT, __VA_ARGS__)
116
+ #define log_info_printf(LOGGER, FMT, ...) log_printf(LOGGER, ::pvxs::Level::Info, FMT, __VA_ARGS__)
117
+ #define log_debug_printf(LOGGER, FMT, ...) log_printf(LOGGER, ::pvxs::Level::Debug, FMT, __VA_ARGS__)
118
+
119
+ #define log_hex_printf(LOGGER, LVL, BUF, BUFLEN, FMT, ...) do{ \
120
+ if(auto _log_prefix = ::pvxs::detail::log_prep(LOGGER, unsigned(LVL))) \
121
+ ::pvxs::detail:: _log_printf_hex(unsigned(LVL), BUF, BUFLEN, "%s " FMT, _log_prefix, __VA_ARGS__);\
122
+ }while(0)
123
+
124
+ //! Set level for a specific logger
125
+ PVXS_API void logger_level_set(const char *name, int lvl);
126
+ inline void logger_level_set(const char *name, Level lvl) {
127
+ logger_level_set(name, int(lvl));
128
+ }
129
+ //! Remove any previously logger configurations.
130
+ //! Does _not_ change any logger::lvl
131
+ //! Use prior to re-applying new configuration.
132
+ PVXS_API void logger_level_clear();
133
+
134
+ /** Configure logging from environment variable **$PVXS_LOG**
135
+ *
136
+ * Value of the form "key=VAL,..."
137
+ *
138
+ * Keys may be literal logger names, or may include '*' wildcards
139
+ * to match multiple loggers. eg. "pvxs.*=DEBUG" will enable
140
+ * all internal log messages.
141
+ *
142
+ * VAL may be one of "CRIT", "ERR", "WARN", "INFO", or "DEBUG"
143
+ */
144
+ PVXS_API void logger_config_env();
145
+
146
+ } // namespace pvxs
147
+
148
+ #endif // PVXS_LOG_H
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Copyright - See the COPYRIGHT that is included with this distribution.
3
+ * pvxs is distributed subject to a Software License Agreement found
4
+ * in file LICENSE that is included with this distribution.
5
+ */
6
+ #ifndef PVXS_NETCOMMON_H
7
+ #define PVXS_NETCOMMON_H
8
+
9
+ #if !defined(PVXS_CLIENT_H) && !defined(PVXS_SERVER_H)
10
+ # error Include <pvxs/client.h> or <pvxs/server.h> Do not include netcommon.h directly
11
+ #endif
12
+
13
+ #include <string>
14
+ #include <list>
15
+ #include <memory>
16
+
17
+ #include <pvxs/version.h>
18
+
19
+ namespace pvxs {
20
+ namespace impl {
21
+ struct Report;
22
+ struct ReportInfo;
23
+ }
24
+ namespace server {
25
+ struct ClientCredentials;
26
+ using impl::Report;
27
+ using impl::ReportInfo;
28
+ }
29
+ namespace client {
30
+ using impl::Report;
31
+ using impl::ReportInfo;
32
+ }
33
+ namespace impl {
34
+
35
+ #ifdef PVXS_EXPERT_API_ENABLED
36
+
37
+ /** Snapshot of information about a client/server
38
+ *
39
+ * cf. pvxs::server::Server::report() and pvxs::client::Context::report()
40
+ *
41
+ * @since 0.2.0
42
+ */
43
+ struct Report {
44
+ //! Info for a single channel (to a particular PV name on a particular server)
45
+ struct Channel {
46
+ //! Channel name. aka. PV name
47
+ std::string name;
48
+ //! transmit and receive counters in bytes
49
+ size_t tx{}, rx{};
50
+ //! Contextual information (maybe) supplied by the Source
51
+ std::shared_ptr<const ReportInfo> info;
52
+ };
53
+
54
+ //! Info for a single connection to remote peer
55
+ struct Connection {
56
+ //! peer endpoint (eg. IPv4 address and port)
57
+ std::string peer;
58
+ //! Credentials presented by peer. Only from Server::report()
59
+ std::shared_ptr<const server::ClientCredentials> credentials;
60
+ //! transmit and receive counters in bytes
61
+ size_t tx{}, rx{};
62
+ //! Channels currently connected through this socket
63
+ std::list<Channel> channels;
64
+ };
65
+
66
+ //! Currently open sockets
67
+ std::list<Connection> connections;
68
+ };
69
+
70
+ struct PVXS_API ReportInfo {
71
+ ReportInfo() = default;
72
+ ReportInfo(const ReportInfo&) = delete;
73
+ ReportInfo& operator=(const ReportInfo&) = delete;
74
+ virtual ~ReportInfo();
75
+ };
76
+
77
+ #endif
78
+
79
+ } // namespace impl
80
+ } // namespace pvxs
81
+
82
+ #endif // PVXS_NETCOMMON_H
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Copyright - See the COPYRIGHT that is included with this distribution.
3
+ * pvxs is distributed subject to a Software License Agreement found
4
+ * in file LICENSE that is included with this distribution.
5
+ */
6
+ #ifndef PVXS_NT_H
7
+ #define PVXS_NT_H
8
+
9
+ #include <memory>
10
+
11
+ #include <pvxs/version.h>
12
+ #include <pvxs/data.h>
13
+
14
+ struct epicsTimeStamp; // epicsTime.h
15
+
16
+ namespace pvxs {
17
+ namespace nt {
18
+
19
+ /** The time_t struct
20
+ *
21
+ * @code
22
+ * // equivalent
23
+ * struct time_t {
24
+ * int64_t secondsPastEpoch;
25
+ * int32_t nanoseconds;
26
+ * int32_t userTag;
27
+ * };
28
+ * @endcode
29
+ * @since 0.1.4
30
+ */
31
+ struct TimeStamp {
32
+ PVXS_API
33
+ TypeDef build();
34
+ };
35
+
36
+ /** The alarm_t struct
37
+ *
38
+ * @code
39
+ * // equivalent
40
+ * struct alarm_t {
41
+ * int32_t severity;
42
+ * int32_t status;
43
+ * string message;
44
+ * };
45
+ * @endcode
46
+ * @since 0.1.4
47
+ */
48
+ struct Alarm {
49
+ PVXS_API
50
+ TypeDef build();
51
+ };
52
+
53
+ /** A scalar, or array of scalars, and meta-data
54
+ *
55
+ * @code
56
+ * auto def = pvxs::nt::NTScalar{TypeCode::Float64}.build();
57
+ * def += {
58
+ * Member(TypeCode::String, "myspecial"),
59
+ * };
60
+ * auto value = def.create(); // instantiate a Value
61
+ * @endcode
62
+ */
63
+ struct NTScalar {
64
+ //! Type of the ".value" field.
65
+ TypeCode value;
66
+ //! Include display (range) meta-data
67
+ bool display;
68
+ //! Include control (range) meta-data
69
+ bool control;
70
+ //! Include alarm (range) meta-data
71
+ bool valueAlarm;
72
+ /** Include 'display.form' and 'display.precision' when 'value' is a numeric type
73
+ * @pre requires display=true
74
+ * @since 1.2.0
75
+ */
76
+ bool form;
77
+
78
+ constexpr
79
+ NTScalar(TypeCode value = TypeCode::Float64,
80
+ bool display = false,
81
+ bool control = false,
82
+ bool valueAlarm = false,
83
+ bool form = false)
84
+ :value(value), display(display), control(control), valueAlarm(valueAlarm), form(form)
85
+ {}
86
+
87
+ //! A TypeDef which can be appended
88
+ PVXS_API
89
+ TypeDef build() const;
90
+ //! Instantiate
91
+ inline Value create() const {
92
+ return build().create();
93
+ }
94
+ };
95
+
96
+ /** An enumerated value (choice from a list of strings)
97
+ *
98
+ * @since 0.1.5
99
+ */
100
+ struct NTEnum {
101
+ //! A TypeDef which can be appended
102
+ PVXS_API
103
+ TypeDef build() const;
104
+ //! Instantiate
105
+ inline Value create() const {
106
+ return build().create();
107
+ }
108
+ };
109
+
110
+ /** Columnar data.
111
+ *
112
+ * Unlike other NT* builders. This create() method returns a Value
113
+ * with the labels field set, and marked. While suitable for an
114
+ * initial value, repeated create() could result in re-sending
115
+ * the same labels array with every update. Users should
116
+ * create() once, and then Value::cloneEmpty() or Value::unmark() for
117
+ * subsequent updates.
118
+ *
119
+ * @since 1.2.3
120
+ */
121
+ struct PVXS_API NTTable final {
122
+
123
+ NTTable();
124
+ ~NTTable();
125
+
126
+ /** Append a column
127
+ *
128
+ * @param code Value type of column
129
+ * @param name Field name of column
130
+ * @param label Display label of column. (defaults to field name)
131
+ * Only used in create().
132
+ * @returns this
133
+ */
134
+ NTTable& add_column(TypeCode code,
135
+ const char *name,
136
+ const char *label=nullptr);
137
+
138
+ //! A TypeDef which can be appended
139
+ TypeDef build() const;
140
+ //! Instantiate. Also populates labels list.
141
+ Value create() const;
142
+
143
+ struct Pvt;
144
+ private:
145
+ std::shared_ptr<Pvt> pvt;
146
+ };
147
+
148
+ /** The areaDetector inspired N-dimension array/image container.
149
+ *
150
+ * @code
151
+ * auto def = pvxs::nt::NTNDArray{}.build();
152
+ * auto value = def.create(); // instantiate a Value
153
+ * @endcode
154
+ */
155
+ struct NTNDArray {
156
+ //! A TypeDef which can be appended
157
+ PVXS_API
158
+ TypeDef build() const;
159
+ //! Instantiate
160
+ inline Value create() const {
161
+ return build().create();
162
+ }
163
+ };
164
+
165
+ class PVXS_API NTURI {
166
+ TypeDef _def;
167
+ public:
168
+ NTURI(std::initializer_list<Member> mem);
169
+
170
+ //! A TypeDef which can be appended
171
+ inline
172
+ TypeDef build() const { return _def; }
173
+
174
+ //! Instantiate
175
+ inline Value create() const {
176
+ return build().create();
177
+ }
178
+
179
+ private:
180
+ template<typename Iter, typename T, typename ...Args>
181
+ static
182
+ void _assign(Iter& cur, const Iter& end, const T& v, Args... args)
183
+ {
184
+ if(cur==end)
185
+ throw std::logic_error("Too many arguments");
186
+ (*cur).template from<T>(v);
187
+ ++cur;
188
+ _assign(cur, end, args...);
189
+ }
190
+ template<typename Iter>
191
+ static
192
+ void _assign(Iter& cur, const Iter& end)
193
+ {}
194
+ public:
195
+
196
+ template<typename ...Args>
197
+ Value call(Args... args) const {
198
+ auto val(create());
199
+ auto iterable = val["query"].ichildren();
200
+ auto it = iterable.begin();
201
+ _assign(it, iterable.end(), args...);
202
+ return val;
203
+ }
204
+ };
205
+
206
+ }} // namespace pvxs::nt
207
+
208
+ #endif // PVXS_NT_H