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
18namespace 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>
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>
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
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
281 { prefix=copy.prefix; get=copy.get; }
282
284
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
334template<class C, class T, class G, class S>
335std::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}
352catch (Error& error)
353{
354 return "-";
355}
356
357template<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}
366catch (Error& error)
367{
368 throw error += "TextInterface::OptionalInterface::set_value";
369}
370
371template<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
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}
457catch (Error& error)
458{
459 throw error += "TextInterface::OptionalInterface::matches";
460}
461
462template<class C, class T, class G, class S>
463void 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}
482catch (Error& error)
483{
484 throw error += "TextInterface::OptionalInterface::set_modifiers";
485}
486
487template<class C, class T, class G, class S>
489{
490 if (value)
491 value->reset_modifiers ();
492 else
494}
495catch (Error& error)
496{
497 throw error += "TextInterface::OptionalInterface::reset_modifiers";
498}
499
500
501
502
503
504
505
506
507template<class V, class G, class S>
508std::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
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}
546catch (Error& error)
547{
548 throw error += "TextInterface::VectorOfInterfaces::get_value";
549}
550
551template<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}
564catch (Error& error)
565{
566 throw error += "TextInterface::VectorOfInterfaces::set_value";
567}
568
569template<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}
601catch (Error& error)
602{
603 throw error += "TextInterface::VectorOfInterfaces::matches";
604}
605
606template<class M, class K, class G>
607std::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}
634catch (Error& error)
635{
636 throw error += "TextInterface::MapOfInterfaces::get_value";
637}
638
639template<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}
652catch (Error& error)
653{
654 throw error += "TextInterface::MapOfInterfaces::set_value";
655}
656
657template<class M, class K, class G>
658void
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}
685catch (Error& error)
686{
687 throw error += "TextInterface::MapOfInterfaces::get_indeces";
688}
689
690template<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}
718catch (Error& error)
719{
720 throw error += "TextInterface::MapOfInterfaces::matches";
721}
722
723#endif
A convenient exception handling class.
Definition Error.h:54
Template class manages Reference::Able objects.
Definition ReferenceTo.h:25
Attribute< C > * clone() const
Return a clone.
Definition TextInterfaceAttribute.h:260
AttributeGetSet(const std::string &_name, Get _get, Set _set)
Constructor.
Definition TextInterfaceAttribute.h:256
void set_value(C *ptr, const std::string &value)
Set the value of the attribute.
Definition TextInterfaceAttribute.h:263
Get get
The get method.
Definition TextInterfaceAttribute.h:243
void reset_modifiers() const
Reset any output stream modifiers.
Definition TextInterfaceAttribute.h:228
std::string get_name() const
Get the name of the attribute.
Definition TextInterfaceAttribute.h:200
void set_modifiers(const std::string &modifiers) const
Parse any modifiers that will alter the behaviour of the output stream.
Definition TextInterfaceAttribute.h:225
std::string name
The name of the attribute.
Definition TextInterfaceAttribute.h:234
std::string get_value() const
Get the value of the attribute.
Definition TextInterfaceAttribute.h:31
Reference::To< C, false > instance
Pointer to the instance from which attribute value will be obtained.
Definition TextInterfaceAttribute.h:54
Attribute()
Default constructor.
Definition TextInterfaceAttribute.h:28
Embedded interface factory for TextInterface::To<C>
Definition TextInterfaceEmbed.h:257
Policy for getting a Parser.
Definition TextInterfaceEmbed.h:70
MapOfInterfaces(const MapOfInterfaces &copy)
Copy constructor.
Definition TextInterfaceEmbed.h:280
std::string remainder
Remainder parsed from name during matches.
Definition TextInterfaceEmbed.h:324
std::string get_name() const
Get the name of the attribute.
Definition TextInterfaceEmbed.h:290
void set_detailed_description(const std::string &)
Set the detailed description of the attribute.
Definition TextInterfaceEmbed.h:307
bool matches(const std::string &name) const
Return true if the name argument matches.
Definition TextInterfaceEmbed.h:692
MapOfInterfaces(const std::string &pre, Get g)
Construct from a pointer to parent class attribute interface.
Definition TextInterfaceEmbed.h:276
void set_value(M *ptr, const std::string &value)
Set the value of the attribute.
Definition TextInterfaceEmbed.h:640
Attribute< M > * clone() const
Set the prefix to be added before attribute name.
Definition TextInterfaceEmbed.h:286
std::string range
Range parsed from name during matches.
Definition TextInterfaceEmbed.h:321
Get get
Method of M that returns element, given K.
Definition TextInterfaceEmbed.h:315
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
void set_description(const std::string &)
Set the description of the attribute.
Definition TextInterfaceEmbed.h:304
std::string get_description() const
Get the description of the attribute.
Definition TextInterfaceEmbed.h:294
std::string prefix
The name of the map instance.
Definition TextInterfaceEmbed.h:318
Dynamically embeds the interface of something that can be got and set.
Definition TextInterfaceEmbed.h:27
bool matches(const std::string &name) const
Return true if the name argument matches.
Definition TextInterfaceEmbed.h:373
void set_modifiers(const std::string &) const
Parse any modifiers that will alter the behaviour of the output stream.
Definition TextInterfaceEmbed.h:463
Reference::To< Value > value
Value found during match.
Definition TextInterfaceEmbed.h:61
void set_value(C *ptr, const std::string &value)
Set the value of the attribute.
Definition TextInterfaceEmbed.h:358
OptionalInterface(const std::string &t, Get g, Set s)
Construct from a pointer to element attribute interface.
Definition TextInterfaceEmbed.h:32
std::string get_name() const
Get the name of the attribute.
Definition TextInterfaceEmbed.h:41
void reset_modifiers() const
Reset any output stream modifiers.
Definition TextInterfaceEmbed.h:488
An array of Value interfaces.
Definition TextInterfaceParser.h:31
virtual std::string get_value() const =0
Get the value as text.
Reference::To< Parser, false > parent
The Parser composite in which this Value component is integrated.
Definition TextInterfaceValue.h:75
Dynamically embeds the interfaces of elements in a vector.
Definition TextInterfaceEmbed.h:186
VectorOfInterfaces(const VectorOfInterfaces &copy)
Copy constructor.
Definition TextInterfaceEmbed.h:195
std::string remainder
Remainder parsed from name during matches.
Definition TextInterfaceEmbed.h:248
Get get
Method of V that returns E*.
Definition TextInterfaceEmbed.h:236
std::string modifiers
Any modifiers set by caller.
Definition TextInterfaceEmbed.h:251
VectorOfInterfaces(const std::string &p, Get g, Size s)
Construct from a pointer to element attribute interface.
Definition TextInterfaceEmbed.h:191
void reset_modifiers() const
Reset any output stream modifiers.
Definition TextInterfaceEmbed.h:230
bool matches(const std::string &name) const
Return true if the name argument matches.
Definition TextInterfaceEmbed.h:571
Attribute< V > * clone() const
Retun a newly constructed copy.
Definition TextInterfaceEmbed.h:199
std::string prefix
The name of the vector instance.
Definition TextInterfaceEmbed.h:242
void set_detailed_description(const std::string &)
Set the detailed description of the attribute.
Definition TextInterfaceEmbed.h:220
void set_value(V *ptr, const std::string &value)
Set the value of the attribute.
Definition TextInterfaceEmbed.h:552
Size size
Method of V that returns size of vector.
Definition TextInterfaceEmbed.h:239
std::string get_name() const
Get the name of the attribute.
Definition TextInterfaceEmbed.h:203
std::string range
Range parsed from name during matches.
Definition TextInterfaceEmbed.h:245
void set_modifiers(const std::string &mod) const
Parse any modifiers that will alter the behaviour of the output stream.
Definition TextInterfaceEmbed.h:226
std::string get_description() const
Get the description of the attribute.
Definition TextInterfaceEmbed.h:207
void set_description(const std::string &)
Set the description of the attribute.
Definition TextInterfaceEmbed.h:217

Generated using doxygen 1.14.0