8e706d2c3e
Summary: There is no reason to guard `tuple_size`, `tuple_element` and `get<I>(...)` for pair and array inside of `<__tuple>` so that they are only available when we have variadic templates. This requires there be redundant declarations and definitions. It also makes it easy to get things wrong. For example the following code should compile (and does in c++11). ``` #define _LIBCPP_HAS_NO_VARIADICS #include <array> int main() { static_assert((std::tuple_size<std::array<int, 10> volatile>::value == 10), ""); } ``` This patch lifts the non-variadic parts of `tuple_size`, `tuple_types`, and `get<I>(...)` to the top of `<__tuple>` where they don't require variadic templates. This patch also removes `<__tuple_03>` because there is no longer a need for it. Reviewers: danalbert, K-ballo, mclow.lists Reviewed By: mclow.lists Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D7774 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@232492 91177308-0d34-0410-b5e6-96231b3b80d8
332 lines
11 KiB
C++
332 lines
11 KiB
C++
// -*- C++ -*-
|
|
//===---------------------------- array -----------------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is dual licensed under the MIT and the University of Illinois Open
|
|
// Source Licenses. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef _LIBCPP_ARRAY
|
|
#define _LIBCPP_ARRAY
|
|
|
|
/*
|
|
array synopsis
|
|
|
|
namespace std
|
|
{
|
|
template <class T, size_t N >
|
|
struct array
|
|
{
|
|
// types:
|
|
typedef T & reference;
|
|
typedef const T & const_reference;
|
|
typedef implementation defined iterator;
|
|
typedef implementation defined const_iterator;
|
|
typedef size_t size_type;
|
|
typedef ptrdiff_t difference_type;
|
|
typedef T value_type;
|
|
typedef T* pointer;
|
|
typedef const T* const_pointer;
|
|
typedef std::reverse_iterator<iterator> reverse_iterator;
|
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
|
|
|
// No explicit construct/copy/destroy for aggregate type
|
|
void fill(const T& u);
|
|
void swap(array& a) noexcept(noexcept(swap(declval<T&>(), declval<T&>())));
|
|
|
|
// iterators:
|
|
iterator begin() noexcept;
|
|
const_iterator begin() const noexcept;
|
|
iterator end() noexcept;
|
|
const_iterator end() const noexcept;
|
|
|
|
reverse_iterator rbegin() noexcept;
|
|
const_reverse_iterator rbegin() const noexcept;
|
|
reverse_iterator rend() noexcept;
|
|
const_reverse_iterator rend() const noexcept;
|
|
|
|
const_iterator cbegin() const noexcept;
|
|
const_iterator cend() const noexcept;
|
|
const_reverse_iterator crbegin() const noexcept;
|
|
const_reverse_iterator crend() const noexcept;
|
|
|
|
// capacity:
|
|
constexpr size_type size() const noexcept;
|
|
constexpr size_type max_size() const noexcept;
|
|
constexpr bool empty() const noexcept;
|
|
|
|
// element access:
|
|
reference operator[](size_type n);
|
|
const_reference operator[](size_type n) const; // constexpr in C++14
|
|
const_reference at(size_type n) const; // constexpr in C++14
|
|
reference at(size_type n);
|
|
|
|
reference front();
|
|
const_reference front() const; // constexpr in C++14
|
|
reference back();
|
|
const_reference back() const; // constexpr in C++14
|
|
|
|
T* data() noexcept;
|
|
const T* data() const noexcept;
|
|
};
|
|
|
|
template <class T, size_t N>
|
|
bool operator==(const array<T,N>& x, const array<T,N>& y);
|
|
template <class T, size_t N>
|
|
bool operator!=(const array<T,N>& x, const array<T,N>& y);
|
|
template <class T, size_t N>
|
|
bool operator<(const array<T,N>& x, const array<T,N>& y);
|
|
template <class T, size_t N>
|
|
bool operator>(const array<T,N>& x, const array<T,N>& y);
|
|
template <class T, size_t N>
|
|
bool operator<=(const array<T,N>& x, const array<T,N>& y);
|
|
template <class T, size_t N>
|
|
bool operator>=(const array<T,N>& x, const array<T,N>& y);
|
|
|
|
template <class T, size_t N >
|
|
void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y)));
|
|
|
|
template <class T> class tuple_size;
|
|
template <int I, class T> class tuple_element;
|
|
template <class T, size_t N> struct tuple_size<array<T, N>>;
|
|
template <int I, class T, size_t N> struct tuple_element<I, array<T, N>>;
|
|
template <int I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14
|
|
template <int I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14
|
|
template <int I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14
|
|
|
|
} // std
|
|
|
|
*/
|
|
|
|
#include <__config>
|
|
#include <__tuple>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
#include <iterator>
|
|
#include <algorithm>
|
|
#include <stdexcept>
|
|
#if defined(_LIBCPP_NO_EXCEPTIONS)
|
|
#include <cassert>
|
|
#endif
|
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
|
#pragma GCC system_header
|
|
#endif
|
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
template <class _Tp, size_t _Size>
|
|
struct _LIBCPP_TYPE_VIS_ONLY array
|
|
{
|
|
// types:
|
|
typedef array __self;
|
|
typedef _Tp value_type;
|
|
typedef value_type& reference;
|
|
typedef const value_type& const_reference;
|
|
typedef value_type* iterator;
|
|
typedef const value_type* const_iterator;
|
|
typedef value_type* pointer;
|
|
typedef const value_type* const_pointer;
|
|
typedef size_t size_type;
|
|
typedef ptrdiff_t difference_type;
|
|
typedef std::reverse_iterator<iterator> reverse_iterator;
|
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
|
|
|
value_type __elems_[_Size > 0 ? _Size : 1];
|
|
|
|
// No explicit construct/copy/destroy for aggregate type
|
|
_LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u)
|
|
{_VSTD::fill_n(__elems_, _Size, __u);}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
|
|
{_VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);}
|
|
|
|
// iterators:
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
iterator begin() _NOEXCEPT {return iterator(__elems_);}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
const_iterator cbegin() const _NOEXCEPT {return begin();}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
const_iterator cend() const _NOEXCEPT {return end();}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
const_reverse_iterator crend() const _NOEXCEPT {return rend();}
|
|
|
|
// capacity:
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
_LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return _Size;}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
_LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
_LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;}
|
|
|
|
// element access:
|
|
_LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) {return __elems_[__n];}
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference operator[](size_type __n) const {return __elems_[__n];}
|
|
reference at(size_type __n);
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY reference front() {return __elems_[0];}
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const {return __elems_[0];}
|
|
_LIBCPP_INLINE_VISIBILITY reference back() {return __elems_[_Size > 0 ? _Size-1 : 0];}
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const {return __elems_[_Size > 0 ? _Size-1 : 0];}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
value_type* data() _NOEXCEPT {return __elems_;}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
const value_type* data() const _NOEXCEPT {return __elems_;}
|
|
};
|
|
|
|
template <class _Tp, size_t _Size>
|
|
typename array<_Tp, _Size>::reference
|
|
array<_Tp, _Size>::at(size_type __n)
|
|
{
|
|
if (__n >= _Size)
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
throw out_of_range("array::at");
|
|
#else
|
|
assert(!"array::at out_of_range");
|
|
#endif
|
|
return __elems_[__n];
|
|
}
|
|
|
|
template <class _Tp, size_t _Size>
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
typename array<_Tp, _Size>::const_reference
|
|
array<_Tp, _Size>::at(size_type __n) const
|
|
{
|
|
if (__n >= _Size)
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
throw out_of_range("array::at");
|
|
#else
|
|
assert(!"array::at out_of_range");
|
|
#endif
|
|
return __elems_[__n];
|
|
}
|
|
|
|
template <class _Tp, size_t _Size>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
|
|
{
|
|
return _VSTD::equal(__x.__elems_, __x.__elems_ + _Size, __y.__elems_);
|
|
}
|
|
|
|
template <class _Tp, size_t _Size>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
|
|
{
|
|
return !(__x == __y);
|
|
}
|
|
|
|
template <class _Tp, size_t _Size>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
|
|
{
|
|
return _VSTD::lexicographical_compare(__x.__elems_, __x.__elems_ + _Size, __y.__elems_, __y.__elems_ + _Size);
|
|
}
|
|
|
|
template <class _Tp, size_t _Size>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
|
|
{
|
|
return __y < __x;
|
|
}
|
|
|
|
template <class _Tp, size_t _Size>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
|
|
{
|
|
return !(__y < __x);
|
|
}
|
|
|
|
template <class _Tp, size_t _Size>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
|
|
{
|
|
return !(__x < __y);
|
|
}
|
|
|
|
template <class _Tp, size_t _Size>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
typename enable_if
|
|
<
|
|
__is_swappable<_Tp>::value,
|
|
void
|
|
>::type
|
|
swap(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
|
|
_NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
|
|
{
|
|
__x.swap(__y);
|
|
}
|
|
|
|
template <class _Tp, size_t _Size>
|
|
class _LIBCPP_TYPE_VIS_ONLY tuple_size<array<_Tp, _Size> >
|
|
: public integral_constant<size_t, _Size> {};
|
|
|
|
template <size_t _Ip, class _Tp, size_t _Size>
|
|
class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, array<_Tp, _Size> >
|
|
{
|
|
public:
|
|
typedef _Tp type;
|
|
};
|
|
|
|
template <size_t _Ip, class _Tp, size_t _Size>
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
_Tp&
|
|
get(array<_Tp, _Size>& __a) _NOEXCEPT
|
|
{
|
|
static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)");
|
|
return __a.__elems_[_Ip];
|
|
}
|
|
|
|
template <size_t _Ip, class _Tp, size_t _Size>
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
const _Tp&
|
|
get(const array<_Tp, _Size>& __a) _NOEXCEPT
|
|
{
|
|
static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)");
|
|
return __a.__elems_[_Ip];
|
|
}
|
|
|
|
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
|
|
template <size_t _Ip, class _Tp, size_t _Size>
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
_Tp&&
|
|
get(array<_Tp, _Size>&& __a) _NOEXCEPT
|
|
{
|
|
static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)");
|
|
return _VSTD::move(__a.__elems_[_Ip]);
|
|
}
|
|
|
|
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
#endif // _LIBCPP_ARRAY
|