/* * * 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. * */ // PST stub for class vector // from STL library. // As for string stub, we made // the choice not to give a template // argument for class Allocator, // and to matter only about the // number of elements contained // in the vector. #ifndef PST_STL_VECTOR #define PST_STL_VECTOR // necessary in visual mode // for ptrdiff_t #include <__polyspace__container.h> #include // macros undefined at the end of file #define OUT_OF_RANGE(cond) assert (!(cond)) #define LENGTH_ERROR(cond) assert (!(cond)) #define VALID_RANGE(f,l) assert ((f!=0 && l!=0) && f<=l) #define VALID_SIZE(s) assert(s <= (PST_CONTAINER_MAX_SIZE/sizeof(value_type)) && s >= 0) #define VALID_SIZE_MAX(s,n) assert(s <= (PST_CONTAINER_MAX_SIZE/sizeof(value_type)) - n) #define VALID_SIZE_MIN(s,n) assert(s >= n) #define NON_NULL(p) assert(p != 0) #define RESET_ELEMENTS() { value_type* volatile random_element ; _pst_elements = new value_type(*random_element) ; } // create "first" element #define ADD_ELEMENT(t) { volatile int random_alias = 0 ; if (random_alias) _pst_elements = new value_type(t) ; } #define ITERATOR_ELEMENT(i) i(_pst_elements) #ifdef PST_VISUAL #pragma pack(push, 8) /* push default value */ #endif namespace std { template struct __PST_VECTOR_ADD_ELEMENTS_T { }; template struct __PST_VECTOR_ADD_ELEMENTS_T { static size_t add(InputIterator __first, InputIterator __last, value_type *&_pst_elements ) { size_t nbelt = 0; // 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) { ADD_ELEMENT(*tmp) ; nbelt++ ; } VALID_SIZE(nbelt) ; return nbelt; } ; } ; // specialization for pointer template struct __PST_VECTOR_ADD_ELEMENTS_T { static size_t add(Pointed* __first, Pointed* __last, value_type *&_pst_elements ) { VALID_RANGE(__first,__last); VALID_SIZE(__last - __first); for (Pointed* tmp = __first; tmp != __last; ++tmp) { ADD_ELEMENT(*tmp) ; } return __last - __first; } ; } ; template struct __PST_VECTOR_ADD_ELEMENTS_T { static size_t add(InputIterator __first, InputIterator __last, value_type *&_pst_elements) { ADD_ELEMENT(__last) ; return __first; } } ; PST_TEMPLATE_DECL_DEF_FOR_CONTAINER(T) class vector { public: // types typedef T value_type; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef PST_ALLOCATOR allocator_type; typedef value_type* pointer; typedef const value_type* const_pointer; #if defined(__PST_STL_VECTOR_CONST_ITERATOR_DIFFER_ITERATOR__) typedef __pst__generic_iterator iterator; typedef __pst__generic_iterator const_iterator; typedef __pst__reverse_iterator const_reverse_iterator; typedef __pst__reverse_iterator reverse_iterator; #else // implementation choice : norm specify that vector (and all sequence container) iterator // should be at least forward_iterator; for vector, random_access_iterator seems more suitable typedef __pst__generic_iterator iterator; // implementation choice: const_iterator is the same as iterator, this avoids // the need for an implicit conversion from const_iterator to iterator typedef iterator const_iterator; typedef __pst__reverse_iterator reverse_iterator; // implementation choice: const_reverse_iterator is the same as reverse_iterator, this avoids // the need for an implicit conversion from const_reverse_iterator to reverse_iterator typedef reverse_iterator const_reverse_iterator; #endif /* #if defined(__PST_STL_VECTOR_CONST_ITERATOR_DIFFER_ITERATOR__) */ private: // the current number of elements // contained in the vector size_type _nbelt; pointer _pst_elements ; public: // construct/copy/destroy // the default constructor // Post-condition : size() == 0 vector(PST_ALLOCATOR_DECL1) { _nbelt=0; RESET_ELEMENTS() ; } // Post : size() == n __ps_explicit vector(size_type __n, const T& __value = T() PST_ALLOCATOR_DECL_LAST) { VALID_SIZE(__n); _nbelt = __n; RESET_ELEMENTS() ; volatile int random = 0 ; while (random) _pst_elements = new value_type(__value) ; } // Post : size() == __x.size() vector(const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& __x) { _nbelt = __x.size() ; _pst_elements = new value_type(*__x._pst_elements) ; } // destructor : // the access to any member of the // vector object should provoke // a runtime error after calling // the destructor. We set the number // of elements contained in *this // to 0 though it doesn't have // much meaning... ~vector() { _nbelt = 0; _pst_elements = 0 ; } // post-condition : size() == distance // between __first and __last. template vector(InputIterator __first, InputIterator __last PST_ALLOCATOR_DECL_LAST) { RESET_ELEMENTS() ; _nbelt = __PST_VECTOR_ADD_ELEMENTS_T::is_int_type >::add(__first, __last, _pst_elements ); } PST_TEMPLATE_CONTAINER_NAME1(vector, T)& operator=(const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& __x) { _nbelt = __x.size(); _pst_elements = new value_type(*(__x._pst_elements)) ; return *this; } // assign(), a generalized assignment member function. Two // versions: one that takes a count, and one that takes a range. void assign(size_type __n, const T& __val){ VALID_SIZE(__n); _nbelt = __n; volatile int random = 0; while (random) ADD_ELEMENT(__val) ; } template void assign(InputIterator __first, InputIterator __last) { RESET_ELEMENTS() ; _nbelt = __PST_VECTOR_ADD_ELEMENTS_T::is_int_type >::add(__first, __last, _pst_elements ); } // 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 ; } // iterators iterator begin() { return ITERATOR_ELEMENT(iterator) ; } const_iterator begin() const { return ITERATOR_ELEMENT(const_iterator) ; } iterator end() { return ITERATOR_ELEMENT(iterator) ; } const_iterator end() const { return ITERATOR_ELEMENT(const_iterator) ; } reverse_iterator rbegin() { return ITERATOR_ELEMENT(reverse_iterator) ; } const_reverse_iterator rbegin() const { return ITERATOR_ELEMENT(const_reverse_iterator) ; } reverse_iterator rend() { return ITERATOR_ELEMENT(reverse_iterator) ; } const_reverse_iterator rend() const { return ITERATOR_ELEMENT(const_reverse_iterator) ; } // capacity size_type size() const { return _nbelt; } // Returns the greatest unsigned // int value. size_type max_size() const { return PST_CONTAINER_MAX_SIZE/sizeof(value_type); } size_type capacity() const { volatile size_type delta = (size_type)0; return (_nbelt + delta); } __ps_bool empty() const { return _nbelt == 0; } // Post : size() not modified. // throws length_error if // __n > max_size(). void reserve(size_type __n) { LENGTH_ERROR(__n > max_size()); } // size() is set to // __new_size iff _nbelt is greater. // otherwise, size() is set to // __new_size. void resize(size_type __new_size, T __x = T()) { VALID_SIZE(__new_size); _nbelt = __new_size; volatile int random = 0; while (random) ADD_ELEMENT(__x) ; } reference operator[](size_type __n) { OUT_OF_RANGE(__n >= _nbelt || __n < 0); iterator it = ITERATOR_ELEMENT(iterator) ; return *it; } const_reference operator[](size_type __n) const { OUT_OF_RANGE(__n >= _nbelt || __n < 0); const_iterator it = ITERATOR_ELEMENT(const_iterator) ; return *it; } reference at(size_type __n) { OUT_OF_RANGE(__n >= _nbelt); iterator it = ITERATOR_ELEMENT(iterator) ; return *it; } const_reference at(size_type __n) const { OUT_OF_RANGE(__n >= _nbelt); const_iterator it = ITERATOR_ELEMENT(const_iterator) ; return *it; } reference front() { return *begin(); // too complicated ? } const_reference front() const { return *begin(); // too complicated ? } reference back() { return *begin(); // sementically __ps_false ... but correct for verifier with begin impl. } const_reference back() const { return *begin(); // sementically __ps_false ... but correct for verifier with begin impl. } // modifiers // inserts __x at the end of *this. // size() is increased by one. // the norm doesn't specify // any condition about adding // an element when size() is // already equal to max_size() ... void push_back(const T& __x) { VALID_SIZE_MAX(_nbelt,1); _nbelt++ ; ADD_ELEMENT(__x) ; } // remove the last element of // *this, and so size() is // decreased by one. // The norm doesn't specify // to check if *this is already empty... // we check it anyway void pop_back() { VALID_SIZE_MIN(_nbelt,1); _nbelt--; } // not specified in the norm, but we guess // that __x is inserted at position __position // in the vector controlled by *this. // so the number of elements in increased by one. // We also suppose that the iterator returned // is __position. iterator insert(iterator __position, const T& __x) { NON_NULL(__position); VALID_SIZE_MAX(_nbelt,1); _nbelt++; ADD_ELEMENT(__x) ; return ITERATOR_ELEMENT(iterator); } // not specified in the norm, but we guess // that __x is inserted n times at position __position // in the vector controlled by *this. // so the number of elements is increased by n. // as above, we suppose that the result is __position. void insert(iterator __position, size_type __n, const T& __x) { NON_NULL(__position); VALID_SIZE_MAX(_nbelt,__n); _nbelt += __n; volatile int random = 0 ; while (random) ADD_ELEMENT(__x) ; } // not specified in the norm, but we guess // that all elements between __first and __last // are inserted from position __pos // in the vector controlled by *this. // so the number of elements in increased by (__last - __first). template void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { size_t added = __PST_VECTOR_ADD_ELEMENTS_T<_InputIterator, value_type, __polyspace_is_int_type<_InputIterator>::is_int_type >::add(__first, __last, _pst_elements ); VALID_SIZE_MAX(_nbelt, added); _nbelt += added; } // erases the element at postion __position // in the vector : size() is decreased by one. iterator erase(iterator __position) { NON_NULL(__position); VALID_SIZE_MIN(_nbelt,1); _nbelt--; return __position; } // erases all elements between __first // and __last, and so size() is decreased // by (__last - __first). iterator erase(iterator __first, iterator __last) { VALID_RANGE(__first, __last); VALID_SIZE_MIN(_nbelt,(__last - __first)); _nbelt -= __last - __first; return __first; } // swaps __x and *this void swap(PST_TEMPLATE_CONTAINER_NAME1(vector, T)& __x) { size_type n = _nbelt; _nbelt = __x.size(); __x._nbelt = n ; pointer tmp = __x._pst_elements ; __x._pst_elements = _pst_elements ; _pst_elements = tmp ; } // post: size() == 0 void clear() { _nbelt = 0; RESET_ELEMENTS() ; } // for vector<__ps_bool> void flip() {} }; // class vector // non-member operators PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) __ps_bool operator==(const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& x, const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& y) { volatile __ps_bool b = true; if (x.size() != y.size()) return __ps_false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) __ps_bool operator<(const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& x, const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& y) { volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) __ps_bool operator!=(const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& x, const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& y) { volatile __ps_bool b = false; if (x.size() != y.size()) return __ps_true; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) __ps_bool operator>(const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& x, const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& y) { volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) __ps_bool operator>=(const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& x, const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& y) { volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) __ps_bool operator<=(const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& x, const PST_TEMPLATE_CONTAINER_NAME1(vector, T)& y) { volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) void swap(PST_TEMPLATE_CONTAINER_NAME1(vector, T)& x, PST_TEMPLATE_CONTAINER_NAME1(vector, T)& y) { x.swap(y); } } // 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 OUT_OF_RANGE #undef LENGTH_ERROR #undef VALID_RANGE #undef VALID_SIZE #undef VALID_SIZE_MAX #undef VALID_SIZE_MIN #undef NON_NULL #undef ADD_ELEMENT #undef RESET_ELEMENT #undef ITERATOR_ELEMENT #endif /* PST_STL_VECTOR */