Česky
Kamil Dudka

Share Library (C++)

File detail

Name:Downloadsharelib.h [Download]
Location: sharelib > src > sharelib
Size:39.5 KB
Last modification:2007-08-27 01:16

Source code

#ifndef SHARELIB_H
#define SHARELIB_H
 
/**
 * @file sharelib.h
 * @brief Share library interface
 * @author Kamil Dudka, xdudka00@gmail.com
 * @date 2007-05-15
 * @ingroup core
 * @ingroup stl
 */
 
#ifdef _WIN32
  // Export symbols to .dll while using MS C++ compiler
# define SHARE_EXPORT __declspec(dllexport)
#else
  // There is no need to declare export on Linux
# define SHARE_EXPORT
#endif
 
#include <new>            // Import std::bad_alloc exception
#include <memory>         // Import std::allocator
#include <iterator>       // Import std::random_access_iterator_tag
#include <functional>
#include <stddef.h>       // Import base set of system types (like size_t, ptrdiff_t, ...)
 
/**
 * @namespace Share
 * @brief Library namespace
 */
namespace Share {
  /**
   * @brief Compile-time assertion.
   */
  template <bool> struct ERROR_CTAssert_failed__Unexpected_sizeof_char;
  /**
   * @brief template specialization.
   */
  template <> struct ERROR_CTAssert_failed__Unexpected_sizeof_char<true> { };
 
  /**
   * @brief General exception carrying text message inside
   * @ingroup core
   */
  class ShareException: public std::bad_alloc {
    public:
      /**
       * Create exception object
       * @param message Text message describing exception
       */
      SHARE_EXPORT ShareException (const char *message);
 
      /**
       * Overloaded destructor from std::bad_alloc
       */
      SHARE_EXPORT ~ShareException () throw ();
 
      /**
       * Copy constructor needed to pass exception by value
       */
      SHARE_EXPORT ShareException (const ShareException &);
 
      /**
       * @return Return text message describing exception
       */
      SHARE_EXPORT const char* message() const;
 
    private:
      void operator= (const ShareException &);
      char *message_;
  };
 
  /**
   * Non-instantiable class.
   * @brief Class handling low-level pointer relocation
   * @attention Implementation expects @b sizeof(char) @b == @b 1 !
   * @ingroup core
   */
  class Relocator {
    public:
      typedef void* absolute_pointer;                 ///< @brief Absolute pointer type
      typedef const void* absolute_const_pointer;     ///< @brief Absolute const pointer type
      typedef size_t relative_pointer;                ///< @brief Relative pointer type
      typedef const size_t relative_const_pointer;    ///< @brief Relative const pointer type
 
      /**
       * Convert absolute address to relative.
       * @param abs Absolute address to convert.
       * @param base Base address for relocation.
       * @return Return relative address.
       */
      static relative_pointer absToRel (absolute_pointer abs, absolute_pointer base) {
        ERROR_CTAssert_failed__Unexpected_sizeof_char<sizeof(char)==1>();
        return
          (abs) ?
          static_cast<char *> (abs) - static_cast<char *> (base) :
          0;
       }
 
      /**
       * Overloaded method for const pointers.
       * @copydoc Relocator::absToRel(absolute_pointer,absolute_pointer)
       */
      static relative_const_pointer absToRel (absolute_const_pointer abs, absolute_pointer base) {
        return absToRel (const_cast<absolute_pointer>(abs), base);
      }
 
      /**
       * Convert relative address to absolute.
       * @param rel Relative address to convert.
       * @param base Base address for relocation.
       * @return Return absolute address.
       */
      static absolute_pointer relToAbs (relative_pointer rel, absolute_pointer base) {
        ERROR_CTAssert_failed__Unexpected_sizeof_char<sizeof(char)==1>();
        return
          (rel) ?
          static_cast<char *> (base) + rel :
          0;
      }
 
    private:
      /**
       * Private constructor to avoid class instantiation.
       */
      Relocator ();
  };
 
  /**
   * Struct defines type for reference and const reference.
   * This helps to avoid referencing void type in templates.
   * @brief Reference generic template
   * @ingroup core
   */
  template <class T> struct TReference {
    typedef T& reference;                       ///< @brief Reference type derived from template parameter
    typedef const T& const_reference;           ///< @brief Const reference type derived from template parameter
  };
 
  /**
   * @brief template specialization.
   */
  template <> struct TReference<void> {
    typedef void reference;                     ///< @brief Avoid referencing @c void
    typedef void const_reference;               ///< @brief Avoid referencing @c void
  };
 
  /**
   * @brief template specialization.
   */
  template <> struct TReference<const void> {
    typedef void reference;                     ///< @brief Avoid referencing @c void
    typedef void const_reference;               ///< @brief Avoid referencing @c void
  };
 
