#include #include #include #include using namespace std; class PathString_for_ptree { string filename; string::size_type start, size; public: PathString_for_ptree( std::string const& s ) : filename(s), start(0), size(filename.size()) {} string dump() const { return filename.substr(start); } bool empty() const { return start == size; } // aka pop_front and return the fragment // modifies the path string reduce() { assert(not empty()); // don't crash in production, just in case if (empty()) return string(); string::size_type next_sep = filename.find('/', start); // no separator, then pretend separator is at the end if (next_sep == string::npos) next_sep = size-1; // include the trailing separator string::size_type old_start = start; start = next_sep+1; return filename.substr(old_start, start-old_start); } bool single() const { // will return true if empty, it should not be asked for empty paths anyway // it is a "single" path if there is a slash BEFORE the last character. // if the last character is /, then it can be a "single" directory. // std::string::size_type idx = filename.find('/', start); return idx == std::string::npos or idx == size-1; } }; static void test( string f, string should_frag, string should_remainder ) { PathString_for_ptree f2(f); cout << f2.dump() << (f2.single() ? " SINGLE" : "") << " --> "; string frag = f2.reduce(); cout << frag << " && " << f2.dump() << endl; if (frag != should_frag) throw logic_error("err frag"); if (f2.dump() != should_remainder) throw logic_error("err remainder"); } static void descend( string f ) { PathString_for_ptree f2(f); while (not f2.empty()) { cout << f2.dump() << (f2.single() ? " SINGLE" : " more") << " --> "; string frag = f2.reduce(); cout << frag << " && " << f2.dump() << endl; } } int main() { test("hello/there/you.txt", "hello/", "there/you.txt"); test("hello/there/you/", "hello/", "there/you/"); test("hello/there/", "hello/", "there/"); test("hello/there.txt", "hello/", "there.txt"); test("there.txt", "there.txt", ""); test("a", "a", ""); test("a/", "a/", ""); test("b/a", "b/", "a"); test("b/a/", "b/", "a/"); test("/a/", "/", "a/"); test("./a/", "./", "a/"); descend("hello/there/you.txt"); return 0; }