make directory_iterator all inline so Filesystem lib can be built as DLL

[SVN r21311]
This commit is contained in:
Beman Dawes 2003-12-18 01:57:49 +00:00
parent cb638a2b0a
commit bdeca0a7c9
3 changed files with 90 additions and 74 deletions

View File

@ -74,17 +74,33 @@ namespace boost
BOOST_FILESYSTEM_DECL path system_complete( const path & ph );
BOOST_FILESYSTEM_DECL path complete( const path & ph, const path & base = initial_path() );
// directory_iterator helpers ----------------------------------------------//
// forwarding functions avoid need for BOOST_FILESYSTEM_DECL for class
// directory_iterator, and so avoid iterator_facade DLL template problems
namespace detail
{
class dir_itr_imp;
// shared_ptr provides shallow-copy semantics required for InputIterators
typedef boost::shared_ptr< dir_itr_imp > dir_itr_imp_ptr;
BOOST_FILESYSTEM_DECL void dir_itr_init( dir_itr_imp_ptr & m_imp,
const path & dir_path );
BOOST_FILESYSTEM_DECL path & dir_itr_dereference(
const dir_itr_imp_ptr & m_imp );
BOOST_FILESYSTEM_DECL void dir_itr_increment( dir_itr_imp_ptr & m_imp );
} // namespace detail
// directory_iterator ------------------------------------------------------//
class BOOST_FILESYSTEM_DECL directory_iterator
class directory_iterator
: public boost::iterator_facade<
directory_iterator,
path,
boost::single_pass_traversal_tag >
{
public:
directory_iterator(); // creates the "end" iterator
explicit directory_iterator( const path & p );
directory_iterator(){} // creates the "end" iterator
explicit directory_iterator( const path & p )
{ detail::dir_itr_init( m_imp, p ); }
/*
The *r++ requirement doesn't appear to apply to the new single_pass_traversal category
@ -105,14 +121,12 @@ struct path_proxy // allows *r++ to work, as required by 24.1.1
*/
private:
class dir_itr_imp;
// shared_ptr provides shallow-copy semantics required for InputIterators
typedef boost::shared_ptr< dir_itr_imp > m_imp_ptr;
m_imp_ptr m_imp;
detail::dir_itr_imp_ptr m_imp;
friend class boost::iterator_core_access;
reference dereference() const;
void increment();
reference dereference() const
{ return detail::dir_itr_dereference( m_imp ); }
void increment()
{ detail::dir_itr_increment( m_imp ); }
bool equal( const directory_iterator & rhs ) const
{ return m_imp == rhs.m_imp; }
};

View File