  /**
   * Struct defines type for @c void and @c const @c void.
   * This helps to carry constness of pointer trough generic template.
   * @brief Void pointer generic template
   * @ingroup core
   */
  template <class T> struct TVoidPointer {
    typedef void* void_pointer;                 ///< @brief @c void pointer type derived from template parameter
    typedef const void* const_void_pointer;     ///< @brief @c const @c void pointer type derived from template parameter
  };
 
  /**
   * @brief template specialization
   */
  template <class T> struct TVoidPointer<const T> {
    typedef const void* void_pointer;           ///< @copydoc TVoidPointer::void_pointer
    typedef const void* const_void_pointer;     ///< @copydoc TVoidPointer::const_void_pointer
  };
 
  class SharedSegment;          // Platform-independent shared segment representation
  class SegmentHeader;          // Object placed at begin of each shared segment
 
  /**
   * High-level interface to shared segment manipulation.
   * Design pattern  @b signleton
   * @brief @b Gateway to shared segment
   * @ingroup core
   */
  class ShareManager {
    public:
      typedef Relocator::relative_pointer relative_pointer;               ///< @copydoc Relocator::relative_pointer
      typedef Relocator::relative_const_pointer relative_const_pointer;   ///< @copydoc Relocator::relative_const_pointer
 
      /**
       * Method to access to singleton object.
       * @return Return pointer to singleton object.
       * @callergraph
       */
      SHARE_EXPORT static ShareManager* instance();
 
      /**
       * Destroy singleton object.
       * This method should be called automatically on application exit using std::atexit() function.
       */
      SHARE_EXPORT static void destroySelf();
 
      /**
       * Create and attach new segment.
       * @param name Name of new segment. Method throws ShareException if name is already used.
       * @param size How much memory will be allocated for data. Note that real size can be larger.
       * @brief @b Create @b and @b attach segment
       * @throw ShareException Generic exception thrown if creation process fails.
       */
      SHARE_EXPORT void createSegment (const char *name, size_t size) throw (ShareException);
 
      /**
       * Method throws ShareException if segment does not exist.
       * @param name Name of shared segment to attach to.
       * @brief Attach an already existing shared segment.
       * @throw ShareException Generic exception thrown if attaching fails.
       * @note Do not call this method after createSegment method call.
       */
      SHARE_EXPORT void attachSegment (const char *name) throw (ShareException);
 
      /**
       * All relative and absolute pointers to segment will be invalid after detach.
       * @brief Detach from shared segment.
       */
      SHARE_EXPORT void detachSegment () throw ();
 
      /**
       * Segment will be realy destroyed after references count fades to zero.
       * This means that calling prcess has to detach shared segment after this call to destroy it.
       * @brief Mark shared segment to be destroyed
       * @attention On Win32 platform is segment destoroyed automatically by OS, when there are no more references to segment.
       */
      SHARE_EXPORT void unlinkSegment () throw ();
 
      /**
       * @brief Name of attached shared segment
       * @return Return name of shared segment.
       */
      SHARE_EXPORT const char* name ();
 
      /**
       * Convert absolute address to relative.
       * @param abs Absolute address to convert.
       * @return Return relative address.
       */
      relative_pointer absToRel (void *abs) {
        return Relocator::absToRel (abs, atAddr_);
      }
 
      /**
       * @copydoc ShareManager::absToRel(void*)
       */
      relative_const_pointer absToRel (const void *abs) {
        return Relocator::absToRel (abs, atAddr_);
      }
 
      /**
       * @copydoc ShareManager::absToRel(void*)
       */
      template <class T> relative_pointer absToRel (T *abs) {
        typedef typename TVoidPointer<T>::void_pointer void_pointer;
        return absToRel(static_cast<void_pointer> (abs));
      }
 
      /**
       * Convert relative address to absolute.
       * @param rel Relative address to convert.
       * @return Return absolute address.
       */
      void* relToAbs (relative_pointer rel) {
        return Relocator::relToAbs (rel, atAddr_);
      }
 
      /**
       * Allocate piece of memory from shared segment or local heap.
       * @param size Requested size to allocate.
       * @return Return local pointer to allocated memory.
       * @throw ShareException Library-specific exception derived from std::bad_alloc
       */
      SHARE_EXPORT void* alloc (size_t size) throw (ShareException);
 
      /**
       * @copydoc alloc(size_t)
       * @param count Objects count to allocate.
       * @note Used for STL allocator.
       */
      void* alloc (size_t size, size_t count) throw (ShareException) {
        return this-> alloc (size * count);
      }
 
      /**
       * Free memory allocated by method alloc().
       * @param addr Address returned by alloc(). If this is different addres,
       * all attached application will crash terribly.
       */
      SHARE_EXPORT void free (void *addr) throw ();
 
