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

📄 flex_string_shell.h

📁 loki库的源代码。loki库是以模板技术和面向对象技术为基础的c++类库。
💻 H
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////////////////////////
// flex_string
// Copyright (c) 2001 by Andrei Alexandrescu
// Permission to use, copy, modify, distribute and sell this software for any
//     purpose is hereby granted without fee, provided that the above copyright
//     notice appear in all copies and that both that copyright notice and this
//     permission notice appear in supporting documentation.
// The author makes no representations about the
//     suitability of this software for any purpose. It is provided "as is"
//     without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////

#ifndef FLEX_STRING_SHELL_INC_
#define FLEX_STRING_SHELL_INC_

///////////////////////////////////////////////////////////////////////////////
// class template flex_string
// This file does not include any storage policy headers
///////////////////////////////////////////////////////////////////////////////

#include <memory>
#include <algorithm>
#include <functional>
#include <cassert>
#include <limits>
#include <stdexcept>
#include "flex_string_details.h"
#include <string>

// Forward declaration for default storage policy
template <typename E, class A> class AllocatorStringStorage;


template <class T> class mallocator
{
public:
    typedef T                 value_type;
    typedef value_type*       pointer;
    typedef const value_type* const_pointer;
    typedef value_type&       reference;
    typedef const value_type& const_reference;
    typedef std::size_t       size_type;
    //typedef unsigned int      size_type;
    //typedef std::ptrdiff_t    difference_type;
    typedef int               difference_type;

    template <class U> 
    struct rebind { typedef mallocator<U> other; };

    mallocator() {}
    mallocator(const mallocator&) {}
    //template <class U> 
    //mallocator(const mallocator<U>&) {}
    ~mallocator() {}

    pointer address(reference x) const { return &x; }
    const_pointer address(const_reference x) const 
    { 
        return x;
    }

    pointer allocate(size_type n, const_pointer = 0) 
    {
        using namespace std;
        void* p = malloc(n * sizeof(T));
        if (!p) throw bad_alloc();
        return static_cast<pointer>(p);
    }

    void deallocate(pointer p, size_type) 
    { 
        using namespace std;
        free(p); 
    }

    size_type max_size() const 
    { 
        return static_cast<size_type>(-1) / sizeof(T);
    }

    void construct(pointer p, const value_type& x) 
    { 
        new(p) value_type(x); 
    }

    void destroy(pointer p) 
    { 
        p->~value_type(); 
    }

private:
    void operator=(const mallocator&);
};

template<> class mallocator<void>
{
  typedef void        value_type;
  typedef void*       pointer;
  typedef const void* const_pointer;

  template <class U> 
  struct rebind { typedef mallocator<U> other; };
};

template <class T>
inline bool operator==(const mallocator<T>&, 
                       const mallocator<T>&) {
  return true;
}

template <class T>
inline bool operator!=(const mallocator<T>&, 
                       const mallocator<T>&) {
  return false;
}

template <class Allocator>
typename Allocator::pointer Reallocate(
    Allocator& alloc,
    typename Allocator::pointer p, 
    typename Allocator::size_type oldObjCount,
    typename Allocator::size_type newObjCount,
    void*)
{
    // @@@ not implemented
}

template <class Allocator>
typename Allocator::pointer Reallocate(
    Allocator& alloc,
    typename Allocator::pointer p, 
    typename Allocator::size_type oldObjCount,
    typename Allocator::size_type newObjCount,
    mallocator<void>*)
{
    // @@@ not implemented
}


////////////////////////////////////////////////////////////////////////////////
// class template flex_string
// a std::basic_string compatible implementation 
// Uses a Storage policy 
////////////////////////////////////////////////////////////////////////////////

template <typename E,
    class T = std::char_traits<E>,
    class A = std::allocator<E>,
    class Storage = AllocatorStringStorage<E, A> >
class flex_string : private Storage
{

    template <typename Exception>
    static void Enforce(bool condition, Exception*, const char* msg)
    { if (!condition) throw Exception(msg); }

    bool Sane() const
    {
        return
            begin() <= end() &&
            empty() == (size() == 0) &&
            empty() == (begin() == end()) &&
            size() <= max_size() &&
            capacity() <= max_size() &&
            size() <= capacity();
    }

    struct Invariant;
    friend struct Invariant;
    struct Invariant
    {
#ifndef NDEBUG
    	Invariant(const flex_string& s) : s_(s)
        {
            assert(s_.Sane());
        }
        ~Invariant()
        {
            assert(s_.Sane());
        }
    private:
        const flex_string& s_;
#else
    	Invariant(const flex_string&) {} 
#endif
	Invariant& operator=(const Invariant&);
    };
    
public:
    // types
    typedef T traits_type;
    typedef typename traits_type::char_type value_type;
    typedef A allocator_type;
    typedef typename A::size_type size_type;
    typedef typename A::difference_type difference_type;
    
    typedef typename Storage::reference reference;
    typedef typename A::const_reference const_reference;
    typedef typename A::pointer pointer;
    typedef typename A::const_pointer const_pointer;
    
    typedef typename Storage::iterator iterator;
    typedef typename Storage::const_iterator const_iterator;
    typedef std::reverse_iterator<iterator
#ifdef NO_ITERATOR_TRAITS
    , value_type
#endif
    > reverse_iterator;
    typedef std::reverse_iterator<const_iterator
#ifdef NO_ITERATOR_TRAITS
    , const value_type 
#endif
    > const_reverse_iterator;

