mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 06:06:07 +00:00

This defines a new policy for removal of transitive includes. The goal of the policy it to make it relatively easy to remove headers when needed, but avoid breaking developers using and vendors shipping libc++. The method used is to guard transitive includes based on the C++ language version. For the upcoming C++23 we can remove headers when we want, but for other language versions we try to keep it to a minimum. In this code the transitive include of `<chrono>` is removed since D128577 introduces a header cycle between `<format>` and `<chrono>`. This cycle is indirectly required by the Standard. Our cycle dependency tool basically is a grep based tool, so it needs some hints to ignore cycles. With the input of our transitive include tests we can create a better tool. However that's out of the scope of this patch. Note the flag `_LIBCPP_REMOVE_TRANSITIVE_INCLUDES` remains unchanged. So users can still opt-out of transitives includes entirely. Reviewed By: #libc, ldionne, philnik Differential Revision: https://reviews.llvm.org/D132284
367 lines
12 KiB
C++
367 lines
12 KiB
C++
// -*- C++ -*-
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef _LIBCPP_STACK
|
|
#define _LIBCPP_STACK
|
|
|
|
/*
|
|
stack synopsis
|
|
|
|
namespace std
|
|
{
|
|
|
|
template <class T, class Container = deque<T>>
|
|
class stack
|
|
{
|
|
public:
|
|
typedef Container container_type;
|
|
typedef typename container_type::value_type value_type;
|
|
typedef typename container_type::reference reference;
|
|
typedef typename container_type::const_reference const_reference;
|
|
typedef typename container_type::size_type size_type;
|
|
|
|
protected:
|
|
container_type c;
|
|
|
|
public:
|
|
stack() = default;
|
|
~stack() = default;
|
|
|
|
stack(const stack& q) = default;
|
|
stack(stack&& q) = default;
|
|
|
|
stack& operator=(const stack& q) = default;
|
|
stack& operator=(stack&& q) = default;
|
|
|
|
explicit stack(const container_type& c);
|
|
explicit stack(container_type&& c);
|
|
template <class InputIterator> stack(InputIterator first, InputIterator last); // since C++23
|
|
template <class Alloc> explicit stack(const Alloc& a);
|
|
template <class Alloc> stack(const container_type& c, const Alloc& a);
|
|
template <class Alloc> stack(container_type&& c, const Alloc& a);
|
|
template <class Alloc> stack(const stack& c, const Alloc& a);
|
|
template <class Alloc> stack(stack&& c, const Alloc& a);
|
|
template<class InputIterator, class Alloc>
|
|
stack(InputIterator first, InputIterator last, const Alloc&); // since C++23
|
|
|
|
bool empty() const;
|
|
size_type size() const;
|
|
reference top();
|
|
const_reference top() const;
|
|
|
|
void push(const value_type& x);
|
|
void push(value_type&& x);
|
|
template <class... Args> reference emplace(Args&&... args); // reference in C++17
|
|
void pop();
|
|
|
|
void swap(stack& c) noexcept(is_nothrow_swappable_v<Container>)
|
|
};
|
|
|
|
template<class Container>
|
|
stack(Container) -> stack<typename Container::value_type, Container>; // C++17
|
|
|
|
template<class InputIterator>
|
|
stack(InputIterator, InputIterator) -> stack<iter-value-type<InputIterator>>; // since C++23
|
|
|
|
template<class Container, class Allocator>
|
|
stack(Container, Allocator) -> stack<typename Container::value_type, Container>; // C++17
|
|
|
|
template<class InputIterator, class Allocator>
|
|
stack(InputIterator, InputIterator, Allocator)
|
|
-> stack<iter-value-type<InputIterator>,
|
|
deque<iter-value-type<InputIterator>, Allocator>>; // since C++23
|
|
|
|
template <class T, class Container>
|
|
bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
|
|
template <class T, class Container>
|
|
bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
|
|
template <class T, class Container>
|
|
bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
|
|
template <class T, class Container>
|
|
bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
|
|
template <class T, class Container>
|
|
bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
|
|
template <class T, class Container>
|
|
bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
|
|
|
|
template <class T, class Container>
|
|
void swap(stack<T, Container>& x, stack<T, Container>& y)
|
|
noexcept(noexcept(x.swap(y)));
|
|
|
|
} // std
|
|
|
|
*/
|
|
|
|
#include <__assert> // all public C++ headers provide the assertion handler
|
|
#include <__config>
|
|
#include <__iterator/iterator_traits.h>
|
|
#include <__memory/uses_allocator.h>
|
|
#include <__utility/forward.h>
|
|
#include <deque>
|
|
#include <type_traits>
|
|
#include <version>
|
|
|
|
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
|
|
# include <functional>
|
|
#endif
|
|
|
|
// standard-mandated includes
|
|
#include <compare>
|
|
#include <initializer_list>
|
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
|
# pragma GCC system_header
|
|
#endif
|
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
template <class _Tp, class _Container = deque<_Tp> > class _LIBCPP_TEMPLATE_VIS stack;
|
|
|
|
template <class _Tp, class _Container>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y);
|
|
|
|
template <class _Tp, class _Container>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y);
|
|
|
|
template <class _Tp, class _Container /*= deque<_Tp>*/>
|
|
class _LIBCPP_TEMPLATE_VIS stack
|
|
{
|
|
public:
|
|
typedef _Container container_type;
|
|
typedef typename container_type::value_type value_type;
|
|
typedef typename container_type::reference reference;
|
|
typedef typename container_type::const_reference const_reference;
|
|
typedef typename container_type::size_type size_type;
|
|
static_assert((is_same<_Tp, value_type>::value), "" );
|
|
|
|
protected:
|
|
container_type c;
|
|
|
|
public:
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
stack()
|
|
_NOEXCEPT_(is_nothrow_default_constructible<container_type>::value)
|
|
: c() {}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
stack(const stack& __q) : c(__q.c) {}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
stack& operator=(const stack& __q) {c = __q.c; return *this;}
|
|
|
|
|
|
#ifndef _LIBCPP_CXX03_LANG
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
stack(stack&& __q)
|
|
_NOEXCEPT_(is_nothrow_move_constructible<container_type>::value)
|
|
: c(_VSTD::move(__q.c)) {}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
stack& operator=(stack&& __q)
|
|
_NOEXCEPT_(is_nothrow_move_assignable<container_type>::value)
|
|
{c = _VSTD::move(__q.c); return *this;}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
explicit stack(container_type&& __c) : c(_VSTD::move(__c)) {}
|
|
#endif // _LIBCPP_CXX03_LANG
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
explicit stack(const container_type& __c) : c(__c) {}
|
|
|
|
template <class _Alloc>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
explicit stack(const _Alloc& __a,
|
|
__enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0)
|
|
: c(__a) {}
|
|
template <class _Alloc>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
stack(const container_type& __c, const _Alloc& __a,
|
|
__enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0)
|
|
: c(__c, __a) {}
|
|
template <class _Alloc>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
stack(const stack& __s, const _Alloc& __a,
|
|
__enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0)
|
|
: c(__s.c, __a) {}
|
|
#ifndef _LIBCPP_CXX03_LANG
|
|
template <class _Alloc>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
stack(container_type&& __c, const _Alloc& __a,
|
|
__enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0)
|
|
: c(_VSTD::move(__c), __a) {}
|
|
template <class _Alloc>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
stack(stack&& __s, const _Alloc& __a,
|
|
__enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0)
|
|
: c(_VSTD::move(__s.c), __a) {}
|
|
#endif // _LIBCPP_CXX03_LANG
|
|
|
|
#if _LIBCPP_STD_VER > 20
|
|
template <class _InputIterator,
|
|
class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
|
|
_LIBCPP_HIDE_FROM_ABI
|
|
stack(_InputIterator __first, _InputIterator __last) : c(__first, __last) {}
|
|
|
|
template <class _InputIterator,
|
|
class _Alloc,
|
|
class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
|
|
class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
|
|
_LIBCPP_HIDE_FROM_ABI
|
|
stack(_InputIterator __first, _InputIterator __last, const _Alloc& __alloc) : c(__first, __last, __alloc) {}
|
|
#endif
|
|
|
|
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
|
|
bool empty() const {return c.empty();}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
size_type size() const {return c.size();}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
reference top() {return c.back();}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
const_reference top() const {return c.back();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
void push(const value_type& __v) {c.push_back(__v);}
|
|
#ifndef _LIBCPP_CXX03_LANG
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
void push(value_type&& __v) {c.push_back(_VSTD::move(__v));}
|
|
|
|
template <class... _Args>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
#if _LIBCPP_STD_VER > 14
|
|
decltype(auto) emplace(_Args&&... __args)
|
|
{ return c.emplace_back(_VSTD::forward<_Args>(__args)...);}
|
|
#else
|
|
void emplace(_Args&&... __args)
|
|
{ c.emplace_back(_VSTD::forward<_Args>(__args)...);}
|
|
#endif
|
|
#endif // _LIBCPP_CXX03_LANG
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
void pop() {c.pop_back();}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
void swap(stack& __s)
|
|
_NOEXCEPT_(__is_nothrow_swappable<container_type>::value)
|
|
{
|
|
using _VSTD::swap;
|
|
swap(c, __s.c);
|
|
}
|
|
|
|
template <class T1, class _C1>
|
|
friend
|
|
bool
|
|
operator==(const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);
|
|
|
|
template <class T1, class _C1>
|
|
friend
|
|
bool
|
|
operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);
|
|
};
|
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
template<class _Container,
|
|
class = enable_if_t<!__is_allocator<_Container>::value>
|
|
>
|
|
stack(_Container)
|
|
-> stack<typename _Container::value_type, _Container>;
|
|
|
|
template<class _Container,
|
|
class _Alloc,
|
|
class = enable_if_t<!__is_allocator<_Container>::value>,
|
|
class = enable_if_t<uses_allocator<_Container, _Alloc>::value>
|
|
>
|
|
stack(_Container, _Alloc)
|
|
-> stack<typename _Container::value_type, _Container>;
|
|
#endif
|
|
|
|
#if _LIBCPP_STD_VER > 20
|
|
template<class _InputIterator,
|
|
class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
|
|
stack(_InputIterator, _InputIterator)
|
|
-> stack<__iter_value_type<_InputIterator>>;
|
|
|
|
template<class _InputIterator,
|
|
class _Alloc,
|
|
class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
|
|
class = __enable_if_t<__is_allocator<_Alloc>::value>>
|
|
stack(_InputIterator, _InputIterator, _Alloc)
|
|
-> stack<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>;
|
|
#endif
|
|
|
|
template <class _Tp, class _Container>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
|
|
{
|
|
return __x.c == __y.c;
|
|
}
|
|
|
|
template <class _Tp, class _Container>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
|
|
{
|
|
return __x.c < __y.c;
|
|
}
|
|
|
|
template <class _Tp, class _Container>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator!=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
|
|
{
|
|
return !(__x == __y);
|
|
}
|
|
|
|
template <class _Tp, class _Container>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator> (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
|
|
{
|
|
return __y < __x;
|
|
}
|
|
|
|
template <class _Tp, class _Container>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
|
|
{
|
|
return !(__x < __y);
|
|
}
|
|
|
|
template <class _Tp, class _Container>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
|
|
{
|
|
return !(__y < __x);
|
|
}
|
|
|
|
template <class _Tp, class _Container>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
__enable_if_t<__is_swappable<_Container>::value, void>
|
|
swap(stack<_Tp, _Container>& __x, stack<_Tp, _Container>& __y)
|
|
_NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
|
|
{
|
|
__x.swap(__y);
|
|
}
|
|
|
|
template <class _Tp, class _Container, class _Alloc>
|
|
struct _LIBCPP_TEMPLATE_VIS uses_allocator<stack<_Tp, _Container>, _Alloc>
|
|
: public uses_allocator<_Container, _Alloc>
|
|
{
|
|
};
|
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
#endif // _LIBCPP_STACK
|