text:
/** \file stlsoft/containers/pod_vector.hpp
 *
 * \brief [C++ only] Definition of the stlsoft::pod_vector container class
 *   template
 *   (\ref group__library__containers "Containers" Library).
 */

#ifndef STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_POD_VECTOR
#define STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_POD_VECTOR

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_POD_VECTOR_MAJOR       4
# define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_POD_VECTOR_MINOR       2
# define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_POD_VECTOR_REVISION    2
# define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_POD_VECTOR_EDIT        76
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

/* /////////////////////////////////////////////////////////////////////////
 * Compatibility
 */

/*
[Incompatibilies-start]
STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
STLSOFT_COMPILER_IS_WATCOM:
[Incompatibilies-end]
 */

/* /////////////////////////////////////////////////////////////////////////
 * Includes
 */

#ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
# include <stlsoft/stlsoft.h>
#endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */

#if defined(STLSOFT_COMPILER_IS_MSVC) && \
    _MSC_VER < 1200
# error stlsoft/containers/pod_vector.hpp is not compatible with Visual C++ 5.0 or earlier
#endif /* compiler */

#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_UTIL_HPP_STD_SWAP
# include <stlsoft/util/std_swap.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP */
#ifndef STLSOFT_INCL_STLSOFT_ALGORITHMS_HPP_POD
# include <stlsoft/algorithms/pod.hpp>          // for pod_copy_n(), etc.
#endif /* !STLSOFT_INCL_STLSOFT_ALGORITHMS_HPP_POD */
#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_STD_HPP_ITERATOR_HELPER
# include <stlsoft/util/std/iterator_helper.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER */

#ifndef STLSOFT_INCL_STDEXCEPT
# define STLSOFT_INCL_STDEXCEPT
# include <stdexcept>                            // for std::out_of_range
#endif /* !STLSOFT_INCL_STDEXCEPT */

/* /////////////////////////////////////////////////////////////////////////
 * Namespace
 */

