/* * * This file and its contents are the property of The MathWorks, Inc. * * This file contains confidential proprietary information. * The reproduction, distribution, utilization or the communication * of this file or any part thereof is strictly prohibited. * Offenders will be held liable for the payment of damages. * * Copyright 1999-2012 The MathWorks, Inc. * */ #ifndef PST_STL_STRING #define PST_STL_STRING // new PST definition for string class // this interface contains all the // specifications described in the // C++ standard ISO #include <__polyspace__stdlib.h> #include #include <__polyspace__string.h> #include <__polyspace__char_traits.h> // needed for forward declarations #include <__polyspace__allocator.h> #ifdef PST_VISUAL #pragma pack(push, 8) /* pop back to previous value */ #endif /* forward declaration may be needed for */ namespace std { PST_TEMPLATE_DECL_DEF_FOR_BASIC_STRING_CLASSES(charT, traits, char_traits) class basic_string ; typedef basic_string > string; typedef basic_string > wstring; } // get // get // get #include <__polyspace__container.h> #ifdef PST_VISUAL #pragma pack(pop) /* pop back to previous value */ #endif #include // macros undefined at the end of file // norm realy unclear about max_size() => should be < npos // remarks : // max_size() should be representable as signed unless s[max_size()] would overflow // 65535 seems to be resaonably enough ... #define STRING_MAX_SIZE 65535u #define OUT_OF_RANGE(cond) assert (!(cond)) #define VALID_RANGE(f,l) assert ((f!=0 && l!=0) && f<=l) #define VALID_ITERATOR_ON_THIS(i) assert( i!=0 && (begin()<=i) && (i<=end())) // LENGTH_ERROR macros: // check if we can build a string whose size is s // TC1 say that we must compare with max_size() #define VALID_SIZE(s) assert((s) <= STRING_MAX_SIZE && (s) >= 0) //check if we can add n element when current size is s // if n==STRING_MAX_SIZE+1 assert is red ! // n should be a local variable #define VALID_SIZE_MAX(s,n) assert( ((n) <= STRING_MAX_SIZE) && ((s) <= (STRING_MAX_SIZE - (n)))) //check if we can remove n element when current size is s #define VALID_SIZE_MIN(s,n) assert((s) >= (n)) #define PST_MIN(a,b) (((a) < (b))?(a):(b)) #define NON_NULL(p) assert((p) != 0) #define RETURN_ITERATOR(iterator, pos) \ charT* dat = (_size>0) ? new charT[_size] : new charT(); \ return (iterator)(dat + pos) ; #define RETURN_ANY_ITERATOR(iterator) \ volatile size_type r = (size_type)0; size_type pos = r ; assert( r<=_size ) ; \ charT* dat = (_size>0) ? new charT[_size] : new charT(); \ return (iterator)(dat + pos) ; #ifdef PST_VISUAL #pragma pack(push, 8) /* push default value */ #endif namespace std { template struct __PST_TEST_STRING { }; template struct __PST_TEST_STRING { static size_t _get_size(InputIterator first, InputIterator last) { size_t sz = 0 ; //VALID_RANGE(first, last); // Valid range macro require < to be defined on InputIterator, thats not allways __ps_true // if range is not valid, we should get a NTL above for (InputIterator tmp = first; tmp != last; ++tmp,sz++) ; VALID_SIZE(sz); return sz; } } ; // specialization for pointer template struct __PST_TEST_STRING { static size_t _get_size(Pointed* first, Pointed* last) { size_t sz; VALID_RANGE(first, last); sz = last - first; VALID_SIZE(sz); return sz; } } ; template struct __PST_TEST_STRING { static size_t _get_size(InputIterator first, InputIterator last) { size_t ret = static_cast(first) ; VALID_SIZE(ret) ; return ret; } } ; // helper : #define PST_TEMPLATE_GET_SIZE(InputIterator, first, last) \ __PST_TEST_STRING::is_int_type>::_get_size(first, last); PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) class basic_string { public: //types typedef size_t size_type; typedef traits traits_type; typedef __ps_typename traits::char_type value_type; typedef ptrdiff_t difference_type; typedef PST_ALLOCATOR allocator_type; typedef charT& reference; typedef const charT& const_reference; typedef charT* pointer; typedef const charT* const_pointer; #if 0 /* The iterators should be defined this way. Anyway, it would lead to some precision losses. */ typedef __pst__normal_iterator iterator; typedef __pst__normal_iterator const_iterator; #else typedef pointer iterator; typedef const_pointer const_iterator; #endif typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; private: // the length of the string size_type _size; public: // must not be initialized inside of the class. static const size_type npos; // Constructors - Destructors // template // basic_string::basic_string() // constructs an object of class basic_string. // It is the default constructor. // Postconditions : size() == 0 and capacity() is // an unspecified positive value; we need to compute // the capacity of the string only for // the access function capacity() __ps_explicit basic_string(PST_ALLOCATOR_DECL1){ _size = 0 ; } // Constructs an object of class basic_string // whose length is determined by choosing // the smallest value between n and str.size(). basic_string(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str, size_type pos=0, size_type n=npos PST_ALLOCATOR_DECL_LAST) { size_type s = str._size; OUT_OF_RANGE(pos > s); size_type min = PST_MIN(n, (s - pos)); VALID_SIZE(min); _size = min; } // Constructs an object of class basic_string // whose size is initialized with n. // Pre : s must not be a null pointer basic_string(const charT* s, size_type n PST_ALLOCATOR_DECL_LAST){ NON_NULL(s); VALID_SIZE(n); _size = n; } // Constructs an object of class basic_string // whose initial size is determined by the length // of the parameter s. // Pre : s must not be a null pointer basic_string(const charT* s PST_ALLOCATOR_DECL_LAST){ NON_NULL(s); const charT *ptr = s; size_type i = 0; while(*ptr!=0){ i++;ptr++;} VALID_SIZE(i); _size = i; } // Constructs an object of class basic_string // whose size is initialized with n. basic_string(size_type n, charT c PST_ALLOCATOR_DECL_LAST){ VALID_SIZE(n); _size = n; } // Constructor with Iterators : // Pre : [first, last) is a valid range // This constructor cannot be specialized // inside the class, otherwise it would force // to specialize the whole class too. template basic_string(InputIterator first, InputIterator last PST_ALLOCATOR_DECL_LAST) { // The right version of the method _get_size // will be instantiated, according to whether // __polyspace_is_int_type::is_int_type is __ps_true or __ps_false. _size = PST_TEMPLATE_GET_SIZE(InputIterator, first, last) ; } // destructor : as it is static analysis, // no need to call functions such as free or // delete. But the size is reset to 0, so as // to specify that the string no longer has any // elements (as it is destroyed). ~basic_string(){ } // As we don't use the template argument allocator, // we don't matter about its type allocator_type get_allocator() const { PST_RETURN_STAT_FOR_GET_ALLOCATOR ; } // *this is resized to str.size(); PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& operator=(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str){ _size = str._size; return *this; } // To compute the new size of the // string controlled by *this, we // need to count the number of // char-like objects contained in // s : it necessarily ends with // a null pointer (otherwise it // would be an infinite string !). PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& operator=(const charT* s){ NON_NULL(s); const charT *ptr = s; size_type i = 0; while(*ptr!=0){ i++; ptr++; } VALID_SIZE(i); _size = i; return *this; } // a string made of one character is // assigned to the string controlled // by *this : the size is set to 1. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& operator=(charT c){ _size = 1; return *this; } // iterators iterator begin() { RETURN_ITERATOR(iterator, 0) ; } // Idem as above, but the iterator // is const. const_iterator begin() const { RETURN_ITERATOR(const_iterator, 0) ; } // Idem as begin(). iterator end() { RETURN_ITERATOR(iterator, _size); } const_iterator end() const { RETURN_ITERATOR(const_iterator, _size); } // Idem as begin(). reverse_iterator rbegin() { RETURN_ITERATOR(reverse_iterator, 0) ; } // Idem as begin() const. const_reverse_iterator rbegin() const{ RETURN_ITERATOR(const_reverse_iterator, 0) ; } // Idem as end(). reverse_iterator rend() { RETURN_ITERATOR(reverse_iterator, _size) ; } // Idem as end() const. const_reverse_iterator rend() const { RETURN_ITERATOR(const_reverse_iterator, _size) ; } // capacity // The access function to the // size of the string controlled // by *this. size_type size() const { return _size; } // Idem as size(). size_type length() const { return _size; } // Returns the maximum size of the // string controlled by *this : // We chose the greatest unsigned // integer value. size_type max_size() const { return STRING_MAX_SIZE; } // Reset the length of // the string controlled by *this // to n. void resize(size_type n, charT c='\0'){ VALID_SIZE(n) ; _size = n; } // Returns the size of the allocated storage // in the string. The only condition on // this variable is that it must be >= size() size_type capacity() const { volatile size_type delta = (size_type)0; return (_size + delta); } // This method modifies the capacity of the string. // The capacity cannot be greater than the maximal size. // size() remains the same. void reserve(size_type res_arg = 0) { VALID_SIZE(res_arg) ; } // This method is equivalent to erase( begin(), end()): // it removes all the elements of the string // controlled by *this. // So the size of the string becomes null. void clear() { _size = 0; } // Says if the string is empty. // To avoid link between methods of // the class, it returns an indifferent // value. __ps_bool empty() const { return (_size == 0); } // element access // This function returns the // element contained at position pos // in the string. // Pre : pos <= size() const_reference operator[](size_type pos) const { OUT_OF_RANGE( pos > _size ); if (pos==_size) return *(new charT()) ; volatile charT c = '\0'; charT* dat = new charT[pos+1]; dat[pos] = c; // it is a strange idea to construct an array and to initialize only one element ... return (const_reference)(dat[pos]); } // This function returns the element // at position pos in the string, only if // pos < size(). Otherwise, the behavior // is undefined. reference operator[](size_type pos){ OUT_OF_RANGE( pos >= _size ); // if pos = size() the return is undefined for non-const version 21.3.4 - 1 volatile charT c = '\0'; charT* dat = new charT[pos+1]; dat[pos] = c; return (reference)(dat[pos]); } // This function returns the element // of the string at position n, n // must be < size(). const_reference at(size_type n) const { OUT_OF_RANGE(n >= _size) ; volatile charT c = '\0'; charT* dat = new charT[n+1]; dat[n] = c; return (dat[n]); } // This function returns the element // at position n in the string, with // the condition n < size(). reference at (size_type n) { OUT_OF_RANGE(n >= _size); volatile charT c = '\0'; charT* dat = new charT[n+1]; dat[n] = c; return (reference)dat[n]; } // modifiers // This function appends rhs // to the string controlled by *this. // So the current size is increased // with rhs.size(). PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& operator+= (const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs){ size_type s = rhs._size; VALID_SIZE_MAX(_size, s); _size += s; return *this; } // The string s is appended to // the string controlled by *this. // The current size is increased with // the length of s. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& operator+= (const charT* s) { NON_NULL(s); const charT *ptr = s; size_type i = 0; while(*ptr!=0){ i++;ptr++;} VALID_SIZE_MAX(_size, i); _size += i; return *this; } // This function append the character // c to the string controlled by *this. // The current size is increased of 1. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& operator+=(charT c) { VALID_SIZE_MAX(_size,1); _size++; return *this; } // This method appends the string str // to the string controlled by *this. // The current size is increased with // str.size(). PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& append(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str){ size_type t = str._size; VALID_SIZE_MAX(_size,t); _size += t; return *this; } // This function appends the remaining // elements of the string str, from position // pos, to the string controlled by *this, // with the condition that pos <= str.size(). // The current size is increased with // the smallest of n and str.size() - pos. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& append (const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str, size_type pos, size_type n){ size_type str_size = str._size; OUT_OF_RANGE(pos > str_size); size_type min = PST_MIN((str_size - pos), n); VALID_SIZE_MAX(_size, min); _size += min; return *this; } // This function appends the string s // to the string controlled by *this. // The current size is increased by // the length of s. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& append (const charT* s, size_type n){ NON_NULL(s); VALID_SIZE_MAX(_size, n); _size += n; return *this; } // This function appends the string s // to the string controlled by *this. // The current size is increased by // the length of s. // To compute the length of s, // One way is to count the // number of non-null char-like objects // contained in s. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& append (const charT* s){ NON_NULL(s); const charT *ptr = s; size_type i = 0; while(*ptr!=0){ i++;ptr++;} VALID_SIZE_MAX(_size, i); _size += i; return *this; } // This function appends the character c // to the string controlled by *this. // The current size is increased by 1. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& append (size_type n, charT c){ VALID_SIZE_MAX(_size,n); _size += n; return *this; } // This method appends the string // delimited by first and last // to the string controlled by *this. template PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& append (InputIterator first, InputIterator last) { PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits) str_to_append = basic_string(first, last); size_type tmp = PST_TEMPLATE_GET_SIZE(InputIterator, first, last) VALID_SIZE_MAX(_size, tmp) ; _size += tmp ; return *this; } void push_back(const charT) { VALID_SIZE_MAX(_size,1); ++_size; } // This method assigns str to // the string controlled by *this. // The current size is set to str.size(). PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& assign(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str){ _size = str._size; return *this; } // This method assigns the // string begining at position // pos in str to the string // controlled by *this. // The current size of the string // is set to the smallest of n and // str.size() - pos (which has to be > 0). PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& assign (const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str, size_type pos, size_type n){ int str_size = str._size - pos; OUT_OF_RANGE(str_size < 0); size_type min = PST_MIN(str_size, n); VALID_SIZE(min); _size = min; return *this; } // This method assigns s to the // string controlled by *this. // The current size is set to the // length of s, which must be n. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& assign (const charT* s, size_type n){ NON_NULL(s); VALID_SIZE(n); _size = n; return *this; } // This method assigns s to the // string controlled by *this. // The current size is set to the // length of s. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& assign (const charT* s){ NON_NULL(s); const charT *ptr = s; size_type i = 0; while(*ptr!=0){ i++; ptr++; } VALID_SIZE(i); _size = i; return *this; } // This method assigns the character c // to the string controlled by *this, // the initial size() is set to n. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& assign (size_type n, charT c) { VALID_SIZE(n); _size = n; return *this; } // This method assigns the string // delimited by first and last to // to the string controlled by *this. template PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& assign(InputIterator first, InputIterator last) { PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits) str_to_assign = basic_string(first, last); _size = __PST_TEST_STRING::is_int_type>::_get_size(first, last); return *this; } // This method inserts a str into // the string controlled by *this. // The current size is increased // by str.size(). PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& insert(size_type pos1, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str){ OUT_OF_RANGE(pos1 > _size); size_type tmp = str._size ; VALID_SIZE_MAX(_size, tmp) ; _size += tmp; return *this; } // This method inserts a string // of length rlen at position pos2 // in the string controlled by *this. // rlen is determined by the smallest of // n and str.size() - pos2. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& insert (size_type pos1, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str, size_type pos2, size_type n = npos){ size_type str_size = str._size; OUT_OF_RANGE(pos1 > _size || pos2 > str_size); size_type rlen = PST_MIN(str_size - pos2, n); VALID_SIZE_MAX(_size, rlen) ; _size += rlen; return *this; } // This method inserts the string s // at position pos of the string // controlled by *this. We must have // pos <= size(). // The current size is increased by // the length of s, which must be n. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& insert (size_type pos, const charT* s, size_type n){ NON_NULL(s); OUT_OF_RANGE(pos > _size); VALID_SIZE_MAX(_size, n) ; _size += n; return *this; } // Idem as above, except that the // length of s is not given and then // must be computed. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& insert (size_type pos, const charT* s) { NON_NULL(s); OUT_OF_RANGE(pos > _size); const charT *ptr = s; size_type sz = 0; while(*ptr!=0){ sz++; ptr++; } VALID_SIZE_MAX(_size, sz) ; _size += sz; return *this; } // This method inserts the character c n times // in the string controlled by *this, at position pos. // pos must be smaller than _size. // The current size is increased by n. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& insert (size_type pos, size_type n, charT c){ OUT_OF_RANGE(pos > _size); VALID_SIZE_MAX(_size, n) ; _size += n; return *this; } #ifdef PST_VISUAL // this method inserts one character // in the string // the size is increased by 1. iterator insert(iterator p) { return insert(p, '\0') ; } #endif /* PST_VISUAL */ // this method inserts one character // in the string // the size is increased by 1. iterator insert(iterator p, charT c) { NON_NULL(p); VALID_ITERATOR_ON_THIS(p) ; VALID_SIZE_MAX(_size, 1); _size++; RETURN_ANY_ITERATOR(iterator) ; } // This method inserts the character // c n times in the string controlled // by *this. The size is increased by // n. void insert(iterator p, size_type n, charT c) { VALID_ITERATOR_ON_THIS(p) ; VALID_SIZE_MAX(_size, n); _size += n; } // This method inserts the string // contained in [first, last) at // position pointed to by p in the // string controlled by *this. template void insert(iterator p, InputIterator first, InputIterator last) { VALID_ITERATOR_ON_THIS(p) ; size_type tmp = PST_TEMPLATE_GET_SIZE(InputIterator, first, last) ; VALID_SIZE_MAX(_size, tmp) ; _size += tmp ; } // This method erases characters from // position pos (pos must be smaller than size()). // The current size is set to the smaller // of n and size() - pos. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& erase (size_type pos = 0, size_type n = npos){ OUT_OF_RANGE(_size < pos); size_type min = PST_MIN(_size-pos, n); VALID_SIZE_MIN(_size, min); _size -= min; return *this; } // This method removes the // character referred to by p. // The current size is decreased // by one. // The pre-condition "position is a // valid iterator on *this" is checked // by assertion on size(). iterator erase(iterator position) { VALID_ITERATOR_ON_THIS(position) ; VALID_SIZE_MIN(_size,1); _size--; RETURN_ANY_ITERATOR(iterator) ; } // To compute the new size of // the string controlled by *this, // we must assume that pointer f is // prior to pointer l. iterator erase(iterator f, iterator l) { size_type n=0; VALID_RANGE(f,l); while (f!=l) { f++; n++; } VALID_SIZE_MIN(_size, n); _size -= n; RETURN_ANY_ITERATOR(iterator) ; } // This method replaces from position pos1 // *this by str. // Pre : (pos1 <= size()) PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& replace (size_type pos, size_type n1, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str) { size_type rlen = str._size; OUT_OF_RANGE(pos > _size); size_type xlen = PST_MIN(n1, _size - pos) ; VALID_SIZE_MAX(_size-xlen, rlen); _size -= xlen ; // we are sure thats xlen < _size, we prevent overflow _size += rlen ; return *this; } // Precondition : pos1 <= size() && pos2 <= str.size() // The effective length xlen of the string to be removed // is the smallest of n1 and size() - pos1. // The effective length rlen of the string to be inserted // is the smallest of n2 and str.size(). PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& replace (size_type pos1, size_type n1, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str, size_type pos2, size_type n2) { size_type t = str._size; size_type rlen, xlen; OUT_OF_RANGE(pos1 > _size || pos2 > t); rlen = PST_MIN(n2,t - pos2) ; xlen = PST_MIN(n1,_size - pos1) ; VALID_SIZE_MAX(_size-xlen, rlen) ; _size -= xlen ; // we are sure thats xlen < _size _size += rlen ; return *this; } // This method replaces // the string controlled by *this with s, // from position pos. // Pre : pos <= size(). PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& replace (size_type pos, size_type n1, const charT* s, size_type n2) { NON_NULL(s); OUT_OF_RANGE(pos > _size); size_type xlen = PST_MIN(n1, _size - pos) ; VALID_SIZE_MAX(_size-xlen, n2); _size -= xlen ; // we are sure thats xlen < _size, we prevent overflow _size += n2 ; return *this; } // This method replaces // the string controlled by *this // from position pos (pos <= size()) // by s. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& replace (size_type pos, size_type n1, const charT* s) { NON_NULL(s); OUT_OF_RANGE(pos > _size); size_type xlen = PST_MIN(n1, _size - pos) ; const charT *ptr = s ; size_type sz = 0; while(*ptr!=0){ sz++; ptr++; } VALID_SIZE_MAX(_size-xlen, sz) ; _size -= xlen ; // we are sure thats xlen < _size, we prevent overflow _size += sz ; return *this; } // This method replaces at most n2 // characters in the string // controlled by *this. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& replace (size_type pos, size_type n1, size_type n2, charT c) { OUT_OF_RANGE(pos > _size); size_type xlen = PST_MIN(n1 , _size - pos) ; VALID_SIZE_MAX(_size-xlen, n2); _size -= xlen ; _size += n2 ; return *this; } // The norm specifies that // this method replaces the string controlled by // *this with a string of length // size() - (i2 - i1) + str.size(). // Pre : [i1,i2) is a valid range in // the string controlled by *this. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& replace (iterator i1, iterator i2, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str) { VALID_RANGE(i1, i2); size_type xlen = i2-i1 ; size_type rlen = str._size ; VALID_SIZE_MIN(_size, xlen) ; // we can remove xlen elements ... VALID_SIZE_MAX(_size-xlen, rlen) ; //we can add after that rlen elements _size -= xlen ; // we are sure thats xlen < _size, we prevent overflow _size += rlen ; return *this; } PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& replace (iterator i1, iterator i2, const charT* s, size_type n){ NON_NULL(s); VALID_RANGE(i1, i2); size_type xlen = i2-i1 ; VALID_SIZE_MIN(_size, xlen) ; // we can remove xlen elements ... VALID_SIZE_MAX(_size-xlen, n) ; //we can add after that n elements _size -= xlen ; // we are sure thats xlen < _size, we prevent overflow _size += n ; return *this; } PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& replace (iterator i1, iterator i2, const charT* s) { NON_NULL(s); const charT *ptr = s; size_type rlen = 0; while(*ptr!=0){ rlen++;ptr++;} VALID_RANGE(i1, i2); size_type xlen = i2-i1 ; VALID_SIZE_MIN(_size, xlen) ; // we can remove xlen elements ... VALID_SIZE_MAX(_size-xlen, rlen) ; //we can add after that rlen elements _size -= xlen ; // we are sure thats xlen < _size, we prevent overflow _size += rlen ; return *this; } // This method replaces the range [i1; i2[ of the string by c. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& replace (iterator i1, iterator i2, size_type n, charT c) { VALID_RANGE(i1, i2); size_type xlen = i2-i1 ; VALID_SIZE_MIN(_size, xlen) ; // we can remove xlen elements ... VALID_SIZE_MAX(_size-xlen, n) ; //we can add after that n elements _size -= xlen ; // we are sure thats xlen < _size, we prevent overflow _size += n ; return *this; } // This method replaces the string controlled // *this with the string contained in [i3; i4) // Pre : [i1; i2) and [i3; i4) must be valid ranges. template PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& replace (iterator i1, iterator i2, InputIterator i3, InputIterator i4) { VALID_RANGE(i1, i2); size_type xlen = i2-i1 ; size_type rlen = PST_TEMPLATE_GET_SIZE(InputIterator, i3, i4) VALID_SIZE_MIN(_size, xlen) ; // we can remove xlen elements ... VALID_SIZE_MAX(_size-xlen, rlen) ; //we can add after that rlen elements _size -= xlen ; // we are sure thats xlen < _size, we prevent overflow _size += rlen ; return *this; } // This method copies the string // controlled by *this into s. // it returns the size of // the string copied. // s shall designate an array at least of // rlen elements, with rlen defined by the // smallest of n and size() - pos. // We matter only about the size. // What should be copied into s // is not taken into account for the // moment size_type copy (charT* s, size_type n, size_type pos = 0) const { NON_NULL(s); size_type rlen = 0; OUT_OF_RANGE(pos > _size); rlen = PST_MIN(n, _size - pos) ; size_type j=0; if (_size != 0) { for (; j < rlen; j++) { volatile charT c = '\0'; charT b = c; assert(b!='\0'); s[j] = b; } } return rlen; } // Swaps s.data() with the string controlled // by *this. The current size is set to s.size(). // s.size() is set to size(). void swap (PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits) &s){ size_type size_tmp = s._size; s._size = _size; _size = size_tmp; } // string operations // Returns the string controlled by *this. // We chose to fill the string with indifferent // values, and to matter only about the size. const charT* data () const { if (_size == 0) return new charT; volatile charT c = '\0'; charT* _dat = new charT[_size]; for (size_type j=0;j< _size ;j++) { _dat[j] = c; } return _dat; } // Idem as data(), but the string ends // with the character '\0'. const charT* c_str () const { charT* _dat; if (_size == 0) { _dat = new charT[1]; _dat[0] = '\0'; } else { size_type j; volatile charT c = '\0'; _dat = new charT[_size + 1]; for (j = 0; j < _size; j++) { _dat[j] = c; } _dat[j] = '\0'; } return _dat; } // All of the following methods return the position // in the string controlled by *this of the // first substring matching the string given as a parameter. // As we chose not to manage the contain of the string, an // indifferent value is returned. size_type find (const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str, size_type pos = 0) const { volatile size_type ind = (size_type)0; return ind; } size_type find (const charT* s, size_type pos, size_type n) const { NON_NULL(s); VALID_SIZE(n) ; volatile size_type ind = (size_type)0; return ind; } size_type find (const charT* s, size_type pos = 0) const { NON_NULL(s); volatile size_type ind = (size_type)0; return ind; } size_type find (charT c, size_type pos = 0) const { volatile size_type ind = (size_type)0; return ind; } size_type rfind (const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str, size_type pos = npos) const { volatile size_type ind = (size_type)0; return ind; } size_type rfind (const charT* s, size_type pos, size_type n) const { NON_NULL(s); VALID_SIZE(n) ; volatile size_type ind = (size_type)0; return ind; } size_type rfind (charT* s, size_type pos = npos) const { NON_NULL(s); volatile size_type ind = (size_type)0; return ind; } size_type rfind (charT c, size_type pos = npos) const { volatile size_type ind = (size_type)0; return ind; } size_type find_first_of (const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str, size_type pos = 0) const { volatile size_type ind = (size_type)0; return ind; } size_type find_first_of (const charT* s, size_type pos, size_type n) const { NON_NULL(s); VALID_SIZE(n) ; volatile size_type ind = (size_type)0; return ind; } size_type find_first_of (const charT* s, size_type pos = 0) const { NON_NULL(s); volatile size_type ind = (size_type)0; return ind; } size_type find_first_of (charT c, size_type pos = 0) const { volatile size_type ind = (size_type)0; return ind; } size_type find_last_of (const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str, size_type pos = npos) const { volatile size_type ind = (size_type)0; return ind; } size_type find_last_of (const charT* s, size_type pos, size_type n) const { NON_NULL(s); VALID_SIZE(n) ; volatile size_type ind = (size_type)0; return ind; } size_type find_last_of (const charT* s, size_type pos = npos) const { NON_NULL(s); volatile size_type ind = (size_type)0; return ind; } size_type find_last_of (charT c, size_type pos = npos) const { volatile size_type ind = (size_type)0; return ind; } size_type find_first_not_of (const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str, size_type pos = 0) const { volatile size_type ind = (size_type)0; return ind; } size_type find_first_not_of (const charT* s, size_type pos, size_type n) const { NON_NULL(s); VALID_SIZE(n) ; volatile size_type ind = (size_type)0; return ind; } size_type find_first_not_of (const charT* s, size_type pos = 0) const { NON_NULL(s); volatile size_type ind = (size_type)0; return ind; } size_type find_first_not_of (charT c, size_type pos = 0) const { volatile size_type ind = (size_type)0; return ind; } size_type find_last_not_of (const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str, size_type pos = npos) const { volatile size_type ind = (size_type)0; return ind; } size_type find_last_not_of (const charT* s, size_type pos, size_type n) const { NON_NULL(s); VALID_SIZE(n) ; volatile size_type ind = (size_type)0; return ind; } size_type find_last_not_of (const charT* s, size_type pos = npos) const { NON_NULL(s); volatile size_type ind = (size_type)0; return ind; } size_type find_last_not_of (charT c, size_type pos = npos) const { volatile size_type ind = (size_type)0; return ind; } // Precondition : pos <= size(). // returns the substring of the // string controlled by *this, // from position pos. PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits) substr (size_type pos = 0, size_type n = npos) const { OUT_OF_RANGE(pos > _size); size_type rlen = PST_MIN(n, _size - pos) ; volatile charT c = '\0'; return basic_string(rlen, c); } // The following comparison methods do not affect the size of // the string controlled by *this, so an // indifferent value is returned. int compare (const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str) const { volatile int i = 0; return i; } int compare (size_type pos1, size_type n1, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str) const { OUT_OF_RANGE(pos1 > _size) ; volatile int i = 0; return i; } int compare (size_type pos1, size_type n1, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str, size_type pos2, size_type n2) const { OUT_OF_RANGE(pos1 > _size) ; OUT_OF_RANGE(pos2 > str._size) ; volatile int i = 0; return i; } int compare (const charT* s) const { NON_NULL(s); volatile int i = 0; return i; } int compare (size_type pos1, size_type n1, const charT* s, size_type n2 = npos) const { NON_NULL(s); OUT_OF_RANGE(pos1 > _size) ; volatile int i = 0; return i; } }; // static member npos : must be defined outside the class. // norm say -1, put maximum value that can be stored into a size_t for compatibility with -detect-unsigned-overflow // that change nothing to the final value. PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::npos = PST_MAX_SIZE_T ; // non member-functions PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) inline basic_ostream& operator<<(basic_ostream& os, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str) { return os; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) basic_istream& operator>>(basic_istream& is, PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& str_res) { volatile __ps_typename PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type str_len; volatile charT c = '\0'; charT b = c; assert(b != 0); str_res = PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)(str_len,b); return is; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) basic_istream& getline (basic_istream& is, PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& s, charT delim) { volatile int random = 0; __ps_typename PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type max = s.max_size(); __ps_typename PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type count = 0; if (random) { s.erase(); while (count < max && random) { volatile charT c = '\0'; assert(c != delim); s.append(1,c); ++count; } } return is; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) basic_istream& getline (basic_istream& is, PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& s) { volatile int random = 0; __ps_typename PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type max = s.max_size(); __ps_typename PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type count = 0; if (random) { s.erase(); while (count < max && random) { volatile charT c = '\0'; s.append(1,c); ++count; } } return is; } // non string members operators // All of the operator+ defined here // return a string whose size is the // sum of the sizes of the two parameters // given. The content of the resulting // string is indifferent. PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits) operator+(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { __ps_typename PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type len; len = lhs.size() + rhs.size(); if (len != 0) { charT* dat = new charT[len]; return PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)(dat,len); } return PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)(); } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits) operator+(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const charT* rhs) { NON_NULL(rhs); const charT* ptr = rhs; __ps_typename PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type n; n = 0; while (*ptr!=0) { ptr++; n++; } __ps_typename PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type len; len = n + lhs.size(); if (len != 0) { charT* dat = new charT[len]; return PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)(dat, len); } return PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)(); } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits) operator+(const charT* lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { NON_NULL(lhs); const charT* ptr =lhs; __ps_typename PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type n = 0; while (*ptr!=0) { ptr++; n++; } __ps_typename PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type len; len = n + rhs.size(); if (len != 0) { charT* dat = new charT[len]; return PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)(dat, len); } return PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)(); } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits) operator+(const charT lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { __ps_typename PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type len = rhs.size()+1; charT* dat = new charT[len]; return PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)(dat, len); } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits) operator+(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const charT rhs) { __ps_typename PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)::size_type len; len = lhs.size()+1; charT* dat = new charT[len]; return PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)(dat, len); } // All of the following comparison operators // do not modify the size of the string controlled // by *this. // As we chose not to manage the contain of the string, an // indifferent boolean value is returned. // However, to increase precision, the right result is // returned when possible (for instance, when strings s1 and s2 // don't have the same size we can say that they're different...) PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator==(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { if (lhs.size()!=rhs.size()) return __ps_false; volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator==(const charT* lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { NON_NULL(lhs); const charT *ptr = lhs; size_t size_lhs = 0; while(*ptr!=0){ size_lhs++;ptr++;} if (size_lhs!=rhs.size()) return __ps_false; volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator==(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const charT* rhs) { NON_NULL(rhs); const charT *ptr = rhs; size_t size_rhs = 0; while(*ptr!=0){ size_rhs++;ptr++;} if (size_rhs!=lhs.size()) return __ps_false; volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator!=(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { if (lhs.size()!=rhs.size()) return __ps_true; volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator!=(const charT* lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { NON_NULL(lhs); const charT *ptr = lhs; size_t size_lhs = 0; while(*ptr!=0){ size_lhs++; ptr++; } if (size_lhs!=rhs.size()) return __ps_true; volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator!=(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const charT* rhs) { NON_NULL(rhs); const charT *ptr = rhs; size_t size_rhs = 0; while(*ptr!=0){ size_rhs++; ptr++; } if (size_rhs!=lhs.size()) return __ps_true; volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator<(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator<(const charT* lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { NON_NULL(lhs); volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator<(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const charT* rhs) { NON_NULL(rhs); volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator>(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator>(const charT* lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { NON_NULL(lhs); volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator>(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const charT* rhs) { NON_NULL(rhs); volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator<=(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator<=(const charT* lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { NON_NULL(lhs); volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator<=(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const charT* rhs) { NON_NULL(rhs); volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator>=(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator>=(const charT* lhs, const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { NON_NULL(lhs); volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) __ps_bool operator>=(const PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, const charT* rhs) { NON_NULL(rhs); volatile __ps_bool b = false; return b; } // This method swaps the two // string given as parameters. // Both sizes are correctly // updated thanks to operator=. PST_TEMPLATE_DECL_FOR_CONTAINER2(class charT, class traits) void swap(PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& lhs, PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits)& rhs) { PST_TEMPLATE_CONTAINER_NAME2(basic_string, charT, traits) str_tmp = lhs; lhs = rhs; rhs = str_tmp; } } // end namespace std #ifdef __PST_IMPLICIT_USING_STD /* Implicitly include a using directive for the STD namespace when this preprocessing flag is TRUE. */ using namespace std; #endif /* ifdef __PST_IMPLICIT_USING_STD */ #ifdef PST_VISUAL #pragma pack(pop) /* pop back to previous value */ #endif // undef macros defined in this file #undef STRING_MAX_SIZE #undef OUT_OF_RANGE #undef VALID_RANGE #undef VALID_ITERATOR_ON_THIS #undef VALID_SIZE #undef VALID_SIZE_MAX #undef VALID_SIZE_MIN #undef PST_MIN #undef NON_NULL #undef PST_TEMPLATE_GET_SIZE #undef RETURN_ITERATOR #undef RETURN_ANY_ITERATOR #endif /* PST_STL_STRING */