#include <ostream> #include <dirent.h> #include <assert.h> #include <sstream> #include <string> #include <memory> #include <vector> #include <iostream> #include <algorithm> typedef bool bool_t; typedef unsigned char short_t; typedef unsigned short smallint_t; typedef unsigned int int_t; typedef unsigned long long_t; namespace variadic { template<bool D, typename Head, typename... Tail> struct accumulate_stream { static void call(std::ostringstream& stream, const Head& head, const Tail&... tail) { stream << head; accumulate_stream<sizeof...(Tail) == 1, Tail...>::call(stream, tail...); } }; template<class Head> struct accumulate_stream<true, Head> { static void call(std::ostringstream& stream, const Head& head) { stream << head; } }; template<bool D, typename Head, typename... Tail> struct accumulate_stream_separated { static void call(std::ostringstream& stream, const char separator, const Head& head, const Tail&... tail) { stream << separator << head; accumulate_stream_separated<sizeof...(Tail) == 1, Tail...>::call(stream, tail...); } }; template<class Head> struct accumulate_stream_separated<true, Head> { static void call(std::ostringstream& stream, const char separator, const Head& head) { stream << separator << head; } }; template<typename Head, typename... Tail> static const std::string accumulate(const Head& head, const Tail&... tail) { std::ostringstream oss; variadic::accumulate_stream<sizeof...(Tail) == 0, Head, Tail...>::call(oss, head, tail...); return oss.str(); } template<typename Head, typename... Tail> static const std::string accumulate_separator(const char separator, const Head& head, const Tail&... tail) { std::ostringstream oss; variadic::accumulate_stream_separated<sizeof...(Tail) == 0, Head, Tail...>::call(oss, separator, head, tail...); return oss.str(); } } //// namespace fs { class any; typedef long_t size_t; typedef int_t inner_int_t; extern const fs::size_t not_fetched = -1; extern const fs::size_t unknown = -2; extern const fs::size_t empty = 0; static any* no_parent = nullptr; extern const char separator = '/'; extern const char dot = '.'; typedef inner_int_t file_type; typedef std::string directory_name; typedef std::string file_name; typedef std::string path; typedef std::string ext; class variadic_constructor {}; class unknown_ext { public: unknown_ext(const fs::ext& E) : m_e(E) {} virtual ~unknown_ext() throw() {} const fs::ext& what() const throw() { return m_e; } private: const fs::ext m_e; }; class any { public: typedef std::shared_ptr<any> ptr; typedef const std::shared_ptr<any> const_ptr; any() : m_parent(fs::no_parent), m_name(), m_size(fs::unknown), m_offset(fs::unknown), m_childs() {std::cout<<"any::no arg"<<std::endl;} any(const std::string& n) : m_parent(fs::no_parent), m_name(n), m_size(fs::not_fetched), m_offset(fs::not_fetched), m_childs() {std::cout<<"any::string"<<std::endl;} any(ptr p, const std::string& n) : m_parent(p), m_name(n), m_size(fs::not_fetched), m_offset(fs::not_fetched), m_childs() {std::cout<<"any::parent string"<<std::endl;} template<typename Head, typename... Tail> any(const Head& head, const Tail&... tail) : m_parent(fs::no_parent), m_name(variadic::accumulate_separator(fs::separator, head, tail...)), m_size(fs::unknown), m_offset(fs::unknown), m_childs() {std::cout<<"any::variadic"<<std::endl;} virtual ~any() { m_childs.clear(); } virtual inline bool is_file() const = 0; virtual inline bool is_directory() const = 0; const std::string& name() const { return m_name; } inline fs::size_t size() const { return m_size; } inline fs::size_t offset() const { return m_offset; } std::vector<ptr>::iterator begin() { return std::begin(m_childs); } std::vector<ptr>::iterator end() { return std::end(m_childs); } const std::string path(const std::string& Pf) const { auto str(variadic::accumulate(Pf, fs::separator, m_name)); return m_parent ? path(str) : str; } protected: const_ptr m_parent; std::string m_name; fs::size_t m_size; fs::size_t m_offset; /// Only used if you're using fs::write std::vector<ptr> m_childs; void update_size() { m_size = std::accumulate(begin(), end(), 0, [](fs::size_t a, ptr b) { assert(b->size() != fs::unknown); return a+b->size(); }); if(m_parent) m_parent->update_size(); } private: //virtual const std::string str() const = 0; }; class directory: public any { public: typedef std::shared_ptr<directory> ptr; typedef const std::shared_ptr<directory> const_ptr; class could_not_open { public: could_not_open(const fs::directory_name& P) : m_p(P) {} virtual ~could_not_open() throw() {} const fs::directory_name& what() const throw() { return m_p; } private: const fs::directory_name m_p; }; enum child_type: unsigned short { Unknown, OnlyFiles, OnlyDirectories, Mixed }; directory() : any(){ std::cout << "dir::no arg" << std::endl; } directory(const fs::directory_name& n, bool recursive) : any(n){ std::cout << "dir::string/bool"<<std::endl;} directory(ptr p, const fs::directory_name& n, bool recursive) : any(p, n) { std::cout << "dir::parent/string/bool"<<std::endl;} template<typename Head, typename... Tail> directory(const Head& head, const Tail&... tail) : any(head, tail...) {std::cout<<"dir::variadic"<<std::endl;} virtual ~directory() { } inline bool is_file() const { return false; } inline bool is_directory() const { return true; } }; } int main() { fs::directory::ptr A(new fs::directory()); fs::directory::ptr B(new fs::directory("ABC", true)); fs::directory::ptr C(new fs::directory(B, "DEF", true)); fs::directory::ptr D(new fs::directory("A", "B", "C")); }
Standard input is empty
prog.cpp: In instantiation of ‘static void variadic::accumulate_stream_separated<D, Head, Tail>::call(std::ostringstream&, char, const Head&, const Tail& ...) [with bool D = false; Head = std::shared_ptr<fs::directory>; Tail = {std::basic_string<char, std::char_traits<char>, std::allocator<char> >}; std::ostringstream = std::basic_ostringstream<char>]’: prog.cpp:62:9: required from ‘const string variadic::accumulate_separator(char, const Head&, const Tail& ...) [with Head = std::shared_ptr<fs::directory>; Tail = {std::basic_string<char, std::char_traits<char>, std::allocator<char> >}; std::string = std::basic_string<char>]’ prog.cpp:107:202: required from ‘fs::any::any(const Head&, const Tail& ...) [with Head = std::shared_ptr<fs::directory>; Tail = {std::basic_string<char, std::char_traits<char>, std::allocator<char> >}]’ prog.cpp:163:81: required from here prog.cpp:40:13: error: no matching function for call to ‘variadic::accumulate_stream_separated<true, std::basic_string<char> >::call(std::ostringstream&, const std::basic_string<char>&)’ prog.cpp:40:13: note: candidate is: prog.cpp:46:21: note: static void variadic::accumulate_stream_separated<true, Head>::call(std::ostringstream&, char, const Head&) [with Head = std::basic_string<char>; std::ostringstream = std::basic_ostringstream<char>] prog.cpp:46:21: note: candidate expects 3 arguments, 2 provided prog.cpp: In instantiation of ‘static void variadic::accumulate_stream_separated<D, Head, Tail>::call(std::ostringstream&, char, const Head&, const Tail& ...) [with bool D = false; Head = char [4]; Tail = {bool}; std::ostringstream = std::basic_ostringstream<char>]’: prog.cpp:62:9: required from ‘const string variadic::accumulate_separator(char, const Head&, const Tail& ...) [with Head = char [4]; Tail = {bool}; std::string = std::basic_string<char>]’ prog.cpp:107:202: required from ‘fs::any::any(const Head&, const Tail& ...) [with Head = char [4]; Tail = {bool}]’ prog.cpp:165:77: required from ‘fs::directory::directory(const Head&, const Tail& ...) [with Head = char [4]; Tail = {bool}]’ prog.cpp:175:55: required from here prog.cpp:40:13: error: no matching function for call to ‘variadic::accumulate_stream_separated<true, bool>::call(std::ostringstream&, const bool&)’ prog.cpp:40:13: note: candidate is: prog.cpp:46:21: note: static void variadic::accumulate_stream_separated<true, Head>::call(std::ostringstream&, char, const Head&) [with Head = bool; std::ostringstream = std::basic_ostringstream<char>] prog.cpp:46:21: note: candidate expects 3 arguments, 2 provided prog.cpp: In instantiation of ‘static void variadic::accumulate_stream_separated<D, Head, Tail>::call(std::ostringstream&, char, const Head&, const Tail& ...) [with bool D = false; Head = std::shared_ptr<fs::directory>; Tail = {char [4], bool}; std::ostringstream = std::basic_ostringstream<char>]’: prog.cpp:62:9: required from ‘const string variadic::accumulate_separator(char, const Head&, const Tail& ...) [with Head = std::shared_ptr<fs::directory>; Tail = {char [4], bool}; std::string = std::basic_string<char>]’ prog.cpp:107:202: required from ‘fs::any::any(const Head&, const Tail& ...) [with Head = std::shared_ptr<fs::directory>; Tail = {char [4], bool}]’ prog.cpp:165:77: required from ‘fs::directory::directory(const Head&, const Tail& ...) [with Head = std::shared_ptr<fs::directory>; Tail = {char [4], bool}]’ prog.cpp:176:58: required from here prog.cpp:40:13: error: no matching function for call to ‘variadic::accumulate_stream_separated<false, char [4], bool>::call(std::ostringstream&, const char [4], const bool&)’ prog.cpp:40:13: note: candidate is: prog.cpp:37:21: note: static void variadic::accumulate_stream_separated<D, Head, Tail>::call(std::ostringstream&, char, const Head&, const Tail& ...) [with bool D = false; Head = char [4]; Tail = {bool}; std::ostringstream = std::basic_ostringstream<char>] prog.cpp:37:21: note: candidate expects 4 arguments, 3 provided prog.cpp: In instantiation of ‘static void variadic::accumulate_stream_separated<D, Head, Tail>::call(std::ostringstream&, char, const Head&, const Tail& ...) [with bool D = false; Head = char [2]; Tail = {char [2], char [2]}; std::ostringstream = std::basic_ostringstream<char>]’: prog.cpp:62:9: required from ‘const string variadic::accumulate_separator(char, const Head&, const Tail& ...) [with Head = char [2]; Tail = {char [2], char [2]}; std::string = std::basic_string<char>]’ prog.cpp:107:202: required from ‘fs::any::any(const Head&, const Tail& ...) [with Head = char [2]; Tail = {char [2], char [2]}]’ prog.cpp:165:77: required from ‘fs::directory::directory(const Head&, const Tail& ...) [with Head = char [2]; Tail = {char [2], char [2]}]’ prog.cpp:177:57: required from here prog.cpp:40:13: error: no matching function for call to ‘variadic::accumulate_stream_separated<false, char [2], char [2]>::call(std::ostringstream&, const char [2], const char [2])’ prog.cpp:40:13: note: candidate is: prog.cpp:37:21: note: static void variadic::accumulate_stream_separated<D, Head, Tail>::call(std::ostringstream&, char, const Head&, const Tail& ...) [with bool D = false; Head = char [2]; Tail = {char [2]}; std::ostringstream = std::basic_ostringstream<char>] prog.cpp:37:21: note: candidate expects 4 arguments, 3 provided prog.cpp: In instantiation of ‘static void variadic::accumulate_stream_separated<D, Head, Tail>::call(std::ostringstream&, char, const Head&, const Tail& ...) [with bool D = false; Head = char [2]; Tail = {char [2]}; std::ostringstream = std::basic_ostringstream<char>]’: prog.cpp:40:13: required from ‘static void variadic::accumulate_stream_separated<D, Head, Tail>::call(std::ostringstream&, char, const Head&, const Tail& ...) [with bool D = false; Head = char [2]; Tail = {char [2], char [2]}; std::ostringstream = std::basic_ostringstream<char>]’ prog.cpp:62:9: required from ‘const string variadic::accumulate_separator(char, const Head&, const Tail& ...) [with Head = char [2]; Tail = {char [2], char [2]}; std::string = std::basic_string<char>]’ prog.cpp:107:202: required from ‘fs::any::any(const Head&, const Tail& ...) [with Head = char [2]; Tail = {char [2], char [2]}]’ prog.cpp:165:77: required from ‘fs::directory::directory(const Head&, const Tail& ...) [with Head = char [2]; Tail = {char [2], char [2]}]’ prog.cpp:177:57: required from here prog.cpp:40:13: error: no matching function for call to ‘variadic::accumulate_stream_separated<true, char [2]>::call(std::ostringstream&, const char [2])’ prog.cpp:40:13: note: candidate is: prog.cpp:46:21: note: static void variadic::accumulate_stream_separated<true, Head>::call(std::ostringstream&, char, const Head&) [with Head = char [2]; std::ostringstream = std::basic_ostringstream<char>] prog.cpp:46:21: note: candidate expects 3 arguments, 2 provided
Standard output is empty