stl_queue.h

Go to the documentation of this file.
00001 // Queue implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 /*
00027  *
00028  * Copyright (c) 1994
00029  * Hewlett-Packard Company
00030  *
00031  * Permission to use, copy, modify, distribute and sell this software
00032  * and its documentation for any purpose is hereby granted without fee,
00033  * provided that the above copyright notice appear in all copies and
00034  * that both that copyright notice and this permission notice appear
00035  * in supporting documentation.  Hewlett-Packard Company makes no
00036  * representations about the suitability of this software for any
00037  * purpose.  It is provided "as is" without express or implied warranty.
00038  *
00039  *
00040  * Copyright (c) 1996,1997
00041  * Silicon Graphics Computer Systems, Inc.
00042  *
00043  * Permission to use, copy, modify, distribute and sell this software
00044  * and its documentation for any purpose is hereby granted without fee,
00045  * provided that the above copyright notice appear in all copies and
00046  * that both that copyright notice and this permission notice appear
00047  * in supporting documentation.  Silicon Graphics makes no
00048  * representations about the suitability of this software for any
00049  * purpose.  It is provided "as is" without express or implied warranty.
00050  */
00051 
00052 /** @file stl_queue.h
00053  *  This is an internal header file, included by other library headers.
00054  *  You should not attempt to use it directly.
00055  */
00056 
00057 #ifndef _STL_QUEUE_H
00058 #define _STL_QUEUE_H 1
00059 
00060 #include <bits/concept_check.h>
00061 #include <debug/debug.h>
00062 
00063 _GLIBCXX_BEGIN_NAMESPACE(std)
00064 
00065   /**
00066    *  @brief  A standard container giving FIFO behavior.
00067    *
00068    *  @ingroup sequences
00069    *
00070    *  Meets many of the requirements of a
00071    *  <a href="tables.html#65">container</a>,
00072    *  but does not define anything to do with iterators.  Very few of the
00073    *  other standard container interfaces are defined.
00074    *
00075    *  This is not a true container, but an @e adaptor.  It holds another
00076    *  container, and provides a wrapper interface to that container.  The
00077    *  wrapper is what enforces strict first-in-first-out %queue behavior.
00078    *
00079    *  The second template parameter defines the type of the underlying
00080    *  sequence/container.  It defaults to std::deque, but it can be any type
00081    *  that supports @c front, @c back, @c push_back, and @c pop_front,
00082    *  such as std::list or an appropriate user-defined type.
00083    *
00084    *  Members not found in @a normal containers are @c container_type,
00085    *  which is a typedef for the second Sequence parameter, and @c push and
00086    *  @c pop, which are standard %queue/FIFO operations.
00087   */
00088   template<typename _Tp, typename _Sequence = deque<_Tp> >
00089     class queue
00090     {
00091       // concept requirements
00092       typedef typename _Sequence::value_type _Sequence_value_type;
00093       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
00094       __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept)
00095       __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)
00096       __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
00097 
00098       template<typename _Tp1, typename _Seq1>
00099         friend bool
00100         operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
00101 
00102       template<typename _Tp1, typename _Seq1>
00103         friend bool
00104         operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
00105 
00106     public:
00107       typedef typename _Sequence::value_type                value_type;
00108       typedef typename _Sequence::reference                 reference;
00109       typedef typename _Sequence::const_reference           const_reference;
00110       typedef typename _Sequence::size_type                 size_type;
00111       typedef          _Sequence                            container_type;
00112 
00113     protected:
00114       /**
00115        *  'c' is the underlying container.  Maintainers wondering why
00116        *  this isn't uglified as per style guidelines should note that
00117        *  this name is specified in the standard, [23.2.3.1].  (Why?
00118        *  Presumably for the same reason that it's protected instead
00119        *  of private: to allow derivation.  But none of the other
00120        *  containers allow for derivation.  Odd.)
00121        */
00122       _Sequence c;
00123 
00124     public:
00125       /**
00126        *  @brief  Default constructor creates no elements.
00127        */
00128 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00129       explicit
00130       queue(const _Sequence& __c = _Sequence())
00131       : c(__c) { }
00132 #else
00133       explicit
00134       queue(const _Sequence& __c)
00135       : c(__c) { }
00136 
00137       explicit
00138       queue(_Sequence&& __c = _Sequence())
00139       : c(std::move(__c)) { }
00140 #endif
00141 
00142       /**
00143        *  Returns true if the %queue is empty.
00144        */
00145       bool
00146       empty() const
00147       { return c.empty(); }
00148 
00149       /**  Returns the number of elements in the %queue.  */
00150       size_type
00151       size() const
00152       { return c.size(); }
00153 
00154       /**
00155        *  Returns a read/write reference to the data at the first
00156        *  element of the %queue.
00157        */
00158       reference
00159       front()
00160       {
00161     __glibcxx_requires_nonempty();
00162     return c.front();
00163       }
00164 
00165       /**
00166        *  Returns a read-only (constant) reference to the data at the first
00167        *  element of the %queue.
00168        */
00169       const_reference
00170       front() const
00171       {
00172     __glibcxx_requires_nonempty();
00173     return c.front();
00174       }
00175 
00176       /**
00177        *  Returns a read/write reference to the data at the last
00178        *  element of the %queue.
00179        */
00180       reference
00181       back()
00182       {
00183     __glibcxx_requires_nonempty();
00184     return c.back();
00185       }
00186 
00187       /**
00188        *  Returns a read-only (constant) reference to the data at the last
00189        *  element of the %queue.
00190        */
00191       const_reference
00192       back() const
00193       {
00194     __glibcxx_requires_nonempty();
00195     return c.back();
00196       }
00197 
00198       /**
00199        *  @brief  Add data to the end of the %queue.
00200        *  @param  x  Data to be added.
00201        *
00202        *  This is a typical %queue operation.  The function creates an
00203        *  element at the end of the %queue and assigns the given data
00204        *  to it.  The time complexity of the operation depends on the
00205        *  underlying sequence.
00206        */
00207       void
00208       push(const value_type& __x)
00209       { c.push_back(__x); }
00210 
00211 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00212       void
00213       push(value_type&& __x)
00214       { c.push_back(std::move(__x)); }
00215 
00216       template<typename... _Args>
00217         void
00218         emplace(_Args&&... __args)
00219     { c.emplace_back(std::forward<_Args>(__args)...); }
00220 #endif
00221 
00222       /**
00223        *  @brief  Removes first element.
00224        *
00225        *  This is a typical %queue operation.  It shrinks the %queue by one.
00226        *  The time complexity of the operation depends on the underlying
00227        *  sequence.
00228        *
00229        *  Note that no data is returned, and if the first element's
00230        *  data is needed, it should be retrieved before pop() is
00231        *  called.
00232        */
00233       void
00234       pop()
00235       {
00236     __glibcxx_requires_nonempty();
00237     c.pop_front();
00238       }
00239 
00240 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00241       void
00242       swap(queue& __q)
00243       { c.swap(__q.c); }
00244 #endif
00245     };
00246 
00247   /**
00248    *  @brief  Queue equality comparison.
00249    *  @param  x  A %queue.
00250    *  @param  y  A %queue of the same type as @a x.
00251    *  @return  True iff the size and elements of the queues are equal.
00252    *
00253    *  This is an equivalence relation.  Complexity and semantics depend on the
00254    *  underlying sequence type, but the expected rules are:  this relation is
00255    *  linear in the size of the sequences, and queues are considered equivalent
00256    *  if their sequences compare equal.
00257   */
00258   template<typename _Tp, typename _Seq>
00259     inline bool
00260     operator==(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
00261     { return __x.c == __y.c; }
00262 
00263   /**
00264    *  @brief  Queue ordering relation.
00265    *  @param  x  A %queue.
00266    *  @param  y  A %queue of the same type as @a x.
00267    *  @return  True iff @a x is lexicographically less than @a y.
00268    *
00269    *  This is an total ordering relation.  Complexity and semantics
00270    *  depend on the underlying sequence type, but the expected rules
00271    *  are: this relation is linear in the size of the sequences, the
00272    *  elements must be comparable with @c <, and
00273    *  std::lexicographical_compare() is usually used to make the
00274    *  determination.
00275   */
00276   template<typename _Tp, typename _Seq>
00277     inline bool
00278     operator<(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
00279     { return __x.c < __y.c; }
00280 
00281   /// Based on operator==
00282   template<typename _Tp, typename _Seq>
00283     inline bool
00284     operator!=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
00285     { return !(__x == __y); }
00286 
00287   /// Based on operator<
00288   template<typename _Tp, typename _Seq>
00289     inline bool
00290     operator>(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
00291     { return __y < __x; }
00292 
00293   /// Based on operator<
00294   template<typename _Tp, typename _Seq>
00295     inline bool
00296     operator<=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
00297     { return !(__y < __x); }
00298 
00299   /// Based on operator<
00300   template<typename _Tp, typename _Seq>
00301     inline bool
00302     operator>=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
00303     { return !(__x < __y); }
00304 
00305 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00306   template<typename _Tp, typename _Seq>
00307     inline void
00308     swap(queue<_Tp, _Seq>& __x, queue<_Tp, _Seq>& __y)
00309     { __x.swap(__y); }
00310 
00311   template<typename _Tp, typename _Seq, typename _Alloc>
00312     struct uses_allocator<queue<_Tp, _Seq>, _Alloc>
00313     : public uses_allocator<_Seq, _Alloc>::type { };
00314 #endif
00315 
00316   /**
00317    *  @brief  A standard container automatically sorting its contents.
00318    *
00319    *  @ingroup sequences
00320    *
00321    *  This is not a true container, but an @e adaptor.  It holds
00322    *  another container, and provides a wrapper interface to that
00323    *  container.  The wrapper is what enforces priority-based sorting 
00324    *  and %queue behavior.  Very few of the standard container/sequence
00325    *  interface requirements are met (e.g., iterators).
00326    *
00327    *  The second template parameter defines the type of the underlying
00328    *  sequence/container.  It defaults to std::vector, but it can be
00329    *  any type that supports @c front(), @c push_back, @c pop_back,
00330    *  and random-access iterators, such as std::deque or an
00331    *  appropriate user-defined type.
00332    *
00333    *  The third template parameter supplies the means of making
00334    *  priority comparisons.  It defaults to @c less<value_type> but
00335    *  can be anything defining a strict weak ordering.
00336    *
00337    *  Members not found in @a normal containers are @c container_type,
00338    *  which is a typedef for the second Sequence parameter, and @c
00339    *  push, @c pop, and @c top, which are standard %queue operations.
00340    *
00341    *  @note No equality/comparison operators are provided for
00342    *  %priority_queue.
00343    *
00344    *  @note Sorting of the elements takes place as they are added to,
00345    *  and removed from, the %priority_queue using the
00346    *  %priority_queue's member functions.  If you access the elements
00347    *  by other means, and change their data such that the sorting
00348    *  order would be different, the %priority_queue will not re-sort
00349    *  the elements for you.  (How could it know to do so?)
00350   */
00351   template<typename _Tp, typename _Sequence = vector<_Tp>,
00352        typename _Compare  = less<typename _Sequence::value_type> >
00353     class priority_queue
00354     {
00355       // concept requirements
00356       typedef typename _Sequence::value_type _Sequence_value_type;
00357       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
00358       __glibcxx_class_requires(_Sequence, _SequenceConcept)
00359       __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept)
00360       __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
00361       __glibcxx_class_requires4(_Compare, bool, _Tp, _Tp,
00362                 _BinaryFunctionConcept)
00363 
00364     public:
00365       typedef typename _Sequence::value_type                value_type;
00366       typedef typename _Sequence::reference                 reference;
00367       typedef typename _Sequence::const_reference           const_reference;
00368       typedef typename _Sequence::size_type                 size_type;
00369       typedef          _Sequence                            container_type;
00370 
00371     protected:
00372       //  See queue::c for notes on these names.
00373       _Sequence  c;
00374       _Compare   comp;
00375 
00376     public:
00377       /**
00378        *  @brief  Default constructor creates no elements.
00379        */
00380 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00381       explicit
00382       priority_queue(const _Compare& __x = _Compare(),
00383              const _Sequence& __s = _Sequence())
00384       : c(__s), comp(__x)
00385       { std::make_heap(c.begin(), c.end(), comp); }
00386 #else
00387       explicit
00388       priority_queue(const _Compare& __x,
00389              const _Sequence& __s)
00390       : c(__s), comp(__x)
00391       { std::make_heap(c.begin(), c.end(), comp); }
00392 
00393       explicit
00394       priority_queue(const _Compare& __x = _Compare(),
00395              _Sequence&& __s = _Sequence())
00396       : c(std::move(__s)), comp(__x)
00397       { std::make_heap(c.begin(), c.end(), comp); }
00398 #endif
00399 
00400       /**
00401        *  @brief  Builds a %queue from a range.
00402        *  @param  first  An input iterator.
00403        *  @param  last  An input iterator.
00404        *  @param  x  A comparison functor describing a strict weak ordering.
00405        *  @param  s  An initial sequence with which to start.
00406        *
00407        *  Begins by copying @a s, inserting a copy of the elements
00408        *  from @a [first,last) into the copy of @a s, then ordering
00409        *  the copy according to @a x.
00410        *
00411        *  For more information on function objects, see the
00412        *  documentation on @link functors functor base
00413        *  classes@endlink.
00414        */
00415 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00416       template<typename _InputIterator>
00417         priority_queue(_InputIterator __first, _InputIterator __last,
00418                const _Compare& __x = _Compare(),
00419                const _Sequence& __s = _Sequence())
00420     : c(__s), comp(__x)
00421         {
00422       __glibcxx_requires_valid_range(__first, __last);
00423       c.insert(c.end(), __first, __last);
00424       std::make_heap(c.begin(), c.end(), comp);
00425     }
00426 #else
00427       template<typename _InputIterator>
00428         priority_queue(_InputIterator __first, _InputIterator __last,
00429                const _Compare& __x,
00430                const _Sequence& __s)
00431     : c(__s), comp(__x)
00432         {
00433       __glibcxx_requires_valid_range(__first, __last);
00434       c.insert(c.end(), __first, __last);
00435       std::make_heap(c.begin(), c.end(), comp);
00436     }
00437 
00438       template<typename _InputIterator>
00439         priority_queue(_InputIterator __first, _InputIterator __last,
00440                const _Compare& __x = _Compare(),
00441                _Sequence&& __s = _Sequence())
00442     : c(std::move(__s)), comp(__x)
00443         {
00444       __glibcxx_requires_valid_range(__first, __last);
00445       c.insert(c.end(), __first, __last);
00446       std::make_heap(c.begin(), c.end(), comp);
00447     }
00448 #endif
00449 
00450       /**
00451        *  Returns true if the %queue is empty.
00452        */
00453       bool
00454       empty() const
00455       { return c.empty(); }
00456 
00457       /**  Returns the number of elements in the %queue.  */
00458       size_type
00459       size() const
00460       { return c.size(); }
00461 
00462       /**
00463        *  Returns a read-only (constant) reference to the data at the first
00464        *  element of the %queue.
00465        */
00466       const_reference
00467       top() const
00468       {
00469     __glibcxx_requires_nonempty();
00470     return c.front();
00471       }
00472 
00473       /**
00474        *  @brief  Add data to the %queue.
00475        *  @param  x  Data to be added.
00476        *
00477        *  This is a typical %queue operation.
00478        *  The time complexity of the operation depends on the underlying
00479        *  sequence.
00480        */
00481       void
00482       push(const value_type& __x)
00483       {
00484     c.push_back(__x);
00485     std::push_heap(c.begin(), c.end(), comp);
00486       }
00487 
00488 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00489       void
00490       push(value_type&& __x)
00491       {
00492     c.push_back(std::move(__x));
00493     std::push_heap(c.begin(), c.end(), comp);
00494       }
00495 
00496       template<typename... _Args>
00497         void
00498         emplace(_Args&&... __args)
00499     {
00500       c.emplace_back(std::forward<_Args>(__args)...);
00501       std::push_heap(c.begin(), c.end(), comp);
00502     }
00503 #endif
00504 
00505       /**
00506        *  @brief  Removes first element.
00507        *
00508        *  This is a typical %queue operation.  It shrinks the %queue
00509        *  by one.  The time complexity of the operation depends on the
00510        *  underlying sequence.
00511        *
00512        *  Note that no data is returned, and if the first element's
00513        *  data is needed, it should be retrieved before pop() is
00514        *  called.
00515        */
00516       void
00517       pop()
00518       {
00519     __glibcxx_requires_nonempty();
00520     std::pop_heap(c.begin(), c.end(), comp);
00521     c.pop_back();
00522       }
00523 
00524 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00525       void
00526       swap(priority_queue& __pq)
00527       {
00528     using std::swap;
00529     c.swap(__pq.c);
00530     swap(comp, __pq.comp);
00531       }
00532 #endif
00533     };
00534 
00535   // No equality/comparison operators are provided for priority_queue.
00536 
00537 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00538   template<typename _Tp, typename _Sequence, typename _Compare>
00539     inline void
00540     swap(priority_queue<_Tp, _Sequence, _Compare>& __x,
00541      priority_queue<_Tp, _Sequence, _Compare>& __y)
00542     { __x.swap(__y); }
00543 
00544   template<typename _Tp, typename _Sequence, typename _Compare,
00545        typename _Alloc>
00546     struct uses_allocator<priority_queue<_Tp, _Sequence, _Compare>, _Alloc>
00547     : public uses_allocator<_Sequence, _Alloc>::type { };
00548 #endif
00549 
00550 _GLIBCXX_END_NAMESPACE
00551 
00552 #endif /* _STL_QUEUE_H */