]> AND Private Git Repository - canny.git/blob - stc/exp/ml_stc_linux_make_v1.0/include/boost/filesystem/convenience.hpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
6491c1d25978fd6c4b7602f9d5def7711b2e64f8
[canny.git] / stc / exp / ml_stc_linux_make_v1.0 / include / boost / filesystem / convenience.hpp
1 //  boost/filesystem/convenience.hpp  ----------------------------------------//\r
2 \r
3 //  Copyright Beman Dawes, 2002-2005\r
4 //  Copyright Vladimir Prus, 2002\r
5 //  Use, modification, and distribution is subject to the Boost Software\r
6 //  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at\r
7 //  http://www.boost.org/LICENSE_1_0.txt)\r
8 \r
9 //  See library home page at http://www.boost.org/libs/filesystem\r
10 \r
11 //----------------------------------------------------------------------------// \r
12 \r
13 #ifndef BOOST_FILESYSTEM_CONVENIENCE_HPP\r
14 #define BOOST_FILESYSTEM_CONVENIENCE_HPP\r
15 \r
16 #include <boost/filesystem/operations.hpp>\r
17 #include <boost/system/error_code.hpp>\r
18 #include <vector>\r
19 #include <stack>\r
20 \r
21 #include <boost/config/abi_prefix.hpp> // must be the last #include\r
22 \r
23 # ifndef BOOST_FILESYSTEM_NARROW_ONLY\r
24 #   define BOOST_FS_FUNC(BOOST_FS_TYPE) \\r
25       template<class Path> typename boost::enable_if<is_basic_path<Path>, \\r
26       BOOST_FS_TYPE>::type\r
27 #   define BOOST_FS_FUNC_STRING BOOST_FS_FUNC(typename Path::string_type)\r
28 #   define BOOST_FS_TYPENAME typename\r
29 # else\r
30 #   define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE \r
31     typedef boost::filesystem::path Path;\r
32 #   define BOOST_FS_FUNC_STRING inline std::string\r
33 #   define BOOST_FS_TYPENAME\r
34 # endif\r
35 \r
36 namespace boost\r
37 {\r
38   namespace filesystem\r
39   {\r
40 \r
41     BOOST_FS_FUNC(bool) create_directories(const Path& ph)\r
42     {\r
43          if (ph.empty() || exists(ph))\r
44          {\r
45            if ( !ph.empty() && !is_directory(ph) )\r
46                boost::throw_exception( basic_filesystem_error<Path>(\r
47                  "boost::filesystem::create_directories", ph,\r
48                  make_error_code( boost::system::posix::file_exists ) ) );\r
49            return false;\r
50          }\r
51 \r
52          // First create branch, by calling ourself recursively\r
53          create_directories(ph.parent_path());\r
54          // Now that parent's path exists, create the directory\r
55          create_directory(ph);\r
56          return true;\r
57      }\r
58 \r
59 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED\r
60 \r
61     BOOST_FS_FUNC_STRING extension(const Path& ph)\r
62     {\r
63       typedef BOOST_FS_TYPENAME Path::string_type string_type;\r
64       string_type filename = ph.filename();\r
65 \r
66       BOOST_FS_TYPENAME string_type::size_type n = filename.rfind('.');\r
67       if (n != string_type::npos)\r
68         return filename.substr(n);\r
69       else\r
70         return string_type();\r
71     }\r
72 \r
73     BOOST_FS_FUNC_STRING basename(const Path& ph)\r
74     {\r
75       typedef BOOST_FS_TYPENAME Path::string_type string_type;\r
76       string_type filename = ph.filename();\r
77       BOOST_FS_TYPENAME string_type::size_type n = filename.rfind('.');\r
78       return filename.substr(0, n);\r
79     }\r
80 \r
81 \r
82     BOOST_FS_FUNC(Path) change_extension( const Path & ph,\r
83       const BOOST_FS_TYPENAME Path::string_type & new_extension )\r
84       { return ph.parent_path() / (basename(ph) + new_extension); }\r
85 \r
86 # endif\r
87 \r
88 # ifndef BOOST_FILESYSTEM_NARROW_ONLY\r
89 \r
90     // "do-the-right-thing" overloads  ---------------------------------------//\r
91 \r
92     inline bool create_directories(const path& ph)\r
93       { return create_directories<path>(ph); }\r
94     inline bool create_directories(const wpath& ph)\r
95       { return create_directories<wpath>(ph); }\r
96 \r
97 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED\r
98     inline std::string extension(const path& ph)\r
99       { return extension<path>(ph); }\r
100     inline std::wstring extension(const wpath& ph)\r
101       { return extension<wpath>(ph); }\r
102 \r
103     inline std::string basename(const path& ph)\r
104       { return basename<path>( ph ); }\r
105     inline std::wstring basename(const wpath& ph)\r
106       { return basename<wpath>( ph ); }\r
107 \r
108     inline path change_extension( const path & ph, const std::string& new_ex )\r
109       { return change_extension<path>( ph, new_ex ); }\r
110     inline wpath change_extension( const wpath & ph, const std::wstring& new_ex )\r
111       { return change_extension<wpath>( ph, new_ex ); }\r
112 # endif\r
113 \r
114 # endif\r
115 \r
116 \r
117     //  basic_recursive_directory_iterator helpers  --------------------------//\r
118 \r
119     namespace detail\r
120     {\r
121       template< class Path >\r
122       struct recur_dir_itr_imp\r
123       {\r
124         typedef basic_directory_iterator< Path > element_type;\r
125         std::stack< element_type, std::vector< element_type > > m_stack;\r
126         int  m_level;\r
127         bool m_no_push;\r
128         bool m_no_throw;\r
129 \r
130         recur_dir_itr_imp() : m_level(0), m_no_push(false), m_no_throw(false) {}\r
131       };\r
132 \r
133     } // namespace detail\r
134 \r
135     //  basic_recursive_directory_iterator  ----------------------------------//\r
136 \r
137     template< class Path >\r
138     class basic_recursive_directory_iterator\r
139       : public boost::iterator_facade<\r
140           basic_recursive_directory_iterator<Path>,\r
141           basic_directory_entry<Path>,\r
142           boost::single_pass_traversal_tag >\r
143     {\r
144     public:\r
145       typedef Path path_type;\r
146 \r
147       basic_recursive_directory_iterator(){}  // creates the "end" iterator\r
148 \r
149       explicit basic_recursive_directory_iterator( const Path & dir_path );\r
150       basic_recursive_directory_iterator( const Path & dir_path,\r
151         system::error_code & ec );\r
152 \r
153       int level() const { return m_imp->m_level; }\r
154 \r
155       void pop();\r
156       void no_push()\r
157       {\r
158         BOOST_ASSERT( m_imp.get() && "attempt to no_push() on end iterator" );\r
159         m_imp->m_no_push = true;\r
160       }\r
161 \r
162       file_status status() const\r
163       {\r
164         BOOST_ASSERT( m_imp.get()\r
165           && "attempt to call status() on end recursive_iterator" );\r
166         return m_imp->m_stack.top()->status();\r
167       }\r
168 \r
169       file_status symlink_status() const\r
170       {\r
171         BOOST_ASSERT( m_imp.get()\r
172           && "attempt to call symlink_status() on end recursive_iterator" );\r
173         return m_imp->m_stack.top()->symlink_status();\r
174       }\r
175 \r
176     private:\r
177 \r
178       // shared_ptr provides shallow-copy semantics required for InputIterators.\r
179       // m_imp.get()==0 indicates the end iterator.\r
180       boost::shared_ptr< detail::recur_dir_itr_imp< Path > >  m_imp;\r
181 \r
182       friend class boost::iterator_core_access;\r
183 \r
184       typename boost::iterator_facade< \r
185         basic_recursive_directory_iterator<Path>,\r
186         basic_directory_entry<Path>,\r
187         boost::single_pass_traversal_tag >::reference\r
188       dereference() const \r
189       {\r
190         BOOST_ASSERT( m_imp.get() && "attempt to dereference end iterator" );\r
191         return *m_imp->m_stack.top();\r
192       }\r
193 \r
194       void increment();\r
195 \r
196       bool equal( const basic_recursive_directory_iterator & rhs ) const\r
197         { return m_imp == rhs.m_imp; }\r
198 \r
199     };\r
200 \r
201     typedef basic_recursive_directory_iterator<path> recursive_directory_iterator;\r
202 # ifndef BOOST_FILESYSTEM_NARROW_ONLY\r
203     typedef basic_recursive_directory_iterator<wpath> wrecursive_directory_iterator;\r
204 # endif\r
205 \r
206     //  basic_recursive_directory_iterator implementation  -------------------//\r
207 \r
208     //  constructors\r
209     template<class Path>\r
210     basic_recursive_directory_iterator<Path>::\r
211       basic_recursive_directory_iterator( const Path & dir_path )\r
212       : m_imp( new detail::recur_dir_itr_imp<Path> )\r
213     {\r
214       m_imp->m_stack.push( basic_directory_iterator<Path>( dir_path ) );\r
215       if ( m_imp->m_stack.top () == basic_directory_iterator<Path>() )\r
216         { m_imp.reset (); }\r
217     }\r
218 \r
219     template<class Path>\r
220     basic_recursive_directory_iterator<Path>::\r
221       basic_recursive_directory_iterator( const Path & dir_path,\r
222         system::error_code & ec )\r
223       : m_imp( new detail::recur_dir_itr_imp<Path> )\r
224     {\r
225       m_imp->m_no_throw = true;\r
226       m_imp->m_stack.push( basic_directory_iterator<Path>( dir_path, ec ) );\r
227       if ( m_imp->m_stack.top () == basic_directory_iterator<Path>() )\r
228         { m_imp.reset (); }\r
229     }\r
230 \r
231     //  increment\r
232     template<class Path>\r
233     void basic_recursive_directory_iterator<Path>::increment()\r
234     {\r
235       BOOST_ASSERT( m_imp.get() && "increment on end iterator" );\r
236       \r
237       static const basic_directory_iterator<Path> end_itr;\r
238 \r
239       if ( m_imp->m_no_push )\r
240         { m_imp->m_no_push = false; }\r
241       else if ( is_directory( m_imp->m_stack.top()->status() ) )\r
242       {\r
243         system::error_code ec;\r
244 #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610))\r
245         if( m_imp->m_no_throw ) {\r
246             m_imp->m_stack.push(\r
247                 basic_directory_iterator<Path>( *m_imp->m_stack.top(), ec )\r
248             );\r
249         }\r
250         else {\r
251             m_imp->m_stack.push(\r
252                 basic_directory_iterator<Path>( *m_imp->m_stack.top() )\r
253             );\r
254         }\r
255 #else\r
256         m_imp->m_stack.push(\r
257           m_imp->m_no_throw\r
258             ? basic_directory_iterator<Path>( *m_imp->m_stack.top(), ec )\r
259             : basic_directory_iterator<Path>( *m_imp->m_stack.top() ) );\r
260 #endif\r
261         if ( m_imp->m_stack.top() != end_itr )\r
262         {\r
263           ++m_imp->m_level;\r
264           return;\r
265         }\r
266         m_imp->m_stack.pop();\r
267       }\r
268 \r
269       while ( !m_imp->m_stack.empty()\r
270         && ++m_imp->m_stack.top() == end_itr )\r
271       {\r
272         m_imp->m_stack.pop();\r
273         --m_imp->m_level;\r
274       }\r
275 \r
276       if ( m_imp->m_stack.empty() ) m_imp.reset(); // done, so make end iterator\r
277     }\r
278 \r
279     //  pop\r
280     template<class Path>\r
281     void basic_recursive_directory_iterator<Path>::pop()\r
282     {\r
283       BOOST_ASSERT( m_imp.get() && "pop on end iterator" );\r
284       BOOST_ASSERT( m_imp->m_level > 0 && "pop with level < 1" );\r
285 \r
286       static const basic_directory_iterator<Path> end_itr;\r
287 \r
288       do\r
289       {\r
290         m_imp->m_stack.pop();\r
291         --m_imp->m_level;\r
292       }\r
293       while ( !m_imp->m_stack.empty()\r
294         && ++m_imp->m_stack.top() == end_itr );\r
295 \r
296       if ( m_imp->m_stack.empty() ) m_imp.reset(); // done, so make end iterator\r
297     }\r
298 \r
299   } // namespace filesystem\r
300 } // namespace boost\r
301 \r
302 #undef BOOST_FS_FUNC_STRING\r
303 #undef BOOST_FS_FUNC\r
304 \r
305 #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas\r
306 #endif // BOOST_FILESYSTEM_CONVENIENCE_HPP\r