YARP
Yet Another Robot Platform
Vector.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2019 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #ifndef YARP_SIG_VECTOR_H
11 #define YARP_SIG_VECTOR_H
12 
13 #include <cstring>
14 #include <cstddef> //defines size_t
15 #include <memory>
16 #include <string>
17 
18 #include <yarp/os/Portable.h>
19 #include <yarp/os/ManagedBytes.h>
20 #include <yarp/os/Type.h>
21 
22 #include <yarp/sig/api.h>
23 #include <yarp/os/Log.h>
24 
28 namespace yarp {
29 
30  namespace sig {
31  class VectorBase;
32  template<class T> class VectorOf;
33  // Swig(3.0.12) crashes when generating
34  // ruby bindings without these guards.
35  // Bindings for Vector are generated
36  // anyways throught the %template directive
37  // in the interface file.
38 #ifndef SWIG
39  typedef VectorOf<double> Vector;
40 #endif
41  }
42 }
43 
44 
53 {
54 public:
55  virtual size_t getElementSize() const = 0;
56  virtual int getBottleTag() const = 0;
57 
58  virtual size_t getListSize() const = 0;
59  virtual const char *getMemoryBlock() const = 0;
60  virtual char *getMemoryBlock() = 0;
61  virtual void resize(size_t size) = 0;
62 
63  /*
64  * Read vector from a connection.
65  * return true iff a vector was read correctly
66  */
67  bool read(yarp::os::ConnectionReader& connection) override;
68 
73  bool write(yarp::os::ConnectionWriter& connection) const override;
74 
75 protected:
76  virtual std::string getFormatStr(int tag) const;
77 
78 };
79 
80 /*
81 * This is a simple function that maps a type into its corresponding BOTTLE tag.
82 * Used for bottle compatible serialization, called inside getBottleTag().
83 * Needs to be instantiated for each type T used in VectorOf<T>.
84 */
85 template<class T>
86 inline int BottleTagMap () {
87  /* make sure this is never called unspecified */
88  yAssert(0);
89  return 0;
90  }
91 
92 template<>
93 inline int BottleTagMap <double> () {
94  return BOTTLE_TAG_FLOAT64;
95  }
96 
97 template<>
98 inline int BottleTagMap <int> () {
99  return BOTTLE_TAG_INT32;
100  }
101 
118 template<class T>
119 class yarp::sig::VectorOf : public VectorBase
120 {
121 private:
123  T *first;
124  size_t len;
125 
126  inline void _updatePointers() {
127  len = bytes.used()/sizeof(T);
128  if (len==0) {
129  first = nullptr;
130  } else {
131  first = reinterpret_cast<T*>(bytes.get());
132  }
133  }
134 
135 public:
136  typedef T* iterator;
137  typedef const T* const_iterator;
138 
140  bytes.allocate(16*sizeof(T)); // preallocate space for 16 elements
141  bytes.setUsed(0);
142  first = nullptr;
143  len = 0;
144  }
145 
146  VectorOf(size_t size) : bytes(size*sizeof(T)) {
147  bytes.setUsed(size*sizeof(T));
148  _updatePointers();
149  }
150 
155  VectorOf(std::initializer_list<T> values) : bytes(values.size()*sizeof(T))
156  {
157  bytes.setUsed(values.size()*sizeof(T));
158  len = values.size();
159  _updatePointers();
160  std::uninitialized_copy(values.begin(), values.end(), first);
161  }
162 
168  VectorOf(size_t s, const T& def)
169  {
170  this->resize(s,def);
171  }
172 
179  VectorOf(size_t s, const T *p)
180  {
181  len = 0;
182  this->resize(s);
183 
184  memcpy(this->data(), p, sizeof(T)*s);
185  }
186 
188  {
189  bytes = r.bytes;
190  _updatePointers();
191  }
192 
197  {
198 
199  if (this == &r) return *this;
200 
201  if(this->size() == r.size())
202  {
203  memcpy(this->data(), r.data(), sizeof(T)*r.size());
204  }
205  else
206  {
207  bytes = r.bytes;
208  _updatePointers();
209  }
210  return *this;
211  }
212 
213  size_t getElementSize() const override {
214  return sizeof(T);
215  }
216 
217  int getBottleTag() const override {
218  return BottleTagMap <T>();
219  }
220 
221  size_t getListSize() const override
222  {
223  return len;
224  }
225 
226  const char* getMemoryBlock() const override
227  {
228  return bytes.get();
229  }
230 
231  char* getMemoryBlock() override
232  {
233  return bytes.get();
234  }
235 #ifndef YARP_NO_DEPRECATED // since YARP 3.2.0
236  YARP_DEPRECATED_MSG("Use either data() if you need the pointer to the first element,"
237  " or cbegin() if you need the iterator")
238  inline const T *getFirst() const
239  {
240  return first;
241  }
242 
243  YARP_DEPRECATED_MSG("Use either data() if you need the pointer to the first element,"
244  " or begin() if you need the iterator")
245  inline T *getFirst()
246  {
247  return first;
248  }
249 #endif // YARP_NO_DEPRECATED
250 
255  inline T *data()
256  { return first; }
257 
263  inline const T *data() const
264  { return first;}
265 
270  void resize(size_t size) override
271  {
272  size_t prev_len = len;
273  bytes.allocateOnNeed(size*sizeof(T),size*sizeof(T));
274  bytes.setUsed(size*sizeof(T));
275  _updatePointers();
276  for (size_t i = prev_len; i < size; i++) {
277  new (&((*this)[i])) T(); // non-allocating placement operator new
278  }
279  }
280 
286  void resize(size_t size, const T&def)
287  {
288  bytes.allocateOnNeed(size*sizeof(T),size*sizeof(T));
289  bytes.setUsed(size*sizeof(T));
290  _updatePointers();
291  for (size_t i = 0; i < size; i++) {
292  new (&((*this)[i])) T(def); // non-allocating placement operator new
293  }
294  }
295 
301  void reserve(size_t size) {
302  bytes.allocateOnNeed(size*sizeof(T),size*sizeof(T));
303  _updatePointers();
304  }
305 
309  inline void push_back (const T &elem)
310  {
311  bytes.allocateOnNeed(bytes.used()+sizeof(T),bytes.length()*2+sizeof(T));
312  bytes.setUsed(bytes.used()+sizeof(T));
313  _updatePointers();
314  new (&((*this)[len-1])) T(elem); // non-allocating placement operator new
315  }
316 
321  inline void push_back (T&& elem)
322  {
323  this->emplace_back(std::move(elem));
324  }
325 
331  template<typename... _Args>
332  inline T& emplace_back(_Args&&... args)
333  {
334  bytes.allocateOnNeed(bytes.used()+sizeof(T),bytes.length()*2+sizeof(T));
335  bytes.setUsed(bytes.used()+sizeof(T));
336  _updatePointers();
337  new (&((*this)[len-1])) T(std::forward<_Args>(args)...); // non-allocating placement operator new
338  return (*this)[len-1];
339  }
340 
344  inline void pop_back (void)
345  {
346  if (bytes.used()>sizeof(T)) {
347  bytes.setUsed(bytes.used()-sizeof(T));
348  len--;
349  _updatePointers();
350  }
351  }
352 
358  inline T &operator[](size_t i)
359  {
360  return first[i];
361  }
362 
368  inline const T &operator[](size_t i) const
369  {
370  return first[i];
371  }
372 
378  inline T &operator()(size_t i)
379  {
380  return first[i];
381  }
382 
388  inline const T &operator()(size_t i) const
389  {
390  return first[i];
391  }
392 
393  inline size_t size() const {
394  return len;
395  }
396 
401  inline size_t length() const
402  { return this->size();}
403 
408  inline size_t capacity() const {
409  return bytes.length()/sizeof(T);
410  }
411 
415  void zero()
416  {
417  memset(this->data(), 0, sizeof(T)*this->size());
418  }
419 
429  std::string toString(int precision=-1, int width=-1) const
430  {
431  std::string ret = "";
432  size_t c = 0;
433  const size_t buffSize = 256;
434  char tmp[buffSize];
435  std::string formatStr;
436  if (getBottleTag() == BOTTLE_TAG_FLOAT64) {
437  if (width<0) {
438  formatStr = "% .*lf\t";
439  for (c=0;c<length();c++) {
440  snprintf(tmp, buffSize, formatStr.c_str(), precision, (*this)[c]);
441  ret+=tmp;
442  }
443  }
444  else{
445  formatStr = "% *.*lf ";
446  for (c=0;c<length();c++){
447  snprintf(tmp, buffSize, formatStr.c_str(), width, precision, (*this)[c]);
448  ret+=tmp;
449  }
450  }
451  }
452  else {
453  formatStr = "%" + getFormatStr(getBottleTag()) + " ";
454  for (c=0;c<length();c++) {
455  snprintf(tmp, buffSize, formatStr.c_str(), (*this)[c]);
456  ret+=tmp;
457  }
458  }
459 
460  if (length()>=1)
461  return ret.substr(0, ret.length()-1);
462  return ret;
463  }
464 
471  VectorOf<T> subVector(unsigned int first, unsigned int last) const
472  {
474  if ((first<=last)&&((int)last<(int)this->size()))
475  {
476  ret.resize(last-first+1);
477  for (unsigned int k=first; k<=last; k++)
478  ret[k-first]=(*this)[k];
479  }
480  return ret;
481  }
482 
492  bool setSubvector(int position, const VectorOf<T> &v)
493  {
494  if (position+v.size() > this->size())
495  return false;
496  for (size_t i=0;i<v.size();i++)
497  (*this)[position+i] = v(i);
498  return true;
499  }
500 
504  const VectorOf<T> &operator=(T v)
505  {
506  T *tmp = this->data();
507 
508  for(size_t k=0; k<length(); k++)
509  tmp[k]=v;
510 
511  return *this;
512  }
513 
517  bool operator==(const VectorOf<T> &r) const
518  {
519  //check dimensions first
520  size_t c=size();
521  if (c!=r.size())
522  return false;
523 
524  const T *tmp1=data();
525  const T *tmp2=r.data();
526 
527  while(c--)
528  {
529  if (*tmp1++!=*tmp2++)
530  return false;
531  }
532 
533  return true;
534 
535  }
536 
542  iterator begin() noexcept {
543  return first;
544  }
545 
549  iterator end() noexcept {
550  return first + len;
551  }
552 
558  const_iterator cbegin() const noexcept {
559  return first;
560  }
561 
565  const_iterator cend() const noexcept {
566  return first + len;
567  }
568  void clear() {
569  bytes.clear();
570  bytes.setUsed(0);
571  len = 0;
572  first = nullptr;
573  }
574 
575  yarp::os::Type getType() const override {
576  return yarp::os::Type::byName("yarp/vector");
577  }
578 };
579 
580 
581 #ifdef _MSC_VER
582 /*YARP_sig_EXTERN*/ template class YARP_sig_API yarp::sig::VectorOf<double>;
583 #endif
584 
585 #endif // YARP_SIG_VECTOR_H
VectorOf(size_t s, const T &def)
Build a vector and initialize it with def.
Definition: Vector.h:168
const T & operator[](size_t i) const
Single element access, no range check, const version.
Definition: Vector.h:368
bool write(const ImageOf< PixelRgb > &src, const std::string &dest, image_fileformat format=FORMAT_PPM)
Definition: ImageFile.cpp:553
void push_back(T &&elem)
Move a new element in the vector: size is changed.
Definition: Vector.h:321
bool setSubvector(int position, const VectorOf< T > &v)
Set a portion of this vector with the values of the specified vector.
Definition: Vector.h:492
VectorOf< double > Vector
Definition: Vector.h:32
const T * const_iterator
Definition: Vector.h:137
#define BOTTLE_TAG_INT32
Definition: Bottle.h:23
bool read(ImageOf< PixelRgb > &dest, const std::string &src, image_fileformat format=FORMAT_ANY)
Definition: ImageFile.cpp:516
char * getMemoryBlock() override
Definition: Vector.h:231
const char * getMemoryBlock() const override
Definition: Vector.h:226
bool ret
const VectorOf< T > & operator=(T v)
Set all elements of the vector to a scalar.
Definition: Vector.h:504
T & operator()(size_t i)
Single element access, no range check.
Definition: Vector.h:378
int getBottleTag() const override
Definition: Vector.h:217
This is a base class for objects that can be both read from and be written to the YARP network...
Definition: Portable.h:28
static Type byName(const char *name)
Definition: Type.cpp:174
void resize(size_t size) override
Resize the vector.
Definition: Vector.h:270
int BottleTagMap< double >()
Definition: Vector.h:93
size_t setUsed(size_t used)
explicitly declare how many of the bytes are in use.
void resize(size_t size, const T &def)
Resize the vector and initilize the element to a default value.
Definition: Vector.h:286
Provides:
Definition: Vector.h:32
The main, catch-all namespace for YARP.
Definition: numeric.h:47
int BottleTagMap< int >()
Definition: Vector.h:98
VectorOf(size_t s, const T *p)
Builds a vector and initialize it with values from &#39;p&#39;.
Definition: Vector.h:179
T & emplace_back(_Args &&... args)
Construct a new element in the vector: size is changed.
Definition: Vector.h:332
const T & operator()(size_t i) const
Single element access, no range check, const version.
Definition: Vector.h:388
size_t getListSize() const override
Definition: Vector.h:221
size_t capacity() const
capacity
Definition: Vector.h:408
size_t length() const
Get the length of the vector.
Definition: Vector.h:401
#define YARP_sig_API
Definition: api.h:19
iterator end() noexcept
Returns an iterator to the end of the VectorOf.
Definition: Vector.h:549
An interface for writing to a network connection.
const_iterator cend() const noexcept
Returns a const iterator to the end of the VectorOf.
Definition: Vector.h:565
VectorOf(size_t size)
Definition: Vector.h:146
T * data()
Return a pointer to the first element of the vector.
Definition: Vector.h:255
void zero()
Zero the elements of the vector.
Definition: Vector.h:415
int BottleTagMap()
Definition: Vector.h:86
void pop_back(void)
Pop an element out of the vector: size is changed.
Definition: Vector.h:344
#define BOTTLE_TAG_FLOAT64
Definition: Bottle.h:27
VectorOf(const VectorOf &r)
Definition: Vector.h:187
#define yAssert(x)
Definition: Log.h:112
void allocate(size_t len)
Makes a data block of the specified length that will be deleted if this object is destroyed...
An interface for reading from a network connection.
bool operator==(const VectorOf< T > &r) const
True iff all elements of &#39;a&#39; match all element of &#39;b&#39;.
Definition: Vector.h:517
T & operator[](size_t i)
Single element access, no range check.
Definition: Vector.h:358
VectorOf< T > subVector(unsigned int first, unsigned int last) const
Creates and returns a new vector, being the portion of the original vector defined by the first and l...
Definition: Vector.h:471
size_t getElementSize() const override
Definition: Vector.h:213
yarp::os::Type getType() const override
Definition: Vector.h:575
const VectorOf< T > & operator=(const VectorOf< T > &r)
Copy operator;.
Definition: Vector.h:196
const T * data() const
Return a pointer to the first element of the vector, const version.
Definition: Vector.h:263
const char * get() const
size_t size() const
Definition: Vector.h:393
iterator begin() noexcept
Returns an iterator to the beginning of the VectorOf.
Definition: Vector.h:542
void reserve(size_t size)
reserve, increase the capacity of the vector to a value that&#39;s greater or equal to size...
Definition: Vector.h:301
void push_back(const T &elem)
Push a new element in the vector: size is changed.
Definition: Vector.h:309
An abstraction for a block of bytes, with optional responsibility for allocating/destroying that bloc...
Definition: ManagedBytes.h:24
std::string toString(int precision=-1, int width=-1) const
Creates a string object containing a text representation of the object.
Definition: Vector.h:429
VectorOf(std::initializer_list< T > values)
Initializer list constructor.
Definition: Vector.h:155
A Base class for a VectorOf<T>, provide default implementation for read/write methods.
Definition: Vector.h:52
const_iterator cbegin() const noexcept
Returns a const iterator to the beginning of the VectorOf.
Definition: Vector.h:558
#define YARP_DEPRECATED_MSG(MSG)
Expands to either the standard [[deprecated]] attribute or a compiler-specific decorator such as __at...
Definition: compiler.h:2852