BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_stack.h
Go to the documentation of this file.
1/// @file bslstl_stack.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_stack.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_STACK
9#define INCLUDED_BSLSTL_STACK
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_stack bslstl_stack
15/// @brief Provide an STL-compliant stack class.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_stack
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_stack-purpose"> Purpose</a>
25/// * <a href="#bslstl_stack-classes"> Classes </a>
26/// * <a href="#bslstl_stack-description"> Description </a>
27/// * <a href="#bslstl_stack-requirements-on-container"> Requirements on CONTAINER </a>
28/// * <a href="#bslstl_stack-required-types"> Required Types </a>
29/// * <a href="#bslstl_stack-required-methods-free-operators-and-free-functions"> Required Methods, Free Operators, and Free Functions </a>
30/// * <a href="#bslstl_stack-requirements-on-value"> Requirements on VALUE </a>
31/// * <a href="#bslstl_stack-value-and-container-value_type"> VALUE and CONTAINER::value_type </a>
32/// * <a href="#bslstl_stack-memory-allocation"> Memory Allocation </a>
33/// * <a href="#bslstl_stack-bslma-style-allocators"> bslma-Style Allocators </a>
34/// * <a href="#bslstl_stack-operations"> Operations </a>
35/// * <a href="#bslstl_stack-usage"> Usage </a>
36/// * <a href="#bslstl_stack-example-1-household-chores-to-do-list"> Example 1: Household Chores To Do List </a>
37///
38/// # Purpose {#bslstl_stack-purpose}
39/// Provide an STL-compliant stack class.
40///
41/// # Classes {#bslstl_stack-classes}
42///
43/// - bsl::stack: STL-compliant stack template
44///
45/// **Canonical header:** bsl_stack.h
46///
47/// @see bslstl_deque, bslstl_vector, bslstl_list, bslstl_queue,
48/// bslstl_priorityqueue
49///
50/// # Description {#bslstl_stack-description}
51/// This component defines a single class template, `bsl::stack`,
52/// a container adapter that takes an underlying container and provides a stack
53/// interface which the user accesses primarily through `push`, `pop`, and `top`
54/// operations. A `deque` (the default), `vector`, or `list` may be used, but
55/// any container which supports `push_back`, @ref pop_back , `back`, and `size`,
56/// plus a template specialization `uses_allocator::type`, may be used.
57///
58/// A stack meets the requirements of a container adaptor as described in the
59/// C++ standard [stack]. The `stack` implemented here adheres to the C++11
60/// standard when compiled with a C++11 compiler, and makes the best
61/// approximation when compiled with a C++03 compiler. In particular, for C++03
62/// we emulate move semantics, but limit forwarding (in `emplace`) to `const`
63/// lvalues, and make no effort to emulate `noexcept` or initializer-lists.
64///
65/// ## Requirements on CONTAINER {#bslstl_stack-requirements-on-container}
66///
67///
68/// The `bsl::stack` adapter can accept for its (optional) `CONTAINER` template
69/// parameter `bsl::deque` (the default), `bsl::vector`, `bsl::list`, or other
70/// container classes that support the following types and methods.
71///
72/// ### Required Types {#bslstl_stack-required-types}
73///
74///
75/// * `value_type`
76/// * `reference`
77/// * @ref const_reference
78/// * `size_type`
79/// * `allocator_type` (if any `stack` constructor taking an allocator is used)
80///
81/// ### Required Methods, Free Operators, and Free Functions {#bslstl_stack-required-methods-free-operators-and-free-functions}
82///
83///
84/// * `void push_back(const value_type&)` (and variant taking rvalue reference)
85/// * `void pop_back()`
86/// * `reference back()`
87/// * `size_type size() const`
88/// * `const_reference back() const`
89/// * @ref emplace_back
90/// * copy-assignment and move-assignment operators
91/// * free `==`, `!=`, `<`, `>`, `<=`, `>=` operators
92/// * free `swap` function (found via ADL with `std::swap` in the lookup set)
93///
94/// ## Requirements on VALUE {#bslstl_stack-requirements-on-value}
95///
96///
97/// The following term is used to more precisely specify the requirements on
98/// template parameter types in function-level documentation:
99///
100/// *equality-comparable*:
101/// The type provides an equality-comparison operator that defines an
102/// equivalence relationship and is both reflexive and transitive.
103///
104/// ### VALUE and CONTAINER::value_type {#bslstl_stack-value-and-container-value_type}
105///
106///
107/// When the `CONTAINER` template parameter is omitted the `VALUE` template
108/// parameter specifies the `value_type` of `bsl::vector`, the default container
109/// type. The `VALUE` template has no other role.
110///
111/// For C++17 and later, the behavior is undefined unless:
112/// @code
113/// true == bsl::is_same<VALUE, typename CONTAINER::value_type>::value
114/// @endcode
115/// Prior to C++17, `CONTAINER::value_type` determines the contained value type
116/// and `VALUE` is simply ignored. The resulting code may work with instances
117/// of `VALUE` (e.g., `VALUE` is convertible to `CONTAINER::value_type`) or not
118/// (compiler errors).
119///
120/// ## Memory Allocation {#bslstl_stack-memory-allocation}
121///
122///
123/// No memory allocator template arg is directly supplied to this class, the
124/// allocator type used is the allocator specified for the container class.
125/// Some functions of this template only exist if type
126/// `CONTAINER::allocator_type` exists, and if it does exist it is assumed to be
127/// the allocator type used by `CONTAINER`, and that `CONTAINER` supports
128/// constructors of this type.
129///
130/// ## bslma-Style Allocators {#bslstl_stack-bslma-style-allocators}
131///
132///
133/// The constructors of this class take, as optional parameters, allocators of
134/// the object's parameterized `CONTAINER::allocator_type` type, and allocators
135/// of this type are propagated to all constructors of the underlying container.
136/// In the case of container types `bsl::deque` (the default type),
137/// `bsl::vector`, and `bsl::list`, `CONTAINER::allocator_type` is
138/// `bsl::allocator` which is implicitly convertible from `bslma::Allocator *`,
139/// and which can be converted to a `bslma::Allocator *` through the `mechanism`
140/// accessor.
141///
142/// Hence if the underlying container takes `bsl::allocator`, then the `stack`
143/// object can take `bslma::Allocator *`s to supply memory allocation. If no
144/// allocator is specified, `allocator()` is used, which winds up using
145/// `bslma::Default::allocator(0)`.
146///
147/// ## Operations {#bslstl_stack-operations}
148///
149///
150/// Below is a list of public methods of the `bsl::stack` class that effectively
151/// forward their implementations to corresponding operations in the held
152/// container (referenced as `c`) which is here assumed to be either
153/// `bsl::deque`, or `bsl::vector`, or `bsl::list`.
154/// @code
155/// Legend
156/// ------
157/// 'C' - (template parameter) type 'CONTAINER' of the stack
158/// 'V' - (template parameter) type 'VALUE' of the stack
159/// 's', 't' - two distinct objects of type 'stack<V, C>'
160///
161/// 'nc' - number of elements in container 'c'
162/// 'n', 'm' - number of elements in 's' and 't', respectively
163/// 'al' - STL-style memory allocator
164/// 'v' - an object of type 'V'
165///
166/// +----------------------------------------------------+--------------------+
167/// | Note: the following estimations of operation complexity assume the |
168/// | underlying container is a 'bsl::deque', 'bsl::vector', or 'bsl::list'. |
169/// +----------------------------------------------------+--------------------+
170/// | Operation | Complexity |
171/// +====================================================+====================+
172/// | stack<V, C> s; (default construction) | O(1) |
173/// | stack<V, C> s(al); | |
174/// +----------------------------------------------------+--------------------+
175/// | stack<V, C> s(c); | O(nc) |
176/// | stack<V, C> s(c, al); | |
177/// +----------------------------------------------------+--------------------+
178/// | stack<V, C> s(t); | O(n) |
179/// | stack<V, C> s(t, al); | |
180/// +----------------------------------------------------+--------------------+
181/// | s.~stack(V, C>(); (destruction) | O(n) |
182/// +----------------------------------------------------+--------------------+
183/// | s = t; (assignment) | O(n) |
184/// +----------------------------------------------------+--------------------+
185/// | s.push(v) | O(1) |
186/// +----------------------------------------------------+--------------------+
187/// | s.pop() | O(1) |
188/// +----------------------------------------------------+--------------------+
189/// | s.top() | O(1) |
190/// +----------------------------------------------------+--------------------+
191/// | s == t, s != t | O(n) |
192/// +---------------------------------------------------+--------------------+
193/// | s < t, s <= t, s > t, s >= t | O(n) |
194/// +----------------------------------------------------+--------------------+
195/// | s.swap(t), swap(s,t) | depends on the |
196/// | | container; for |
197/// | | deque, vector, and |
198/// | | list: |
199/// | | O(1) if 's' and |
200/// | | 't' use the same |
201/// | | allocator, |
202/// | | O(n + m) otherwise |
203/// +----------------------------------------------------+--------------------+
204/// | s.size() | O(1) if 'C' is |
205/// | | deque or vector |
206/// +----------------------------------------------------+--------------------+
207/// | s.empty() | O(1) |
208/// +----------------------------------------------------+--------------------+
209/// @endcode
210///
211/// ## Usage {#bslstl_stack-usage}
212///
213///
214/// In this section we show intended use of this component.
215///
216/// ### Example 1: Household Chores To Do List {#bslstl_stack-example-1-household-chores-to-do-list}
217///
218///
219/// Suppose someone wants to keep track of chores their partner has asked them
220/// to do. Over the years, they have noticed that their partner generally wants
221/// the most recently requested task done first. If the partner has a new task
222/// in mind that is low-priority, they will avoid asking for it until higher
223/// priority tasks are finished. When they have finished all tasks, they report
224/// to their partner that they are ready for more.
225///
226/// First, we define the class implementing the to-do list.
227/// @code
228/// class ToDoList {
229/// // DATA
230/// bsl::stack<const char *> d_stack;
231///
232/// public:
233/// // MANIPULATORS
234///
235/// /// Add the specified `task`, a string describing a task, to the
236/// /// list. Note the lifetime of the string referred to by `task`
237/// /// must exceed the lifetime of the task in this list.
238/// void enqueueTask(const char *task);
239///
240/// /// Remove the current task from the list. Return `true` if a task
241/// /// was removed and it was the last task on the list, and return
242/// /// `false` otherwise.
243/// bool finishTask();
244///
245/// // ACCESSORS
246///
247/// /// Return the string representing the current task. If there
248/// /// is no current task, return the string "<EMPTY>", which is
249/// /// not a valid task.
250/// const char *currentTask() const;
251/// };
252///
253/// // MANIPULATORS
254/// void ToDoList::enqueueTask(const char *task)
255/// {
256/// d_stack.push(task);
257/// }
258///
259/// bool ToDoList::finishTask()
260/// {
261/// if (!d_stack.empty()) {
262/// d_stack.pop();
263///
264/// return d_stack.empty();
265/// }
266///
267/// return false;
268/// };
269///
270/// // ACCESSORS
271/// const char *ToDoList::currentTask() const
272/// {
273/// if (d_stack.empty()) {
274/// return "<EMPTY>";
275/// }
276///
277/// return d_stack.top();
278/// }
279/// @endcode
280/// Then, create an object of type `ToDoList`.
281/// @code
282/// ToDoList toDoList;
283/// @endcode
284/// Next, a few tasks are requested:
285/// @code
286/// toDoList.enqueueTask("Change the car's oil.");
287/// toDoList.enqueueTask("Pay the bills.");
288/// @endcode
289/// Then, they watch the Yankee's game on TV. Upon returning to the list they
290/// consult the list to see what task is up next:
291/// @code
292/// assert(!strcmp("Pay the bills.", toDoList.currentTask()));
293/// @endcode
294/// Next, they see that they have to pay the bills. When the bills are
295/// finished, they flush that task from the list:
296/// @code
297/// assert(false == toDoList.finishTask());
298/// @endcode
299/// Then, they consult the list for the next task.
300/// @code
301/// assert(!strcmp("Change the car's oil.", toDoList.currentTask()));
302/// @endcode
303/// Next, they see that they have to change the car's oil. Before they can get
304/// started, another request comes in:
305/// @code
306/// toDoList.enqueueTask("Get some hot dogs.");
307/// assert(!strcmp("Get some hot dogs.", toDoList.currentTask()));
308/// @endcode
309/// Then, they drive the car to the convenience store and picks up some hot dogs
310/// and buns. Upon returning home, they give the hot dogs to their partner,
311/// update the list, and consult it for the next task.
312/// @code
313/// assert(false == toDoList.finishTask());
314/// assert(!strcmp("Change the car's oil.", toDoList.currentTask()));
315/// @endcode
316/// Next, they finish the oil change, update the list, and consult it for the
317/// next task.
318/// @code
319/// assert(true == toDoList.finishTask());
320/// assert(!strcmp("<EMPTY>", toDoList.currentTask()));
321/// @endcode
322/// Finally, their partner has now been informed that everything is done, and
323/// they make another request:
324/// @code
325/// toDoList.enqueueTask("Clean the rain gutters.");
326/// @endcode
327/// @}
328/** @} */
329/** @} */
330
331/** @addtogroup bsl
332 * @{
333 */
334/** @addtogroup bslstl
335 * @{
336 */
337/** @addtogroup bslstl_stack
338 * @{
339 */
340
341#include <bslscm_version.h>
342
343#include <bslstl_compare.h>
344#include <bslstl_deque.h>
345
346#include <bslalg_swaputil.h>
347
349#include <bslma_isstdallocator.h>
350
351#include <bslmf_assert.h>
352#include <bslmf_enableif.h>
353#include <bslmf_isconvertible.h>
354#include <bslmf_issame.h>
355#include <bslmf_movableref.h>
357#include <bslmf_usesallocator.h>
358#include <bslmf_util.h> // 'forward(V)'
359
361#include <bsls_keyword.h>
362#include <bsls_libraryfeatures.h>
363#include <bsls_platform.h>
364#include <bsls_util.h> // 'forward<T>(V)'
365
366#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
367// Include version that can be compiled with C++03
368// Generated on Thu Oct 21 10:11:37 2021
369// Command line: sim_cpp11_features.pl bslstl_stack.h
370# define COMPILING_BSLSTL_STACK_H
371# include <bslstl_stack_cpp03.h>
372# undef COMPILING_BSLSTL_STACK_H
373#else
374
375namespace bsl {
376
377 // ===========
378 // class stack
379 // ===========
380
381/// This `class` defines a container adapter which supports access primarily
382/// via `push`, `pop`, and `top`. This type can be based on a variety of
383/// other container types, including `deque`, `vector`, and `list`. This
384/// type is value-semantic if the supporting `CONTAINER` and `VALUE` are
385/// value-semantic.
386///
387/// Note that we never use `VALUE` in the implementation except in the
388/// default argument of `CONTAINER`. We use `CONTAINER::value_type` for
389/// everything, which means that if `CONTAINER` is specified, then `VALUE`
390/// is ignored.
391///
392/// See @ref bslstl_stack
393template <class VALUE, class CONTAINER = deque<VALUE> >
394class stack {
395
396#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
397 // STATIC CHECK: Type mismatch is UB per C++17
399#endif
400
401 private:
402 // PRIVATE TYPES
403
404 /// This `typedef` is a convenient alias for the utility associated with
405 /// movable references.
406 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
407
408 public:
409 // PUBLIC TYPES
410 typedef typename CONTAINER::value_type value_type;
411 typedef typename CONTAINER::reference reference;
412 typedef typename CONTAINER::const_reference const_reference;
413 typedef typename CONTAINER::size_type size_type;
414 typedef CONTAINER container_type;
415
416
417 protected:
418 // PROTECTED DATA
419 container_type c; // We are required by the standard to have the
420 // container be a protected variable named 'c'.
421
422 private:
423 // FRIENDS
424 template <class VAL, class CONT>
425 friend bool operator==(const stack<VAL, CONT>&, const stack<VAL, CONT>&);
426 template <class VAL, class CONT>
427 friend bool operator!=(const stack<VAL, CONT>&, const stack<VAL, CONT>&);
428 template <class VAL, class CONT>
429 friend bool operator< (const stack<VAL, CONT>&, const stack<VAL, CONT>&);
430 template <class VAL, class CONT>
431 friend bool operator> (const stack<VAL, CONT>&, const stack<VAL, CONT>&);
432 template <class VAL, class CONT>
433 friend bool operator<=(const stack<VAL, CONT>&, const stack<VAL, CONT>&);
434 template <class VAL, class CONT>
435 friend bool operator>=(const stack<VAL, CONT>&, const stack<VAL, CONT>&);
436#if defined BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON \
437 && defined BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
438 template <class VAL, three_way_comparable CONT>
439 friend compare_three_way_result_t<CONT>
440 operator<=>(const stack<VAL, CONT>&, const stack<VAL, CONT>&);
441#endif
442
443 public:
444 // TRAITS
446 stack,
447 BloombergLP::bslma::UsesBslmaAllocator,
448 BloombergLP::bslma::UsesBslmaAllocator<container_type>::value);
449
450 // CREATORS
451
452 /// Create an empty stack. No allocator will be provided to the
453 /// underlying container. That container's memory allocation will be
454 /// provided by the default allocator of its type.
455 explicit stack();
456
457 /// Create a stack having the value of the specified `original`. The
458 /// currently installed default allocator is used to supply memory.
459 stack(const stack& original);
460
461 /// Create a stack having the value of the specified `original` by
462 /// moving the contents of `original` to the new stack. The allocator
463 /// associated with `original` is propagated for use in the new stack.
464 /// `original` is left in a valid but unspecified state.
465 stack(BloombergLP::bslmf::MovableRef<stack> original);
466
467 /// Create a stack whose underlying container has the value of the
468 /// specified `container`. The currently installed default allocator is
469 /// used to supply memory.
470 explicit
471 stack(const CONTAINER& container);
472
473 /// Create a stack whose underlying container has the value of the
474 /// specified `container` (on entry) by moving the contents of
475 /// `container` to the new stack. The allocator associated with
476 /// `container` is propagated for use in the new stack. `container` is
477 /// left in a valid but unspecified state.
478 explicit
479 stack(BloombergLP::bslmf::MovableRef<CONTAINER> container);
480
481 /// Create an empty stack, and use the specified `basicAllocator` to
482 /// supply memory. If `CONTAINER::allocator_type` does not exist, this
483 /// constructor may not be used.
484 template <class ALLOCATOR>
485 explicit
486 stack(const ALLOCATOR& basicAllocator,
488 ALLOCATOR>::type * = 0);
489
490 /// Create a stack whose underlying container has the value of the
491 /// specified `container`, and use the specified `basicAllocator` to
492 /// supply memory. If `CONTAINER::allocator_type` does not exist, this
493 /// constructor may not be used.
494 template <class ALLOCATOR>
495 stack(const CONTAINER& container,
496 const ALLOCATOR& basicAllocator,
498 ALLOCATOR>::type * = 0);
499
500 /// Create a stack having the value of the specified stack `original`
501 /// and use the specified `basicAllocator` to supply memory. If
502 /// `CONTAINER::allocator_type` does not exist, this constructor may not
503 /// be used.
504 template <class ALLOCATOR>
505 stack(const stack& original,
506 const ALLOCATOR& basicAllocator,
508 ALLOCATOR>::type * = 0);
509
510 /// Create a stack whose underlying container has the value of the
511 /// specified `container` (on entry) that uses `basicAllocator` to
512 /// supply memory by using the allocator-extended move constructor of
513 /// `CONTAINER. `container' is left in a valid but unspecified state.
514 /// A `bslma::Allocator *` can be supplied for `basicAllocator` if the
515 /// (template parameter) `ALLOCATOR` is `bsl::allocator` (the default).
516 /// This method assumes that `CONTAINER` has a move constructor. If
517 /// `CONTAINER::allocator_type` does not exist, this constructor may not
518 /// be used.
519 template <class ALLOCATOR>
520 stack(BloombergLP::bslmf::MovableRef<CONTAINER> container,
521 const ALLOCATOR& basicAllocator,
523 ALLOCATOR>::type * = 0);
524
525 /// Create a stack having the value of the specified `original` (on
526 /// entry) that uses `basicAllocator` to supply memory by using the
527 /// allocator-extended moved constructor of `CONTAINER`. `original` is
528 /// left in a valid but unspecified state. Note that a
529 /// `bslma::Allocator *` can be supplied for `basicAllocator` if the
530 /// (template parameter) `ALLOCATOR` is `bsl::allocator` (the default).
531 /// Also note that this method assumes that `CONTAINER` has a move
532 /// constructor. Also note that if `CONTAINER::allocator_type` does not
533 /// exist, this constructor may not be used.
534 template <class ALLOCATOR>
535 stack(BloombergLP::bslmf::MovableRef<stack> original,
536 const ALLOCATOR& basicAllocator,
538 ALLOCATOR>::type * = 0);
539
540 // MANIPULATORS
541
542 /// Assign to this object the value of the specified `rhs` object, and
543 /// return a reference providing modifiable access to this object.
544 stack& operator=(const stack& rhs);
545
546 /// Assign to this object the value of the specified `rhs` object, and
547 /// return a reference providing modifiable access to this object. The
548 /// contents of `rhs` are moved to this stack using the move-assignment
549 /// operator of `CONTAINER`. `rhs` is left in a valid but unspecified
550 /// state, and if an exception is thrown, `*this` is left in a valid but
551 /// unspecified state.
552 stack& operator=(BloombergLP::bslmf::MovableRef<stack> rhs)
554
555#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
556 /// Push onto this stack a newly created `value_type` object constructed
557 /// by forwarding `get_allocator()` (if required) and the specified
558 /// (variable number of) `args` to the corresponding constructor of
559 /// `value_type`. Return a reference providing modifiable access to the
560 /// inserted element.
561 template <class... Args>
562 reference emplace(Args&&... args);
563
564#endif
565
566 /// Remove the top element from this stack. The behavior is undefined
567 /// if this stack is empty.
568 void pop();
569
570 /// Push the specified `value` onto the top of this stack.
571 void push(const value_type& value);
572
573 /// Push onto this stack a `value_type` object having the value of the
574 /// specified `value` (on entry) by moving the contents of `value` to
575 /// the new object on this stack. `value` is left in a valid but
576 /// unspecified state.
577 void push(BloombergLP::bslmf::MovableRef<value_type> value);
578
579 /// Exchange the value of this stack with the value of the specified
580 /// `other` stack.
582 bsl::is_nothrow_swappable<CONTAINER>::value);
583
584 /// Return a reference to the element at the top of this stack. The
585 /// behavior is undefined if this stack is empty.
587
588 // ACCESSORS
589
590 /// Return `true` if this stack contains no elements and `false`
591 /// otherwise.
592 bool empty() const;
593
594 /// Return the number of elements contained in this stack.
595 size_type size() const;
596
597 /// Return a reference providing non-modifiable access to the element at
598 /// the top of this stack. The behavior is undefined if the stack is
599 /// empty.
601};
602
603#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
604// CLASS TEMPLATE DEDUCTION GUIDES
605
606/// Deduce the template parameters `VALUE` and `CONTAINER` from the
607/// parameters supplied to the constructor of `stack`. This deduction guide
608/// does not participate if the parameter meets the requirements for a
609/// standard allocator.
610template<class CONTAINER,
611 class = bsl::enable_if_t<!bsl::IsStdAllocator_v<CONTAINER>>
612 >
614
615/// Deduce the template parameters `VALUE` and `CONTAINER` from the
616/// parameters supplied to the constructor of `stack`. This deduction
617/// guide does not participate unless the supplied allocator is convertible
618/// to the underlying container's `allocator_type`.
619template<
620 class CONTAINER,
621 class ALLOCATOR,
622 class = bsl::enable_if_t<bsl::uses_allocator_v<CONTAINER, ALLOCATOR>>
623 >
625#endif
626
627// FREE OPERATORS
628
629/// Return `true` if the specified `lhs` and `rhs` objects have the same
630/// value, and `false` otherwise. Two `stack` objects `lhs` and `rhs` have
631/// the same value if they have the same number of elements, and each
632/// element in the ordered sequence of elements of `lhs` has the same value
633/// as the corresponding element in the ordered sequence of elements of
634/// `rhs`. This method requires that the (template parameter) type `VALUE`
635/// be `equality-comparable` (see {Requirements on `VALUE`}).
636template <class VALUE, class CONTAINER>
637bool operator==(const stack<VALUE, CONTAINER>& lhs,
638 const stack<VALUE, CONTAINER>& rhs);
639
640/// Return `true` if the specified `lhs` and `rhs` objects do not have the
641/// same value, and `false` otherwise. Two `stack` objects `lhs` and `rhs`
642/// do not have the same value if they do not have the same number of
643/// elements, or some element in the ordered sequence of elements of `lhs`
644/// does not have the same value as the corresponding element in the ordered
645/// sequence of elements of `rhs`. This method requires that the (template
646/// parameter) type `VALUE` be `equality-comparable` (see {Requirements on
647/// `VALUE`}).
648template <class VALUE, class CONTAINER>
649bool operator!=(const stack<VALUE, CONTAINER>& lhs,
650 const stack<VALUE, CONTAINER>& rhs);
651
652/// Return `true` if the value of the specified `lhs` stack is
653/// lexicographically less than that of the specified `rhs` stack, and
654/// `false` otherwise. Given iterators `i` and `j` over the respective
655/// sequences `[lhs.begin() .. lhs.end())` and `[rhs.begin() .. rhs.end())`,
656/// the value of stack `lhs` is lexicographically less than that of stack
657/// `rhs` if `true == *i < *j` for the first pair of corresponding iterator
658/// positions where `*i < *j` and `*j < *i` are not both `false`. If no
659/// such corresponding iterator position exists, the value of `lhs` is
660/// lexicographically less than that of `rhs` if `lhs.size() < rhs.size()`.
661/// This method requires that `operator<`, inducing a total order, be
662/// defined for `value_type`.
663template <class VALUE, class CONTAINER>
664bool operator< (const stack<VALUE, CONTAINER>& lhs,
665 const stack<VALUE, CONTAINER>& rhs);
666
667/// Return `true` if the value of the specified `lhs` stack is
668/// lexicographically greater than that of the specified `rhs` stack, and
669/// `false` otherwise. The value of stack `lhs` is lexicographically
670/// greater than that of stack `rhs` if `rhs` is lexicographically less than
671/// `lhs` (see `operator<`). This method requires that `operator<`,
672/// inducing a total order, be defined for `value_type`. Note that this
673/// operator returns `rhs < lhs`.
674template <class VALUE, class CONTAINER>
675bool operator> (const stack<VALUE, CONTAINER>& lhs,
676 const stack<VALUE, CONTAINER>& rhs);
677
678/// Return `true` if the value of the specified `lhs` stack is
679/// lexicographically less than or equal to that of the specified `rhs`
680/// stack, and `false` otherwise. The value of stack `lhs` is
681/// lexicographically less than or equal to that of stack `rhs` if `rhs` is
682/// not lexicographically less than `lhs` (see `operator<`). This method
683/// requires that `operator<`, inducing a total order, be defined for
684/// `value_type`. Note that this operator returns `!(rhs < lhs)`.
685template <class VALUE, class CONTAINER>
686bool operator<=(const stack<VALUE, CONTAINER>& lhs,
687 const stack<VALUE, CONTAINER>& rhs);
688
689/// Return `true` if the value of the specified `lhs` stack is
690/// lexicographically greater than or equal to that of the specified `rhs`
691/// stack, and `false` otherwise. The value of stack `lhs` is
692/// lexicographically greater than or equal to that of stack `rhs` if `lhs`
693/// is not lexicographically less than `rhs` (see `operator<`). This method
694/// requires that `operator<`, inducing a total order, be defined for
695/// `value_type`. Note that this operator returns `!(lhs < rhs)`.
696template <class VALUE, class CONTAINER>
697bool operator>=(const stack<VALUE, CONTAINER>& lhs,
698 const stack<VALUE, CONTAINER>& rhs);
699
700// FREE FUNCTIONS
701
702/// Swap the value of the specified `lhs` stack with the value of the
703/// specified `rhs` stack.
704template <class VALUE, class CONTAINER>
705void swap(stack<VALUE, CONTAINER>& lhs,
708
709//=============================================================================
710// TEMPLATE AND INLINE FUNCTION DEFINITIONS
711//=============================================================================
712
713 // -----------
714 // class stack
715 // -----------
716
717// CREATORS
718template <class VALUE, class CONTAINER>
719inline
724
725template <class VALUE, class CONTAINER>
726inline
727stack<VALUE, CONTAINER>::stack(const CONTAINER& container)
728: c(container)
729{
730}
731
732template <class VALUE, class CONTAINER>
733inline
734stack<VALUE, CONTAINER>::stack(BloombergLP::bslmf::MovableRef<stack> original)
735: c(MoveUtil::move(MoveUtil::access(original).c))
736{
737}
738
739template <class VALUE, class CONTAINER>
740template <class ALLOCATOR>
741inline
742stack<VALUE, CONTAINER>::stack(const ALLOCATOR& basicAllocator,
744 ALLOCATOR>::type *)
745: c(basicAllocator)
746{
747}
748
749template <class VALUE, class CONTAINER>
750template <class ALLOCATOR>
751inline
753 const CONTAINER& container,
754 const ALLOCATOR& basicAllocator,
756 ALLOCATOR>::type *)
757: c(container, basicAllocator)
758{
759}
760
761template <class VALUE, class CONTAINER>
762inline
764: c(original.c)
765{
766}
767
768template <class VALUE, class CONTAINER>
769template <class ALLOCATOR>
770inline
772 const stack& original,
773 const ALLOCATOR& basicAllocator,
775 ALLOCATOR>::type *)
776: c(original.c, basicAllocator)
777{
778}
779
780template <class VALUE, class CONTAINER>
781inline
782stack<VALUE, CONTAINER>::stack(BloombergLP::bslmf::MovableRef<CONTAINER>
783 container)
784: c(MoveUtil::move(container))
785{
786}
787
788template <class VALUE, class CONTAINER>
789template <class ALLOCATOR>
790inline
792 BloombergLP::bslmf::MovableRef<CONTAINER> container,
793 const ALLOCATOR& basicAllocator,
795 ALLOCATOR>::type *)
796: c(MoveUtil::move(container), basicAllocator)
797{
798}
799
800template <class VALUE, class CONTAINER>
801template <class ALLOCATOR>
802inline
804 BloombergLP::bslmf::MovableRef<stack> original,
805 const ALLOCATOR& basicAllocator,
807 ALLOCATOR>::type *)
808: c(MoveUtil::move(MoveUtil::access(original).c), basicAllocator)
809{
810}
811
812// MANIPULATORS
813template <class VALUE, class CONTAINER>
814inline
816{
817 c = rhs.c;
818
819 return *this;
820}
821
822template <class VALUE, class CONTAINER>
823inline
825 BloombergLP::bslmf::MovableRef<stack> rhs)
827{
828 c = MoveUtil::move(MoveUtil::access(rhs).c);
829 return *this;
830}
831
832#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
833template <class VALUE, class CONTAINER>
834template <class... Args>
835inline
838{
839 c.emplace_back(BSLS_COMPILERFEATURES_FORWARD(Args,args)...);
840 return top();
841}
842#endif
843
844template <class VALUE, class CONTAINER>
845inline
847{
849
850 c.pop_back();
851}
852
853template <class VALUE, class CONTAINER>
854inline
856{
857 c.push_back(value);
858}
859
860template <class VALUE, class CONTAINER>
861inline
862void stack<VALUE, CONTAINER>::push(BloombergLP::bslmf::MovableRef<value_type>
863 value)
864{
865 c.push_back(MoveUtil::move(value));
866}
867
868template <class VALUE, class CONTAINER>
869inline
872 bsl::is_nothrow_swappable<CONTAINER>::value)
873{
874 BloombergLP::bslalg::SwapUtil::swap(&c, &other.c);
875}
876
877template <class VALUE, class CONTAINER>
878inline
879typename CONTAINER::reference stack<VALUE, CONTAINER>::top()
880{
882
883 return c.back();
884}
885
886// ACCESSORS
887template <class VALUE, class CONTAINER>
888inline
890{
891 return 0 == c.size();
892}
893
894template <class VALUE, class CONTAINER>
895inline
896typename CONTAINER::size_type stack<VALUE, CONTAINER>::size() const
897{
898 return c.size();
899}
900
901template <class VALUE, class CONTAINER>
902inline
903typename CONTAINER::const_reference stack<VALUE, CONTAINER>::top() const
904{
905 return c.back();
906}
907
908// FREE OPERATORS
909template <class VALUE, class CONTAINER>
910inline
911bool operator==(const stack<VALUE, CONTAINER>& lhs,
912 const stack<VALUE, CONTAINER>& rhs)
913{
914 return lhs.c == rhs.c;
915}
916
917template <class VALUE, class CONTAINER>
918inline
919bool operator!=(const stack<VALUE, CONTAINER>& lhs,
920 const stack<VALUE, CONTAINER>& rhs)
921{
922 return lhs.c != rhs.c;
923}
924
925template <class VALUE, class CONTAINER>
926inline
927bool operator< (const stack<VALUE, CONTAINER>& lhs,
928 const stack<VALUE, CONTAINER>& rhs)
929{
930 return lhs.c < rhs.c;
931}
932
933template <class VALUE, class CONTAINER>
934inline
935bool operator> (const stack<VALUE, CONTAINER>& lhs,
936 const stack<VALUE, CONTAINER>& rhs)
937{
938 return lhs.c > rhs.c;
939}
940
941template <class VALUE, class CONTAINER>
942inline
943bool operator<=(const stack<VALUE, CONTAINER>& lhs,
944 const stack<VALUE, CONTAINER>& rhs)
945{
946 return lhs.c <= rhs.c;
947}
948
949template <class VALUE, class CONTAINER>
950inline
951bool operator>=(const stack<VALUE, CONTAINER>& lhs,
952 const stack<VALUE, CONTAINER>& rhs)
953{
954 return lhs.c >= rhs.c;
955}
956
957#if defined BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON \
958 && defined BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
959template <class VALUE, three_way_comparable CONTAINER>
960inline compare_three_way_result_t<CONTAINER>
961operator<=>(const stack<VALUE, CONTAINER>& lhs,
962 const stack<VALUE, CONTAINER>& rhs)
963{
964 return lhs.c <=> rhs.c;
965}
966#endif
967
968// FREE FUNCTIONS
969template <class VALUE, class CONTAINER>
970inline
974{
975 lhs.swap(rhs);
976}
977
978} // close namespace bsl
979
980#endif // End C++11 code
981
982#endif
983
984// ----------------------------------------------------------------------------
985// Copyright 2016 Bloomberg Finance L.P.
986//
987// Licensed under the Apache License, Version 2.0 (the "License");
988// you may not use this file except in compliance with the License.
989// You may obtain a copy of the License at
990//
991// http://www.apache.org/licenses/LICENSE-2.0
992//
993// Unless required by applicable law or agreed to in writing, software
994// distributed under the License is distributed on an "AS IS" BASIS,
995// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
996// See the License for the specific language governing permissions and
997// limitations under the License.
998// ----------------------------- END-OF-FILE ----------------------------------
999
1000/** @} */
1001/** @} */
1002/** @} */
Definition bslstl_stack.h:394
CONTAINER::reference reference
Definition bslstl_stack.h:411
const_reference top() const
CONTAINER::size_type size_type
Definition bslstl_stack.h:413
friend bool operator>(const stack< VAL, CONT > &, const stack< VAL, CONT > &)
stack()
Definition bslstl_stack.h:720
friend bool operator<(const stack< VAL, CONT > &, const stack< VAL, CONT > &)
CONTAINER container_type
Definition bslstl_stack.h:414
friend bool operator!=(const stack< VAL, CONT > &, const stack< VAL, CONT > &)
friend bool operator>=(const stack< VAL, CONT > &, const stack< VAL, CONT > &)
bool empty() const
Definition bslstl_stack.h:889
friend bool operator==(const stack< VAL, CONT > &, const stack< VAL, CONT > &)
void pop()
Definition bslstl_stack.h:846
void push(const value_type &value)
Push the specified value onto the top of this stack.
Definition bslstl_stack.h:855
void swap(stack &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl reference top()
Definition bslstl_stack.h:586
BSLMF_NESTED_TRAIT_DECLARATION_IF(stack, BloombergLP::bslma::UsesBslmaAllocator, BloombergLP::bslma::UsesBslmaAllocator< container_type >::value)
stack & operator=(const stack &rhs)
Definition bslstl_stack.h:815
friend bool operator<=(const stack< VAL, CONT > &, const stack< VAL, CONT > &)
size_type size() const
Return the number of elements contained in this stack.
Definition bslstl_stack.h:896
CONTAINER::value_type value_type
Definition bslstl_stack.h:410
CONTAINER::const_reference const_reference
Definition bslstl_stack.h:412
container_type c
Definition bslstl_stack.h:419
reference emplace(Args &&... args)
Definition bslstl_stack.h:837
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2018
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:634
Definition bdlb_printmethods.h:283
BSLS_KEYWORD_CONSTEXPR bool empty(const CONTAINER &container)
Definition bslstl_iterator.h:1279
Definition bslmf_enableif.h:525
Definition bslmf_issame.h:146
Definition bslmf_usesallocator.h:165