      /**
       * @copydoc free(void*)
       * @note Used for STL allocator.
       */
      void free (void *addr, size_t) throw () {
        this-> free (addr);
      }
 
      /**
       * @return Return size of avalilable memory in shared segment
       */
      SHARE_EXPORT size_t available ();
 
    protected:
      /**
       * @ingroup sharectl
       * @brief Initialize ShareManager for debuging
       * @param segment Pointer to initialized segment object
       */
      SHARE_EXPORT void initDebugMode (SharedSegment *segment);
 
      /**
       * @ingroup sharectl
       * @brief Destroy current shared segment immediately
       */
      SHARE_EXPORT void destroySegment ();
 
      /**
       * @brief Bridge from sharectl to sharelib
       */
      friend class SharedSegmentWrapper;
 
    private:
      static ShareManager *instance_;                   ///< Pointer to singleton object
      SharedSegment *segment_;                          ///< Platform independent segment representation
      SegmentHeader *atAddr_;                           ///< attached addres of shared memory segment
 
    private:
      ShareManager ();
      ~ShareManager ();
      ShareManager (const ShareManager&);               ///< avoid object copying
      ShareManager& operator= (const ShareManager&);    ///< avoid object copying
  };
 
  /**
   * It overload operators @b new and @b delete for derived class.
   * @brief Shareable object @b base @b class
   * @ingroup core
   */
  class SharedObject {
  public:
    /**
     * Overloaded operator new
     * @throw ShareException Library-specific exception derived from std::bad_alloc
     */
    static void* operator new (size_t size) throw (ShareException)
    {
      return alloc(size);
    }
 
    /**
     * Overloaded operator new[]
     * @throw ShareException Library-specific exception derived from std::bad_alloc
     */
    static void* operator new[] (size_t size) throw (ShareException)
    {
      return alloc(size);
    }
 
    /**
     * Overloaded opeartor delete
     */
    static void operator delete (void *addr, size_t) throw ()
    {
      free (addr);
    }
 
    /**
     * Overloaded operator delete[]
     */
    static void operator delete[] (void *addr, size_t) throw()
    {
      free (addr);
    }
 
    /**
     * Allocate block of memory inside shared segment.
     * @param size Desired size of block to allocate.
     * @return Return local address of allocated block on success.
     * @throw ShareException Library-specific exception derived from std::bad_alloc
     */
    static void* alloc (size_t size) throw (ShareException)
    {
      return ShareManager::instance()-> alloc (size);
    }
 
    /**
      * @copydoc alloc(size_t)
      * @param count Objects count to allocate.
      * @note Used for STL allocator.
      */
    static void* alloc (size_t size, size_t count) throw (ShareException) {
      return alloc (size * count);
    }
 
    /**
     * Free block of memory previously allocated by alloc() method.
     * @param addr Address of block returned by alloc() method.
     * @attention All attached application may crash if this method is called with invalid address as parameter
     */
    static void free (void *addr) throw ()
    {
      ShareManager::instance()-> free (addr);
    }
 
  protected:
    SharedObject () { }           ///< This is base class only and could not be instantiated direct
    ~SharedObject () { }          ///< This is base class only and could not be deleted direct
  };
 
