/* * * 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 list // from STL library. // As for string stub, we made // the choice to matter only about the // number of elements contained // in the list. #ifndef PST_STL_LIST #define PST_STL_LIST #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) #define VALID_SIZE_MAX(s,n) assert(s <= PST_CONTAINER_MAX_SIZE - 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 RESET_ELEMENTS_ON(p) { value_type* volatile random_element ; p._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) namespace std { #ifdef PST_VISUAL #pragma pack(push, 8) /* push default value */ #endif template struct __PST_LIST_ADD_ELEMENTS_T { }; template struct __PST_LIST_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 //VALID_RANGE(__first,__last); for (InputIterator tmp = __first; tmp != __last; ++tmp) { ADD_ELEMENT(*tmp) ; nbelt++ ; } VALID_SIZE(nbelt) ; return nbelt; } ; } ; // specialization for pointer template struct __PST_LIST_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_LIST_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 list { // types public: typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; #if defined(__PST_STL_LIST_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 list (and all sequence container) iterator // should be at least forward_iterator; for list bidirectional_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_LIST_CONST_ITERATOR_DIFFER_ITERATOR__) */ typedef PST_ALLOCATOR allocator_type; allocator_type get_allocator() const { PST_RETURN_STAT_FOR_GET_ALLOCATOR ; } private: // the current number of elements // contained in the list size_type _nbelt; pointer _pst_elements ; public: // construct/copy/destroy // the default constructor // Post-condition : size() == 0 __ps_explicit list(PST_ALLOCATOR_DECL1) { _nbelt=0; RESET_ELEMENTS() ; } // Post : size() == __n list(size_type __n, const T& __value = T() PST_ALLOCATOR_DECL_LAST) { VALID_SIZE(__n); _nbelt = __n; volatile int random = 0 ; RESET_ELEMENTS() ; while (random) _pst_elements = new value_type(__value) ; } template list(_InputIterator __first, _InputIterator __last PST_ALLOCATOR_DECL_LAST) { RESET_ELEMENTS() ; _nbelt = __PST_LIST_ADD_ELEMENTS_T<_InputIterator, value_type, __polyspace_is_int_type<_InputIterator>::is_int_type >::add(__first, __last, _pst_elements ); } list(const PST_TEMPLATE_CONTAINER_NAME1(list, T)& __x) { _nbelt = __x.size(); _pst_elements = new value_type(*__x._pst_elements) ; } // Destructor ~list() { _nbelt = 0 ; _pst_elements = 0 ; } 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) ; } __ps_bool empty() const { return (size() == 0); } size_type size() const { return _nbelt; } size_type max_size() const { return PST_CONTAINER_MAX_SIZE; } 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. } // swaps __x and *this void swap(PST_TEMPLATE_CONTAINER_NAME1(list, T)& x) { size_type n = _nbelt; _nbelt = x._nbelt; x._nbelt = n ; pointer tmp = x._pst_elements ; x._pst_elements = _pst_elements ; _pst_elements = tmp ; } iterator insert(iterator __position, const T& __x) { NON_NULL(__position); VALID_SIZE_MAX(_nbelt,1); _nbelt++; ADD_ELEMENT(__x) ; return ITERATOR_ELEMENT(iterator) ; } void insert(iterator __pos, size_type __n, const T& __x) { NON_NULL(__pos); VALID_SIZE_MAX(_nbelt, __n); for (int i=0; i<__n; i++) ADD_ELEMENT(__x) ; _nbelt += __n; } template void insert(iterator position, InputIterator __first, InputIterator __last) { size_t added = __PST_LIST_ADD_ELEMENTS_T::is_int_type >::add(__first, __last, _pst_elements ); VALID_SIZE_MAX(_nbelt, added); _nbelt += added; } // Those two methods adds a single // element to the list controlled // by *this void push_front(const T& __x) { VALID_SIZE_MAX(_nbelt,1); _nbelt++; ADD_ELEMENT(__x) ; } // Those two methods add // one single element to the list // controlled by *this. void push_back(const T& __x) { VALID_SIZE_MAX(_nbelt,1); _nbelt++; ADD_ELEMENT(__x) ; } // This method erases the element // pointed to by __position. // the list contains one less element. iterator erase(iterator __position) { NON_NULL(__position); VALID_SIZE_MIN(_nbelt,1); _nbelt--; return ITERATOR_ELEMENT(iterator) ; } // This method erases all elements // contained in the range [__first, __last) // 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 ITERATOR_ELEMENT(iterator) ; } // Post = size()==0 void clear() { _nbelt = 0; RESET_ELEMENTS() ; } // post : size() == __new_size void resize(size_type __new_size, const T& __x = T()){ VALID_SIZE(__new_size); _nbelt = __new_size; volatile int random = 0; while (random) ADD_ELEMENT(__x) ; } void pop_front() { VALID_SIZE_MIN(_nbelt,1); _nbelt--; } void pop_back() { VALID_SIZE_MIN(_nbelt,1); _nbelt--; } PST_TEMPLATE_CONTAINER_NAME1(list, T)& operator=(const PST_TEMPLATE_CONTAINER_NAME1(list, T)& __x) { _nbelt = __x.size(); _pst_elements = new value_type(*(__x._pst_elements)) ; return *this; } 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_LIST_ADD_ELEMENTS_T<_InputIterator, value_type, __polyspace_is_int_type<_InputIterator>::is_int_type >::add(__first, __last, _pst_elements ); } // move all elements of x // to *this, before position __position. // Pre : &x != this // Post : __x.empty()==__ps_true void splice(iterator __position, list& __x) { NON_NULL(__position); assert(&__x != this); VALID_SIZE_MAX(_nbelt, __x.size()); _nbelt += __x.size(); ADD_ELEMENT(*__x._pst_elements) ; __x = list(); } // moves element from x pointed to by __i // to *this at position __position. // the result is unchanged if __position == i // or __position == ++i // Post : x has one less element. void splice(iterator __position, list& __x, iterator __i) { NON_NULL(__position); NON_NULL(__i); if (__position != __i && __position!= __i+1) { VALID_SIZE_MAX(_nbelt,1); VALID_SIZE_MIN(__x._nbelt,1); _nbelt++; ADD_ELEMENT(*__x._pst_elements) ;/* copy potentielle de tous les objets */ __x._nbelt--; } } // moves elements in range [__first, __last) from x // to *this, before __position. // Pre : [__first, __last) is a valid range void splice(iterator __position, list& __x, iterator __first, iterator __last) { NON_NULL(__position); VALID_RANGE(__first, __last); VALID_SIZE_MAX(_nbelt, (__last - __first)); VALID_SIZE_MIN(__x._nbelt, (__last - __first)); _nbelt += __last - __first; ADD_ELEMENT(*__x._pst_elements) ; __x._nbelt -= __last - __first; } // Removes every ocurrence // of __value in the list controlled // by *this. So we cannot predict // the value of size(), but it can only // be smaller. void remove(const T& __value) { volatile size_type nb_removed = (size_type)0; VALID_SIZE_MIN(_nbelt, nb_removed); _nbelt -= nb_removed; } // Erases all the elements in the list // referred by a list iterator i for // which the following condition holds: pred(*i) != __ps_false. template void remove_if(Predicate pred) { value_type* volatile elt ; __ps_bool b = pred( *(value_type*) elt); volatile size_type nb_removed = (size_type)0; VALID_SIZE_MIN(_nbelt, nb_removed); _nbelt -= nb_removed; } // Removes all but first elements // from every consecutive group of // equal elements referred to by // iterator i in the range [first + 1, last) // So we cannot predict what size() will be. // We only know that we'll have size() <= size() void unique() { volatile size_type nb_removed = (size_type)0; // the number of elements removed // cannot be greater that the number // of elements contained in the list. assert(nb_removed < _nbelt); _nbelt -= nb_removed; } template void unique(BinaryPredicate binary_pred) { volatile size_type nb_removed = (size_type)0; // the number of elements removed // cannot be greater that the number // of elements contained in the list. assert(nb_removed < _nbelt); _nbelt -= nb_removed; } void merge(list& x) { VALID_SIZE_MAX(_nbelt, x.size()); _nbelt += x.size(); ADD_ELEMENT(*x._pst_elements) ; // suppress elements from x x._nbelt= 0; RESET_ELEMENTS_ON(x) ; } template void merge(list& x, Compare comp) { VALID_SIZE_MAX(_nbelt, x.size()); _nbelt += x.size(); ADD_ELEMENT(*x._pst_elements) ; // suppress elements from x x._nbelt= 0; RESET_ELEMENTS_ON(x) ; } // Sorts the elements of the list, // it doesn't affect its number // if elements. void sort() {} template void sort(Compare comp) {} // Reverses all elements // and so doesn't affect // the number of elements void reverse() {} }; PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) inline __ps_bool operator==(const PST_TEMPLATE_CONTAINER_NAME1(list, T)& __x, const PST_TEMPLATE_CONTAINER_NAME1(list, T)& __y){ if (__x.size() != __y.size()) return __ps_false; volatile __ps_bool b = true; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) inline __ps_bool operator<(const PST_TEMPLATE_CONTAINER_NAME1(list, T)& __x, const PST_TEMPLATE_CONTAINER_NAME1(list, T)& __y){ volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) __ps_bool operator!=(const PST_TEMPLATE_CONTAINER_NAME1(list, T)& x, const PST_TEMPLATE_CONTAINER_NAME1(list, 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(list, T)& x, const PST_TEMPLATE_CONTAINER_NAME1(list, T)& y) { volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) __ps_bool operator>=(const PST_TEMPLATE_CONTAINER_NAME1(list, T)& x, const PST_TEMPLATE_CONTAINER_NAME1(list, T)& y) { volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) __ps_bool operator<=(const PST_TEMPLATE_CONTAINER_NAME1(list, T)& x, const PST_TEMPLATE_CONTAINER_NAME1(list, T)& y) { volatile __ps_bool b = false; return b; } PST_TEMPLATE_DECL_FOR_CONTAINER1(class T) inline void swap(PST_TEMPLATE_CONTAINER_NAME1(list, T)& __x, PST_TEMPLATE_CONTAINER_NAME1(list, T)& __y) { __x.swap(__y); } #ifdef PST_VISUAL #pragma pack(pop) /* pop back to previous value */ #endif } // 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 */ // 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_LIST */