/* Copyright 2012 The MathWorks, Inc. */ #ifndef PST_STL_SET #define PST_STL_SET #include #include #include <__polyspace__container.h> namespace std { #ifdef PST_VISUAL #pragma pack(push, 8) /* push default value */ #endif // pst verification macros #define VALID_SIZE(s) assert(s <= PST_CONTAINER_MAX_SIZE) #define VALID_SIZE_MAX(s,n) assert(s + n <= PST_CONTAINER_MAX_SIZE) #define VALID_SIZE_MIN(s,n) assert(s >= n) // pst internal macros #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) // pst compatibility with Visual 6&7.1 includes #ifdef PST_VISUAL #define PST_SET_ERASE_ITERATOR_RETURN_TYPE iterator #define PST_SET_ERASE_ITERATOR_RETURN_STAT return ITERATOR_ELEMENT(iterator) ; #else /* PST_VISUAL */ #define PST_SET_ERASE_ITERATOR_RETURN_TYPE void #define PST_SET_ERASE_ITERATOR_RETURN_STAT #endif /* PST_VISUAL */ PST_TEMPLATE_DECL_DEF_FOR_CONTAINER_SET(Key, Compare, less) class set { public: typedef Key key_type ; typedef Key value_type ; typedef Compare key_compare ; typedef Compare value_compare ; typedef PST_ALLOCATOR allocator_type ; typedef value_type& reference ; typedef const value_type& const_reference ; typedef value_type* pointer ; typedef const value_type* const_pointer ; typedef size_t size_type; typedef ptrdiff_t difference_type; #if defined(__PST_STL_SET_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 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_SET_CONST_ITERATOR_DIFFER_ITERATOR__) */ // 23.3.3.1 constructor/copy/destroy __ps_explicit set(const Compare& comp = Compare() PST_ALLOCATOR_DECL_LAST) : _size(0) { RESET_ELEMENTS() ; } template set(InputIterator first, InputIterator last, const Compare& comp = Compare() PST_ALLOCATOR_DECL_LAST) : _size(0) { RESET_ELEMENTS() ; for(InputIterator temp = first ; temp != last; ++temp) { //value_type dummy = *temp ; // read entry ADD_ELEMENT(*temp) ; _size++ ; } } set(const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& src) : _size(src._size) { _pst_elements = new value_type(*src._pst_elements) ; } ~set() { } PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& operator=(const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& src) { _size = src._size ; _pst_elements = new value_type(*src._pst_elements) ; return *this ; } // even if not really required in the norm, assume need it allocator_type get_allocator() const { PST_RETURN_STAT_FOR_GET_ALLOCATOR ; } // iterator 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 __ps_bool empty() const { return _size==0 ; } size_type size() const { return _size ; } size_type max_size() const { return PST_CONTAINER_MAX_SIZE ; } // modifiers pair insert(const value_type& x) { volatile int random = 0 ; if (random) { return make_pair(ITERATOR_ELEMENT(iterator), __ps_false) ; } else { _size++ ; ADD_ELEMENT(x) ; // read of x is done here return make_pair(ITERATOR_ELEMENT(iterator), __ps_true) ; } } iterator insert(iterator position, const value_type& x) // same as insert(x) { volatile int random = 0 ; iterator dummy(position) ; // read entry if (random) { return ITERATOR_ELEMENT(iterator) ; } else { _size++ ; ADD_ELEMENT(x) ; // read of x is done here return ITERATOR_ELEMENT(iterator) ; } } template void insert(InputIterator first, InputIterator last) { volatile int random = 0 ; for(InputIterator temp = first ; temp != last; ++temp) { if (random) /* if element are not yet inserted */ { _size++ ; ADD_ELEMENT(*temp) ; // read entry } } } PST_SET_ERASE_ITERATOR_RETURN_TYPE erase(iterator position) { iterator dummy(position) ; // read entry assert(_size>0) ; // iterator should be valid on this _size-- ; PST_SET_ERASE_ITERATOR_RETURN_STAT } size_t erase(const key_type& x) // return the number of elements erased 0 or 1 { if (_size==0) return 0 ; // if no elements, cannot erase any key_type dummy(x) ; // read entry volatile int random = 0 ; if (random) { _size-- ; return 1 ; } else { return 0 ; } } PST_SET_ERASE_ITERATOR_RETURN_TYPE erase(iterator first, iterator last) { // because we assume iterator are valid on this, all object in range are destroyed for(iterator temp = first ; temp != last; ++temp) { assert(_size>0) ; _size-- ; } PST_SET_ERASE_ITERATOR_RETURN_STAT } void swap(PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& x) { size_t tmp = _size ; _size = x._size ; x._size = tmp ; pointer tmp2 = x._pst_elements ; x._pst_elements = _pst_elements ; _pst_elements = tmp2 ; } void clear() { _size = 0 ; RESET_ELEMENTS() ; } // observers key_compare key_comp() const { volatile key_compare k ; return *(key_compare*)&k ; } value_compare value_comp() const { volatile key_compare k ; return *(key_compare*)&k ; } iterator find(const key_type& x) { // if begin() & end() will be more precise // we can give a random on between begin() & end() key_type dummy(x) ; // read entry return ITERATOR_ELEMENT(iterator) ; } const_iterator find(const key_type& x) const { key_type dummy(x) ; // read entry return ITERATOR_ELEMENT(const_iterator) ; } size_t count(const key_type& x) const { if (_size==0) return 0 ; // if no elements ... volatile int rand = 0 ; return rand ? 0 : 1 ; } iterator lower_bound(const key_type& x) { // if begin() & end() will be more precise // we can give a random on between begin() & end() // because we does not store Compare object, it is useless to try to applly constraints // such as assert( (ret==end()) || !(Compare()(ret->first,x))) ; key_type dummy(x) ; // read entry return ITERATOR_ELEMENT(iterator); } const_iterator lower_bound(const key_type& x) const { key_type dummy(x) ; // read entry return ITERATOR_ELEMENT(const_iterator); } iterator upper_bound(const key_type& x) { // if begin() & end() will be more precise // we can give a random on between begin() & end() key_type dummy(x) ; // read entry return ITERATOR_ELEMENT(iterator); } const_iterator upper_bound(const key_type& x) const { key_type dummy(x) ; // read entry return ITERATOR_ELEMENT(const_iterator); } pair equal_range(const key_type& x) { // if begin() & end() will be more precise // we can give a random on between begin() & end() return make_pair(lower_bound(x), upper_bound(x)) ; } pair equal_range(const key_type& x) const { return make_pair(lower_bound(x), upper_bound(x)) ; } friend __ps_bool std::operator==(const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& y) ; private: size_t _size ; pointer _pst_elements ; } ; PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) void swap(PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& x, PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& y) { x.swap(y) ; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) __ps_bool operator==(const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& y) { volatile int rand = 0 ; return (x._size == y._size) ? rand : __ps_false ; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) __ps_bool operator!=(const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& y) { return !(x==y) ; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) __ps_bool operator<(const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& y) { volatile int rand = 0 ; return rand ; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) __ps_bool operator<=(const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& y) { volatile int rand = 0 ; return rand ; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) __ps_bool operator> (const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& y) { volatile int rand = 0 ; return rand ; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) __ps_bool operator>=(const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(set, Key, Compare)& y) { volatile int rand = 0 ; return rand ; } // only difference from set : // - absence of operator[] // - difference of return and implemetation of insert( ... ) methods // - difference in implementation of count(const key_type&), erase(const key_type&) PST_TEMPLATE_DECL_DEF_FOR_CONTAINER_SET(Key, Compare, less) class multiset { public: typedef Key key_type ; typedef Key value_type ; typedef Compare key_compare ; typedef Compare value_compare ; typedef PST_ALLOCATOR allocator_type ; typedef value_type& reference ; typedef const value_type& const_reference ; typedef value_type* pointer ; typedef const value_type* const_pointer ; typedef size_t size_type; typedef ptrdiff_t difference_type; 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; // 23.3.1.1 constructor/copy/destroy __ps_explicit multiset(const Compare& comp = Compare() PST_ALLOCATOR_DECL_LAST) : _size(0) { RESET_ELEMENTS() ; } template multiset(InputIterator first, InputIterator last, const Compare& comp = Compare() PST_ALLOCATOR_DECL_LAST) : _size(0) { RESET_ELEMENTS() ; for(InputIterator temp = first ; temp != last; ++temp) { ADD_ELEMENT(*temp) ; _size++ ; } } multiset(const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& src) : _size(src._size) { _pst_elements = new value_type(*src._pst_elements) ; } ~multiset() { } PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& operator=(const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& src) { _size = src._size ; _pst_elements = new value_type(*src._pst_elements) ; return *this ; } // even if not really required in the norm, assume need it 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 __ps_bool empty() const { return _size==0 ; } size_type size() const { return _size ; } size_type max_size() const { return PST_CONTAINER_MAX_SIZE ; } // modifiers iterator insert(const value_type& x) { _size++ ; ADD_ELEMENT(x) ; // read of x is done here return ITERATOR_ELEMENT(iterator) ; } iterator insert(iterator position, const value_type& x) // same as insert(x) { iterator dummy(position) ; // read entry _size++ ; ADD_ELEMENT(x) ; // read of x is done here return ITERATOR_ELEMENT(iterator) ; } template void insert(InputIterator first, InputIterator last) { for(InputIterator temp = first ; temp != last; ++temp) { ADD_ELEMENT(*temp) ; // read entry _size++ ; } } PST_SET_ERASE_ITERATOR_RETURN_TYPE erase(iterator position) { iterator dummy(position) ; // read entry assert(_size>0) ; // iterator should be valid on this _size-- ; PST_SET_ERASE_ITERATOR_RETURN_STAT } size_t erase(const key_type& x) // return the number of elements erased { key_type dummy(x) ; // read entry volatile size_t random = 0 ; size_t cpt = random ; assert(cpt <= _size) ; // number of element to be removed _size -= cpt ; return cpt ; } PST_SET_ERASE_ITERATOR_RETURN_TYPE erase(iterator first, iterator last) { // because we assume iterator are valid on this, all object in range are destroyed for(iterator temp = first ; temp != last; ++temp) { assert(_size>0) ; // iterator are valid on this _size-- ; } PST_SET_ERASE_ITERATOR_RETURN_STAT } void swap(PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& x) { size_t tmp = _size ; _size = x._size ; x._size = tmp ; pointer tmp2 = x._pst_elements ; x._pst_elements = _pst_elements ; _pst_elements = tmp2 ; } void clear() { _size = 0 ; RESET_ELEMENTS() ; } // observers key_compare key_comp() const { volatile key_compare k ; return *(key_compare*)&k ; } value_compare value_comp() const { volatile key_compare k ; return value_compare(*(key_compare*)&k) ; } // 23.3.1.3 iterator find(const key_type& x) { // if begin() & end() will be more precise // we can give a random on between begin() & end() key_type dummy(x) ; // read entry return ITERATOR_ELEMENT(iterator) ; } const_iterator find(const key_type& x) const { key_type dummy(x) ; // read entry return ITERATOR_ELEMENT(const_iterator) ; } size_t count(const key_type& x) const { key_type dummy(x) ; // read entry volatile size_t random = 0 ; size_t cpt = random ; assert(cpt <= _size) ; // number of element to be counted return cpt ; } iterator lower_bound(const key_type& x) { // if begin() & end() will be more precise // we can give a random on between begin() & end() key_type dummy(x) ; // read entry return ITERATOR_ELEMENT(iterator); } const_iterator lower_bound(const key_type& x) const { key_type dummy(x) ; // read entry return ITERATOR_ELEMENT(const_iterator); } iterator upper_bound(const key_type& x) { // if begin() & end() will be more precise // we can give a random on between begin() & end() key_type dummy(x) ; // read entry return ITERATOR_ELEMENT(iterator); } const_iterator upper_bound(const key_type& x) const { key_type dummy(x) ; // read entry return ITERATOR_ELEMENT(const_iterator); } pair equal_range(const key_type& x) { // if begin() & end() will be more precise // we can give a random on between begin() & end() return make_pair(lower_bound(x), upper_bound(x)) ; } pair equal_range(const key_type& x) const { return make_pair(lower_bound(x), upper_bound(x)) ; } friend __ps_bool std::operator==(const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& y) ; private: size_t _size ; pointer _pst_elements ; } ; PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) void swap(PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& x, PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& y) { x.swap(y) ; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) __ps_bool operator==(const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& y) { volatile int rand = 0 ; return (x._size == y._size) ? rand : __ps_false ; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) __ps_bool operator!=(const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& y) { return !(x==y) ; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) __ps_bool operator<(const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& y) { volatile int rand = 0 ; return rand ; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) __ps_bool operator<=(const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& y) { volatile int rand = 0 ; return rand ; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) __ps_bool operator> (const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& y) { volatile int rand = 0 ; return rand ; } PST_TEMPLATE_DECL_FOR_CONTAINER2(class Key, class Compare) __ps_bool operator>=(const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& x, const PST_TEMPLATE_CONTAINER_NAME2(multiset, Key, Compare)& y) { volatile int rand = 0 ; return rand ; } #ifdef PST_VISUAL #pragma pack(pop) /* pop back to previous value */ #endif } #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 VALID_SIZE #undef VALID_SIZE_MAX #undef VALID_SIZE_MIN #undef RESET_ELEMENTS #undef ADD_ELEMENT #undef ITERATOR_ELEMENT #undef PST_SET_ERASE_ITERATOR_RETURN_TYPE #undef PST_SET_ERASE_ITERATOR_RETURN_STAT #endif /* PST_STL_SET */