  /**
   * @brief @b Relocable @b pointer type.
   * @note Used for STL allocator.
   * @ingroup core
   */
  template <class T> class RelocPtr: public SharedObject {
    public:
      typedef T value_type;
      typedef size_t size_type;
      typedef ptrdiff_t difference_type;
      typedef T* pointer;
      typedef const T* const_pointer;
      typedef typename TVoidPointer<T>::void_pointer void_pointer;                  ///< @copydoc TVoidPointer::void_pointer
      typedef typename TVoidPointer<T>::const_void_pointer const_void_pointer;      ///< @copydoc TVoidPointer::const_void_pointer
      typedef typename TReference<T>::reference reference;                          ///< @copydoc TReference::reference
      typedef typename TReference<T>::const_reference const_reference;              ///< @copydoc TReference::const_reference
      typedef typename Relocator::relative_pointer relative_pointer;                ///< @copydoc Relocator::relative_pointer
      typedef typename Relocator::relative_const_pointer relative_const_pointer;    ///< @copydoc Relocator::relative_const_pointer
 
      /**
       * @brief STL iterator category
       */
      typedef std::random_access_iterator_tag iterator_category;
 
      /**
       * Construct null pointer
       */
      RelocPtr ():
        rel_ (0)
      {
      }
 
      /**
       * Initialize object using ShareManager singleton to obtain relative address.
       * @param abs Absolute pointer to save to object.
       */
      RelocPtr (void_pointer abs):
        rel_ (ShareManager::instance()-> absToRel (abs))
      {
      }
 
      /**
       * Initialize object using given base address.
       * @param abs Absolute pointer to save to object.
       * @param base Base address for relocation.
       */
      RelocPtr (void_pointer abs, void *base):
        rel_ (Relocator::absToRel (abs, base))
      {
      }
 
      /**
       * Copy constructor
       */
      RelocPtr (const RelocPtr &src):
        SharedObject(),
        rel_ (src.rel_)
      {
      }
 
      /**
       * Assignment
       */
      RelocPtr& operator= (const RelocPtr &src) {
        rel_= src.rel_;
        return *this;
      }
 
      /**
       * Assignment from absolute pointer
       */
      RelocPtr& operator= (void_pointer abs) {
        rel_= ShareManager::instance()-> absToRel (abs);
        return *this;
      }
 
      /**
       * Implicit conversion for accessing members
       * @return Return absolute pointer using ShareManager singleton to obtain absolute address.
       */
      pointer operator-> () const {
        return static_cast <T *> (ShareManager::instance()-> relToAbs (rel_));
      }
 
      /**
       * @brief Implicit conversion to native pointer.
       * @return Return absolute pointer using ShareManager singleton to obtain absolute address.
       * @callgraph
       */
      operator pointer () const {
        return operator-> ();
      }
 
      /**
       * Indexer
       * @param i index
       */
      reference operator[] (size_type i) {
        RelocPtr<T> tmp (*this);
        tmp+= i;
        return *(tmp.operator->());
      }
 
      /**
       * @brief @b Export pointer to number
       */
      relative_pointer toRel () const {
        return rel_;
      }
 
      /**
       * @brief @b Import pointer from number
       */
      static RelocPtr<T> fromRel (relative_pointer rel) {
        RelocPtr<T> tmp;
        tmp.rel_= rel;
        return tmp;
      }
 
      /**
       * Pre-increment
       */
      RelocPtr& operator++ () {
        rel_+= sizeof(T);
        return *this;
      }
      /**
       * Pre-decrement
       */
      RelocPtr& operator-- () {
        rel_-= sizeof(T);
        return *this;
      }
 
      /**
       * Overloaded operator +=
       */
      RelocPtr& operator+= (difference_type count) {
        rel_+= count * sizeof(T);
        return *this;
      }
 
      /**
       * Overloaded operator -=
       */
      RelocPtr& operator-= (difference_type count) {
        rel_-= count * sizeof(T);
        return *this;
      }
 
    private:
      relative_pointer rel_;   ///< Internal pointer representation
  };
 
  /**
   * @brief RelocPtr post-increment
   */
  template <class T> RelocPtr<T> operator++ (RelocPtr<T> &ptr, int)
  {
    RelocPtr<T> tmp(ptr);
    ++ptr;
    return tmp;
  }
 
  /**
   * @brief RelocPtr post-decrement
   */
  template <class T> RelocPtr<T> operator-- (RelocPtr<T> &ptr, int)
  {
    RelocPtr<T> tmp(ptr);
    --ptr;
    return tmp;
  }
 
  /**
   * @brief RelocPtr pointer difference
   */
  template <class T> ptrdiff_t operator- (RelocPtr<T> &a, RelocPtr<T> &b)
  {
    return (a.toRel()-b.toRel())/sizeof(T);
  }
 
  /**
   * @brief RelocPtr pointer arithmetic - go next N
   */
  template <class T> RelocPtr<T> operator+ (RelocPtr<T> ptr, ptrdiff_t diff)
  {
    ptr+= diff;
    return ptr;
  }
 
  /**
   * @brief RelocPtr pointer arithemtic - go back N
   */
  template <class T> RelocPtr<T> operator- (RelocPtr<T> ptr, ptrdiff_t diff)
  {
    ptr-= diff;
    return ptr;
  }
 
