⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glob_sequence.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 3 页
字号:
#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_())
        , 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 /* = noSort */)
        : 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 = noSort);

    template<ss_typename_param_k S>
    glob_sequence(S const& directory, char const* pattern, us_int_t flags = noSort)
        : 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 = noSort)
        : 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 = noSort);

    glob_sequence(char_type const* directory, char_type const* pattern, us_int_t flags = noSort);

#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 = noSort);
#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_CF_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_CF_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 = noSort);

    // 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
    us_size_t           init_glob_(char_type const* directory, char_type const* pattern);
/// @}

/// \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 /* = noSort */)
    : 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 /* = noSort */)
    : 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 /* = noSort */)
    : 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 /* = noSort */)
    : m_flags(validate_flags_(flags))
    , m_buffer(1)
{

    m_cItems = init_glob_(NULL, 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_CF_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_CF_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);

    // 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( 0 < lastNameChar &&
        '.' == s[lastNameChar])
    {
        --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;
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -