#pragma once #include namespace ivy { #ifdef WIN32 #ifdef IVY_EXPORTS class _declspec(dllexport) string; template class _declspec(dllexport) list; template class _declspec(dllexport) vector; #else #pragma comment(lib,"Ivy.LIB" ) class _declspec(dllimport) string; template class _declspec(dllimport) list; template class _declspec(dllimport) vector; #endif #endif class string { public: static const size_t npos = size_t(-1); string(size_t len = 0) { ptr = allocBuffer( len ); }; string ( const string& s ) { ptr = 0; copy( s.ptr, s.size ); } string( const char * s, size_t len = npos ) { ptr = 0; if ( len == npos ) len = strlen(s) ; copy( s, len ); } ~string() { delete [] ptr; } size_t length() { return size; } bool empty() const { return size==0; } void copy( const char * s, size_t len ) { if ( ptr ) delete [] ptr; ptr = allocBuffer( len ); strncpy_s( ptr, len + 1, s, len ); } void erase(size_t start=0, size_t len = npos) { char *newptr; size_t real_len; size_t buf_size; real_len = len == npos ? size - start : len; if ( real_len > size ) real_len = size; buf_size = size - real_len; newptr = allocBuffer( buf_size ); strncpy_s( newptr, buf_size +1, ptr , start ); strncpy_s( &newptr[start], buf_size +1 - start, &ptr[start+real_len], size - start ); delete ptr; ptr = newptr; } void append( const char *s , size_t len = npos ) { insert ( size, s , len ); } void insert(size_t index, const char * s, size_t len = npos) { char *newptr; if ( len == npos ) len = strlen(s) ; size_t buf_len = size + len; newptr = allocBuffer( buf_len ); strncpy_s( newptr , buf_len +1, ptr, index ); strncpy_s( newptr+index, buf_len + 1 - index, s, len ) ; strncpy_s( newptr+index+len, buf_len + 1 - index -len, &ptr[index], size - (index+len) ) ; delete ptr; ptr = newptr; } string substr( size_t start, size_t len = npos ) { return string ( &ptr[start], len ); } size_t find_first_of( const char* strCharSet ) { char *fnd = strpbrk( ptr, strCharSet ); if ( fnd ) return (size_t)(fnd - ptr); else return npos; } size_t rfind( char c ) { char *fnd = strrchr( ptr, c); if ( fnd ) return (size_t)(fnd - ptr); else return npos; } // friend string operator + (const string& left, const char* right); // friend string operator + (const char* left, const string& right); friend string operator + (const string& left, const string& right) { string str( left.size + right.size ); str.append( left.ptr, left.size); str.append( right.ptr, right.size); return str; } void operator +=(string s) { append( s.ptr, s.size ); } void operator +=(const char* s) { append( s, strlen(s) ); } void operator +=(char c) { append( &c, 1);} string operator +(string s) const { string str ( ptr, size ); str.append( s.ptr, s.size ); return str; } string operator +(const char c) const { string str ( ptr, size ); str.append( &c, 1); return str; } string& operator=(const string& s) { copy(s.ptr,s.size); return *this; } string& operator=(const char* s) { copy(s,strlen(s)); return *this; } // Nondestructive typecast operator operator const char*() const { return ptr; } const char *c_str() const // remove this ugly thing { return ptr; } private: char *ptr; size_t size; // always allocate one extra character for '\0' termination char *allocBuffer(size_t len) { char *newptr; size = len; newptr = new char[len+1] ; newptr[len] = '\0'; return newptr; } }; template class list { protected: struct _Node; friend struct _Node; typedef struct _Node Node; typedef Node* NodePtr; struct _Node { NodePtr next, prev; T value; }; public: //friend class iterator; class iterator { public: iterator() {ptr = 0;} iterator(NodePtr p) {ptr = p;} T& operator*() const {return ptr->value; } // T* operator->() const // {return &(ptr->value); } // T* operator->() const // {return (&**this); } iterator& operator++() {ptr = ptr->next; return (*this); } iterator operator++(int) {iterator tmp = *this; ++*this; return (tmp); } iterator& operator--() {ptr = ptr.prev; return (*this); } iterator operator--(int) {iterator tmp = *this; --*this; return (tmp); } bool operator==(const iterator& p) const {return (ptr == p.ptr); } bool operator!=(const iterator& p) const {return (ptr != p.ptr); } NodePtr next() const {return ptr->next; }; NodePtr prev() const {return ptr->prev ; }; NodePtr node() const {return (ptr); } protected: NodePtr ptr; }; list() { head = new Node; head->next = head->prev = head; } ~list() { clear(); delete head; } bool empty() { return head->next == head ; } T& front() {return (*begin()); } const T& front() const {return (*begin()); } T& back() {return (*(--end())); } const T& back() const {return (*(--end())); } iterator erase(iterator p) { NodePtr s = (p++).node(); s->prev->next = s->next; s->next->prev = s->prev; delete s; return (p); } iterator insert(iterator p, const T& v =T()) { NodePtr s = p.node(); NodePtr newnode = new Node; newnode->value = v; newnode->prev = s->prev; newnode->next = s; s->prev->next = newnode; s->prev = newnode; return (iterator(newnode)); } void push_front(const T& v) {insert(begin(), v); } void pop_front() {erase(begin()); } void push_back(const T& v) {insert(end(), v); } void pop_back() {erase(--end()); } iterator erase(iterator first, iterator last) { while (first != last) erase(first++); return (first); } void clear() {erase(begin(), end()); } void remove( const T& data ) { iterator last = end(); for (iterator iter = begin(); iter != last; ) if (*iter == data) erase(iter++); else ++iter; } iterator begin() {return (iterator(head->next)); } iterator end() {return (iterator(head));} protected: NodePtr head; }; template class vector { public: vector ( ) { data = 0; len = 0; } size_t size() { return len; } void reserve( size_t index ) { if ( index >= len ) resize( index ); } void resize( size_t index ) { size_t i; T* newdata = new T[index]; for ( i = 0; i < len ; i ++ ) newdata[i] = data[i]; for ( i = len; i < index ; i ++ ) newdata[i] = 0; if ( data ) delete [] data; data = newdata; len = index; } // Accesses indexed component of vector T & operator [](size_t index ) { // reserve( index ); // TODO or NOT check range return data[index] ; } T & operator [](size_t index ) const { return data[index] ; } void push_back( const T& value ) { T* newdata = new T[len+1]; for ( size_t i = 0; i < len ; i ++ ) newdata[i] = data[i]; newdata[len++] = value; if ( data ) delete [] data; data = newdata; } void erase( int i ) { data[i] = 0; } void clear() { delete [] data; data = 0; len = 0; } private: T* data; size_t len; }; }