  /**
   * Equivalent to std::allocator using ShareManager to define storage.
   * @brief STL @b allocator
   * @bug This allocator is known not to work with usual implementations of STL.
   * @ingroup core
   */
  template <class T> class Allocator {
    public:
      typedef T value_type;
      typedef size_t size_type;
      typedef ptrdiff_t difference_type;
      typedef RelocPtr<T> pointer;                ///< @brief Using relocable pointer type
      typedef RelocPtr<const T> const_pointer;    ///< @brief Using relocable pointer type
      typedef T& reference;
      typedef const T& const_reference;
 
      /**
       * @note Not used for now
       */
      Allocator() throw() { }
 
      /**
       * @note Not used for now
       */
      ~Allocator() throw() { }
 
      /**
       * Copy constructor
       */
      template <class U> Allocator (const Allocator<U>&) throw() { }
 
      /**
       * Another type of allocator can be derived from existing one using this template.
       * @brief STL allocator type adapter template
       */
      template <class U>
      struct rebind {
        typedef Allocator<U> other;
      };
 
      /**
       * @param obj Reference to object
       * @return Return pointer to object
       */
      pointer address (reference obj) const {
        return &obj;
      }
 
      /**
       * @param obj Reference to const object
       * @return Return pointer to const object
       */
      const_pointer address (const_reference obj) const {
        return &obj;
      }
 
      /**
       * Allocate array of object
       * @param count Count of object to allocate
       * @return Return pointer to allocated array
       */
      pointer allocate (size_type count) {
        return pointer (static_cast<T*>(ShareManager::instance()-> alloc (sizeof(T), count)));
      }
 
      /**
       * Deallocate array of object
       * @param addr Pointer to array to deallocate
       * @param count Count of object to deallocate
       * @note Parameter @c count is not used by default implementation
       */
      void deallocate (pointer addr, size_type count) {
        ShareManager::instance()-> free (addr, count);
      }
 
      void construct (pointer p, const T& val) {
        ::new(p) T(val);
      }
 
      void destroy (pointer p) {
        p->~T();
      }
 
      size_type max_size () const throw() {
        return 
          (ShareManager::instance()-> available())
          /sizeof(T);
      }
  };
  template <class T1, class T2> bool operator== (const Allocator<T1>&, const Allocator<T2>&) throw() { return true; }
  template <class T1, class T2> bool operator!= (const Allocator<T1>&, const Allocator<T2>&) throw() { return false; }
 
  // Patch for Microsoft C++ compiler
#ifdef _WIN32
  template <> void Allocator<char>::destroy(Allocator<char>::pointer) { }
#endif // _WIN32
 
  /**
   * Light-weight implementation of STL std::vector
   * @brief STL vector
   * @ingroup stl
   * @param TItem Type of object stored in container.
   * @param TAllocator Type of allocator for container. Default is @b std::allocator. For sharing use Share::Allocator instead.
   */
  template <
    class TItem,
    class TAllocator = std::allocator<TItem>
    >
  class Vector {
      /**
       * Base capacity of vector to allocate. Given as exponent of 2^n.
       */
      static const size_t allocBase2Exp = 4;
 
      /**
       * Allocation down factor. Given as exponent of 2^n.
       */
      static const size_t allocDownFactor2Exp = 2;
 
      typedef typename TAllocator::size_type size_type;
      typedef typename TAllocator::difference_type difference_type;
      typedef typename TAllocator::pointer pointer;
      typedef typename TAllocator::const_pointer const_pointer;
      typedef typename TAllocator::reference reference;
      typedef typename TAllocator::const_reference const_reference;
 
    public:
      typedef pointer iterator;                   ///< STL vector iterator equivalent
      typedef const_pointer const_iterator;       ///< STL vector const_iterator equivalent
 
      /**
       * Construct empty vector
       */
      Vector():
        size_ (0),
        capacity_ (0),
        data_ (0)
      {
        lowLevelResize(0);
      }
 
      Vector (size_type size):
        size_ (0),
        capacity_ (0),
        data_ (0)
      {
        lowLevelResize(size);
        size_ = size;
      }
 
      /**
       * Copy constructor
       */
      Vector (const Vector &other):
        size_ (0),
        capacity_ (0),
        data_ (0)
      {
        operator= (other);
      }
 
      /**
       * assignment
       */
      Vector& operator= (const Vector &other) {
        size_type newSize = other.size();
        lowLevelResize(newSize);
        size_ = newSize;
        TItem *s1 = begin();
        const TItem *s2 = other.begin();
        const TItem *s2end = other.end();
        for (; s2!=s2end; s1++, s2++)
          alloc_.construct (s1, *s2);
 
        return *this;
      }
 
      ~Vector() {
        TItem *pEnd = end();
        for (TItem *i=begin(); i!=pEnd; i++)
          alloc_.destroy (i);
        alloc_.deallocate (data_, capacity_);
      }
 
      /**
       * Indexer
       * @param index index
       * @return Return reference to indexed object.
       */
      reference operator[] (size_type index) {
        return data_[index];
      }
 
      /**
       * @copydoc operator[](size_type)
       */
      const_reference operator[] (size_type index) const {
        return data_[index];
      }
 
      /**
       * equivalence
       */
      bool operator== (const Vector &other) const {
        const TItem *s1 = begin();
        const TItem *s2 = other.begin();
        for (; s1!=end() && s2!=other.end(); s1++, s2++)
          if (*s1 != *s2)
            return false;
        return
          s1 == end() &&
          s2 == other.end();
      }
 
      /**
       * non-equivalence
       */
      bool operator!= (const Vector &other) const {
        return !operator== (other);
      }
 
      /**
       * @return Return iterator pointing to begin of vector.
       */
      iterator begin() {
        return data_;
      }
 
      /**
       * @return Return iterator pointing behind the last element of vector.
       */
      iterator end() {
        return data_ + static_cast<difference_type> (size_);
      }
 
