Colibri Core
datatypes.h
Go to the documentation of this file.
1 #ifndef COLIBRIDATATYPES_H
2 #define COLIBRIDATATYPES_H
3 
4 #include <string>
5 #include <iostream>
6 #include <ostream>
7 #include <istream>
8 #include <vector>
9 #include <set>
10 #include <algorithm>
11 #include "common.h"
12 #include "pattern.h"
13 #include "datatypes.h"
14 #include "classdecoder.h"
15 
34  public:
35  uint32_t sentence;
36  uint16_t token;
37  IndexReference() { sentence=0; token = 0; }
38 
42  IndexReference(uint32_t sentence, uint16_t token ) { this->sentence = sentence; this->token = token; }
43 
44  IndexReference(std::istream * in) {
45  in->read( (char*) &sentence, sizeof(uint32_t));
46  in->read( (char*) &token, sizeof(uint16_t));
47  }
48  IndexReference(const IndexReference& other) { //copy constructor
49  sentence = other.sentence;
50  token = other.token;
51  };
52  void write(std::ostream * out) const {
53  out->write( (char*) &sentence, sizeof(uint32_t));
54  out->write( (char*) &token, sizeof(uint16_t));
55  }
56  bool operator< (const IndexReference& other) const {
57  if (sentence < other.sentence) {
58  return true;
59  } else if (sentence == other.sentence) {
60  return (token < other.token);
61  } else {
62  return false;
63  }
64  }
65  bool operator> (const IndexReference& other) const {
66  return other < *this;
67  }
68  bool operator==(const IndexReference &other) const { return ( (sentence == other.sentence) && (token == other.token)); };
69  bool operator!=(const IndexReference &other) const { return ( (sentence != other.sentence) || (token != other.token)); };
70  IndexReference operator+(const int other) const { return IndexReference(sentence, token+ other); };
71 
72  std::string tostring() const {
73  return std::to_string((unsigned int) sentence) + ":" + std::to_string((unsigned int) token);
74  }
75 
76  friend std::ostream& operator<<(std::ostream & out, const IndexReference & iref) {
77  out << iref.tostring();
78  return out;
79  }
80 };
81 
86 class IndexedData {
87  public:
88  std::vector<IndexReference> data;
89  IndexedData() { };
90  IndexedData(std::istream * in);
91  void write(std::ostream * out) const;
92 
93  bool has(const IndexReference & ref, bool sorted = false) const {
94  if (sorted) {
95  return std::binary_search(this->begin(), this->end(), ref);
96  } else {
97  return std::find(this->begin(), this->end(), ref) != this->end();
98  }
99  }
100 
104  unsigned int count() const { return data.size(); }
105 
106  void insert(IndexReference ref) { data.push_back(ref); }
107  size_t size() const { return data.size(); }
108 
109  typedef std::vector<IndexReference>::iterator iterator;
110  typedef std::vector<IndexReference>::const_iterator const_iterator;
111 
112  iterator begin() { return data.begin(); }
113  const_iterator begin() const { return data.begin(); }
114 
115  iterator end() { return data.end(); }
116  const_iterator end() const { return data.end(); }
117 
118  iterator find(const IndexReference & ref) { return std::find(this->begin(), this->end(), ref); }
119  const_iterator find(const IndexReference & ref) const { return std::find(this->begin(), this->end(), ref); }
120 
124  std::set<int> sentences() const {
125  std::set<int> sentences;
126  for (const_iterator iter = this->begin(); iter != this->end(); iter++) {
127  const IndexReference ref = *iter;
128  sentences.insert(ref.sentence);
129  }
130  return sentences;
131  }
132 
136  std::set<IndexReference> set() const {
137  return std::set<IndexReference>(this->begin(), this->end() );
138  }
139 
143  void sort() {
144  std::sort(this->begin(), this->end());
145  }
146 
147  void reserve(size_t size) {
148  data.reserve(size);
149  }
150  void shrink_to_fit() {
151  data.shrink_to_fit();
152  }
153 
154 };
155 
156 /************* ValueHandler for reading/serialising basic types ********************/
157 
158 
167 template<class ValueType>
169  public:
170  virtual std::string id() { return "AbstractValueHandler"; }
171  virtual void read(std::istream * in, ValueType & value)=0; //read value from input stream (binary)
172  virtual void write(std::ostream * out, ValueType & value)=0; //write value to output stream (binary)
173  virtual std::string tostring(ValueType & value)=0; //convert value to string)
174  virtual unsigned int count(ValueType & value) const =0; //what count does this value represent?
175  virtual void add(ValueType * value, const IndexReference & ref ) const=0; //add the indexreference to the value, will be called whenever a token is found during pattern building
176 
177  virtual void convertto(ValueType * source, ValueType* & target ) const { target = source; }; //this doesn't really convert as source and target are same type, but it is required!
178 };
179 
184 template<class ValueType>
185 class BaseValueHandler: public AbstractValueHandler<ValueType> {
186  public:
187  virtual std::string id() { return "BaseValueHandler"; }
188  const static bool indexed = false;
189  void read(std::istream * in, ValueType & v) {
190  in->read( (char*) &v, sizeof(ValueType));
191  }
192  void write(std::ostream * out, ValueType & value) {
193  out->write( (char*) &value, sizeof(ValueType));
194  }
195  virtual std::string tostring(ValueType & value) {
196  return tostring(value);
197  }
198  unsigned int count(ValueType & value) const {
199  return (unsigned int) value;
200  }
201  void add(ValueType * value, const IndexReference & ref ) const {
202  *value = *value + 1;
203  }
204 
205  void convertto(ValueType * source, ValueType* & target ) const { target = source; }; //this doesn't really convert as source and target are same type, but it is required!
206 
207  void convertto(ValueType * source, IndexedData* & target ) const { target = new IndexedData(); }; //this doesn't convert either, it returns a totally EMPTY indexeddata, allowing unindexed models to be read as indexed, but losing all counts!
208 };
209 
210 
211 /************* ValueHandler for reading/serialising indexed types ********************/
212 
213 
218 class IndexedDataHandler: public AbstractValueHandler<IndexedData> {
219  public:
220  const static bool indexed = true;
221  virtual std::string id() { return "IndexedDataHandler"; }
222  void read(std::istream * in, IndexedData & v) {
223  uint32_t c;
224  in->read((char*) &c, sizeof(uint32_t));
225  v.reserve(c); //reserve space to optimise
226  for (unsigned int i = 0; i < c; i++) {
227  IndexReference ref = IndexReference(in);
228  v.insert(ref);
229  }
230  v.shrink_to_fit(); //try to keep vector as small as possible (slows insertions down a bit)
231  }
232  void write(std::ostream * out, IndexedData & value) {
233  const uint32_t c = value.count();
234  out->write((char*) &c, sizeof(uint32_t));
235  //we already assume everything is nicely sorted!
236  for (IndexedData::iterator iter = value.data.begin(); iter != value.data.end(); iter++) {
237  iter->write(out);
238  }
239  }
240  virtual std::string tostring(IndexedData & value) {
241  std::string s = "";
242  for (IndexedData::iterator iter = value.data.begin(); iter != value.data.end(); iter++) {
243  if (!s.empty()) s += " ";
244  s += iter->tostring();
245  }
246  return s;
247  }
248  unsigned int count(IndexedData & value) const {
249  return value.data.size();
250  }
251  void add(IndexedData * value, const IndexReference & ref ) const {
252  if (value == NULL) {
253  std::cerr << "ValueHandler: Value is NULL!" << std::endl;
254  throw InternalError();
255  }
256  value->insert(ref);
257  }
258  void convertto(IndexedData * source , IndexedData *& target) const { target = source; }; //noop
259  void convertto(IndexedData * value, unsigned int * & convertedvalue) const { convertedvalue = new unsigned int; *convertedvalue = value->count(); };
260 };
261 
262 
263 
264 
265 
266 
267 
268 
269 template<class FeatureType>
271  public:
273  std::vector<FeatureType> data;
274 
276  virtual ~PatternFeatureVector() {};
277  PatternFeatureVector(const Pattern & ref) { pattern = ref; }
278 
279  PatternFeatureVector(const Pattern & ref, const std::vector<FeatureType> & dataref) {
280  pattern = ref;
281  data = dataref;
282  }
283 
284  //copy constructor
286  pattern = ref.pattern;
287  data = ref.data;
288  };
289  PatternFeatureVector(std::istream * in) {
290  read(in);
291  }
292 
293 
294  void read(std::istream * in) {
295  this->pattern = Pattern(in);
296  uint16_t c;
297  in->read((char*) &c, sizeof(uint16_t));
298  data.reserve(c);
299  for (unsigned int i = 0; i < c; i++) {
300  FeatureType f;
301  in->read((char*) &f, sizeof(FeatureType));
302  data.push_back(f);
303  }
304  data.shrink_to_fit();
305  }
306  void write(std::ostream * out) {
307  this->pattern.write(out);
308  unsigned int s = data.size();
309  if (s >= 65536) {
310  std::cerr << "ERROR: PatternFeatureVector size exceeds maximum 16-bit capacity!! Not writing arbitrary parts!!! Set thresholds to prevent this!" << std::endl;
311  s = 65536;
312  }
313  uint16_t c = (uint16_t) s;
314  out->write((char*) &c , sizeof(uint16_t));
315  for (unsigned int i = 0; i < s; i++) {
316  FeatureType f = data[i];
317  out->write((char*) &f, sizeof(FeatureType));
318  }
319  }
320 
321  typedef typename std::vector<FeatureType>::iterator iterator;
322  typedef typename std::vector<FeatureType>::const_iterator const_iterator;
323 
324  size_t size() const { return data.size(); }
325 
328 
331 
332  FeatureType get(int index) {
333  return data[index];
334  }
335 
336  void clear() {
337  data.clear();
338  }
339  void push_back(FeatureType & f) {
340  data.push_back(f);
341  }
342  void reserve(size_t size) {
343  data.reserve(size);
344  }
345  void shrink_to_fit() {
346  data.shrink_to_fit();
347  }
348 
349 };
350 
351 template<class FeatureType>
352 class PatternFeatureVectorMap { //acts like a (small) map (but implemented as a vector to save memory), for 2nd-order use (i.e, within another map)
353  public:
354 
355 
356  std::vector<PatternFeatureVector<FeatureType> *> data;
357 
358  typedef typename std::vector<PatternFeatureVector<FeatureType>*>::const_iterator const_iterator;
359  typedef typename std::vector<PatternFeatureVector<FeatureType>*>::iterator iterator;
360 
362 
364  for (const_iterator iter = ref.begin(); iter != ref.end(); iter++) {
365  //make a copy
366  const PatternFeatureVector<FeatureType> * pfv_ref = *iter;
368  this->data.push_back(pfv);
369  }
370  }
371 
372 
373  /* get double free or corruption error: //TODO: possible memory
374  * leak?? */
376  /*
377  const size_t s = this->data.size();
378  for (int i = 0; i < s; i++) {
379  PatternFeatureVector<FeatureType> * pfv = this->data[i];
380  delete pfv;
381  data[i] = NULL;
382  }*/
383  }
384 
385  bool has(const Pattern & ref) const {
386  for (const_iterator iter = this->begin(); iter != this->end(); iter++) {
387  const PatternFeatureVector<FeatureType> * pfv = *iter;
388  if (pfv->pattern == ref) {
389  return true;
390  }
391  }
392  return false;
393  }
394 
395 
396  iterator find(const Pattern & ref) {
397  for (iterator iter = this->begin(); iter != this->end(); iter++) {
398  const PatternFeatureVector<FeatureType> * pfv = *iter;
399  if (pfv->pattern == ref) {
400  return iter;
401  }
402  }
403  return this->end();
404  }
405 
406  unsigned int count() const { return data.size(); }
407 
408 
409 
410  void insert(PatternFeatureVector<FeatureType> * pfv, bool checkexists=true) {
411  //inserts pointer directly, makes no copy!!
412  if (checkexists) {
413  iterator found = this->find(pfv->pattern);
414  if (found != this->end()) {
415  const PatternFeatureVector<FeatureType> * old = *found;
416  delete old;
417  *found = pfv;
418  } else {
419  this->data.push_back(pfv);
420  }
421  } else {
422  this->data.push_back(pfv);
423  }
424  }
425 
426  void insert(PatternFeatureVector<FeatureType> & value, bool checkexists=true) {
427  //make a copy, safer
429  if (checkexists) {
430  iterator found = this->find(value.pattern);
431  if (found != this->end()) {
432  const PatternFeatureVector<FeatureType> * old = *found;
433  delete old;
434  *found = pfv;
435  } else {
436  this->data.push_back(pfv);
437  }
438  } else {
439  this->data.push_back(pfv);
440  }
441  }
442 
443  size_t size() const { return data.size(); }
444 
445  virtual std::string tostring() {
446  //we have no classdecoder at this point
447  std::cerr << "ERROR: PatternFeatureVector does not support serialisation to string" << std::endl;
448  throw InternalError();
449  }
450 
451  iterator begin() { return data.begin(); }
452  const_iterator begin() const { return data.begin(); }
453 
454  iterator end() { return data.end(); }
455  const_iterator end() const { return data.end(); }
456 
457  virtual PatternFeatureVector<FeatureType> * getdata(const Pattern & pattern) {
458  iterator iter = this->find(pattern);
459  if (iter != this->end()) {
460  PatternFeatureVector<FeatureType> * pfv = *iter;
461  return pfv;
462  }
463  return NULL;
464  }
465 
466  void reserve(size_t size) {
467  data.reserve(size);
468  }
469  void shrink_to_fit() {
470  data.shrink_to_fit();
471  }
472 
473 
474 };
475 
476 template<class FeatureType>
477 class PatternFeatureVectorMapHandler: public AbstractValueHandler<PatternFeatureVectorMap<FeatureType>> {
478  public:
479  virtual std::string id() { return "PatternFeatureVectorMapHandler"; }
480  void read(std::istream * in, PatternFeatureVectorMap<FeatureType> & v) {
481  uint16_t c;
482  in->read((char*) &c, sizeof(uint16_t));
483  v.reserve(c); //reserve space to optimise
484  for (unsigned int i = 0; i < c; i++) {
486  v.insert(ref, false); //checkifexists=false, to speed things up when loading, assuming data is sane
487  }
488  v.shrink_to_fit(); //try to keep vector as small as possible (slows additional insertions down a bit)
489 
490  }
491  void write(std::ostream * out, PatternFeatureVectorMap<FeatureType> & value) {
492  unsigned int s = value.size();
493  if (s >= 65536) {
494  std::cerr << "ERROR: PatternFeatureVector size exceeds maximum 16-bit capacity!! Not writing arbitrary parts!!! Set thresholds to prevent this!" << std::endl;
495  s = 65535;
496  }
497  const uint16_t c = (uint16_t) s;
498  out->write((char*) &c, sizeof(uint16_t));
499  unsigned int n = 0;
500  for (typename PatternFeatureVectorMap<FeatureType>::iterator iter = value.begin(); iter != value.end(); iter++) {
501  if (n==s) break;
502  PatternFeatureVector<FeatureType> * pfv = *iter;
503  pfv->write(out);
504  n++;
505  }
506  }
507  virtual std::string tostring(PatternFeatureVectorMap<FeatureType> & value) {
508  std::cerr << "ERROR: PatternFeatureVectorMapHandler does not support serialisation to string (no classdecoder at this point)" << std::endl;
509  throw InternalError();
510  }
511  unsigned int count(PatternFeatureVectorMap<FeatureType> & value) const {
512  return value.size();
513  }
514  void add(PatternFeatureVectorMap<FeatureType> * value, const IndexReference & ref ) const {
515  std::cerr << "ERROR: PatternFeatureVectorMapHandler does not support insertion of index references, model can not be computed with train()" << std::endl;
516  throw InternalError();
517  }
518  void convertto(PatternFeatureVectorMap<FeatureType> * source , PatternFeatureVectorMap<FeatureType> * & target) const { target = source; }; //noop
519  void convertto(PatternFeatureVectorMap<FeatureType> * source , IndexedData * & target) const { }; //not possible, noop (target = NULL)
520  void convertto(PatternFeatureVectorMap<FeatureType> * value, unsigned int * & convertedvalue) const { convertedvalue = new unsigned int; *convertedvalue = value->count(); };
521 };
522 
523 #endif
bool operator!=(const IndexReference &other) const
Definition: datatypes.h:69
PatternFeatureVector(const Pattern &ref, const std::vector< FeatureType > &dataref)
Definition: datatypes.h:279
virtual std::string id()
Definition: datatypes.h:170
void write(std::ostream *out, ValueType &value)
Definition: datatypes.h:192
virtual unsigned int count(ValueType &value) const =0
const_iterator begin() const
Definition: datatypes.h:113
PatternFeatureVector(const PatternFeatureVector &ref)
Definition: datatypes.h:285
void write(std::ostream *out) const
IndexReference(const IndexReference &other)
Definition: datatypes.h:48
void convertto(ValueType *source, IndexedData *&target) const
Definition: datatypes.h:207
const_iterator end() const
Definition: datatypes.h:116
Definition: datatypes.h:477
static const bool indexed
Definition: datatypes.h:188
unsigned int count() const
Definition: datatypes.h:406
This templated class can be used for all numeric base types (such as int, uint16_t, float, etc).
Definition: datatypes.h:185
virtual std::string id()
Definition: datatypes.h:221
iterator find(const IndexReference &ref)
Definition: datatypes.h:118
PatternFeatureVector< FeatureType >::iterator begin()
Definition: datatypes.h:326
void push_back(FeatureType &f)
Definition: datatypes.h:339
PatternFeatureVector(const Pattern &ref)
Definition: datatypes.h:277
void reserve(size_t size)
Definition: datatypes.h:466
PatternFeatureVector< FeatureType >::const_iterator begin() const
Definition: datatypes.h:327
std::vector< IndexReference >::iterator iterator
Definition: datatypes.h:109
Classes for data types and handlers for those data types.
Pattern class, represents a pattern (ngram, skipgram or flexgram). Encoded in a memory-saving fashion...
Definition: pattern.h:75
friend std::ostream & operator<<(std::ostream &out, const IndexReference &iref)
Definition: datatypes.h:76
bool operator>(const IndexReference &other) const
Definition: datatypes.h:65
void reserve(size_t size)
Definition: datatypes.h:342
std::vector< PatternFeatureVector< FeatureType > * >::iterator iterator
Definition: datatypes.h:359
std::vector< PatternFeatureVector< FeatureType > * >::const_iterator const_iterator
Definition: datatypes.h:358
Abstract value handler class, all value handlers are derived from this. Value handlers are interfaces...
Definition: datatypes.h:168
virtual std::string id()
Definition: datatypes.h:479
void add(PatternFeatureVectorMap< FeatureType > *value, const IndexReference &ref) const
Definition: datatypes.h:514
const_iterator end() const
Definition: datatypes.h:455
bool has(const IndexReference &ref, bool sorted=false) const
Definition: datatypes.h:93
void reserve(size_t size)
Definition: datatypes.h:147
virtual void read(std::istream *in, ValueType &value)=0
void write(std::ostream *out, IndexedData &value)
Definition: datatypes.h:232
void read(std::istream *in, ValueType &v)
Definition: datatypes.h:189
IndexReference(std::istream *in)
Definition: datatypes.h:44
void write(std::ostream *out, PatternFeatureVectorMap< FeatureType > &value)
Definition: datatypes.h:491
PatternFeatureVector()
Definition: datatypes.h:275
IndexReference()
Definition: datatypes.h:37
virtual void convertto(ValueType *source, ValueType *&target) const
Definition: datatypes.h:177
const_iterator find(const IndexReference &ref) const
Definition: datatypes.h:119
std::vector< PatternFeatureVector< FeatureType > * > data
Definition: datatypes.h:356
Reference to a position in the corpus.
Definition: datatypes.h:33
iterator find(const Pattern &ref)
Definition: datatypes.h:396
unsigned int count(IndexedData &value) const
Definition: datatypes.h:248
void sort()
Definition: datatypes.h:143
IndexedData()
Definition: datatypes.h:89
virtual std::string tostring(PatternFeatureVectorMap< FeatureType > &value)
Definition: datatypes.h:507
const_iterator begin() const
Definition: datatypes.h:452
unsigned int count(PatternFeatureVectorMap< FeatureType > &value) const
Definition: datatypes.h:511
unsigned int count() const
Definition: datatypes.h:104
void convertto(PatternFeatureVectorMap< FeatureType > *value, unsigned int *&convertedvalue) const
Definition: datatypes.h:520
iterator end()
Definition: datatypes.h:115
virtual std::string tostring(ValueType &value)
Definition: datatypes.h:195
Pattern pattern
Definition: datatypes.h:272
virtual ~PatternFeatureVector()
Definition: datatypes.h:276
void write(std::ostream *out) const
Definition: datatypes.h:52
void convertto(IndexedData *source, IndexedData *&target) const
Definition: datatypes.h:258
virtual void write(std::ostream *out, ValueType &value)=0
void read(std::istream *in, IndexedData &v)
Definition: datatypes.h:222
void insert(PatternFeatureVector< FeatureType > *pfv, bool checkexists=true)
Definition: datatypes.h:410
std::vector< FeatureType >::iterator iterator
Definition: datatypes.h:321
virtual std::string id()
Definition: datatypes.h:187
size_t size() const
Definition: datatypes.h:107
void shrink_to_fit()
Definition: datatypes.h:469
void convertto(ValueType *source, ValueType *&target) const
Definition: datatypes.h:205
std::set< int > sentences() const
Definition: datatypes.h:124
void read(std::istream *in, PatternFeatureVectorMap< FeatureType > &v)
Definition: datatypes.h:480
uint16_t token
Definition: datatypes.h:36
std::vector< FeatureType > data
Definition: datatypes.h:273
static const bool indexed
Definition: datatypes.h:220
void read(std::istream *in)
Definition: datatypes.h:294
void insert(IndexReference ref)
Definition: datatypes.h:106
void add(IndexedData *value, const IndexReference &ref) const
Definition: datatypes.h:251
void add(ValueType *value, const IndexReference &ref) const
Definition: datatypes.h:201
Collection of references to position in the corpus (IndexReference). Used by Indexed Pattern models...
Definition: datatypes.h:86
Data handler for IndexedData. Deals with serialisation from/to file and conversions.
Definition: datatypes.h:218
void insert(PatternFeatureVector< FeatureType > &value, bool checkexists=true)
Definition: datatypes.h:426
size_t size() const
Definition: datatypes.h:443
std::vector< FeatureType >::const_iterator const_iterator
Definition: datatypes.h:322
void write(std::ostream *out, const unsigned char *corpusstart=NULL) const
Definition: pattern.cpp:228
PatternFeatureVector(std::istream *in)
Definition: datatypes.h:289
iterator end()
Definition: datatypes.h:454
size_t size() const
Definition: datatypes.h:324
std::vector< IndexReference >::const_iterator const_iterator
Definition: datatypes.h:110
std::set< IndexReference > set() const
Definition: datatypes.h:136
void convertto(PatternFeatureVectorMap< FeatureType > *source, IndexedData *&target) const
Definition: datatypes.h:519
Definition: common.h:35
bool has(const Pattern &ref) const
Definition: datatypes.h:385
Basic largely trivial functions for the common good.
std::vector< IndexReference > data
Definition: datatypes.h:88
virtual std::string tostring(ValueType &value)=0
IndexReference(uint32_t sentence, uint16_t token)
Definition: datatypes.h:42
void convertto(IndexedData *value, unsigned int *&convertedvalue) const
Definition: datatypes.h:259
PatternFeatureVector< FeatureType >::iterator end()
Definition: datatypes.h:329
bool operator==(const IndexReference &other) const
Definition: datatypes.h:68
void clear()
Definition: datatypes.h:336
Definition: datatypes.h:270
void shrink_to_fit()
Definition: datatypes.h:345
iterator begin()
Definition: datatypes.h:451
virtual std::string tostring()
Definition: datatypes.h:445
unsigned int count(ValueType &value) const
Definition: datatypes.h:198
Contains the Pattern class that is ubiquitous throughout Colibri Core.
Class for decoding binary class-encoded data back to plain-text.
iterator begin()
Definition: datatypes.h:112
IndexReference operator+(const int other) const
Definition: datatypes.h:70
void shrink_to_fit()
Definition: datatypes.h:150
uint32_t sentence
Definition: datatypes.h:35
Definition: datatypes.h:352
bool operator<(const IndexReference &other) const
Definition: datatypes.h:56
void convertto(PatternFeatureVectorMap< FeatureType > *source, PatternFeatureVectorMap< FeatureType > *&target) const
Definition: datatypes.h:518
PatternFeatureVector< FeatureType >::const_iterator end() const
Definition: datatypes.h:330
virtual PatternFeatureVector< FeatureType > * getdata(const Pattern &pattern)
Definition: datatypes.h:457
virtual void add(ValueType *value, const IndexReference &ref) const =0
std::string tostring() const
Definition: datatypes.h:72
void write(std::ostream *out)
Definition: datatypes.h:306
virtual std::string tostring(IndexedData &value)
Definition: datatypes.h:240