41 #include <drain/UniTuple.h>
49 #include <drain/String.h>
50 #include <drain/Sprinter.h>
81 PathSeparatorPolicy(
char separator=
'/',
bool lead=
true,
bool repeated=
false,
bool trail=
true) :
83 set(lead, repeated, trail);
85 throw std::runtime_error(
"PathSeparatorPolict (char separator): separator=0, did you mean empty init (\"\")");
95 std::ostream & operator<<(std::ostream & ostr,
const PathSeparatorPolicy & policy) {
96 ostr <<
"Separator='" << policy.character <<
"', policy=" << policy.tuple();
111 template <
class T,
char SEP=
'/',
bool ALEAD=
true,
bool AREPEAT=
false,
bool ATRAIL=
true>
112 class Path :
public std::list<T> {
120 typedef std::list< path_t > list_t;
125 Path() : separator(SEP, ALEAD, AREPEAT, ATRAIL){
130 Path(
const path_t & p) : std::list<T>(p), separator(p.separator){
135 Path(
typename path_t::const_iterator it,
typename path_t::const_iterator it2) : separator(SEP, ALEAD, AREPEAT, ATRAIL) {
144 template <
typename ... TT>
146 Path(
const path_t & arg,
const TT &... args) : separator(SEP, ALEAD, AREPEAT, ATRAIL){
152 template <
typename ... TT>
154 Path(
const std::string & arg,
const TT &... args) : separator(SEP, ALEAD, AREPEAT, ATRAIL){
160 template <
typename ... TT>
162 Path(
const char * arg,
const TT &... args) : separator(SEP, ALEAD, AREPEAT, ATRAIL){
187 template <
typename ... TT>
188 void set(
const TT &... args) {
195 template <
typename T2,
typename ... TT>
196 void append(
const T2 & arg,
const TT &... args) {
201 template <
typename ... TT>
202 void append(
const path_t &p,
const TT &... args) {
203 this->insert(this->end(), p.begin(), p.end());
207 template <
typename ... TT>
208 void append(
const char * arg,
const TT &... args) {
213 template <
typename ... TT>
214 void append(
const std::string &arg,
const TT &... args) {
245 this->push_back(elem);
248 else if (this->empty()){
250 this->push_back(elem);
253 else if (this->back().empty()){
256 this->push_back(elem);
261 this->push_back(elem);
264 std::cerr << __FUNCTION__ <<
"? failed in appending: " << sprinter(*
this) <<
'\n';
281 return ((this->size()==1) && this->front().empty());
294 return this->front().empty();
310 this->push_front(elem_t());
322 const size_t minLength = COMPLETE ? 0 : 1;
323 while (this->size() > minLength){
325 if (!this->front().empty()){
336 const size_t minLength = COMPLETE ? 0 : 1;
337 while (this->size() > minLength){
339 if (!this->back().empty()){
376 if (this->front().empty()){
377 typename path_t::const_iterator it0 = ++this->begin();
378 typename path_t::const_iterator it = it0;
379 while (it != this->end()) {
400 if (this->back().empty()){
401 typename path_t::const_iterator it0 = --this->end();
402 typename path_t::const_iterator it = it0;
404 while (it != this->begin()) {
449 path_t &
operator=(
const std::string & p){
491 this->insert(this->end(), path.begin(), path.end());
518 std::ostream &
toStream(std::ostream & ostr)
const {
521 ostr << separator.character;
524 layout.arrayChars.separator = separator.character;
536 std::string str()
const {
537 std::stringstream sstr;
543 operator std::string()
const {
547 std::ostream & debug(std::ostream & ostr = std::cout)
const {
549 ostr <<
"Path elems:" << this->size() <<
" sep:" << separator <<
" typeid: " <<
typeid(T).name() <<
"\n";
550 ostr << *
this <<
'\n';
552 for (
typename path_t::const_iterator it = this->begin(); it != this->end(); ++it) {
555 ostr <<
" " << i <<
'\t' << *it <<
'\n';
571 template <
typename T2>
580 if (start == p.length()){
589 size_t nextSep = p.find(separator.character, start);
592 if (nextSep==std::string::npos){
624 template <
class T,
char SEP=
'/',
bool ALEAD=
true,
bool AREPEAT=
false,
bool ATRAIL=
true>
626 std::ostream & operator<<(std::ostream & ostr,
const Path<T,SEP,ALEAD,AREPEAT,ATRAIL> & p) {
627 return p.toStream(ostr);
631 template <
class T,
char SEP=
'/',
bool ALEAD=
true,
bool AREPEAT=
false,
bool ATRAIL=
true>
633 std::istream & operator>>(std::istream &istr, Path<T,SEP,ALEAD,AREPEAT,ATRAIL> & p) {
virtual ~Path()
Why the three above instead of this?
Definition: Path.h:181
void simplify()
ORIGINAL. Removes trailing empty elements, except for the root itself.
Definition: Path.h:363
void _append(const T2 &p)
Handler for all the rest args, assumed convertable to elem_t.
Definition: Path.h:572
void simplifyTail()
Remove duplicates of empty elements from the end.
Definition: Path.h:395
void _appendPath(const std::string &p, size_t start=0)
Extract elements from the string, starting at position i.
Definition: Path.h:578
path_t & operator<<(const elem_t &elem)
Append an element, unless empty string.
Definition: Path.h:484
void appendElem(const elem_t &elem)
Main method for adding elements.
Definition: Path.h:234
void appendPath(const char *p)
Specialized handler for strings (note, possibly: elem_t==std:::string)
Definition: Path.h:222
void simplifyHead()
Remove duplicates of empty elements from the start.
Definition: Path.h:371
path_t & operator=(const Path< T2 > &p)
Conversion from str path type.
Definition: Path.h:442
Path(const char *arg, const TT &... args)
Initialize with a path.
Definition: Path.h:162
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:280
Path(const path_t &arg, const TT &... args)
Initialize with a path.
Definition: Path.h:146
Path(const path_t &p)
Copy constructor.
Definition: Path.h:130
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:518
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:135
void append(const T2 &arg, const TT &... args)
Append path with element(s), path(s) or string(s).
Definition: Path.h:196
Path(const std::string &arg, const TT &... args)
Initialize with a path.
Definition: Path.h:154
path_t & ensureRoot()
Returns true, if the path is not empty and the first element is empty.
Definition: Path.h:308
void trimTail(bool COMPLETE=false)
Removes trailing empty elements. The resulting string presentation will not end with the separator.
Definition: Path.h:335
void append()
Terminal function for variadic templates.
Definition: Path.h:609
void trimHead(bool COMPLETE=false)
Removes leading empty elements. The resulting string presentation will not start with the separator.
Definition: Path.h:321
bool hasRoot() const
Returns true, if the path is not empty and the first element is empty.
Definition: Path.h:292
void _append(const elem_t &elem)
"Default" append function.
Definition: Path.h:564
path_t & operator=(const path_t &p)
Assigns a path directly with std::list assignment.
Definition: Path.h:425
path_t & operator>>(elem_t &e)
Extract last element.
Definition: Path.h:505
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:321
Tuple of N elements of type T.
Definition: UniTuple.h:65
Definition: DataSelector.cpp:1277
Determines if separators will be stored in the path.
Definition: Path.h:67
bool & acceptRepeated
If true, allow empty elements in the middle (appearing as repeated separators)
Definition: Path.h:76
bool & acceptTrailing
If true, allow trailing empty elements (appearing as repeated separators)
Definition: Path.h:79
bool & acceptLeading
If true, allow leading empties (ie leading separators) // Accepts one. to start with.
Definition: Path.h:73
Definition: Sprinter.h:137