      /**
       * @copydoc begin()
       */
      const_iterator begin() const {
        return static_cast<const_iterator>(data_);
      }
 
      /**
       * @copydoc end()
       */
      const_iterator end() const {
        return static_cast<const_iterator>(data_ + static_cast<difference_type>(size_));
      }
 
      /**
       * Remove all items from vector.
       */
      void clear() {
        for (TItem *i=begin(); i!=end(); i++)
          alloc_.destroy (i);
        lowLevelResize(0);
        size_ = 0;
      }
 
      /**
       * @return Return true if vector is empty.
       */
      bool empty() const {
        return size_==0;
      }
 
      /**
       * Append item to end of vector.
       * @param item Item to append.
       * @note Vector capacity will be increased if needed.
       */
      void push_back (const_reference item) {
        lowLevelResize (size_ + 1, true);
        alloc_.construct (this + static_cast<difference_type>(size_), item);
        size_ ++;
      }
 
      /**
       * Remove last element of vector
       * @attention This method could not be called if vector is empty.
       */
      void pop_back() {
        lowLevelResize(size_ - 1, true);
        size_ --;
      }
 
      /**
       * @return Return size of vector
       */
      size_type size() const {
        return size_;
      }
 
      /**
       * Resize vector to desired size.
       * @param newSize Desired size of vector
       * @param val Value to assign to new object if newSize is greater then current size.
       */
      void resize (size_type newSize, const_reference val= TItem()) {
        lowLevelResize(newSize, true);
        for (; size_ < newSize; size_++)
          data_[size_] = val;
 
        size_ = newSize;
      }
 
    private:
      TAllocator alloc_;
      size_type size_;
      size_type capacity_;
      iterator data_;
 
      void lowLevelCopy (TItem *dest, const TItem *src, size_type count) {
        for (size_type i=0; i<count; i++, dest++, src++)
          *dest = *src;
      }
 
      void lowLevelResize (size_type newSize, bool bCopyContent=false) {
        static const size_type allocBaseSize = 1 << allocBase2Exp;
        if (newSize < allocBaseSize)
          newSize = allocBaseSize;
 
        if (
            newSize <= capacity_ &&
            newSize >= (capacity_ >> allocDownFactor2Exp)
            )
          return;
 
        for (capacity_= allocBaseSize; capacity_<newSize; capacity_<<=1);
        TItem *newBlock = alloc_.allocate (capacity_);
 
        if (data_) {
          if (bCopyContent)
            lowLevelCopy (newBlock, static_cast<const_iterator>(data_), size_);
 
          alloc_.deallocate (data_, size_);
        }
 
        data_ = newBlock;
      }
  };
 
  /**
   * Light-weight implementation of std::string
   * @brief STL string
   * @ingroup stl
   * @param TAllocator Type of allocator for container. Default is @b std::allocator. For sharing use Share::Allocator instead.
   */
  template <class TAllocator = std::allocator<char> >
  class String {
      typedef char TItem;
      typedef Vector<TItem, TAllocator> TContainer;
      typedef typename TAllocator::size_type size_type;
      typedef typename TAllocator::difference_type difference_type;
      typedef typename TAllocator::pointer pointer;
      typedef typename TAllocator::const_pointer const_pointer;
      typedef typename TAllocator::reference reference;
      typedef typename TAllocator::const_reference const_reference;
 
    public:
      typedef typename TContainer::iterator iterator;                   ///< STL string iterator equivalent
      typedef typename TContainer::const_iterator const_iterator;       ///< STL string const_iterator equivalent
 
      /**
       * Construct empty string
       */
      String():
        array_ (1, '\0')
      {
      }
 
      /**
       * Construct string of desired size
       * @param size Desired size of string.
       * @param val Character to fill string.
       */
      String (size_type size, const_reference val):
        array_ (size+1, val)
      {
        array_ [size] = '\0';
      }
 
      /**
       * Construct string from existing zero-ended string.
       * @param sz Pointer to zero-ended string.
       */
      String (const TItem *sz):
        array_ (szLength (sz)+1)
      {
        TItem *i = array_.begin();
        for (; *sz; sz++, i++)
          *i = *sz;
        *i = '\0';
      }
 
      /**
       * Copy constructor
       */
      String (const String &other):
        array_ (other.array_)
      {
      }
 
      /**
       * assignment
       */
      String& operator= (const TItem *sz) {
        array_.resize (szLength (sz)+1);
        TItem *i = array_.begin();
        for (; *sz; sz++, i++)
          *i = *sz;
        *i = '\0';
 
        return *this;
      }
 
      /**
       * assignment
       */
      String& operator= (const String &other) {
        array_ = other.array_;
        return *this;
      }
 
      /**
       * @param index Index of desired character
       * @return Return reference to character at desired position.
       */
      reference operator[] (size_type index) {
        return array_[index];
      }
 
