slist.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,612 行 · 第 1/4 页
HPP
1,612 行
//! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()). //! //! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! and iterators to elements that are not removed remain valid. void unique() { this->unique(value_equal()); } //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! elements that satisfy some binary predicate from the list. //! //! <b>Throws</b>: If pred throws. //! //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons). //! //! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! and iterators to elements that are not removed remain valid. template <class Pred> void unique(Pred pred) { typedef ValueCompareToNodeCompare<Pred> Predicate; this->icont().unique_and_dispose(Predicate(pred), Destroyer(this->node_alloc())); } //! <b>Requires</b>: The lists x and *this must be distinct. //! //! <b>Effects</b>: This function removes all of x's elements and inserts them //! in order into *this according to std::less<value_type>. The merge is stable; //! that is, if an element from *this is equivalent to one from x, then the element //! from *this will precede the one from x. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: This function is linear time: it performs at most //! size() + x.size() - 1 comparisons. void merge(slist& x) { this->merge(x, value_less()); } //void merge(const detail::moved_object<slist>& x) //{ this->merge(x.get(), value_less()); } //! <b>Requires</b>: p must be a comparison function that induces a strict weak //! ordering and both *this and x must be sorted according to that ordering //! The lists x and *this must be distinct. //! //! <b>Effects</b>: This function removes all of x's elements and inserts them //! in order into *this. The merge is stable; that is, if an element from *this is //! equivalent to one from x, then the element from *this will precede the one from x. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: This function is linear time: it performs at most //! size() + x.size() - 1 comparisons. //! //! <b>Note</b>: Iterators and references to *this are not invalidated. template <class StrictWeakOrdering> void merge(slist& x, StrictWeakOrdering comp) { if((NodeAlloc&)*this == (NodeAlloc&)x){ this->icont().merge(x.icont(), ValueCompareToNodeCompare<StrictWeakOrdering>(comp)); } else{ throw std::runtime_error("list::merge called with unequal allocators"); } } //template <class StrictWeakOrdering> //void merge(const detail::moved_object<slist>& x, StrictWeakOrdering comp) //{ this->merge(x.get(), comp); } //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. //! The sort is stable, that is, the relative order of equivalent elements is preserved. //! //! <b>Throws</b>: Nothing. //! //! <b>Notes</b>: Iterators and references are not invalidated. //! //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N //! is the list's size. void sort() { this->sort(value_less()); } //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. //! The sort is stable, that is, the relative order of equivalent elements is preserved. //! //! <b>Throws</b>: Nothing. //! //! <b>Notes</b>: Iterators and references are not invalidated. //! //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N //! is the list's size. template <class StrictWeakOrdering> void sort(StrictWeakOrdering comp) { // nothing if the slist has length 0 or 1. if (this->size() < 2) return; this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp)); } /// @cond private: //Iterator range version template<class InpIterator> void priv_create_and_insert_nodes (const_iterator prev, InpIterator beg, InpIterator end) { typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat; priv_create_and_insert_nodes(prev, beg, end, alloc_version(), ItCat()); } template<class InpIterator> void priv_create_and_insert_nodes (const_iterator prev, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag) { for (; beg != end; ++beg){ this->icont().insert_after(prev.get(), *this->create_node_from_it(beg)); ++prev; } } template<class InpIterator> void priv_create_and_insert_nodes (const_iterator prev, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag) { //Just forward to the default one priv_create_and_insert_nodes(prev, beg, end, allocator_v1(), std::input_iterator_tag()); } class insertion_functor; friend class insertion_functor; class insertion_functor { Icont &icont_; typename Icont::const_iterator prev_; public: insertion_functor(Icont &icont, typename Icont::const_iterator prev) : icont_(icont), prev_(prev) {} void operator()(Node &n) { prev_ = this->icont_.insert_after(prev_, n); } }; template<class FwdIterator> void priv_create_and_insert_nodes (const_iterator prev, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag) { //Optimized allocation and construction this->allocate_many_and_construct (beg, std::distance(beg, end), insertion_functor(this->icont(), prev.get())); } //Default constructed version void priv_create_and_insert_nodes(const_iterator prev, size_type n) { typedef default_construct_iterator<value_type, difference_type> default_iterator; this->priv_create_and_insert_nodes(prev, default_iterator(n), default_iterator()); } //Copy constructed version void priv_create_and_insert_nodes(const_iterator prev, size_type n, const T& x) { typedef constant_iterator<value_type, difference_type> cvalue_iterator; this->priv_create_and_insert_nodes(prev, cvalue_iterator(x, n), cvalue_iterator()); } //Dispatch to detect iterator range or integer overloads template <class InputIter> void priv_insert_dispatch(const_iterator prev, InputIter first, InputIter last, detail::false_) { this->priv_create_and_insert_nodes(prev, first, last); } template<class Integer> void priv_insert_dispatch(const_iterator prev, Integer n, Integer x, detail::true_) { this->priv_create_and_insert_nodes(prev, n, x); } void priv_fill_assign(size_type n, const T& val) { iterator end_n(this->end()); iterator prev(this->before_begin()); iterator node(this->begin()); for ( ; node != end_n && n > 0 ; --n){ *node = val; prev = node; ++node; } if (n > 0) this->priv_create_and_insert_nodes(prev, n, val); else this->erase_after(prev, end_n); } template <class Int> void priv_assign_dispatch(Int n, Int val, detail::true_) { this->priv_fill_assign((size_type) n, (T)val); } template <class InpIt> void priv_assign_dispatch(InpIt first, InpIt last, detail::false_) { iterator end_n(this->end()); iterator prev(this->before_begin()); iterator node(this->begin()); while (node != end_n && first != last){ *node = *first; prev = node; ++node; ++first; } if (first != last) this->priv_create_and_insert_nodes(prev, first, last); else this->erase_after(prev, end_n); } template <class Int> void priv_insert_after_range_dispatch(const_iterator prev_pos, Int n, Int x, detail::true_) { this->priv_create_and_insert_nodes(prev_pos, n, x); } template <class InIter> void priv_insert_after_range_dispatch(const_iterator prev_pos, InIter first, InIter last, detail::false_) { this->priv_create_and_insert_nodes(prev_pos, first, last); } //Functors for member algorithm defaults struct value_less { bool operator()(const value_type &a, const value_type &b) const { return a < b; } }; struct value_equal { bool operator()(const value_type &a, const value_type &b) const { return a == b; } }; struct value_equal_to_this { explicit value_equal_to_this(const value_type &ref) : m_ref(ref){} bool operator()(const value_type &val) const { return m_ref == val; } const value_type &m_ref; }; /// @endcond};template <class T, class A>inline bool operator==(const slist<T,A>& x, const slist<T,A>& y){ if(x.size() != y.size()){ return false; } typedef typename slist<T,A>::const_iterator const_iterator; const_iterator end1 = x.end(); const_iterator i1 = x.begin(); const_iterator i2 = y.begin(); while (i1 != end1 && *i1 == *i2){ ++i1; ++i2; } return i1 == end1;}template <class T, class A>inline booloperator<(const slist<T,A>& sL1, const slist<T,A>& sL2){ return std::lexicographical_compare (sL1.begin(), sL1.end(), sL2.begin(), sL2.end());}template <class T, class A>inline bool operator!=(const slist<T,A>& sL1, const slist<T,A>& sL2) { return !(sL1 == sL2); }template <class T, class A>inline bool operator>(const slist<T,A>& sL1, const slist<T,A>& sL2) { return sL2 < sL1; }template <class T, class A>inline bool operator<=(const slist<T,A>& sL1, const slist<T,A>& sL2) { return !(sL2 < sL1); }template <class T, class A>inline bool operator>=(const slist<T,A>& sL1, const slist<T,A>& sL2) { return !(sL1 < sL2); }#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCEtemplate <class T, class A>inline void swap(slist<T,A>& x, slist<T,A>& y) { x.swap(y); }template <class T, class A>inline void swap(const detail::moved_object<slist<T,A> >& x, slist<T,A>& y) { x.get().swap(y); }template <class T, class A>inline void swap(slist<T,A>& x, const detail::moved_object<slist<T,A> >& y) { x.swap(y.get()); }#elsetemplate <class T, class A>inline void swap(slist<T,A>&&x, slist<T,A>&&y) { x.swap(y); }#endif/// @cond//!This class is movabletemplate <class T, class A>struct is_movable<slist<T, A> >{ enum { value = true };};//!This class is movabletemplate <class A, class VoidPointer>struct is_movable<detail::slist_node<A, VoidPointer> >{ enum { value = true };};//!This class is movable/*template <class A>struct is_movable<detail::slist_alloc<A> >{ enum { value = true };};*///!has_trivial_destructor_after_move<> == true_type//!specialization for optimizationstemplate <class T, class A>struct has_trivial_destructor_after_move<slist<T, A> >{ enum { value = has_trivial_destructor<A>::value };};/// @endcond}} //namespace boost{ namespace interprocess{// Specialization of insert_iterator so that insertions will be constant// time rather than linear time.///@cond//Ummm, I don't like to define things in namespace std, but //there is no other waynamespace std {template <class T, class A>class insert_iterator<boost::interprocess::slist<T, A> > { protected: typedef boost::interprocess::slist<T, A> Container; Container* container; typename Container::iterator iter; public: typedef Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(Container& x, typename Container::iterator i, bool is_previous = false) : container(&x), iter(is_previous ? i : x.previous(i)){ } insert_iterator<Container>& operator=(const typename Container::value_type& value) { iter = container->insert_after(iter, value); return *this; } insert_iterator<Container>& operator*(){ return *this; } insert_iterator<Container>& operator++(){ return *this; } insert_iterator<Container>& operator++(int){ return *this; }};} //namespace std;///@endcond#include <boost/interprocess/detail/config_end.hpp>#endif /* BOOST_INTERPROCESS_SLIST_HPP */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?