#ifndef _STLSOFT_NO_NAMESPACE
namespace stlsoft
{
#endif /* _STLSOFT_NO_NAMESPACE */

/* /////////////////////////////////////////////////////////////////////////
 * Classes
 */

/** \brief Efficient vector class for use with POD types only
 *
 * \ingroup group__library__containers
 */
template<   ss_typename_param_k T
#if defined(STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT) && \
    defined(STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT)
        ,   ss_typename_param_k A       =   ss_typename_type_def_k allocator_selector<T>::allocator_type
        ,   ss_size_t           SPACE   =   64
#else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT && STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT */
        ,   ss_typename_param_k A       /* =    ss_typename_type_def_k stlsoft_ns_qual(allocator_selector)<T>::allocator_type */
        ,   ss_size_t           SPACE   /* =    64 */
#endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT && STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT */
        >
class pod_vector
    : public stl_collection_tag
{
/// \name Typedefs
/// @{
private:
    typedef auto_buffer_old<T, A, SPACE>                            buffer_type_;
public:
    /// The value type
    typedef ss_typename_type_k buffer_type_::value_type             value_type;
    /// The allocator type
    typedef ss_typename_type_k buffer_type_::allocator_type         allocator_type;
    /// The type of the current parameterisation
    typedef pod_vector<T, A, SPACE>                                 class_type;
    /// The reference type
    typedef ss_typename_type_k buffer_type_::reference              reference;
    /// The non-mutable (const) reference type
    typedef ss_typename_type_k buffer_type_::const_reference        const_reference;
    /// The pointer type
    typedef ss_typename_type_k buffer_type_::pointer                pointer;
    /// The non-mutable (const) pointer type
    typedef ss_typename_type_k buffer_type_::const_pointer          const_pointer;
    /// The iterator type
    typedef ss_typename_type_k buffer_type_::iterator               iterator;
    /// The non-mutable (const) iterator type
    typedef ss_typename_type_k buffer_type_::const_iterator         const_iterator;
#if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
    /// The type of the non-const (mutating) reverse iterator
    typedef ss_typename_type_k buffer_type_::reverse_iterator       reverse_iterator;
    /// The type of the const (non-mutating) reverse iterator
    typedef ss_typename_type_k buffer_type_::const_reverse_iterator const_reverse_iterator;
#endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
    /// The size type
    typedef ss_typename_type_k buffer_type_::size_type              size_type;
    /// The difference type
    typedef ss_typename_type_k buffer_type_::difference_type        difference_type;
/// @}

/// \name Construction
/// @{
public:
    ss_explicit_k pod_vector(size_type cItems = 0);
    pod_vector(size_type cItems, value_type const& value);
    pod_vector(class_type const& rhs);
    pod_vector(const_iterator first, const_iterator last);

    pod_vector& operator =(class_type const& rhs);
/// @}

/// \name Iteration
/// @{
public:
    iterator                begin();
    const_iterator          begin() const;
    iterator                end();
    const_iterator          end() const;
#if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
    reverse_iterator        rbegin();
    const_reverse_iterator  rbegin() const;
    reverse_iterator        rend();
    const_reverse_iterator  rend() const;
#endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
/// @}

/// \name Attributes
/// @{
public:
    size_type       size() const;
    size_type       capacity() const;
    size_type       max_size() const;
    ss_bool_t       empty() const;
    allocator_type  get_allocator() const;
/// @}

/// \name Accessors
/// @{
public:
    reference       at(size_type index);
    const_reference at(size_type index) const;
    reference       operator [](size_type index);
    const_reference operator [](size_type index) const;
    reference       front();
    const_reference front() const;
    reference       back();
    const_reference back() const;
/// @}

/// \name Operations
/// @{
public:
    void        clear();
    void        swap(class_type& rhs);
    void        reserve(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */;
// Note: resize() is split into two, so the one-param version can be very quick
    void        resize(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */;
    void        resize(size_type cItems, value_type const& value) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */;
    void        push_back(value_type const& value);
    void        pop_back();

    void        assign(const_iterator first, const_iterator last);
    void        assign(size_type cItems, value_type const& value = value_type());
    iterator    insert(iterator it, value_type const& value = value_type());
    void        insert(iterator it, size_type cItems, value_type const& value);
    void        insert(iterator it, const_iterator first, const_iterator last);
    iterator    erase(iterator it);
    iterator    erase(iterator first, iterator last);
/// @}

/// \name Implementation
/// @{
private:
    pointer         begin_();
    const_pointer   begin_() const;

    void        range_check_(size_type index) const /* stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) ) */;

    ss_bool_t   resize_(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */;

    ss_bool_t   is_valid_() const;
/// @}

/// \name Members
/// @{
private:
    size_type       m_cItems;   // A size member is used, rather than m_end (iterator), because some of the state
                                // is maintained in the parent class. Doing it this way makes swap() and other methods
                                // very simple.
    buffer_type_    m_buffer;   // The auto_buffer
/// @}
};

/* /////////////////////////////////////////////////////////////////////////
 * Operators
 */

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline ss_bool_t operator ==(pod_vector<T, A, SPACE> const& lhs, pod_vector<T, A, SPACE> const& rhs)
{
    if(lhs.size() != rhs.size())
    {
        return false;
    }
    else
    {
#if 0
        for(ss_typename_type_k pod_vector<T, A, SPACE>::size_type i = 0, size = lhs.size(); i < size; ++i)
        {
            if(lhs[i] != rhs[i])
            {
                return false;
            }
        }

        return true;
#else /* ? 0 */
        return 0 == memcmp(&lhs[0], &rhs[0], sizeof(ss_typename_type_k pod_vector<T, A, SPACE>::size_type) * lhs.size());
#endif /* 0 */
    }
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline ss_bool_t operator !=(pod_vector<T, A, SPACE> const& lhs, pod_vector<T, A, SPACE> const& rhs)
{
    return !operator ==(lhs, rhs);
}

/* /////////////////////////////////////////////////////////////////////////
 * swapping
 */

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline void swap(pod_vector<T, A, SPACE>& lhs, pod_vector<T, A, SPACE>& rhs)
{
    lhs.swap(rhs);
}

/* /////////////////////////////////////////////////////////////////////////
 * Unit-testing
 */

#ifdef STLSOFT_UNITTEST
# include "./unittest/pod_vector_unittest_.h"
#endif /* STLSOFT_UNITTEST */

/* /////////////////////////////////////////////////////////////////////////
 * Implementation
 */

#if defined(STLSOFT_COMPILER_IS_MSVC) && \
    _MSC_VER >= 1310
# define STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS
#endif /* compiler */

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::pointer pod_vector<T, A, SPACE>::begin_()
{
    return m_buffer.data();
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_pointer pod_vector<T, A, SPACE>::begin_() const
{
    return m_buffer.data();
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline void pod_vector<T, A, SPACE>::range_check_(size_type index) const /* stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) ) */
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline void pod_vector<T, A, SPACE>::range_check_(ss_typename_type_k pod_vector<T, A, SPACE>::size_type index) const /* stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) ) */
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline void pod_vector<T, A, SPACE>::range_check_(size_type index) const /* stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) ) */
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
# ifdef STLSOFT_CF_EXCEPTION_SUPPORT
    if(!(index < size()))
    {
        STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("pod vector index out of range"));
    }
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
    STLSOFT_MESSAGE_ASSERT("w index out of range", index < size());
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline ss_bool_t pod_vector<T, A, SPACE>::resize_(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_bool_t pod_vector<T, A, SPACE>::resize_(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_bool_t pod_vector<T, A, SPACE>::resize_(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    // This method is only called for insertions, so we can make some assumptions.

    size_type   curr_capacity   =   capacity();

    // We only resize the internal buffer if it is not large enough
    if(cItems > curr_capacity)
    {
        size_type   capacity = m_buffer.internal_size() + cItems;

        capacity -= capacity % m_buffer.internal_size();

        if(!m_buffer.resize(capacity))
        {
            return false;
        }
    }

    m_cItems = cItems;

    return true;
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline ss_bool_t pod_vector<T, A, SPACE>::is_valid_() const
{
    if(m_buffer.size() < m_cItems)
    {
        return false;
    }

    return true;
}

// Construction

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline /* ss_explicit_k */ pod_vector<T, A, SPACE>::pod_vector(size_type cItems /* = 0 */)
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline /* ss_explicit_k */ pod_vector<T, A, SPACE>::pod_vector(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems /* = 0 */)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline /* ss_explicit_k */ pod_vector<T, A, SPACE>::pod_vector(size_type cItems /* = 0 */)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
    : m_buffer(cItems)
{
    m_cItems = m_buffer.size(); // This is done here, since it comes before m_buffer in
                                // the object layout for efficiency (caching) reasons

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline pod_vector<T, A, SPACE>::pod_vector(size_type cItems, value_type const& value)
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline pod_vector<T, A, SPACE>::pod_vector(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems, ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline pod_vector<T, A, SPACE>::pod_vector(size_type cItems, value_type const& value)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
    : m_buffer(cItems)
{
    m_cItems = m_buffer.size(); // This is done here, since it comes before m_buffer in
                                // the object layout for efficiency (caching) reasons

    pod_fill_n(begin_(), size(), value);

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline pod_vector<T, A, SPACE>::pod_vector(class_type const& rhs)
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline pod_vector<T, A, SPACE>::pod_vector(ss_typename_type_k pod_vector<T, A, SPACE>::class_type const& rhs)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline pod_vector<T, A, SPACE>::pod_vector(class_type const& rhs)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
    : m_buffer(rhs.size())
{
    m_cItems = m_buffer.size(); // This is done here, since it comes before m_buffer in
                                // the object layout for efficiency (caching) reasons

    pod_copy_n(begin_(), rhs.begin_(), size());

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline pod_vector<T, A, SPACE>::pod_vector(const_iterator first, const_iterator last)
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline pod_vector<T, A, SPACE>::pod_vector(ss_typename_type_k pod_vector<T, A, SPACE>::const_iterator first, ss_typename_type_k pod_vector<T, A, SPACE>::const_iterator last)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline pod_vector<T, A, SPACE>::pod_vector(const_iterator first, const_iterator last)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
    : m_buffer(static_cast<ss_size_t>(last - first))
{
    m_cItems = m_buffer.size(); // This is done here, since it comes before m_buffer in
                                // the object layout for efficiency (caching) reasons

    if(0 != size()) // It will either be the full size requested, or 0
    {
        pod_copy(&*first, &*last, begin_());
    }

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline pod_vector<T, A, SPACE> &pod_vector<T, A, SPACE>::operator =(class_type const& rhs)
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline pod_vector<T, A, SPACE> &pod_vector<T, A, SPACE>::operator =(ss_typename_type_k pod_vector<T, A, SPACE>::class_type const& rhs)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline pod_vector<T, A, SPACE> &pod_vector<T, A, SPACE>::operator =(class_type const& rhs)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
// NOTE: This will be optimised by testing the contents of this and the rhs

    STLSOFT_ASSERT(is_valid_());

    class_type  temp(rhs);

    temp.swap(*this);

    STLSOFT_ASSERT(is_valid_());

    return *this;
}

// Iteration

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::begin()
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::begin()
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    return m_buffer.begin();
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_iterator pod_vector<T, A, SPACE>::begin() const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_iterator pod_vector<T, A, SPACE>::begin() const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    return m_buffer.begin();
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::end()
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::end()
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    return &begin_()[size()];
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_iterator pod_vector<T, A, SPACE>::end() const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_iterator pod_vector<T, A, SPACE>::end() const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    return &begin_()[size()];
}

#if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reverse_iterator pod_vector<T, A, SPACE>::rbegin()
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reverse_iterator pod_vector<T, A, SPACE>::rbegin()
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    return reverse_iterator(end());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reverse_iterator pod_vector<T, A, SPACE>::rbegin() const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reverse_iterator pod_vector<T, A, SPACE>::rbegin() const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    return const_reverse_iterator(end());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reverse_iterator pod_vector<T, A, SPACE>::rend()
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reverse_iterator pod_vector<T, A, SPACE>::rend()
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    return reverse_iterator(begin());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reverse_iterator pod_vector<T, A, SPACE>::rend() const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reverse_iterator pod_vector<T, A, SPACE>::rend() const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    return const_reverse_iterator(begin());
}
#endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */

// Attributes

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::size_type pod_vector<T, A, SPACE>::size() const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_size_t pod_vector<T, A, SPACE>::size() const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    return m_cItems;
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::size_type pod_vector<T, A, SPACE>::capacity() const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_size_t pod_vector<T, A, SPACE>::capacity() const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    return m_buffer.size();
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::size_type pod_vector<T, A, SPACE>::max_size() const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_size_t pod_vector<T, A, SPACE>::max_size() const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    return static_cast<size_type>(-1) / sizeof(value_type);
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline ss_bool_t pod_vector<T, A, SPACE>::empty() const
{
    STLSOFT_ASSERT(is_valid_());

    return 0 == size();
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::allocator_type pod_vector<T, A, SPACE>::get_allocator() const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::allocator_type pod_vector<T, A, SPACE>::get_allocator() const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    return m_buffer.get_allocator();
}

// Accessors
template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::at(size_type index)
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::at(ss_typename_type_k pod_vector<T, A, SPACE>::size_type index)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline T &pod_vector<T, A, SPACE>::at(size_type index)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    range_check_(index);

    STLSOFT_ASSERT(is_valid_());

    return begin_()[index];
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::at(size_type index) const
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::at(ss_typename_type_k pod_vector<T, A, SPACE>::size_type index) const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline T const& pod_vector<T, A, SPACE>::at(size_type index) const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    range_check_(index);

    STLSOFT_ASSERT(is_valid_());

    return begin_()[index];
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::operator [](size_type index)
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::operator [](ss_typename_type_k pod_vector<T, A, SPACE>::size_type index)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline T &pod_vector<T, A, SPACE>::operator [](size_type index)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    // The index must be <= the size(). It is allowed to be equal to the size because
    // we must facilitate the taking of the end() element in order to specify ranges.
    STLSOFT_MESSAGE_ASSERT("Requested index is out of range", !(size() < index));

    return begin_()[index];
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::operator [](size_type index) const
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::operator [](ss_typename_type_k pod_vector<T, A, SPACE>::size_type index) const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline T const& pod_vector<T, A, SPACE>::operator [](size_type index) const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    STLSOFT_MESSAGE_ASSERT("Requested index is out of range", index < size());

    return begin_()[index];
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::front()
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::front()
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline T &pod_vector<T, A, SPACE>::front()
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    STLSOFT_MESSAGE_ASSERT("Range is empty!", 0 != size());

    return begin_()[0];
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::front() const
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::front() const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline T const& pod_vector<T, A, SPACE>::front() const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    STLSOFT_MESSAGE_ASSERT("Range is empty!", 0 != size());

    return begin_()[0];
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::back()
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::back()
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline T &pod_vector<T, A, SPACE>::back()
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    STLSOFT_MESSAGE_ASSERT("Range is empty!", 0 != size());

    return begin_()[size() - 1];
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::back() const
#elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::back() const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline T const& pod_vector<T, A, SPACE>::back() const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    STLSOFT_MESSAGE_ASSERT("Range is empty!", 0 != size());

    return begin_()[size() - 1];
}

// Operations

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline void pod_vector<T, A, SPACE>::clear()
{
    STLSOFT_ASSERT(is_valid_());

    if(m_buffer.resize(0))
    {
        m_cItems = 0;
    }

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline void pod_vector<T, A, SPACE>::swap(pod_vector<T, A, SPACE>& rhs)
{
    STLSOFT_ASSERT(is_valid_());

    m_buffer.swap(rhs.m_buffer);
    std_swap(m_cItems, rhs.m_cItems);

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline void pod_vector<T, A, SPACE>::reserve(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline void pod_vector<T, A, SPACE>::reserve(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    // We do not follow vector's much maligned example and refuse to truncate, although
    // we only do so if the requested size is 0.
    if( 0 == cItems ||
        cItems > size())
    {
        m_buffer.resize(cItems);
    }

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline void pod_vector<T, A, SPACE>::resize(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline void pod_vector<T, A, SPACE>::resize(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    resize(cItems, value_type());

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline void pod_vector<T, A, SPACE>::resize(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems, ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline void pod_vector<T, A, SPACE>::resize(size_type cItems, ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    if(m_buffer.resize(cItems))
    {
        if(m_cItems < cItems)
        {
            pod_fill_n(begin_() + m_cItems, cItems - m_cItems, value);
        }

        m_cItems = cItems;
    }

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline void pod_vector<T, A, SPACE>::push_back(ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline void pod_vector<T, A, SPACE>::push_back(ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    insert(end(), value);

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
inline void pod_vector<T, A, SPACE>::pop_back()
{
    STLSOFT_ASSERT(is_valid_());

    STLSOFT_MESSAGE_ASSERT("No elements to pop", size() > 0);

    if(0 == --m_cItems)
    {
        m_buffer.resize(0);
    }

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline void pod_vector<T, A, SPACE>::assign(ss_typename_type_k pod_vector<T, A, SPACE>::const_iterator first, ss_typename_type_k pod_vector<T, A, SPACE>::const_iterator last)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline void pod_vector<T, A, SPACE>::assign(const_iterator first, const_iterator last)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

// NOTE: This will be optimised by testing the contents of this and the rhs

    class_type  temp(first, last);

    temp.swap(*this);

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline void pod_vector<T, A, SPACE>::assign(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems, ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value /* = value_type() */)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline void pod_vector<T, A, SPACE>::assign(size_type cItems, value_type const& value /* = value_type() */)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

// NOTE: This will be optimised by testing the contents of this and the rhs

    class_type  temp(cItems, value);

    temp.swap(*this);

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::insert(ss_typename_type_k pod_vector<T, A, SPACE>::iterator it, ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value /* = value_type() */)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::insert(iterator it, value_type const& value /* = value_type() */)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    STLSOFT_ASSERT(!(end() < it));
    STLSOFT_ASSERT(!(it < begin()));

    size_type   index = static_cast<size_type>(it - begin());

    insert(it, 1, value);

    STLSOFT_ASSERT(is_valid_());

    return begin() + index;
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline void pod_vector<T, A, SPACE>::insert(ss_typename_type_k pod_vector<T, A, SPACE>::iterator it, ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems, ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline void pod_vector<T, A, SPACE>::insert(iterator it, size_type cItems, value_type const& value)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    STLSOFT_ASSERT(!(end() < it));
    STLSOFT_ASSERT(!(it < begin()));

    size_type   curr_size   =   size();
    size_type   index       =   static_cast<size_type>(it - begin());

    if(resize_(size() + cItems))
    {
        size_type cMove = curr_size - index;

        // The resize_ may have invalidated the iterator(s)!!
        it = begin() + index;

        // Move the existing ones up out of the way
        pod_move_n(&it[cItems], &it[0], cMove);

        // And insert the new ones
        pod_fill_n(begin_() + index, cItems, value);
    }

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline void pod_vector<T, A, SPACE>::insert(ss_typename_type_k pod_vector<T, A, SPACE>::iterator it, ss_typename_type_k pod_vector<T, A, SPACE>::const_iterator first, ss_typename_type_k pod_vector<T, A, SPACE>::const_iterator last)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline void pod_vector<T, A, SPACE>::insert(iterator it, const_iterator first, const_iterator last)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    STLSOFT_ASSERT(!(end() < it));
    STLSOFT_ASSERT(!(it < begin()));

    size_type   curr_size   =   size();
    size_type   index       =   it - begin();
    size_type   cItems      =   last - first;

    if(resize_(size() + cItems))
    {
        size_type cMove = curr_size - index;

        // The resize_ may have invalidated the iterator(s)!!
        it = begin() + index;

        // Move the existing ones up out of the way
        pod_move_n(&it[cItems], &it[0], cMove);

        // And insert the new ones
        pod_copy_n(it, first, cItems);
    }

    STLSOFT_ASSERT(is_valid_());
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::erase(ss_typename_type_k pod_vector<T, A, SPACE>::iterator it)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::erase(iterator it)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    STLSOFT_ASSERT(it < end());
    STLSOFT_ASSERT(!(it < begin()));

    size_type   index = it - begin();
    size_type   cMove = size() - (index + 1);

    pod_move_n(&it[0], &it[1], cMove);

    if(0 == --m_cItems)
    {
        m_buffer.resize(0);

        it = begin();
    }

    STLSOFT_ASSERT(is_valid_());

    return it;
}

template<   ss_typename_param_k T
        ,   ss_typename_param_k A
        ,   ss_size_t           SPACE
        >
#if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::erase(ss_typename_type_k pod_vector<T, A, SPACE>::iterator first, ss_typename_type_k pod_vector<T, A, SPACE>::iterator last)
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::erase(iterator first, iterator last)
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
    STLSOFT_ASSERT(is_valid_());

    STLSOFT_ASSERT(first < end());
    STLSOFT_ASSERT(!(first < begin()));
    STLSOFT_ASSERT(!(end() < last));
    STLSOFT_ASSERT(!(last < begin()));

    size_type   curr_size   =   size();
    size_type   index_first =   first - begin();
    size_type   index_last  =   last - begin();
    size_type   cItems      =   last - first;
    size_type   cMove       =   curr_size - index_last;

    // Move the remaining ones down
    pod_move_n(&first[0], &last[0], cMove);

    resize(curr_size - cItems);

    STLSOFT_ASSERT(is_valid_());

    return begin() + index_first;
}

#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

/* ////////////////////////////////////////////////////////////////////// */

#ifndef _STLSOFT_NO_NAMESPACE
} // namespace stlsoft
#endif /* _STLSOFT_NO_NAMESPACE */

/* In the special case of Intel behaving as VC++ 7.0 or earlier on Win32, we
 * illegally insert into the std namespace.
 */
#if defined(STLSOFT_CF_std_NAMESPACE)
# if ( ( defined(STLSOFT_COMPILER_IS_INTEL) && \
         defined(_MSC_VER))) && \
     _MSC_VER < 1310
namespace std
{
    template<   ss_typename_param_k         T
            ,   ss_typename_param_k         A
            ,   stlsoft_ns_qual(ss_size_t)  SPACE
            >
    inline void swap(stlsoft_ns_qual(pod_vector)<T, A, SPACE>& lhs, stlsoft_ns_qual(pod_vector)<T, A, SPACE>& rhs)
    {
        lhs.swap(rhs);
    }
} // namespace std
# endif /* INTEL && _MSC_VER < 1310 */
#endif /* STLSOFT_CF_std_NAMESPACE */

/* ////////////////////////////////////////////////////////////////////// */

#endif /* !STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_POD_VECTOR */

/* ///////////////////////////// end of file //////////////////////////// */


text:
layout: post
title:  "People first"
date:   2016-02-23 00:10:25
categories: software people
---

It's important to always put people first. [Even when writing software].

I've worked with software developers who forgets this. Heck, I forget it sometimes too.

Some developers write code (software) for machines first. They forget it's humans that maintain code over time. This reason is most times a huge contributor to why some programmers [remain mediocre].

The amount of energy, friction, and time lost for not having this as a principle is huge, both as an individual developer and as a software team.

Always remember this.

[Even when writing software]: http://blog.codinghorror.com/assertiveness-for-software-developers/
[remain mediocre]: http://blog.codinghorror.com/how-to-become-a-better-programmer-by-not-programming/

redpajama_set_name: RedPajamaGithub


text:
"""
tankmanager.status
~~~~~~~~~~~~~~~~~~

Get tanks current status:
    * test lock file
    * file system usage
    * logged users
    * etc
"""
import os
import commands
import multiprocessing

from flask import request, jsonify

from . import status
from .. helpers import get_usage_fire, get_hops

def get_usage_cpu():
    result = dict(zip(['1m', '5m', '15m'], os.getloadavg()))
    result['cores_num'] = multiprocessing.cpu_count()
    return result

def get_usage_disk(path='/home', rec=10):
    result = {}
    retcode, du = commands.getstatusoutput(\
    'du -csk %s/* 2>/dev/null | sort -r -n' % path)
    for line in du.split('\n')[:rec + 1]:
        splt = line.split()
        result[splt[1]] = splt[0]
    return result

@status.route('/usage/<tgt>', methods=['GET'])
def usage(tgt):
    if str(tgt) == 'all':
        result = {
            'cpu': get_usage_cpu(),
            'disk': get_usage_disk(),
            'fire': get_usage_fire(),
        }
        return jsonify(result)

    if str(tgt) == 'cpu':
        return jsonify(get_usage_cpu())

    if str(tgt) == 'disk':
        return jsonify(get_usage_disk())

    if str(tgt) == 'fire':
        return jsonify(get_usage_fire())

    return 'No such tgt', 404

@status.route('/hops/to', methods=['GET'])
def hops_to():
    dst_hosts = request.args.get('hosts', None)
    if not dst_hosts:
        return '*hosts* request param is required', 400

    fqdn_lst = dst_hosts.split(',')
    result = [(name, get_hops(name)) for name in fqdn_lst]
    return jsonify(result)


text:
package com.ibm.timetrackerweb.model.obsolete;

import java.io.Serializable;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

import com.fasterxml.jackson.annotation.JsonIgnore;

//@Entity
public class IpAddress  implements Serializable{

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;

	/*@ManyToOne(targetEntity = MacAddress.class)
	@JoinColumn(name="id",insertable=false, updatable=false)
	private Integer parentId;*/
	@JsonIgnore
	@ManyToOne
	private MacAddress parent;

	@Column
	private String ipAddress;

	@Column
	private String startTime;

	@Column
	private String endTime;

	@Column
	private String parentMac;

	public String getIpAddress() {
		return ipAddress;
	}

	public void setIpAddress(String ipAddress) {
		this.ipAddress = ipAddress;
	}

	public String getStartTime() {
		return startTime;
	}

	public void setStartTime(String startTime) {
		this.startTime = startTime;
	}

	public String getEndTime() {
		return endTime;
	}

	public void setEndTime(String endTime) {
		this.endTime = endTime;
	}

	public String getParentMac() {
		return parentMac;
	}

	public void setParentMac(String parentMac) {
		this.parentMac = parentMac;
	}

	protected double getHours()
	{
		if(getEndTime() == null || getStartTime() == null)
		{
			return 0;
		}
		Calendar cal = Calendar.getInstance();
		String[] endTime = getEndTime().split(":");
		cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(endTime[0]));
		cal.set(Calendar.MINUTE, Integer.parseInt(endTime[1]));
		long end = cal.getTimeInMillis();

		String[] startTime = getStartTime().split(":");
		cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(startTime[0]));
		cal.set(Calendar.MINUTE, Integer.parseInt(startTime[1]));
		long start = cal.getTimeInMillis();

		long diff = end - start;
		long hours = TimeUnit.MILLISECONDS.toHours(diff);
		long minutes = TimeUnit.MILLISECONDS.toMinutes(diff - (hours * 60 * 60 * 1000));
		double minuteD = (double)minutes/60;
		return hours + minuteD;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	/*public Integer getParentId() {
		return parentId;
	}

	public void setParentId(Integer parentId) {
		this.parentId = parentId;
	}*/

	public MacAddress getParent() {
		return parent;
	}

	public void setParent(MacAddress parent) {
		this.parent = parent;
	}

}


text:
package org.elasticsearch.test.transport;

import org.elasticsearch.Version;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.test.hamcrest.ElasticsearchAssertions;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.*;
import org.elasticsearch.transport.local.LocalTransport;

import java.io.IOException;
import java.util.Random;

/**
 *
 */
public class AssertingLocalTransport extends LocalTransport {
    private final Random random;

    @Inject
    public AssertingLocalTransport(Settings settings, ThreadPool threadPool, Version version) {
        super(settings, threadPool, version);
        final long seed = settings.getAsLong(ElasticsearchIntegrationTest.INDEX_SEED_SETTING, 0l);
        random = new Random(seed);
    }

    @Override
    protected void handleParsedRespone(final TransportResponse response, final TransportResponseHandler handler) {
        ElasticsearchAssertions.assertVersionSerializable(ElasticsearchTestCase.randomVersion(random), response);
        super.handleParsedRespone(response, handler);
    }

    @Override
    public void sendRequest(final DiscoveryNode node, final long requestId, final String action, final TransportRequest request, TransportRequestOptions options) throws IOException, TransportException {
        ElasticsearchAssertions.assertVersionSerializable(ElasticsearchTestCase.randomVersion(random), request);
        super.sendRequest(node, requestId, action, request, options);
    }
}


text:
gameNumber = open("gameNumber.txt", "rU")
num = int(gameNumber.readline())
gameNumber.close()

tableString = "htmlTables/table" + str(num) + ".html"
tableFile = open(tableString, "rU")
tableHTML = [line for line in tableFile]
tableFile.close()

print "Content-type: text/html"
print
print "<title>X-League Stats</title>"
print "<img src=\"testImg.png\">"
for line in tableHTML:
    print line


text:
using System.Collections;
using System.Collections.Generic;
using System.Linq;

/// <summary>
/// A Dual-Key Dictionary class. The original (thread-safe) implementation
/// can be found at:
/// http://www.fyslexicduck.com/2009/02/multi-key-generic-dictionary-class-for.html
/// </summary>
/// <typeparam name="TKey1">The type of the primary key.</typeparam>
/// <typeparam name="TKey2">The type of the sub-key.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
public class DualKeyDictionary<TKey1, TKey2, TValue> : IEnumerable<KeyValuePair<TKey1, TValue>>
{
    private readonly Dictionary<TKey1, TValue> baseDictionary = new Dictionary<TKey1, TValue>();
    private readonly Dictionary<TKey2, TKey1> subDictionary = new Dictionary<TKey2, TKey1>();
    private readonly Dictionary<TKey1, TKey2> primaryToSubKeyMapping = new Dictionary<TKey1, TKey2>();

    public List<TValue> Values
    {
        get
        {
            return this.baseDictionary.Values.ToList();
        }
    }

    public int Count
    {
        get
        {
            return this.baseDictionary.Count;
        }
    }

    public TValue this[TKey2 subKey]
    {
        get
        {
            TValue item;
            if (this.TryGetValue(subKey, out item))
            {
                return item;
            }

            throw new KeyNotFoundException("Sub-key not found: " + subKey.ToString());
        }
    }

    public TValue this[TKey1 primaryKey]
    {
        get
        {
            TValue item;
            if (this.TryGetValue(primaryKey, out item))
            {
                return item;
            }

            throw new KeyNotFoundException("Primary key not found: " + primaryKey.ToString());
        }
    }

    public void Associate(TKey2 subKey, TKey1 primaryKey)
    {
        if (!this.baseDictionary.ContainsKey(primaryKey))
        {
            throw new KeyNotFoundException(string.Format("The base dictionary does not contain the key '{0}'", primaryKey));
        }

        if (this.primaryToSubKeyMapping.ContainsKey(primaryKey))
        {
            // Remove the old mapping first
            TKey2 oldSubKey = this.primaryToSubKeyMapping[primaryKey];
            if (this.subDictionary.ContainsKey(oldSubKey))
            {
                this.subDictionary.Remove(oldSubKey);
            }

            this.primaryToSubKeyMapping.Remove(primaryKey);
        }

        this.subDictionary[subKey] = primaryKey;
        this.primaryToSubKeyMapping[primaryKey] = subKey;
    }

    public bool TryGetValue(TKey2 subKey, out TValue value)
    {
        value = default(TValue);

        TKey1 primaryKey;
        if (this.subDictionary.TryGetValue(subKey, out primaryKey))
        {
            return this.baseDictionary.TryGetValue(primaryKey, out value);
        }

        return false;
    }

    public bool TryGetValue(TKey1 primaryKey, out TValue value)
    {
        return this.baseDictionary.TryGetValue(primaryKey, out value);
    }

    public bool ContainsKey(TKey2 subKey)
    {
        TValue value;

        return this.TryGetValue(subKey, out value);
    }

    public bool ContainsKey(TKey1 primaryKey)
    {
        TValue value;

        return this.TryGetValue(primaryKey, out value);
    }

    public void Remove(TKey1 primaryKey)
    {
        if (this.primaryToSubKeyMapping.ContainsKey(primaryKey))
        {
            TKey2 subKey = this.primaryToSubKeyMapping[primaryKey];
            if (this.subDictionary.ContainsKey(subKey))
            {
                this.subDictionary.Remove(subKey);
            }

            this.primaryToSubKeyMapping.Remove(primaryKey);
        }

        this.baseDictionary.Remove(primaryKey);
    }

    public void Remove(TKey2 subKey)
    {
        TKey1 primaryKey = this.subDictionary[subKey];
        this.baseDictionary.Remove(primaryKey);

        this.primaryToSubKeyMapping.Remove(primaryKey);

        this.subDictionary.Remove(subKey);
    }

    public void Add(TKey1 primaryKey, TValue value)
    {
        this.baseDictionary.Add(primaryKey, value);
    }

    public void Add(TKey1 primaryKey, TKey2 subKey, TValue val)
    {
        this.Add(primaryKey, val);

        this.Associate(subKey, primaryKey);
    }

    public TValue[] CloneValues()
    {
        TValue[] values = new TValue[this.baseDictionary.Values.Count];

        this.baseDictionary.Values.CopyTo(values, 0);

        return values;
    }

    public TKey1[] ClonePrimaryKeys()
    {
        TKey1[] primaryKeys = new TKey1[this.baseDictionary.Keys.Count];

        this.baseDictionary.Keys.CopyTo(primaryKeys, 0);

        return primaryKeys;
    }

    public TKey2[] CloneSubKeys()
    {
        TKey2[] subKeys = new TKey2[this.subDictionary.Keys.Count];

        this.subDictionary.Keys.CopyTo(subKeys, 0);

        return subKeys;
    }

    public void Clear()
    {
        this.baseDictionary.Clear();

        this.subDictionary.Clear();

        this.primaryToSubKeyMapping.Clear();
    }

    public IEnumerator<KeyValuePair<TKey1, TValue>> GetEnumerator()
    {
        return this.baseDictionary.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable<KeyValuePair<TKey1, TValue>>)this).GetEnumerator();
    }
}


text:
namespace GeodesicDist
{
    class CApproximateOneToAll : public CExactOneToAll
    {
    private:
        void CutHeapTopData(EdgeWindow& EdgeWindowOut) override;
    };
}


text:
# coding: utf-8

#-------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
#--------------------------------------------------------------------------
import unittest
import time

import azure.mgmt.servicebus.models
from azure.mgmt.servicebus.models import SBNamespace,SBSku,SkuName,SBQueue,SBAuthorizationRule,AccessRights,AccessKeys
from azure.common.credentials import ServicePrincipalCredentials

from devtools_testutils import AzureMgmtTestCase, RandomNameResourceGroupPreparer

class MgmtServiceBusTest(AzureMgmtTestCase):

    def setUp(self):
        super(MgmtServiceBusTest, self).setUp()

        self.servicebus_client = self.create_mgmt_client(
            azure.mgmt.servicebus.ServiceBusManagementClient
        )

    @RandomNameResourceGroupPreparer()
    def test_sb_queue_curd(self, resource_group, location):
        # List all topic types
        resource_group_name = resource_group.name

        # Create a Namespace
        namespace_name = self.get_replayable_random_resource_name("testingpythontestcasequeue")

        namespaceparameter = SBNamespace(location=location, tags={'tag1': 'value1', 'tag2': 'value2'}, sku=SBSku(name=SkuName.standard))
        creatednamespace = self.servicebus_client.namespaces.create_or_update(resource_group_name, namespace_name, namespaceparameter).result()
        self.assertEqual(creatednamespace.name, namespace_name)

        while (self.servicebus_client.namespaces.get(resource_group_name, namespace_name).provisioning_state != 'Succeeded'):
            if self.is_live:
                time.sleep(15)
            continue

        # Create a Queue
        queue_name = self.get_replayable_random_resource_name("testingpythonsdkqueue")
        createqueueresponse = self.servicebus_client.queues.create_or_update(resource_group_name, namespace_name,queue_name,SBQueue())
        self.assertEqual(createqueueresponse.name, queue_name)

        # Get the created Queue
        getqueueresponse = self.servicebus_client.queues.get(resource_group_name, namespace_name,queue_name)
        self.assertEqual(getqueueresponse.name, queue_name)

        # Get all the queues
        listbynamespacequeueresponse = list(self.servicebus_client.queues.list_by_namespace(resource_group_name, namespace_name))
        self.assertEqual(len(listbynamespacequeueresponse),1)
        self.assertEqual(listbynamespacequeueresponse[0].name, queue_name)

        # update queue
        updatequeueresponse = self.servicebus_client.queues.create_or_update(resource_group_name, namespace_name, queue_name, SBQueue(enable_express=True, max_delivery_count=5, max_size_in_megabytes=1024 ))
        self.assertEqual(updatequeueresponse.name, queue_name)
        self.assertEqual(updatequeueresponse.max_delivery_count, 5)
        self.assertEqual(updatequeueresponse.max_size_in_megabytes, 1024)
        self.assertEqual(updatequeueresponse.enable_express, True)

        # Create a new authorizationrule
        authoRule_name = self.get_replayable_random_resource_name("testingauthrulepy")
        createqueueauthorule = self.servicebus_client.queues.create_or_update_authorization_rule(resource_group_name, namespace_name, queue_name, authoRule_name, [AccessRights('Send'), AccessRights('Listen')])
        self.assertEqual(createqueueauthorule.name, authoRule_name,"Authorization rule name not as created - create_or_update_authorization_rule ")
        self.assertEqual(len(createqueueauthorule.rights), 2)

        # Get the created authorizationrule
        getqueueauthorule = self.servicebus_client.queues.get_authorization_rule(resource_group_name, namespace_name, queue_name, authoRule_name)
        self.assertEqual(getqueueauthorule.name, authoRule_name, "Authorization rule name not as passed as parameter - get_authorization_rule")
        self.assertEqual(len(getqueueauthorule.rights), 2, "Access rights mis match as created  - get_authorization_rule ")

        # update the rights of the authorizatiorule
        getqueueauthorule.rights.append('Manage')
        updatequeueauthorule = self.servicebus_client.queues.create_or_update_authorization_rule(resource_group_name, namespace_name, queue_name, authoRule_name, getqueueauthorule.rights)
        self.assertEqual(updatequeueauthorule.name, authoRule_name,"Authorization rule name not as passed as parameter for update call - create_or_update_authorization_rule ")
        self.assertEqual(len(updatequeueauthorule.rights), 3,"Access rights mis match as updated  - create_or_update_authorization_rule ")

        # list all the authorization ruels for the given Queue
        listqueueauthorule = list(self.servicebus_client.queues.list_authorization_rules(resource_group_name, namespace_name, queue_name))
        self.assertEqual(len(listqueueauthorule), 1,"number of authorization rule mismatch, created = 1 - list_authorization_rules")

        # List keys for the authorization rule
        listkeysauthorizationrule = self.servicebus_client.queues.list_keys(resource_group_name, namespace_name, queue_name, authoRule_name)
        self.assertIsNotNone(listkeysauthorizationrule)

        # regenerate Keys for authorizationrule - Primary
        regenratePrimarykeyauthorizationrule = self.servicebus_client.queues.regenerate_keys(resource_group_name,namespace_name, queue_name, authoRule_name,'PrimaryKey')
        self.assertNotEqual(listkeysauthorizationrule.primary_key, regenratePrimarykeyauthorizationrule.primary_key)

        # regenerate Keys for authorizationrule - Primary
        regenrateSecondarykeyauthorizationrule = self.servicebus_client.queues.regenerate_keys(resource_group_name,namespace_name, queue_name, authoRule_name,'SecondaryKey')
        self.assertNotEqual(listkeysauthorizationrule.secondary_key, regenrateSecondarykeyauthorizationrule.secondary_key)

        # delete the authorizationrule
        self.servicebus_client.queues.delete_authorization_rule(resource_group_name, namespace_name, queue_name, authoRule_name)

        # list all the authorization ruels for the given Queue
        listqueueauthorule = list(self.servicebus_client.queues.list_authorization_rules(resource_group_name, namespace_name, queue_name))
        lenTemp = len(listqueueauthorule)

        # delete the Queue
        self.servicebus_client.queues.delete(resource_group_name, namespace_name, queue_name)

        # Delete the create namespace
        deletenamespace = self.servicebus_client.namespaces.delete(resource_group_name, namespace_name).result()

#------------------------------------------------------------------------------
if __name__ == '__main__':
    unittest.main()


text:
<!DOCTYPE html>

  <title>ui.js</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  <link rel="stylesheet" media="all" href="docco.css" />

          Jump To …
          +

<<< back to documentation

                abstract.js

                defaults.js

                factory.js

                field.js

                form.js

                main.js

                multiple.js

                pubsub.js

                remote.js

                ui.js

                utils.js

                validator.js

                validator_registry.js

ui.js

                ¶

import $ from 'jquery';
import ParsleyUtils from './utils';

var ParsleyUI = {};

var diffResults = function (newResult, oldResult, deep) {
  var added = [];
  var kept = [];

  for (var i = 0; i < newResult.length; i++) {
    var found = false;

    for (var j = 0; j < oldResult.length; j++)
      if (newResult[i].assert.name === oldResult[j].assert.name) {
        found = true;
        break;
      }

    if (found)
      kept.push(newResult[i]);
    else
      added.push(newResult[i]);
  }

  return {
    kept: kept,
    added: added,
    removed: !deep ? diffResults(oldResult, newResult, true).added : []
  };
};

ParsleyUI.Form = {

  _actualizeTriggers: function () {
    this.$element.on('submit.Parsley', evt => { this.onSubmitValidate(evt); });
    this.$element.on('click.Parsley', ParsleyUtils._SubmitSelector, evt => { this.onSubmitButton(evt); });

                ¶

UI could be disabled

    if (false === this.options.uiEnabled)
      return;

    this.$element.attr('novalidate', '');
  },

  focus: function () {
    this._focusedField = null;

    if (true === this.validationResult || 'none' === this.options.focus)
      return null;

    for (var i = 0; i < this.fields.length; i++) {
      var field = this.fields[i];
      if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {
        this._focusedField = field.$element;
        if ('first' === this.options.focus)
          break;
      }
    }

    if (null === this._focusedField)
      return null;

    return this._focusedField.focus();
  },

  _destroyUI: function () {

                ¶

Reset all event listeners

    this.$element.off('.Parsley');
  }

};

ParsleyUI.Field = {

  _reflowUI: function () {
    this._buildUI();

                ¶

If this field doesn't have an active UI don't bother doing something

    if (!this._ui)
      return;

                ¶

Diff between two validation results

    var diff = diffResults(this.validationResult, this._ui.lastValidationResult);

                ¶

Then store current validation result for next reflow

    this._ui.lastValidationResult = this.validationResult;

                ¶

Handle valid / invalid / none field class

    this._manageStatusClass();

                ¶

Add, remove, updated errors messages

    this._manageErrorsMessages(diff);

                ¶

Triggers impl

    this._actualizeTriggers();

                ¶

If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user

    if ((diff.kept.length || diff.added.length) && !this._failedOnce) {
      this._failedOnce = true;
      this._actualizeTriggers();
    }
  },

                ¶

Returns an array of field's error message(s)

  getErrorsMessages: function () {

                ¶

No error message, field is valid

    if (true === this.validationResult)
      return [];

    var messages = [];

    for (var i = 0; i < this.validationResult.length; i++)
      messages.push(this.validationResult[i].errorMessage ||
       this._getErrorMessage(this.validationResult[i].assert));

    return messages;
  },

                ¶

It's a goal of Parsley that this method is no longer required [#1073]

  addError: function (name, {message, assert, updateClass = true} = {}) {
    this._buildUI();
    this._addError(name, {message, assert});

    if (updateClass)
      this._errorClass();
  },

                ¶

It's a goal of Parsley that this method is no longer required [#1073]

  updateError: function (name, {message, assert, updateClass = true} = {}) {
    this._buildUI();
    this._updateError(name, {message, assert});

    if (updateClass)
      this._errorClass();
  },

                ¶

It's a goal of Parsley that this method is no longer required [#1073]

  removeError: function (name, {updateClass = true} = {}) {
    this._buildUI();
    this._removeError(name);

                ¶

edge case possible here: remove a standard Parsley error that is still failing in this.validationResult
but highly improbable cuz' manually removing a well Parsley handled error makes no sense.

    if (updateClass)
      this._manageStatusClass();
  },

  _manageStatusClass: function () {
    if (this.hasConstraints() && this.needsValidation() && true === this.validationResult)
      this._successClass();
    else if (this.validationResult.length > 0)
      this._errorClass();
    else
      this._resetClass();
  },

  _manageErrorsMessages: function (diff) {
    if ('undefined' !== typeof this.options.errorsMessagesDisabled)
      return;

                ¶

Case where we have errorMessage option that configure an unique field error message, regardless failing validators

    if ('undefined' !== typeof this.options.errorMessage) {
      if ((diff.added.length || diff.kept.length)) {
        this._insertErrorWrapper();

        if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length)
          this._ui.$errorsWrapper
            .append(
              $(this.options.errorTemplate)
              .addClass('parsley-custom-error-message')
            );

        return this._ui.$errorsWrapper
          .addClass('filled')
          .find('.parsley-custom-error-message')
          .html(this.options.errorMessage);
      }

      return this._ui.$errorsWrapper
        .removeClass('filled')
        .find('.parsley-custom-error-message')
        .remove();
    }

                ¶

Show, hide, update failing constraints messages

    for (var i = 0; i < diff.removed.length; i++)
      this._removeError(diff.removed[i].assert.name);

    for (i = 0; i < diff.added.length; i++)
      this._addError(diff.added[i].assert.name, {message: diff.added[i].errorMessage, assert: diff.added[i].assert});

    for (i = 0; i < diff.kept.length; i++)
      this._updateError(diff.kept[i].assert.name, {message: diff.kept[i].errorMessage, assert: diff.kept[i].assert});
  },

  _addError: function (name, {message, assert}) {
    this._insertErrorWrapper();
    this._ui.$errorsWrapper
      .addClass('filled')
      .append(
        $(this.options.errorTemplate)
        .addClass('parsley-' + name)
        .html(message || this._getErrorMessage(assert))
      );
  },

  _updateError: function (name, {message, assert}) {
    this._ui.$errorsWrapper
      .addClass('filled')
      .find('.parsley-' + name)
      .html(message || this._getErrorMessage(assert));
  },

  _removeError: function (name) {
    this._ui.$errorsWrapper
      .removeClass('filled')
      .find('.parsley-' + name)
      .remove();
  },

  _getErrorMessage: function (constraint) {
    var customConstraintErrorMessage = constraint.name + 'Message';

    if ('undefined' !== typeof this.options[customConstraintErrorMessage])
      return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);

    return window.Parsley.getErrorMessage(constraint);
  },

  _buildUI: function () {

                ¶

UI could be already built or disabled

    if (this._ui || false === this.options.uiEnabled)
      return;

    var _ui = {};

                ¶

Give field its Parsley id in DOM

    this.$element.attr(this.options.namespace + 'id', this.__id__);

    /** Generate important UI elements and store them in this **/

                ¶

$errorClassHandler is the $element that woul have parsley-error and parsley-success classes

    _ui.$errorClassHandler = this._manageClassHandler();

                ¶

$errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer

    _ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);
    _ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId);

                ¶

ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly

    _ui.lastValidationResult = [];
    _ui.validationInformationVisible = false;

                ¶

Store it in this for later

    this._ui = _ui;
  },

                ¶

Determine which element will have parsley-error and parsley-success classes

  _manageClassHandler: function () {

                ¶

An element selector could be passed through DOM with data-parsley-class-handler=#foo

    if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length)
      return $(this.options.classHandler);

                ¶

Class handled could also be determined by function given in Parsley options

    var $handler = this.options.classHandler.call(this, this);

                ¶

If this function returned a valid existing DOM element, go for it

    if ('undefined' !== typeof $handler && $handler.length)
      return $handler;

    return this._inputHolder();
  },

  _inputHolder: function() {

                ¶

if simple element (input, texatrea, select…) it will perfectly host the classes and precede the error container

    if (!this.options.multiple || this.$element.is('select'))
      return this.$element;

                ¶

But if multiple element (radio, checkbox), that would be their parent

    return this.$element.parent();
  },

  _insertErrorWrapper: function () {
    var $errorsContainer;

                ¶

Nothing to do if already inserted

    if (0 !== this._ui.$errorsWrapper.parent().length)
      return this._ui.$errorsWrapper.parent();

    if ('string' === typeof this.options.errorsContainer) {
      if ($(this.options.errorsContainer).length)
        return $(this.options.errorsContainer).append(this._ui.$errorsWrapper);
      else
        ParsleyUtils.warn('The errors container `'</span> + <span class="hljs-keyword">this</span>.options.errorsContainer + <span class="hljs-string">'` does not exist in DOM');
    } else if ('function' === typeof this.options.errorsContainer)
      $errorsContainer = this.options.errorsContainer.call(this, this);

    if ('undefined' !== typeof $errorsContainer && $errorsContainer.length)
      return $errorsContainer.append(this._ui.$errorsWrapper);

    return this._inputHolder().after(this._ui.$errorsWrapper);
  },

  _actualizeTriggers: function () {
    var $toBind = this._findRelated();
    var trigger;

                ¶

Remove Parsley events already bound on this field

    $toBind.off('.Parsley');
    if (this._failedOnce)
      $toBind.on(ParsleyUtils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), () => {
        this._validateIfNeeded();
      });
    else if (trigger = ParsleyUtils.namespaceEvents(this.options.trigger, 'Parsley')) {
      $toBind.on(trigger, event => {
        this._validateIfNeeded(event);
      });
    }
  },

  _validateIfNeeded: function (event) {

                ¶

For keyup, keypress, keydown, input… events that could be a little bit obstrusive
do not validate if val length < min threshold on first validation. Once field have been validated once and info
about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.

    if (event && /key|input/.test(event.type))
      if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold)
        return;

    if (this.options.debounce) {
      window.clearTimeout(this._debounced);
      this._debounced = window.setTimeout(() => this.validate(), this.options.debounce);
    } else
      this.validate();
  },

  _resetUI: function () {

                ¶

Reset all event listeners

    this._failedOnce = false;
    this._actualizeTriggers();

                ¶

Nothing to do if UI never initialized for this field

    if ('undefined' === typeof this._ui)
      return;

                ¶

Reset all errors' li

    this._ui.$errorsWrapper
      .removeClass('filled')
      .children()
      .remove();

                ¶

Reset validation class

    this._resetClass();

                ¶

Reset validation flags and last validation result

    this._ui.lastValidationResult = [];
    this._ui.validationInformationVisible = false;
  },

  _destroyUI: function () {
    this._resetUI();

    if ('undefined' !== typeof this._ui)
      this._ui.$errorsWrapper.remove();

    delete this._ui;
  },

  _successClass: function () {
    this._ui.validationInformationVisible = true;
    this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);
  },
  _errorClass: function () {
    this._ui.validationInformationVisible = true;
    this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);
  },
  _resetClass: function () {
    this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);
  }
};

export default ParsleyUI;


text:
goog.provide('shakaDemo.Utils');

shakaDemo.Utils = class {
  /**
   * Goes through the various values in shaka.extern.PlayerConfiguration, and
   * calls the given callback on them so that they can be stored to or read from
   * an URL hash.
   *
   * @param {function(string, string)} callback A callback to call on each
   *   config value that can be automatically handled. The first parameter is
   *   the hashName (desired name in the hash). The second parameter is the
   *   configName (the full path of the value, as found in the config object).
   *
   * @param {!shaka.extern.PlayerConfiguration} config A config object to use
   *   for reference. Note that the exact config values in this are not used; it
   *   is checked only to determine the shape and structure of a
   *   PlayerConfiguration object.
   */
  static runThroughHashParams(callback, config) {
    // Override the "natural" name for a config value in the hash.
    // This exists for legacy reasons; the previous demo page had some hash
    // values set to names that did not match the names of their corresponding
    // config object name.
    const overridden = [];
    const configOverride = (hashName, configName) => {
      overridden.push(configName);
      callback(hashName, configName);
    };

    // Override config values with custom names.
    configOverride('audiolang', 'preferredAudioLanguage');
    configOverride('textlang', 'preferredTextLanguage');
    configOverride('textrole', 'preferredTextRole');
    configOverride('channels', 'preferredAudioChannelCount');

    // Override config values that are handled manually.
    overridden.push('abr.enabled');
    overridden.push('streaming.jumpLargeGaps');
    overridden.push('drm.advanced');
    overridden.push('drm.servers');

    // Determine which config values should be given full namespace names.
    // This is to remove ambiguity in situations where there are two objects in
    // the config that share a key with the same name, without wasting space by
    // pointlessly adding namespace information to every value.
    const added = [];
    const collisions = [];
    const findCollisions = (object) => {
      for (const key in object) {
        if (added.includes(key) && !collisions.includes(key)) {
          collisions.push(key);
        }
        added.push(key);

        const value = object[key];
        if (typeof value != 'number' && typeof value != 'string' &&
            typeof value != 'boolean') {
          findCollisions(value);
        }
      }
    };
    findCollisions(config);

    // TODO: This system for handling name collisions does mean that, if a new
    // collision appears later on, old hashes will become invalid.
    // E.g. if we add 'manifest.bufferBehind', then suddenly the page will
    // discard any 'bufferBehind=' values from old hashes.

    // Now automatically do other config values.
    const handleConfig = (object, accumulated) => {
      for (const key in object) {
        let hashName = key;
        const configName = accumulated + key;
        if (overridden.includes(configName)) {
          continue;
        }
        if (collisions.includes(key)) {
          hashName = configName;
        }

        const value = object[key];
        if (typeof value == 'number' || typeof value == 'string' ||
            typeof value == 'boolean') {
          callback(hashName, configName);
        } else {
          handleConfig(value, configName + '.');
        }
      }
    };
    handleConfig(config, '');
  }

  /**
   * @return {boolean} True if the browser would support the uncompiled build.
   */
  static browserSupportsUncompiledMode() {
    // Check if ES6 arrow function syntax and ES7 async are usable.  Both are
    // needed for uncompiled builds to work.
    try {
      eval('async ()=>{}');
      return true;
    } catch (e) {
      return false;
    }
  }
};


text:
var GPBackgroundLayer = cc.LayerColor.extend({

  ctor: function (color) {

    this._super(color);

    this.initBackground();

  },

  initBackground: function () {
    var sptBg = new cc.Sprite(res.background);
    sptBg.attr({
      x: GC.w_2,
      y: GC.h_2
    });
    this.addChild(sptBg);
  }
});


text:
import type { PluginCreator } from 'postcss';
declare const creator: PluginCreator<null>;
export default creator;


text:
/*
Package client is a Go client for the Docker Engine API.

The "docker" command uses this package to communicate with the daemon. It can also
be used by your own Go applications to do anything the command-line interface does
- running containers, pulling images, managing swarms, etc.

For more information about the Engine API, see the documentation:
https://docs.docker.com/engine/reference/api/

Usage

You use the library by creating a client object and calling methods on it. The
client can be created either from environment variables with NewEnvClient, or
configured manually with NewClient.

For example, to list running containers (the equivalent of "docker ps"):

	package main

	import (
		"context"
		"fmt"

		"github.com/docker/docker/api/types"
		"github.com/docker/docker/client"
	)

	func main() {
		cli, err := client.NewEnvClient()
		if err != nil {
			panic(err)
		}

		containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
		if err != nil {
			panic(err)
		}

		for _, container := range containers {
			fmt.Printf("%s %s\n", container.ID[:10], container.Image)
		}
	}

*/
package client

import (
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/docker/docker/api"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/versions"
	"github.com/docker/go-connections/sockets"
	"github.com/docker/go-connections/tlsconfig"
	"golang.org/x/net/context"
)

// ErrRedirect is the error returned by checkRedirect when the request is non-GET.
var ErrRedirect = errors.New("unexpected redirect in response")

// Client is the API client that performs all operations
// against a docker server.
type Client struct {
	// scheme sets the scheme for the client
	scheme string
	// host holds the server address to connect to
	host string
	// proto holds the client protocol i.e. unix.
	proto string
	// addr holds the client address.
	addr string
	// basePath holds the path to prepend to the requests.
	basePath string
	// client used to send and receive http requests.
	client *http.Client
	// version of the server to talk to.
	version string
	// custom http headers configured by users.
	customHTTPHeaders map[string]string
	// manualOverride is set to true when the version was set by users.
	manualOverride bool
}

// CheckRedirect specifies the policy for dealing with redirect responses:
// If the request is non-GET return `ErrRedirect`. Otherwise use the last response.
//
// Go 1.8 changes behavior for HTTP redirects (specifically 301, 307, and 308) in the client .
// The Docker client (and by extension docker API client) can be made to to send a request
// like POST /containers//start where what would normally be in the name section of the URL is empty.
// This triggers an HTTP 301 from the daemon.
// In go 1.8 this 301 will be converted to a GET request, and ends up getting a 404 from the daemon.
// This behavior change manifests in the client in that before the 301 was not followed and
// the client did not generate an error, but now results in a message like Error response from daemon: page not found.
func CheckRedirect(req *http.Request, via []*http.Request) error {
	if via[0].Method == http.MethodGet {
		return http.ErrUseLastResponse
	}
	return ErrRedirect
}

// NewEnvClient initializes a new API client based on environment variables.
// Use DOCKER_HOST to set the url to the docker server.
// Use DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest.
// Use DOCKER_CERT_PATH to load the TLS certificates from.
// Use DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default.
func NewEnvClient() (*Client, error) {
	var client *http.Client
	if dockerCertPath := os.Getenv("DOCKER_CERT_PATH"); dockerCertPath != "" {
		options := tlsconfig.Options{
			CAFile:             filepath.Join(dockerCertPath, "ca.pem"),
			CertFile:           filepath.Join(dockerCertPath, "cert.pem"),
			KeyFile:            filepath.Join(dockerCertPath, "key.pem"),
			InsecureSkipVerify: os.Getenv("DOCKER_TLS_VERIFY") == "",
		}
		tlsc, err := tlsconfig.Client(options)
		if err != nil {
			return nil, err
		}

		client = &http.Client{
			Transport: &http.Transport{
				TLSClientConfig: tlsc,
			},
			CheckRedirect: CheckRedirect,
		}
	}

	host := os.Getenv("DOCKER_HOST")
	if host == "" {
		host = DefaultDockerHost
	}
	version := os.Getenv("DOCKER_API_VERSION")
	if version == "" {
		version = api.DefaultVersion
	}

	cli, err := NewClient(host, version, client, nil)
	if err != nil {
		return cli, err
	}
	if os.Getenv("DOCKER_API_VERSION") != "" {
		cli.manualOverride = true
	}
	return cli, nil
}

// NewClient initializes a new API client for the given host and API version.
// It uses the given http client as transport.
// It also initializes the custom http headers to add to each request.
//
// It won't send any version information if the version number is empty. It is
// highly recommended that you set a version or your client may break if the
// server is upgraded.
func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) {
	proto, addr, basePath, err := ParseHost(host)
	if err != nil {
		return nil, err
	}

	if client != nil {
		if _, ok := client.Transport.(http.RoundTripper); !ok {
			return nil, fmt.Errorf("unable to verify TLS configuration, invalid transport %v", client.Transport)
		}
	} else {
		transport := new(http.Transport)
		sockets.ConfigureTransport(transport, proto, addr)
		client = &http.Client{
			Transport:     transport,
			CheckRedirect: CheckRedirect,
		}
	}

	scheme := "http"
	tlsConfig := resolveTLSConfig(client.Transport)
	if tlsConfig != nil {
		// TODO(stevvooe): This isn't really the right way to write clients in Go.
		// `NewClient` should probably only take an `*http.Client` and work from there.
		// Unfortunately, the model of having a host-ish/url-thingy as the connection
		// string has us confusing protocol and transport layers. We continue doing
		// this to avoid breaking existing clients but this should be addressed.
		scheme = "https"
	}

	return &Client{
		scheme:            scheme,
		host:              host,
		proto:             proto,
		addr:              addr,
		basePath:          basePath,
		client:            client,
		version:           version,
		customHTTPHeaders: httpHeaders,
	}, nil
}

// Close ensures that transport.Client is closed
// especially needed while using NewClient with *http.Client = nil
// for example
// client.NewClient("unix:///var/run/docker.sock", nil, "v1.18", map[string]string{"User-Agent": "engine-api-cli-1.0"})
func (cli *Client) Close() error {

	if t, ok := cli.client.Transport.(*http.Transport); ok {
		t.CloseIdleConnections()
	}

	return nil
}

// getAPIPath returns the versioned request path to call the api.
// It appends the query parameters to the path if they are not empty.
func (cli *Client) getAPIPath(p string, query url.Values) string {
	var apiPath string
	if cli.version != "" {
		v := strings.TrimPrefix(cli.version, "v")
		apiPath = cli.basePath + "/v" + v + p
	} else {
		apiPath = cli.basePath + p
	}

	u := &url.URL{
		Path: apiPath,
	}
	if len(query) > 0 {
		u.RawQuery = query.Encode()
	}
	return u.String()
}

// ClientVersion returns the version string associated with this
// instance of the Client. Note that this value can be changed
// via the DOCKER_API_VERSION env var.
// This operation doesn't acquire a mutex.
func (cli *Client) ClientVersion() string {
	return cli.version
}

// NegotiateAPIVersion updates the version string associated with this
// instance of the Client to match the latest version the server supports
func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
	ping, _ := cli.Ping(ctx)
	cli.NegotiateAPIVersionPing(ping)
}

// NegotiateAPIVersionPing updates the version string associated with this
// instance of the Client to match the latest version the server supports
func (cli *Client) NegotiateAPIVersionPing(p types.Ping) {
	if cli.manualOverride {
		return
	}

	// try the latest version before versioning headers existed
	if p.APIVersion == "" {
		p.APIVersion = "1.24"
	}

	// if the client is not initialized with a version, start with the latest supported version
	if cli.version == "" {
		cli.version = api.DefaultVersion
	}

	// if server version is lower than the maximum version supported by the Client, downgrade
	if versions.LessThan(p.APIVersion, api.DefaultVersion) {
		cli.version = p.APIVersion
	}
}

// DaemonHost returns the host associated with this instance of the Client.
// This operation doesn't acquire a mutex.
func (cli *Client) DaemonHost() string {
	return cli.host
}

// ParseHost verifies that the given host strings is valid.
func ParseHost(host string) (string, string, string, error) {
	protoAddrParts := strings.SplitN(host, "://", 2)
	if len(protoAddrParts) == 1 {
		return "", "", "", fmt.Errorf("unable to parse docker host `%s`", host)
	}

	var basePath string
	proto, addr := protoAddrParts[0], protoAddrParts[1]
	if proto == "tcp" {
		parsed, err := url.Parse("tcp://" + addr)
		if err != nil {
			return "", "", "", err
		}
		addr = parsed.Host
		basePath = parsed.Path
	}
	return proto, addr, basePath, nil
}

// CustomHTTPHeaders returns the custom http headers associated with this
// instance of the Client. This operation doesn't acquire a mutex.
func (cli *Client) CustomHTTPHeaders() map[string]string {
	m := make(map[string]string)
	for k, v := range cli.customHTTPHeaders {
		m[k] = v
	}
	return m
}

// SetCustomHTTPHeaders updates the custom http headers associated with this
// instance of the Client. This operation doesn't acquire a mutex.
func (cli *Client) SetCustomHTTPHeaders(headers map[string]string) {
	cli.customHTTPHeaders = headers
}