      /**
       * @copydoc operator[](size_type)
       */
      const_reference operator[] (size_type index) const {
        return array_[index];
      }
 
      /**
       * @return Return iterator pointing to first character of string.
       */
      iterator begin() {
        return array_.begin();
      }
 
      /**
       * @return Return itertor pointing behind the last character of string.
       */
      iterator end() {
        return array_.end()-1;
      }
 
      /**
       * @copydoc begin()
       */
      const_iterator begin() const {
        return array_.begin();
      }
 
      /**
       * @copydoc end()
       */
      const_iterator end() const {
        return array_.end()-1;
      }
 
      /**
       * Lexical comparation with other string
       * @param other Other string to compare to
       * @return Return equivalen of strcmp (this, other)
       */
      int compare (const String &other) const {
        const TItem *s1 = begin();
        const TItem *s2 = other.begin();
        const TItem *s1end = end();
        const TItem *s2end = other.end();
        for (; s1!=s1end && s2!=s2end; s1++, s2++) {
          if (*s1 < *s2)
            return -1;
          else if (*s1 > *s2)
            return 1;
        }
        if (s1 != end())
          return 1;
        else if (s2 != other.end())
          return -1;
        else
          return 0;
      }
      bool operator== (const String<TAllocator> &other) const { return 0==compare (other); }
      bool operator!= (const String<TAllocator> &other) const { return 0!=compare (other); }
      bool operator<= (const String<TAllocator> &other) const { return 0>=compare (other); }
      bool operator>= (const String<TAllocator> &other) const { return 0<=compare (other); }
      bool operator<  (const String<TAllocator> &other) const { return 0> compare (other); }
      bool operator>  (const String<TAllocator> &other) const { return 0< compare (other); }
 
      /**
       * @note Not implemented yet.
       */
      void append (const TItem *);
 
      /**
       * Replace string with empty string.
       */
      void clear() {
        array_.clear();
      }
 
      /**
       * @return Return true if string is empty.
       */
      bool empty() const {
        return array_.empty();
      }
 
      /**
       * @return String length
       */
      size_type length() const {
        return array_.size();
      }
 
      /**
       * @return Return pointer to zero-ended string.
       */
      const TItem* c_str() const {
        return array_.begin();
      }
 
    private:
      TContainer array_;
      TAllocator alloc_;
 
    private:
      static size_type szLength (const TItem *sz) {
        int len = 0;
        while (*sz)
          len++, sz++;
        return len;
      }
  };
 
  /**
   * @brief Share::Vector string concatenation
   */
  template <class A> String<A> operator+ (String<A> s1, const String<A> &s2)
  {
    s1.append (s2);
    return s1;
  }
 
  /**
   * Light-weight implementation of std::pair
   * @brief STL pair
   * @ingroup stl
   */
  template <
    class TFirst,
    class TSecond
    >
  struct Pair {
    TFirst first;
    TSecond second;
  };
 
  /**
   * Light-weight implementation of std::map
   * @brief STL map
   * @ingroup stl
   * @param TKey Type of map key
   * @param TValue Type of map value
   * @param TAllocator Type of allocator for container. Default is @b std::allocator. For sharing use Share::Allocator instead.
   */
  template <
    class TKey,
    class TValue,
    class TAllocator = std::allocator< Pair<TKey, TValue> >
    >
  class Map {
      /**
       * Default hashTable size
       */
      static const size_t defaultHtSize = 1 << 12;
 
      typedef Pair<TKey, TValue> TData;
      typedef TData& TData_reference;
      typedef const TData* TData_const_pointer;
      typedef size_t size_type;
      typedef typename TAllocator::template rebind<Map>::other TMapAllocator;
      typedef typename TMapAllocator::const_pointer TMap_const_pointer;
 
    public:
      /**
       * @param htSize Size of hash table
       * @note This is not standardized constructor.
       */
      Map (size_type htSize= defaultHtSize):
        htSize_ (htSize)
      {
        htArray_ = pItemAlloc_.allocate (htSize_);
        for (size_type i=0; i<htSize_; i++)
          htArray_[i]=0;
      }
 
    private:
      struct Item;
      typedef typename TAllocator::template rebind<Item>::other TItemAllocator;
      typedef typename TItemAllocator::pointer TItem_pointer;
      typedef typename TItemAllocator::const_pointer TItem_const_pointer;
      typedef typename TItemAllocator::reference TItem_reference;
      struct Item {
        TData data;
        TItem_pointer next;
      };
      typedef typename TAllocator::template rebind<TItem_pointer>::other TPItemAllocator;
      typedef typename TPItemAllocator::pointer TPItem_pointer;
 
    public:
      /**
       * @brief STL map const_iterator equivalent
       * @ingroup stl
       */
      class const_iterator {
        public:
          const_iterator():
            hTable_ (0),
            hashIndex_ (0),
            item_ (0)
          {
          }
 
