41#include <drain/UniTuple.h>
49#include <drain/StringTools.h>
50#include <drain/Sprinter.h>
82 PathSeparatorPolicy(
char separator=
'/',
bool lead=
true,
bool repeated=
false,
bool trail=
true) :
84 set(lead, repeated, trail);
86 throw std::runtime_error(
"PathSeparatorPolict (char separator): separator=0, did you mean empty init (\"\")");
116std::ostream & operator<<(std::ostream & ostr,
const PathSeparatorPolicy & policy) {
117 ostr <<
"PathSeparatorPolicy";
118 if (policy.character){
119 ostr <<
'[' << policy.character <<
']';
121 ostr <<
'(' << policy.tuple() <<
')';
136template <
class T,
char SEP=
'/',
bool ALEAD=
true,
bool AREPEAT=
false,
bool ATRAIL=
true>
137class Path :
public std::list<T> {
145 typedef std::list< path_t > list_t;
164 Path(
typename path_t::const_iterator it,
typename path_t::const_iterator it2){
173 template <
typename ... TT>
181 template <
typename ... TT>
183 Path(
const std::string & arg,
const TT &... args){
189 template <
typename ... TT>
191 Path(
const char * arg,
const TT &... args){
216 template <
typename ... TT>
217 void set(
const TT &... args) {
224 template <
typename T2,
typename ... TT>
225 void append(
const T2 & arg,
const TT &... args) {
231 template <
typename ... TT>
232 void append(
const path_t &p,
const TT &... args) {
233 this->insert(this->end(), p.begin(), p.end());
238 template <
typename ... TT>
239 void append(
char c,
const TT &... args) {
241 std::cerr << __FILE__ <<
' ' << __FUNCTION__ <<
"::" <<
" null separator char \n";
243 else if (c==separator.character){
253 template <
typename ... TT>
254 void append(
const char * arg,
const TT &... args) {
260 template <
typename ... TT>
261 void append(
const std::string &arg,
const TT &... args) {
292 this->push_back(elem);
295 else if (this->empty()){
297 this->push_back(elem);
300 else if (this->back().empty()){
303 this->push_back(elem);
308 this->push_back(elem);
311 std::cerr << __FUNCTION__ <<
"? failed in appending: " << sprinter(*
this) <<
'\n';
317 template <
typename T2>
335 return ((this->size()==1) && this->front().empty());
348 return this->front().empty();
364 this->push_front(elem_t());
376 const size_t minLength = COMPLETE ? 0 : 1;
377 while (this->size() > minLength){
379 if (!this->front().empty()){
390 const size_t minLength = COMPLETE ? 0 : 1;
391 while (this->size() > minLength){
393 if (!this->back().empty()){
430 if (this->front().empty()){
431 typename path_t::const_iterator it0 = ++this->begin();
432 typename path_t::const_iterator it = it0;
433 while (it != this->end()) {
454 if (this->back().empty()){
455 typename path_t::const_iterator it0 = --this->end();
456 typename path_t::const_iterator it = it0;
458 while (it != this->begin()) {
503 path_t &
operator=(
const std::string & p){
545 this->insert(this->end(), path.begin(), path.end());
572 std::ostream &
toStream(std::ostream & ostr)
const {
575 ostr << separator.character;
578 layout.arrayChars.separator = separator.character;
590 std::string str()
const {
591 std::stringstream sstr;
597 operator std::string()
const {
601 std::ostream & debug(std::ostream & ostr = std::cout)
const {
603 ostr <<
"Path elems:" << this->size() <<
" sep:" << separator <<
" typeid: " <<
typeid(T).name() <<
"\n";
604 ostr << *
this <<
'\n';
606 for (
typename path_t::const_iterator it = this->begin(); it != this->end(); ++it) {
609 ostr <<
" " << i <<
'\t' << *it <<
'\n';
626 template <typename T2>
627 void _append(const T2 & p){
635 if (start == p.length()){
644 size_t nextSep = p.find(separator.character, start);
647 if (nextSep==std::string::npos){
679template <
class T,
char SEP=
'/',
bool ALEAD=
true,
bool AREPEAT=
false,
bool ATRAIL=
true>
681std::ostream & operator<<(std::ostream & ostr,
const Path<T,SEP,ALEAD,AREPEAT,ATRAIL> & p) {
682 return p.toStream(ostr);
686template <
class T,
char SEP=
'/',
bool ALEAD=
true,
bool AREPEAT=
false,
bool ATRAIL=
true>
688std::istream & operator>>(std::istream &istr, Path<T,SEP,ALEAD,AREPEAT,ATRAIL> & p) {
705template <
class T,
char SEP,
bool ALEAD,
bool AREPEAT,
bool ATRAIL>
706const PathSeparatorPolicy Path<T,SEP,ALEAD,AREPEAT,ATRAIL>::separator(SEP, ALEAD, AREPEAT, ATRAIL);
709template <
class T,
char SEP,
bool ALEAD,
bool AREPEAT,
bool ATRAIL>
715 const std::string & str(){
718 "Path<",
TypeName<T>::str(),
">[", SEP?SEP:
'?',
"](", ALEAD, AREPEAT, ATRAIL,
')');
virtual ~Path()
Why the three above instead of this?
Definition Path.h:210
void simplify()
ORIGINAL. Removes trailing empty elements, except for the root itself.
Definition Path.h:417
void simplifyTail()
Remove duplicates of empty elements from the end.
Definition Path.h:449
virtual std::ostream & toStream(std::ostream &ostr) const
Path is written like a list, adding the separator between items. Exception: root is displayed as sepa...
Definition Path.h:572
void appendElem(const elem_t &elem)
Main method for adding elements.
Definition Path.h:281
void appendSubStr(const std::string &p, size_t start=0)
"Default" append function.
Definition Path.h:633
void appendPath(const char *p)
Add path. Specialized handler for strings (note, possibly: elem_t==std:string)
Definition Path.h:269
void simplifyHead()
Remove duplicates of empty elements from the start.
Definition Path.h:425
void append(const std::string &arg, const TT &... args)
Add elements. Any string argument handled as a path.
Definition Path.h:261
path_t & operator=(const path_t &p)
Assigns a path directly with std::list assignment.
Definition Path.h:479
Path(const char *arg, const TT &... args)
Initialize with a path.
Definition Path.h:191
bool isRoot() const
Returns true, if the path as only one element which is empty. An empty path is not a root.
Definition Path.h:334
Path(const path_t &arg, const TT &... args)
Initialize with a path.
Definition Path.h:175
Path(const path_t &p)
Copy constructor.
Definition Path.h:159
void appendElem(const T2 &elem)
To be specialized in subclasses.
Definition Path.h:319
path_t & operator<<(const elem_t &elem)
Append an element, unless empty string.
Definition Path.h:538
Path(typename path_t::const_iterator it, typename path_t::const_iterator it2)
Secondary copy constructor. Handy for creating a parent path, for example.
Definition Path.h:164
void append(const T2 &arg, const TT &... args)
Append path with element(s), path(s) or string(s).
Definition Path.h:225
Path(const std::string &arg, const TT &... args)
Initialize with a path.
Definition Path.h:183
path_t & operator=(const Path< T2 > &p)
Conversion from str path type.
Definition Path.h:496
void append(char c, const TT &... args)
Add elements, first of which is a character. Any string argument is handled as a path.
Definition Path.h:239
path_t & ensureRoot()
Returns true, if the path is not empty and the first element is empty.
Definition Path.h:362
path_t & operator>>(elem_t &e)
Extract last element.
Definition Path.h:559
void append(const char *arg, const TT &... args)
Add elements. Any string argument handled as a path.
Definition Path.h:254
void trimTail(bool COMPLETE=false)
Removes trailing empty elements. The resulting string presentation will not end with the separator.
Definition Path.h:389
void append()
Terminal function for variadic templates.
Definition Path.h:664
void trimHead(bool COMPLETE=false)
Removes leading empty elements. The resulting string presentation will not start with the separator.
Definition Path.h:375
bool hasRoot() const
Returns true, if the path is not empty and the first element is empty.
Definition Path.h:346
static std::ostream & sequenceToStream(std::ostream &ostr, const T &x, const SprinterLayout &layout)
Convenience: if sequence type (array, list, set, map) not given, assume array.
Definition Sprinter.h:325
Definition StringBuilder.h:58
Tuple of N elements of type T.
Definition UniTuple.h:65
Definition DataSelector.cpp:1277
DRAIN_TYPENAME(void)
Add a specialization for each type of those you want to support.
Determines how separator char (often / ) will be handled in the path.
Definition Path.h:68
bool & acceptRepeated
If true, allow empty elements in the middle (appearing as repeated separators)
Definition Path.h:77
bool & acceptTrailing
If true, allow trailing empty elements (appearing as repeated separators)
Definition Path.h:80
bool & acceptLeading
If true, allow leading empties (ie leading separators) // Accepts one. to start with.
Definition Path.h:74
Definition Sprinter.h:137
Default implementation.
Definition Type.h:541
static const std::string name
Default implementation: name returned by std::type_info::name()
Definition Type.h:549