fork download
  1. #include <ostream>
  2. #include <dirent.h>
  3. #include <assert.h>
  4. #include <sstream>
  5. #include <string>
  6. #include <memory>
  7. #include <vector>
  8. #include <iostream>
  9. #include <algorithm>
  10. typedef bool bool_t;
  11. typedef unsigned char short_t;
  12. typedef unsigned short smallint_t;
  13. typedef unsigned int int_t;
  14. typedef unsigned long long_t;
  15. namespace variadic
  16. {
  17. template<bool D, typename Head, typename... Tail>
  18. struct accumulate_stream
  19. {
  20. static void call(std::ostringstream& stream, const Head& head, const Tail&... tail)
  21. {
  22. stream << head;
  23. accumulate_stream<sizeof...(Tail) == 1, Tail...>::call(stream, tail...);
  24. }
  25. };
  26. template<class Head>
  27. struct accumulate_stream<true, Head>
  28. {
  29. static void call(std::ostringstream& stream, const Head& head)
  30. {
  31. stream << head;
  32. }
  33. };
  34. template<bool D, typename Head, typename... Tail>
  35. struct accumulate_stream_separated
  36. {
  37. static void call(std::ostringstream& stream, const char separator, const Head& head, const Tail&... tail)
  38. {
  39. stream << separator << head;
  40. accumulate_stream_separated<sizeof...(Tail) == 1, Tail...>::call(stream, tail...);
  41. }
  42. };
  43. template<class Head>
  44. struct accumulate_stream_separated<true, Head>
  45. {
  46. static void call(std::ostringstream& stream, const char separator, const Head& head)
  47. {
  48. stream << separator << head;
  49. }
  50. };
  51. template<typename Head, typename... Tail>
  52. static const std::string accumulate(const Head& head, const Tail&... tail)
  53. {
  54. std::ostringstream oss;
  55. variadic::accumulate_stream<sizeof...(Tail) == 0, Head, Tail...>::call(oss, head, tail...);
  56. return oss.str();
  57. }
  58. template<typename Head, typename... Tail>
  59. static const std::string accumulate_separator(const char separator, const Head& head, const Tail&... tail)
  60. {
  61. std::ostringstream oss;
  62. variadic::accumulate_stream_separated<sizeof...(Tail) == 0, Head, Tail...>::call(oss, separator, head, tail...);
  63. return oss.str();
  64. }
  65. }
  66.  
  67.  
  68.  
  69. ////
  70.  
  71.  
  72. namespace fs
  73. {
  74. class any;
  75. typedef long_t size_t;
  76. typedef int_t inner_int_t;
  77. extern const fs::size_t not_fetched = -1;
  78. extern const fs::size_t unknown = -2;
  79. extern const fs::size_t empty = 0;
  80. static any* no_parent = nullptr;
  81. extern const char separator = '/';
  82. extern const char dot = '.';
  83. typedef inner_int_t file_type;
  84. typedef std::string directory_name;
  85. typedef std::string file_name;
  86. typedef std::string path;
  87. typedef std::string ext;
  88. class variadic_constructor {};
  89. class unknown_ext
  90. {
  91. public:
  92. unknown_ext(const fs::ext& E) : m_e(E) {}
  93. virtual ~unknown_ext() throw() {}
  94. const fs::ext& what() const throw() { return m_e; }
  95. private:
  96. const fs::ext m_e;
  97. };
  98. class any
  99. {
  100. public:
  101. typedef std::shared_ptr<any> ptr;
  102. typedef const std::shared_ptr<any> const_ptr;
  103. 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;}
  104. 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;}
  105. 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;}
  106. template<typename Head, typename... Tail>
  107. 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;}
  108. virtual ~any() { m_childs.clear(); }
  109. virtual inline bool is_file() const = 0;
  110. virtual inline bool is_directory() const = 0;
  111. const std::string& name() const { return m_name; }
  112. inline fs::size_t size() const { return m_size; }
  113. inline fs::size_t offset() const { return m_offset; }
  114. std::vector<ptr>::iterator begin() { return std::begin(m_childs); }
  115. std::vector<ptr>::iterator end() { return std::end(m_childs); }
  116. const std::string path(const std::string& Pf) const
  117. {
  118. auto str(variadic::accumulate(Pf, fs::separator, m_name));
  119. return m_parent ? path(str) : str;
  120. }
  121. protected:
  122. const_ptr m_parent;
  123. std::string m_name;
  124. fs::size_t m_size;
  125. fs::size_t m_offset; /// Only used if you're using fs::write
  126. std::vector<ptr> m_childs;
  127. void update_size()
  128. {
  129. m_size = std::accumulate(begin(), end(), 0,
  130. [](fs::size_t a, ptr b)
  131. {
  132. assert(b->size() != fs::unknown);
  133. return a+b->size();
  134. });
  135. if(m_parent) m_parent->update_size();
  136. }
  137. private:
  138. //virtual const std::string str() const = 0;
  139. };
  140. class directory: public any
  141. {
  142. public:
  143. typedef std::shared_ptr<directory> ptr;
  144. typedef const std::shared_ptr<directory> const_ptr;
  145. class could_not_open
  146. {
  147. public:
  148. could_not_open(const fs::directory_name& P) : m_p(P) {}
  149. virtual ~could_not_open() throw() {}
  150. const fs::directory_name& what() const throw() { return m_p; }
  151. private:
  152. const fs::directory_name m_p;
  153. };
  154. enum child_type: unsigned short
  155. {
  156. Unknown,
  157. OnlyFiles,
  158. OnlyDirectories,
  159. Mixed
  160. };
  161. directory() : any(){ std::cout << "dir::no arg" << std::endl; }
  162. directory(const fs::directory_name& n, bool recursive) : any(n){ std::cout << "dir::string/bool"<<std::endl;}
  163. directory(ptr p, const fs::directory_name& n, bool recursive) : any(p, n) { std::cout << "dir::parent/string/bool"<<std::endl;}
  164. template<typename Head, typename... Tail>
  165. directory(const Head& head, const Tail&... tail) : any(head, tail...) {std::cout<<"dir::variadic"<<std::endl;}
  166. virtual ~directory() { }
  167. inline bool is_file() const { return false; }
  168. inline bool is_directory() const { return true; }
  169. };
  170. }
  171.  
  172. int main()
  173. {
  174. fs::directory::ptr A(new fs::directory());
  175. fs::directory::ptr B(new fs::directory("ABC", true));
  176. fs::directory::ptr C(new fs::directory(B, "DEF", true));
  177. fs::directory::ptr D(new fs::directory("A", "B", "C"));
  178. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
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
stdout
Standard output is empty