@ -25,7 +25,7 @@ namespace boost
{
namespace filesystem
{
class BOOST_FILESYSTEM_DECL directory_iterator;
class directory_iterator;
// path -------------------------------------------------------------------//
@ -131,9 +131,8 @@ namespace boost
// warning #427-D: qualified name is not allowed in member declaration
friend class iterator;
void m_path_append( const std::string & src, name_check checker );
public: // should be private, but friend functions don't work for me
void m_path_append( const std::string & src, name_check checker );
void m_replace_leaf( const char * new_leaf );
};

View File

@ -167,6 +167,7 @@ namespace
#endif
fs::directory_iterator end_itr;
bool is_empty_directory( const fs::path & dir_path )
@ -196,85 +197,87 @@ namespace boost
{
namespace filesystem
{
namespace detail
{
// dir_itr_imp -------------------------------------------------------------//
class directory_iterator::dir_itr_imp
{
public:
path entry_path;
BOOST_HANDLE handle;
~dir_itr_imp()
class dir_itr_imp
{
if ( handle != BOOST_INVALID_HANDLE_VALUE ) find_close( handle );
}
};
public:
path entry_path;
BOOST_HANDLE handle;
~dir_itr_imp()
{
if ( handle != BOOST_INVALID_HANDLE_VALUE ) find_close( handle );
}
};
// directory_iterator implementation ---------------------------------------//
// default ctor creates the "end" iterator (by letting base default to 0)
directory_iterator::directory_iterator() {}
directory_iterator::directory_iterator( const path & dir_path )
{
m_imp.reset( new dir_itr_imp );
BOOST_SYSTEM_DIRECTORY_TYPE scratch;
const char * name = 0; // initialization quiets compiler warnings
if ( dir_path.empty() )
m_imp->handle = BOOST_INVALID_HANDLE_VALUE;
else
name = find_first_file( dir_path.native_directory_string().c_str(),
m_imp->handle, scratch ); // sets handle
if ( m_imp->handle != BOOST_INVALID_HANDLE_VALUE )
BOOST_FILESYSTEM_DECL void dir_itr_init( dir_itr_imp_ptr & m_imp,
const path & dir_path )
{
m_imp->entry_path = dir_path;
if ( std::strcmp( name, "." ) != 0
&& std::strcmp( name, ".." ) != 0 )
{
m_imp->entry_path.m_path_append( name, no_check );
m_imp.reset( new dir_itr_imp );
BOOST_SYSTEM_DIRECTORY_TYPE scratch;
const char * name = 0; // initialization quiets compiler warnings
if ( dir_path.empty() )
m_imp->handle = BOOST_INVALID_HANDLE_VALUE;
else
name = find_first_file( dir_path.native_directory_string().c_str(),
m_imp->handle, scratch ); // sets handle
if ( m_imp->handle != BOOST_INVALID_HANDLE_VALUE )
{
m_imp->entry_path = dir_path;
if ( std::strcmp( name, "." ) != 0
&& std::strcmp( name, ".." ) != 0 )
{
m_imp->entry_path.m_path_append( name, no_check );
}
else
{
m_imp->entry_path.m_path_append( "dummy", no_check );
dir_itr_increment( m_imp );
}
}
else
{
m_imp->entry_path.m_path_append( "dummy", no_check );
operator++();
}
boost::throw_exception( filesystem_error(
"boost::filesystem::directory_iterator constructor",
dir_path, fs::detail::system_error_code() ) );
}
}
else
BOOST_FILESYSTEM_DECL path & dir_itr_dereference(
const dir_itr_imp_ptr & m_imp )
{
boost::throw_exception( filesystem_error(
"boost::filesystem::directory_iterator constructor",
dir_path, fs::detail::system_error_code() ) );
}
}
assert( m_imp.get() ); // fails if dereference end iterator
return m_imp->entry_path;
}
directory_iterator::reference directory_iterator::dereference() const
{
assert( m_imp.get() ); // fails if dereference end iterator
return m_imp->entry_path;
}
void directory_iterator::increment()
{
assert( m_imp.get() ); // fails on increment end iterator
assert( m_imp->handle != BOOST_INVALID_HANDLE_VALUE ); // reality check
BOOST_SYSTEM_DIRECTORY_TYPE scratch;
const char * name;
while ( (name = find_next_file( m_imp->handle,
m_imp->entry_path, scratch )) != 0 )
BOOST_FILESYSTEM_DECL void dir_itr_increment( dir_itr_imp_ptr & m_imp )
{
if ( std::strcmp( name, "." ) != 0
&& std::strcmp( name, ".." ) != 0 )
assert( m_imp.get() ); // fails on increment end iterator
assert( m_imp->handle != BOOST_INVALID_HANDLE_VALUE ); // reality check
BOOST_SYSTEM_DIRECTORY_TYPE scratch;
const char * name;
while ( (name = find_next_file( m_imp->handle,
m_imp->entry_path, scratch )) != 0 )
{
m_imp->entry_path.m_replace_leaf( name );
return;
if ( std::strcmp( name, "." ) != 0
&& std::strcmp( name, ".." ) != 0 )
{
m_imp->entry_path.m_replace_leaf( name );
return;
}
}
m_imp.reset(); // make base() the end iterator
}
m_imp.reset(); // make base() the end iterator
}
} // namespace detail
// free functions ----------------------------------------------------------//