TextInterfaceEmbed.h
1 //-*-C++-*-
2 
3 /***************************************************************************
4  *
5  * Copyright (C) 2013 by Willem van Straten
6  * Licensed under the Academic Free License version 2.1
7  *
8  ***************************************************************************/
9 
10 // psrchive/Util/units/TextInterfaceEmbed.h
11 
12 #ifndef __TextInterfaceEmbed_h
13 #define __TextInterfaceEmbed_h
14 
15 #include "TextInterfaceAttribute.h"
16 #include "separate.h"
17 
18 namespace TextInterface
19 {
21 
25  template<class C, class Type, class Get, class Set>
26  class OptionalInterface : public AttributeGetSet<C,Type,Get,Set>
27  {
28 
29  public:
30 
32  OptionalInterface (const std::string& t, Get g, Set s)
33  : AttributeGetSet<C,Type,Get,Set> (t,g,s)
34  {
35 #if _DEBUG
36  std::cerr << "OptionalInterface name=" << t << std::endl;
37 #endif
38  }
39 
41  std::string get_name () const
43 
45  std::string get_value (const C* ptr) const;
46 
48  void set_value (C* ptr, const std::string& value);
49 
51  bool matches (const std::string& name) const;
52 
53  void set_modifiers (const std::string&) const;
54  void reset_modifiers () const;
55 
56  protected:
57 
58  virtual Parser* get_parser (const C* ptr) const = 0;
59 
62  mutable bool help = false;
63  };
64 
65 
67 
68  template<class C, class Get>
69  class GetParserPolicy
70  {
71  public:
72  Parser* operator () (const C* ptr, Get func) const
73  {
74  return func (const_cast<C*>(ptr));
75  }
76  };
77 
78  template<class C, class P>
79  class GetParserPolicy<C, Parser* (P::*)()>
80  {
81  public:
82  Parser* operator () (const C* ptr, Parser* (P::*get)()) const
83  {
84  return (const_cast<C*>(ptr)->*get)();
85  }
86  };
87 
88  template<class C>
89  class GetParserPolicy<C, Parser* (C*)>
90  {
91  public:
92  Parser* operator () (const C* ptr, Parser* (*func)(C*)) const
93  {
94  return func (const_cast<C*>(ptr));
95  }
96  };
97 
98  template<class C, class Type, class Get, class Set, class GetParser>
99  class DirectInterface : public OptionalInterface<C,Type,Get,Set>
100  {
101 
102  GetParserPolicy<C,GetParser> get_parser_policy;
103 
104  public:
105 
107  DirectInterface (const std::string& t, Get g, Set s, GetParser p)
108  : OptionalInterface<C,Type,Get,Set> (t,g,s), get_parser_method (p) { }
109 
111  Attribute<C>* clone () const
112  { return new DirectInterface(*this); }
113 
114  protected:
115 
117  GetParser get_parser_method;
118 
119  Parser* get_parser (const C* ptr) const try
120  {
121  return get_parser_policy (ptr, get_parser_method);
122  }
123  catch (Error& error)
124  {
125  throw error += "DirectInterface::get_parser";
126  }
127  };
128 
129  template<class C, class Type, class Get, class Set, class GetParser>
130  class IndirectInterface : public OptionalInterface<C,Type,Get,Set>
131  {
132 
133  public:
134 
136  IndirectInterface (const std::string& t, Get g, Set s, GetParser p)
137  : OptionalInterface<C,Type,Get,Set> (t,g,s), get_parser_method (p) { }
138 
140  Attribute<C>* clone () const
141  { return new IndirectInterface(*this); }
142 
143  protected:
144 
146  GetParser get_parser_method;
147 
148  Parser* get_parser (const C* ptr) const try
149  {
150  Type tptr = (const_cast<C*>(ptr)->*(this->get))();
151  return (tptr->*get_parser_method)();
152  }
153  catch (Error& error)
154  {
155  throw error += "IndirectInterface::get_parser";
156  }
157  };
158 
159  template<class C, class Type>
160  class EmbedAllocator
161  {
162  public:
164  template<class Get, class Set, class GetParser>
165  OptionalInterface<C,Type,Get,Set>*
166  direct (const std::string& n, Get g, Set s, GetParser p)
167  {
168  return new DirectInterface<C,Type,Get,Set,GetParser> (n,g,s,p);
169  }
170 
172  template<class Get, class Set, class GetParser>
173  OptionalInterface<C,Type,Get,Set>*
174  indirect (const std::string& n, Get g, Set s, GetParser p)
175  {
176  return new IndirectInterface<C,Type,Get,Set,GetParser> (n,g,s,p);
177  }
178  };
179 
181 
184  template<class V, class Get, class Size>
185  class VectorOfInterfaces : public Attribute<V>
186  {
187 
188  public:
189 
191  VectorOfInterfaces (const std::string& p, Get g, Size s)
192  { prefix = p; get = g; size = s; }
193 
196  { get=copy.get; size=copy.size; prefix=copy.prefix; }
197 
199  Attribute<V>* clone () const
200  { return new VectorOfInterfaces(*this); }
201 
203  std::string get_name () const
204  { return prefix + "*:@"; }
205 
207  std::string get_description () const
208  { return prefix + ":help for attribute list"; }
209 
211  std::string get_value (const V* ptr) const;
212 
214  void set_value (V* ptr, const std::string& value);
215 
217  void set_description (const std::string&) {}
218 
220  void set_detailed_description (const std::string&) {}
221 
223  bool matches (const std::string& name) const;
224 
226  void set_modifiers (const std::string& mod) const
227  { modifiers = mod; }
228 
230  void reset_modifiers () const
231  { modifiers.erase(); }
232 
233  protected:
234 
236  Get get;
237 
239  Size size;
240 
242  std::string prefix;
243 
245  mutable std::string range;
246 
248  mutable std::string remainder;
249 
251  mutable std::string modifiers;
252  };
253 
255  template<class C>
256  class Embed
257  {
258  public:
259  template <class G, class S>
260  VectorOfInterfaces<C,G,S>* operator() (const std::string& name, G g, S s)
261  {
262  return new VectorOfInterfaces<C,G,S>(name, g, s);
263  }
264  };
265 
267 
269  template<class M, class K, class Get>
270  class MapOfInterfaces : public Attribute<M>
271  {
272 
273  public:
274 
276  MapOfInterfaces (const std::string& pre, Get g)
277  { prefix = pre; get = g; }
278 
280  MapOfInterfaces (const MapOfInterfaces& copy)
281  { prefix=copy.prefix; get=copy.get; }
282 
284 
286  Attribute<M>* clone () const
287  { return new MapOfInterfaces(*this); }
288 
290  std::string get_name () const
291  { return prefix + "?:@"; }
292 
294  std::string get_description () const
295  { return prefix + ":help for attribute list"; }
296 
298  std::string get_value (const M* ptr) const;
299 
301  void set_value (M* ptr, const std::string& value);
302 
304  void set_description (const std::string&) {}
305 
307  void set_detailed_description (const std::string&) {}
308 
310  bool matches (const std::string& name) const;
311 
312  protected:
313 
315  Get get;
316 
318  std::string prefix;
319 
321  mutable std::string range;
322 
324  mutable std::string remainder;
325 
327  void get_indeces (std::vector<K>& keys,
328  const std::string& param) const;
329 
330  };
331 
332 }
333 
334 template<class C, class T, class G, class S>
335 std::string
337 {
338  if (help)
339  {
340  Reference::To<Parser> parser = get_parser(ptr);
341  if (parser)
342  return "\n" + parser->help();
343  else
344  return "no text parser available";
345  }
346 
347  if (value)
348  return value->get_value();
349 
351 }
352 catch (Error& error)
353 {
354  return "-";
355 }
356 
357 template<class C, class T, class G, class S>
359  const std::string& val) try
360 {
361  if (value)
362  value->set_value (val);
363  else
365 }
366 catch (Error& error)
367 {
368  throw error += "TextInterface::OptionalInterface::set_value";
369 }
370 
371 template<class C, class T, class G, class S>
373  (const std::string& text) const try
374 {
375 #ifdef _DEBUG
376  std::cerr << "TextInterface::OptionalInterface::matches"
377  " text='" << text << "'" << std::endl;
378 #endif
379 
380  value = 0;
381  help = false;
382 
383  if (text == this->name)
384  return true;
385 
386  if (text == this->name + "[:@]")
387  return true;
388 
389  std::string range;
390  std::string remainder;
391  if (!match (this->name, text, &range, &remainder))
392  return false;
393 
394 #ifdef _DEBUG
395  std::cerr << "TextInterface::OptionalInterface::matches"
396  " remainder='" << remainder << "'" << std::endl;
397 #endif
398 
399  if (remainder == "help")
400  {
401  help = true;
402  return true;
403  }
404 
405  if (!this->instance)
406  {
407 #ifdef _DEBUG
408  std::cerr << "TextInterface::OptionalInterface::matches"
409  " no instance" << std::endl;
410 #endif
411  return false;
412  }
413 
414 #ifdef _DEBUG
415  std::cerr << "TextInterface::OptionalInterface::matches"
416  " getting Parser" << std::endl;
417 #endif
418 
419  Reference::To<Parser> parser;
420 
421  try
422  {
423  parser = get_parser(this->instance);
424  }
425  catch (Error&)
426  {
427  return false;
428  }
429 
430  if (!parser)
431  return false;
432 
433 #ifdef _DEBUG
434  std::cerr << "TextInterface::OptionalInterface::matches"
435  " got Parser" << std::endl;
436 #endif
437 
438  bool throw_exception = false;
439  value = parser->find (remainder, throw_exception);
440 
441  if (!value)
442  {
443 #ifdef _DEBUG
444  std::cerr << "TextInterface::OptionalInterface::matches"
445  " Parser::find(" << remainder << ") returns false" << std::endl;
446 #endif
447  return false;
448  }
449 
450 #ifdef _DEBUG
451  std::cerr << "TextInterface::OptionalInterface::matches"
452  " Parser::find(" << remainder << ") returns true" << std::endl;
453 #endif
454 
455  return true;
456 }
457 catch (Error& error)
458 {
459  throw error += "TextInterface::OptionalInterface::matches";
460 }
461 
462 template<class C, class T, class G, class S>
463 void TextInterface::OptionalInterface<C,T,G,S>::set_modifiers (const std::string& modifiers) const try
464 {
465  if (value)
466  {
467 #ifdef _DEBUG
468  std::cerr << "TextInterface::OptionalInterface"
469  " calling Value::set_modifiers (" << modifiers << ")" << std::endl;
470 #endif
471  value->set_modifiers (modifiers);
472  }
473  else
474  {
475 #ifdef _DEBUG
476  std::cerr << "TextInterface::OptionalInterface"
477  " calling AttributeGetSet<>::set_modifiers" << std::endl;
478 #endif
480  }
481 }
482 catch (Error& error)
483 {
484  throw error += "TextInterface::OptionalInterface::set_modifiers";
485 }
486 
487 template<class C, class T, class G, class S>
489 {
490  if (value)
491  value->reset_modifiers ();
492  else
494 }
495 catch (Error& error)
496 {
497  throw error += "TextInterface::OptionalInterface::reset_modifiers";
498 }
499 
500 
501 
502 
503 
504 
505 
506 
507 template<class V, class G, class S>
508 std::string
510 {
511  std::vector<unsigned> ind;
512  parse_indeces (ind, this->range, (ptr->*(this->size))());
513  std::string result;
514 
515  if (!this->parent)
516  throw Error (InvalidState, "VectorOfInterfaces["+prefix+"]", "no parent");
517 
518  for (unsigned i=0; i<ind.size(); i++)
519  {
520  // place a delimiter between elements
521  if (i)
522  result += this->parent->get_delimiter();
523 
524  // label the elements
525  if (label_elements && ind.size() > 1)
526  result += tostring(ind[i]) + ")";
527 
528  Reference::To<Parser> parser;
529  parser = (const_cast<V*>(ptr)->*get)(ind[i])->get_interface();
530 
531  parser->set_delimiter( this->parent->get_delimiter() );
532 
533  if (remainder == "help")
534  result += "\n" + parser->help();
535  else
536  {
537  std::string pass_to_parser = remainder;
538  if (modifiers.length() > 0)
539  pass_to_parser += "%" + modifiers;
540  result += parser->get_value (pass_to_parser);
541  }
542  }
543 
544  return result;
545 }
546 catch (Error& error)
547 {
548  throw error += "TextInterface::VectorOfInterfaces::get_value";
549 }
550 
551 template<class V, class G, class S>
553  const std::string& val) try
554 {
555  std::vector<unsigned> ind;
556  parse_indeces (ind, range, (ptr->*size)());
557 
558  for (unsigned i=0; i<ind.size(); i++)
559  {
560  Reference::To<Parser> parser = (ptr->*get)(ind[i])->get_interface();
561  parser->set_value (remainder, val);
562  }
563 }
564 catch (Error& error)
565 {
566  throw error += "TextInterface::VectorOfInterfaces::set_value";
567 }
568 
569 template<class C,class Get,class Size>
571  (const std::string& name) const try
572 {
573 #ifdef _DEBUG
574  std::cerr << "TextInterface::VectorOfInterfaces::matches" << std::endl;
575 #endif
576 
577  if (!match (prefix, name, &range, &remainder))
578  return false;
579 
580  if (remainder == "@")
581  return true;
582 
583  if (remainder == "help")
584  return true;
585 
586  if (!this->instance)
587  return false;
588 
589  std::vector<unsigned> ind;
590  parse_indeces (ind, range, (this->instance->*size)());
591 
592  for (unsigned i=0; i<ind.size(); i++)
593  {
594  C* ptr = this->instance.ptr();
595  Reference::To<Parser> parser = (ptr->*get)(ind[i])->get_interface();
596  if (! parser->found (remainder))
597  return false;
598  }
599  return true;
600 }
601 catch (Error& error)
602 {
603  throw error += "TextInterface::VectorOfInterfaces::matches";
604 }
605 
606 template<class M, class K, class G>
607 std::string
609 {
610  std::vector<K> ind;
611  get_indeces (ind, range);
612  std::string result;
613 
614  if (!this->parent)
615  throw Error (InvalidState, "MapOfInterfaces["+prefix+"]", "no parent");
616 
617  for (unsigned i=0; i<ind.size(); i++)
618  {
619  // place a delimiter between elements
620  if (i)
621  result += this->parent->get_delimiter();
622 
623  // label the elements
624  if (label_elements && ind.size() > 1)
625  result += tostring(ind[i]) + ")";
626 
627  Reference::To<Parser> parser = (const_cast<M*>(ptr)->*get)(ind[i])->get_interface();
628  parser->set_delimiter( this->parent->get_delimiter() );
629  result += parser->get_value (remainder);
630  }
631 
632  return result;
633 }
634 catch (Error& error)
635 {
636  throw error += "TextInterface::MapOfInterfaces::get_value";
637 }
638 
639 template<class M, class K, class G>
641  const std::string& val) try
642 {
643  std::vector<K> ind;
644  get_indeces (ind, range);
645 
646  for (unsigned i=0; i<ind.size(); i++)
647  {
648  Reference::To<Parser> parser = (ptr->*get)(ind[i])->get_interface();
649  parser->set_value (remainder, val);
650  }
651 }
652 catch (Error& error)
653 {
654  throw error += "TextInterface::MapOfInterfaces::set_value";
655 }
656 
657 template<class M, class K, class G>
658 void
660  const std::string& par) const try
661 {
662 #ifdef _DEBUG
663  std::cerr << "MapOfInterfaces::get_indeces " << par << std::endl;
664 #endif
665 
666  std::string::size_type length = par.length();
667 
668  std::string range = par;
669 
670  if (prefix.length()) {
671  if (par[0] != '[' || par[length-1] != ']')
672  return;
673  range = par.substr (1, length-2);
674  }
675  else if (par == "?")
676  return;
677 
678  std::vector<std::string> key_str;
679  separate (range, key_str, ", ");
680 
681  indeces.resize (key_str.size());
682  for (unsigned i=0; i<key_str.size(); i++)
683  indeces[i] = fromstring<K>(key_str[i]);
684 }
685 catch (Error& error)
686 {
687  throw error += "TextInterface::MapOfInterfaces::get_indeces";
688 }
689 
690 template<class M, class K, class G>
692  (const std::string& name) const try
693 {
694 #ifdef _DEBUG
695  std::cerr << "TextInterface::MapOfInterfaces::matches" << std::endl;
696 #endif
697 
698  if (!match (prefix, name, &range, &remainder))
699  return false;
700 
701  if (remainder == "@")
702  return true;
703 
704  if (!this->instance)
705  return false;
706 
707  std::vector<K> ind;
708  get_indeces (ind, range);
709 
710  for (unsigned i=0; i<ind.size(); i++)
711  {
712  Reference::To<Parser> parser = (const_cast<M*>(this->instance)->*get)(ind[i])->get_interface();
713  if (! parser->found (remainder))
714  return false;
715  }
716  return true;
717 }
718 catch (Error& error)
719 {
720  throw error += "TextInterface::MapOfInterfaces::matches";
721 }
722 
723 #endif
std::string remainder
Remainder parsed from name during matches.
Definition: TextInterfaceEmbed.h:253
MapOfInterfaces(const std::string &pre, Get g)
Construct from a pointer to parent class attribute interface.
Definition: TextInterfaceEmbed.h:281
bool matches(const std::string &name) const
Return true if the name argument matches.
Definition: TextInterfaceEmbed.h:373
std::string get_name() const
Get the name of the attribute.
Definition: TextInterfaceAttribute.h:206
void set_modifiers(const std::string &mod) const
Parse any modifiers that will alter the behaviour of the output stream.
Definition: TextInterfaceEmbed.h:231
std::string prefix
The name of the vector instance.
Definition: TextInterfaceEmbed.h:247
VectorOfInterfaces(const VectorOfInterfaces &copy)
Copy constructor.
Definition: TextInterfaceEmbed.h:200
Attribute< V > * clone() const
Retun a newly constructed copy.
Definition: TextInterfaceEmbed.h:204
void get_indeces(std::vector< K > &keys, const std::string &param) const
Worker function parses keys for get_value and set_value.
Definition: TextInterfaceEmbed.h:659
std::string range
Range parsed from name during matches.
Definition: TextInterfaceEmbed.h:326
OptionalInterface(const std::string &t, Get g, Set s)
Construct from a pointer to element attribute interface.
Definition: TextInterfaceEmbed.h:42
std::string get_name() const
Get the name of the attribute.
Definition: TextInterfaceEmbed.h:51
Attribute< M > * clone() const
Set the prefix to be added before attribute name.
Definition: TextInterfaceEmbed.h:291
A convenient exception handling class.
Definition: Error.h:54
void set_value(M *ptr, const std::string &value)
Set the value of the attribute.
Definition: TextInterfaceEmbed.h:640
void set_detailed_description(const std::string &)
Set the detailed description of the attribute.
Definition: TextInterfaceEmbed.h:312
void set_detailed_description(const std::string &)
Set the detailed description of the attribute.
Definition: TextInterfaceEmbed.h:225
An array of Value interfaces.
Definition: TextInterfaceParser.h:35
void reset_modifiers() const
Reset any output stream modifiers.
Definition: TextInterfaceEmbed.h:488
void reset_modifiers() const
Reset any output stream modifiers.
Definition: TextInterfaceEmbed.h:235
std::string modifiers
Any modifiers set by caller.
Definition: TextInterfaceEmbed.h:256
Template class manages Reference::Able objects.
Definition: Reference.h:74
bool matches(const std::string &name) const
Return true if the name argument matches.
Definition: TextInterfaceEmbed.h:692
void set_value(C *ptr, const std::string &value)
Set the value of the attribute.
Definition: TextInterfaceEmbed.h:358
void set_value(V *ptr, const std::string &value)
Set the value of the attribute.
Definition: TextInterfaceEmbed.h:552
std::string get_name() const
Get the name of the attribute.
Definition: TextInterfaceEmbed.h:208
AttributeGetSet(const std::string &_name, Get _get, Set _set)
Constructor.
Definition: TextInterfaceAttribute.h:262
std::string get_description() const
Get the description of the attribute.
Definition: TextInterfaceEmbed.h:299
std::string range
Range parsed from name during matches.
Definition: TextInterfaceEmbed.h:250
Reference::To< Value > value
Value found during match.
Definition: TextInterfaceEmbed.h:71
std::string get_description() const
Get the description of the attribute.
Definition: TextInterfaceEmbed.h:212
Get get
Method of V that returns E*.
Definition: TextInterfaceEmbed.h:241
Interface to a class attribute with an accessor and modifier methods.
Definition: TextInterfaceAttribute.h:256
VectorOfInterfaces(const std::string &p, Get g, Size s)
Construct from a pointer to element attribute interface.
Definition: TextInterfaceEmbed.h:196
Policy for getting a Parser.
Definition: TextInterfaceEmbed.h:74
std::string get_value() const
Get the value of the attribute.
Definition: TextInterfaceAttribute.h:42
Size size
Method of V that returns size of vector.
Definition: TextInterfaceEmbed.h:244
void set_modifiers(const std::string &) const
Parse any modifiers that will alter the behaviour of the output stream.
Definition: TextInterfaceEmbed.h:463
void set_description(const std::string &)
Set the description of the attribute.
Definition: TextInterfaceEmbed.h:309
std::string name
The name of the attribute.
Definition: TextInterfaceAttribute.h:240
Embedded interface factory for TextInterface::To<C>
Definition: TextInterfaceEmbed.h:261
bool matches(const std::string &name) const
Return true if the name argument matches.
Definition: TextInterfaceEmbed.h:571
Get get
Method of M that returns element, given K.
Definition: TextInterfaceEmbed.h:320
std::string remainder
Remainder parsed from name during matches.
Definition: TextInterfaceEmbed.h:329
void set_description(const std::string &)
Set the description of the attribute.
Definition: TextInterfaceEmbed.h:222
std::string prefix
The name of the map instance.
Definition: TextInterfaceEmbed.h:323
Dynamically embeds the interfaces of elements in a vector.
Definition: TextInterfaceEmbed.h:190
std::string get_name() const
Get the name of the attribute.
Definition: TextInterfaceEmbed.h:295

Generated using doxygen 1.8.17