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