    static const size_type npos;    // = size_type(-1)

private:
    static size_type Min(size_type lhs, size_type rhs)
    { return lhs < rhs ? lhs : rhs; }
	static void Procust(size_type& n, size_type nmax)
    { if (n > nmax) n = nmax; }
    
public:    
    // 21.3.1 construct/copy/destroy
    explicit flex_string(const A& a = A())
    : Storage(a) 
    {}
    
    flex_string(const flex_string& str)
    : Storage(str) 
    {}
    
    flex_string(const flex_string& str, size_type pos, 
        size_type n = npos, const A& a = A())
    : Storage(a) 
    {
        assign(str, pos, n);
    }
    
    flex_string(const value_type* s, const A& a = A())
    : Storage(s, traits_type::length(s), a)
    {}
    
    flex_string(const value_type* s, size_type n, const A& a = A())
    : Storage(s, n, a)
    {}
    
    flex_string(size_type n, value_type c, const A& a = A())
    : Storage(n, c, a)
    {}

    template <class InputIterator>
    flex_string(InputIterator begin, InputIterator end, const A& a = A())
    : Storage(a)
    {
        assign(begin, end);
    }

    ~flex_string()
    {}
    
    flex_string& operator=(const flex_string& str)
    {
        Storage& s = *this;
        s = str;
        return *this;
    }   
    
    flex_string& operator=(const value_type* s)
    {
        assign(s);
        return *this;
    }

    flex_string& operator=(value_type c)
    {
        assign(1, c);
        return *this;
    }
    
    // 21.3.2 iterators:
    iterator begin()
    { return Storage::begin(); }
    
    const_iterator begin() const
    { return Storage::begin(); }
    
    iterator end()
    { return Storage::end(); }
    
    const_iterator end() const
    { return Storage::end(); }

    reverse_iterator rbegin()
    { return reverse_iterator(end()); }
    
    const_reverse_iterator rbegin() const
    { return const_reverse_iterator(end()); }
    
    reverse_iterator rend()
    { return reverse_iterator(begin()); }
    
    const_reverse_iterator rend() const
    { return const_reverse_iterator(begin()); }
    
    // 21.3.3 capacity:
    size_type size() const
    { return Storage::size(); }
    
    size_type length() const
    { return size(); }
    
    size_type max_size() const
    { return Storage::max_size(); }

    void resize(size_type n, value_type c)
    { Storage::resize(n, c); }
    
    void resize(size_type n)
    { resize(n, value_type()); }
    
    size_type capacity() const
    { return Storage::capacity(); }
    
    void reserve(size_type res_arg = 0)
    {
        Enforce(res_arg <= max_size(), static_cast<std::length_error*>(0), "");
        Storage::reserve(res_arg);
    }
    
    void clear()
    { resize(0); } 
    
    bool empty() const
    { return size() == 0; }
    
    // 21.3.4 element access:
    const_reference operator[](size_type pos) const
    { return *(c_str() + pos); }
    
    reference operator[](size_type pos)
    { return *(begin() + pos); }

    const_reference at(size_type n) const
    {
        Enforce(n <= size(), static_cast<std::out_of_range*>(0), "");
        return (*this)[n];
    }
    
    reference at(size_type n)
    {
        Enforce(n < size(), static_cast<std::out_of_range*>(0), "");
        return (*this)[n];
    }
    
    // 21.3.5 modifiers:
    flex_string& operator+=(const flex_string& str)
    { return append(str); }
    
    flex_string& operator+=(const value_type* s)
    { return append(s); }

    flex_string& operator+=(const value_type c)
    { 
    	push_back(c);
        return *this;
    }
    
    flex_string& append(const flex_string& str)
    { return append(str.data(), str.length()); }
    
    flex_string& append(const flex_string& str, const size_type pos,
        size_type n)
    { 
        const size_type sz = str.size();
        Enforce(pos <= sz, static_cast<std::out_of_range*>(0), "");
    	Procust(n, sz - pos);
        return append(str.data() + pos, n); 
    }
    
    flex_string& append(const value_type* s, const size_type n)
    { 
    	Invariant checker(*this); 
        (void) checker; 
        static std::less_equal<const value_type*> le;
    	if (le(&*begin(), s) && le(s, &*end())) // aliasing
        {
        	const size_type offset = s - &*begin();
        	Storage::reserve(size() + n);
        	s = &*begin() + offset;
        }
        Storage::append(s, s + n); 
        return *this;
    }
    
    flex_string& append(const value_type* s)
    { return append(s, traits_type::length(s)); }
    
    flex_string& append(size_type n, value_type c)
    { 
        resize(size() + n, c);
        return *this;
    }
    
    template<class InputIterator>
    flex_string& append(InputIterator first, InputIterator last)
    {
    	insert(end(), first, last);
        return *this;
    }
    
    void push_back(const value_type c) // primitive
    { 
        const size_type cap = capacity();
        if (size() == cap)
        {
            reserve(cap << 1u);
        }
    	Storage::append(&c, &c + 1);
    }

    flex_string& assign(const flex_string& str)
    { 
        if (&str == this) return *this;
        return assign(str.data(), str.size());
    }
    
    flex_string& assign(const flex_string& str, const size_type pos,
        size_type n)
    { 
    	const size_type sz = str.size();

⌨️ 快捷键说明

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