          /**
           * @return Return pointer to member.
           */
          TData_const_pointer operator->() {
            if (!item_)
              return 0;
            else
              return &(item_-> data);
          }
 
          /**
           * Implicit conversion to pointer.
           */
          operator TData_const_pointer() {
            return operator->();
          }
 
          /**
           * iterator - step forward operation
           */
          const_iterator& operator ++() {
            if (item_)
              item_ = item_-> next;
 
            if (!item_) {
              for (
                  hashIndex_++;
                  hashIndex_ < hTable_->htSize_ && hTable_->htArray_[hashIndex_] == 0;
                  hashIndex_ ++);
 
              if (hashIndex_ < hTable_->htSize_)
                item_ = hTable_-> htArray_ [hashIndex_];
            }
 
            return *this;
          }
 
          /**
           * @copydoc operator++()
           */
          const_iterator operator ++(int) {
            const_iterator tmp = *this;
            operator ++();
            return tmp;
          }
 
          /**
           * iterator comparatation
           */
          bool operator== (const const_iterator &other) {
            return
              hTable_ == other.hTable_ &&
              item_ == other.item_;
          }
 
          /**
           * iterator negative comparation
           */
          bool operator!= (const const_iterator &other) {
            return !operator== (other);
          }
 
        private:
          const_iterator (TMap_const_pointer ht, size_type hashIndex, TItem_const_pointer item):
            hTable_ (ht),
            hashIndex_ (hashIndex),
            item_ (item)
          {
          }
 
        private:
          TMap_const_pointer hTable_;
          size_type hashIndex_;
          TItem_const_pointer item_;
          friend class Map;
      };  // (class const_iterator)
 
      ~Map() {
        clear();
        pItemAlloc_.deallocate (htArray_, htSize_);
      }
 
      /**
       * Remove all items from map.
       */
      void clear() {
        TItem_pointer *ppCurrent = htArray_;
        for (size_type hashIndex=0; hashIndex<htSize_; hashIndex++, ppCurrent++) {
          Item *pCurrent = *ppCurrent;
          while (pCurrent) {
            Item *pNext = pCurrent->next;
            itemAlloc_.destroy (pCurrent);
            itemAlloc_.deallocate (pCurrent, 1);
            pCurrent = pNext;
          }
          *ppCurrent = 0;
        }
      }
 
      /**
       * @brief Look up for key in map by key.
       * @param key to look up
       * @return Return iterator of found item, end() if not found.
       */
      const_iterator find (const TKey &key) {
        size_type hashIndex = hashFunction (key);
        TItem_pointer pCurrent = htArray_ [hashIndex];
 
        while (pCurrent && pCurrent->data.first != key)
          pCurrent = pCurrent->next;
 
        return const_iterator (this, hashIndex, pCurrent);
      }
 
      /**
       * Look up for pair in map by key. New Pair is created if key is not found.
       * @brief indexer
       * @param key to look up
       * @return Return reference to value.
       */
      TValue& operator[] (const TKey &key) {
        size_type hashIndex = hashFunction (key);
        typedef typename TItemAllocator::difference_type TDiff;
        TItem_pointer *ppCurrent = htArray_ + static_cast<TDiff>(hashIndex);
 
        for (; *ppCurrent; ppCurrent = &((*ppCurrent)-> next)) {
          TData_reference current = (*ppCurrent)-> data;
          if (current.first == key)
            return current.second;
        }
 
        Item item = {
          { key, TValue() },
          0
        };
 
        *ppCurrent = itemAlloc_.allocate (1);
        itemAlloc_.construct (*ppCurrent, item);
 
        return (*ppCurrent)->data.second;
      }
 
      /**
       * @return Return iterator to begin of map.
       * @note There is no way to get map elements in specified order by const_iterator
       */
      const_iterator begin() const {
        const_iterator iter (this, 0, 0);
        iter++;
        return iter;
      }
 
      /**
       * @return Return iterator to element behind end of map.
       * @note There is no way to get map elements in specified order by const_iterator
       */
      const_iterator end() const {
        return const_iterator (this, 0, 0);
      }
 
    private:
      size_t htSize_;
      TPItem_pointer htArray_;
      TItemAllocator itemAlloc_;
      TPItemAllocator pItemAlloc_;
 
      /**
       * @note Implementation for string only
       */
      template<class T> size_t hashFunction (const T &key) {
        typedef typename T::const_iterator Iterator;
        Iterator i= key.begin();
        unsigned int h=0;
        for (; i != key.end(); i++) {
          unsigned char p = static_cast<unsigned char> (*i);
          h = 31*h + p;
        }
        return h % htSize_;
      }
  };
}
 
#endif // SHARELIB_H