You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							1361 lines
						
					
					
						
							46 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							1361 lines
						
					
					
						
							46 KiB
						
					
					
				
								/* /////////////////////////////////////////////////////////////////////////
							 | 
						|
								 * File:        unixstl/filesystem/glob_sequence.hpp
							 | 
						|
								 *
							 | 
						|
								 * Purpose:     glob_sequence class.
							 | 
						|
								 *
							 | 
						|
								 * Created:     15th January 2002
							 | 
						|
								 * Updated:     4th June 2012
							 | 
						|
								 *
							 | 
						|
								 * Thanks:      To Carlos Santander Bernal for helping with Mac compatibility.
							 | 
						|
								 *              To Nevin Liber for pressing upon me the need to lead by
							 | 
						|
								 *              example when writing books about good design/implementation.
							 | 
						|
								 *
							 | 
						|
								 * Home:        http://stlsoft.org/
							 | 
						|
								 *
							 | 
						|
								 * Copyright (c) 2002-2012, Matthew Wilson and Synesis Software
							 | 
						|
								 * All rights reserved.
							 | 
						|
								 *
							 | 
						|
								 * Redistribution and use in source and binary forms, with or without
							 | 
						|
								 * modification, are permitted provided that the following conditions are met:
							 | 
						|
								 *
							 | 
						|
								 * - Redistributions of source code must retain the above copyright notice, this
							 | 
						|
								 *   list of conditions and the following disclaimer.
							 | 
						|
								 * - Redistributions in binary form must reproduce the above copyright notice,
							 | 
						|
								 *   this list of conditions and the following disclaimer in the documentation
							 | 
						|
								 *   and/or other materials provided with the distribution.
							 | 
						|
								 * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
							 | 
						|
								 *   any contributors may be used to endorse or promote products derived from
							 | 
						|
								 *   this software without specific prior written permission.
							 | 
						|
								 *
							 | 
						|
								 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
							 | 
						|
								 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
							 | 
						|
								 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
							 | 
						|
								 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
							 | 
						|
								 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
							 | 
						|
								 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
							 | 
						|
								 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
							 | 
						|
								 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
							 | 
						|
								 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
							 | 
						|
								 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
							 | 
						|
								 * POSSIBILITY OF SUCH DAMAGE.
							 | 
						|
								 *
							 | 
						|
								 * ////////////////////////////////////////////////////////////////////// */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/** \file unixstl/filesystem/glob_sequence.hpp
							 | 
						|
								 *
							 | 
						|
								 * \brief [C++ only] Definition of the unixstl::glob_sequence class
							 | 
						|
								 *   (\ref group__library__filesystem "File System" Library).
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE
							 | 
						|
								#define UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE
							 | 
						|
								
							 | 
						|
								#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
							 | 
						|
								# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_MAJOR     5
							 | 
						|
								# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_MINOR     2
							 | 
						|
								# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_REVISION  5
							 | 
						|
								# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_EDIT      159
							 | 
						|
								#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
							 | 
						|
								
							 | 
						|
								/* /////////////////////////////////////////////////////////////////////////
							 | 
						|
								 * Includes
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#ifndef UNIXSTL_INCL_UNIXSTL_H_UNIXSTL
							 | 
						|
								# include <unixstl/unixstl.h>
							 | 
						|
								#endif /* !UNIXSTL_INCL_UNIXSTL_H_UNIXSTL */
							 | 
						|
								#ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
							 | 
						|
								# include <unixstl/filesystem/filesystem_traits.hpp>
							 | 
						|
								#endif /* !UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS */
							 | 
						|
								#ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILE_PATH_BUFFER
							 | 
						|
								# include <unixstl/filesystem/file_path_buffer.hpp>
							 | 
						|
								#endif /* !UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILE_PATH_BUFFER */
							 | 
						|
								#ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
							 | 
						|
								# include <stlsoft/util/std/iterator_helper.hpp>
							 | 
						|
								#endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER */
							 | 
						|
								#ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
							 | 
						|
								# include <stlsoft/memory/auto_buffer.hpp>
							 | 
						|
								#endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */
							 | 
						|
								#ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR
							 | 
						|
								# include <stlsoft/memory/allocator_selector.hpp>
							 | 
						|
								#endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR */
							 | 
						|
								#ifndef STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_SCOPED_HANDLE
							 | 
						|
								# include <stlsoft/smartptr/scoped_handle.hpp>
							 | 
						|
								#endif /* !STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_SCOPED_HANDLE */
							 | 
						|
								#ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_TOKENISER_FUNCTIONS
							 | 
						|
								//# include <stlsoft/string/tokeniser_functions.hpp> // for find_next_token
							 | 
						|
								#endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_TOKENISER_FUNCTIONS */
							 | 
						|
								#ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
							 | 
						|
								# include <stlsoft/collections/util/collections.hpp>
							 | 
						|
								#endif /* !STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS */
							 | 
						|
								#ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
							 | 
						|
								# include <stlsoft/util/std_swap.hpp>
							 | 
						|
								#endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP */
							 | 
						|
								
							 | 
						|
								#ifndef STLSOFT_INCL_SYS_H_TYPES
							 | 
						|
								# define STLSOFT_INCL_SYS_H_TYPES
							 | 
						|
								# include <sys/types.h>
							 | 
						|
								#endif /* !STLSOFT_INCL_SYS_H_TYPES */
							 | 
						|
								#ifndef STLSOFT_INCL_SYS_H_STAT
							 | 
						|
								# define STLSOFT_INCL_SYS_H_STAT
							 | 
						|
								# include <sys/stat.h>                      // for stat()
							 | 
						|
								#endif /* !STLSOFT_INCL_SYS_H_STAT */
							 | 
						|
								#ifndef STLSOFT_INCL_H_ERRNO
							 | 
						|
								# define STLSOFT_INCL_H_ERRNO
							 | 
						|
								# include <errno.h>
							 | 
						|
								#endif /* !STLSOFT_INCL_H_ERRNO */
							 | 
						|
								#ifndef STLSOFT_INCL_H_GLOB
							 | 
						|
								# define STLSOFT_INCL_H_GLOB
							 | 
						|
								# include <glob.h>                           // for glob(), globfree()
							 | 
						|
								#endif /* !STLSOFT_INCL_H_GLOB */
							 | 
						|
								
							 | 
						|
								#ifndef STLSOFT_INCL_ALGORITHM
							 | 
						|
								# define STLSOFT_INCL_ALGORITHM
							 | 
						|
								# include <algorithm>                        // for std::sort
							 | 
						|
								#endif /* !STLSOFT_INCL_ALGORITHM */
							 | 
						|
								#ifndef STLSOFT_INCL_EXCEPTION
							 | 
						|
								# define STLSOFT_INCL_EXCEPTION
							 | 
						|
								# include <exception>                        // for std::exception
							 | 
						|
								#endif /* !STLSOFT_INCL_EXCEPTION */
							 | 
						|
								#ifndef STLSOFT_INCL_STDEXCEPT
							 | 
						|
								# define STLSOFT_INCL_STDEXCEPT
							 | 
						|
								# include <stdexcept>                        // for std::runtime_error
							 | 
						|
								#endif /* !STLSOFT_INCL_STDEXCEPT */
							 | 
						|
								
							 | 
						|
								#ifdef STLSOFT_UNITTEST
							 | 
						|
								# include <stlsoft/string/simple_string.hpp>
							 | 
						|
								#endif /* STLSOFT_UNITTEST */
							 | 
						|
								
							 | 
						|
								/* /////////////////////////////////////////////////////////////////////////
							 | 
						|
								 * Library compatibility
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								/* User may define UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR to cause the
							 | 
						|
								 * component to trust GLOB_ONLYDIR, if present. If GLOB_ONLYDIR is not
							 | 
						|
								 * detected, UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR is ignored.
							 | 
						|
								 *
							 | 
						|
								 * For any implementations that 
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#ifndef GLOB_ONLYDIR
							 | 
						|
								# ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR
							 | 
						|
								#  undef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR
							 | 
						|
								# endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR */
							 | 
						|
								#endif /* GLOB_ONLYDIR */
							 | 
						|
								
							 | 
						|
								/* User may define UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG to cause the
							 | 
						|
								 * component to trust GLOB_ONLYREG, if present. If GLOB_ONLYREG is not
							 | 
						|
								 * detected, UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG is ignored.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#ifndef GLOB_ONLYREG
							 | 
						|
								# ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG
							 | 
						|
								#  undef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG
							 | 
						|
								# endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG */
							 | 
						|
								#endif /* GLOB_ONLYREG */
							 | 
						|
								
							 | 
						|
								/* User may define UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS to cause the
							 | 
						|
								 * component to trust GLOB_NODOTSDIRS, if present. If GLOB_NODOTSDIRS is
							 | 
						|
								 * not detected, UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS is ignored.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#ifndef GLOB_NODOTSDIRS
							 | 
						|
								# ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS
							 | 
						|
								#  undef UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS
							 | 
						|
								# endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS */
							 | 
						|
								#endif /* GLOB_NODOTSDIRS */
							 | 
						|
								
							 | 
						|
								/* User may define UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK do prevent the
							 | 
						|
								 * component from trusting GLOB_MARK; this is meaningless on non-Windows
							 | 
						|
								 * systems, since marking cannot be trusted to filter for files by eliding
							 | 
						|
								 * directories because entries may also be sockets, etc.
							 | 
						|
								 */
							 | 
						|
								#ifndef _WIN32
							 | 
						|
								# ifndef UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK
							 | 
						|
								#  define UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK
							 | 
						|
								# endif /* !UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK */
							 | 
						|
								#endif /* !_WIN32 */
							 | 
						|
								
							 | 
						|
								/* /////////////////////////////////////////////////////////////////////////
							 | 
						|
								 * Compiler compatibility
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
							 | 
						|
								# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
							 | 
						|
								#elif defined(STLSOFT_COMPILER_IS_CUSTOM)
							 | 
						|
								# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
							 | 
						|
								#elif defined(STLSOFT_COMPILER_IS_UNKNOWN)
							 | 
						|
								# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
							 | 
						|
								#elif defined(STLSOFT_COMPILER_IS_BORLAND)
							 | 
						|
								# define GLOB_SEQUENCE_CTOR_OLD_FORM
							 | 
						|
								#elif defined(STLSOFT_COMPILER_IS_COMO)
							 | 
						|
								# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
							 | 
						|
								#elif defined(STLSOFT_COMPILER_IS_DMC)
							 | 
						|
								# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
							 | 
						|
								#elif defined(STLSOFT_COMPILER_IS_GCC)
							 | 
						|
								# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
							 | 
						|
								#elif defined(STLSOFT_COMPILER_IS_INTEL)
							 | 
						|
								# define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
							 | 
						|
								#elif defined(STLSOFT_COMPILER_IS_MSVC)
							 | 
						|
								# if _MSC_VER >= 1310
							 | 
						|
								#  define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
							 | 
						|
								# elif _MSC_VER >= 1020
							 | 
						|
								#  define GLOB_SEQUENCE_CTOR_ALT_FORM
							 | 
						|
								# else /* ? compiler */
							 | 
						|
								#  define GLOB_SEQUENCE_CTOR_OLD_FORM
							 | 
						|
								# endif /* compiler */
							 | 
						|
								#elif defined(STLSOFT_COMPILER_IS_MWERKS)
							 | 
						|
								# define GLOB_SEQUENCE_CTOR_ALT_FORM
							 | 
						|
								#elif defined(STLSOFT_COMPILER_IS_VECTORC)
							 | 
						|
								# define GLOB_SEQUENCE_CTOR_ALT_FORM
							 | 
						|
								#elif defined(STLSOFT_COMPILER_IS_WATCOM)
							 | 
						|
								# define GLOB_SEQUENCE_CTOR_OLD_FORM
							 | 
						|
								#else /* ? compiler */
							 | 
						|
								# error Unrecognised compiler
							 | 
						|
								#endif /* compiler */
							 | 
						|
								
							 | 
						|
								/* /////////////////////////////////////////////////////////////////////////
							 | 
						|
								 * Namespace
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#ifndef _UNIXSTL_NO_NAMESPACE
							 | 
						|
								# if defined(_STLSOFT_NO_NAMESPACE) || \
							 | 
						|
								     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
							 | 
						|
								/* There is no stlsoft namespace, so must define ::unixstl */
							 | 
						|
								namespace unixstl
							 | 
						|
								{
							 | 
						|
								# else
							 | 
						|
								/* Define stlsoft::unixstl_project */
							 | 
						|
								
							 | 
						|
								namespace stlsoft
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								namespace unixstl_project
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								# endif /* _STLSOFT_NO_NAMESPACE */
							 | 
						|
								#endif /* !_UNIXSTL_NO_NAMESPACE */
							 | 
						|
								
							 | 
						|
								/* /////////////////////////////////////////////////////////////////////////
							 | 
						|
								 * Classes
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
							 | 
						|
								/** \brief The exception-type thrown by unixstl::glob_sequence
							 | 
						|
								 *
							 | 
						|
								 * \ingroup group__library__filesystem
							 | 
						|
								 */
							 | 
						|
								class glob_sequence_exception
							 | 
						|
								#if defined(STLSOFT_COMPILER_IS_DMC)
							 | 
						|
								    : public std::exception
							 | 
						|
								#else /* ? compiler */
							 | 
						|
								    : public unixstl_ns_qual_std(exception)
							 | 
						|
								#endif /* compiler */
							 | 
						|
								{
							 | 
						|
								/// \name Types
							 | 
						|
								/// @{
							 | 
						|
								public:
							 | 
						|
								#if defined(STLSOFT_COMPILER_IS_DMC)
							 | 
						|
								    typedef std::exception                  parent_class_type;
							 | 
						|
								#else /* ? compiler */
							 | 
						|
								    typedef unixstl_ns_qual_std(exception)  parent_class_type;
							 | 
						|
								#endif /* compiler */
							 | 
						|
								    typedef glob_sequence_exception         class_type;
							 | 
						|
								/// @}
							 | 
						|
								
							 | 
						|
								/// \name Construction
							 | 
						|
								/// @{
							 | 
						|
								public:
							 | 
						|
								    ss_explicit_k glob_sequence_exception(us_int_t globStatus, us_int_t errno_) stlsoft_throw_0()
							 | 
						|
								        : m_globStatus(globStatus)
							 | 
						|
								        , m_errno(errno_)
							 | 
						|
								    {}
							 | 
						|
								/// @}
							 | 
						|
								
							 | 
						|
								/// \name Accessors
							 | 
						|
								/// @{
							 | 
						|
								public:
							 | 
						|
								#if defined(STLSOFT_COMPILER_IS_DMC)
							 | 
						|
								    char const* what() const throw()
							 | 
						|
								#else /* ? compiler */
							 | 
						|
								    char const* what() const stlsoft_throw_0()
							 | 
						|
								#endif /* compiler */
							 | 
						|
								    {
							 | 
						|
								        return "glob_sequence failure";
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    us_int_t get_globstatus() const stlsoft_throw_0()
							 | 
						|
								    {
							 | 
						|
								        return m_globStatus;
							 | 
						|
								    }
							 | 
						|
								    us_int_t get_errno() const stlsoft_throw_0()
							 | 
						|
								    {
							 | 
						|
								        return m_errno;
							 | 
						|
								    }
							 | 
						|
								/// @}
							 | 
						|
								
							 | 
						|
								/// \name Members
							 | 
						|
								/// @{
							 | 
						|
								private:
							 | 
						|
								    us_int_t const  m_globStatus;
							 | 
						|
								    us_int_t const  m_errno;
							 | 
						|
								/// @}
							 | 
						|
								
							 | 
						|
								/// \name Not to be implemented
							 | 
						|
								/// @{
							 | 
						|
								private:
							 | 
						|
								    class_type& operator =(class_type const&);
							 | 
						|
								/// @}
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
							 | 
						|
								
							 | 
						|
								/** \brief STL-like readonly sequence based on the results of file-system wildcard matches
							 | 
						|
								 *
							 | 
						|
								 * \ingroup group__library__filesystem
							 | 
						|
								 *
							 | 
						|
								 * This class presents and STL-like readonly sequence interface to allow the
							 | 
						|
								 * iteration over the results of file-system wildcard matches.
							 | 
						|
								 */
							 | 
						|
								class glob_sequence
							 | 
						|
								    : public stlsoft_ns_qual(stl_collection_tag)
							 | 
						|
								{
							 | 
						|
								/// \name Types
							 | 
						|
								/// @{
							 | 
						|
								public:
							 | 
						|
								    /// \brief This class
							 | 
						|
								    typedef glob_sequence                                                   class_type;
							 | 
						|
								    /// \brief The char type
							 | 
						|
								    typedef us_char_a_t                                                     char_type;
							 | 
						|
								    // The traits type
							 | 
						|
								    typedef filesystem_traits<char_type>                                    traits_type;
							 | 
						|
								    /// \brief The value type
							 | 
						|
								    typedef char_type const*                                                value_type;
							 | 
						|
								    /// \brief The non-mutating (const) reference type
							 | 
						|
								    typedef value_type const&                                               const_reference;
							 | 
						|
								    /// \brief The non-mutating (const) pointer type
							 | 
						|
								    typedef value_type const*                                               const_pointer;
							 | 
						|
								    /// \brief The size type
							 | 
						|
								    typedef us_size_t                                                       size_type;
							 | 
						|
								    /// \brief The difference type
							 | 
						|
								    typedef us_ptrdiff_t                                                    difference_type;
							 | 
						|
								    /// \brief The allocator type
							 | 
						|
								    typedef stlsoft_ns_qual(allocator_selector)<value_type>::allocator_type allocator_type;
							 | 
						|
								
							 | 
						|
								    /// \brief The non-mutating (const) iterator type
							 | 
						|
								    typedef stlsoft_ns_qual(pointer_iterator)<   value_type const
							 | 
						|
								                                             ,   const_pointer
							 | 
						|
								                                             ,   const_reference
							 | 
						|
								                                             >::type                        const_iterator;
							 | 
						|
								
							 | 
						|
								#ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
							 | 
						|
								    /// \brief The type of the const (non-mutating) reverse iterator
							 | 
						|
								    typedef stlsoft_ns_qual(reverse_iterator_base)  <   const_iterator
							 | 
						|
								                                                    ,   value_type
							 | 
						|
								                                                    ,   const_reference
							 | 
						|
								                                                    ,   const_pointer
							 | 
						|
								                                                    ,   difference_type
							 | 
						|
								                                                    >                       const_reverse_iterator;
							 | 
						|
								#endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
							 | 
						|
								/// @}
							 | 
						|
								
							 | 
						|
								/// \name Member Constants
							 | 
						|
								/// @{
							 | 
						|
								public:
							 | 
						|
								    enum search_flags
							 | 
						|
								    {
							 | 
						|
								            includeDots     =   0x0008  /*!< \brief Requests that dots directories be included in the returned sequence for wildcard patterns, for which \c matchPeriod must also be specified (if GLOB_PERIOD is defined). Always ignored unless \c directories is specified. */
							 | 
						|
								        ,   directories     =   0x0010  /*!< \brief Causes the search to include directories */
							 | 
						|
								        ,   files           =   0x0020  /*!< \brief Causes the search to include files */
							 | 
						|
								        ,   noSort          =   0x0100  /*!< \brief Does not sort entries. Corresponds to GLOB_NOSORT. */
							 | 
						|
								        ,   markDirs        =   0x0200  /*!< \brief Mark directories with a trailing path name separator. Corresponds to GLOB_MARK. */
							 | 
						|
								        ,   absolutePath    =   0x0400  /*!< \brief Return all entries in absolute format. Ignored when a dots directory is specified as the pattern. Note, absolute paths may not always be in canonical form, e.g. '/user/me/.' if specify ('/user/me', '.', absolutePath), in which case the caller is responsible for obtaining canonical form. */
							 | 
						|
								
							 | 
						|
								        ,   breakOnError    =   0x0800  /*!< \brief Causes processing to stop on the first filesystem error. Corresponds to GLOB_ERR. */
							 | 
						|
								        ,   noEscape        =   0x1000  /*!< \brief Treats backslashes literally. Corresponds to GLOB_NOESCAPE. */
							 | 
						|
								
							 | 
						|
								#ifdef GLOB_PERIOD
							 | 
						|
								        ,   matchPeriod     =   0x2000  /*!< \brief Leading '.' can be matched by metacharacters. Corresponds to GLOB_PERIOD. */
							 | 
						|
								#endif /* GLOB_PERIOD */
							 | 
						|
								#ifdef GLOB_BRACE
							 | 
						|
								        ,   bracePatterns   =   0x4000  /*!< \brief Allow "{*.cpp;makefile*}" style multi-part patterns. Corresponds to GLOB_BRACE. */
							 | 
						|
								#endif /* GLOB_BRACE */
							 | 
						|
								#ifdef GLOB_TILDE
							 | 
						|
								        ,   expandTilde     =   0x8000  /*!< \brief Expand ~ and ~<user> directories. Corresponds to GLOB_TILDE. */
							 | 
						|
								#endif /* GLOB_TILDE */
							 | 
						|
								    };
							 | 
						|
								/// @}
							 | 
						|
								
							 | 
						|
								/// \name Construction
							 | 
						|
								/// @{
							 | 
						|
								public:
							 | 
						|
								#if defined(GLOB_SEQUENCE_CTOR_PRIMARY_FORM)
							 | 
						|
								    /// \brief Constructs a sequence according to the given criteria
							 | 
						|
								    ///
							 | 
						|
								    /// The constructor initialises a glob_sequence instance on the given
							 | 
						|
								    /// pattern with the given flags.
							 | 
						|
								    ///
							 | 
						|
								    /// \param pattern The pattern against which to match the file-system contents
							 | 
						|
								    /// \param flags Flags to alter the behaviour of the search
							 | 
						|
								    ///
							 | 
						|
								    /// \note If exceptions are supported, then this will throw a glob_sequence_exception
							 | 
						|
								    /// on failure of any underlying functions
							 | 
						|
								    template<ss_typename_param_k S>
							 | 
						|
								    ss_explicit_k glob_sequence(S const& pattern, us_int_t flags = files | directories)
							 | 
						|
								        : m_flags(validate_flags_(flags))
							 | 
						|
								        , m_buffer(1)
							 | 
						|
								    {
							 | 
						|
								        m_cItems = init_glob_(NULL, stlsoft_ns_qual(c_str_ptr)(pattern));
							 | 
						|
								
							 | 
						|
								        UNIXSTL_ASSERT(is_valid());
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								# ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
							 | 
						|
								    template<ss_typename_param_k S>
							 | 
						|
								    glob_sequence(S const& pattern, search_flags flag)
							 | 
						|
								        : m_flags(validate_flags_(flag))
							 | 
						|
								        , m_buffer(1)
							 | 
						|
								    {
							 | 
						|
								        m_cItems = init_glob_(NULL, stlsoft_ns_qual(c_str_ptr)(pattern));
							 | 
						|
								
							 | 
						|
								        UNIXSTL_ASSERT(is_valid());
							 | 
						|
								    }
							 | 
						|
								# endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
							 | 
						|
								
							 | 
						|
								    /// \brief Constructs a sequence according to the given criteria
							 | 
						|
								    ///
							 | 
						|
								    /// The constructor initialises a glob_sequence instance on the given
							 | 
						|
								    /// pattern with the given flags.
							 | 
						|
								    ///
							 | 
						|
								    /// \param directory The directory in which the pattern is located
							 | 
						|
								    /// \param pattern The pattern against which to match the file-system contents
							 | 
						|
								    /// \param flags Flags to alter the behaviour of the search
							 | 
						|
								    ///
							 | 
						|
								    /// \note If exceptions are supported, then this will throw a glob_sequence_exception
							 | 
						|
								    /// on failure of any underlying functions
							 | 
						|
								    template<   ss_typename_param_k S1
							 | 
						|
								            ,   ss_typename_param_k S2
							 | 
						|
								            >
							 | 
						|
								    glob_sequence(S1 const& directory, S2 const& pattern, us_int_t flags = files | directories)
							 | 
						|
								        : m_flags(validate_flags_(flags))
							 | 
						|
								        , m_buffer(1)
							 | 
						|
								    {
							 | 
						|
								        m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));
							 | 
						|
								
							 | 
						|
								        UNIXSTL_ASSERT(is_valid());
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								# ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
							 | 
						|
								    template<   ss_typename_param_k S1
							 | 
						|
								            ,   ss_typename_param_k S2
							 | 
						|
								            >
							 | 
						|
								    glob_sequence(S1 const& directory, S2 const& pattern, search_flags flag)
							 | 
						|
								        : m_flags(validate_flags_(flag))
							 | 
						|
								        , m_buffer(1)
							 | 
						|
								    {
							 | 
						|
								        m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));
							 | 
						|
								
							 | 
						|
								        UNIXSTL_ASSERT(is_valid());
							 | 
						|
								    }
							 | 
						|
								# endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
							 | 
						|
								
							 | 
						|
								#elif defined(GLOB_SEQUENCE_CTOR_ALT_FORM)
							 | 
						|
								
							 | 
						|
								    template<ss_typename_param_k S>
							 | 
						|
								    ss_explicit_k glob_sequence(S const& pattern)
							 | 
						|
								        : m_flags(validate_flags_(files | directories))
							 | 
						|
								        , m_buffer(1)
							 | 
						|
								    {
							 | 
						|
								        m_cItems = init_glob_(NULL, stlsoft_ns_qual(c_str_ptr)(pattern));
							 | 
						|
								
							 | 
						|
								        UNIXSTL_ASSERT(is_valid());
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    template<ss_typename_param_k S>
							 | 
						|
								    glob_sequence(S const& pattern, us_int_t flags)
							 | 
						|
								        : m_flags(validate_flags_(flags))
							 | 
						|
								        , m_buffer(1)
							 | 
						|
								    {
							 | 
						|
								        m_cItems = init_glob_(NULL, stlsoft_ns_qual(c_str_ptr)(pattern));
							 | 
						|
								
							 | 
						|
								        UNIXSTL_ASSERT(is_valid());
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    glob_sequence(char_type const* directory, char_type const* pattern, us_int_t flags = files | directories);
							 | 
						|
								
							 | 
						|
								    template<ss_typename_param_k S>
							 | 
						|
								    glob_sequence(S const& directory, char const* pattern, us_int_t flags = files | directories)
							 | 
						|
								        : m_flags(validate_flags_(flags))
							 | 
						|
								        , m_buffer(1)
							 | 
						|
								    {
							 | 
						|
								        m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));
							 | 
						|
								
							 | 
						|
								        UNIXSTL_ASSERT(is_valid());
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    template<ss_typename_param_k S>
							 | 
						|
								    glob_sequence(S const& directory, S const& pattern, us_int_t flags = files | directories)
							 | 
						|
								        : m_flags(validate_flags_(flags))
							 | 
						|
								        , m_buffer(1)
							 | 
						|
								    {
							 | 
						|
								        m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));
							 | 
						|
								
							 | 
						|
								        UNIXSTL_ASSERT(is_valid());
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								#elif defined(GLOB_SEQUENCE_CTOR_OLD_FORM)
							 | 
						|
								
							 | 
						|
								    ss_explicit_k glob_sequence(char_type const* pattern, us_int_t flags = files | directories);
							 | 
						|
								
							 | 
						|
								    glob_sequence(char_type const* directory, char_type const* pattern, us_int_t flags = files | directories);
							 | 
						|
								
							 | 
						|
								#else /* ? constructor form */
							 | 
						|
								# error Constructor form not recognised
							 | 
						|
								#endif /* constructor form */
							 | 
						|
								
							 | 
						|
								#if 0
							 | 
						|
								    /// \brief Constructs a sequence according to the given criteria
							 | 
						|
								    ///
							 | 
						|
								    /// The constructor initialises a glob_sequence instance on the given
							 | 
						|
								    /// pattern with the given flags.
							 | 
						|
								    ///
							 | 
						|
								    /// \param directory The directory in which the pattern is located
							 | 
						|
								    /// \param pattern The pattern against which to match the file-system contents
							 | 
						|
								    /// \param flags Flags to alter the behaviour of the search
							 | 
						|
								    ///
							 | 
						|
								    /// \note If exceptions are supported, then this will throw a glob_sequence_exception
							 | 
						|
								    /// on failure of any underlying functions
							 | 
						|
								    glob_sequence(char_type const* directory, char_type const* pattern, char_type delim, us_int_t flags = files | directories);
							 | 
						|
								#endif /* 0 */
							 | 
						|
								
							 | 
						|
								    /// \brief Releases any acquired resources
							 | 
						|
								    ~glob_sequence() stlsoft_throw_0();
							 | 
						|
								/// @}
							 | 
						|
								
							 | 
						|
								/// \name Attributes
							 | 
						|
								/// @{
							 | 
						|
								public:
							 | 
						|
								    /// \brief Returns the number of elements in the sequence
							 | 
						|
								    us_size_t size() const;
							 | 
						|
								
							 | 
						|
								    /// \brief Indicates whether the search sequence is empty
							 | 
						|
								    us_bool_t empty() const;
							 | 
						|
								/// @}
							 | 
						|
								
							 | 
						|
								/// \name Element Access
							 | 
						|
								/// @{
							 | 
						|
								public:
							 | 
						|
								    /// \brief Returns the value corresponding to the given index
							 | 
						|
								    ///
							 | 
						|
								    /// \note In debug-mode a runtime assert is applied to enforce that the index is valid. There is <b>no</b> release-time checking on the index validity!
							 | 
						|
								    const_reference operator [](size_type index) const;
							 | 
						|
								/// @}
							 | 
						|
								
							 | 
						|
								/// \name Iteration
							 | 
						|
								/// @{
							 | 
						|
								public:
							 | 
						|
								    /// \brief Begins the iteration
							 | 
						|
								    ///
							 | 
						|
								    /// \return An iterator representing the start of the sequence
							 | 
						|
								    const_iterator  begin() const;
							 | 
						|
								    /// \brief Ends the iteration
							 | 
						|
								    ///
							 | 
						|
								    /// \return An iterator representing the end of the sequence
							 | 
						|
								    const_iterator  end() const;
							 | 
						|
								
							 | 
						|
								#ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
							 | 
						|
								    /// \brief Begins the reverse iteration
							 | 
						|
								    ///
							 | 
						|
								    /// \return An iterator representing the start of the reverse sequence
							 | 
						|
								    const_reverse_iterator  rbegin() const;
							 | 
						|
								    /// \brief Ends the reverse iteration
							 | 
						|
								    ///
							 | 
						|
								    /// \return An iterator representing the end of the reverse sequence
							 | 
						|
								    const_reverse_iterator  rend() const;
							 | 
						|
								#endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
							 | 
						|
								/// @}
							 | 
						|
								
							 | 
						|
								/// \name Implementation
							 | 
						|
								/// @{
							 | 
						|
								private:
							 | 
						|
								    // Tests the class invariant
							 | 
						|
								    us_bool_t           is_valid() const;
							 | 
						|
								
							 | 
						|
								    // Validates the flags, and sets up defaults
							 | 
						|
								    static us_int_t     validate_flags_(us_int_t flags);
							 | 
						|
								
							 | 
						|
								    // Returns true if pch is a path separator "/" (or "\\"); false otherwise
							 | 
						|
								    static us_bool_t    is_path_separator_(char_type ch);
							 | 
						|
								
							 | 
						|
								    // Returns true if pch == "" or "/" (or "\\"); false otherwise
							 | 
						|
								    static us_bool_t    is_end_of_path_elements_(char_type const* pch, difference_type index);
							 | 
						|
								
							 | 
						|
								    // Returns true if s points to a path that is a dots directory; false otherwise
							 | 
						|
								    static us_bool_t    is_dots_maybe_slashed_(char_type const* s, us_bool_t* bTwoDots);
							 | 
						|
								
							 | 
						|
								    // Calls glob() and process the results
							 | 
						|
								    //
							 | 
						|
								    // init_glob_()   - handles any directory and/or pattern (where the pattern may contain rel/abs dir)
							 | 
						|
								    // init_glob_1_() - splits combined path into directory+pattern (which are passed to init_glob_2_())
							 | 
						|
								    // init_glob_2_() - handles receives properly split directory+pattern (and does test in order to call init_glob_3_())
							 | 
						|
								    // init_glob_3_() - handles full pattern, with bool indicating whether pattern contains wildcard at leaf
							 | 
						|
								    us_size_t           init_glob_(char_type const* directory, char_type const* pattern);
							 | 
						|
								    us_size_t           init_glob_1_(size_type bufferSize, char_type* combinedPath);
							 | 
						|
								    us_size_t           init_glob_2_(char_type const* patternDir, char_type const* pattern0);
							 | 
						|
								    us_size_t           init_glob_3_(char_type const* pattern, bool isPattern0Wild);
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/// @}
							 | 
						|
								
							 | 
						|
								/// \name Members
							 | 
						|
								/// @{
							 | 
						|
								private:
							 | 
						|
								    typedef stlsoft_ns_qual(auto_buffer_old)<   char_type const*
							 | 
						|
								                                            ,   allocator_type
							 | 
						|
								                                            ,   128
							 | 
						|
								                                            >       buffer_type_;
							 | 
						|
								
							 | 
						|
								    us_int_t const      m_flags;
							 | 
						|
								    char_type const**   m_base;
							 | 
						|
								    us_size_t           m_cItems;
							 | 
						|
								    buffer_type_        m_buffer;
							 | 
						|
								    glob_t              m_glob;
							 | 
						|
								/// @}
							 | 
						|
								
							 | 
						|
								/// \name Not to be implemented
							 | 
						|
								/// @{
							 | 
						|
								private:
							 | 
						|
								    glob_sequence(class_type const&);
							 | 
						|
								    class_type const& operator =(class_type const&);
							 | 
						|
								/// @}
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								////////////////////////////////////////////////////////////////////////////
							 | 
						|
								// Unit-testing
							 | 
						|
								
							 | 
						|
								#ifdef STLSOFT_UNITTEST
							 | 
						|
								# include "./unittest/glob_sequence_unittest_.h"
							 | 
						|
								#endif /* STLSOFT_UNITTEST */
							 | 
						|
								
							 | 
						|
								/* /////////////////////////////////////////////////////////////////////////
							 | 
						|
								 * Implementation
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
							 | 
						|
								
							 | 
						|
								#if defined(GLOB_SEQUENCE_CTOR_OLD_FORM)
							 | 
						|
								inline /* ss_explicit_k */ glob_sequence::glob_sequence(glob_sequence::char_type const* pattern, us_int_t flags)
							 | 
						|
								    : m_flags(validate_flags_(flags))
							 | 
						|
								    , m_buffer(1)
							 | 
						|
								{
							 | 
						|
								    m_cItems = init_glob_(NULL, pattern);
							 | 
						|
								
							 | 
						|
								    UNIXSTL_ASSERT(is_valid());
							 | 
						|
								}
							 | 
						|
								#endif /* GLOB_SEQUENCE_CTOR_OLD_FORM */
							 | 
						|
								
							 | 
						|
								#if defined(GLOB_SEQUENCE_CTOR_OLD_FORM) || \
							 | 
						|
								    defined(GLOB_SEQUENCE_CTOR_ALT_FORM)
							 | 
						|
								inline glob_sequence::glob_sequence(glob_sequence::char_type const* directory, glob_sequence::char_type const* pattern, us_int_t flags)
							 | 
						|
								    : m_flags(validate_flags_(flags))
							 | 
						|
								    , m_buffer(1)
							 | 
						|
								{
							 | 
						|
								    m_cItems = init_glob_(directory, pattern);
							 | 
						|
								
							 | 
						|
								    UNIXSTL_ASSERT(is_valid());
							 | 
						|
								}
							 | 
						|
								#endif /* GLOB_SEQUENCE_CTOR_OLD_FORM || GLOB_SEQUENCE_CTOR_ALT_FORM */
							 | 
						|
								
							 | 
						|
								#if 0
							 | 
						|
								template<   ss_typename_param_k S1
							 | 
						|
								        ,   ss_typename_param_k S2
							 | 
						|
								        >
							 | 
						|
								inline glob_sequence::glob_sequence(S1 const& directory, S2 const& pattern, us_int_t flags)
							 | 
						|
								    : m_flags(validate_flags_(flags))
							 | 
						|
								    , m_buffer(1)
							 | 
						|
								{
							 | 
						|
								    m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));
							 | 
						|
								
							 | 
						|
								    UNIXSTL_ASSERT(is_valid());
							 | 
						|
								}
							 | 
						|
								#endif /* 0 */
							 | 
						|
								
							 | 
						|
								#if 0
							 | 
						|
								inline glob_sequence::glob_sequence(char_type const* directory, char_type const* pattern, char_type delim, us_int_t flags)
							 | 
						|
								    : m_flags(validate_flags_(flags))
							 | 
						|
								    , m_buffer(1)
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								    m_cItems = init_glob_(directory, pattern);
							 | 
						|
								
							 | 
						|
								    UNIXSTL_ASSERT(is_valid());
							 | 
						|
								}
							 | 
						|
								#endif /* 0 */
							 | 
						|
								
							 | 
						|
								inline glob_sequence::~glob_sequence() stlsoft_throw_0()
							 | 
						|
								{
							 | 
						|
								    UNIXSTL_ASSERT(is_valid());
							 | 
						|
								
							 | 
						|
								    if(NULL != m_base)
							 | 
						|
								    {
							 | 
						|
								        ::globfree(&m_glob);
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								inline us_size_t glob_sequence::size() const
							 | 
						|
								{
							 | 
						|
								    return m_cItems;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								inline us_bool_t glob_sequence::empty() const
							 | 
						|
								{
							 | 
						|
								    return 0 == size();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								inline glob_sequence::const_reference glob_sequence::operator [](glob_sequence::size_type index) const
							 | 
						|
								{
							 | 
						|
								    UNIXSTL_MESSAGE_ASSERT("index access out of range in glob_sequence", index < 1 + size());   // Has to be +1, since legitimate to take address of one-past-the-end
							 | 
						|
								
							 | 
						|
								    return m_base[index];
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								inline glob_sequence::const_iterator glob_sequence::begin() const
							 | 
						|
								{
							 | 
						|
								    return m_base;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								inline glob_sequence::const_iterator glob_sequence::end() const
							 | 
						|
								{
							 | 
						|
								    return m_base + m_cItems;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								#ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
							 | 
						|
								inline glob_sequence::const_reverse_iterator glob_sequence::rbegin() const
							 | 
						|
								{
							 | 
						|
								    return const_reverse_iterator(end());
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								inline glob_sequence::const_reverse_iterator glob_sequence::rend() const
							 | 
						|
								{
							 | 
						|
								    return const_reverse_iterator(begin());
							 | 
						|
								}
							 | 
						|
								#endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
							 | 
						|
								
							 | 
						|
								inline us_bool_t glob_sequence::is_valid() const
							 | 
						|
								{
							 | 
						|
								    if((0 != m_cItems) && (NULL == m_base))
							 | 
						|
								    {
							 | 
						|
								        return false;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    return true;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								inline /* static */ us_int_t glob_sequence::validate_flags_(us_int_t flags)
							 | 
						|
								{
							 | 
						|
								    const us_int_t  validFlags  =   0
							 | 
						|
								                                |   includeDots
							 | 
						|
								                                |   directories
							 | 
						|
								                                |   files
							 | 
						|
								                                |   noSort
							 | 
						|
								                                |   markDirs
							 | 
						|
								                                |   absolutePath
							 | 
						|
								                                |   breakOnError
							 | 
						|
								                                |   noEscape
							 | 
						|
								#ifdef GLOB_PERIOD
							 | 
						|
								                                |   matchPeriod
							 | 
						|
								#endif /* GLOB_PERIOD */
							 | 
						|
								#ifdef GLOB_BRACE
							 | 
						|
								                                |   bracePatterns
							 | 
						|
								#endif /* GLOB_BRACE */
							 | 
						|
								#ifdef GLOB_TILDE
							 | 
						|
								                                |   expandTilde
							 | 
						|
								#endif /* GLOB_TILDE */
							 | 
						|
								                                |   0;
							 | 
						|
								
							 | 
						|
								    UNIXSTL_MESSAGE_ASSERT("Specification of unrecognised/unsupported flags", flags == (flags & validFlags));
							 | 
						|
								    STLSOFT_SUPPRESS_UNUSED(validFlags);
							 | 
						|
								
							 | 
						|
								    if(0 == (flags & (directories | files)))
							 | 
						|
								    {
							 | 
						|
								        flags |= (directories | files);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								#ifndef UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK
							 | 
						|
								    // If we're not searching for directories, then we can optimise the
							 | 
						|
								    // subsequent filtering by asking for the dots directories (so we
							 | 
						|
								    // skip that filtering) and asking for directories to be marked (so
							 | 
						|
								    // we can detect the mark rather than making a system call (stat())
							 | 
						|
								    if(0 == (flags & directories))
							 | 
						|
								    {
							 | 
						|
								        // It's more efficient to not bother doing a separate dots check if all
							 | 
						|
								        // directories are being elided.
							 | 
						|
								        flags |= includeDots;
							 | 
						|
								
							 | 
						|
								        // Since we're not going to be returning directories to the caller, and
							 | 
						|
								        // it's more efficient to believe the glob() directory marking rather
							 | 
						|
								        // than calling stat, we add the markDirs flag here.
							 | 
						|
								        flags |= markDirs;
							 | 
						|
								    }
							 | 
						|
								#endif /* !UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK */
							 | 
						|
								
							 | 
						|
								    return flags;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								inline /* static */ us_bool_t glob_sequence::is_path_separator_(glob_sequence::char_type ch)
							 | 
						|
								{
							 | 
						|
								    return  ch == '/'
							 | 
						|
								#if defined(_UNIXSTL_COMPILER_IS_UNKNOWN) && \
							 | 
						|
								    !defined(_UNIXSTL_GLOB_SEQUENCE_NO_BACK_SLASH_TERMINATOR)
							 | 
						|
								            || ch == '\\' /* Allow for testing on Win32 systems */
							 | 
						|
								#endif /* _UNIXSTL_COMPILER_IS_UNKNOWN && !_UNIXSTL_GLOB_SEQUENCE_NO_BACK_SLASH_TERMINATOR */
							 | 
						|
								            ;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								inline /* static */ us_bool_t glob_sequence::is_end_of_path_elements_(glob_sequence::char_type const* pch, glob_sequence::difference_type index)
							 | 
						|
								{
							 | 
						|
								    return  pch[index] == '\0' ||
							 | 
						|
								            (   pch[index + 1] == '\0' &&
							 | 
						|
								                is_path_separator_(pch[index]));
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								inline /* static */ us_bool_t glob_sequence::is_dots_maybe_slashed_(glob_sequence::char_type const* s, us_bool_t* bTwoDots)
							 | 
						|
								{
							 | 
						|
								    UNIXSTL_ASSERT(NULL != s);
							 | 
						|
								    UNIXSTL_ASSERT(NULL != bTwoDots);
							 | 
						|
								
							 | 
						|
								    // This must match all patterns like the following:
							 | 
						|
								    //
							 | 
						|
								    // "."          l=1, s[0] = .
							 | 
						|
								    // ".."         l=2, s[0] = ., s[1] = .
							 | 
						|
								    // "./"         l=2, s[0] = ., s[1] = sep
							 | 
						|
								    // "../"        l=3, s[0] = ., s[1] = ., s[2] = sep
							 | 
						|
								    // "abc/."
							 | 
						|
								    // "abc/.."
							 | 
						|
								    // "abc/./"
							 | 
						|
								    // "abc/../"
							 | 
						|
								
							 | 
						|
								    const us_size_t len             =   traits_type::str_len(s);
							 | 
						|
								    us_size_t       lastNameChar    =   len -1;
							 | 
						|
								
							 | 
						|
								    UNIXSTL_ASSERT(len > 0);
							 | 
						|
								
							 | 
						|
								    if(is_path_separator_(s[lastNameChar]))
							 | 
						|
								    {
							 | 
						|
								        --lastNameChar;
							 | 
						|
								    }
							 | 
						|
								    if('.' == s[lastNameChar])
							 | 
						|
								    {
							 | 
						|
								        if(0 == lastNameChar)
							 | 
						|
								        {
							 | 
						|
								            return true;
							 | 
						|
								        }
							 | 
						|
								        else
							 | 
						|
								        {
							 | 
						|
								            --lastNameChar;
							 | 
						|
								
							 | 
						|
								            if( 0 == lastNameChar ||
							 | 
						|
								                is_path_separator_(s[lastNameChar]))
							 | 
						|
								            {
							 | 
						|
								                *bTwoDots = false;
							 | 
						|
								                return true;
							 | 
						|
								            }
							 | 
						|
								            else if( 0 < lastNameChar &&
							 | 
						|
								                    '.' == s[lastNameChar])
							 | 
						|
								            {
							 | 
						|
								                --lastNameChar;
							 | 
						|
								
							 | 
						|
								                if( 0 == lastNameChar ||
							 | 
						|
								                    is_path_separator_(s[lastNameChar]))
							 | 
						|
								                {
							 | 
						|
								                    *bTwoDots = true;
							 | 
						|
								                    return true;
							 | 
						|
								                }
							 | 
						|
								                else
							 | 
						|
								                {
							 | 
						|
								                    return false;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    return false;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								inline us_size_t glob_sequence::init_glob_(glob_sequence::char_type const* directory, glob_sequence::char_type const* pattern)
							 | 
						|
								{
							 | 
						|
								    UNIXSTL_MESSAGE_ASSERT("Null pattern given to glob_sequence", NULL != pattern);
							 | 
						|
								
							 | 
						|
								    char_type const* lastSlash = traits_type::find_last_path_name_separator(pattern);
							 | 
						|
								
							 | 
						|
								    if(NULL == lastSlash)
							 | 
						|
								    {
							 | 
						|
								        // already properly separated
							 | 
						|
								
							 | 
						|
								        return init_glob_2_(directory, pattern);
							 | 
						|
								    }
							 | 
						|
								    else
							 | 
						|
								    {
							 | 
						|
								        if(traits_type::is_path_rooted(pattern))
							 | 
						|
								        {
							 | 
						|
								            directory = NULL;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        basic_file_path_buffer<char_type>   scratch_;   // Scratch buffer for directory + pattern
							 | 
						|
								
							 | 
						|
								        size_type                           dirLen  =   (NULL == directory) ? 0u : traits_type::str_len(directory);
							 | 
						|
								        size_type                           patLen  =   traits_type::str_len(pattern);
							 | 
						|
								
							 | 
						|
								        if(0 != dirLen)
							 | 
						|
								        {
							 | 
						|
								            traits_type::char_copy(&scratch_[0] + 0, directory, dirLen);
							 | 
						|
								            scratch_[dirLen] = '\0';
							 | 
						|
								            dirLen += traits_type::str_len(traits_type::ensure_dir_end(&scratch_[0] + (dirLen - 1))) - 1;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        traits_type::char_copy(&scratch_[0] + dirLen, pattern, patLen);
							 | 
						|
								        scratch_[dirLen + patLen] = '\0';
							 | 
						|
								
							 | 
						|
								        return init_glob_1_(scratch_.size(), scratch_.data());
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								inline us_size_t glob_sequence::init_glob_1_(size_type bufferSize, char_type* combinedPath)
							 | 
						|
								{
							 | 
						|
								    char_type const* const lastSlash = traits_type::find_last_path_name_separator(combinedPath);
							 | 
						|
								
							 | 
						|
								    UNIXSTL_ASSERT(NULL != lastSlash);
							 | 
						|
								
							 | 
						|
								    combinedPath[lastSlash - combinedPath] = '\0';
							 | 
						|
								
							 | 
						|
								    char_type const*    directory   =   combinedPath;
							 | 
						|
								    char_type const*    pattern     =   lastSlash + 1;
							 | 
						|
								
							 | 
						|
								    return init_glob_2_(directory, pattern);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								inline us_size_t glob_sequence::init_glob_2_(char_type const* directory, char_type const* pattern0)
							 | 
						|
								{
							 | 
						|
								    // Preconditions:
							 | 
						|
								    //
							 | 
						|
								    // - pattern must not be NULL
							 | 
						|
								    // - pattern must not contain a path-name separator
							 | 
						|
								    UNIXSTL_ASSERT(NULL != pattern0);
							 | 
						|
								    UNIXSTL_ASSERT(NULL == traits_type::str_chr(pattern0, '/'));
							 | 
						|
								#ifdef _WIN32
							 | 
						|
								    UNIXSTL_ASSERT(NULL == traits_type::str_chr(pattern0, '\\'));
							 | 
						|
								#endif /* _WIN32 */
							 | 
						|
								
							 | 
						|
								    static char_type const s_wildChars[] = { '?', '*', '\0' };
							 | 
						|
								
							 | 
						|
								    us_bool_t const isPattern0Wild = (NULL != traits_type::str_pbrk(pattern0, s_wildChars));
							 | 
						|
								
							 | 
						|
								    if( NULL != directory &&
							 | 
						|
								        '\0' != directory[0])
							 | 
						|
								    {
							 | 
						|
								        if( absolutePath == (m_flags & absolutePath) &&
							 | 
						|
								            !traits_type::is_path_rooted(directory))
							 | 
						|
								        {
							 | 
						|
								            us_bool_t const isPatternDirWild = (NULL != traits_type::str_pbrk(directory, s_wildChars));
							 | 
						|
								
							 | 
						|
								            if(isPatternDirWild)
							 | 
						|
								            {
							 | 
						|
								                errno = EINVAL;
							 | 
						|
								
							 | 
						|
								                m_base = NULL;
							 | 
						|
								
							 | 
						|
								                return 0;
							 | 
						|
								            }
							 | 
						|
								            else
							 | 
						|
								            {
							 | 
						|
								                basic_file_path_buffer<char_type> scratch2_; // Scratch buffer for absolute path
							 | 
						|
								
							 | 
						|
								                size_type absLen = traits_type::get_full_path_name(directory, scratch2_.size(), &scratch2_[0]);
							 | 
						|
								
							 | 
						|
								                if(0 == absLen)
							 | 
						|
								                {
							 | 
						|
								                    m_base = NULL;
							 | 
						|
								
							 | 
						|
								                    return 0;
							 | 
						|
								                }
							 | 
						|
								                else
							 | 
						|
								                {
							 | 
						|
								                    return init_glob_2_(scratch2_.data(), pattern0);
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								        else
							 | 
						|
								        {
							 | 
						|
								            basic_file_path_buffer<char_type> scratch_;   // Scratch buffer for directory / pattern
							 | 
						|
								
							 | 
						|
								#ifndef STLSOFT_CF_EXCEPTION_SUPPORT
							 | 
						|
								            if(0 == scratch_.size())
							 | 
						|
								            {
							 | 
						|
								                m_base = NULL;
							 | 
						|
								
							 | 
						|
								                return 0;
							 | 
						|
								            }
							 | 
						|
								            else
							 | 
						|
								#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT */
							 | 
						|
								            {
							 | 
						|
								                size_type dirLen = traits_type::str_len(directory);
							 | 
						|
								                size_type patLen = traits_type::str_len(pattern0);
							 | 
						|
								
							 | 
						|
								                traits_type::char_copy(&scratch_[0] + 0, directory, dirLen);
							 | 
						|
								                scratch_[dirLen] = '\0';
							 | 
						|
								
							 | 
						|
								                dirLen += traits_type::str_len(traits_type::ensure_dir_end(&scratch_[0] + (dirLen - 1))) - 1;
							 | 
						|
								
							 | 
						|
								                traits_type::char_copy(&scratch_[0] + dirLen, pattern0, patLen);
							 | 
						|
								                scratch_[dirLen + patLen] = '\0';
							 | 
						|
								
							 | 
						|
								                return init_glob_3_(scratch_.c_str(), isPattern0Wild);
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								    else
							 | 
						|
								    {
							 | 
						|
								        return init_glob_3_(pattern0, isPattern0Wild);
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								inline us_size_t glob_sequence::init_glob_3_(char_type const* pattern, bool isPattern0Wild)
							 | 
						|
								{
							 | 
						|
								    us_int_t glob_flags = 0;
							 | 
						|
								
							 | 
						|
								    if(m_flags & noSort)
							 | 
						|
								    {
							 | 
						|
								        // Don't bother sorting
							 | 
						|
								        glob_flags |= GLOB_NOSORT;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    if(m_flags & markDirs)
							 | 
						|
								    {
							 | 
						|
								        // Ask for trailing slashes on directories
							 | 
						|
								        glob_flags |= GLOB_MARK;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								#ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR // If this is not defined, we rely on stat
							 | 
						|
								    if(directories == (m_flags & (directories | files)))
							 | 
						|
								    {
							 | 
						|
								        // Ask for only directories
							 | 
						|
								        glob_flags |= GLOB_ONLYDIR;
							 | 
						|
								    }
							 | 
						|
								#endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR */
							 | 
						|
								
							 | 
						|
								#ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG // If this is not defined, we rely on stat
							 | 
						|
								    if(files == (m_flags & (directories | files)))
							 | 
						|
								    {
							 | 
						|
								        // Ask for only files
							 | 
						|
								        glob_flags |= GLOB_ONLYREG;
							 | 
						|
								    }
							 | 
						|
								#endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG */
							 | 
						|
								
							 | 
						|
								#ifdef GLOB_ERR
							 | 
						|
								    if(m_flags & breakOnError)
							 | 
						|
								    {
							 | 
						|
								        glob_flags |= GLOB_ERR;
							 | 
						|
								    }
							 | 
						|
								#endif /* GLOB_ERR */
							 | 
						|
								
							 | 
						|
								#ifdef GLOB_NOESCAPE
							 | 
						|
								    if(m_flags & noEscape)
							 | 
						|
								    {
							 | 
						|
								        glob_flags |= GLOB_NOESCAPE;
							 | 
						|
								    }
							 | 
						|
								#endif /* GLOB_NOESCAPE */
							 | 
						|
								
							 | 
						|
								#ifdef GLOB_PERIOD
							 | 
						|
								    if(m_flags & matchPeriod)
							 | 
						|
								    {
							 | 
						|
								        glob_flags |= GLOB_PERIOD;
							 | 
						|
								    }
							 | 
						|
								#endif /* GLOB_PERIOD */
							 | 
						|
								
							 | 
						|
								#ifdef GLOB_BRACE
							 | 
						|
								    if(m_flags & bracePatterns)
							 | 
						|
								    {
							 | 
						|
								        glob_flags |= GLOB_BRACE;
							 | 
						|
								    }
							 | 
						|
								#endif /* GLOB_BRACE */
							 | 
						|
								
							 | 
						|
								#ifdef GLOB_TILDE
							 | 
						|
								    if(m_flags & expandTilde)
							 | 
						|
								    {
							 | 
						|
								        glob_flags |= GLOB_TILDE;
							 | 
						|
								    }
							 | 
						|
								#endif /* GLOB_TILDE */
							 | 
						|
								
							 | 
						|
								#ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS
							 | 
						|
								    if(0 == (m_flags & includeDots))
							 | 
						|
								    {
							 | 
						|
								        glob_flags |= GLOB_NODOTSDIRS;
							 | 
						|
								    }
							 | 
						|
								#endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS */
							 | 
						|
								
							 | 
						|
								    int gr = ::glob(pattern, glob_flags, NULL, &m_glob);
							 | 
						|
								
							 | 
						|
								    if(0 != gr)
							 | 
						|
								    {
							 | 
						|
								#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
							 | 
						|
								# ifdef GLOB_NOMATCH
							 | 
						|
								        // When GLOB_NOMATCH is not defined, we can reasonably infer that
							 | 
						|
								        // there is no replacement value, so throwing on a non-zero
							 | 
						|
								        // return from glob() is appropriate
							 | 
						|
								        if(GLOB_NOMATCH != gr)
							 | 
						|
								# endif /* GLOB_NOMATCH */
							 | 
						|
								        {
							 | 
						|
								            STLSOFT_THROW_X(glob_sequence_exception(gr, 0));
							 | 
						|
								        }
							 | 
						|
								#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
							 | 
						|
								
							 | 
						|
								        m_base = NULL;
							 | 
						|
								
							 | 
						|
								        return 0;
							 | 
						|
								    }
							 | 
						|
								    else
							 | 
						|
								    {
							 | 
						|
								        // Sink the glob_t instance into a local scoped_handle, to invoke
							 | 
						|
								        // ::globfree() automatically if we encounter any problems during
							 | 
						|
								        // the processing. At the end we'll call detach(), to "give it"
							 | 
						|
								        // to the glob_sequence instance.
							 | 
						|
								
							 | 
						|
								        stlsoft_ns_qual(scoped_handle)<glob_t*> cleanup(&m_glob, ::globfree);
							 | 
						|
								
							 | 
						|
								        char_type** base    =   m_glob.gl_pathv;
							 | 
						|
								        us_size_t   cItems  =   static_cast<us_size_t>(m_glob.gl_pathc);
							 | 
						|
								
							 | 
						|
								        // This section performs a COW on the entry pointers, into
							 | 
						|
								        // the m_buffer member, if any of the following hold:
							 | 
						|
								        //
							 | 
						|
								        // 1. we're eliding dots
							 | 
						|
								        // 2. we want directories only, and so will need to
							 | 
						|
								        //     remove files, AND we do not trust GLOB_ONLYDIR
							 | 
						|
								        // 3. we want files only, and so will need
							 | 
						|
								        //     to remove directories
							 | 
						|
								        //
							 | 
						|
								
							 | 
						|
								        bool const elidingDots = isPattern0Wild && (0 == (m_flags & includeDots));
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								        if( elidingDots ||                                      // 1
							 | 
						|
								#ifndef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR
							 | 
						|
								            directories == (m_flags & (directories | files)) || // 2
							 | 
						|
								#endif /* !UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR */
							 | 
						|
								            files == (m_flags & (directories | files)))         // 3
							 | 
						|
								        {
							 | 
						|
								            if(!m_buffer.resize(cItems))
							 | 
						|
								            {
							 | 
						|
								#ifndef STLSOFT_CF_EXCEPTION_SUPPORT
							 | 
						|
								                m_base = NULL;
							 | 
						|
								
							 | 
						|
								                return 0;
							 | 
						|
								#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT */
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            UNIXSTL_ASSERT(m_buffer.size() == cItems);
							 | 
						|
								
							 | 
						|
								            base = static_cast<char_type**>(memcpy(&m_buffer[0], base, m_buffer.size() * sizeof(char_type*)));
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        // This section elides dots directories.
							 | 
						|
								        if(elidingDots)
							 | 
						|
								        {
							 | 
						|
								#ifndef UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS
							 | 
						|
								            // Now remove the dots. If located at the start of
							 | 
						|
								            // the gl buffer, then simply increment m_base to
							 | 
						|
								            // be above that. If not then rearrange the base
							 | 
						|
								            // two pointers such that they are there.
							 | 
						|
								
							 | 
						|
								            us_bool_t           bFoundDot1   =   false;
							 | 
						|
								            us_bool_t           bFoundDot2   =   false;
							 | 
						|
								            char_type**         begin        =   base;
							 | 
						|
								            char_type** const   end          =   begin + cItems;
							 | 
						|
								
							 | 
						|
								            for(; begin != end; ++begin)
							 | 
						|
								            {
							 | 
						|
								                us_bool_t bTwoDots = false;
							 | 
						|
								
							 | 
						|
								                if(is_dots_maybe_slashed_(*begin, &bTwoDots))
							 | 
						|
								                {
							 | 
						|
								                    // Swap with whatever is at base[0]
							 | 
						|
								                    if(begin != base)
							 | 
						|
								                    {
							 | 
						|
								                        stlsoft_ns_qual(std_swap)(*begin, *base);
							 | 
						|
								                    }
							 | 
						|
								                    ++base;
							 | 
						|
								                    --cItems;
							 | 
						|
								
							 | 
						|
								                     // We're only going to get one "." and one ".."
							 | 
						|
								                    (bTwoDots ? bFoundDot2 : bFoundDot1) = true;
							 | 
						|
								
							 | 
						|
								                    if( bFoundDot1 &&
							 | 
						|
								                        bFoundDot2)
							 | 
						|
								                    {
							 | 
						|
								                        break;
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								#endif /* !UNIXSTL_GLOB_SEQUENCE_TRUST_NODOTSDIRS */
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        // This section performs the main filtering section, with
							 | 
						|
								        // conditional shortcuts for if any of the following hold:
							 | 
						|
								        //
							 | 
						|
								        // 1. Looking for files only
							 | 
						|
								        //  - and GLOB_ONLYREG is supported
							 | 
						|
								        // 2. Looking for directories only
							 | 
						|
								        //  - and GLOB_ONLYDIR is supported
							 | 
						|
								        // 3. Looking for anything
							 | 
						|
								        // 
							 | 
						|
								
							 | 
						|
								#ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG
							 | 
						|
								        // 1. Looking for files only
							 | 
						|
								        if(files == (m_flags & (directories | files)))
							 | 
						|
								        {
							 | 
						|
								            ; // Nothing to do
							 | 
						|
								        }
							 | 
						|
								        else
							 | 
						|
								#endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYREG */
							 | 
						|
								#ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR
							 | 
						|
								        // 2. Looking for directories only
							 | 
						|
								        if(directories == (m_flags & (directories | files)))
							 | 
						|
								        {
							 | 
						|
								            ; // Nothing to do
							 | 
						|
								        }
							 | 
						|
								        else
							 | 
						|
								#endif /* UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR */
							 | 
						|
								        // 3. Looking for anything
							 | 
						|
								        if(0 == (m_flags & (directories | files)))
							 | 
						|
								        {
							 | 
						|
								            // NOTE: this conditional branch is a future-compatibility
							 | 
						|
								            // feature, for when sockets and links are supported
							 | 
						|
								
							 | 
						|
								            ; // Nothing to do
							 | 
						|
								        }
							 | 
						|
								        else
							 | 
						|
								        {
							 | 
						|
								            // Must filter based on type ascertained by call to stat()
							 | 
						|
								            // (except if we trust MARKDIR
							 | 
						|
								
							 | 
						|
								            char_type**         begin   =   base;
							 | 
						|
								            char_type** const   end     =   begin + cItems;
							 | 
						|
								
							 | 
						|
								            for(; begin != end; ++begin)
							 | 
						|
								            {
							 | 
						|
								                // Now need to process the file, by using stat
							 | 
						|
								                traits_type::stat_data_type st;
							 | 
						|
								                char_type const* const      entry = *begin;
							 | 
						|
								
							 | 
						|
								                // Shortcut relying on mark, based on the assumption that
							 | 
						|
								                // a strlen()-equiv. operation is faster than a call to
							 | 
						|
								                // stat().
							 | 
						|
								# ifndef UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK
							 | 
						|
								                if(markDirs == (m_flags & markDirs))
							 | 
						|
								                {
							 | 
						|
								                    bool const isDirectory = traits_type::has_dir_end(entry);
							 | 
						|
								
							 | 
						|
								                    if( isDirectory &&
							 | 
						|
								                        directories == (m_flags & (directories)))
							 | 
						|
								                    {
							 | 
						|
								                        // It is a directory, and we want directories, so
							 | 
						|
								                        // don't elide (by continue-ing)
							 | 
						|
								                        continue;
							 | 
						|
								                    }
							 | 
						|
								                    else
							 | 
						|
								                    if( !isDirectory &&
							 | 
						|
								                        files == (m_flags & (directories | files)))
							 | 
						|
								                    {
							 | 
						|
								                        // It is not a directory, and we want files,
							 | 
						|
								                        // so don't elide (by continue-ing)
							 | 
						|
								                        continue;
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								                else
							 | 
						|
								# endif /* !UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK */
							 | 
						|
								                if(!traits_type::stat(entry, &st))
							 | 
						|
								                {
							 | 
						|
								                    // We could throw an exception here, but it might just be
							 | 
						|
								                    // the case that a file has been deleted subsequent to its
							 | 
						|
								                    // having been included in the glob list. As such, it makes
							 | 
						|
								                    // more sense to just kick it from the list
							 | 
						|
								
							 | 
						|
								// TODO: Consider adding a callback function here, which can elect to throw, if the application requires that. Also, consider a throwOnStat flag
							 | 
						|
								                }
							 | 
						|
								                else
							 | 
						|
								                { // stat() succeeded
							 | 
						|
								
							 | 
						|
								                    if( files == (m_flags & (files)) &&
							 | 
						|
								                        traits_type::is_file(&st))
							 | 
						|
								                    {
							 | 
						|
								                        continue; // A file, so accept it
							 | 
						|
								                    }
							 | 
						|
								                    else
							 | 
						|
								                    if( directories == (m_flags & (directories)) &&
							 | 
						|
								                        traits_type::is_directory(&st))
							 | 
						|
								                    {
							 | 
						|
								                        continue; // A directory, so accept it
							 | 
						|
								                    }
							 | 
						|
								                    else
							 | 
						|
								                    {
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								
							 | 
						|
								                // This section elides the entry from the list
							 | 
						|
								                //
							 | 
						|
								                // Note that there is no test here to determine whether or not
							 | 
						|
								                // begin == base. It is assumed that most cases of file elision
							 | 
						|
								                // will involve several files - how many directories have just
							 | 
						|
								                // one file in them? - so the test would actually be a
							 | 
						|
								                // pessimisation
							 | 
						|
								
							 | 
						|
								                // Swap with whatever is at base[0]
							 | 
						|
								                stlsoft_ns_qual(std_swap)(*begin, *base);
							 | 
						|
								                ++base;
							 | 
						|
								                --cItems;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        // Ensure we've not corrupted the sort order
							 | 
						|
								        if( 0 == (m_flags & noSort) &&
							 | 
						|
								            cItems != static_cast<us_size_t>(m_glob.gl_pathc))
							 | 
						|
								        {
							 | 
						|
								            unixstl_ns_qual_std(sort)(base, base + cItems);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        // Set m_base and m_cItems to the correct values, with
							 | 
						|
								        // or without dots. m_base is cast here to remove the
							 | 
						|
								        // need for const-casting throughout the rest of the
							 | 
						|
								        // class
							 | 
						|
								        m_base = const_cast<char_type const**>(base);
							 | 
						|
								
							 | 
						|
								        // Everything has succeeded, so give ownership over to the
							 | 
						|
								        // glob_sequence instance
							 | 
						|
								        cleanup.detach();
							 | 
						|
								
							 | 
						|
								        return cItems;
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
							 | 
						|
								
							 | 
						|
								/* ////////////////////////////////////////////////////////////////////// */
							 | 
						|
								
							 | 
						|
								#ifndef _UNIXSTL_NO_NAMESPACE
							 | 
						|
								# if defined(_STLSOFT_NO_NAMESPACE) || \
							 | 
						|
								     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
							 | 
						|
								} // namespace unixstl
							 | 
						|
								# else
							 | 
						|
								} // namespace unixstl_project
							 | 
						|
								} // namespace stlsoft
							 | 
						|
								# endif /* _STLSOFT_NO_NAMESPACE */
							 | 
						|
								#endif /* !_UNIXSTL_NO_NAMESPACE */
							 | 
						|
								
							 | 
						|
								/* ////////////////////////////////////////////////////////////////////// */
							 | 
						|
								
							 | 
						|
								#endif /* !UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE */
							 | 
						|
								
							 | 
						|
								/* ///////////////////////////// end of file //////////////////////////// */
							 |