libiio  1.0
Library for interfacing with IIO devices
iiopp.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /*
3  * libiio - Library for interfacing industrial I/O (IIO) devices
4  *
5  * Copyright (C) 2023, DIFITEC GmbH
6  * Author: Tilman Blumhagen <tilman.blumhagen@difitec.de>
7  */
8 
15 #pragma once
16 
17 #include <iio/iio.h>
18 #include <string>
19 
20 #define IIOPP_HAVE_STD_OPIONAL (__cplusplus >= 201703L || _MSC_VER >= 1910)
21 
22 #if IIOPP_HAVE_STD_OPIONAL
23 #include <optional>
24 #else
25 #include <boost/optional.hpp>
26 #endif
27 #include <stdexcept>
28 #include <system_error>
29 #include <cassert>
30 #include <type_traits>
31 
59 namespace iiopp
60 {
61 
62 #if IIOPP_HAVE_STD_OPIONAL
63 using std::optional;
64 #else
65 using boost::optional;
66 #endif
67 
68 class Context;
69 class Device;
70 class Buffer;
71 
78 class cstr
79 {
80  char const * const s;
81 public:
82  cstr(std::string const & s) : s(s.c_str()){}
83  cstr(char const * s) : s(s){assert(s);}
84  cstr(void const * s) : s(static_cast<char const *>(s)){assert(s);}
85 
86  char const * c_str() const {return s;}
87  operator char const * () const {return s;}
88 };
89 
92 class error : public std::system_error
93 {
94 public:
95  using std::system_error::system_error;
96 };
97 
100 typedef optional<cstr> optstr;
101 
102 
106 namespace impl
107 {
108 
109 inline optstr opt(char const * s)
110 {
111  return s ? optstr{{s}} : optstr{};
112 }
113 
114 template <class T, class C> optional<T> maybe(C * obj)
115 {
116  return obj ? optional<T>{{obj}} : optional<T>{};
117 }
118 
119 inline std::string err_str(int err)
120 {
121  char buf[1024]; // Flawfinder: ignore
122  iio_strerror(err, buf, sizeof(buf));
123  return buf;
124 }
125 
126 [[noreturn]] inline void err(int err, char const * ctx)
127 {
128  assert(err > 0);
129  throw error(err, std::generic_category(), ctx);
130 }
131 
132 inline void check(int ret, char const * ctx)
133 {
134  if (ret)
135  {
136  assert(ret < 0);
137  err(-ret, ctx);
138  }
139 }
140 
141 template <class T>
142 T * check(T * ret, char const * ctx)
143 {
144  if (int e = iio_err(ret))
145  {
146  err(e, ctx);
147  }
148 
149  return ret;
150 }
151 
152 template <class T>
153 T check_n(T n, char const * s)
154 {
155  if (n < 0)
156  impl::err(static_cast<int>(-n), s);
157  return n;
158 }
159 
164 template <class container_T, class element_T> //, class size_T=std::size_t, class diff_T=std::ptrdiff_t>
166 {
167  container_T & _me() {return *static_cast<container_T*>(this);}
168 public:
169 
172  class Iterator
173  {
174  public:
175  typedef std::random_access_iterator_tag iterator_category;
176  typedef element_T value_type;
177  typedef decltype(std::declval<container_T>().size()) size_type;
178  typedef std::make_signed<size_type> difference_type;
179  typedef element_T *pointer;
180  typedef element_T &reference;
181 
182  Iterator(container_T &cont, size_type idx) : c(cont), i(idx) {assert(idx <= cont.size());}
183 
184  element_T operator*() const { return c[i]; }
185  Iterator& operator++() { assert(i <= c.size()); ++i; return *this;}
186  Iterator operator++(int) { Iterator tmp = *this; ++(*this); return tmp; }
187  bool operator == (const Iterator& rhs) const { assert(&c == &rhs.c); return i == rhs.i; }
188  bool operator != (const Iterator& rhs) const { assert(&c == &rhs.c); return i != rhs.i; }
189  bool operator < (const Iterator& rhs) const { assert(&c == &rhs.c); return i < rhs.i; }
190  bool operator > (const Iterator& rhs) const { assert(&c == &rhs.c); return i > rhs.i; }
191  bool operator <= (const Iterator& rhs) const { assert(&c == &rhs.c); return i <= rhs.i; }
192  bool operator >= (const Iterator& rhs) const { assert(&c == &rhs.c); return i >= rhs.i; }
193  Iterator operator + (difference_type x) const { return Iterator(c, i + x); }
194  int operator - (Iterator rhs) const { assert(&c == &rhs.c); return i - rhs.i; }
195  private:
196  container_T & c;
197  size_type i;
198  };
199 
200  Iterator begin() {return Iterator(_me(), 0);}
201  Iterator end() {return Iterator(_me(), _me().size());}
202 };
203 
204 }
205 
206 
209 class Attr
210 {
211  iio_attr const * p;
212 public:
213  Attr() = delete;
214  Attr(iio_attr const * attr) : p(attr){assert(attr);}
215  operator iio_attr const * () const {return p;}
216 
217  cstr name() {return iio_attr_get_name(p);}
218  cstr filename() {return iio_attr_get_filename(p);}
219  cstr static_value() {return iio_attr_get_static_value(p);}
220 
221  size_t read_raw(char * dst, size_t size) const {return impl::check_n(iio_attr_read_raw(p, dst, size), "iio_attr_read_raw");}
222  bool read_bool() const {bool val; impl::check(iio_attr_read_bool(p, &val), "iio_attr_read_bool"); return val;}
223  double read_double() const {double val; impl::check(iio_attr_read_double(p, &val), "iio_attr_read_double"); return val;}
224  long long read_longlong() const {long long val; impl::check(iio_attr_read_longlong(p, &val), "iio_attr_read_longlong"); return val;}
225 
226  size_t write_raw(void const * src, size_t len) {return impl::check_n(iio_attr_write_raw(p, src, len), "iio_attr_write_raw");}
227  size_t write_string(cstr val) {return impl::check_n(iio_attr_write_string(p, val), "iio_attr_write_string");}
228  void write_bool(bool val) {impl::check(iio_attr_write_bool(p, val), "iio_attr_write_bool");}
229  void write_double(double val) {impl::check(iio_attr_write_double(p, val), "iio_attr_write_double");}
230  void write_longlong(long long val) {impl::check(iio_attr_write_longlong(p, val), "iio_attr_write_longlong");}
231 
232  operator bool () const {return read_bool();}
233  operator double () const {return read_double();}
234  operator long long () const {return read_longlong();}
235 
236  cstr operator = (cstr val){write_string(val); return val;}
237  bool operator = (bool val){write_bool(val); return val;}
238  double operator = (double val){write_double(val); return val;}
239  long long operator = (long long val){write_longlong(val); return val;}
240 };
241 
242 namespace impl
243 {
244 
247 #ifdef DOXYGEN
248 template <class obj_T>
249 class AttrSeqT : public IndexedSequence<AttrSeqT<obj_T>, Attr>
250 #else
251 template <class obj_T,
252  unsigned int get_attrs_count_T(obj_T const *),
253  iio_attr const * get_attr_T(obj_T const *, unsigned int),
254  iio_attr const * find_attr_T(obj_T const *, char const *)
255  >
256 class AttrSeqT : public IndexedSequence<AttrSeqT<obj_T, get_attrs_count_T, get_attr_T, find_attr_T>, Attr>
257 #endif
258 {
259  obj_T const * const _obj;
260 public:
261  AttrSeqT(obj_T const * obj) : _obj(obj){assert(obj);}
262 
265  unsigned int size() const {return get_attrs_count_T(_obj);}
266 
269  Attr operator [](unsigned int idx)
270  {
271  if (auto ret = get_attr_T(_obj, idx))
272  return Attr(ret);
273  throw std::out_of_range("invalid attribute index");
274  }
275 
279  {
280  if (auto ret = find_attr_T(_obj, name))
281  return Attr(ret);
282  throw std::out_of_range("invalid attribute name");
283  }
284 };
285 
286 template <class obj_T, iio_attr const * find_attr_T(obj_T const *, char const *)>
287 optional<Attr> attr(obj_T const * obj, cstr name)
288 {
289  return maybe<Attr>(find_attr_T(obj, name));
290 }
291 
292 template <class obj_T, iio_attr const * get_attr_T(obj_T const *, unsigned int)>
293 optional<Attr> attr(obj_T const * obj, unsigned int index)
294 {
295  return maybe<Attr>(get_attr_T(obj, index));
296 }
297 
298 } // namespace impl
299 
300 
301 
309 template <class obj_T, class ptr_T, void deleter_T(ptr_T *)>
310 class Ptr
311 {
312  obj_T p;
313 public:
314  Ptr() = delete;
315  Ptr(Ptr const &) = delete;
316  Ptr(Ptr && rhs) : p(rhs.p) { rhs.p = nullptr;}
317  explicit Ptr(ptr_T * obj) : p{obj}{}
318  ~Ptr(){ if (p) deleter_T(const_cast<ptr_T*>(static_cast<ptr_T const*>(p)));}
319 
320  Ptr & operator = (Ptr &) = delete;
321  void operator = (Ptr && rhs)
322  {
323  if (p)
324  deleter_T(p);
325  p = rhs.p;
326  rhs.p = nullptr;
327  }
328 
329  operator obj_T * () {return &p;}
330  operator obj_T * () const {return &p;}
331  obj_T * operator -> () {return &p;}
332  obj_T const * operator -> () const {return &p;}
333 };
334 
338 {
339  iio_channels_mask const * const p;
340 public:
341 
342  ChannelsMask() = delete;
343  ChannelsMask(iio_channels_mask const * mask) : p(mask){assert(mask);}
344  operator iio_channels_mask const * () const {return p;}
345 };
346 
348 
349 ChannelsMaskPtr create_channels_mask(unsigned int nb_channels)
350 {
351  return ChannelsMaskPtr(iio_create_channels_mask(nb_channels));
352 }
353 
356 class Block
357 {
358  iio_block * const p;
359 public:
360 
361  Block() = delete;
362  Block(iio_block * block) : p(block){assert(block);}
363  operator iio_block * () const {return p;}
364 
365  void * start() {return iio_block_start(p);}
366  void * first(iio_channel * chn) {return iio_block_first(p, chn);}
367  void * end() {return iio_block_end(p);}
368  ssize_t foreach_sample(const struct iio_channels_mask *mask,
369  ssize_t (*callback)(const struct iio_channel *chn, void *src, size_t bytes, void *d),
370  void *data)
371  {
372  return iio_block_foreach_sample(p, mask, callback, data);
373  }
374 
375  void enqueue(size_t bytes_used, bool cyclic) {impl::check(iio_block_enqueue(p, bytes_used, cyclic), "iio_block_enqueue");}
376  void dequeue(bool nonblock) {impl::check(iio_block_dequeue(p, nonblock), "iio_block_dequeue");}
377  Buffer buffer();
378 };
379 
381 
384 class Channel
385 {
386  iio_channel * const p;
387 public:
388 
389  Channel() = delete;
390  Channel(iio_channel * chan) : p(chan), attrs(chan){assert(chan);}
391  operator iio_channel * () const {return p;}
392 
393 #ifndef DOXYGEN
394  typedef impl::AttrSeqT<iio_channel,
395  iio_channel_get_attrs_count,
396  iio_channel_get_attr,
397  iio_channel_find_attr
398  > AttrSeq;
399 #else
401 #endif
402 
403  AttrSeq attrs;
404 
405  Device device() const;
406  cstr id() const {return iio_channel_get_id(p);}
407  optstr name() const { return impl::opt(iio_channel_get_name(p));}
408  bool is_output() const { return iio_channel_is_output(p);}
409  bool is_scan_element() const { return iio_channel_is_scan_element(p);}
410  unsigned int attrs_count() const {return iio_channel_get_attrs_count(p);}
411  optional<Attr> attr(unsigned int index) {return impl::maybe<Attr>(iio_channel_get_attr(p, index));}
412  optional<Attr> find_attr(cstr name) {return impl::maybe<Attr>(iio_channel_find_attr(p, name));}
413  void enable(iio_channels_mask * mask) {iio_channel_enable(p, mask);}
414  void disable(iio_channels_mask * mask) {iio_channel_disable(p, mask);}
415  bool is_enabled(iio_channels_mask * mask) const { return iio_channel_is_enabled(p, mask);}
416  size_t read(Block block, void * dst, size_t len, bool raw) const; // Flawfinder: ignore
417  size_t write(Block block, void const * src, size_t len, bool raw);
418  void set_data(void * data){iio_channel_set_data(p, data);}
419  void * data() const {return iio_channel_get_data(p);}
420  iio_chan_type type() const {return iio_channel_get_type(p);}
421  iio_modifier modifier() const {return iio_channel_get_modifier(p);}
422  hwmon_chan_type hwmon_type() const {return hwmon_channel_get_type(p);}
423  unsigned long index() const { return impl::check_n(iio_channel_get_index(p), "iio_channel_get_index");}
424  iio_data_format const * data_format() const {return iio_channel_get_data_format(p);}
425  void convert(void * dst, void const * src) const {iio_channel_convert(p, dst, src);}
426  void convert_inverse(void * dst, void const * src) const {iio_channel_convert_inverse(p, dst, src);}
427 };
428 
431 class Stream
432 {
433  iio_stream * const p;
434 public:
435 
436  Stream() = delete;
437  Stream(iio_stream * s) : p(s){assert(s);}
438  operator iio_stream * () const {return p;}
439 
440  Block next_block() {return const_cast<iio_block *>(impl::check(iio_stream_get_next_block(p), "iio_stream_get_next_block")); }
441 };
442 
444 
448 struct Event : public iio_event
449 {
450  iio_event_type type() const { return iio_event_get_type(this);}
451  iio_event_direction direction() const { return iio_event_get_direction(this);}
452  optional<Channel> channel(iio_device * dev, bool diff){return impl::maybe<Channel>(const_cast<iio_channel*>(iio_event_get_channel(this, dev, diff)));}
453 };
454 
458 {
459  iio_event_stream * const p;
460 public:
461 
462  EventStream() = delete;
463  EventStream(iio_event_stream * s) : p(s){assert(p);}
464  operator iio_event_stream * () const {return p;}
465 
466  Event read(bool nonblock) {iio_event ev; impl::check(iio_event_stream_read(p, &ev, nonblock), "iio_event_stream_read"); return static_cast<Event&>(ev);} // Flawfinder: ignore
467 };
468 
470 
471 
474 class Buffer
475 {
476  iio_buffer * const p;
477 public:
478  Buffer() = delete;
479  Buffer(iio_buffer * buffer) : p(buffer), attrs(buffer){assert(buffer);}
480  operator iio_buffer * () const {return p;}
481 
482 #ifndef DOXYGEN
483  typedef impl::AttrSeqT<iio_buffer,
484  iio_buffer_get_attrs_count,
485  iio_buffer_get_attr,
486  iio_buffer_find_attr
487  > AttrSeq;
488 #else
490 #endif
491 
492  AttrSeq attrs;
493 
494  Device device();
495  unsigned int attrs_count() const {return iio_buffer_get_attrs_count(p);}
496  optional<Attr> get_attr(unsigned int index) {return impl::maybe<Attr>(iio_buffer_get_attr(p, index));}
497  optional<Attr> find_attr(cstr name) {return impl::maybe<Attr>(iio_buffer_find_attr(p, name));}
498  void set_data(void * data){iio_buffer_set_data(p, data);}
499  void * data() {return iio_buffer_get_data(p);}
500  void cancel() {iio_buffer_cancel(p);}
501  void enable() {impl::check(iio_buffer_enable(p), "iio_buffer_enable");}
502  void disable() {impl::check(iio_buffer_disable(p), "iio_buffer_disable");}
503  ChannelsMask channels_mask() {return iio_buffer_get_channels_mask(p);}
504  BlockPtr create_block(size_t size) { return BlockPtr{impl::check(iio_buffer_create_block(p, size), "iio_buffer_create_block")}; }
505  StreamPtr create_stream(size_t nb_blocks, size_t sample_count) { return StreamPtr{impl::check(iio_buffer_create_stream(p, nb_blocks, sample_count), "iio_buffer_create_stream")}; }
506 };
507 
509 
512 class Device : public impl::IndexedSequence<Device, Channel>
513 {
514  iio_device * const p;
515 public:
516 
517  unsigned int size() const
518  {
519  return channels_count();
520  }
521 
522  Channel operator [](unsigned int i)
523  {
524  if (auto maybeCh = channel(i))
525  return *maybeCh;
526 
527  throw std::out_of_range("channel index out of range");
528  }
529 
530 #ifndef DOXYGEN
531  typedef impl::AttrSeqT<iio_device,
532  iio_device_get_attrs_count,
533  iio_device_get_attr,
534  iio_device_find_attr
535  > AttrSeq;
536 #else
538 #endif
539 
540  AttrSeq attrs;
541 
542 #ifndef DOXYGEN
543  typedef impl::AttrSeqT<iio_device,
544  iio_device_get_debug_attrs_count,
545  iio_device_get_debug_attr,
546  iio_device_find_debug_attr
547  > DebugAttrSeq;
548 #else
550 #endif
551 
552  DebugAttrSeq debug_attrs;
553 
554 
555  Device() = delete;
556  Device(iio_device * dev) : p(dev), attrs(dev), debug_attrs(dev) {assert(dev);}
557  operator iio_device * () const {return p;}
558 
559  Context context();
560  cstr id() const { return iio_device_get_id(p);}
561  optstr name() const { return impl::opt(iio_device_get_name(p));}
562  optstr label() const { return impl::opt(iio_device_get_label(p));}
563  unsigned int channels_count() const {return iio_device_get_channels_count(p);}
564  unsigned int attrs_count() const {return iio_device_get_attrs_count(p);}
565  optional<Channel> channel(unsigned int idx) const {return impl::maybe<Channel>(iio_device_get_channel(p, idx));}
566  optional<Attr> attr(unsigned int idx) {return impl::attr<iio_device, iio_device_get_attr>(p, idx);}
567  optional<Channel> find_channel(cstr name, bool output) const {return impl::maybe<Channel>(iio_device_find_channel(p, name, output));}
568  optional<Attr> find_attr(cstr name) {return impl::attr<iio_device, iio_device_find_attr>(p, name);}
569  void set_data(void * data){iio_device_set_data(p, data);}
570  void * data() const {return iio_device_get_data(p);}
571  Device trigger() const {return Device{const_cast<iio_device*>(impl::check(iio_device_get_trigger(p), "iio_device_get_trigger"))};}
572  void set_trigger(iio_device const * trigger) {impl::check(iio_device_set_trigger(p, trigger), "iio_device_set_trigger");}
573  bool is_trigger() const {return iio_device_is_trigger(p);}
574  BufferPtr create_buffer(unsigned int idx, iio_channels_mask * mask) {return BufferPtr(impl::check(iio_device_create_buffer(p, idx, mask), "iio_device_create_buffer"));}
575  bool is_hwmon() const {return iio_device_is_hwmon(p);}
576  EventStreamPtr create_event_stream() { return EventStreamPtr{impl::check(iio_device_create_event_stream(p), "iio_device_create_event_stream")};}
577  ssize_t sample_size(iio_channels_mask * mask) const {return impl::check_n(iio_device_get_sample_size(p, mask), "iio_device_get_sample_size");}
578  unsigned int debug_attrs_count() const {return iio_device_get_debug_attrs_count(p);}
579  optional<Attr> debug_attr(unsigned int idx) {return impl::attr<iio_device, iio_device_get_debug_attr>(p, idx);}
580  optional<Attr> find_debug_attr(cstr name) {return impl::attr<iio_device, iio_device_find_debug_attr>(p, name);}
581  void reg_write(uint32_t address, uint32_t value) {impl::check(iio_device_reg_write(p, address, value), "iio_device_reg_write");}
582  uint32_t reg_read(uint32_t address) {uint32_t value; impl::check(iio_device_reg_read(p, address, &value), "iio_device_reg_read"); return value;}
583 };
584 
586 
589 class Context : public impl::IndexedSequence<Context, Device>
590 {
591  iio_context * const p;
592 public:
593  unsigned int size() const
594  {
595  return devices_count();
596  }
597 
598  Device operator [](unsigned int i)
599  {
600  if (auto maybeDev = device(i))
601  return *maybeDev;
602 
603  throw std::out_of_range("device index out of range");
604  }
605 
606 #ifndef DOXYGEN
607  typedef impl::AttrSeqT<iio_context,
608  iio_context_get_attrs_count,
609  iio_context_get_attr,
610  iio_context_find_attr
611  > AttrSeq;
612 #else
614 #endif
615 
616  AttrSeq attrs;
617 
618 
619  Context() = delete;
620  Context(iio_context * ctx) : p(ctx), attrs(ctx) {assert(ctx);}
621  operator iio_context * () const {return p;}
622 
623  unsigned int version_major() const { return iio_context_get_version_major(p); }
624  unsigned int version_minor() const { return iio_context_get_version_minor(p); }
625  cstr version_tag() const { return iio_context_get_version_tag(p); }
626  CstrPtr xml() const { return CstrPtr{impl::check(iio_context_get_xml(p), "iio_context_get_xml")};}
627  cstr name() const { return iio_context_get_name(p); }
628  cstr description() const { return iio_context_get_description(p); }
629  unsigned int attrs_count() const {return iio_context_get_attrs_count(p);}
630  optional<Attr> attr(unsigned int idx) {return impl::attr<iio_context, iio_context_get_attr>(p, idx);}
631  optional<Attr> find_attr(cstr name) {return impl::attr<iio_context, iio_context_find_attr>(p, name);}
632  unsigned int devices_count() const {return iio_context_get_devices_count(p);}
633  optional<Device> device(unsigned int idx) const { return impl::maybe<Device>(iio_context_get_device(p, idx)); }
634  optional<Device> find_device(cstr name) const {return impl::maybe<Device>(iio_context_find_device(p, name));}
635  void set_timeout(unsigned int timeout_ms){impl::check(iio_context_set_timeout(p, timeout_ms), "iio_context_set_timeout");}
636  iio_context_params const * params() const {return iio_context_get_params(p);}
637  void set_data(void * data){iio_context_set_data(p, data);}
638  void * data() const {return iio_context_get_data(p);}
639 };
640 
642 
643 inline Buffer Block::buffer() {return iio_block_get_buffer(p);}
644 inline Context Device::context(){return const_cast<iio_context*>(iio_device_get_context(p));}
645 inline Device Channel::device() const {return const_cast<iio_device*>(iio_channel_get_device(p));}
646 inline Device Buffer::device() {return const_cast<iio_device*>(iio_buffer_get_device(p));}
647 inline size_t Channel::read(Block block, void * dst, size_t len, bool raw) const {return iio_channel_read(p, block, dst, len, raw);} // Flawfinder: ignore
648 inline size_t Channel::write(Block block, void const * src, size_t len, bool raw) {return iio_channel_write(p, block, src, len, raw);}
649 
652 inline ContextPtr create_context(iio_context_params * params, const char * uri)
653 {
654  return ContextPtr{impl::check(iio_create_context(params, uri), "iio_create_context")};
655 }
656 
657 class Scan;
658 
659 class ScanResult
660 {
661  struct iio_scan const * const p;
662  size_t const idx;
663 
664  friend class Scan;
665 
666  ScanResult(struct iio_scan const * scan, size_t index) : p(scan), idx(index){assert(scan);}
667 public:
668  cstr description() const { return iio_scan_get_description(p, idx);}
669  cstr uri() const { return iio_scan_get_description(p, idx);}
670 };
671 
674 class Scan : public impl::IndexedSequence<Scan, ScanResult>
675 {
676  struct iio_scan const * const p;
677 public:
678  size_t size() const
679  {
680  return results_count();
681  }
682 
683  ScanResult operator [](size_t i)
684  {
685  assert(i < results_count());
686  return ScanResult{p, i};
687  }
688 
689  Scan() = delete;
690  Scan(struct iio_scan const * scan) : p(scan){assert(scan);}
691  operator struct iio_scan const * () const {return p;}
692  size_t results_count() const { return iio_scan_get_results_count(p);}
693 };
694 
696 
697 ScanPtr scan(struct iio_context_params const * params, char const * backends)
698 {
699  return ScanPtr(impl::check(iio_scan(params, backends), "iio_scan"));
700 }
701 
702 
707 inline double value(Channel ch)
708 {
709  if (auto att = ch.find_attr("input"))
710  return att->read_double() / 1000;
711 
712  double scale = 1;
713  if (auto att = ch.find_attr("scale"))
714  scale = att->read_double();
715 
716  double offset = 0;
717  if (auto att = ch.find_attr("offset"))
718  offset = att->read_double();
719 
720  if (auto att = ch.find_attr("raw"))
721  return (att->read_double() + offset) * scale / 1000.;
722 
723  impl::err(ENOENT, "channel does not provide raw value");
724 }
725 
726 } // namespace iiopp
iiopp::impl::IndexedSequence
Serves as base class to implement a vector-like interface.
Definition: iiopp.h:165
iiopp::Event
Event object.
Definition: iiopp.h:448
iiopp::ChannelsMask
C++ wrapper for iio_channels_mask.
Definition: iiopp.h:337
iiopp::Stream
C++ wrapper for the Stream C-API.
Definition: iiopp.h:431
iiopp::Attr
C++ wrapper for the Attributes C-API.
Definition: iiopp.h:209
iiopp::EventStream
C++ wrapper for iio_event_stream.
Definition: iiopp.h:457
iiopp::Buffer
C++ wrapper for the Buffer C-API.
Definition: iiopp.h:474
iiopp::Block
C++ wrapper for the Block C-API.
Definition: iiopp.h:356
iiopp::error
Thrown to report errors.
Definition: iiopp.h:92
iiopp::cstr
Non-owning immutable null terminated string.
Definition: iiopp.h:78
iiopp::impl::AttrSeqT
Vector-like accessor for all attributes of an object.
Definition: iiopp.h:249
iiopp::Context
C++ wrapper for the Context C-API.
Definition: iiopp.h:589
iiopp::Channel
C++ wrapper for the Channel C-API.
Definition: iiopp.h:384
iiopp::impl::AttrSeqT::size
unsigned int size() const
Count of attributes.
Definition: iiopp.h:265
iiopp::Device
C++ wrapper for the Device C-API.
Definition: iiopp.h:512
iiopp::value
double value(Channel ch)
Reads the value of a channel by using "input" or "raw" attribute and applying "scale" and "offset" if...
Definition: iiopp.h:707
iiopp::create_context
ContextPtr create_context(iio_context_params *params, const char *uri)
C++ wrapper for iio_create_context.
Definition: iiopp.h:652
iiopp
Public C++ API.
Definition: iiopp.h:59
iiopp::optstr
optional< cstr > optstr
Optional string, used for C-functions that return nullptr for "no value".
Definition: iiopp.h:100
iiopp::impl::IndexedSequence::Iterator
A random access iterator for an IndexedSequence.
Definition: iiopp.h:172
iiopp::impl::AttrSeqT::operator[]
Attr operator[](unsigned int idx)
Access by attribute index.
Definition: iiopp.h:269
iiopp::Scan
C++ wrapper for the Scan C-API.
Definition: iiopp.h:674
iiopp::Ptr
Special unique pointer for instances that must be destroyed.
Definition: iiopp.h:310