From e59cf7b09e7388d369e8d2bf73501cde79c28708 Mon Sep 17 00:00:00 2001 From: Toni Uhlig Date: Thu, 8 Apr 2021 16:43:58 +0200 Subject: Squashed 'EASTL/' content from commit fad5471 git-subtree-dir: EASTL git-subtree-split: fad54717f8e4ebb13b20095da7efd07a53af0f10 --- include/EASTL/queue.h | 366 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 366 insertions(+) create mode 100644 include/EASTL/queue.h (limited to 'include/EASTL/queue.h') diff --git a/include/EASTL/queue.h b/include/EASTL/queue.h new file mode 100644 index 0000000..9e06e20 --- /dev/null +++ b/include/EASTL/queue.h @@ -0,0 +1,366 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) Electronic Arts Inc. All rights reserved. +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// This file implements a queue that is just like the C++ std::queue adapter class. +// There are no significant differences between EASTL/queue and std::queue. +// We provide this class for completeness and where std STL may not be available. +/////////////////////////////////////////////////////////////////////////////// + + +#ifndef EASTL_QUEUE_H +#define EASTL_QUEUE_H + + +#include +#include +#include +#include + +#if defined(EA_PRAGMA_ONCE_SUPPORTED) + #pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result. +#endif + + + +namespace eastl +{ + + /// EASTL_QUEUE_DEFAULT_NAME + /// + /// Defines a default container name in the absence of a user-provided name. + /// + #ifndef EASTL_QUEUE_DEFAULT_NAME + #define EASTL_QUEUE_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " queue" // Unless the user overrides something, this is "EASTL queue". + #endif + + /// EASTL_QUEUE_DEFAULT_ALLOCATOR + /// + #ifndef EASTL_QUEUE_DEFAULT_ALLOCATOR + #define EASTL_QUEUE_DEFAULT_ALLOCATOR allocator_type(EASTL_QUEUE_DEFAULT_NAME) + #endif + + + + /// queue + /// + /// queue is an adapter class provides a FIFO (first-in, first-out) interface + /// via wrapping a sequence that provides at least the following operations: + /// push_back + /// pop_front + /// front + /// back + /// + /// In practice this usually means deque, list, intrusive_list. vector and string + /// cannot be used because they don't provide pop-front. This is reasonable because + /// a vector or string pop_front would be inefficient and could lead to + /// silently poor performance. + /// + template > + class queue + { + public: + typedef queue this_type; + typedef Container container_type; + //typedef typename Container::allocator_type allocator_type; // We can't currently declare this because the container may be a type that doesn't have an allocator. + typedef typename Container::value_type value_type; + typedef typename Container::reference reference; + typedef typename Container::const_reference const_reference; + typedef typename Container::size_type size_type; + + public: // We declare public so that global comparison operators can be implemented without adding an inline level and without tripping up GCC 2.x friend declaration failures. GCC (through at least v4.0) is poor at inlining and performance wins over correctness. + container_type c; // The C++ standard specifies that you declare a protected member variable of type Container called 'c'. + + public: + queue(); + + // Allocator is templated here because we aren't allowed to infer the allocator_type from the Container, as some containers (e.g. array) don't + // have allocators. For containers that don't have allocator types, you could use void or char as the Allocator template type. + + template + explicit queue(const Allocator& allocator, typename eastl::enable_if::value>::type* = NULL) + : c(allocator) + { + } + + template + queue(const this_type& x, const Allocator& allocator, typename eastl::enable_if::value>::type* = NULL) + : c(x.c, allocator) + { + } + + template + queue(this_type&& x, const Allocator& allocator, typename eastl::enable_if::value>::type* = NULL) + : c(eastl::move(x.c), allocator) + { + } + + explicit queue(const container_type& x); + explicit queue(container_type&& x); + + // Additional C++11 support to consider: + // + // template + // queue(const container_type& x, const Allocator& allocator); + // + // template + // queue(container_type&& x, const Allocator& allocator); + + queue(std::initializer_list ilist); // C++11 doesn't specify that std::queue has initializer list support. + + bool empty() const; + size_type size() const; + + reference front(); + const_reference front() const; + + reference back(); + const_reference back() const; + + void push(const value_type& value); + void push(value_type&& x); + + template + EA_DEPRECATED void emplace_back(Args&&... args); // backwards compatibility + + template + decltype(auto) emplace(Args&&... args); + + void pop(); + + container_type& get_container(); + const container_type& get_container() const; + + void swap(this_type& x) EA_NOEXCEPT_IF((eastl::is_nothrow_swappable::value)); + + bool validate() const; + + }; // class queue + + + + + /////////////////////////////////////////////////////////////////////// + // queue + /////////////////////////////////////////////////////////////////////// + + template + inline queue::queue() + : c() // To consider: use c(EASTL_QUEUE_DEFAULT_ALLOCATOR) here, though that would add the requirement that the user supplied container support this. + { + // Empty + } + + + template + inline queue::queue(const Container& x) + : c(x) + { + // Empty + } + + + template + inline queue::queue(Container&& x) + : c(eastl::move(x)) + { + // Empty + } + + + template + inline queue::queue(std::initializer_list ilist) + : c() // We could alternatively use c(ilist) here, but that would require c to have an ilist constructor. + { + // Better solution but requires an insert function. + // c.insert(ilist.begin(), ilist.end()); + + // Possibly slower solution but doesn't require an insert function. + for(typename std::initializer_list::iterator it = ilist.begin(); it != ilist.end(); ++it) + { + const value_type& value = *it; + c.push_back(value); + } + } + + + template + inline bool queue::empty() const + { + return c.empty(); + } + + + template + inline typename queue::size_type + queue::size() const + { + return c.size(); + } + + + template + inline typename queue::reference + queue::front() + { + return c.front(); + } + + + template + inline typename queue::const_reference + queue::front() const + { + return c.front(); + } + + + template + inline typename queue::reference + queue::back() + { + return c.back(); + } + + + template + inline typename queue::const_reference + queue::back() const + { + return c.back(); + } + + + template + inline void queue::push(const value_type& value) + { + c.push_back(const_cast(value)); // const_cast so that intrusive_list can work. We may revisit this. + } + + + template + inline void queue::push(value_type&& x) + { + c.push_back(eastl::move(x)); + } + + + template + template + inline void queue::emplace_back(Args&&... args) + { + emplace(eastl::forward(args)...); + } + + template + template + inline decltype(auto) queue::emplace(Args&&... args) + { + return c.emplace_back(eastl::forward(args)...); + } + + + template + inline void queue::pop() + { + c.pop_front(); + } + + + template + inline typename queue::container_type& + queue::get_container() + { + return c; + } + + + template + inline const typename queue::container_type& + queue::get_container() const + { + return c; + } + + + template + void queue::swap(this_type& x) EA_NOEXCEPT_IF((eastl::is_nothrow_swappable::value)) + { + using eastl::swap; + swap(c, x.c); + } + + + template + bool queue::validate() const + { + return c.validate(); + } + + + /////////////////////////////////////////////////////////////////////// + // global operators + /////////////////////////////////////////////////////////////////////// + + template + inline bool operator==(const queue& a, const queue& b) + { + return (a.c == b.c); + } + + template + inline bool operator!=(const queue& a, const queue& b) + { + return !(a.c == b.c); + } + + template + inline bool operator<(const queue& a, const queue& b) + { + return (a.c < b.c); + } + + template + inline bool operator>(const queue& a, const queue& b) + { + return (b.c < a.c); + } + + template + inline bool operator<=(const queue& a, const queue& b) + { + return !(b.c < a.c); + } + + template + inline bool operator>=(const queue& a, const queue& b) + { + return !(a.c < b.c); + } + + + template + inline void swap(queue& a, queue& b) EA_NOEXCEPT_IF((eastl::is_nothrow_swappable::container_type>::value)) // EDG has a bug and won't let us use Container in this noexcept statement + { + a.swap(b); + } + + +} // namespace eastl + + +#endif // Header include guard + + + + + + + + + + + + + -- cgit v1.2.3