SDSL  3.0.0
Succinct Data Structure Library
io.hpp
Go to the documentation of this file.
1 // Copyright (c) 2016, the SDSL Project Authors. All rights reserved.
2 // Please see the AUTHORS file for details. Use of this source code is governed
3 // by a BSD license that can be found in the LICENSE file.
8 #ifndef INCLUDED_SDSL_IO
9 #define INCLUDED_SDSL_IO
10 
11 #include <algorithm>
12 #include <cctype>
13 #include <iostream>
14 #include <string>
15 #include <vector>
16 
17 #include <sdsl/cereal.hpp>
18 #include <sdsl/platform.hpp>
19 #include <sdsl/sdsl_concepts.hpp>
20 #include <sdsl/structure_tree.hpp>
21 #include <sdsl/util.hpp>
22 
23 namespace sdsl
24 {
25 
26 int remove(const std::string &);
27 
28 template <typename T>
29 void load_vector(std::vector<T> &, std::istream &);
30 
31 template <typename T>
32 uint64_t serialize_vector(const std::vector<T> &,
33  std::ostream &,
34  sdsl::structure_tree_node * v = nullptr,
35  std::string = "");
36 
37 // has_serialize<X>::value is true if class X has
38 // implement method serialize
39 // Adapted solution from jrok's proposal:
40 // http://stackoverflow.com/questions/87372/check-if-a-class-has-a-member-function-of-a-given-signature
41 template <typename X>
43 {
44  template <typename T>
45  static constexpr auto
46  check(T *) -> typename std::is_same<decltype(std::declval<T>().serialize(std::declval<std::ostream &>(),
47  std::declval<structure_tree_node *>(),
48  std::declval<std::string>())),
49  typename T::size_type>::type
50  {
51  return std::true_type();
52  }
53  template <typename>
54  static constexpr std::false_type check(...)
55  {
56  return std::false_type();
57  }
58  typedef decltype(check<X>(nullptr)) type;
59  static constexpr bool value = type::value;
60 };
61 
62 // has_load<X>::value is true if class X has
63 // implement method load
64 template <typename X>
65 struct has_load
66 {
67  template <typename T>
68  static constexpr auto
69  check(T *) -> typename std::is_same<decltype(std::declval<T>().load(std::declval<std::istream &>())), void>::type
70  {
71  return std::true_type();
72  }
73  template <typename>
74  static constexpr std::false_type check(...)
75  {
76  return std::false_type();
77  }
78  typedef decltype(check<X>(nullptr)) type;
79  static constexpr bool value = type::value;
80 };
81 
82 // Writes primitive-typed variable t to stream out
83 template <typename T>
84 size_t write_member(const T & t, std::ostream & out, sdsl::structure_tree_node * v = nullptr, std::string name = "")
85 {
86  sdsl::structure_tree_node * child = sdsl::structure_tree::add_child(v, name, util::class_name(t));
87  out.write((char *)&t, sizeof(t));
88  size_t written_bytes = sizeof(t);
89  sdsl::structure_tree::add_size(child, written_bytes);
90  return written_bytes;
91 }
92 
93 // Specialization for std::string
94 template <>
95 inline size_t write_member<std::string>(const std::string & t,
96  std::ostream & out,
98  std::string name)
99 {
100  structure_tree_node * child = structure_tree::add_child(v, name, util::class_name(t));
101  size_t written_bytes = 0;
102  written_bytes += write_member(t.size(), out, child, "length");
103  out.write(t.c_str(), t.size());
104  written_bytes += t.size();
105  structure_tree::add_size(v, written_bytes);
106  return written_bytes;
107 }
108 
109 // Writes primitive-typed variable t to stream out
110 template <typename T>
111 void read_member(T & t, std::istream & in)
112 {
113  in.read((char *)&t, sizeof(t));
114 }
115 
116 // Specialization for std::string
117 template <>
118 inline void read_member<std::string>(std::string & t, std::istream & in)
119 {
121  read_member(size, in);
122  char * buf = new char[size];
123  in.read(buf, size);
124  std::string temp(buf, size);
125  delete[] buf;
126  t = std::move(temp);
127 }
128 
129 template <typename X>
130 typename std::enable_if<has_serialize<X>::value, typename X::size_type>::type
131 serialize(const X & x, std::ostream & out, structure_tree_node * v = nullptr, std::string name = "")
132 {
133  return x.serialize(out, v, name);
134 }
135 
136 template <typename X>
137 typename std::enable_if<std::is_standard_layout<X>::value && std::is_trivial<X>::value, uint64_t>::type
138 serialize(const X & x, std::ostream & out, structure_tree_node * v = nullptr, std::string name = "")
139 {
140  return write_member(x, out, v, name);
141 }
142 
143 template <typename X>
144 uint64_t serialize(const std::vector<X> & x,
145  std::ostream & out,
146  structure_tree_node * v = nullptr,
147  std::string name = "")
148 {
149 
150  return serialize(x.size(), out, v, name) + serialize_vector(x, out, v, name);
151 }
152 
153 template <typename X>
154 typename std::enable_if<has_load<X>::value, void>::type load(X & x, std::istream & in)
155 {
156  x.load(in);
157 }
158 
159 template <typename X>
160 typename std::enable_if<std::is_standard_layout<X>::value && std::is_trivial<X>::value, void>::type load(
161  X & x,
162  std::istream & in)
163 {
164  read_member(x, in);
165 }
166 
167 template <typename X>
168 void load(std::vector<X> & x, std::istream & in)
169 {
171  load(size, in);
172  x.resize(size);
173  load_vector(x, in);
174 }
175 
177 
181 template <typename T>
182 bool load_from_file(T & v, const std::string & file);
183 
185 // TODO: Remove ENDIAN dependency.
186 template <typename t_int_vec>
187 bool load_vector_from_file(t_int_vec & v, const std::string & file, uint8_t num_bytes = 1, uint8_t max_int_width = 64)
188 {
189  if ((uint8_t)0 == num_bytes)
190  { // if byte size is variable read int_vector<0> from file
191  return load_from_file(v, file);
192  }
193  else if (num_bytes == 'd')
194  {
195  uint64_t x = 0, max_x = 0;
196  isfstream in(file, std::ios::in | std::ios::binary);
197  if (!in) { return false; }
198  else
199  {
200  std::vector<uint64_t> tmp;
201  while (in >> x)
202  {
203  tmp.push_back(x);
204  max_x = std::max(x, max_x);
205  }
206  v.width(bits::hi(max_x) + 1);
207  v.resize(tmp.size());
208  for (size_t i = 0; i < tmp.size(); ++i) { v[i] = tmp[i]; }
209  return true;
210  }
211  }
212  else
213  {
214  off_t file_size = util::file_size(file);
215  if (file_size == 0)
216  {
217  v.resize(0);
218  return true;
219  }
220  if (file_size % num_bytes != 0)
221  {
222  throw std::logic_error("file size " + util::to_string(file_size) + " of \"" + file +
223  "\" is not a multiple of " + util::to_string(num_bytes));
224  return false;
225  }
226  isfstream in(file, std::ios::in | std::ios::binary);
227  if (in)
228  {
229  v.width(std::min((int)8 * num_bytes, (int)max_int_width));
230  v.resize(file_size / num_bytes);
231  if (8 == t_int_vec::fixed_int_width and 1 == num_bytes)
232  { // if int_vector<8> is created from byte alphabet file
233  in.read((char *)v.data(), file_size);
234  }
235  else
236  {
237  size_t idx = 0;
238  const size_t block_size = conf::SDSL_BLOCK_SIZE * num_bytes;
239  std::vector<uint8_t> buf(block_size);
240  // TODO: check for larger alphabets with num_bytes*8 = v::fixed_int_width
241 
242  uint64_t x = 0; // value
243  uint8_t cur_byte = 0;
244  do {
245  in.read((char *)buf.data(), block_size);
246  size_t read = in.gcount();
247  uint8_t * begin = buf.data();
248  uint8_t * end = begin + read;
249  while (begin < end)
250  {
251  x |= ((uint64_t)(*begin)) << (cur_byte * 8);
252  ++cur_byte;
253  if (cur_byte == num_bytes)
254  {
255  v[idx++] = x;
256  cur_byte = 0;
257  x = 0ULL;
258  }
259  ++begin;
260  }
261  } while (idx < v.size());
262  in.close();
263  }
264  return true;
265  }
266  else
267  {
268  return false;
269  }
270  }
271 }
272 
274 
279 template <typename T>
280 bool store_to_file(const T & v, const std::string & file);
281 
283 inline bool store_to_file(const char * v, const std::string & file)
284 {
285  osfstream out(file, std::ios::binary | std::ios::trunc | std::ios::out);
286  if (!out)
287  {
288  if (util::verbose)
289  {
290  std::cerr << "ERROR: store_to_file(const char *v, const std::string&)" << std::endl;
291  return false;
292  }
293  }
294  uint64_t n = strlen((const char *)v);
295  out.write(v, n);
296  out.close();
297  return true;
298 }
299 
301 template <uint8_t t_width>
302 bool store_to_file(const int_vector<t_width> & v, const std::string & file);
303 
305 template <typename int_type, typename t_int_vec>
306 bool store_to_plain_array(t_int_vec & v, const std::string & file)
307 {
308  osfstream out(file, std::ios::out | std::ios::binary);
309  if (out)
310  {
311  for (typename t_int_vec::size_type i = 0; i < v.size(); ++i)
312  {
313  int_type x = v[i];
314  out.write((char *)&x, sizeof(int_type));
315  }
316  return true;
317  }
318  else
319  {
320  return false;
321  }
322 }
323 
324 template <typename T>
325 size_t serialize_empty_object(std::ostream &,
326  structure_tree_node * v = nullptr,
327  std::string name = "",
328  const T * t = nullptr)
329 {
330  structure_tree_node * child = structure_tree::add_child(v, name, util::class_name(*t));
331  size_t written_bytes = 0;
332  structure_tree::add_size(child, written_bytes);
333  return written_bytes;
334 }
335 
337 
340 template <typename T>
341 typename T::size_type size_in_bytes(const T & t);
342 
344 
347 template <typename T>
348 double size_in_mega_bytes(const T & t);
349 
350 struct nullstream : std::ostream
351 {
352  struct nullbuf : std::streambuf
353  {
354  int overflow(int c) { return traits_type::not_eof(c); }
355  int xputc(int) { return 0; }
356  std::streamsize xsputn(char const *, std::streamsize n) { return n; }
357  int sync() { return 0; }
358  } m_sbuf;
360  : std::ios(&m_sbuf)
361  , std::ostream(&m_sbuf)
362  , m_sbuf()
363  {}
364 };
365 
367 
375 template <typename T>
376 uint64_t serialize_vector(const std::vector<T> & vec,
377  std::ostream & out,
379  std::string name)
380 {
381  if (vec.size() > 0)
382  {
384  v, name, "std::vector<" + util::class_name(vec[0]) + ">");
385  size_t written_bytes = 0;
386  for (const auto & x : vec) { written_bytes += serialize(x, out, child, "[]"); }
387  structure_tree::add_size(child, written_bytes);
388  return written_bytes;
389  }
390  else
391  {
392  return 0;
393  }
394 }
395 
397 
403 template <typename T>
404 void load_vector(std::vector<T> & vec, std::istream & in)
405 {
406  for (typename std::vector<T>::size_type i = 0; i < vec.size(); ++i) { load(vec[i], in); }
407 }
408 
409 template <format_type F, typename X>
410 void write_structure(const X & x, std::ostream & out)
411 {
412  std::unique_ptr<structure_tree_node> st_node(new structure_tree_node("name", "type"));
413  nullstream ns;
414  serialize(x, ns, st_node.get(), "");
415  if (st_node.get()->children.size() > 0)
416  {
417  for (const auto & child : st_node.get()->children) { sdsl::write_structure_tree<F>(child.second.get(), out); }
418  }
419 }
420 
421 template <format_type F, typename X>
422 void write_structure(const X & x, std::string file)
423 {
424  std::ofstream out(file);
425  write_structure<F>(x, out);
426 }
427 
428 template <format_type F, typename... Xs>
429 void write_structure(std::ostream & out, Xs... xs)
430 {
431  typedef std::unique_ptr<structure_tree_node> up_stn_type;
432  up_stn_type st_node(new structure_tree_node("name", "type"));
433  _write_structure(st_node, xs...);
434  sdsl::write_structure_tree<F>(st_node.get(), out);
435 }
436 
437 template <typename X, typename... Xs>
438 void _write_structure(std::unique_ptr<structure_tree_node> & st_node, X x, Xs... xs)
439 {
440  nullstream ns;
441  serialize(x, ns, st_node.get(), "");
442  _write_structure(st_node, xs...);
443 }
444 
445 inline void _write_structure(std::unique_ptr<structure_tree_node> &) {}
446 
448 inline uint64_t _parse_number(std::string::const_iterator & c, const std::string::const_iterator & end)
449 {
450  std::string::const_iterator s = c;
451  while (c != end and isdigit(*c)) ++c;
452  if (c > s) { return std::stoull(std::string(s, c)); }
453  else
454  {
455  return 0;
456  }
457 }
458 
460 template <typename t_csa>
461 const t_csa & _idx_csa(const t_csa & t, csa_tag)
462 {
463  return t;
464 }
465 
467 template <typename t_cst>
468 const typename t_cst::csa_type & _idx_csa(const t_cst & t, cst_tag)
469 {
470  return t.csa;
471 }
472 
474 template <typename t_csa>
475 std::string _idx_lcp_val(const t_csa &, uint64_t, uint64_t, csa_tag)
476 {
477  return "";
478 }
479 
481 template <typename t_cst>
482 std::string _idx_lcp_val(const t_cst & t, uint64_t i, uint64_t w, cst_tag)
483 {
484  return util::to_string(t.lcp[i], w);
485 }
486 
487 template <typename t_csx, typename t_alph = typename t_csx::alphabet_category>
489 {
490  static const char value = '$';
491 };
492 
493 template <typename t_csx>
495 {
496  static const char value = '$';
497 };
498 
499 template <typename t_csx>
501 {
502  static const char value = '0';
503 };
504 
506 
532 template <typename t_idx>
533 void csXprintf(std::ostream & out,
534  const std::string & format,
535  const t_idx & idx,
536  char sentinel = default_sentinel<t_idx>::value)
537 {
538  typename t_idx::index_category cat;
539  const typename t_idx::csa_type & csa = _idx_csa(idx, cat);
540  std::vector<std::string> res(csa.size());
541  bool truncate = false;
542  for (std::string::const_iterator c = format.begin(), s = c; c != format.end(); s = c)
543  {
544  while (c != format.end() and *c != '%') ++c; // string before the next `%`
545  if (c > s)
546  { // copy format string part
547  std::vector<std::string> to_copy(csa.size(), std::string(s, c));
548  transform(res.begin(), res.end(), to_copy.begin(), res.begin(), std::plus<std::string>());
549  }
550  if (c == format.end()) break;
551  ++c; // skip `%`
552  uint64_t w = _parse_number(c, format.end()); // element width
553  if (c == format.end()) break;
554  uint64_t W = 0; // character width
555  if (':' == *c)
556  {
557  ++c;
558  W = _parse_number(c, format.end());
559  }
560  if (c == format.end()) break;
561  for (uint64_t i = 0; i < csa.size(); ++i)
562  {
563  switch (*c)
564  {
565  case 'I': res[i] += util::to_string(i, w); break;
566  case 'S': res[i] += util::to_string(csa[i], w); break;
567  case 's': res[i] += util::to_string(csa.isa[i], w); break;
568  case 'P': res[i] += util::to_string(csa.psi[i], w); break;
569  case 'p': res[i] += util::to_string(csa.lf[i], w); break;
570  case 'L': res[i] += _idx_lcp_val(idx, i, w, cat); break;
571  case 'B':
572  if (0 == csa.bwt[i]) { res[i] += util::to_string(sentinel, w); }
573  else
574  {
575  res[i] += util::to_string(csa.bwt[i], w);
576  }
577  break;
578  case 'U': truncate = true; SDSL_FALLTHROUGH
579  case 'T':
580  for (uint64_t k = 0; (w > 0 and k < w) or (0 == w and k < csa.size()); ++k)
581  {
582  if (0 == csa.text[(csa[i] + k) % csa.size()])
583  {
584  res[i] += util::to_string(sentinel, W);
585  if (truncate)
586  {
587  truncate = false;
588  break;
589  }
590  }
591  else
592  {
593  res[i] += util::to_string(csa.text[(csa[i] + k) % csa.size()], W);
594  }
595  }
596  break;
597  case 'u': truncate = true; SDSL_FALLTHROUGH
598  case 't':
599  for (uint64_t k = 0; (w > 0 and k < w) or (0 == w and k < csa.size()); ++k)
600  {
601  if (0 == csa.text[(i + k) % csa.size()])
602  {
603  res[i] += util::to_string(sentinel, W);
604  if (truncate)
605  {
606  truncate = false;
607  break;
608  }
609  }
610  else
611  {
612  res[i] += util::to_string(csa.text[(i + k) % csa.size()], W);
613  }
614  }
615  break;
616  case '%': res[i] += "%"; break;
617  }
618  }
619  ++c;
620  }
621  for (size_t i = 0; i < res.size(); ++i) out << res[i] << std::endl;
622 }
623 
625 
630 inline std::string cache_file_name(const std::string & key, const cache_config & config)
631 {
632  if (config.file_map.count(key) != 0) { return config.file_map.at(key); }
633  return config.dir + "/" + key + "_" + config.id + ".sdsl";
634 }
635 
637 
642 template <typename T>
643 std::string cache_file_name(const std::string & key, const cache_config & config)
644 {
645  return cache_file_name(key + "_" + util::class_to_hash(T()), config);
646 }
647 
649 
656 inline void register_cache_file(const std::string & key, cache_config & config)
657 {
658  std::string file_name = cache_file_name(key, config);
659  isfstream in(file_name);
660  if (in)
661  { // if file exists, register it.
662  config.file_map[key] = file_name;
663  }
664 }
665 
667 
672 inline bool cache_file_exists(const std::string & key, const cache_config & config)
673 {
674  std::string file_name = cache_file_name(key, config);
675  isfstream in(file_name);
676  if (in)
677  {
678  in.close();
679  return true;
680  }
681  return false;
682 }
683 
685 
691 template <typename T>
692 bool cache_file_exists(const std::string & key, const cache_config & config)
693 {
694  return cache_file_exists(key + "_" + util::class_to_hash(T()), config);
695 }
696 
698 inline std::string tmp_file(const cache_config & config, std::string name_part = "")
699 {
700  return config.dir + "/" + util::to_string(util::pid()) + "_" + util::to_string(util::id()) + name_part + ".sdsl";
701 }
702 
704 inline std::string tmp_file(const std::string & filename, std::string name_part = "")
705 {
706  return util::dirname(filename) + "/" + util::to_string(util::pid()) + "_" + util::to_string(util::id()) +
707  name_part + ".sdsl";
708 }
709 
710 template <typename T>
711 bool load_from_cache(T & v, const std::string & key, const cache_config & config, bool add_type_hash = false)
712 {
713  std::string file;
714  if (add_type_hash) { file = cache_file_name<T>(key, config); }
715  else
716  {
717  file = cache_file_name(key, config);
718  }
719  if (load_from_file(v, file))
720  {
721  if (util::verbose) { std::cerr << "Load `" << file << std::endl; }
722  return true;
723  }
724  else
725  {
726  std::cerr << "WARNING: Could not load file '";
727  std::cerr << file << "'" << std::endl;
728  return false;
729  }
730 }
731 
733 
736 template <typename T>
737 bool store_to_cache(const T & v, const std::string & key, cache_config & config, bool add_type_hash = false)
738 {
739  std::string file;
740  if (add_type_hash) { file = cache_file_name<T>(key, config); }
741  else
742  {
743  file = cache_file_name(key, config);
744  }
745  if (store_to_file(v, file))
746  {
747  config.file_map[std::string(key)] = file;
748  return true;
749  }
750  else
751  {
752  std::cerr << "WARNING: store_to_cache: could not store file `" << file << "`" << std::endl;
753  return false;
754  }
755 }
756 
757 template <typename T>
758 bool remove_from_cache(const std::string & key, cache_config & config, bool add_type_hash = false)
759 {
760  std::string file;
761  if (add_type_hash) { file = cache_file_name<T>(key, config); }
762  else
763  {
764  file = cache_file_name(key, config);
765  }
766  config.file_map.erase(key);
767  if (sdsl::remove(file) == 0) { return true; }
768  else
769  {
770  std::cerr << "WARNING: delete_from_cache: could not delete file `" << file << "`" << std::endl;
771  return false;
772  }
773 }
774 
775 //==================== Template functions ====================
776 
777 template <typename T>
778 typename T::size_type size_in_bytes(const T & t)
779 {
780  nullstream ns;
781  return serialize(t, ns);
782 }
783 
784 template <typename T>
785 double size_in_mega_bytes(const T & t)
786 {
787  return size_in_bytes(t) / (1024.0 * 1024.0);
788 }
789 
790 template <typename T>
791 void add_hash(const T & t, std::ostream & out)
792 {
793  uint64_t hash_value = util::hashvalue_of_classname(t);
794  write_member(hash_value, out);
795 }
796 
797 template <typename T>
798 bool store_to_file(const T & t, const std::string & file)
799 {
800  osfstream out(file, std::ios::binary | std::ios::trunc | std::ios::out);
801  if (!out)
802  {
803  if (util::verbose) { std::cerr << "ERROR: store_to_file not successful for: `" << file << "`" << std::endl; }
804  return false;
805  }
806  serialize(t, out);
807  out.close();
808  if (util::verbose) { std::cerr << "INFO: store_to_file: `" << file << "`" << std::endl; }
809  return true;
810 }
811 
812 template <typename T>
813 bool store_to_checked_file(const T & t, const std::string & file)
814 {
815  std::string checkfile = file + "_check";
816  osfstream out(checkfile, std::ios::binary | std::ios::trunc | std::ios::out);
817  if (!out)
818  {
819  if (util::verbose)
820  {
821  std::cerr << "ERROR: store_to_checked_file not successful for: `" << checkfile << "`" << std::endl;
822  }
823  return false;
824  }
825  add_hash(t, out);
826  out.close();
827  return store_to_file(t, file);
828 }
829 
830 inline bool store_to_checked_file(const char * v, const std::string & file)
831 {
832  std::string checkfile = file + "_check";
833  osfstream out(checkfile, std::ios::binary | std::ios::trunc | std::ios::out);
834  if (!out)
835  {
836  if (util::verbose)
837  {
838  std::cerr << "ERROR: store_to_checked_file(const char *v, const std::string&)" << std::endl;
839  return false;
840  }
841  }
842  add_hash(v, out);
843  out.close();
844  return store_to_file(v, file);
845 }
846 
847 inline bool store_to_file(const std::string & v, const std::string & file)
848 {
849  osfstream out(file, std::ios::binary | std::ios::trunc | std::ios::out);
850  if (!out)
851  {
852  if (util::verbose)
853  {
854  std::cerr << "ERROR: store_to_file(const std::string& v, const std::string&)" << std::endl;
855  return false;
856  }
857  }
858  out.write(v.data(), v.size());
859  out.close();
860  return true;
861 }
862 
863 template <uint8_t t_width>
864 bool store_to_file(const int_vector<t_width> & v, const std::string & file)
865 {
866  osfstream out(file, std::ios::binary | std::ios::trunc | std::ios::out);
867  if (!out)
868  {
869  std::cerr << "ERROR: util::store_to_file:: Could not open file `" << file << "`" << std::endl;
870  return false;
871  }
872  else
873  {
874  if (util::verbose) { std::cerr << "INFO: store_to_file: `" << file << "`" << std::endl; }
875  }
876  v.serialize(out, nullptr, "");
877  out.close();
878  return true;
879 }
880 
881 template <uint8_t t_width>
882 bool store_to_checked_file(const int_vector<t_width> & v, const std::string & file)
883 {
884  std::string checkfile = file + "_check";
885  osfstream out(checkfile, std::ios::binary | std::ios::trunc | std::ios::out);
886  if (!out)
887  {
888  std::cerr << "ERROR: util::store_to_checked_file: Could not open check file `" << checkfile << "`" << std::endl;
889  return false;
890  }
891  else
892  {
893  if (util::verbose) { std::cerr << "INFO: store_to_checked_file: `" << checkfile << "`" << std::endl; }
894  }
895  add_hash(v, out);
896  out.close();
897  return store_to_file(v, file);
898 }
899 
900 template <typename T>
901 bool load_from_file(T & v, const std::string & file)
902 {
903  isfstream in(file, std::ios::binary | std::ios::in);
904  if (!in)
905  {
906  if (util::verbose) { std::cerr << "Could not load file `" << file << "`" << std::endl; }
907  return false;
908  }
909  load(v, in);
910  in.close();
911  if (util::verbose) { std::cerr << "Load file `" << file << "`" << std::endl; }
912  return true;
913 }
914 
915 template <typename T>
916 bool load_from_checked_file(T & v, const std::string & file)
917 {
918  isfstream in(file + "_check", std::ios::binary | std::ios::in);
919  if (!in)
920  {
921  if (util::verbose) { std::cerr << "Could not load check file `" << file << "_check`" << std::endl; }
922  return false;
923  }
924  uint64_t hash_value;
925  read_member(hash_value, in);
926  if (hash_value != util::hashvalue_of_classname(v))
927  {
928  if (util::verbose)
929  {
930  std::cerr << "File `" << file << "` is not an instance of the class `"
931  << sdsl::util::demangle2(typeid(T).name()) << "`" << std::endl;
932  }
933  return false;
934  }
935  return load_from_file(v, file);
936 }
937 
938 template <typename t_iv>
939 inline typename std::enable_if<std::is_same<typename t_iv::index_category,
940  iv_tag>::value or std::is_same<typename t_iv::index_category, csa_tag>::value or
941  std::is_same<typename t_iv::index_category,
942  lcp_tag>::value,
943  std::ostream &>::type
944 operator<<(std::ostream & os, const t_iv & v)
945 {
946  for (auto it = v.begin(), end = v.end(); it != end; ++it)
947  {
948  os << *it;
949  if (it + 1 != end) os << " ";
950  }
951  return os;
952 }
953 
954 template <typename t_iv>
955 inline typename std::enable_if<std::is_same<typename t_iv::index_category, wt_tag>::value, std::ostream &>::type
956 operator<<(std::ostream & os, const t_iv & v)
957 {
958  for (auto it = v.begin(), end = v.end(); it != end; ++it)
959  {
960  os << *it;
961  if (it + 1 != end and std::is_same<typename t_iv::alphabet_category, int_alphabet_tag>::value) os << " ";
962  }
963  return os;
964 }
965 
966 template <typename t_int>
967 inline typename std::enable_if<std::is_integral<t_int>::value, std::ostream &>::type operator<<(
968  std::ostream & os,
969  const std::vector<t_int> & v)
970 {
971  for (auto it = v.begin(), end = v.end(); it != end; ++it)
972  {
973  os << *it;
974  if (it + 1 != end) os << " ";
975  }
976  return os;
977 }
978 
979 template <typename t_iv>
980 inline typename std::enable_if<std::is_same<typename t_iv::category, csa_member_tag>::value, std::ostream &>::type
981 operator<<(std::ostream & os, const t_iv & v)
982 {
983  for (auto it = v.begin(), end = v.end(); it != end; ++it)
984  {
985  os << *it;
986  if (it + 1 != end and std::is_same<typename t_iv::alphabet_category, int_alphabet_tag>::value) os << " ";
987  }
988  return os;
989 }
990 } // namespace sdsl
991 #endif
cereal.hpp offers cereal support
A generic vector class for integers of width .
Definition: int_vector.hpp:253
size_type size() const noexcept
The number of elements in the int_vector.
size_type serialize(std::ostream &out, structure_tree_node *v=nullptr, std::string name="") const
Serializes the int_vector to a stream.
void close()
Close the stream.
Definition: sfstream.hpp:233
void close()
Close the stream.
Definition: sfstream.hpp:87
static void add_size(structure_tree_node *v, uint64_t value)
static structure_tree_node * add_child(structure_tree_node *v, const std::string &name, const std::string &type)
const uint64_t SDSL_BLOCK_SIZE
Definition: config.hpp:33
int_vector ::size_type size_type
size_t file_size(const std::string &name)
Get the file size.
Definition: ram_fs.hpp:49
int truncate(const int fd, size_t new_size)
Get the content with fd.
Definition: ram_fs.hpp:134
Get the size of a file in bytes size_t file_size(const std::string &file)
Definition: util.hpp:186
Returns the directory of a file A trailing will be removed std::string dirname(std::string file)
Definition: util.hpp:225
uint64_t id()
uint64_t pid()
std::string to_string(const T &t, int w=1)
Namespace for the succinct data structure library.
std::string cache_file_name(const std::string &key, const cache_config &config)
Returns the file name of the resource.
Definition: io.hpp:630
bool load_from_checked_file(T &v, const std::string &file)
Definition: io.hpp:916
bool load_from_cache(T &v, const std::string &key, const cache_config &config, bool add_type_hash=false)
Definition: io.hpp:711
size_t block_size(void *ptr)
std::ostream & operator<<(std::ostream &os, const bp_interval< t_int > &interval)
Definition: cst_sct3.hpp:1332
bool remove_from_cache(const std::string &key, cache_config &config, bool add_type_hash=false)
Definition: io.hpp:758
std::string _idx_lcp_val(const t_csa &, uint64_t, uint64_t, csa_tag)
Internal function used by csXprintf.
Definition: io.hpp:475
void load_vector(std::vector< T > &, std::istream &)
Load all elements of a vector from a input stream.
Definition: io.hpp:404
std::enable_if< has_serialize< X >::value, typename X::size_type >::type serialize(const X &x, std::ostream &out, structure_tree_node *v=nullptr, std::string name="")
Definition: io.hpp:131
uint64_t serialize_vector(const std::vector< T > &, std::ostream &, sdsl::structure_tree_node *v=nullptr, std::string="")
Serialize each element of an std::vector.
Definition: io.hpp:376
std::enable_if< has_load< X >::value, void >::type load(X &x, std::istream &in)
Definition: io.hpp:154
bool store_to_plain_array(t_int_vec &v, const std::string &file)
Store an int_vector as plain int_type array to disk.
Definition: io.hpp:306
bool load_vector_from_file(t_int_vec &v, const std::string &file, uint8_t num_bytes=1, uint8_t max_int_width=64)
from disk.
Definition: io.hpp:187
size_t write_member(const T &t, std::ostream &out, sdsl::structure_tree_node *v=nullptr, std::string name="")
Definition: io.hpp:84
void read_member(T &t, std::istream &in)
Definition: io.hpp:111
std::string tmp_file(const cache_config &config, std::string name_part="")
Returns a name for a temporary file. I.e. the name was not used before.
Definition: io.hpp:698
uint64_t _parse_number(std::string::const_iterator &c, const std::string::const_iterator &end)
Internal function used by csXprintf.
Definition: io.hpp:448
bool load_from_file(T &v, const std::string &file)
Load sdsl-object v from a file.
Definition: io.hpp:901
void csXprintf(std::ostream &out, const std::string &format, const t_idx &idx, char sentinel=default_sentinel< t_idx >::value)
Prints members of CSAs and CSTs.
Definition: io.hpp:533
bool store_to_checked_file(const T &t, const std::string &file)
Definition: io.hpp:813
void register_cache_file(const std::string &key, cache_config &config)
Register the existing resource specified by the key to the cache.
Definition: io.hpp:656
bool store_to_file(const T &v, const std::string &file)
Store a data structure to a file.
Definition: io.hpp:798
bool cache_file_exists(const std::string &key, const cache_config &config)
Checks if the resource specified by the key exists in the cache.
Definition: io.hpp:672
const t_csa & _idx_csa(const t_csa &t, csa_tag)
Internal function used by csXprintf.
Definition: io.hpp:461
void _write_structure(std::unique_ptr< structure_tree_node > &st_node, X x, Xs... xs)
Definition: io.hpp:438
void write_structure(const X &x, std::ostream &out)
Definition: io.hpp:410
bool store_to_cache(const T &v, const std::string &key, cache_config &config, bool add_type_hash=false)
Stores the object v as a resource in the cache.
Definition: io.hpp:737
format_type
Definition: config.hpp:53
int remove(const std::string &)
Remove a file.
Definition: ram_fs.hpp:194
int_vector ::size_type size(const range_type &r)
Size of a range.
Definition: wt_helper.hpp:787
size_t serialize_empty_object(std::ostream &, structure_tree_node *v=nullptr, std::string name="", const T *t=nullptr)
Definition: io.hpp:325
T::size_type size_in_bytes(const T &t)
Get the size of a data structure in bytes.
Definition: io.hpp:778
double size_in_mega_bytes(const T &t)
Get the size of a data structure in mega bytes (MiB).
Definition: io.hpp:785
void add_hash(const T &t, std::ostream &out)
Definition: io.hpp:791
util.hpp contains platform dependend macros.
#define SDSL_FALLTHROUGH
Definition: platform.hpp:24
Contains declarations and definitions of data structure concepts.
static SDSL_CONSTEXPR uint32_t hi(uint64_t x)
Position of the most significant set bit the 64-bit word x.
Definition: bits.hpp:661
Helper class for construction process.
Definition: config.hpp:67
std::string id
Definition: config.hpp:72
std::string dir
Definition: config.hpp:71
static constexpr std::false_type check(...)
Definition: io.hpp:74
static constexpr auto check(T *) -> typename std::is_same< decltype(std::declval< T >().load(std::declval< std::istream & >())), void >::type
Definition: io.hpp:69
decltype(check< X >(nullptr)) typedef type
Definition: io.hpp:58
static constexpr std::false_type check(...)
Definition: io.hpp:54
static constexpr auto check(T *) -> typename std::is_same< decltype(std::declval< T >().serialize(std::declval< std::ostream & >(), std::declval< structure_tree_node * >(), std::declval< std::string >())), typename T::size_type >::type
Definition: io.hpp:46
static constexpr bool value
Definition: io.hpp:59
std::streamsize xsputn(char const *, std::streamsize n)
Definition: io.hpp:356
int overflow(int c)
Definition: io.hpp:354
structure_tree.hpp contains a helper class which can represent the memory structure of a class.
util.hpp contains some helper methods for int_vector and other stuff like demangle class names.