sdk: build libsupc++ from libstdc++ source

git-svn-id: svn://kolibrios.org@5134 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge)
2014-09-21 10:51:57 +00:00
parent c993fd46f8
commit 9d5ad505ec
863 changed files with 369722 additions and 0 deletions

View File

@@ -0,0 +1,826 @@
// <algorithm> Forward declarations -*- C++ -*-
// Copyright (C) 2007-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/algorithmfwd.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{algorithm}
*/
#ifndef _GLIBCXX_ALGORITHMFWD_H
#define _GLIBCXX_ALGORITHMFWD_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/stl_pair.h>
#include <bits/stl_iterator_base_types.h>
#if __cplusplus >= 201103L
#include <initializer_list>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/*
adjacent_find
all_of (C++0x)
any_of (C++0x)
binary_search
copy
copy_backward
copy_if (C++0x)
copy_n (C++0x)
count
count_if
equal
equal_range
fill
fill_n
find
find_end
find_first_of
find_if
find_if_not (C++0x)
for_each
generate
generate_n
includes
inplace_merge
is_heap (C++0x)
is_heap_until (C++0x)
is_partitioned (C++0x)
is_sorted (C++0x)
is_sorted_until (C++0x)
iter_swap
lexicographical_compare
lower_bound
make_heap
max
max_element
merge
min
min_element
minmax (C++0x)
minmax_element (C++0x)
mismatch
next_permutation
none_of (C++0x)
nth_element
partial_sort
partial_sort_copy
partition
partition_copy (C++0x)
partition_point (C++0x)
pop_heap
prev_permutation
push_heap
random_shuffle
remove
remove_copy
remove_copy_if
remove_if
replace
replace_copy
replace_copy_if
replace_if
reverse
reverse_copy
rotate
rotate_copy
search
search_n
set_difference
set_intersection
set_symmetric_difference
set_union
shuffle (C++0x)
sort
sort_heap
stable_partition
stable_sort
swap
swap_ranges
transform
unique
unique_copy
upper_bound
*/
/**
* @defgroup algorithms Algorithms
*
* Components for performing algorithmic operations. Includes
* non-modifying sequence, modifying (mutating) sequence, sorting,
* searching, merge, partition, heap, set, minima, maxima, and
* permutation operations.
*/
/**
* @defgroup mutating_algorithms Mutating
* @ingroup algorithms
*/
/**
* @defgroup non_mutating_algorithms Non-Mutating
* @ingroup algorithms
*/
/**
* @defgroup sorting_algorithms Sorting
* @ingroup algorithms
*/
/**
* @defgroup set_algorithms Set Operation
* @ingroup sorting_algorithms
*
* These algorithms are common set operations performed on sequences
* that are already sorted. The number of comparisons will be
* linear.
*/
/**
* @defgroup binary_search_algorithms Binary Search
* @ingroup sorting_algorithms
*
* These algorithms are variations of a classic binary search, and
* all assume that the sequence being searched is already sorted.
*
* The number of comparisons will be logarithmic (and as few as
* possible). The number of steps through the sequence will be
* logarithmic for random-access iterators (e.g., pointers), and
* linear otherwise.
*
* The LWG has passed Defect Report 270, which notes: <em>The
* proposed resolution reinterprets binary search. Instead of
* thinking about searching for a value in a sorted range, we view
* that as an important special case of a more general algorithm:
* searching for the partition point in a partitioned range. We
* also add a guarantee that the old wording did not: we ensure that
* the upper bound is no earlier than the lower bound, that the pair
* returned by equal_range is a valid range, and that the first part
* of that pair is the lower bound.</em>
*
* The actual effect of the first sentence is that a comparison
* functor passed by the user doesn't necessarily need to induce a
* strict weak ordering relation. Rather, it partitions the range.
*/
// adjacent_find
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
bool
all_of(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Predicate>
bool
any_of(_IIter, _IIter, _Predicate);
#endif
template<typename _FIter, typename _Tp>
bool
binary_search(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
bool
binary_search(_FIter, _FIter, const _Tp&, _Compare);
template<typename _IIter, typename _OIter>
_OIter
copy(_IIter, _IIter, _OIter);
template<typename _BIter1, typename _BIter2>
_BIter2
copy_backward(_BIter1, _BIter1, _BIter2);
#if __cplusplus >= 201103L
template<typename _IIter, typename _OIter, typename _Predicate>
_OIter
copy_if(_IIter, _IIter, _OIter, _Predicate);
template<typename _IIter, typename _Size, typename _OIter>
_OIter
copy_n(_IIter, _Size, _OIter);
#endif
// count
// count_if
template<typename _FIter, typename _Tp>
pair<_FIter, _FIter>
equal_range(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
pair<_FIter, _FIter>
equal_range(_FIter, _FIter, const _Tp&, _Compare);
template<typename _FIter, typename _Tp>
void
fill(_FIter, _FIter, const _Tp&);
template<typename _OIter, typename _Size, typename _Tp>
_OIter
fill_n(_OIter, _Size, const _Tp&);
// find
template<typename _FIter1, typename _FIter2>
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
// find_first_of
// find_if
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
_IIter
find_if_not(_IIter, _IIter, _Predicate);
#endif
// for_each
// generate
// generate_n
template<typename _IIter1, typename _IIter2>
bool
includes(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
bool
includes(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
template<typename _BIter>
void
inplace_merge(_BIter, _BIter, _BIter);
template<typename _BIter, typename _Compare>
void
inplace_merge(_BIter, _BIter, _BIter, _Compare);
#if __cplusplus >= 201103L
template<typename _RAIter>
bool
is_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
bool
is_heap(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
_RAIter
is_heap_until(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_RAIter
is_heap_until(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _Predicate>
bool
is_partitioned(_IIter, _IIter, _Predicate);
template<typename _FIter1, typename _FIter2>
bool
is_permutation(_FIter1, _FIter1, _FIter2);
template<typename _FIter1, typename _FIter2,
typename _BinaryPredicate>
bool
is_permutation(_FIter1, _FIter1, _FIter2, _BinaryPredicate);
template<typename _FIter>
bool
is_sorted(_FIter, _FIter);
template<typename _FIter, typename _Compare>
bool
is_sorted(_FIter, _FIter, _Compare);
template<typename _FIter>
_FIter
is_sorted_until(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_FIter
is_sorted_until(_FIter, _FIter, _Compare);
#endif
template<typename _FIter1, typename _FIter2>
void
iter_swap(_FIter1, _FIter2);
template<typename _FIter, typename _Tp>
_FIter
lower_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_FIter
lower_bound(_FIter, _FIter, const _Tp&, _Compare);
template<typename _RAIter>
void
make_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
void
make_heap(_RAIter, _RAIter, _Compare);
template<typename _Tp>
const _Tp&
max(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
const _Tp&
max(const _Tp&, const _Tp&, _Compare);
// max_element
// merge
template<typename _Tp>
const _Tp&
min(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
const _Tp&
min(const _Tp&, const _Tp&, _Compare);
// min_element
#if __cplusplus >= 201103L
template<typename _Tp>
pair<const _Tp&, const _Tp&>
minmax(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
pair<const _Tp&, const _Tp&>
minmax(const _Tp&, const _Tp&, _Compare);
template<typename _FIter>
pair<_FIter, _FIter>
minmax_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
pair<_FIter, _FIter>
minmax_element(_FIter, _FIter, _Compare);
template<typename _Tp>
_Tp
min(initializer_list<_Tp>);
template<typename _Tp, typename _Compare>
_Tp
min(initializer_list<_Tp>, _Compare);
template<typename _Tp>
_Tp
max(initializer_list<_Tp>);
template<typename _Tp, typename _Compare>
_Tp
max(initializer_list<_Tp>, _Compare);
template<typename _Tp>
pair<_Tp, _Tp>
minmax(initializer_list<_Tp>);
template<typename _Tp, typename _Compare>
pair<_Tp, _Tp>
minmax(initializer_list<_Tp>, _Compare);
#endif
// mismatch
template<typename _BIter>
bool
next_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
bool
next_permutation(_BIter, _BIter, _Compare);
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
bool
none_of(_IIter, _IIter, _Predicate);
#endif
// nth_element
// partial_sort
template<typename _IIter, typename _RAIter>
_RAIter
partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter);
template<typename _IIter, typename _RAIter, typename _Compare>
_RAIter
partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter, _Compare);
// partition
#if __cplusplus >= 201103L
template<typename _IIter, typename _OIter1,
typename _OIter2, typename _Predicate>
pair<_OIter1, _OIter2>
partition_copy(_IIter, _IIter, _OIter1, _OIter2, _Predicate);
template<typename _FIter, typename _Predicate>
_FIter
partition_point(_FIter, _FIter, _Predicate);
#endif
template<typename _RAIter>
void
pop_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
void
pop_heap(_RAIter, _RAIter, _Compare);
template<typename _BIter>
bool
prev_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
bool
prev_permutation(_BIter, _BIter, _Compare);
template<typename _RAIter>
void
push_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
void
push_heap(_RAIter, _RAIter, _Compare);
// random_shuffle
template<typename _FIter, typename _Tp>
_FIter
remove(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Predicate>
_FIter
remove_if(_FIter, _FIter, _Predicate);
template<typename _IIter, typename _OIter, typename _Tp>
_OIter
remove_copy(_IIter, _IIter, _OIter, const _Tp&);
template<typename _IIter, typename _OIter, typename _Predicate>
_OIter
remove_copy_if(_IIter, _IIter, _OIter, _Predicate);
// replace
template<typename _IIter, typename _OIter, typename _Tp>
_OIter
replace_copy(_IIter, _IIter, _OIter, const _Tp&, const _Tp&);
template<typename _Iter, typename _OIter, typename _Predicate, typename _Tp>
_OIter
replace_copy_if(_Iter, _Iter, _OIter, _Predicate, const _Tp&);
// replace_if
template<typename _BIter>
void
reverse(_BIter, _BIter);
template<typename _BIter, typename _OIter>
_OIter
reverse_copy(_BIter, _BIter, _OIter);
template<typename _FIter>
void
rotate(_FIter, _FIter, _FIter);
template<typename _FIter, typename _OIter>
_OIter
rotate_copy(_FIter, _FIter, _FIter, _OIter);
// search
// search_n
// set_difference
// set_intersection
// set_symmetric_difference
// set_union
#if (__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
template<typename _RAIter, typename _UGenerator>
void
shuffle(_RAIter, _RAIter, _UGenerator&&);
#endif
template<typename _RAIter>
void
sort_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
void
sort_heap(_RAIter, _RAIter, _Compare);
template<typename _BIter, typename _Predicate>
_BIter
stable_partition(_BIter, _BIter, _Predicate);
template<typename _Tp>
void
swap(_Tp&, _Tp&)
#if __cplusplus >= 201103L
noexcept(__and_<is_nothrow_move_constructible<_Tp>,
is_nothrow_move_assignable<_Tp>>::value)
#endif
;
template<typename _Tp, size_t _Nm>
void
swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
#if __cplusplus >= 201103L
noexcept(noexcept(swap(*__a, *__b)))
#endif
;
template<typename _FIter1, typename _FIter2>
_FIter2
swap_ranges(_FIter1, _FIter1, _FIter2);
// transform
template<typename _FIter>
_FIter
unique(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
_FIter
unique(_FIter, _FIter, _BinaryPredicate);
// unique_copy
template<typename _FIter, typename _Tp>
_FIter
upper_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_FIter
upper_bound(_FIter, _FIter, const _Tp&, _Compare);
_GLIBCXX_END_NAMESPACE_VERSION
_GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _FIter>
_FIter
adjacent_find(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
_FIter
adjacent_find(_FIter, _FIter, _BinaryPredicate);
template<typename _IIter, typename _Tp>
typename iterator_traits<_IIter>::difference_type
count(_IIter, _IIter, const _Tp&);
template<typename _IIter, typename _Predicate>
typename iterator_traits<_IIter>::difference_type
count_if(_IIter, _IIter, _Predicate);
template<typename _IIter1, typename _IIter2>
bool
equal(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
bool
equal(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _IIter, typename _Tp>
_IIter
find(_IIter, _IIter, const _Tp&);
template<typename _FIter1, typename _FIter2>
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _IIter, typename _Predicate>
_IIter
find_if(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Funct>
_Funct
for_each(_IIter, _IIter, _Funct);
template<typename _FIter, typename _Generator>
void
generate(_FIter, _FIter, _Generator);
template<typename _OIter, typename _Size, typename _Generator>
_OIter
generate_n(_OIter, _Size, _Generator);
template<typename _IIter1, typename _IIter2>
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
template<typename _FIter>
_FIter
max_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_FIter
max_element(_FIter, _FIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _FIter>
_FIter
min_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_FIter
min_element(_FIter, _FIter, _Compare);
template<typename _IIter1, typename _IIter2>
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _RAIter>
void
nth_element(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
void
nth_element(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _RAIter>
void
partial_sort(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
void
partial_sort(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _BIter, typename _Predicate>
_BIter
partition(_BIter, _BIter, _Predicate);
template<typename _RAIter>
void
random_shuffle(_RAIter, _RAIter);
template<typename _RAIter, typename _Generator>
void
random_shuffle(_RAIter, _RAIter,
#if __cplusplus >= 201103L
_Generator&&);
#else
_Generator&);
#endif
template<typename _FIter, typename _Tp>
void
replace(_FIter, _FIter, const _Tp&, const _Tp&);
template<typename _FIter, typename _Predicate, typename _Tp>
void
replace_if(_FIter, _FIter, _Predicate, const _Tp&);
template<typename _FIter1, typename _FIter2>
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _FIter, typename _Size, typename _Tp>
_FIter
search_n(_FIter, _FIter, _Size, const _Tp&);
template<typename _FIter, typename _Size, typename _Tp,
typename _BinaryPredicate>
_FIter
search_n(_FIter, _FIter, _Size, const _Tp&, _BinaryPredicate);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2,
_OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _RAIter>
void
sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
void
sort(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
void
stable_sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
void
stable_sort(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _OIter, typename _UnaryOperation>
_OIter
transform(_IIter, _IIter, _OIter, _UnaryOperation);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _BinaryOperation>
_OIter
transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation);
template<typename _IIter, typename _OIter>
_OIter
unique_copy(_IIter, _IIter, _OIter);
template<typename _IIter, typename _OIter, typename _BinaryPredicate>
_OIter
unique_copy(_IIter, _IIter, _OIter, _BinaryPredicate);
_GLIBCXX_END_NAMESPACE_ALGO
} // namespace std
#ifdef _GLIBCXX_PARALLEL
# include <parallel/algorithmfwd.h>
#endif
#endif

View File

@@ -0,0 +1,566 @@
// Allocator traits -*- C++ -*-
// Copyright (C) 2011-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/alloc_traits.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _ALLOC_TRAITS_H
#define _ALLOC_TRAITS_H 1
#if __cplusplus >= 201103L
#include <bits/memoryfwd.h>
#include <bits/ptr_traits.h>
#include <ext/numeric_traits.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Alloc, typename _Tp>
class __alloctr_rebind_helper
{
template<typename _Alloc2, typename _Tp2>
static constexpr bool
_S_chk(typename _Alloc2::template rebind<_Tp2>::other*)
{ return true; }
template<typename, typename>
static constexpr bool
_S_chk(...)
{ return false; }
public:
static const bool __value = _S_chk<_Alloc, _Tp>(nullptr);
};
template<typename _Alloc, typename _Tp>
const bool __alloctr_rebind_helper<_Alloc, _Tp>::__value;
template<typename _Alloc, typename _Tp,
bool = __alloctr_rebind_helper<_Alloc, _Tp>::__value>
struct __alloctr_rebind;
template<typename _Alloc, typename _Tp>
struct __alloctr_rebind<_Alloc, _Tp, true>
{
typedef typename _Alloc::template rebind<_Tp>::other __type;
};
template<template<typename, typename...> class _Alloc, typename _Tp,
typename _Up, typename... _Args>
struct __alloctr_rebind<_Alloc<_Up, _Args...>, _Tp, false>
{
typedef _Alloc<_Tp, _Args...> __type;
};
/**
* @brief Uniform interface to all allocator types.
* @ingroup allocators
*/
template<typename _Alloc>
struct allocator_traits
{
/// The allocator type
typedef _Alloc allocator_type;
/// The allocated type
typedef typename _Alloc::value_type value_type;
#define _GLIBCXX_ALLOC_TR_NESTED_TYPE(_NTYPE, _ALT) \
private: \
template<typename _Tp> \
static typename _Tp::_NTYPE _S_##_NTYPE##_helper(_Tp*); \
static _ALT _S_##_NTYPE##_helper(...); \
typedef decltype(_S_##_NTYPE##_helper((_Alloc*)0)) __##_NTYPE; \
public:
_GLIBCXX_ALLOC_TR_NESTED_TYPE(pointer, value_type*)
/**
* @brief The allocator's pointer type.
*
* @c Alloc::pointer if that type exists, otherwise @c value_type*
*/
typedef __pointer pointer;
_GLIBCXX_ALLOC_TR_NESTED_TYPE(const_pointer,
typename pointer_traits<pointer>::template rebind<const value_type>)
/**
* @brief The allocator's const pointer type.
*
* @c Alloc::const_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<const value_type> </tt>
*/
typedef __const_pointer const_pointer;
_GLIBCXX_ALLOC_TR_NESTED_TYPE(void_pointer,
typename pointer_traits<pointer>::template rebind<void>)
/**
* @brief The allocator's void pointer type.
*
* @c Alloc::void_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<void> </tt>
*/
typedef __void_pointer void_pointer;
_GLIBCXX_ALLOC_TR_NESTED_TYPE(const_void_pointer,
typename pointer_traits<pointer>::template rebind<const void>)
/**
* @brief The allocator's const void pointer type.
*
* @c Alloc::const_void_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<const void> </tt>
*/
typedef __const_void_pointer const_void_pointer;
_GLIBCXX_ALLOC_TR_NESTED_TYPE(difference_type,
typename pointer_traits<pointer>::difference_type)
/**
* @brief The allocator's difference type
*
* @c Alloc::difference_type if that type exists, otherwise
* <tt> pointer_traits<pointer>::difference_type </tt>
*/
typedef __difference_type difference_type;
_GLIBCXX_ALLOC_TR_NESTED_TYPE(size_type,
typename make_unsigned<difference_type>::type)
/**
* @brief The allocator's size type
*
* @c Alloc::size_type if that type exists, otherwise
* <tt> make_unsigned<difference_type>::type </tt>
*/
typedef __size_type size_type;
_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_copy_assignment,
false_type)
/**
* @brief How the allocator is propagated on copy assignment
*
* @c Alloc::propagate_on_container_copy_assignment if that type exists,
* otherwise @c false_type
*/
typedef __propagate_on_container_copy_assignment
propagate_on_container_copy_assignment;
_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_move_assignment,
false_type)
/**
* @brief How the allocator is propagated on move assignment
*
* @c Alloc::propagate_on_container_move_assignment if that type exists,
* otherwise @c false_type
*/
typedef __propagate_on_container_move_assignment
propagate_on_container_move_assignment;
_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
false_type)
/**
* @brief How the allocator is propagated on swap
*
* @c Alloc::propagate_on_container_swap if that type exists,
* otherwise @c false_type
*/
typedef __propagate_on_container_swap propagate_on_container_swap;
#undef _GLIBCXX_ALLOC_TR_NESTED_TYPE
template<typename _Tp>
using rebind_alloc = typename __alloctr_rebind<_Alloc, _Tp>::__type;
template<typename _Tp>
using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
private:
template<typename _Alloc2>
struct __allocate_helper
{
template<typename _Alloc3,
typename = decltype(std::declval<_Alloc3*>()->allocate(
std::declval<size_type>(),
std::declval<const_void_pointer>()))>
static true_type __test(int);
template<typename>
static false_type __test(...);
typedef decltype(__test<_Alloc>(0)) type;
static const bool value = type::value;
};
template<typename _Alloc2>
static typename
enable_if<__allocate_helper<_Alloc2>::value, pointer>::type
_S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint)
{ return __a.allocate(__n, __hint); }
template<typename _Alloc2>
static typename
enable_if<!__allocate_helper<_Alloc2>::value, pointer>::type
_S_allocate(_Alloc2& __a, size_type __n, ...)
{ return __a.allocate(__n); }
template<typename _Tp, typename... _Args>
struct __construct_helper
{
template<typename _Alloc2,
typename = decltype(std::declval<_Alloc2*>()->construct(
std::declval<_Tp*>(), std::declval<_Args>()...))>
static true_type __test(int);
template<typename>
static false_type __test(...);
typedef decltype(__test<_Alloc>(0)) type;
static const bool value = type::value;
};
template<typename _Tp, typename... _Args>
static typename
enable_if<__construct_helper<_Tp, _Args...>::value, void>::type
_S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
{ __a.construct(__p, std::forward<_Args>(__args)...); }
template<typename _Tp, typename... _Args>
static typename
enable_if<__and_<__not_<__construct_helper<_Tp, _Args...>>,
is_constructible<_Tp, _Args...>>::value, void>::type
_S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
{ ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); }
template<typename _Tp>
struct __destroy_helper
{
template<typename _Alloc2,
typename = decltype(std::declval<_Alloc2*>()->destroy(
std::declval<_Tp*>()))>
static true_type __test(int);
template<typename>
static false_type __test(...);
typedef decltype(__test<_Alloc>(0)) type;
static const bool value = type::value;
};
template<typename _Tp>
static typename enable_if<__destroy_helper<_Tp>::value, void>::type
_S_destroy(_Alloc& __a, _Tp* __p)
{ __a.destroy(__p); }
template<typename _Tp>
static typename enable_if<!__destroy_helper<_Tp>::value, void>::type
_S_destroy(_Alloc&, _Tp* __p)
{ __p->~_Tp(); }
template<typename _Alloc2>
struct __maxsize_helper
{
template<typename _Alloc3,
typename = decltype(std::declval<_Alloc3*>()->max_size())>
static true_type __test(int);
template<typename>
static false_type __test(...);
typedef decltype(__test<_Alloc2>(0)) type;
static const bool value = type::value;
};
template<typename _Alloc2>
static typename
enable_if<__maxsize_helper<_Alloc2>::value, size_type>::type
_S_max_size(_Alloc2& __a)
{ return __a.max_size(); }
template<typename _Alloc2>
static typename
enable_if<!__maxsize_helper<_Alloc2>::value, size_type>::type
_S_max_size(_Alloc2&)
{ return __gnu_cxx::__numeric_traits<size_type>::__max; }
template<typename _Alloc2>
struct __select_helper
{
template<typename _Alloc3, typename
= decltype(std::declval<_Alloc3*>()
->select_on_container_copy_construction())>
static true_type __test(int);
template<typename>
static false_type __test(...);
typedef decltype(__test<_Alloc2>(0)) type;
static const bool value = type::value;
};
template<typename _Alloc2>
static typename
enable_if<__select_helper<_Alloc2>::value, _Alloc2>::type
_S_select(_Alloc2& __a)
{ return __a.select_on_container_copy_construction(); }
template<typename _Alloc2>
static typename
enable_if<!__select_helper<_Alloc2>::value, _Alloc2>::type
_S_select(_Alloc2& __a)
{ return __a; }
public:
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
*
* Calls @c a.allocate(n)
*/
static pointer
allocate(_Alloc& __a, size_type __n)
{ return __a.allocate(__n); }
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
* @param __hint Aid to locality.
* @return Memory of suitable size and alignment for @a n objects
* of type @c value_type
*
* Returns <tt> a.allocate(n, hint) </tt> if that expression is
* well-formed, otherwise returns @c a.allocate(n)
*/
static pointer
allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
{ return _S_allocate(__a, __n, __hint); }
/**
* @brief Deallocate memory.
* @param __a An allocator.
* @param __p Pointer to the memory to deallocate.
* @param __n The number of objects space was allocated for.
*
* Calls <tt> a.deallocate(p, n) </tt>
*/
static void deallocate(_Alloc& __a, pointer __p, size_type __n)
{ __a.deallocate(__p, __n); }
/**
* @brief Construct an object of type @a _Tp
* @param __a An allocator.
* @param __p Pointer to memory of suitable size and alignment for Tp
* @param __args Constructor arguments.
*
* Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
* if that expression is well-formed, otherwise uses placement-new
* to construct an object of type @a _Tp at location @a __p from the
* arguments @a __args...
*/
template<typename _Tp, typename... _Args>
static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
-> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
{ _S_construct(__a, __p, std::forward<_Args>(__args)...); }
/**
* @brief Destroy an object of type @a _Tp
* @param __a An allocator.
* @param __p Pointer to the object to destroy
*
* Calls @c __a.destroy(__p) if that expression is well-formed,
* otherwise calls @c __p->~_Tp()
*/
template <class _Tp>
static void destroy(_Alloc& __a, _Tp* __p)
{ _S_destroy(__a, __p); }
/**
* @brief The maximum supported allocation size
* @param __a An allocator.
* @return @c __a.max_size() or @c numeric_limits<size_type>::max()
*
* Returns @c __a.max_size() if that expression is well-formed,
* otherwise returns @c numeric_limits<size_type>::max()
*/
static size_type max_size(const _Alloc& __a)
{ return _S_max_size(__a); }
/**
* @brief Obtain an allocator to use when copying a container.
* @param __rhs An allocator.
* @return @c __rhs.select_on_container_copy_construction() or @a __rhs
*
* Returns @c __rhs.select_on_container_copy_construction() if that
* expression is well-formed, otherwise returns @a __rhs
*/
static _Alloc
select_on_container_copy_construction(const _Alloc& __rhs)
{ return _S_select(__rhs); }
};
template<typename _Alloc>
template<typename _Alloc2>
const bool allocator_traits<_Alloc>::__allocate_helper<_Alloc2>::value;
template<typename _Alloc>
template<typename _Tp, typename... _Args>
const bool
allocator_traits<_Alloc>::__construct_helper<_Tp, _Args...>::value;
template<typename _Alloc>
template<typename _Tp>
const bool allocator_traits<_Alloc>::__destroy_helper<_Tp>::value;
template<typename _Alloc>
template<typename _Alloc2>
const bool allocator_traits<_Alloc>::__maxsize_helper<_Alloc2>::value;
template<typename _Alloc>
template<typename _Alloc2>
const bool allocator_traits<_Alloc>::__select_helper<_Alloc2>::value;
template<typename _Alloc>
inline void
__do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
{ __one = __two; }
template<typename _Alloc>
inline void
__do_alloc_on_copy(_Alloc&, const _Alloc&, false_type)
{ }
template<typename _Alloc>
inline void __alloc_on_copy(_Alloc& __one, const _Alloc& __two)
{
typedef allocator_traits<_Alloc> __traits;
typedef typename __traits::propagate_on_container_copy_assignment __pocca;
__do_alloc_on_copy(__one, __two, __pocca());
}
template<typename _Alloc>
inline _Alloc __alloc_on_copy(const _Alloc& __a)
{
typedef allocator_traits<_Alloc> __traits;
return __traits::select_on_container_copy_construction(__a);
}
template<typename _Alloc>
inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
{ __one = std::move(__two); }
template<typename _Alloc>
inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
{ }
template<typename _Alloc>
inline void __alloc_on_move(_Alloc& __one, _Alloc& __two)
{
typedef allocator_traits<_Alloc> __traits;
typedef typename __traits::propagate_on_container_move_assignment __pocma;
__do_alloc_on_move(__one, __two, __pocma());
}
template<typename _Alloc>
inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
{
using std::swap;
swap(__one, __two);
}
template<typename _Alloc>
inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
{ }
template<typename _Alloc>
inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two)
{
typedef allocator_traits<_Alloc> __traits;
typedef typename __traits::propagate_on_container_swap __pocs;
__do_alloc_on_swap(__one, __two, __pocs());
}
template<typename _Alloc>
class __is_copy_insertable_impl
{
typedef allocator_traits<_Alloc> _Traits;
template<typename _Up, typename
= decltype(_Traits::construct(std::declval<_Alloc&>(),
std::declval<_Up*>(),
std::declval<const _Up&>()))>
static true_type
_M_select(int);
template<typename _Up>
static false_type
_M_select(...);
public:
typedef decltype(_M_select<typename _Alloc::value_type>(0)) type;
};
// true if _Alloc::value_type is CopyInsertable into containers using _Alloc
template<typename _Alloc>
struct __is_copy_insertable
: __is_copy_insertable_impl<_Alloc>::type
{ };
// std::allocator<_Tp> just requires CopyConstructible
template<typename _Tp>
struct __is_copy_insertable<allocator<_Tp>>
: is_copy_constructible<_Tp>
{ };
// Used to allow copy construction of unordered containers
template<bool> struct __allow_copy_cons { };
// Used to delete copy constructor of unordered containers
template<>
struct __allow_copy_cons<false>
{
__allow_copy_cons() = default;
__allow_copy_cons(const __allow_copy_cons&) = delete;
__allow_copy_cons(__allow_copy_cons&&) = default;
__allow_copy_cons& operator=(const __allow_copy_cons&) = default;
__allow_copy_cons& operator=(__allow_copy_cons&&) = default;
};
template<typename _Alloc>
using __check_copy_constructible
= __allow_copy_cons<__is_copy_insertable<_Alloc>::value>;
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif
#endif

View File

@@ -0,0 +1,221 @@
// Allocators -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
* Copyright (c) 1996-1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/allocator.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _ALLOCATOR_H
#define _ALLOCATOR_H 1
#include <bits/c++allocator.h> // Define the base class to std::allocator.
#include <bits/memoryfwd.h>
#if __cplusplus >= 201103L
#include <type_traits>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup allocators
* @{
*/
/// allocator<void> specialization.
template<>
class allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
template<typename _Tp1>
struct rebind
{ typedef allocator<_Tp1> other; };
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. std::allocator propagate_on_container_move_assignment
typedef true_type propagate_on_container_move_assignment;
#endif
};
/**
* @brief The @a standard allocator, as per [20.4].
*
* See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt04ch11.html
* for further details.
*
* @tparam _Tp Type of allocated object.
*/
template<typename _Tp>
class allocator: public __allocator_base<_Tp>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef _Tp value_type;
template<typename _Tp1>
struct rebind
{ typedef allocator<_Tp1> other; };
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. std::allocator propagate_on_container_move_assignment
typedef true_type propagate_on_container_move_assignment;
#endif
allocator() throw() { }
allocator(const allocator& __a) throw()
: __allocator_base<_Tp>(__a) { }
template<typename _Tp1>
allocator(const allocator<_Tp1>&) throw() { }
~allocator() throw() { }
// Inherit everything else.
};
template<typename _T1, typename _T2>
inline bool
operator==(const allocator<_T1>&, const allocator<_T2>&)
{ return true; }
template<typename _Tp>
inline bool
operator==(const allocator<_Tp>&, const allocator<_Tp>&)
{ return true; }
template<typename _T1, typename _T2>
inline bool
operator!=(const allocator<_T1>&, const allocator<_T2>&)
{ return false; }
template<typename _Tp>
inline bool
operator!=(const allocator<_Tp>&, const allocator<_Tp>&)
{ return false; }
/// @} group allocator
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class allocator<char>;
extern template class allocator<wchar_t>;
#endif
// Undefine.
#undef __allocator_base
// To implement Option 3 of DR 431.
template<typename _Alloc, bool = __is_empty(_Alloc)>
struct __alloc_swap
{ static void _S_do_it(_Alloc&, _Alloc&) { } };
template<typename _Alloc>
struct __alloc_swap<_Alloc, false>
{
static void
_S_do_it(_Alloc& __one, _Alloc& __two)
{
// Precondition: swappable allocators.
if (__one != __two)
swap(__one, __two);
}
};
// Optimize for stateless allocators.
template<typename _Alloc, bool = __is_empty(_Alloc)>
struct __alloc_neq
{
static bool
_S_do_it(const _Alloc&, const _Alloc&)
{ return false; }
};
template<typename _Alloc>
struct __alloc_neq<_Alloc, false>
{
static bool
_S_do_it(const _Alloc& __one, const _Alloc& __two)
{ return __one != __two; }
};
#if __cplusplus >= 201103L
template<typename _Tp, bool
= __or_<is_copy_constructible<typename _Tp::value_type>,
is_nothrow_move_constructible<typename _Tp::value_type>>::value>
struct __shrink_to_fit_aux
{ static bool _S_do_it(_Tp&) { return false; } };
template<typename _Tp>
struct __shrink_to_fit_aux<_Tp, true>
{
static bool
_S_do_it(_Tp& __c)
{
__try
{
_Tp(__make_move_if_noexcept_iterator(__c.begin()),
__make_move_if_noexcept_iterator(__c.end()),
__c.get_allocator()).swap(__c);
return true;
}
__catch(...)
{ return false; }
}
};
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

View File

@@ -0,0 +1,888 @@
// -*- C++ -*- header.
// Copyright (C) 2008-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/atomic_base.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{atomic}
*/
#ifndef _GLIBCXX_ATOMIC_BASE_H
#define _GLIBCXX_ATOMIC_BASE_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <stdbool.h>
#include <stdint.h>
#include <bits/atomic_lockfree_defines.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup atomics Atomics
*
* Components for performing atomic operations.
* @{
*/
/// Enumeration for memory_order
typedef enum memory_order
{
memory_order_relaxed,
memory_order_consume,
memory_order_acquire,
memory_order_release,
memory_order_acq_rel,
memory_order_seq_cst
} memory_order;
enum __memory_order_modifier
{
__memory_order_mask = 0x0ffff,
__memory_order_modifier_mask = 0xffff0000,
__memory_order_hle_acquire = 0x10000,
__memory_order_hle_release = 0x20000
};
constexpr memory_order
operator|(memory_order __m, __memory_order_modifier __mod)
{
return memory_order(__m | int(__mod));
}
constexpr memory_order
operator&(memory_order __m, __memory_order_modifier __mod)
{
return memory_order(__m & int(__mod));
}
// Drop release ordering as per [atomics.types.operations.req]/21
constexpr memory_order
__cmpexch_failure_order2(memory_order __m) noexcept
{
return __m == memory_order_acq_rel ? memory_order_acquire
: __m == memory_order_release ? memory_order_relaxed : __m;
}
constexpr memory_order
__cmpexch_failure_order(memory_order __m) noexcept
{
return memory_order(__cmpexch_failure_order2(__m & __memory_order_mask)
| (__m & __memory_order_modifier_mask));
}
inline void
atomic_thread_fence(memory_order __m) noexcept
{ __atomic_thread_fence(__m); }
inline void
atomic_signal_fence(memory_order __m) noexcept
{ __atomic_signal_fence(__m); }
/// kill_dependency
template<typename _Tp>
inline _Tp
kill_dependency(_Tp __y) noexcept
{
_Tp __ret(__y);
return __ret;
}
// Base types for atomics.
template<typename _IntTp>
struct __atomic_base;
/// atomic_char
typedef __atomic_base<char> atomic_char;
/// atomic_schar
typedef __atomic_base<signed char> atomic_schar;
/// atomic_uchar
typedef __atomic_base<unsigned char> atomic_uchar;
/// atomic_short
typedef __atomic_base<short> atomic_short;
/// atomic_ushort
typedef __atomic_base<unsigned short> atomic_ushort;
/// atomic_int
typedef __atomic_base<int> atomic_int;
/// atomic_uint
typedef __atomic_base<unsigned int> atomic_uint;
/// atomic_long
typedef __atomic_base<long> atomic_long;
/// atomic_ulong
typedef __atomic_base<unsigned long> atomic_ulong;
/// atomic_llong
typedef __atomic_base<long long> atomic_llong;
/// atomic_ullong
typedef __atomic_base<unsigned long long> atomic_ullong;
/// atomic_wchar_t
typedef __atomic_base<wchar_t> atomic_wchar_t;
/// atomic_char16_t
typedef __atomic_base<char16_t> atomic_char16_t;
/// atomic_char32_t
typedef __atomic_base<char32_t> atomic_char32_t;
/// atomic_char32_t
typedef __atomic_base<char32_t> atomic_char32_t;
/// atomic_int_least8_t
typedef __atomic_base<int_least8_t> atomic_int_least8_t;
/// atomic_uint_least8_t
typedef __atomic_base<uint_least8_t> atomic_uint_least8_t;
/// atomic_int_least16_t
typedef __atomic_base<int_least16_t> atomic_int_least16_t;
/// atomic_uint_least16_t
typedef __atomic_base<uint_least16_t> atomic_uint_least16_t;
/// atomic_int_least32_t
typedef __atomic_base<int_least32_t> atomic_int_least32_t;
/// atomic_uint_least32_t
typedef __atomic_base<uint_least32_t> atomic_uint_least32_t;
/// atomic_int_least64_t
typedef __atomic_base<int_least64_t> atomic_int_least64_t;
/// atomic_uint_least64_t
typedef __atomic_base<uint_least64_t> atomic_uint_least64_t;
/// atomic_int_fast8_t
typedef __atomic_base<int_fast8_t> atomic_int_fast8_t;
/// atomic_uint_fast8_t
typedef __atomic_base<uint_fast8_t> atomic_uint_fast8_t;
/// atomic_int_fast16_t
typedef __atomic_base<int_fast16_t> atomic_int_fast16_t;
/// atomic_uint_fast16_t
typedef __atomic_base<uint_fast16_t> atomic_uint_fast16_t;
/// atomic_int_fast32_t
typedef __atomic_base<int_fast32_t> atomic_int_fast32_t;
/// atomic_uint_fast32_t
typedef __atomic_base<uint_fast32_t> atomic_uint_fast32_t;
/// atomic_int_fast64_t
typedef __atomic_base<int_fast64_t> atomic_int_fast64_t;
/// atomic_uint_fast64_t
typedef __atomic_base<uint_fast64_t> atomic_uint_fast64_t;
/// atomic_intptr_t
typedef __atomic_base<intptr_t> atomic_intptr_t;
/// atomic_uintptr_t
typedef __atomic_base<uintptr_t> atomic_uintptr_t;
/// atomic_size_t
typedef __atomic_base<size_t> atomic_size_t;
/// atomic_intmax_t
typedef __atomic_base<intmax_t> atomic_intmax_t;
/// atomic_uintmax_t
typedef __atomic_base<uintmax_t> atomic_uintmax_t;
/// atomic_ptrdiff_t
typedef __atomic_base<ptrdiff_t> atomic_ptrdiff_t;
#define ATOMIC_VAR_INIT(_VI) { _VI }
template<typename _Tp>
struct atomic;
template<typename _Tp>
struct atomic<_Tp*>;
/* The target's "set" value for test-and-set may not be exactly 1. */
#if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1
typedef bool __atomic_flag_data_type;
#else
typedef unsigned char __atomic_flag_data_type;
#endif
/**
* @brief Base type for atomic_flag.
*
* Base type is POD with data, allowing atomic_flag to derive from
* it and meet the standard layout type requirement. In addition to
* compatibilty with a C interface, this allows different
* implementations of atomic_flag to use the same atomic operation
* functions, via a standard conversion to the __atomic_flag_base
* argument.
*/
_GLIBCXX_BEGIN_EXTERN_C
struct __atomic_flag_base
{
__atomic_flag_data_type _M_i;
};
_GLIBCXX_END_EXTERN_C
#define ATOMIC_FLAG_INIT { 0 }
/// atomic_flag
struct atomic_flag : public __atomic_flag_base
{
atomic_flag() noexcept = default;
~atomic_flag() noexcept = default;
atomic_flag(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) volatile = delete;
// Conversion to ATOMIC_FLAG_INIT.
constexpr atomic_flag(bool __i) noexcept
: __atomic_flag_base{ _S_init(__i) }
{ }
bool
test_and_set(memory_order __m = memory_order_seq_cst) noexcept
{
return __atomic_test_and_set (&_M_i, __m);
}
bool
test_and_set(memory_order __m = memory_order_seq_cst) volatile noexcept
{
return __atomic_test_and_set (&_M_i, __m);
}
void
clear(memory_order __m = memory_order_seq_cst) noexcept
{
memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_consume);
__glibcxx_assert(__b != memory_order_acquire);
__glibcxx_assert(__b != memory_order_acq_rel);
__atomic_clear (&_M_i, __m);
}
void
clear(memory_order __m = memory_order_seq_cst) volatile noexcept
{
memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_consume);
__glibcxx_assert(__b != memory_order_acquire);
__glibcxx_assert(__b != memory_order_acq_rel);
__atomic_clear (&_M_i, __m);
}
private:
static constexpr __atomic_flag_data_type
_S_init(bool __i)
{ return __i ? __GCC_ATOMIC_TEST_AND_SET_TRUEVAL : 0; }
};
/// Base class for atomic integrals.
//
// For each of the integral types, define atomic_[integral type] struct
//
// atomic_bool bool
// atomic_char char
// atomic_schar signed char
// atomic_uchar unsigned char
// atomic_short short
// atomic_ushort unsigned short
// atomic_int int
// atomic_uint unsigned int
// atomic_long long
// atomic_ulong unsigned long
// atomic_llong long long
// atomic_ullong unsigned long long
// atomic_char16_t char16_t
// atomic_char32_t char32_t
// atomic_wchar_t wchar_t
//
// NB: Assuming _ITp is an integral scalar type that is 1, 2, 4, or
// 8 bytes, since that is what GCC built-in functions for atomic
// memory access expect.
template<typename _ITp>
struct __atomic_base
{
private:
typedef _ITp __int_type;
__int_type _M_i;
public:
__atomic_base() noexcept = default;
~__atomic_base() noexcept = default;
__atomic_base(const __atomic_base&) = delete;
__atomic_base& operator=(const __atomic_base&) = delete;
__atomic_base& operator=(const __atomic_base&) volatile = delete;
// Requires __int_type convertible to _M_i.
constexpr __atomic_base(__int_type __i) noexcept : _M_i (__i) { }
operator __int_type() const noexcept
{ return load(); }
operator __int_type() const volatile noexcept
{ return load(); }
__int_type
operator=(__int_type __i) noexcept
{
store(__i);
return __i;
}
__int_type
operator=(__int_type __i) volatile noexcept
{
store(__i);
return __i;
}
__int_type
operator++(int) noexcept
{ return fetch_add(1); }
__int_type
operator++(int) volatile noexcept
{ return fetch_add(1); }
__int_type
operator--(int) noexcept
{ return fetch_sub(1); }
__int_type
operator--(int) volatile noexcept
{ return fetch_sub(1); }
__int_type
operator++() noexcept
{ return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
__int_type
operator++() volatile noexcept
{ return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
__int_type
operator--() noexcept
{ return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
__int_type
operator--() volatile noexcept
{ return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
__int_type
operator+=(__int_type __i) noexcept
{ return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
__int_type
operator+=(__int_type __i) volatile noexcept
{ return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
__int_type
operator-=(__int_type __i) noexcept
{ return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
__int_type
operator-=(__int_type __i) volatile noexcept
{ return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
__int_type
operator&=(__int_type __i) noexcept
{ return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
__int_type
operator&=(__int_type __i) volatile noexcept
{ return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
__int_type
operator|=(__int_type __i) noexcept
{ return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
__int_type
operator|=(__int_type __i) volatile noexcept
{ return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
__int_type
operator^=(__int_type __i) noexcept
{ return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
__int_type
operator^=(__int_type __i) volatile noexcept
{ return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
bool
is_lock_free() const noexcept
{ return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
bool
is_lock_free() const volatile noexcept
{ return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
void
store(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept
{
memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_acquire);
__glibcxx_assert(__b != memory_order_acq_rel);
__glibcxx_assert(__b != memory_order_consume);
__atomic_store_n(&_M_i, __i, __m);
}
void
store(__int_type __i,
memory_order __m = memory_order_seq_cst) volatile noexcept
{
memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_acquire);
__glibcxx_assert(__b != memory_order_acq_rel);
__glibcxx_assert(__b != memory_order_consume);
__atomic_store_n(&_M_i, __i, __m);
}
__int_type
load(memory_order __m = memory_order_seq_cst) const noexcept
{
memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_release);
__glibcxx_assert(__b != memory_order_acq_rel);
return __atomic_load_n(&_M_i, __m);
}
__int_type
load(memory_order __m = memory_order_seq_cst) const volatile noexcept
{
memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_release);
__glibcxx_assert(__b != memory_order_acq_rel);
return __atomic_load_n(&_M_i, __m);
}
__int_type
exchange(__int_type __i,
memory_order __m = memory_order_seq_cst) noexcept
{
return __atomic_exchange_n(&_M_i, __i, __m);
}
__int_type
exchange(__int_type __i,
memory_order __m = memory_order_seq_cst) volatile noexcept
{
return __atomic_exchange_n(&_M_i, __i, __m);
}
bool
compare_exchange_weak(__int_type& __i1, __int_type __i2,
memory_order __m1, memory_order __m2) noexcept
{
memory_order __b2 = __m2 & __memory_order_mask;
memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
}
bool
compare_exchange_weak(__int_type& __i1, __int_type __i2,
memory_order __m1,
memory_order __m2) volatile noexcept
{
memory_order __b2 = __m2 & __memory_order_mask;
memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
}
bool
compare_exchange_weak(__int_type& __i1, __int_type __i2,
memory_order __m = memory_order_seq_cst) noexcept
{
return compare_exchange_weak(__i1, __i2, __m,
__cmpexch_failure_order(__m));
}
bool
compare_exchange_weak(__int_type& __i1, __int_type __i2,
memory_order __m = memory_order_seq_cst) volatile noexcept
{
return compare_exchange_weak(__i1, __i2, __m,
__cmpexch_failure_order(__m));
}
bool
compare_exchange_strong(__int_type& __i1, __int_type __i2,
memory_order __m1, memory_order __m2) noexcept
{
memory_order __b2 = __m2 & __memory_order_mask;
memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
}
bool
compare_exchange_strong(__int_type& __i1, __int_type __i2,
memory_order __m1,
memory_order __m2) volatile noexcept
{
memory_order __b2 = __m2 & __memory_order_mask;
memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
}
bool
compare_exchange_strong(__int_type& __i1, __int_type __i2,
memory_order __m = memory_order_seq_cst) noexcept
{
return compare_exchange_strong(__i1, __i2, __m,
__cmpexch_failure_order(__m));
}
bool
compare_exchange_strong(__int_type& __i1, __int_type __i2,
memory_order __m = memory_order_seq_cst) volatile noexcept
{
return compare_exchange_strong(__i1, __i2, __m,
__cmpexch_failure_order(__m));
}
__int_type
fetch_add(__int_type __i,
memory_order __m = memory_order_seq_cst) noexcept
{ return __atomic_fetch_add(&_M_i, __i, __m); }
__int_type
fetch_add(__int_type __i,
memory_order __m = memory_order_seq_cst) volatile noexcept
{ return __atomic_fetch_add(&_M_i, __i, __m); }
__int_type
fetch_sub(__int_type __i,
memory_order __m = memory_order_seq_cst) noexcept
{ return __atomic_fetch_sub(&_M_i, __i, __m); }
__int_type
fetch_sub(__int_type __i,
memory_order __m = memory_order_seq_cst) volatile noexcept
{ return __atomic_fetch_sub(&_M_i, __i, __m); }
__int_type
fetch_and(__int_type __i,
memory_order __m = memory_order_seq_cst) noexcept
{ return __atomic_fetch_and(&_M_i, __i, __m); }
__int_type
fetch_and(__int_type __i,
memory_order __m = memory_order_seq_cst) volatile noexcept
{ return __atomic_fetch_and(&_M_i, __i, __m); }
__int_type
fetch_or(__int_type __i,
memory_order __m = memory_order_seq_cst) noexcept
{ return __atomic_fetch_or(&_M_i, __i, __m); }
__int_type
fetch_or(__int_type __i,
memory_order __m = memory_order_seq_cst) volatile noexcept
{ return __atomic_fetch_or(&_M_i, __i, __m); }
__int_type
fetch_xor(__int_type __i,
memory_order __m = memory_order_seq_cst) noexcept
{ return __atomic_fetch_xor(&_M_i, __i, __m); }
__int_type
fetch_xor(__int_type __i,
memory_order __m = memory_order_seq_cst) volatile noexcept
{ return __atomic_fetch_xor(&_M_i, __i, __m); }
};
/// Partial specialization for pointer types.
template<typename _PTp>
struct __atomic_base<_PTp*>
{
private:
typedef _PTp* __pointer_type;
__pointer_type _M_p;
// Factored out to facilitate explicit specialization.
constexpr ptrdiff_t
_M_type_size(ptrdiff_t __d) { return __d * sizeof(_PTp); }
constexpr ptrdiff_t
_M_type_size(ptrdiff_t __d) volatile { return __d * sizeof(_PTp); }
public:
__atomic_base() noexcept = default;
~__atomic_base() noexcept = default;
__atomic_base(const __atomic_base&) = delete;
__atomic_base& operator=(const __atomic_base&) = delete;
__atomic_base& operator=(const __atomic_base&) volatile = delete;
// Requires __pointer_type convertible to _M_p.
constexpr __atomic_base(__pointer_type __p) noexcept : _M_p (__p) { }
operator __pointer_type() const noexcept
{ return load(); }
operator __pointer_type() const volatile noexcept
{ return load(); }
__pointer_type
operator=(__pointer_type __p) noexcept
{
store(__p);
return __p;
}
__pointer_type
operator=(__pointer_type __p) volatile noexcept
{
store(__p);
return __p;
}
__pointer_type
operator++(int) noexcept
{ return fetch_add(1); }
__pointer_type
operator++(int) volatile noexcept
{ return fetch_add(1); }
__pointer_type
operator--(int) noexcept
{ return fetch_sub(1); }
__pointer_type
operator--(int) volatile noexcept
{ return fetch_sub(1); }
__pointer_type
operator++() noexcept
{ return __atomic_add_fetch(&_M_p, _M_type_size(1),
memory_order_seq_cst); }
__pointer_type
operator++() volatile noexcept
{ return __atomic_add_fetch(&_M_p, _M_type_size(1),
memory_order_seq_cst); }
__pointer_type
operator--() noexcept
{ return __atomic_sub_fetch(&_M_p, _M_type_size(1),
memory_order_seq_cst); }
__pointer_type
operator--() volatile noexcept
{ return __atomic_sub_fetch(&_M_p, _M_type_size(1),
memory_order_seq_cst); }
__pointer_type
operator+=(ptrdiff_t __d) noexcept
{ return __atomic_add_fetch(&_M_p, _M_type_size(__d),
memory_order_seq_cst); }
__pointer_type
operator+=(ptrdiff_t __d) volatile noexcept
{ return __atomic_add_fetch(&_M_p, _M_type_size(__d),
memory_order_seq_cst); }
__pointer_type
operator-=(ptrdiff_t __d) noexcept
{ return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
memory_order_seq_cst); }
__pointer_type
operator-=(ptrdiff_t __d) volatile noexcept
{ return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
memory_order_seq_cst); }
bool
is_lock_free() const noexcept
{ return __atomic_is_lock_free(_M_type_size(1), nullptr); }
bool
is_lock_free() const volatile noexcept
{ return __atomic_is_lock_free(_M_type_size(1), nullptr); }
void
store(__pointer_type __p,
memory_order __m = memory_order_seq_cst) noexcept
{
memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_acquire);
__glibcxx_assert(__b != memory_order_acq_rel);
__glibcxx_assert(__b != memory_order_consume);
__atomic_store_n(&_M_p, __p, __m);
}
void
store(__pointer_type __p,
memory_order __m = memory_order_seq_cst) volatile noexcept
{
memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_acquire);
__glibcxx_assert(__b != memory_order_acq_rel);
__glibcxx_assert(__b != memory_order_consume);
__atomic_store_n(&_M_p, __p, __m);
}
__pointer_type
load(memory_order __m = memory_order_seq_cst) const noexcept
{
memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_release);
__glibcxx_assert(__b != memory_order_acq_rel);
return __atomic_load_n(&_M_p, __m);
}
__pointer_type
load(memory_order __m = memory_order_seq_cst) const volatile noexcept
{
memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_release);
__glibcxx_assert(__b != memory_order_acq_rel);
return __atomic_load_n(&_M_p, __m);
}
__pointer_type
exchange(__pointer_type __p,
memory_order __m = memory_order_seq_cst) noexcept
{
return __atomic_exchange_n(&_M_p, __p, __m);
}
__pointer_type
exchange(__pointer_type __p,
memory_order __m = memory_order_seq_cst) volatile noexcept
{
return __atomic_exchange_n(&_M_p, __p, __m);
}
bool
compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
memory_order __m1,
memory_order __m2) noexcept
{
memory_order __b2 = __m2 & __memory_order_mask;
memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
}
bool
compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
memory_order __m1,
memory_order __m2) volatile noexcept
{
memory_order __b2 = __m2 & __memory_order_mask;
memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
}
__pointer_type
fetch_add(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) noexcept
{ return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
__pointer_type
fetch_add(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) volatile noexcept
{ return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
__pointer_type
fetch_sub(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) noexcept
{ return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
__pointer_type
fetch_sub(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) volatile noexcept
{ return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
};
// @} group atomics
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

View File

@@ -0,0 +1,63 @@
// -*- C++ -*- header.
// Copyright (C) 2008-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/atomic_lockfree_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{atomic}
*/
#ifndef _GLIBCXX_ATOMIC_LOCK_FREE_H
#define _GLIBCXX_ATOMIC_LOCK_FREE_H 1
#pragma GCC system_header
/**
* @addtogroup atomics
* @{
*/
/**
* Lock-free property.
*
* 0 indicates that the types are never lock-free.
* 1 indicates that the types are sometimes lock-free.
* 2 indicates that the types are always lock-free.
*/
#if __cplusplus >= 201103L
#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
#endif
// @} group atomics
#endif

View File

@@ -0,0 +1,477 @@
// Iostreams base classes -*- C++ -*-
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/basic_ios.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ios}
*/
#ifndef _BASIC_IOS_H
#define _BASIC_IOS_H 1
#pragma GCC system_header
#include <bits/localefwd.h>
#include <bits/locale_classes.h>
#include <bits/locale_facets.h>
#include <bits/streambuf_iterator.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Facet>
inline const _Facet&
__check_facet(const _Facet* __f)
{
if (!__f)
__throw_bad_cast();
return *__f;
}
/**
* @brief Template class basic_ios, virtual base class for all
* stream classes.
* @ingroup io
*
* @tparam _CharT Type of character stream.
* @tparam _Traits Traits for character type, defaults to
* char_traits<_CharT>.
*
* Most of the member functions called dispatched on stream objects
* (e.g., @c std::cout.foo(bar);) are consolidated in this class.
*/
template<typename _CharT, typename _Traits>
class basic_ios : public ios_base
{
public:
//@{
/**
* These are standard types. They permit a standardized way of
* referring to names of (or names dependent on) the template
* parameters, which are specific to the implementation.
*/
typedef _CharT char_type;
typedef typename _Traits::int_type int_type;
typedef typename _Traits::pos_type pos_type;
typedef typename _Traits::off_type off_type;
typedef _Traits traits_type;
//@}
//@{
/**
* These are non-standard types.
*/
typedef ctype<_CharT> __ctype_type;
typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> >
__num_put_type;
typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> >
__num_get_type;
//@}
// Data members:
protected:
basic_ostream<_CharT, _Traits>* _M_tie;
mutable char_type _M_fill;
mutable bool _M_fill_init;
basic_streambuf<_CharT, _Traits>* _M_streambuf;
// Cached use_facet<ctype>, which is based on the current locale info.
const __ctype_type* _M_ctype;
// For ostream.
const __num_put_type* _M_num_put;
// For istream.
const __num_get_type* _M_num_get;
public:
//@{
/**
* @brief The quick-and-easy status check.
*
* This allows you to write constructs such as
* <code>if (!a_stream) ...</code> and <code>while (a_stream) ...</code>
*/
operator void*() const
{ return this->fail() ? 0 : const_cast<basic_ios*>(this); }
bool
operator!() const
{ return this->fail(); }
//@}
/**
* @brief Returns the error state of the stream buffer.
* @return A bit pattern (well, isn't everything?)
*
* See std::ios_base::iostate for the possible bit values. Most
* users will call one of the interpreting wrappers, e.g., good().
*/
iostate
rdstate() const
{ return _M_streambuf_state; }
/**
* @brief [Re]sets the error state.
* @param __state The new state flag(s) to set.
*
* See std::ios_base::iostate for the possible bit values. Most
* users will not need to pass an argument.
*/
void
clear(iostate __state = goodbit);
/**
* @brief Sets additional flags in the error state.
* @param __state The additional state flag(s) to set.
*
* See std::ios_base::iostate for the possible bit values.
*/
void
setstate(iostate __state)
{ this->clear(this->rdstate() | __state); }
// Flip the internal state on for the proper state bits, then re
// throws the propagated exception if bit also set in
// exceptions().
void
_M_setstate(iostate __state)
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
_M_streambuf_state |= __state;
if (this->exceptions() & __state)
__throw_exception_again;
}
/**
* @brief Fast error checking.
* @return True if no error flags are set.
*
* A wrapper around rdstate.
*/
bool
good() const
{ return this->rdstate() == 0; }
/**
* @brief Fast error checking.
* @return True if the eofbit is set.
*
* Note that other iostate flags may also be set.
*/
bool
eof() const
{ return (this->rdstate() & eofbit) != 0; }
/**
* @brief Fast error checking.
* @return True if either the badbit or the failbit is set.
*
* Checking the badbit in fail() is historical practice.
* Note that other iostate flags may also be set.
*/
bool
fail() const
{ return (this->rdstate() & (badbit | failbit)) != 0; }
/**
* @brief Fast error checking.
* @return True if the badbit is set.
*
* Note that other iostate flags may also be set.
*/
bool
bad() const
{ return (this->rdstate() & badbit) != 0; }
/**
* @brief Throwing exceptions on errors.
* @return The current exceptions mask.
*
* This changes nothing in the stream. See the one-argument version
* of exceptions(iostate) for the meaning of the return value.
*/
iostate
exceptions() const
{ return _M_exception; }
/**
* @brief Throwing exceptions on errors.
* @param __except The new exceptions mask.
*
* By default, error flags are set silently. You can set an
* exceptions mask for each stream; if a bit in the mask becomes set
* in the error flags, then an exception of type
* std::ios_base::failure is thrown.
*
* If the error flag is already set when the exceptions mask is
* added, the exception is immediately thrown. Try running the
* following under GCC 3.1 or later:
* @code
* #include <iostream>
* #include <fstream>
* #include <exception>
*
* int main()
* {
* std::set_terminate (__gnu_cxx::__verbose_terminate_handler);
*
* std::ifstream f ("/etc/motd");
*
* std::cerr << "Setting badbit\n";
* f.setstate (std::ios_base::badbit);
*
* std::cerr << "Setting exception mask\n";
* f.exceptions (std::ios_base::badbit);
* }
* @endcode
*/
void
exceptions(iostate __except)
{
_M_exception = __except;
this->clear(_M_streambuf_state);
}
// Constructor/destructor:
/**
* @brief Constructor performs initialization.
*
* The parameter is passed by derived streams.
*/
explicit
basic_ios(basic_streambuf<_CharT, _Traits>* __sb)
: ios_base(), _M_tie(0), _M_fill(), _M_fill_init(false), _M_streambuf(0),
_M_ctype(0), _M_num_put(0), _M_num_get(0)
{ this->init(__sb); }
/**
* @brief Empty.
*
* The destructor does nothing. More specifically, it does not
* destroy the streambuf held by rdbuf().
*/
virtual
~basic_ios() { }
// Members:
/**
* @brief Fetches the current @e tied stream.
* @return A pointer to the tied stream, or NULL if the stream is
* not tied.
*
* A stream may be @e tied (or synchronized) to a second output
* stream. When this stream performs any I/O, the tied stream is
* first flushed. For example, @c std::cin is tied to @c std::cout.
*/
basic_ostream<_CharT, _Traits>*
tie() const
{ return _M_tie; }
/**
* @brief Ties this stream to an output stream.
* @param __tiestr The output stream.
* @return The previously tied output stream, or NULL if the stream
* was not tied.
*
* This sets up a new tie; see tie() for more.
*/
basic_ostream<_CharT, _Traits>*
tie(basic_ostream<_CharT, _Traits>* __tiestr)
{
basic_ostream<_CharT, _Traits>* __old = _M_tie;
_M_tie = __tiestr;
return __old;
}
/**
* @brief Accessing the underlying buffer.
* @return The current stream buffer.
*
* This does not change the state of the stream.
*/
basic_streambuf<_CharT, _Traits>*
rdbuf() const
{ return _M_streambuf; }
/**
* @brief Changing the underlying buffer.
* @param __sb The new stream buffer.
* @return The previous stream buffer.
*
* Associates a new buffer with the current stream, and clears the
* error state.
*
* Due to historical accidents which the LWG refuses to correct, the
* I/O library suffers from a design error: this function is hidden
* in derived classes by overrides of the zero-argument @c rdbuf(),
* which is non-virtual for hysterical raisins. As a result, you
* must use explicit qualifications to access this function via any
* derived class. For example:
*
* @code
* std::fstream foo; // or some other derived type
* std::streambuf* p = .....;
*
* foo.ios::rdbuf(p); // ios == basic_ios<char>
* @endcode
*/
basic_streambuf<_CharT, _Traits>*
rdbuf(basic_streambuf<_CharT, _Traits>* __sb);
/**
* @brief Copies fields of __rhs into this.
* @param __rhs The source values for the copies.
* @return Reference to this object.
*
* All fields of __rhs are copied into this object except that rdbuf()
* and rdstate() remain unchanged. All values in the pword and iword
* arrays are copied. Before copying, each callback is invoked with
* erase_event. After copying, each (new) callback is invoked with
* copyfmt_event. The final step is to copy exceptions().
*/
basic_ios&
copyfmt(const basic_ios& __rhs);
/**
* @brief Retrieves the @a empty character.
* @return The current fill character.
*
* It defaults to a space (' ') in the current locale.
*/
char_type
fill() const
{
if (!_M_fill_init)
{
_M_fill = this->widen(' ');
_M_fill_init = true;
}
return _M_fill;
}
/**
* @brief Sets a new @a empty character.
* @param __ch The new character.
* @return The previous fill character.
*
* The fill character is used to fill out space when P+ characters
* have been requested (e.g., via setw), Q characters are actually
* used, and Q<P. It defaults to a space (' ') in the current locale.
*/
char_type
fill(char_type __ch)
{
char_type __old = this->fill();
_M_fill = __ch;
return __old;
}
// Locales:
/**
* @brief Moves to a new locale.
* @param __loc The new locale.
* @return The previous locale.
*
* Calls @c ios_base::imbue(loc), and if a stream buffer is associated
* with this stream, calls that buffer's @c pubimbue(loc).
*
* Additional l10n notes are at
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
*/
locale
imbue(const locale& __loc);
/**
* @brief Squeezes characters.
* @param __c The character to narrow.
* @param __dfault The character to narrow.
* @return The narrowed character.
*
* Maps a character of @c char_type to a character of @c char,
* if possible.
*
* Returns the result of
* @code
* std::use_facet<ctype<char_type> >(getloc()).narrow(c,dfault)
* @endcode
*
* Additional l10n notes are at
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
*/
char
narrow(char_type __c, char __dfault) const
{ return __check_facet(_M_ctype).narrow(__c, __dfault); }
/**
* @brief Widens characters.
* @param __c The character to widen.
* @return The widened character.
*
* Maps a character of @c char to a character of @c char_type.
*
* Returns the result of
* @code
* std::use_facet<ctype<char_type> >(getloc()).widen(c)
* @endcode
*
* Additional l10n notes are at
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
*/
char_type
widen(char __c) const
{ return __check_facet(_M_ctype).widen(__c); }
protected:
// 27.4.5.1 basic_ios constructors
/**
* @brief Empty.
*
* The default constructor does nothing and is not normally
* accessible to users.
*/
basic_ios()
: ios_base(), _M_tie(0), _M_fill(char_type()), _M_fill_init(false),
_M_streambuf(0), _M_ctype(0), _M_num_put(0), _M_num_get(0)
{ }
/**
* @brief All setup is performed here.
*
* This is called from the public constructor. It is not virtual and
* cannot be redefined.
*/
void
init(basic_streambuf<_CharT, _Traits>* __sb);
void
_M_cache_locale(const locale& __loc);
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#include <bits/basic_ios.tcc>
#endif /* _BASIC_IOS_H */

View File

@@ -0,0 +1,188 @@
// basic_ios member functions -*- C++ -*-
// Copyright (C) 1999-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/basic_ios.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ios}
*/
#ifndef _BASIC_IOS_TCC
#define _BASIC_IOS_TCC 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
void
basic_ios<_CharT, _Traits>::clear(iostate __state)
{
if (this->rdbuf())
_M_streambuf_state = __state;
else
_M_streambuf_state = __state | badbit;
if (this->exceptions() & this->rdstate())
__throw_ios_failure(__N("basic_ios::clear"));
}
template<typename _CharT, typename _Traits>
basic_streambuf<_CharT, _Traits>*
basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb)
{
basic_streambuf<_CharT, _Traits>* __old = _M_streambuf;
_M_streambuf = __sb;
this->clear();
return __old;
}
template<typename _CharT, typename _Traits>
basic_ios<_CharT, _Traits>&
basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 292. effects of a.copyfmt (a)
if (this != &__rhs)
{
// Per 27.1.1, do not call imbue, yet must trash all caches
// associated with imbue()
// Alloc any new word array first, so if it fails we have "rollback".
_Words* __words = (__rhs._M_word_size <= _S_local_word_size) ?
_M_local_word : new _Words[__rhs._M_word_size];
// Bump refs before doing callbacks, for safety.
_Callback_list* __cb = __rhs._M_callbacks;
if (__cb)
__cb->_M_add_reference();
_M_call_callbacks(erase_event);
if (_M_word != _M_local_word)
{
delete [] _M_word;
_M_word = 0;
}
_M_dispose_callbacks();
// NB: Don't want any added during above.
_M_callbacks = __cb;
for (int __i = 0; __i < __rhs._M_word_size; ++__i)
__words[__i] = __rhs._M_word[__i];
_M_word = __words;
_M_word_size = __rhs._M_word_size;
this->flags(__rhs.flags());
this->width(__rhs.width());
this->precision(__rhs.precision());
this->tie(__rhs.tie());
this->fill(__rhs.fill());
_M_ios_locale = __rhs.getloc();
_M_cache_locale(_M_ios_locale);
_M_call_callbacks(copyfmt_event);
// The next is required to be the last assignment.
this->exceptions(__rhs.exceptions());
}
return *this;
}
// Locales:
template<typename _CharT, typename _Traits>
locale
basic_ios<_CharT, _Traits>::imbue(const locale& __loc)
{
locale __old(this->getloc());
ios_base::imbue(__loc);
_M_cache_locale(__loc);
if (this->rdbuf() != 0)
this->rdbuf()->pubimbue(__loc);
return __old;
}
template<typename _CharT, typename _Traits>
void
basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb)
{
// NB: This may be called more than once on the same object.
ios_base::_M_init();
// Cache locale data and specific facets used by iostreams.
_M_cache_locale(_M_ios_locale);
// NB: The 27.4.4.1 Postconditions Table specifies requirements
// after basic_ios::init() has been called. As part of this,
// fill() must return widen(' ') any time after init() has been
// called, which needs an imbued ctype facet of char_type to
// return without throwing an exception. Unfortunately,
// ctype<char_type> is not necessarily a required facet, so
// streams with char_type != [char, wchar_t] will not have it by
// default. Because of this, the correct value for _M_fill is
// constructed on the first call of fill(). That way,
// unformatted input and output with non-required basic_ios
// instantiations is possible even without imbuing the expected
// ctype<char_type> facet.
_M_fill = _CharT();
_M_fill_init = false;
_M_tie = 0;
_M_exception = goodbit;
_M_streambuf = __sb;
_M_streambuf_state = __sb ? goodbit : badbit;
}
template<typename _CharT, typename _Traits>
void
basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc)
{
if (__builtin_expect(has_facet<__ctype_type>(__loc), true))
_M_ctype = &use_facet<__ctype_type>(__loc);
else
_M_ctype = 0;
if (__builtin_expect(has_facet<__num_put_type>(__loc), true))
_M_num_put = &use_facet<__num_put_type>(__loc);
else
_M_num_put = 0;
if (__builtin_expect(has_facet<__num_get_type>(__loc), true))
_M_num_get = &use_facet<__num_get_type>(__loc);
else
_M_num_get = 0;
}
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class basic_ios<char>;
#ifdef _GLIBCXX_USE_WCHAR_T
extern template class basic_ios<wchar_t>;
#endif
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,790 @@
// -*- C++ -*-
// Copyright (C) 2004-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
//
/** @file bits/boost_concept_check.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
// GCC Note: based on version 1.12.0 of the Boost library.
#ifndef _BOOST_CONCEPT_CHECK_H
#define _BOOST_CONCEPT_CHECK_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/stl_iterator_base_types.h> // for traits and tags
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#define _IsUnused __attribute__ ((__unused__))
// When the C-C code is in use, we would like this function to do as little
// as possible at runtime, use as few resources as possible, and hopefully
// be elided out of existence... hmmm.
template <class _Concept>
inline void __function_requires()
{
void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;
}
// No definition: if this is referenced, there's a problem with
// the instantiating type not being one of the required integer types.
// Unfortunately, this results in a link-time error, not a compile-time error.
void __error_type_must_be_an_integer_type();
void __error_type_must_be_an_unsigned_integer_type();
void __error_type_must_be_a_signed_integer_type();
// ??? Should the "concept_checking*" structs begin with more than _ ?
#define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \
typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \
template <_func##_type_var##_concept _Tp1> \
struct _concept_checking##_type_var##_concept { }; \
typedef _concept_checking##_type_var##_concept< \
&_ns::_concept <_type_var>::__constraints> \
_concept_checking_typedef##_type_var##_concept
#define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \
typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \
template <_func##_type_var1##_type_var2##_concept _Tp1> \
struct _concept_checking##_type_var1##_type_var2##_concept { }; \
typedef _concept_checking##_type_var1##_type_var2##_concept< \
&_ns::_concept <_type_var1,_type_var2>::__constraints> \
_concept_checking_typedef##_type_var1##_type_var2##_concept
#define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \
typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \
template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \
struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \
typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \
&_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \
_concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept
#define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \
typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \
template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \
struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \
typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \
&_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \
_concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept
template <class _Tp1, class _Tp2>
struct _Aux_require_same { };
template <class _Tp>
struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
template <class _Tp1, class _Tp2>
struct _SameTypeConcept
{
void __constraints() {
typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required;
}
};
template <class _Tp>
struct _IntegerConcept {
void __constraints() {
__error_type_must_be_an_integer_type();
}
};
template <> struct _IntegerConcept<short> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned short> { void __constraints(){} };
template <> struct _IntegerConcept<int> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned int> { void __constraints() {} };
template <> struct _IntegerConcept<long> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned long> { void __constraints() {} };
template <> struct _IntegerConcept<long long> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned long long>
{ void __constraints() {} };
template <class _Tp>
struct _SignedIntegerConcept {
void __constraints() {
__error_type_must_be_a_signed_integer_type();
}
};
template <> struct _SignedIntegerConcept<short> { void __constraints() {} };
template <> struct _SignedIntegerConcept<int> { void __constraints() {} };
template <> struct _SignedIntegerConcept<long> { void __constraints() {} };
template <> struct _SignedIntegerConcept<long long> { void __constraints(){}};
template <class _Tp>
struct _UnsignedIntegerConcept {
void __constraints() {
__error_type_must_be_an_unsigned_integer_type();
}
};
template <> struct _UnsignedIntegerConcept<unsigned short>
{ void __constraints() {} };
template <> struct _UnsignedIntegerConcept<unsigned int>
{ void __constraints() {} };
template <> struct _UnsignedIntegerConcept<unsigned long>
{ void __constraints() {} };
template <> struct _UnsignedIntegerConcept<unsigned long long>
{ void __constraints() {} };
//===========================================================================
// Basic Concepts
template <class _Tp>
struct _DefaultConstructibleConcept
{
void __constraints() {
_Tp __a _IsUnused; // require default constructor
}
};
template <class _Tp>
struct _AssignableConcept
{
void __constraints() {
__a = __a; // require assignment operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __b) {
__a = __b; // const required for argument to assignment
}
_Tp __a;
// possibly should be "Tp* a;" and then dereference "a" in constraint
// functions? present way would require a default ctor, i think...
};
template <class _Tp>
struct _CopyConstructibleConcept
{
void __constraints() {
_Tp __a(__b); // require copy constructor
_Tp* __ptr _IsUnused = &__a; // require address of operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __a) {
_Tp __c _IsUnused(__a); // require const copy constructor
const _Tp* __ptr _IsUnused = &__a; // require const address of operator
}
_Tp __b;
};
// The SGI STL version of Assignable requires copy constructor and operator=
template <class _Tp>
struct _SGIAssignableConcept
{
void __constraints() {
_Tp __b _IsUnused(__a);
__a = __a; // require assignment operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __b) {
_Tp __c _IsUnused(__b);
__a = __b; // const required for argument to assignment
}
_Tp __a;
};
template <class _From, class _To>
struct _ConvertibleConcept
{
void __constraints() {
_To __y _IsUnused = __x;
}
_From __x;
};
// The C++ standard requirements for many concepts talk about return
// types that must be "convertible to bool". The problem with this
// requirement is that it leaves the door open for evil proxies that
// define things like operator|| with strange return types. Two
// possible solutions are:
// 1) require the return type to be exactly bool
// 2) stay with convertible to bool, and also
// specify stuff about all the logical operators.
// For now we just test for convertible to bool.
template <class _Tp>
void __aux_require_boolean_expr(const _Tp& __t) {
bool __x _IsUnused = __t;
}
// FIXME
template <class _Tp>
struct _EqualityComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a == __b);
}
_Tp __a, __b;
};
template <class _Tp>
struct _LessThanComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a < __b);
}
_Tp __a, __b;
};
// This is equivalent to SGI STL's LessThanComparable.
template <class _Tp>
struct _ComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a < __b);
__aux_require_boolean_expr(__a > __b);
__aux_require_boolean_expr(__a <= __b);
__aux_require_boolean_expr(__a >= __b);
}
_Tp __a, __b;
};
#define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \
template <class _First, class _Second> \
struct _NAME { \
void __constraints() { (void)__constraints_(); } \
bool __constraints_() { \
return __a _OP __b; \
} \
_First __a; \
_Second __b; \
}
#define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \
template <class _Ret, class _First, class _Second> \
struct _NAME { \
void __constraints() { (void)__constraints_(); } \
_Ret __constraints_() { \
return __a _OP __b; \
} \
_First __a; \
_Second __b; \
}
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);
#undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT
#undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT
//===========================================================================
// Function Object Concepts
template <class _Func, class _Return>
struct _GeneratorConcept
{
void __constraints() {
const _Return& __r _IsUnused = __f();// require operator() member function
}
_Func __f;
};
template <class _Func>
struct _GeneratorConcept<_Func,void>
{
void __constraints() {
__f(); // require operator() member function
}
_Func __f;
};
template <class _Func, class _Return, class _Arg>
struct _UnaryFunctionConcept
{
void __constraints() {
__r = __f(__arg); // require operator()
}
_Func __f;
_Arg __arg;
_Return __r;
};
template <class _Func, class _Arg>
struct _UnaryFunctionConcept<_Func, void, _Arg> {
void __constraints() {
__f(__arg); // require operator()
}
_Func __f;
_Arg __arg;
};
template <class _Func, class _Return, class _First, class _Second>
struct _BinaryFunctionConcept
{
void __constraints() {
__r = __f(__first, __second); // require operator()
}
_Func __f;
_First __first;
_Second __second;
_Return __r;
};
template <class _Func, class _First, class _Second>
struct _BinaryFunctionConcept<_Func, void, _First, _Second>
{
void __constraints() {
__f(__first, __second); // require operator()
}
_Func __f;
_First __first;
_Second __second;
};
template <class _Func, class _Arg>
struct _UnaryPredicateConcept
{
void __constraints() {
__aux_require_boolean_expr(__f(__arg)); // require op() returning bool
}
_Func __f;
_Arg __arg;
};
template <class _Func, class _First, class _Second>
struct _BinaryPredicateConcept
{
void __constraints() {
__aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool
}
_Func __f;
_First __a;
_Second __b;
};
// use this when functor is used inside a container class like std::set
template <class _Func, class _First, class _Second>
struct _Const_BinaryPredicateConcept {
void __constraints() {
__const_constraints(__f);
}
void __const_constraints(const _Func& __fun) {
__function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >();
// operator() must be a const member function
__aux_require_boolean_expr(__fun(__a, __b));
}
_Func __f;
_First __a;
_Second __b;
};
//===========================================================================
// Iterator Concepts
template <class _Tp>
struct _TrivialIteratorConcept
{
void __constraints() {
// __function_requires< _DefaultConstructibleConcept<_Tp> >();
__function_requires< _AssignableConcept<_Tp> >();
__function_requires< _EqualityComparableConcept<_Tp> >();
// typedef typename std::iterator_traits<_Tp>::value_type _V;
(void)*__i; // require dereference operator
}
_Tp __i;
};
template <class _Tp>
struct _Mutable_TrivialIteratorConcept
{
void __constraints() {
__function_requires< _TrivialIteratorConcept<_Tp> >();
*__i = *__j; // require dereference and assignment
}
_Tp __i, __j;
};
template <class _Tp>
struct _InputIteratorConcept
{
void __constraints() {
__function_requires< _TrivialIteratorConcept<_Tp> >();
// require iterator_traits typedef's
typedef typename std::iterator_traits<_Tp>::difference_type _Diff;
// __function_requires< _SignedIntegerConcept<_Diff> >();
typedef typename std::iterator_traits<_Tp>::reference _Ref;
typedef typename std::iterator_traits<_Tp>::pointer _Pt;
typedef typename std::iterator_traits<_Tp>::iterator_category _Cat;
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::input_iterator_tag> >();
++__i; // require preincrement operator
__i++; // require postincrement operator
}
_Tp __i;
};
template <class _Tp, class _ValueT>
struct _OutputIteratorConcept
{
void __constraints() {
__function_requires< _AssignableConcept<_Tp> >();
++__i; // require preincrement operator
__i++; // require postincrement operator
*__i++ = __t; // require postincrement and assignment
}
_Tp __i;
_ValueT __t;
};
template <class _Tp>
struct _ForwardIteratorConcept
{
void __constraints() {
__function_requires< _InputIteratorConcept<_Tp> >();
__function_requires< _DefaultConstructibleConcept<_Tp> >();
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::forward_iterator_tag> >();
typedef typename std::iterator_traits<_Tp>::reference _Ref;
_Ref __r _IsUnused = *__i;
}
_Tp __i;
};
template <class _Tp>
struct _Mutable_ForwardIteratorConcept
{
void __constraints() {
__function_requires< _ForwardIteratorConcept<_Tp> >();
*__i++ = *__i; // require postincrement and assignment
}
_Tp __i;
};
template <class _Tp>
struct _BidirectionalIteratorConcept
{
void __constraints() {
__function_requires< _ForwardIteratorConcept<_Tp> >();
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::bidirectional_iterator_tag> >();
--__i; // require predecrement operator
__i--; // require postdecrement operator
}
_Tp __i;
};
template <class _Tp>
struct _Mutable_BidirectionalIteratorConcept
{
void __constraints() {
__function_requires< _BidirectionalIteratorConcept<_Tp> >();
__function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
*__i-- = *__i; // require postdecrement and assignment
}
_Tp __i;
};
template <class _Tp>
struct _RandomAccessIteratorConcept
{
void __constraints() {
__function_requires< _BidirectionalIteratorConcept<_Tp> >();
__function_requires< _ComparableConcept<_Tp> >();
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::random_access_iterator_tag> >();
// ??? We don't use _Ref, are we just checking for "referenceability"?
typedef typename std::iterator_traits<_Tp>::reference _Ref;
__i += __n; // require assignment addition operator
__i = __i + __n; __i = __n + __i; // require addition with difference type
__i -= __n; // require assignment subtraction op
__i = __i - __n; // require subtraction with
// difference type
__n = __i - __j; // require difference operator
(void)__i[__n]; // require element access operator
}
_Tp __a, __b;
_Tp __i, __j;
typename std::iterator_traits<_Tp>::difference_type __n;
};
template <class _Tp>
struct _Mutable_RandomAccessIteratorConcept
{
void __constraints() {
__function_requires< _RandomAccessIteratorConcept<_Tp> >();
__function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >();
__i[__n] = *__i; // require element access and assignment
}
_Tp __i;
typename std::iterator_traits<_Tp>::difference_type __n;
};
//===========================================================================
// Container Concepts
template <class _Container>
struct _ContainerConcept
{
typedef typename _Container::value_type _Value_type;
typedef typename _Container::difference_type _Difference_type;
typedef typename _Container::size_type _Size_type;
typedef typename _Container::const_reference _Const_reference;
typedef typename _Container::const_pointer _Const_pointer;
typedef typename _Container::const_iterator _Const_iterator;
void __constraints() {
__function_requires< _InputIteratorConcept<_Const_iterator> >();
__function_requires< _AssignableConcept<_Container> >();
const _Container __c;
__i = __c.begin();
__i = __c.end();
__n = __c.size();
__n = __c.max_size();
__b = __c.empty();
}
bool __b;
_Const_iterator __i;
_Size_type __n;
};
template <class _Container>
struct _Mutable_ContainerConcept
{
typedef typename _Container::value_type _Value_type;
typedef typename _Container::reference _Reference;
typedef typename _Container::iterator _Iterator;
typedef typename _Container::pointer _Pointer;
void __constraints() {
__function_requires< _ContainerConcept<_Container> >();
__function_requires< _AssignableConcept<_Value_type> >();
__function_requires< _InputIteratorConcept<_Iterator> >();
__i = __c.begin();
__i = __c.end();
__c.swap(__c2);
}
_Iterator __i;
_Container __c, __c2;
};
template <class _ForwardContainer>
struct _ForwardContainerConcept
{
void __constraints() {
__function_requires< _ContainerConcept<_ForwardContainer> >();
typedef typename _ForwardContainer::const_iterator _Const_iterator;
__function_requires< _ForwardIteratorConcept<_Const_iterator> >();
}
};
template <class _ForwardContainer>
struct _Mutable_ForwardContainerConcept
{
void __constraints() {
__function_requires< _ForwardContainerConcept<_ForwardContainer> >();
__function_requires< _Mutable_ContainerConcept<_ForwardContainer> >();
typedef typename _ForwardContainer::iterator _Iterator;
__function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >();
}
};
template <class _ReversibleContainer>
struct _ReversibleContainerConcept
{
typedef typename _ReversibleContainer::const_iterator _Const_iterator;
typedef typename _ReversibleContainer::const_reverse_iterator
_Const_reverse_iterator;
void __constraints() {
__function_requires< _ForwardContainerConcept<_ReversibleContainer> >();
__function_requires< _BidirectionalIteratorConcept<_Const_iterator> >();
__function_requires<
_BidirectionalIteratorConcept<_Const_reverse_iterator> >();
const _ReversibleContainer __c;
_Const_reverse_iterator __i = __c.rbegin();
__i = __c.rend();
}
};
template <class _ReversibleContainer>
struct _Mutable_ReversibleContainerConcept
{
typedef typename _ReversibleContainer::iterator _Iterator;
typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator;
void __constraints() {
__function_requires<_ReversibleContainerConcept<_ReversibleContainer> >();
__function_requires<
_Mutable_ForwardContainerConcept<_ReversibleContainer> >();
__function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >();
__function_requires<
_Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >();
_Reverse_iterator __i = __c.rbegin();
__i = __c.rend();
}
_ReversibleContainer __c;
};
template <class _RandomAccessContainer>
struct _RandomAccessContainerConcept
{
typedef typename _RandomAccessContainer::size_type _Size_type;
typedef typename _RandomAccessContainer::const_reference _Const_reference;
typedef typename _RandomAccessContainer::const_iterator _Const_iterator;
typedef typename _RandomAccessContainer::const_reverse_iterator
_Const_reverse_iterator;
void __constraints() {
__function_requires<
_ReversibleContainerConcept<_RandomAccessContainer> >();
__function_requires< _RandomAccessIteratorConcept<_Const_iterator> >();
__function_requires<
_RandomAccessIteratorConcept<_Const_reverse_iterator> >();
const _RandomAccessContainer __c;
_Const_reference __r _IsUnused = __c[__n];
}
_Size_type __n;
};
template <class _RandomAccessContainer>
struct _Mutable_RandomAccessContainerConcept
{
typedef typename _RandomAccessContainer::size_type _Size_type;
typedef typename _RandomAccessContainer::reference _Reference;
typedef typename _RandomAccessContainer::iterator _Iterator;
typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator;
void __constraints() {
__function_requires<
_RandomAccessContainerConcept<_RandomAccessContainer> >();
__function_requires<
_Mutable_ReversibleContainerConcept<_RandomAccessContainer> >();
__function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >();
__function_requires<
_Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >();
_Reference __r _IsUnused = __c[__i];
}
_Size_type __i;
_RandomAccessContainer __c;
};
// A Sequence is inherently mutable
template <class _Sequence>
struct _SequenceConcept
{
typedef typename _Sequence::reference _Reference;
typedef typename _Sequence::const_reference _Const_reference;
void __constraints() {
// Matt Austern's book puts DefaultConstructible here, the C++
// standard places it in Container
// function_requires< DefaultConstructible<Sequence> >();
__function_requires< _Mutable_ForwardContainerConcept<_Sequence> >();
__function_requires< _DefaultConstructibleConcept<_Sequence> >();
_Sequence
__c _IsUnused(__n, __t),
__c2 _IsUnused(__first, __last);
__c.insert(__p, __t);
__c.insert(__p, __n, __t);
__c.insert(__p, __first, __last);
__c.erase(__p);
__c.erase(__p, __q);
_Reference __r _IsUnused = __c.front();
__const_constraints(__c);
}
void __const_constraints(const _Sequence& __c) {
_Const_reference __r _IsUnused = __c.front();
}
typename _Sequence::value_type __t;
typename _Sequence::size_type __n;
typename _Sequence::value_type *__first, *__last;
typename _Sequence::iterator __p, __q;
};
template <class _FrontInsertionSequence>
struct _FrontInsertionSequenceConcept
{
void __constraints() {
__function_requires< _SequenceConcept<_FrontInsertionSequence> >();
__c.push_front(__t);
__c.pop_front();
}
_FrontInsertionSequence __c;
typename _FrontInsertionSequence::value_type __t;
};
template <class _BackInsertionSequence>
struct _BackInsertionSequenceConcept
{
typedef typename _BackInsertionSequence::reference _Reference;
typedef typename _BackInsertionSequence::const_reference _Const_reference;
void __constraints() {
__function_requires< _SequenceConcept<_BackInsertionSequence> >();
__c.push_back(__t);
__c.pop_back();
_Reference __r _IsUnused = __c.back();
}
void __const_constraints(const _BackInsertionSequence& __c) {
_Const_reference __r _IsUnused = __c.back();
};
_BackInsertionSequence __c;
typename _BackInsertionSequence::value_type __t;
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#undef _IsUnused
#endif // _GLIBCXX_BOOST_CONCEPT_CHECK

View File

@@ -0,0 +1,37 @@
// Copyright (C) 2007-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++0x_warning.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/
#ifndef _CXX0X_WARNING_H
#define _CXX0X_WARNING_H 1
#if __cplusplus < 201103L
#error This file requires compiler and library support for the \
ISO C++ 2011 standard. This support is currently experimental, and must be \
enabled with the -std=c++11 or -std=gnu++11 compiler options.
#endif
#endif

View File

@@ -0,0 +1,573 @@
// Character Traits for use by standard string and iostream -*- C++ -*-
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/char_traits.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{string}
*/
//
// ISO C++ 14882: 21 Strings library
//
#ifndef _CHAR_TRAITS_H
#define _CHAR_TRAITS_H 1
#pragma GCC system_header
#include <bits/stl_algobase.h> // std::copy, std::fill_n
#include <bits/postypes.h> // For streampos
#include <cwchar> // For WEOF, wmemmove, wmemset, etc.
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Mapping from character type to associated types.
*
* @note This is an implementation class for the generic version
* of char_traits. It defines int_type, off_type, pos_type, and
* state_type. By default these are unsigned long, streamoff,
* streampos, and mbstate_t. Users who need a different set of
* types, but who don't need to change the definitions of any function
* defined in char_traits, can specialize __gnu_cxx::_Char_types
* while leaving __gnu_cxx::char_traits alone. */
template<typename _CharT>
struct _Char_types
{
typedef unsigned long int_type;
typedef std::streampos pos_type;
typedef std::streamoff off_type;
typedef std::mbstate_t state_type;
};
/**
* @brief Base class used to implement std::char_traits.
*
* @note For any given actual character type, this definition is
* probably wrong. (Most of the member functions are likely to be
* right, but the int_type and state_type typedefs, and the eof()
* member function, are likely to be wrong.) The reason this class
* exists is so users can specialize it. Classes in namespace std
* may not be specialized for fundamental types, but classes in
* namespace __gnu_cxx may be.
*
* See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html
* for advice on how to make use of this class for @a unusual character
* types. Also, check out include/ext/pod_char_traits.h.
*/
template<typename _CharT>
struct char_traits
{
typedef _CharT char_type;
typedef typename _Char_types<_CharT>::int_type int_type;
typedef typename _Char_types<_CharT>::pos_type pos_type;
typedef typename _Char_types<_CharT>::off_type off_type;
typedef typename _Char_types<_CharT>::state_type state_type;
static void
assign(char_type& __c1, const char_type& __c2)
{ __c1 = __c2; }
static _GLIBCXX_CONSTEXPR bool
eq(const char_type& __c1, const char_type& __c2)
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR bool
lt(const char_type& __c1, const char_type& __c2)
{ return __c1 < __c2; }
static int
compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
static std::size_t
length(const char_type* __s);
static const char_type*
find(const char_type* __s, std::size_t __n, const char_type& __a);
static char_type*
move(char_type* __s1, const char_type* __s2, std::size_t __n);
static char_type*
copy(char_type* __s1, const char_type* __s2, std::size_t __n);
static char_type*
assign(char_type* __s, std::size_t __n, char_type __a);
static _GLIBCXX_CONSTEXPR char_type
to_char_type(const int_type& __c)
{ return static_cast<char_type>(__c); }
static _GLIBCXX_CONSTEXPR int_type
to_int_type(const char_type& __c)
{ return static_cast<int_type>(__c); }
static _GLIBCXX_CONSTEXPR bool
eq_int_type(const int_type& __c1, const int_type& __c2)
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR int_type
eof()
{ return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
static _GLIBCXX_CONSTEXPR int_type
not_eof(const int_type& __c)
{ return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
};
template<typename _CharT>
int
char_traits<_CharT>::
compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
{
for (std::size_t __i = 0; __i < __n; ++__i)
if (lt(__s1[__i], __s2[__i]))
return -1;
else if (lt(__s2[__i], __s1[__i]))
return 1;
return 0;
}
template<typename _CharT>
std::size_t
char_traits<_CharT>::
length(const char_type* __p)
{
std::size_t __i = 0;
while (!eq(__p[__i], char_type()))
++__i;
return __i;
}
template<typename _CharT>
const typename char_traits<_CharT>::char_type*
char_traits<_CharT>::
find(const char_type* __s, std::size_t __n, const char_type& __a)
{
for (std::size_t __i = 0; __i < __n; ++__i)
if (eq(__s[__i], __a))
return __s + __i;
return 0;
}
template<typename _CharT>
typename char_traits<_CharT>::char_type*
char_traits<_CharT>::
move(char_type* __s1, const char_type* __s2, std::size_t __n)
{
return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
__n * sizeof(char_type)));
}
template<typename _CharT>
typename char_traits<_CharT>::char_type*
char_traits<_CharT>::
copy(char_type* __s1, const char_type* __s2, std::size_t __n)
{
// NB: Inline std::copy so no recursive dependencies.
std::copy(__s2, __s2 + __n, __s1);
return __s1;
}
template<typename _CharT>
typename char_traits<_CharT>::char_type*
char_traits<_CharT>::
assign(char_type* __s, std::size_t __n, char_type __a)
{
// NB: Inline std::fill_n so no recursive dependencies.
std::fill_n(__s, __n, __a);
return __s;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// 21.1
/**
* @brief Basis for explicit traits specializations.
*
* @note For any given actual character type, this definition is
* probably wrong. Since this is just a thin wrapper around
* __gnu_cxx::char_traits, it is possible to achieve a more
* appropriate definition by specializing __gnu_cxx::char_traits.
*
* See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html
* for advice on how to make use of this class for @a unusual character
* types. Also, check out include/ext/pod_char_traits.h.
*/
template<class _CharT>
struct char_traits : public __gnu_cxx::char_traits<_CharT>
{ };
/// 21.1.3.1 char_traits specializations
template<>
struct char_traits<char>
{
typedef char char_type;
typedef int int_type;
typedef streampos pos_type;
typedef streamoff off_type;
typedef mbstate_t state_type;
static void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ __c1 = __c2; }
static _GLIBCXX_CONSTEXPR bool
eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR bool
lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 < __c2; }
static int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{ return __builtin_memcmp(__s1, __s2, __n); }
static size_t
length(const char_type* __s)
{ return __builtin_strlen(__s); }
static const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{ return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); }
static char_type*
move(char_type* __s1, const char_type* __s2, size_t __n)
{ return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); }
static char_type*
copy(char_type* __s1, const char_type* __s2, size_t __n)
{ return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); }
static char_type*
assign(char_type* __s, size_t __n, char_type __a)
{ return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); }
static _GLIBCXX_CONSTEXPR char_type
to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
{ return static_cast<char_type>(__c); }
// To keep both the byte 0xff and the eof symbol 0xffffffff
// from ending up as 0xffffffff.
static _GLIBCXX_CONSTEXPR int_type
to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
{ return static_cast<int_type>(static_cast<unsigned char>(__c)); }
static _GLIBCXX_CONSTEXPR bool
eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR int_type
eof() _GLIBCXX_NOEXCEPT
{ return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
static _GLIBCXX_CONSTEXPR int_type
not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
{ return (__c == eof()) ? 0 : __c; }
};
#ifdef _GLIBCXX_USE_WCHAR_T
/// 21.1.3.2 char_traits specializations
template<>
struct char_traits<wchar_t>
{
typedef wchar_t char_type;
typedef wint_t int_type;
typedef streamoff off_type;
typedef wstreampos pos_type;
typedef mbstate_t state_type;
static void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ __c1 = __c2; }
static _GLIBCXX_CONSTEXPR bool
eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR bool
lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 < __c2; }
static int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{ return wmemcmp(__s1, __s2, __n); }
static size_t
length(const char_type* __s)
{ return wcslen(__s); }
static const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{ return wmemchr(__s, __a, __n); }
static char_type*
move(char_type* __s1, const char_type* __s2, size_t __n)
{ return wmemmove(__s1, __s2, __n); }
static char_type*
copy(char_type* __s1, const char_type* __s2, size_t __n)
{ return wmemcpy(__s1, __s2, __n); }
static char_type*
assign(char_type* __s, size_t __n, char_type __a)
{ return wmemset(__s, __a, __n); }
static _GLIBCXX_CONSTEXPR char_type
to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
{ return char_type(__c); }
static _GLIBCXX_CONSTEXPR int_type
to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
{ return int_type(__c); }
static _GLIBCXX_CONSTEXPR bool
eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR int_type
eof() _GLIBCXX_NOEXCEPT
{ return static_cast<int_type>(WEOF); }
static _GLIBCXX_CONSTEXPR int_type
not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
{ return eq_int_type(__c, eof()) ? 0 : __c; }
};
#endif //_GLIBCXX_USE_WCHAR_T
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#if ((__cplusplus >= 201103L) \
&& defined(_GLIBCXX_USE_C99_STDINT_TR1))
#include <cstdint>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<>
struct char_traits<char16_t>
{
typedef char16_t char_type;
typedef uint_least16_t int_type;
typedef streamoff off_type;
typedef u16streampos pos_type;
typedef mbstate_t state_type;
static void
assign(char_type& __c1, const char_type& __c2) noexcept
{ __c1 = __c2; }
static constexpr bool
eq(const char_type& __c1, const char_type& __c2) noexcept
{ return __c1 == __c2; }
static constexpr bool
lt(const char_type& __c1, const char_type& __c2) noexcept
{ return __c1 < __c2; }
static int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
for (size_t __i = 0; __i < __n; ++__i)
if (lt(__s1[__i], __s2[__i]))
return -1;
else if (lt(__s2[__i], __s1[__i]))
return 1;
return 0;
}
static size_t
length(const char_type* __s)
{
size_t __i = 0;
while (!eq(__s[__i], char_type()))
++__i;
return __i;
}
static const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
for (size_t __i = 0; __i < __n; ++__i)
if (eq(__s[__i], __a))
return __s + __i;
return 0;
}
static char_type*
move(char_type* __s1, const char_type* __s2, size_t __n)
{
return (static_cast<char_type*>
(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
}
static char_type*
copy(char_type* __s1, const char_type* __s2, size_t __n)
{
return (static_cast<char_type*>
(__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
}
static char_type*
assign(char_type* __s, size_t __n, char_type __a)
{
for (size_t __i = 0; __i < __n; ++__i)
assign(__s[__i], __a);
return __s;
}
static constexpr char_type
to_char_type(const int_type& __c) noexcept
{ return char_type(__c); }
static constexpr int_type
to_int_type(const char_type& __c) noexcept
{ return int_type(__c); }
static constexpr bool
eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
{ return __c1 == __c2; }
static constexpr int_type
eof() noexcept
{ return static_cast<int_type>(-1); }
static constexpr int_type
not_eof(const int_type& __c) noexcept
{ return eq_int_type(__c, eof()) ? 0 : __c; }
};
template<>
struct char_traits<char32_t>
{
typedef char32_t char_type;
typedef uint_least32_t int_type;
typedef streamoff off_type;
typedef u32streampos pos_type;
typedef mbstate_t state_type;
static void
assign(char_type& __c1, const char_type& __c2) noexcept
{ __c1 = __c2; }
static constexpr bool
eq(const char_type& __c1, const char_type& __c2) noexcept
{ return __c1 == __c2; }
static constexpr bool
lt(const char_type& __c1, const char_type& __c2) noexcept
{ return __c1 < __c2; }
static int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
for (size_t __i = 0; __i < __n; ++__i)
if (lt(__s1[__i], __s2[__i]))
return -1;
else if (lt(__s2[__i], __s1[__i]))
return 1;
return 0;
}
static size_t
length(const char_type* __s)
{
size_t __i = 0;
while (!eq(__s[__i], char_type()))
++__i;
return __i;
}
static const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
for (size_t __i = 0; __i < __n; ++__i)
if (eq(__s[__i], __a))
return __s + __i;
return 0;
}
static char_type*
move(char_type* __s1, const char_type* __s2, size_t __n)
{
return (static_cast<char_type*>
(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
}
static char_type*
copy(char_type* __s1, const char_type* __s2, size_t __n)
{
return (static_cast<char_type*>
(__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
}
static char_type*
assign(char_type* __s, size_t __n, char_type __a)
{
for (size_t __i = 0; __i < __n; ++__i)
assign(__s[__i], __a);
return __s;
}
static constexpr char_type
to_char_type(const int_type& __c) noexcept
{ return char_type(__c); }
static constexpr int_type
to_int_type(const char_type& __c) noexcept
{ return int_type(__c); }
static constexpr bool
eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
{ return __c1 == __c2; }
static constexpr int_type
eof() noexcept
{ return static_cast<int_type>(-1); }
static constexpr int_type
not_eof(const int_type& __c) noexcept
{ return eq_int_type(__c, eof()) ? 0 : __c; }
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
#endif // _CHAR_TRAITS_H

View File

@@ -0,0 +1,507 @@
// Locale support (codecvt) -*- C++ -*-
// Copyright (C) 2000-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/codecvt.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.2.1.5 Template class codecvt
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
#ifndef _CODECVT_H
#define _CODECVT_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Empty base class for codecvt facet [22.2.1.5].
class codecvt_base
{
public:
enum result
{
ok,
partial,
error,
noconv
};
};
/**
* @brief Common base for codecvt functions.
*
* This template class provides implementations of the public functions
* that forward to the protected virtual functions.
*
* This template also provides abstract stubs for the protected virtual
* functions.
*/
template<typename _InternT, typename _ExternT, typename _StateT>
class __codecvt_abstract_base
: public locale::facet, public codecvt_base
{
public:
// Types:
typedef codecvt_base::result result;
typedef _InternT intern_type;
typedef _ExternT extern_type;
typedef _StateT state_type;
// 22.2.1.5.1 codecvt members
/**
* @brief Convert from internal to external character set.
*
* Converts input string of intern_type to output string of
* extern_type. This is analogous to wcsrtombs. It does this by
* calling codecvt::do_out.
*
* The source and destination character sets are determined by the
* facet's locale, internal and external types.
*
* The characters in [from,from_end) are converted and written to
* [to,to_end). from_next and to_next are set to point to the
* character following the last successfully converted character,
* respectively. If the result needed no conversion, from_next and
* to_next are not affected.
*
* The @a state argument should be initialized if the input is at the
* beginning and carried from a previous call if continuing
* conversion. There are no guarantees about how @a state is used.
*
* The result returned is a member of codecvt_base::result. If
* all the input is converted, returns codecvt_base::ok. If no
* conversion is necessary, returns codecvt_base::noconv. If
* the input ends early or there is insufficient space in the
* output, returns codecvt_base::partial. Otherwise the
* conversion failed and codecvt_base::error is returned.
*
* @param __state Persistent conversion state data.
* @param __from Start of input.
* @param __from_end End of input.
* @param __from_next Returns start of unconverted data.
* @param __to Start of output buffer.
* @param __to_end End of output buffer.
* @param __to_next Returns start of unused output area.
* @return codecvt_base::result.
*/
result
out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const
{
return this->do_out(__state, __from, __from_end, __from_next,
__to, __to_end, __to_next);
}
/**
* @brief Reset conversion state.
*
* Writes characters to output that would restore @a state to initial
* conditions. The idea is that if a partial conversion occurs, then
* the converting the characters written by this function would leave
* the state in initial conditions, rather than partial conversion
* state. It does this by calling codecvt::do_unshift().
*
* For example, if 4 external characters always converted to 1 internal
* character, and input to in() had 6 external characters with state
* saved, this function would write two characters to the output and
* set the state to initialized conditions.
*
* The source and destination character sets are determined by the
* facet's locale, internal and external types.
*
* The result returned is a member of codecvt_base::result. If the
* state could be reset and data written, returns codecvt_base::ok. If
* no conversion is necessary, returns codecvt_base::noconv. If the
* output has insufficient space, returns codecvt_base::partial.
* Otherwise the reset failed and codecvt_base::error is returned.
*
* @param __state Persistent conversion state data.
* @param __to Start of output buffer.
* @param __to_end End of output buffer.
* @param __to_next Returns start of unused output area.
* @return codecvt_base::result.
*/
result
unshift(state_type& __state, extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const
{ return this->do_unshift(__state, __to,__to_end,__to_next); }
/**
* @brief Convert from external to internal character set.
*
* Converts input string of extern_type to output string of
* intern_type. This is analogous to mbsrtowcs. It does this by
* calling codecvt::do_in.
*
* The source and destination character sets are determined by the
* facet's locale, internal and external types.
*
* The characters in [from,from_end) are converted and written to
* [to,to_end). from_next and to_next are set to point to the
* character following the last successfully converted character,
* respectively. If the result needed no conversion, from_next and
* to_next are not affected.
*
* The @a state argument should be initialized if the input is at the
* beginning and carried from a previous call if continuing
* conversion. There are no guarantees about how @a state is used.
*
* The result returned is a member of codecvt_base::result. If
* all the input is converted, returns codecvt_base::ok. If no
* conversion is necessary, returns codecvt_base::noconv. If
* the input ends early or there is insufficient space in the
* output, returns codecvt_base::partial. Otherwise the
* conversion failed and codecvt_base::error is returned.
*
* @param __state Persistent conversion state data.
* @param __from Start of input.
* @param __from_end End of input.
* @param __from_next Returns start of unconverted data.
* @param __to Start of output buffer.
* @param __to_end End of output buffer.
* @param __to_next Returns start of unused output area.
* @return codecvt_base::result.
*/
result
in(state_type& __state, const extern_type* __from,
const extern_type* __from_end, const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const
{
return this->do_in(__state, __from, __from_end, __from_next,
__to, __to_end, __to_next);
}
int
encoding() const throw()
{ return this->do_encoding(); }
bool
always_noconv() const throw()
{ return this->do_always_noconv(); }
int
length(state_type& __state, const extern_type* __from,
const extern_type* __end, size_t __max) const
{ return this->do_length(__state, __from, __end, __max); }
int
max_length() const throw()
{ return this->do_max_length(); }
protected:
explicit
__codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { }
virtual
~__codecvt_abstract_base() { }
/**
* @brief Convert from internal to external character set.
*
* Converts input string of intern_type to output string of
* extern_type. This function is a hook for derived classes to change
* the value returned. @see out for more information.
*/
virtual result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const = 0;
virtual result
do_unshift(state_type& __state, extern_type* __to,
extern_type* __to_end, extern_type*& __to_next) const = 0;
virtual result
do_in(state_type& __state, const extern_type* __from,
const extern_type* __from_end, const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const = 0;
virtual int
do_encoding() const throw() = 0;
virtual bool
do_always_noconv() const throw() = 0;
virtual int
do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const = 0;
virtual int
do_max_length() const throw() = 0;
};
/**
* @brief Primary class template codecvt.
* @ingroup locales
*
* NB: Generic, mostly useless implementation.
*
*/
template<typename _InternT, typename _ExternT, typename _StateT>
class codecvt
: public __codecvt_abstract_base<_InternT, _ExternT, _StateT>
{
public:
// Types:
typedef codecvt_base::result result;
typedef _InternT intern_type;
typedef _ExternT extern_type;
typedef _StateT state_type;
protected:
__c_locale _M_c_locale_codecvt;
public:
static locale::id id;
explicit
codecvt(size_t __refs = 0)
: __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs),
_M_c_locale_codecvt(0)
{ }
explicit
codecvt(__c_locale __cloc, size_t __refs = 0);
protected:
virtual
~codecvt() { }
virtual result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_unshift(state_type& __state, extern_type* __to,
extern_type* __to_end, extern_type*& __to_next) const;
virtual result
do_in(state_type& __state, const extern_type* __from,
const extern_type* __from_end, const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const;
virtual int
do_encoding() const throw();
virtual bool
do_always_noconv() const throw();
virtual int
do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const;
virtual int
do_max_length() const throw();
};
template<typename _InternT, typename _ExternT, typename _StateT>
locale::id codecvt<_InternT, _ExternT, _StateT>::id;
/// class codecvt<char, char, mbstate_t> specialization.
template<>
class codecvt<char, char, mbstate_t>
: public __codecvt_abstract_base<char, char, mbstate_t>
{
public:
// Types:
typedef char intern_type;
typedef char extern_type;
typedef mbstate_t state_type;
protected:
__c_locale _M_c_locale_codecvt;
public:
static locale::id id;
explicit
codecvt(size_t __refs = 0);
explicit
codecvt(__c_locale __cloc, size_t __refs = 0);
protected:
virtual
~codecvt();
virtual result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_unshift(state_type& __state, extern_type* __to,
extern_type* __to_end, extern_type*& __to_next) const;
virtual result
do_in(state_type& __state, const extern_type* __from,
const extern_type* __from_end, const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const;
virtual int
do_encoding() const throw();
virtual bool
do_always_noconv() const throw();
virtual int
do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const;
virtual int
do_max_length() const throw();
};
#ifdef _GLIBCXX_USE_WCHAR_T
/// class codecvt<wchar_t, char, mbstate_t> specialization.
template<>
class codecvt<wchar_t, char, mbstate_t>
: public __codecvt_abstract_base<wchar_t, char, mbstate_t>
{
public:
// Types:
typedef wchar_t intern_type;
typedef char extern_type;
typedef mbstate_t state_type;
protected:
__c_locale _M_c_locale_codecvt;
public:
static locale::id id;
explicit
codecvt(size_t __refs = 0);
explicit
codecvt(__c_locale __cloc, size_t __refs = 0);
protected:
virtual
~codecvt();
virtual result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_unshift(state_type& __state,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_in(state_type& __state,
const extern_type* __from, const extern_type* __from_end,
const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const;
virtual
int do_encoding() const throw();
virtual
bool do_always_noconv() const throw();
virtual
int do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const;
virtual int
do_max_length() const throw();
};
#endif //_GLIBCXX_USE_WCHAR_T
/// class codecvt_byname [22.2.1.6].
template<typename _InternT, typename _ExternT, typename _StateT>
class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT>
{
public:
explicit
codecvt_byname(const char* __s, size_t __refs = 0)
: codecvt<_InternT, _ExternT, _StateT>(__refs)
{
if (__builtin_strcmp(__s, "C") != 0
&& __builtin_strcmp(__s, "POSIX") != 0)
{
this->_S_destroy_c_locale(this->_M_c_locale_codecvt);
this->_S_create_c_locale(this->_M_c_locale_codecvt, __s);
}
}
protected:
virtual
~codecvt_byname() { }
};
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class codecvt_byname<char, char, mbstate_t>;
extern template
const codecvt<char, char, mbstate_t>&
use_facet<codecvt<char, char, mbstate_t> >(const locale&);
extern template
bool
has_facet<codecvt<char, char, mbstate_t> >(const locale&);
#ifdef _GLIBCXX_USE_WCHAR_T
extern template class codecvt_byname<wchar_t, char, mbstate_t>;
extern template
const codecvt<wchar_t, char, mbstate_t>&
use_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
extern template
bool
has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
#endif
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // _CODECVT_H

View File

@@ -0,0 +1,80 @@
// Concept-checking control -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/concept_check.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
#ifndef _CONCEPT_CHECK_H
#define _CONCEPT_CHECK_H 1
#pragma GCC system_header
#include <bits/c++config.h>
// All places in libstdc++-v3 where these are used, or /might/ be used, or
// don't need to be used, or perhaps /should/ be used, are commented with
// "concept requirements" (and maybe some more text). So grep like crazy
// if you're looking for additional places to use these.
// Concept-checking code is off by default unless users turn it on via
// configure options or editing c++config.h.
#ifndef _GLIBCXX_CONCEPT_CHECKS
#define __glibcxx_function_requires(...)
#define __glibcxx_class_requires(_a,_b)
#define __glibcxx_class_requires2(_a,_b,_c)
#define __glibcxx_class_requires3(_a,_b,_c,_d)
#define __glibcxx_class_requires4(_a,_b,_c,_d,_e)
#else // the checks are on
#include <bits/boost_concept_check.h>
// Note that the obvious and elegant approach of
//
//#define glibcxx_function_requires(C) debug::function_requires< debug::C >()
//
// won't work due to concept templates with more than one parameter, e.g.,
// BinaryPredicateConcept. The preprocessor tries to split things up on
// the commas in the template argument list. We can't use an inner pair of
// parenthesis to hide the commas, because "debug::(Temp<Foo,Bar>)" isn't
// a valid instantiation pattern. Thus, we steal a feature from C99.
#define __glibcxx_function_requires(...) \
__gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >();
#define __glibcxx_class_requires(_a,_C) \
_GLIBCXX_CLASS_REQUIRES(_a, __gnu_cxx, _C);
#define __glibcxx_class_requires2(_a,_b,_C) \
_GLIBCXX_CLASS_REQUIRES2(_a, _b, __gnu_cxx, _C);
#define __glibcxx_class_requires3(_a,_b,_c,_C) \
_GLIBCXX_CLASS_REQUIRES3(_a, _b, _c, __gnu_cxx, _C);
#define __glibcxx_class_requires4(_a,_b,_c,_d,_C) \
_GLIBCXX_CLASS_REQUIRES4(_a, _b, _c, _d, __gnu_cxx, _C);
#endif // enable/disable
#endif // _GLIBCXX_CONCEPT_CHECK

View File

@@ -0,0 +1,424 @@
// The -*- C++ -*- type traits classes for internal use in libstdc++
// Copyright (C) 2000-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cpp_type_traits.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ext/type_traits}
*/
// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
#ifndef _CPP_TYPE_TRAITS_H
#define _CPP_TYPE_TRAITS_H 1
#pragma GCC system_header
#include <bits/c++config.h>
//
// This file provides some compile-time information about various types.
// These representations were designed, on purpose, to be constant-expressions
// and not types as found in <bits/type_traits.h>. In particular, they
// can be used in control structures and the optimizer hopefully will do
// the obvious thing.
//
// Why integral expressions, and not functions nor types?
// Firstly, these compile-time entities are used as template-arguments
// so function return values won't work: We need compile-time entities.
// We're left with types and constant integral expressions.
// Secondly, from the point of view of ease of use, type-based compile-time
// information is -not- *that* convenient. On has to write lots of
// overloaded functions and to hope that the compiler will select the right
// one. As a net effect, the overall structure isn't very clear at first
// glance.
// Thirdly, partial ordering and overload resolution (of function templates)
// is highly costly in terms of compiler-resource. It is a Good Thing to
// keep these resource consumption as least as possible.
//
// See valarray_array.h for a case use.
//
// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
//
// Update 2005: types are also provided and <bits/type_traits.h> has been
// removed.
//
// Forward declaration hack, should really include this from somewhere.
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Iterator, typename _Container>
class __normal_iterator;
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __true_type { };
struct __false_type { };
template<bool>
struct __truth_type
{ typedef __false_type __type; };
template<>
struct __truth_type<true>
{ typedef __true_type __type; };
// N.B. The conversions to bool are needed due to the issue
// explained in c++/19404.
template<class _Sp, class _Tp>
struct __traitor
{
enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
typedef typename __truth_type<__value>::__type __type;
};
// Compare for equality of types.
template<typename, typename>
struct __are_same
{
enum { __value = 0 };
typedef __false_type __type;
};
template<typename _Tp>
struct __are_same<_Tp, _Tp>
{
enum { __value = 1 };
typedef __true_type __type;
};
// Holds if the template-argument is a void type.
template<typename _Tp>
struct __is_void
{
enum { __value = 0 };
typedef __false_type __type;
};
template<>
struct __is_void<void>
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// Integer types
//
template<typename _Tp>
struct __is_integer
{
enum { __value = 0 };
typedef __false_type __type;
};
// Thirteen specializations (yes there are eleven standard integer
// types; <em>long long</em> and <em>unsigned long long</em> are
// supported as extensions)
template<>
struct __is_integer<bool>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<signed char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned char>
{
enum { __value = 1 };
typedef __true_type __type;
};
# ifdef _GLIBCXX_USE_WCHAR_T
template<>
struct __is_integer<wchar_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
# endif
#if __cplusplus >= 201103L
template<>
struct __is_integer<char16_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<char32_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
template<>
struct __is_integer<short>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned short>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<int>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned int>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<long>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned long>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<long long>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned long long>
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// Floating point types
//
template<typename _Tp>
struct __is_floating
{
enum { __value = 0 };
typedef __false_type __type;
};
// three specializations (float, double and 'long double')
template<>
struct __is_floating<float>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_floating<double>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_floating<long double>
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// Pointer types
//
template<typename _Tp>
struct __is_pointer
{
enum { __value = 0 };
typedef __false_type __type;
};
template<typename _Tp>
struct __is_pointer<_Tp*>
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// Normal iterator type
//
template<typename _Tp>
struct __is_normal_iterator
{
enum { __value = 0 };
typedef __false_type __type;
};
template<typename _Iterator, typename _Container>
struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
_Container> >
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// An arithmetic type is an integer type or a floating point type
//
template<typename _Tp>
struct __is_arithmetic
: public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
{ };
//
// A fundamental type is `void' or and arithmetic type
//
template<typename _Tp>
struct __is_fundamental
: public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
{ };
//
// A scalar type is an arithmetic type or a pointer type
//
template<typename _Tp>
struct __is_scalar
: public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
{ };
//
// For use in std::copy and std::find overloads for streambuf iterators.
//
template<typename _Tp>
struct __is_char
{
enum { __value = 0 };
typedef __false_type __type;
};
template<>
struct __is_char<char>
{
enum { __value = 1 };
typedef __true_type __type;
};
#ifdef _GLIBCXX_USE_WCHAR_T
template<>
struct __is_char<wchar_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
template<typename _Tp>
struct __is_byte
{
enum { __value = 0 };
typedef __false_type __type;
};
template<>
struct __is_byte<char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_byte<signed char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_byte<unsigned char>
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// Move iterator type
//
template<typename _Tp>
struct __is_move_iterator
{
enum { __value = 0 };
typedef __false_type __type;
};
#if __cplusplus >= 201103L
template<typename _Iterator>
class move_iterator;
template<typename _Iterator>
struct __is_move_iterator< move_iterator<_Iterator> >
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif //_CPP_TYPE_TRAITS_H

View File

@@ -0,0 +1,60 @@
// cxxabi.h subset for cancellation -*- C++ -*-
// Copyright (C) 2007-2013 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cxxabi_forced.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{cxxabi.h}
*/
#ifndef _CXXABI_FORCED_H
#define _CXXABI_FORCED_H 1
#pragma GCC system_header
#pragma GCC visibility push(default)
#ifdef __cplusplus
namespace __cxxabiv1
{
/**
* @brief Thrown as part of forced unwinding.
* @ingroup exceptions
*
* A magic placeholder class that can be caught by reference to
* recognize forced unwinding.
*/
class __forced_unwind
{
virtual ~__forced_unwind() throw();
// Prevent catch by value.
virtual void __pure_dummy() = 0;
};
}
#endif // __cplusplus
#pragma GCC visibility pop
#endif // __CXXABI_FORCED_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
// -fno-exceptions Support -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/exception_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{exception}
*/
#ifndef _EXCEPTION_DEFINES_H
#define _EXCEPTION_DEFINES_H 1
#ifndef __EXCEPTIONS
// Iff -fno-exceptions, transform error handling code to work without it.
# define __try if (true)
# define __catch(X) if (false)
# define __throw_exception_again
#else
// Else proceed normally.
# define __try try
# define __catch(X) catch(X)
# define __throw_exception_again throw
#endif
#endif

View File

@@ -0,0 +1,198 @@
// Exception Handling support header (exception_ptr class) for -*- C++ -*-
// Copyright (C) 2008-2013 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/exception_ptr.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{exception}
*/
#ifndef _EXCEPTION_PTR_H
#define _EXCEPTION_PTR_H
#pragma GCC visibility push(default)
#include <bits/c++config.h>
#include <bits/exception_defines.h>
#if ATOMIC_INT_LOCK_FREE < 2
# error This platform does not support exception propagation.
#endif
extern "C++" {
namespace std
{
class type_info;
/**
* @addtogroup exceptions
* @{
*/
namespace __exception_ptr
{
class exception_ptr;
}
using __exception_ptr::exception_ptr;
/** Obtain an exception_ptr to the currently handled exception. If there
* is none, or the currently handled exception is foreign, return the null
* value.
*/
exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT;
/// Throw the object pointed to by the exception_ptr.
void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__));
namespace __exception_ptr
{
/**
* @brief An opaque pointer to an arbitrary exception.
* @ingroup exceptions
*/
class exception_ptr
{
void* _M_exception_object;
explicit exception_ptr(void* __e) _GLIBCXX_USE_NOEXCEPT;
void _M_addref() _GLIBCXX_USE_NOEXCEPT;
void _M_release() _GLIBCXX_USE_NOEXCEPT;
void *_M_get() const _GLIBCXX_NOEXCEPT __attribute__ ((__pure__));
friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT;
friend void std::rethrow_exception(exception_ptr);
public:
exception_ptr() _GLIBCXX_USE_NOEXCEPT;
exception_ptr(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
#if __cplusplus >= 201103L
exception_ptr(nullptr_t) noexcept
: _M_exception_object(0)
{ }
exception_ptr(exception_ptr&& __o) noexcept
: _M_exception_object(__o._M_exception_object)
{ __o._M_exception_object = 0; }
#endif
#if (__cplusplus < 201103L) || defined (_GLIBCXX_EH_PTR_COMPAT)
typedef void (exception_ptr::*__safe_bool)();
// For construction from nullptr or 0.
exception_ptr(__safe_bool) _GLIBCXX_USE_NOEXCEPT;
#endif
exception_ptr&
operator=(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
#if __cplusplus >= 201103L
exception_ptr&
operator=(exception_ptr&& __o) noexcept
{
exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this);
return *this;
}
#endif
~exception_ptr() _GLIBCXX_USE_NOEXCEPT;
void
swap(exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
#ifdef _GLIBCXX_EH_PTR_COMPAT
// Retained for compatibility with CXXABI_1.3.
void _M_safe_bool_dummy() _GLIBCXX_USE_NOEXCEPT
__attribute__ ((__const__));
bool operator!() const _GLIBCXX_USE_NOEXCEPT
__attribute__ ((__pure__));
operator __safe_bool() const _GLIBCXX_USE_NOEXCEPT;
#endif
#if __cplusplus >= 201103L
explicit operator bool() const
{ return _M_exception_object; }
#endif
friend bool
operator==(const exception_ptr&, const exception_ptr&)
_GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__));
const class std::type_info*
__cxa_exception_type() const _GLIBCXX_USE_NOEXCEPT
__attribute__ ((__pure__));
};
bool
operator==(const exception_ptr&, const exception_ptr&)
_GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__));
bool
operator!=(const exception_ptr&, const exception_ptr&)
_GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__));
inline void
swap(exception_ptr& __lhs, exception_ptr& __rhs)
{ __lhs.swap(__rhs); }
} // namespace __exception_ptr
/// Obtain an exception_ptr pointing to a copy of the supplied object.
template<typename _Ex>
exception_ptr
copy_exception(_Ex __ex) _GLIBCXX_USE_NOEXCEPT
{
__try
{
#ifdef __EXCEPTIONS
throw __ex;
#endif
}
__catch(...)
{
return current_exception();
}
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 1130. copy_exception name misleading
/// Obtain an exception_ptr pointing to a copy of the supplied object.
template<typename _Ex>
exception_ptr
make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT
{ return std::copy_exception<_Ex>(__ex); }
// @} group exceptions
} // namespace std
} // extern "C++"
#pragma GCC visibility pop
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,511 @@
// <forward_list.tcc> -*- C++ -*-
// Copyright (C) 2008-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/forward_list.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{forward_list}
*/
#ifndef _FORWARD_LIST_TCC
#define _FORWARD_LIST_TCC 1
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Tp, typename _Alloc>
_Fwd_list_base<_Tp, _Alloc>::
_Fwd_list_base(_Fwd_list_base&& __lst, const _Node_alloc_type& __a)
: _M_impl(__a)
{
if (__lst._M_get_Node_allocator() == __a)
{
this->_M_impl._M_head._M_next = __lst._M_impl._M_head._M_next;
__lst._M_impl._M_head._M_next = 0;
}
else
{
this->_M_impl._M_head._M_next = 0;
_Fwd_list_node_base* __to = &this->_M_impl._M_head;
_Node* __curr = static_cast<_Node*>(__lst._M_impl._M_head._M_next);
while (__curr)
{
__to->_M_next =
_M_create_node(std::move_if_noexcept(*__curr->_M_valptr()));
__to = __to->_M_next;
__curr = static_cast<_Node*>(__curr->_M_next);
}
}
}
template<typename _Tp, typename _Alloc>
template<typename... _Args>
_Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>::
_M_insert_after(const_iterator __pos, _Args&&... __args)
{
_Fwd_list_node_base* __to
= const_cast<_Fwd_list_node_base*>(__pos._M_node);
_Node* __thing = _M_create_node(std::forward<_Args>(__args)...);
__thing->_M_next = __to->_M_next;
__to->_M_next = __thing;
return __to->_M_next;
}
template<typename _Tp, typename _Alloc>
_Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>::
_M_erase_after(_Fwd_list_node_base* __pos)
{
_Node* __curr = static_cast<_Node*>(__pos->_M_next);
__pos->_M_next = __curr->_M_next;
_Tp_alloc_type __a(_M_get_Node_allocator());
allocator_traits<_Tp_alloc_type>::destroy(__a, __curr->_M_valptr());
__curr->~_Node();
_M_put_node(__curr);
return __pos->_M_next;
}
template<typename _Tp, typename _Alloc>
_Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>::
_M_erase_after(_Fwd_list_node_base* __pos,
_Fwd_list_node_base* __last)
{
_Node* __curr = static_cast<_Node*>(__pos->_M_next);
while (__curr != __last)
{
_Node* __temp = __curr;
__curr = static_cast<_Node*>(__curr->_M_next);
_Tp_alloc_type __a(_M_get_Node_allocator());
allocator_traits<_Tp_alloc_type>::destroy(__a, __temp->_M_valptr());
__temp->~_Node();
_M_put_node(__temp);
}
__pos->_M_next = __last;
return __last;
}
// Called by the range constructor to implement [23.3.4.2]/9
template<typename _Tp, typename _Alloc>
template<typename _InputIterator>
void
forward_list<_Tp, _Alloc>::
_M_range_initialize(_InputIterator __first, _InputIterator __last)
{
_Node_base* __to = &this->_M_impl._M_head;
for (; __first != __last; ++__first)
{
__to->_M_next = this->_M_create_node(*__first);
__to = __to->_M_next;
}
}
// Called by forward_list(n,v,a).
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
_M_fill_initialize(size_type __n, const value_type& __value)
{
_Node_base* __to = &this->_M_impl._M_head;
for (; __n; --__n)
{
__to->_M_next = this->_M_create_node(__value);
__to = __to->_M_next;
}
}
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
_M_default_initialize(size_type __n)
{
_Node_base* __to = &this->_M_impl._M_head;
for (; __n; --__n)
{
__to->_M_next = this->_M_create_node();
__to = __to->_M_next;
}
}
template<typename _Tp, typename _Alloc>
forward_list<_Tp, _Alloc>&
forward_list<_Tp, _Alloc>::
operator=(const forward_list& __list)
{
if (&__list != this)
{
if (_Node_alloc_traits::_S_propagate_on_copy_assign())
{
auto& __this_alloc = this->_M_get_Node_allocator();
auto& __that_alloc = __list._M_get_Node_allocator();
if (!_Node_alloc_traits::_S_always_equal()
&& __this_alloc != __that_alloc)
{
// replacement allocator cannot free existing storage
clear();
}
std::__alloc_on_copy(__this_alloc, __that_alloc);
}
assign(__list.cbegin(), __list.cend());
}
return *this;
}
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
_M_default_insert_after(const_iterator __pos, size_type __n)
{
const_iterator __saved_pos = __pos;
__try
{
for (; __n; --__n)
__pos = emplace_after(__pos);
}
__catch(...)
{
erase_after(__saved_pos, ++__pos);
__throw_exception_again;
}
}
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
resize(size_type __sz)
{
iterator __k = before_begin();
size_type __len = 0;
while (__k._M_next() != end() && __len < __sz)
{
++__k;
++__len;
}
if (__len == __sz)
erase_after(__k, end());
else
_M_default_insert_after(__k, __sz - __len);
}
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
resize(size_type __sz, const value_type& __val)
{
iterator __k = before_begin();
size_type __len = 0;
while (__k._M_next() != end() && __len < __sz)
{
++__k;
++__len;
}
if (__len == __sz)
erase_after(__k, end());
else
insert_after(__k, __sz - __len, __val);
}
template<typename _Tp, typename _Alloc>
typename forward_list<_Tp, _Alloc>::iterator
forward_list<_Tp, _Alloc>::
_M_splice_after(const_iterator __pos,
const_iterator __before, const_iterator __last)
{
_Node_base* __tmp = const_cast<_Node_base*>(__pos._M_node);
_Node_base* __b = const_cast<_Node_base*>(__before._M_node);
_Node_base* __end = __b;
while (__end && __end->_M_next != __last._M_node)
__end = __end->_M_next;
if (__b != __end)
return iterator(__tmp->_M_transfer_after(__b, __end));
else
return iterator(__tmp);
}
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
splice_after(const_iterator __pos, forward_list&&,
const_iterator __i)
{
const_iterator __j = __i;
++__j;
if (__pos == __i || __pos == __j)
return;
_Node_base* __tmp = const_cast<_Node_base*>(__pos._M_node);
__tmp->_M_transfer_after(const_cast<_Node_base*>(__i._M_node),
const_cast<_Node_base*>(__j._M_node));
}
template<typename _Tp, typename _Alloc>
typename forward_list<_Tp, _Alloc>::iterator
forward_list<_Tp, _Alloc>::
insert_after(const_iterator __pos, size_type __n, const _Tp& __val)
{
if (__n)
{
forward_list __tmp(__n, __val, get_allocator());
return _M_splice_after(__pos, __tmp.before_begin(), __tmp.end());
}
else
return iterator(const_cast<_Node_base*>(__pos._M_node));
}
template<typename _Tp, typename _Alloc>
template<typename _InputIterator, typename>
typename forward_list<_Tp, _Alloc>::iterator
forward_list<_Tp, _Alloc>::
insert_after(const_iterator __pos,
_InputIterator __first, _InputIterator __last)
{
forward_list __tmp(__first, __last, get_allocator());
if (!__tmp.empty())
return _M_splice_after(__pos, __tmp.before_begin(), __tmp.end());
else
return iterator(const_cast<_Node_base*>(__pos._M_node));
}
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
remove(const _Tp& __val)
{
_Node* __curr = static_cast<_Node*>(&this->_M_impl._M_head);
_Node* __extra = 0;
while (_Node* __tmp = static_cast<_Node*>(__curr->_M_next))
{
if (*__tmp->_M_valptr() == __val)
{
if (__tmp->_M_valptr() != std::__addressof(__val))
{
this->_M_erase_after(__curr);
continue;
}
else
__extra = __curr;
}
__curr = static_cast<_Node*>(__curr->_M_next);
}
if (__extra)
this->_M_erase_after(__extra);
}
template<typename _Tp, typename _Alloc>
template<typename _Pred>
void
forward_list<_Tp, _Alloc>::
remove_if(_Pred __pred)
{
_Node* __curr = static_cast<_Node*>(&this->_M_impl._M_head);
while (_Node* __tmp = static_cast<_Node*>(__curr->_M_next))
{
if (__pred(*__tmp->_M_valptr()))
this->_M_erase_after(__curr);
else
__curr = static_cast<_Node*>(__curr->_M_next);
}
}
template<typename _Tp, typename _Alloc>
template<typename _BinPred>
void
forward_list<_Tp, _Alloc>::
unique(_BinPred __binary_pred)
{
iterator __first = begin();
iterator __last = end();
if (__first == __last)
return;
iterator __next = __first;
while (++__next != __last)
{
if (__binary_pred(*__first, *__next))
erase_after(__first);
else
__first = __next;
__next = __first;
}
}
template<typename _Tp, typename _Alloc>
template<typename _Comp>
void
forward_list<_Tp, _Alloc>::
merge(forward_list&& __list, _Comp __comp)
{
_Node_base* __node = &this->_M_impl._M_head;
while (__node->_M_next && __list._M_impl._M_head._M_next)
{
if (__comp(*static_cast<_Node*>
(__list._M_impl._M_head._M_next)->_M_valptr(),
*static_cast<_Node*>
(__node->_M_next)->_M_valptr()))
__node->_M_transfer_after(&__list._M_impl._M_head,
__list._M_impl._M_head._M_next);
__node = __node->_M_next;
}
if (__list._M_impl._M_head._M_next)
{
__node->_M_next = __list._M_impl._M_head._M_next;
__list._M_impl._M_head._M_next = 0;
}
}
template<typename _Tp, typename _Alloc>
bool
operator==(const forward_list<_Tp, _Alloc>& __lx,
const forward_list<_Tp, _Alloc>& __ly)
{
// We don't have size() so we need to walk through both lists
// making sure both iterators are valid.
auto __ix = __lx.cbegin();
auto __iy = __ly.cbegin();
while (__ix != __lx.cend() && __iy != __ly.cend())
{
if (*__ix != *__iy)
return false;
++__ix;
++__iy;
}
if (__ix == __lx.cend() && __iy == __ly.cend())
return true;
else
return false;
}
template<typename _Tp, class _Alloc>
template<typename _Comp>
void
forward_list<_Tp, _Alloc>::
sort(_Comp __comp)
{
// If `next' is 0, return immediately.
_Node* __list = static_cast<_Node*>(this->_M_impl._M_head._M_next);
if (!__list)
return;
unsigned long __insize = 1;
while (1)
{
_Node* __p = __list;
__list = 0;
_Node* __tail = 0;
// Count number of merges we do in this pass.
unsigned long __nmerges = 0;
while (__p)
{
++__nmerges;
// There exists a merge to be done.
// Step `insize' places along from p.
_Node* __q = __p;
unsigned long __psize = 0;
for (unsigned long __i = 0; __i < __insize; ++__i)
{
++__psize;
__q = static_cast<_Node*>(__q->_M_next);
if (!__q)
break;
}
// If q hasn't fallen off end, we have two lists to merge.
unsigned long __qsize = __insize;
// Now we have two lists; merge them.
while (__psize > 0 || (__qsize > 0 && __q))
{
// Decide whether next node of merge comes from p or q.
_Node* __e;
if (__psize == 0)
{
// p is empty; e must come from q.
__e = __q;
__q = static_cast<_Node*>(__q->_M_next);
--__qsize;
}
else if (__qsize == 0 || !__q)
{
// q is empty; e must come from p.
__e = __p;
__p = static_cast<_Node*>(__p->_M_next);
--__psize;
}
else if (__comp(*__p->_M_valptr(), *__q->_M_valptr()))
{
// First node of p is lower; e must come from p.
__e = __p;
__p = static_cast<_Node*>(__p->_M_next);
--__psize;
}
else
{
// First node of q is lower; e must come from q.
__e = __q;
__q = static_cast<_Node*>(__q->_M_next);
--__qsize;
}
// Add the next node to the merged list.
if (__tail)
__tail->_M_next = __e;
else
__list = __e;
__tail = __e;
}
// Now p has stepped `insize' places along, and q has too.
__p = __q;
}
__tail->_M_next = 0;
// If we have done only one merge, we're finished.
// Allow for nmerges == 0, the empty list case.
if (__nmerges <= 1)
{
this->_M_impl._M_head._M_next = __list;
return;
}
// Otherwise repeat, merging lists twice the size.
__insize *= 2;
}
}
_GLIBCXX_END_NAMESPACE_CONTAINER
} // namespace std
#endif /* _FORWARD_LIST_TCC */

View File

@@ -0,0 +1,982 @@
// File based streams -*- C++ -*-
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/fstream.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{fstream}
*/
//
// ISO C++ 14882: 27.8 File-based streams
//
#ifndef _FSTREAM_TCC
#define _FSTREAM_TCC 1
#pragma GCC system_header
#include <bits/cxxabi_forced.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
void
basic_filebuf<_CharT, _Traits>::
_M_allocate_internal_buffer()
{
// Allocate internal buffer only if one doesn't already exist
// (either allocated or provided by the user via setbuf).
if (!_M_buf_allocated && !_M_buf)
{
_M_buf = new char_type[_M_buf_size];
_M_buf_allocated = true;
}
}
template<typename _CharT, typename _Traits>
void
basic_filebuf<_CharT, _Traits>::
_M_destroy_internal_buffer() throw()
{
if (_M_buf_allocated)
{
delete [] _M_buf;
_M_buf = 0;
_M_buf_allocated = false;
}
delete [] _M_ext_buf;
_M_ext_buf = 0;
_M_ext_buf_size = 0;
_M_ext_next = 0;
_M_ext_end = 0;
}
template<typename _CharT, typename _Traits>
basic_filebuf<_CharT, _Traits>::
basic_filebuf() : __streambuf_type(), _M_lock(), _M_file(&_M_lock),
_M_mode(ios_base::openmode(0)), _M_state_beg(), _M_state_cur(),
_M_state_last(), _M_buf(0), _M_buf_size(BUFSIZ),
_M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(),
_M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false),
_M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0),
_M_ext_end(0)
{
if (has_facet<__codecvt_type>(this->_M_buf_locale))
_M_codecvt = &use_facet<__codecvt_type>(this->_M_buf_locale);
}
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
basic_filebuf<_CharT, _Traits>::
open(const char* __s, ios_base::openmode __mode)
{
__filebuf_type *__ret = 0;
if (!this->is_open())
{
_M_file.open(__s, __mode);
if (this->is_open())
{
_M_allocate_internal_buffer();
_M_mode = __mode;
// Setup initial buffer to 'uncommitted' mode.
_M_reading = false;
_M_writing = false;
_M_set_buffer(-1);
// Reset to initial state.
_M_state_last = _M_state_cur = _M_state_beg;
// 27.8.1.3,4
if ((__mode & ios_base::ate)
&& this->seekoff(0, ios_base::end, __mode)
== pos_type(off_type(-1)))
this->close();
else
__ret = this;
}
}
return __ret;
}
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
basic_filebuf<_CharT, _Traits>::
close()
{
if (!this->is_open())
return 0;
bool __testfail = false;
{
// NB: Do this here so that re-opened filebufs will be cool...
struct __close_sentry
{
basic_filebuf *__fb;
__close_sentry (basic_filebuf *__fbi): __fb(__fbi) { }
~__close_sentry ()
{
__fb->_M_mode = ios_base::openmode(0);
__fb->_M_pback_init = false;
__fb->_M_destroy_internal_buffer();
__fb->_M_reading = false;
__fb->_M_writing = false;
__fb->_M_set_buffer(-1);
__fb->_M_state_last = __fb->_M_state_cur = __fb->_M_state_beg;
}
} __cs (this);
__try
{
if (!_M_terminate_output())
__testfail = true;
}
__catch(__cxxabiv1::__forced_unwind&)
{
_M_file.close();
__throw_exception_again;
}
__catch(...)
{ __testfail = true; }
}
if (!_M_file.close())
__testfail = true;
if (__testfail)
return 0;
else
return this;
}
template<typename _CharT, typename _Traits>
streamsize
basic_filebuf<_CharT, _Traits>::
showmanyc()
{
streamsize __ret = -1;
const bool __testin = _M_mode & ios_base::in;
if (__testin && this->is_open())
{
// For a stateful encoding (-1) the pending sequence might be just
// shift and unshift prefixes with no actual character.
__ret = this->egptr() - this->gptr();
#if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
// About this workaround, see libstdc++/20806.
const bool __testbinary = _M_mode & ios_base::binary;
if (__check_facet(_M_codecvt).encoding() >= 0
&& __testbinary)
#else
if (__check_facet(_M_codecvt).encoding() >= 0)
#endif
__ret += _M_file.showmanyc() / _M_codecvt->max_length();
}
return __ret;
}
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::int_type
basic_filebuf<_CharT, _Traits>::
underflow()
{
int_type __ret = traits_type::eof();
const bool __testin = _M_mode & ios_base::in;
if (__testin)
{
if (_M_writing)
{
if (overflow() == traits_type::eof())
return __ret;
_M_set_buffer(-1);
_M_writing = false;
}
// Check for pback madness, and if so switch back to the
// normal buffers and jet outta here before expensive
// fileops happen...
_M_destroy_pback();
if (this->gptr() < this->egptr())
return traits_type::to_int_type(*this->gptr());
// Get and convert input sequence.
const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
// Will be set to true if ::read() returns 0 indicating EOF.
bool __got_eof = false;
// Number of internal characters produced.
streamsize __ilen = 0;
codecvt_base::result __r = codecvt_base::ok;
if (__check_facet(_M_codecvt).always_noconv())
{
__ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
__buflen);
if (__ilen == 0)
__got_eof = true;
}
else
{
// Worst-case number of external bytes.
// XXX Not done encoding() == -1.
const int __enc = _M_codecvt->encoding();
streamsize __blen; // Minimum buffer size.
streamsize __rlen; // Number of chars to read.
if (__enc > 0)
__blen = __rlen = __buflen * __enc;
else
{
__blen = __buflen + _M_codecvt->max_length() - 1;
__rlen = __buflen;
}
const streamsize __remainder = _M_ext_end - _M_ext_next;
__rlen = __rlen > __remainder ? __rlen - __remainder : 0;
// An imbue in 'read' mode implies first converting the external
// chars already present.
if (_M_reading && this->egptr() == this->eback() && __remainder)
__rlen = 0;
// Allocate buffer if necessary and move unconverted
// bytes to front.
if (_M_ext_buf_size < __blen)
{
char* __buf = new char[__blen];
if (__remainder)
__builtin_memcpy(__buf, _M_ext_next, __remainder);
delete [] _M_ext_buf;
_M_ext_buf = __buf;
_M_ext_buf_size = __blen;
}
else if (__remainder)
__builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
_M_ext_next = _M_ext_buf;
_M_ext_end = _M_ext_buf + __remainder;
_M_state_last = _M_state_cur;
do
{
if (__rlen > 0)
{
// Sanity check!
// This may fail if the return value of
// codecvt::max_length() is bogus.
if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
{
__throw_ios_failure(__N("basic_filebuf::underflow "
"codecvt::max_length() "
"is not valid"));
}
streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
if (__elen == 0)
__got_eof = true;
else if (__elen == -1)
break;
_M_ext_end += __elen;
}
char_type* __iend = this->eback();
if (_M_ext_next < _M_ext_end)
__r = _M_codecvt->in(_M_state_cur, _M_ext_next,
_M_ext_end, _M_ext_next,
this->eback(),
this->eback() + __buflen, __iend);
if (__r == codecvt_base::noconv)
{
size_t __avail = _M_ext_end - _M_ext_buf;
__ilen = std::min(__avail, __buflen);
traits_type::copy(this->eback(),
reinterpret_cast<char_type*>
(_M_ext_buf), __ilen);
_M_ext_next = _M_ext_buf + __ilen;
}
else
__ilen = __iend - this->eback();
// _M_codecvt->in may return error while __ilen > 0: this is
// ok, and actually occurs in case of mixed encodings (e.g.,
// XML files).
if (__r == codecvt_base::error)
break;
__rlen = 1;
}
while (__ilen == 0 && !__got_eof);
}
if (__ilen > 0)
{
_M_set_buffer(__ilen);
_M_reading = true;
__ret = traits_type::to_int_type(*this->gptr());
}
else if (__got_eof)
{
// If the actual end of file is reached, set 'uncommitted'
// mode, thus allowing an immediate write without an
// intervening seek.
_M_set_buffer(-1);
_M_reading = false;
// However, reaching it while looping on partial means that
// the file has got an incomplete character.
if (__r == codecvt_base::partial)
__throw_ios_failure(__N("basic_filebuf::underflow "
"incomplete character in file"));
}
else if (__r == codecvt_base::error)
__throw_ios_failure(__N("basic_filebuf::underflow "
"invalid byte sequence in file"));
else
__throw_ios_failure(__N("basic_filebuf::underflow "
"error reading the file"));
}
return __ret;
}
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::int_type
basic_filebuf<_CharT, _Traits>::
pbackfail(int_type __i)
{
int_type __ret = traits_type::eof();
const bool __testin = _M_mode & ios_base::in;
if (__testin)
{
if (_M_writing)
{
if (overflow() == traits_type::eof())
return __ret;
_M_set_buffer(-1);
_M_writing = false;
}
// Remember whether the pback buffer is active, otherwise below
// we may try to store in it a second char (libstdc++/9761).
const bool __testpb = _M_pback_init;
const bool __testeof = traits_type::eq_int_type(__i, __ret);
int_type __tmp;
if (this->eback() < this->gptr())
{
this->gbump(-1);
__tmp = traits_type::to_int_type(*this->gptr());
}
else if (this->seekoff(-1, ios_base::cur) != pos_type(off_type(-1)))
{
__tmp = this->underflow();
if (traits_type::eq_int_type(__tmp, __ret))
return __ret;
}
else
{
// At the beginning of the buffer, need to make a
// putback position available. But the seek may fail
// (f.i., at the beginning of a file, see
// libstdc++/9439) and in that case we return
// traits_type::eof().
return __ret;
}
// Try to put back __i into input sequence in one of three ways.
// Order these tests done in is unspecified by the standard.
if (!__testeof && traits_type::eq_int_type(__i, __tmp))
__ret = __i;
else if (__testeof)
__ret = traits_type::not_eof(__i);
else if (!__testpb)
{
_M_create_pback();
_M_reading = true;
*this->gptr() = traits_type::to_char_type(__i);
__ret = __i;
}
}
return __ret;
}
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::int_type
basic_filebuf<_CharT, _Traits>::
overflow(int_type __c)
{
int_type __ret = traits_type::eof();
const bool __testeof = traits_type::eq_int_type(__c, __ret);
const bool __testout = _M_mode & ios_base::out;
if (__testout)
{
if (_M_reading)
{
_M_destroy_pback();
const int __gptr_off = _M_get_ext_pos(_M_state_last);
if (_M_seek(__gptr_off, ios_base::cur, _M_state_last)
== pos_type(off_type(-1)))
return __ret;
}
if (this->pbase() < this->pptr())
{
// If appropriate, append the overflow char.
if (!__testeof)
{
*this->pptr() = traits_type::to_char_type(__c);
this->pbump(1);
}
// Convert pending sequence to external representation,
// and output.
if (_M_convert_to_external(this->pbase(),
this->pptr() - this->pbase()))
{
_M_set_buffer(0);
__ret = traits_type::not_eof(__c);
}
}
else if (_M_buf_size > 1)
{
// Overflow in 'uncommitted' mode: set _M_writing, set
// the buffer to the initial 'write' mode, and put __c
// into the buffer.
_M_set_buffer(0);
_M_writing = true;
if (!__testeof)
{
*this->pptr() = traits_type::to_char_type(__c);
this->pbump(1);
}
__ret = traits_type::not_eof(__c);
}
else
{
// Unbuffered.
char_type __conv = traits_type::to_char_type(__c);
if (__testeof || _M_convert_to_external(&__conv, 1))
{
_M_writing = true;
__ret = traits_type::not_eof(__c);
}
}
}
return __ret;
}
template<typename _CharT, typename _Traits>
bool
basic_filebuf<_CharT, _Traits>::
_M_convert_to_external(_CharT* __ibuf, streamsize __ilen)
{
// Sizes of external and pending output.
streamsize __elen;
streamsize __plen;
if (__check_facet(_M_codecvt).always_noconv())
{
__elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
__plen = __ilen;
}
else
{
// Worst-case number of external bytes needed.
// XXX Not done encoding() == -1.
streamsize __blen = __ilen * _M_codecvt->max_length();
char* __buf = static_cast<char*>(__builtin_alloca(__blen));
char* __bend;
const char_type* __iend;
codecvt_base::result __r;
__r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
__iend, __buf, __buf + __blen, __bend);
if (__r == codecvt_base::ok || __r == codecvt_base::partial)
__blen = __bend - __buf;
else if (__r == codecvt_base::noconv)
{
// Same as the always_noconv case above.
__buf = reinterpret_cast<char*>(__ibuf);
__blen = __ilen;
}
else
__throw_ios_failure(__N("basic_filebuf::_M_convert_to_external "
"conversion error"));
__elen = _M_file.xsputn(__buf, __blen);
__plen = __blen;
// Try once more for partial conversions.
if (__r == codecvt_base::partial && __elen == __plen)
{
const char_type* __iresume = __iend;
streamsize __rlen = this->pptr() - __iend;
__r = _M_codecvt->out(_M_state_cur, __iresume,
__iresume + __rlen, __iend, __buf,
__buf + __blen, __bend);
if (__r != codecvt_base::error)
{
__rlen = __bend - __buf;
__elen = _M_file.xsputn(__buf, __rlen);
__plen = __rlen;
}
else
__throw_ios_failure(__N("basic_filebuf::_M_convert_to_external "
"conversion error"));
}
}
return __elen == __plen;
}
template<typename _CharT, typename _Traits>
streamsize
basic_filebuf<_CharT, _Traits>::
xsgetn(_CharT* __s, streamsize __n)
{
// Clear out pback buffer before going on to the real deal...
streamsize __ret = 0;
if (_M_pback_init)
{
if (__n > 0 && this->gptr() == this->eback())
{
*__s++ = *this->gptr(); // emulate non-underflowing sbumpc
this->gbump(1);
__ret = 1;
--__n;
}
_M_destroy_pback();
}
else if (_M_writing)
{
if (overflow() == traits_type::eof())
return __ret;
_M_set_buffer(-1);
_M_writing = false;
}
// Optimization in the always_noconv() case, to be generalized in the
// future: when __n > __buflen we read directly instead of using the
// buffer repeatedly.
const bool __testin = _M_mode & ios_base::in;
const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
&& __testin)
{
// First, copy the chars already present in the buffer.
const streamsize __avail = this->egptr() - this->gptr();
if (__avail != 0)
{
traits_type::copy(__s, this->gptr(), __avail);
__s += __avail;
this->setg(this->eback(), this->gptr() + __avail,
this->egptr());
__ret += __avail;
__n -= __avail;
}
// Need to loop in case of short reads (relatively common
// with pipes).
streamsize __len;
for (;;)
{
__len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
__n);
if (__len == -1)
__throw_ios_failure(__N("basic_filebuf::xsgetn "
"error reading the file"));
if (__len == 0)
break;
__n -= __len;
__ret += __len;
if (__n == 0)
break;
__s += __len;
}
if (__n == 0)
{
_M_set_buffer(0);
_M_reading = true;
}
else if (__len == 0)
{
// If end of file is reached, set 'uncommitted'
// mode, thus allowing an immediate write without
// an intervening seek.
_M_set_buffer(-1);
_M_reading = false;
}
}
else
__ret += __streambuf_type::xsgetn(__s, __n);
return __ret;
}
template<typename _CharT, typename _Traits>
streamsize
basic_filebuf<_CharT, _Traits>::
xsputn(const _CharT* __s, streamsize __n)
{
streamsize __ret = 0;
// Optimization in the always_noconv() case, to be generalized in the
// future: when __n is sufficiently large we write directly instead of
// using the buffer.
const bool __testout = _M_mode & ios_base::out;
if (__check_facet(_M_codecvt).always_noconv()
&& __testout && !_M_reading)
{
// Measurement would reveal the best choice.
const streamsize __chunk = 1ul << 10;
streamsize __bufavail = this->epptr() - this->pptr();
// Don't mistake 'uncommitted' mode buffered with unbuffered.
if (!_M_writing && _M_buf_size > 1)
__bufavail = _M_buf_size - 1;
const streamsize __limit = std::min(__chunk, __bufavail);
if (__n >= __limit)
{
const streamsize __buffill = this->pptr() - this->pbase();
const char* __buf = reinterpret_cast<const char*>(this->pbase());
__ret = _M_file.xsputn_2(__buf, __buffill,
reinterpret_cast<const char*>(__s),
__n);
if (__ret == __buffill + __n)
{
_M_set_buffer(0);
_M_writing = true;
}
if (__ret > __buffill)
__ret -= __buffill;
else
__ret = 0;
}
else
__ret = __streambuf_type::xsputn(__s, __n);
}
else
__ret = __streambuf_type::xsputn(__s, __n);
return __ret;
}
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::__streambuf_type*
basic_filebuf<_CharT, _Traits>::
setbuf(char_type* __s, streamsize __n)
{
if (!this->is_open())
{
if (__s == 0 && __n == 0)
_M_buf_size = 1;
else if (__s && __n > 0)
{
// This is implementation-defined behavior, and assumes that
// an external char_type array of length __n exists and has
// been pre-allocated. If this is not the case, things will
// quickly blow up. When __n > 1, __n - 1 positions will be
// used for the get area, __n - 1 for the put area and 1
// position to host the overflow char of a full put area.
// When __n == 1, 1 position will be used for the get area
// and 0 for the put area, as in the unbuffered case above.
_M_buf = __s;
_M_buf_size = __n;
}
}
return this;
}
// According to 27.8.1.4 p11 - 13, seekoff should ignore the last
// argument (of type openmode).
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::pos_type
basic_filebuf<_CharT, _Traits>::
seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
{
int __width = 0;
if (_M_codecvt)
__width = _M_codecvt->encoding();
if (__width < 0)
__width = 0;
pos_type __ret = pos_type(off_type(-1));
const bool __testfail = __off != 0 && __width <= 0;
if (this->is_open() && !__testfail)
{
// tellg and tellp queries do not affect any state, unless
// ! always_noconv and the put sequence is not empty.
// In that case, determining the position requires converting the
// put sequence. That doesn't use ext_buf, so requires a flush.
bool __no_movement = __way == ios_base::cur && __off == 0
&& (!_M_writing || _M_codecvt->always_noconv());
// Ditch any pback buffers to avoid confusion.
if (!__no_movement)
_M_destroy_pback();
// Correct state at destination. Note that this is the correct
// state for the current position during output, because
// codecvt::unshift() returns the state to the initial state.
// This is also the correct state at the end of the file because
// an unshift sequence should have been written at the end.
__state_type __state = _M_state_beg;
off_type __computed_off = __off * __width;
if (_M_reading && __way == ios_base::cur)
{
__state = _M_state_last;
__computed_off += _M_get_ext_pos(__state);
}
if (!__no_movement)
__ret = _M_seek(__computed_off, __way, __state);
else
{
if (_M_writing)
__computed_off = this->pptr() - this->pbase();
off_type __file_off = _M_file.seekoff(0, ios_base::cur);
if (__file_off != off_type(-1))
{
__ret = __file_off + __computed_off;
__ret.state(__state);
}
}
}
return __ret;
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 171. Strange seekpos() semantics due to joint position
// According to the resolution of DR 171, seekpos should ignore the last
// argument (of type openmode).
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::pos_type
basic_filebuf<_CharT, _Traits>::
seekpos(pos_type __pos, ios_base::openmode)
{
pos_type __ret = pos_type(off_type(-1));
if (this->is_open())
{
// Ditch any pback buffers to avoid confusion.
_M_destroy_pback();
__ret = _M_seek(off_type(__pos), ios_base::beg, __pos.state());
}
return __ret;
}
template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::pos_type
basic_filebuf<_CharT, _Traits>::
_M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
{
pos_type __ret = pos_type(off_type(-1));
if (_M_terminate_output())
{
off_type __file_off = _M_file.seekoff(__off, __way);
if (__file_off != off_type(-1))
{
_M_reading = false;
_M_writing = false;
_M_ext_next = _M_ext_end = _M_ext_buf;
_M_set_buffer(-1);
_M_state_cur = __state;
__ret = __file_off;
__ret.state(_M_state_cur);
}
}
return __ret;
}
// Returns the distance from the end of the ext buffer to the point
// corresponding to gptr(). This is a negative value. Updates __state
// from eback() correspondence to gptr().
template<typename _CharT, typename _Traits>
int basic_filebuf<_CharT, _Traits>::
_M_get_ext_pos(__state_type& __state)
{
if (_M_codecvt->always_noconv())
return this->gptr() - this->egptr();
else
{
// Calculate offset from _M_ext_buf that corresponds to
// gptr(). Precondition: __state == _M_state_last, which
// corresponds to eback().
const int __gptr_off =
_M_codecvt->length(__state, _M_ext_buf, _M_ext_next,
this->gptr() - this->eback());
return _M_ext_buf + __gptr_off - _M_ext_end;
}
}
template<typename _CharT, typename _Traits>
bool
basic_filebuf<_CharT, _Traits>::
_M_terminate_output()
{
// Part one: update the output sequence.
bool __testvalid = true;
if (this->pbase() < this->pptr())
{
const int_type __tmp = this->overflow();
if (traits_type::eq_int_type(__tmp, traits_type::eof()))
__testvalid = false;
}
// Part two: output unshift sequence.
if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
&& __testvalid)
{
// Note: this value is arbitrary, since there is no way to
// get the length of the unshift sequence from codecvt,
// without calling unshift.
const size_t __blen = 128;
char __buf[__blen];
codecvt_base::result __r;
streamsize __ilen = 0;
do
{
char* __next;
__r = _M_codecvt->unshift(_M_state_cur, __buf,
__buf + __blen, __next);
if (__r == codecvt_base::error)
__testvalid = false;
else if (__r == codecvt_base::ok ||
__r == codecvt_base::partial)
{
__ilen = __next - __buf;
if (__ilen > 0)
{
const streamsize __elen = _M_file.xsputn(__buf, __ilen);
if (__elen != __ilen)
__testvalid = false;
}
}
}
while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
if (__testvalid)
{
// This second call to overflow() is required by the standard,
// but it's not clear why it's needed, since the output buffer
// should be empty by this point (it should have been emptied
// in the first call to overflow()).
const int_type __tmp = this->overflow();
if (traits_type::eq_int_type(__tmp, traits_type::eof()))
__testvalid = false;
}
}
return __testvalid;
}
template<typename _CharT, typename _Traits>
int
basic_filebuf<_CharT, _Traits>::
sync()
{
// Make sure that the internal buffer resyncs its idea of
// the file position with the external file.
int __ret = 0;
if (this->pbase() < this->pptr())
{
const int_type __tmp = this->overflow();
if (traits_type::eq_int_type(__tmp, traits_type::eof()))
__ret = -1;
}
return __ret;
}
template<typename _CharT, typename _Traits>
void
basic_filebuf<_CharT, _Traits>::
imbue(const locale& __loc)
{
bool __testvalid = true;
const __codecvt_type* _M_codecvt_tmp = 0;
if (__builtin_expect(has_facet<__codecvt_type>(__loc), true))
_M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
if (this->is_open())
{
// encoding() == -1 is ok only at the beginning.
if ((_M_reading || _M_writing)
&& __check_facet(_M_codecvt).encoding() == -1)
__testvalid = false;
else
{
if (_M_reading)
{
if (__check_facet(_M_codecvt).always_noconv())
{
if (_M_codecvt_tmp
&& !__check_facet(_M_codecvt_tmp).always_noconv())
__testvalid = this->seekoff(0, ios_base::cur, _M_mode)
!= pos_type(off_type(-1));
}
else
{
// External position corresponding to gptr().
_M_ext_next = _M_ext_buf
+ _M_codecvt->length(_M_state_last, _M_ext_buf,
_M_ext_next,
this->gptr() - this->eback());
const streamsize __remainder = _M_ext_end - _M_ext_next;
if (__remainder)
__builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
_M_ext_next = _M_ext_buf;
_M_ext_end = _M_ext_buf + __remainder;
_M_set_buffer(-1);
_M_state_last = _M_state_cur = _M_state_beg;
}
}
else if (_M_writing && (__testvalid = _M_terminate_output()))
_M_set_buffer(-1);
}
}
if (__testvalid)
_M_codecvt = _M_codecvt_tmp;
else
_M_codecvt = 0;
}
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class basic_filebuf<char>;
extern template class basic_ifstream<char>;
extern template class basic_ofstream<char>;
extern template class basic_fstream<char>;
#ifdef _GLIBCXX_USE_WCHAR_T
extern template class basic_filebuf<wchar_t>;
extern template class basic_ifstream<wchar_t>;
extern template class basic_ofstream<wchar_t>;
extern template class basic_fstream<wchar_t>;
#endif
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

View File

@@ -0,0 +1,106 @@
// Function-Based Exception Support -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/functexcept.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{exception}
*
* This header provides support for -fno-exceptions.
*/
//
// ISO C++ 14882: 19.1 Exception classes
//
#ifndef _FUNCTEXCEPT_H
#define _FUNCTEXCEPT_H 1
#include <bits/c++config.h>
#include <bits/exception_defines.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Helper for exception objects in <except>
void
__throw_bad_exception(void) __attribute__((__noreturn__));
// Helper for exception objects in <new>
void
__throw_bad_alloc(void) __attribute__((__noreturn__));
// Helper for exception objects in <typeinfo>
void
__throw_bad_cast(void) __attribute__((__noreturn__));
void
__throw_bad_typeid(void) __attribute__((__noreturn__));
// Helpers for exception objects in <stdexcept>
void
__throw_logic_error(const char*) __attribute__((__noreturn__));
void
__throw_domain_error(const char*) __attribute__((__noreturn__));
void
__throw_invalid_argument(const char*) __attribute__((__noreturn__));
void
__throw_length_error(const char*) __attribute__((__noreturn__));
void
__throw_out_of_range(const char*) __attribute__((__noreturn__));
void
__throw_runtime_error(const char*) __attribute__((__noreturn__));
void
__throw_range_error(const char*) __attribute__((__noreturn__));
void
__throw_overflow_error(const char*) __attribute__((__noreturn__));
void
__throw_underflow_error(const char*) __attribute__((__noreturn__));
// Helpers for exception objects in <ios>
void
__throw_ios_failure(const char*) __attribute__((__noreturn__));
void
__throw_system_error(int) __attribute__((__noreturn__));
void
__throw_future_error(int) __attribute__((__noreturn__));
// Helpers for exception objects in <functional>
void
__throw_bad_function_call() __attribute__((__noreturn__));
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@@ -0,0 +1,212 @@
// functional_hash.h header -*- C++ -*-
// Copyright (C) 2007-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/functional_hash.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _FUNCTIONAL_HASH_H
#define _FUNCTIONAL_HASH_H 1
#pragma GCC system_header
#include <bits/hash_bytes.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/** @defgroup hashes Hashes
* @ingroup functors
*
* Hashing functors taking a variable type and returning a @c std::size_t.
*
* @{
*/
template<typename _Result, typename _Arg>
struct __hash_base
{
typedef _Result result_type;
typedef _Arg argument_type;
};
/// Primary class template hash.
template<typename _Tp>
struct hash;
/// Partial specializations for pointer types.
template<typename _Tp>
struct hash<_Tp*> : public __hash_base<size_t, _Tp*>
{
size_t
operator()(_Tp* __p) const noexcept
{ return reinterpret_cast<size_t>(__p); }
};
// Explicit specializations for integer types.
#define _Cxx_hashtable_define_trivial_hash(_Tp) \
template<> \
struct hash<_Tp> : public __hash_base<size_t, _Tp> \
{ \
size_t \
operator()(_Tp __val) const noexcept \
{ return static_cast<size_t>(__val); } \
};
/// Explicit specialization for bool.
_Cxx_hashtable_define_trivial_hash(bool)
/// Explicit specialization for char.
_Cxx_hashtable_define_trivial_hash(char)
/// Explicit specialization for signed char.
_Cxx_hashtable_define_trivial_hash(signed char)
/// Explicit specialization for unsigned char.
_Cxx_hashtable_define_trivial_hash(unsigned char)
/// Explicit specialization for wchar_t.
_Cxx_hashtable_define_trivial_hash(wchar_t)
/// Explicit specialization for char16_t.
_Cxx_hashtable_define_trivial_hash(char16_t)
/// Explicit specialization for char32_t.
_Cxx_hashtable_define_trivial_hash(char32_t)
/// Explicit specialization for short.
_Cxx_hashtable_define_trivial_hash(short)
/// Explicit specialization for int.
_Cxx_hashtable_define_trivial_hash(int)
/// Explicit specialization for long.
_Cxx_hashtable_define_trivial_hash(long)
/// Explicit specialization for long long.
_Cxx_hashtable_define_trivial_hash(long long)
/// Explicit specialization for unsigned short.
_Cxx_hashtable_define_trivial_hash(unsigned short)
/// Explicit specialization for unsigned int.
_Cxx_hashtable_define_trivial_hash(unsigned int)
/// Explicit specialization for unsigned long.
_Cxx_hashtable_define_trivial_hash(unsigned long)
/// Explicit specialization for unsigned long long.
_Cxx_hashtable_define_trivial_hash(unsigned long long)
#undef _Cxx_hashtable_define_trivial_hash
struct _Hash_impl
{
static size_t
hash(const void* __ptr, size_t __clength,
size_t __seed = static_cast<size_t>(0xc70f6907UL))
{ return _Hash_bytes(__ptr, __clength, __seed); }
template<typename _Tp>
static size_t
hash(const _Tp& __val)
{ return hash(&__val, sizeof(__val)); }
template<typename _Tp>
static size_t
__hash_combine(const _Tp& __val, size_t __hash)
{ return hash(&__val, sizeof(__val), __hash); }
};
struct _Fnv_hash_impl
{
static size_t
hash(const void* __ptr, size_t __clength,
size_t __seed = static_cast<size_t>(2166136261UL))
{ return _Fnv_hash_bytes(__ptr, __clength, __seed); }
template<typename _Tp>
static size_t
hash(const _Tp& __val)
{ return hash(&__val, sizeof(__val)); }
template<typename _Tp>
static size_t
__hash_combine(const _Tp& __val, size_t __hash)
{ return hash(&__val, sizeof(__val), __hash); }
};
/// Specialization for float.
template<>
struct hash<float> : public __hash_base<size_t, float>
{
size_t
operator()(float __val) const noexcept
{
// 0 and -0 both hash to zero.
return __val != 0.0f ? std::_Hash_impl::hash(__val) : 0;
}
};
/// Specialization for double.
template<>
struct hash<double> : public __hash_base<size_t, double>
{
size_t
operator()(double __val) const noexcept
{
// 0 and -0 both hash to zero.
return __val != 0.0 ? std::_Hash_impl::hash(__val) : 0;
}
};
/// Specialization for long double.
template<>
struct hash<long double>
: public __hash_base<size_t, long double>
{
_GLIBCXX_PURE size_t
operator()(long double __val) const noexcept;
};
// @} group hashes
// Hint about performance of hash functor. If not fast the hash based
// containers will cache the hash code.
// Default behavior is to consider that hasher are fast unless specified
// otherwise.
template<typename _Hash>
struct __is_fast_hash : public std::true_type
{ };
template<>
struct __is_fast_hash<hash<long double>> : public std::false_type
{ };
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // _FUNCTIONAL_HASH_H

View File

@@ -0,0 +1,185 @@
// The template and inlines for the -*- C++ -*- gslice class.
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/gslice.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{valarray}
*/
// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
#ifndef _GSLICE_H
#define _GSLICE_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup numeric_arrays
* @{
*/
/**
* @brief Class defining multi-dimensional subset of an array.
*
* The slice class represents a multi-dimensional subset of an array,
* specified by three parameter sets: start offset, size array, and stride
* array. The start offset is the index of the first element of the array
* that is part of the subset. The size and stride array describe each
* dimension of the slice. Size is the number of elements in that
* dimension, and stride is the distance in the array between successive
* elements in that dimension. Each dimension's size and stride is taken
* to begin at an array element described by the previous dimension. The
* size array and stride array must be the same size.
*
* For example, if you have offset==3, stride[0]==11, size[1]==3,
* stride[1]==3, then slice[0,0]==array[3], slice[0,1]==array[6],
* slice[0,2]==array[9], slice[1,0]==array[14], slice[1,1]==array[17],
* slice[1,2]==array[20].
*/
class gslice
{
public:
/// Construct an empty slice.
gslice();
/**
* @brief Construct a slice.
*
* Constructs a slice with as many dimensions as the length of the @a l
* and @a s arrays.
*
* @param __o Offset in array of first element.
* @param __l Array of dimension lengths.
* @param __s Array of dimension strides between array elements.
*/
gslice(size_t __o, const valarray<size_t>& __l,
const valarray<size_t>& __s);
// XXX: the IS says the copy-ctor and copy-assignment operators are
// synthesized by the compiler but they are just unsuitable
// for a ref-counted semantic
/// Copy constructor.
gslice(const gslice&);
/// Destructor.
~gslice();
// XXX: See the note above.
/// Assignment operator.
gslice& operator=(const gslice&);
/// Return array offset of first slice element.
size_t start() const;
/// Return array of sizes of slice dimensions.
valarray<size_t> size() const;
/// Return array of array strides for each dimension.
valarray<size_t> stride() const;
private:
struct _Indexer
{
size_t _M_count;
size_t _M_start;
valarray<size_t> _M_size;
valarray<size_t> _M_stride;
valarray<size_t> _M_index; // Linear array of referenced indices
_Indexer()
: _M_count(1), _M_start(0), _M_size(), _M_stride(), _M_index() {}
_Indexer(size_t, const valarray<size_t>&,
const valarray<size_t>&);
void
_M_increment_use()
{ ++_M_count; }
size_t
_M_decrement_use()
{ return --_M_count; }
};
_Indexer* _M_index;
template<typename _Tp> friend class valarray;
};
inline size_t
gslice::start() const
{ return _M_index ? _M_index->_M_start : 0; }
inline valarray<size_t>
gslice::size() const
{ return _M_index ? _M_index->_M_size : valarray<size_t>(); }
inline valarray<size_t>
gslice::stride() const
{ return _M_index ? _M_index->_M_stride : valarray<size_t>(); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 543. valarray slice default constructor
inline
gslice::gslice()
: _M_index(new gslice::_Indexer()) {}
inline
gslice::gslice(size_t __o, const valarray<size_t>& __l,
const valarray<size_t>& __s)
: _M_index(new gslice::_Indexer(__o, __l, __s)) {}
inline
gslice::gslice(const gslice& __g)
: _M_index(__g._M_index)
{ if (_M_index) _M_index->_M_increment_use(); }
inline
gslice::~gslice()
{
if (_M_index && _M_index->_M_decrement_use() == 0)
delete _M_index;
}
inline gslice&
gslice::operator=(const gslice& __g)
{
if (__g._M_index)
__g._M_index->_M_increment_use();
if (_M_index && _M_index->_M_decrement_use() == 0)
delete _M_index;
_M_index = __g._M_index;
return *this;
}
// @} group numeric_arrays
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _GSLICE_H */

View File

@@ -0,0 +1,218 @@
// The template and inlines for the -*- C++ -*- gslice_array class.
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/gslice_array.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{valarray}
*/
// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
#ifndef _GSLICE_ARRAY_H
#define _GSLICE_ARRAY_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup numeric_arrays
* @{
*/
/**
* @brief Reference to multi-dimensional subset of an array.
*
* A gslice_array is a reference to the actual elements of an array
* specified by a gslice. The way to get a gslice_array is to call
* operator[](gslice) on a valarray. The returned gslice_array then
* permits carrying operations out on the referenced subset of elements in
* the original valarray. For example, operator+=(valarray) will add
* values to the subset of elements in the underlying valarray this
* gslice_array refers to.
*
* @param Tp Element type.
*/
template<typename _Tp>
class gslice_array
{
public:
typedef _Tp value_type;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 253. valarray helper functions are almost entirely useless
/// Copy constructor. Both slices refer to the same underlying array.
gslice_array(const gslice_array&);
/// Assignment operator. Assigns slice elements to corresponding
/// elements of @a a.
gslice_array& operator=(const gslice_array&);
/// Assign slice elements to corresponding elements of @a v.
void operator=(const valarray<_Tp>&) const;
/// Multiply slice elements by corresponding elements of @a v.
void operator*=(const valarray<_Tp>&) const;
/// Divide slice elements by corresponding elements of @a v.
void operator/=(const valarray<_Tp>&) const;
/// Modulo slice elements by corresponding elements of @a v.
void operator%=(const valarray<_Tp>&) const;
/// Add corresponding elements of @a v to slice elements.
void operator+=(const valarray<_Tp>&) const;
/// Subtract corresponding elements of @a v from slice elements.
void operator-=(const valarray<_Tp>&) const;
/// Logical xor slice elements with corresponding elements of @a v.
void operator^=(const valarray<_Tp>&) const;
/// Logical and slice elements with corresponding elements of @a v.
void operator&=(const valarray<_Tp>&) const;
/// Logical or slice elements with corresponding elements of @a v.
void operator|=(const valarray<_Tp>&) const;
/// Left shift slice elements by corresponding elements of @a v.
void operator<<=(const valarray<_Tp>&) const;
/// Right shift slice elements by corresponding elements of @a v.
void operator>>=(const valarray<_Tp>&) const;
/// Assign all slice elements to @a t.
void operator=(const _Tp&) const;
template<class _Dom>
void operator=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator*=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator/=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator%=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator+=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator-=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator^=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator&=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator|=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator<<=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator>>=(const _Expr<_Dom, _Tp>&) const;
private:
_Array<_Tp> _M_array;
const valarray<size_t>& _M_index;
friend class valarray<_Tp>;
gslice_array(_Array<_Tp>, const valarray<size_t>&);
// not implemented
gslice_array();
};
template<typename _Tp>
inline
gslice_array<_Tp>::gslice_array(_Array<_Tp> __a,
const valarray<size_t>& __i)
: _M_array(__a), _M_index(__i) {}
template<typename _Tp>
inline
gslice_array<_Tp>::gslice_array(const gslice_array<_Tp>& __a)
: _M_array(__a._M_array), _M_index(__a._M_index) {}
template<typename _Tp>
inline gslice_array<_Tp>&
gslice_array<_Tp>::operator=(const gslice_array<_Tp>& __a)
{
std::__valarray_copy(_Array<_Tp>(__a._M_array),
_Array<size_t>(__a._M_index), _M_index.size(),
_M_array, _Array<size_t>(_M_index));
return *this;
}
template<typename _Tp>
inline void
gslice_array<_Tp>::operator=(const _Tp& __t) const
{
std::__valarray_fill(_M_array, _Array<size_t>(_M_index),
_M_index.size(), __t);
}
template<typename _Tp>
inline void
gslice_array<_Tp>::operator=(const valarray<_Tp>& __v) const
{
std::__valarray_copy(_Array<_Tp>(__v), __v.size(),
_M_array, _Array<size_t>(_M_index));
}
template<typename _Tp>
template<class _Dom>
inline void
gslice_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const
{
std::__valarray_copy (__e, _M_index.size(), _M_array,
_Array<size_t>(_M_index));
}
#undef _DEFINE_VALARRAY_OPERATOR
#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \
template<typename _Tp> \
inline void \
gslice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \
{ \
_Array_augmented_##_Name(_M_array, _Array<size_t>(_M_index), \
_Array<_Tp>(__v), __v.size()); \
} \
\
template<typename _Tp> \
template<class _Dom> \
inline void \
gslice_array<_Tp>::operator _Op##= (const _Expr<_Dom, _Tp>& __e) const\
{ \
_Array_augmented_##_Name(_M_array, _Array<size_t>(_M_index), __e,\
_M_index.size()); \
}
_DEFINE_VALARRAY_OPERATOR(*, __multiplies)
_DEFINE_VALARRAY_OPERATOR(/, __divides)
_DEFINE_VALARRAY_OPERATOR(%, __modulus)
_DEFINE_VALARRAY_OPERATOR(+, __plus)
_DEFINE_VALARRAY_OPERATOR(-, __minus)
_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor)
_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and)
_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or)
_DEFINE_VALARRAY_OPERATOR(<<, __shift_left)
_DEFINE_VALARRAY_OPERATOR(>>, __shift_right)
#undef _DEFINE_VALARRAY_OPERATOR
// @} group numeric_arrays
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _GSLICE_ARRAY_H */

View File

@@ -0,0 +1,59 @@
// Declarations for hash functions. -*- C++ -*-
// Copyright (C) 2010-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/hash_bytes.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _HASH_BYTES_H
#define _HASH_BYTES_H 1
#pragma GCC system_header
#include <bits/c++config.h>
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Hash function implementation for the nontrivial specialization.
// All of them are based on a primitive that hashes a pointer to a
// byte array. The actual hash algorithm is not guaranteed to stay
// the same from release to release -- it may be updated or tuned to
// improve hash quality or speed.
size_t
_Hash_bytes(const void* __ptr, size_t __len, size_t __seed);
// A similar hash primitive, using the FNV hash algorithm. This
// algorithm is guaranteed to stay the same from release to release.
// (although it might not produce the same values on different
// machines.)
size_t
_Fnv_hash_bytes(const void* __ptr, size_t __len, size_t __seed);
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,212 @@
// The template and inlines for the -*- C++ -*- indirect_array class.
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/indirect_array.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{valarray}
*/
// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
#ifndef _INDIRECT_ARRAY_H
#define _INDIRECT_ARRAY_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup numeric_arrays
* @{
*/
/**
* @brief Reference to arbitrary subset of an array.
*
* An indirect_array is a reference to the actual elements of an array
* specified by an ordered array of indices. The way to get an
* indirect_array is to call operator[](valarray<size_t>) on a valarray.
* The returned indirect_array then permits carrying operations out on the
* referenced subset of elements in the original valarray.
*
* For example, if an indirect_array is obtained using the array (4,2,0) as
* an argument, and then assigned to an array containing (1,2,3), then the
* underlying array will have array[0]==3, array[2]==2, and array[4]==1.
*
* @param Tp Element type.
*/
template <class _Tp>
class indirect_array
{
public:
typedef _Tp value_type;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 253. valarray helper functions are almost entirely useless
/// Copy constructor. Both slices refer to the same underlying array.
indirect_array(const indirect_array&);
/// Assignment operator. Assigns elements to corresponding elements
/// of @a a.
indirect_array& operator=(const indirect_array&);
/// Assign slice elements to corresponding elements of @a v.
void operator=(const valarray<_Tp>&) const;
/// Multiply slice elements by corresponding elements of @a v.
void operator*=(const valarray<_Tp>&) const;
/// Divide slice elements by corresponding elements of @a v.
void operator/=(const valarray<_Tp>&) const;
/// Modulo slice elements by corresponding elements of @a v.
void operator%=(const valarray<_Tp>&) const;
/// Add corresponding elements of @a v to slice elements.
void operator+=(const valarray<_Tp>&) const;
/// Subtract corresponding elements of @a v from slice elements.
void operator-=(const valarray<_Tp>&) const;
/// Logical xor slice elements with corresponding elements of @a v.
void operator^=(const valarray<_Tp>&) const;
/// Logical and slice elements with corresponding elements of @a v.
void operator&=(const valarray<_Tp>&) const;
/// Logical or slice elements with corresponding elements of @a v.
void operator|=(const valarray<_Tp>&) const;
/// Left shift slice elements by corresponding elements of @a v.
void operator<<=(const valarray<_Tp>&) const;
/// Right shift slice elements by corresponding elements of @a v.
void operator>>=(const valarray<_Tp>&) const;
/// Assign all slice elements to @a t.
void operator= (const _Tp&) const;
// ~indirect_array();
template<class _Dom>
void operator=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator*=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator/=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator%=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator+=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator-=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator^=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator&=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator|=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator<<=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator>>=(const _Expr<_Dom, _Tp>&) const;
private:
/// Copy constructor. Both slices refer to the same underlying array.
indirect_array(_Array<_Tp>, size_t, _Array<size_t>);
friend class valarray<_Tp>;
friend class gslice_array<_Tp>;
const size_t _M_sz;
const _Array<size_t> _M_index;
const _Array<_Tp> _M_array;
// not implemented
indirect_array();
};
template<typename _Tp>
inline
indirect_array<_Tp>::indirect_array(const indirect_array<_Tp>& __a)
: _M_sz(__a._M_sz), _M_index(__a._M_index), _M_array(__a._M_array) {}
template<typename _Tp>
inline
indirect_array<_Tp>::indirect_array(_Array<_Tp> __a, size_t __s,
_Array<size_t> __i)
: _M_sz(__s), _M_index(__i), _M_array(__a) {}
template<typename _Tp>
inline indirect_array<_Tp>&
indirect_array<_Tp>::operator=(const indirect_array<_Tp>& __a)
{
std::__valarray_copy(__a._M_array, _M_sz, __a._M_index, _M_array,
_M_index);
return *this;
}
template<typename _Tp>
inline void
indirect_array<_Tp>::operator=(const _Tp& __t) const
{ std::__valarray_fill(_M_array, _M_index, _M_sz, __t); }
template<typename _Tp>
inline void
indirect_array<_Tp>::operator=(const valarray<_Tp>& __v) const
{ std::__valarray_copy(_Array<_Tp>(__v), _M_sz, _M_array, _M_index); }
template<typename _Tp>
template<class _Dom>
inline void
indirect_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const
{ std::__valarray_copy(__e, _M_sz, _M_array, _M_index); }
#undef _DEFINE_VALARRAY_OPERATOR
#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \
template<typename _Tp> \
inline void \
indirect_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const\
{ \
_Array_augmented_##_Name(_M_array, _M_index, _Array<_Tp>(__v), _M_sz); \
} \
\
template<typename _Tp> \
template<class _Dom> \
inline void \
indirect_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\
{ \
_Array_augmented_##_Name(_M_array, _M_index, __e, _M_sz); \
}
_DEFINE_VALARRAY_OPERATOR(*, __multiplies)
_DEFINE_VALARRAY_OPERATOR(/, __divides)
_DEFINE_VALARRAY_OPERATOR(%, __modulus)
_DEFINE_VALARRAY_OPERATOR(+, __plus)
_DEFINE_VALARRAY_OPERATOR(-, __minus)
_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor)
_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and)
_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or)
_DEFINE_VALARRAY_OPERATOR(<<, __shift_left)
_DEFINE_VALARRAY_OPERATOR(>>, __shift_right)
#undef _DEFINE_VALARRAY_OPERATOR
// @} group numeric_arrays
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _INDIRECT_ARRAY_H */

View File

@@ -0,0 +1,975 @@
// Iostreams base classes -*- C++ -*-
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ios_base.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ios}
*/
//
// ISO C++ 14882: 27.4 Iostreams base classes
//
#ifndef _IOS_BASE_H
#define _IOS_BASE_H 1
#pragma GCC system_header
#include <ext/atomicity.h>
#include <bits/localefwd.h>
#include <bits/locale_classes.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// The following definitions of bitmask types are enums, not ints,
// as permitted (but not required) in the standard, in order to provide
// better type safety in iostream calls. A side effect is that
// expressions involving them are no longer compile-time constants.
enum _Ios_Fmtflags
{
_S_boolalpha = 1L << 0,
_S_dec = 1L << 1,
_S_fixed = 1L << 2,
_S_hex = 1L << 3,
_S_internal = 1L << 4,
_S_left = 1L << 5,
_S_oct = 1L << 6,
_S_right = 1L << 7,
_S_scientific = 1L << 8,
_S_showbase = 1L << 9,
_S_showpoint = 1L << 10,
_S_showpos = 1L << 11,
_S_skipws = 1L << 12,
_S_unitbuf = 1L << 13,
_S_uppercase = 1L << 14,
_S_adjustfield = _S_left | _S_right | _S_internal,
_S_basefield = _S_dec | _S_oct | _S_hex,
_S_floatfield = _S_scientific | _S_fixed,
_S_ios_fmtflags_end = 1L << 16
};
inline _GLIBCXX_CONSTEXPR _Ios_Fmtflags
operator&(_Ios_Fmtflags __a, _Ios_Fmtflags __b)
{ return _Ios_Fmtflags(static_cast<int>(__a) & static_cast<int>(__b)); }
inline _GLIBCXX_CONSTEXPR _Ios_Fmtflags
operator|(_Ios_Fmtflags __a, _Ios_Fmtflags __b)
{ return _Ios_Fmtflags(static_cast<int>(__a) | static_cast<int>(__b)); }
inline _GLIBCXX_CONSTEXPR _Ios_Fmtflags
operator^(_Ios_Fmtflags __a, _Ios_Fmtflags __b)
{ return _Ios_Fmtflags(static_cast<int>(__a) ^ static_cast<int>(__b)); }
inline _GLIBCXX_CONSTEXPR _Ios_Fmtflags
operator~(_Ios_Fmtflags __a)
{ return _Ios_Fmtflags(~static_cast<int>(__a)); }
inline const _Ios_Fmtflags&
operator|=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b)
{ return __a = __a | __b; }
inline const _Ios_Fmtflags&
operator&=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b)
{ return __a = __a & __b; }
inline const _Ios_Fmtflags&
operator^=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b)
{ return __a = __a ^ __b; }
enum _Ios_Openmode
{
_S_app = 1L << 0,
_S_ate = 1L << 1,
_S_bin = 1L << 2,
_S_in = 1L << 3,
_S_out = 1L << 4,
_S_trunc = 1L << 5,
_S_ios_openmode_end = 1L << 16
};
inline _GLIBCXX_CONSTEXPR _Ios_Openmode
operator&(_Ios_Openmode __a, _Ios_Openmode __b)
{ return _Ios_Openmode(static_cast<int>(__a) & static_cast<int>(__b)); }
inline _GLIBCXX_CONSTEXPR _Ios_Openmode
operator|(_Ios_Openmode __a, _Ios_Openmode __b)
{ return _Ios_Openmode(static_cast<int>(__a) | static_cast<int>(__b)); }
inline _GLIBCXX_CONSTEXPR _Ios_Openmode
operator^(_Ios_Openmode __a, _Ios_Openmode __b)
{ return _Ios_Openmode(static_cast<int>(__a) ^ static_cast<int>(__b)); }
inline _GLIBCXX_CONSTEXPR _Ios_Openmode
operator~(_Ios_Openmode __a)
{ return _Ios_Openmode(~static_cast<int>(__a)); }
inline const _Ios_Openmode&
operator|=(_Ios_Openmode& __a, _Ios_Openmode __b)
{ return __a = __a | __b; }
inline const _Ios_Openmode&
operator&=(_Ios_Openmode& __a, _Ios_Openmode __b)
{ return __a = __a & __b; }
inline const _Ios_Openmode&
operator^=(_Ios_Openmode& __a, _Ios_Openmode __b)
{ return __a = __a ^ __b; }
enum _Ios_Iostate
{
_S_goodbit = 0,
_S_badbit = 1L << 0,
_S_eofbit = 1L << 1,
_S_failbit = 1L << 2,
_S_ios_iostate_end = 1L << 16
};
inline _GLIBCXX_CONSTEXPR _Ios_Iostate
operator&(_Ios_Iostate __a, _Ios_Iostate __b)
{ return _Ios_Iostate(static_cast<int>(__a) & static_cast<int>(__b)); }
inline _GLIBCXX_CONSTEXPR _Ios_Iostate
operator|(_Ios_Iostate __a, _Ios_Iostate __b)
{ return _Ios_Iostate(static_cast<int>(__a) | static_cast<int>(__b)); }
inline _GLIBCXX_CONSTEXPR _Ios_Iostate
operator^(_Ios_Iostate __a, _Ios_Iostate __b)
{ return _Ios_Iostate(static_cast<int>(__a) ^ static_cast<int>(__b)); }
inline _GLIBCXX_CONSTEXPR _Ios_Iostate
operator~(_Ios_Iostate __a)
{ return _Ios_Iostate(~static_cast<int>(__a)); }
inline const _Ios_Iostate&
operator|=(_Ios_Iostate& __a, _Ios_Iostate __b)
{ return __a = __a | __b; }
inline const _Ios_Iostate&
operator&=(_Ios_Iostate& __a, _Ios_Iostate __b)
{ return __a = __a & __b; }
inline const _Ios_Iostate&
operator^=(_Ios_Iostate& __a, _Ios_Iostate __b)
{ return __a = __a ^ __b; }
enum _Ios_Seekdir
{
_S_beg = 0,
_S_cur = _GLIBCXX_STDIO_SEEK_CUR,
_S_end = _GLIBCXX_STDIO_SEEK_END,
_S_ios_seekdir_end = 1L << 16
};
// 27.4.2 Class ios_base
/**
* @brief The base of the I/O class hierarchy.
* @ingroup io
*
* This class defines everything that can be defined about I/O that does
* not depend on the type of characters being input or output. Most
* people will only see @c ios_base when they need to specify the full
* name of the various I/O flags (e.g., the openmodes).
*/
class ios_base
{
public:
/**
* @brief These are thrown to indicate problems with io.
* @ingroup exceptions
*
* 27.4.2.1.1 Class ios_base::failure
*/
class failure : public exception
{
public:
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 48. Use of non-existent exception constructor
explicit
failure(const string& __str) throw();
// This declaration is not useless:
// http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Vague-Linkage.html
virtual
~failure() throw();
virtual const char*
what() const throw();
private:
string _M_msg;
};
// 27.4.2.1.2 Type ios_base::fmtflags
/**
* @brief This is a bitmask type.
*
* @c @a _Ios_Fmtflags is implementation-defined, but it is valid to
* perform bitwise operations on these values and expect the Right
* Thing to happen. Defined objects of type fmtflags are:
* - boolalpha
* - dec
* - fixed
* - hex
* - internal
* - left
* - oct
* - right
* - scientific
* - showbase
* - showpoint
* - showpos
* - skipws
* - unitbuf
* - uppercase
* - adjustfield
* - basefield
* - floatfield
*/
typedef _Ios_Fmtflags fmtflags;
/// Insert/extract @c bool in alphabetic rather than numeric format.
static const fmtflags boolalpha = _S_boolalpha;
/// Converts integer input or generates integer output in decimal base.
static const fmtflags dec = _S_dec;
/// Generate floating-point output in fixed-point notation.
static const fmtflags fixed = _S_fixed;
/// Converts integer input or generates integer output in hexadecimal base.
static const fmtflags hex = _S_hex;
/// Adds fill characters at a designated internal point in certain
/// generated output, or identical to @c right if no such point is
/// designated.
static const fmtflags internal = _S_internal;
/// Adds fill characters on the right (final positions) of certain
/// generated output. (I.e., the thing you print is flush left.)
static const fmtflags left = _S_left;
/// Converts integer input or generates integer output in octal base.
static const fmtflags oct = _S_oct;
/// Adds fill characters on the left (initial positions) of certain
/// generated output. (I.e., the thing you print is flush right.)
static const fmtflags right = _S_right;
/// Generates floating-point output in scientific notation.
static const fmtflags scientific = _S_scientific;
/// Generates a prefix indicating the numeric base of generated integer
/// output.
static const fmtflags showbase = _S_showbase;
/// Generates a decimal-point character unconditionally in generated
/// floating-point output.
static const fmtflags showpoint = _S_showpoint;
/// Generates a + sign in non-negative generated numeric output.
static const fmtflags showpos = _S_showpos;
/// Skips leading white space before certain input operations.
static const fmtflags skipws = _S_skipws;
/// Flushes output after each output operation.
static const fmtflags unitbuf = _S_unitbuf;
/// Replaces certain lowercase letters with their uppercase equivalents
/// in generated output.
static const fmtflags uppercase = _S_uppercase;
/// A mask of left|right|internal. Useful for the 2-arg form of @c setf.
static const fmtflags adjustfield = _S_adjustfield;
/// A mask of dec|oct|hex. Useful for the 2-arg form of @c setf.
static const fmtflags basefield = _S_basefield;
/// A mask of scientific|fixed. Useful for the 2-arg form of @c setf.
static const fmtflags floatfield = _S_floatfield;
// 27.4.2.1.3 Type ios_base::iostate
/**
* @brief This is a bitmask type.
*
* @c @a _Ios_Iostate is implementation-defined, but it is valid to
* perform bitwise operations on these values and expect the Right
* Thing to happen. Defined objects of type iostate are:
* - badbit
* - eofbit
* - failbit
* - goodbit
*/
typedef _Ios_Iostate iostate;
/// Indicates a loss of integrity in an input or output sequence (such
/// as an irrecoverable read error from a file).
static const iostate badbit = _S_badbit;
/// Indicates that an input operation reached the end of an input sequence.
static const iostate eofbit = _S_eofbit;
/// Indicates that an input operation failed to read the expected
/// characters, or that an output operation failed to generate the
/// desired characters.
static const iostate failbit = _S_failbit;
/// Indicates all is well.
static const iostate goodbit = _S_goodbit;
// 27.4.2.1.4 Type ios_base::openmode
/**
* @brief This is a bitmask type.
*
* @c @a _Ios_Openmode is implementation-defined, but it is valid to
* perform bitwise operations on these values and expect the Right
* Thing to happen. Defined objects of type openmode are:
* - app
* - ate
* - binary
* - in
* - out
* - trunc
*/
typedef _Ios_Openmode openmode;
/// Seek to end before each write.
static const openmode app = _S_app;
/// Open and seek to end immediately after opening.
static const openmode ate = _S_ate;
/// Perform input and output in binary mode (as opposed to text mode).
/// This is probably not what you think it is; see
/// http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch27s02.html
static const openmode binary = _S_bin;
/// Open for input. Default for @c ifstream and fstream.
static const openmode in = _S_in;
/// Open for output. Default for @c ofstream and fstream.
static const openmode out = _S_out;
/// Open for input. Default for @c ofstream.
static const openmode trunc = _S_trunc;
// 27.4.2.1.5 Type ios_base::seekdir
/**
* @brief This is an enumerated type.
*
* @c @a _Ios_Seekdir is implementation-defined. Defined values
* of type seekdir are:
* - beg
* - cur, equivalent to @c SEEK_CUR in the C standard library.
* - end, equivalent to @c SEEK_END in the C standard library.
*/
typedef _Ios_Seekdir seekdir;
/// Request a seek relative to the beginning of the stream.
static const seekdir beg = _S_beg;
/// Request a seek relative to the current position within the sequence.
static const seekdir cur = _S_cur;
/// Request a seek relative to the current end of the sequence.
static const seekdir end = _S_end;
// Annex D.6
typedef int io_state;
typedef int open_mode;
typedef int seek_dir;
typedef std::streampos streampos;
typedef std::streamoff streamoff;
// Callbacks;
/**
* @brief The set of events that may be passed to an event callback.
*
* erase_event is used during ~ios() and copyfmt(). imbue_event is used
* during imbue(). copyfmt_event is used during copyfmt().
*/
enum event
{
erase_event,
imbue_event,
copyfmt_event
};
/**
* @brief The type of an event callback function.
* @param __e One of the members of the event enum.
* @param __b Reference to the ios_base object.
* @param __i The integer provided when the callback was registered.
*
* Event callbacks are user defined functions that get called during
* several ios_base and basic_ios functions, specifically imbue(),
* copyfmt(), and ~ios().
*/
typedef void (*event_callback) (event __e, ios_base& __b, int __i);
/**
* @brief Add the callback __fn with parameter __index.
* @param __fn The function to add.
* @param __index The integer to pass to the function when invoked.
*
* Registers a function as an event callback with an integer parameter to
* be passed to the function when invoked. Multiple copies of the
* function are allowed. If there are multiple callbacks, they are
* invoked in the order they were registered.
*/
void
register_callback(event_callback __fn, int __index);
protected:
streamsize _M_precision;
streamsize _M_width;
fmtflags _M_flags;
iostate _M_exception;
iostate _M_streambuf_state;
// 27.4.2.6 Members for callbacks
// 27.4.2.6 ios_base callbacks
struct _Callback_list
{
// Data Members
_Callback_list* _M_next;
ios_base::event_callback _M_fn;
int _M_index;
_Atomic_word _M_refcount; // 0 means one reference.
_Callback_list(ios_base::event_callback __fn, int __index,
_Callback_list* __cb)
: _M_next(__cb), _M_fn(__fn), _M_index(__index), _M_refcount(0) { }
void
_M_add_reference() { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); }
// 0 => OK to delete.
int
_M_remove_reference()
{
// Be race-detector-friendly. For more info see bits/c++config.
_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount);
int __res = __gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1);
if (__res == 0)
{
_GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount);
}
return __res;
}
};
_Callback_list* _M_callbacks;
void
_M_call_callbacks(event __ev) throw();
void
_M_dispose_callbacks(void) throw();
// 27.4.2.5 Members for iword/pword storage
struct _Words
{
void* _M_pword;
long _M_iword;
_Words() : _M_pword(0), _M_iword(0) { }
};
// Only for failed iword/pword calls.
_Words _M_word_zero;
// Guaranteed storage.
// The first 5 iword and pword slots are reserved for internal use.
enum { _S_local_word_size = 8 };
_Words _M_local_word[_S_local_word_size];
// Allocated storage.
int _M_word_size;
_Words* _M_word;
_Words&
_M_grow_words(int __index, bool __iword);
// Members for locale and locale caching.
locale _M_ios_locale;
void
_M_init() throw();
public:
// 27.4.2.1.6 Class ios_base::Init
// Used to initialize standard streams. In theory, g++ could use
// -finit-priority to order this stuff correctly without going
// through these machinations.
class Init
{
friend class ios_base;
public:
Init();
~Init();
private:
static _Atomic_word _S_refcount;
static bool _S_synced_with_stdio;
};
// [27.4.2.2] fmtflags state functions
/**
* @brief Access to format flags.
* @return The format control flags for both input and output.
*/
fmtflags
flags() const
{ return _M_flags; }
/**
* @brief Setting new format flags all at once.
* @param __fmtfl The new flags to set.
* @return The previous format control flags.
*
* This function overwrites all the format flags with @a __fmtfl.
*/
fmtflags
flags(fmtflags __fmtfl)
{
fmtflags __old = _M_flags;
_M_flags = __fmtfl;
return __old;
}
/**
* @brief Setting new format flags.
* @param __fmtfl Additional flags to set.
* @return The previous format control flags.
*
* This function sets additional flags in format control. Flags that
* were previously set remain set.
*/
fmtflags
setf(fmtflags __fmtfl)
{
fmtflags __old = _M_flags;
_M_flags |= __fmtfl;
return __old;
}
/**
* @brief Setting new format flags.
* @param __fmtfl Additional flags to set.
* @param __mask The flags mask for @a fmtfl.
* @return The previous format control flags.
*
* This function clears @a mask in the format flags, then sets
* @a fmtfl @c & @a mask. An example mask is @c ios_base::adjustfield.
*/
fmtflags
setf(fmtflags __fmtfl, fmtflags __mask)
{
fmtflags __old = _M_flags;
_M_flags &= ~__mask;
_M_flags |= (__fmtfl & __mask);
return __old;
}
/**
* @brief Clearing format flags.
* @param __mask The flags to unset.
*
* This function clears @a __mask in the format flags.
*/
void
unsetf(fmtflags __mask)
{ _M_flags &= ~__mask; }
/**
* @brief Flags access.
* @return The precision to generate on certain output operations.
*
* Be careful if you try to give a definition of @a precision here; see
* DR 189.
*/
streamsize
precision() const
{ return _M_precision; }
/**
* @brief Changing flags.
* @param __prec The new precision value.
* @return The previous value of precision().
*/
streamsize
precision(streamsize __prec)
{
streamsize __old = _M_precision;
_M_precision = __prec;
return __old;
}
/**
* @brief Flags access.
* @return The minimum field width to generate on output operations.
*
* <em>Minimum field width</em> refers to the number of characters.
*/
streamsize
width() const
{ return _M_width; }
/**
* @brief Changing flags.
* @param __wide The new width value.
* @return The previous value of width().
*/
streamsize
width(streamsize __wide)
{
streamsize __old = _M_width;
_M_width = __wide;
return __old;
}
// [27.4.2.4] ios_base static members
/**
* @brief Interaction with the standard C I/O objects.
* @param __sync Whether to synchronize or not.
* @return True if the standard streams were previously synchronized.
*
* The synchronization referred to is @e only that between the standard
* C facilities (e.g., stdout) and the standard C++ objects (e.g.,
* cout). User-declared streams are unaffected. See
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch28s02.html
*/
static bool
sync_with_stdio(bool __sync = true);
// [27.4.2.3] ios_base locale functions
/**
* @brief Setting a new locale.
* @param __loc The new locale.
* @return The previous locale.
*
* Sets the new locale for this stream, and then invokes each callback
* with imbue_event.
*/
locale
imbue(const locale& __loc) throw();
/**
* @brief Locale access
* @return A copy of the current locale.
*
* If @c imbue(loc) has previously been called, then this function
* returns @c loc. Otherwise, it returns a copy of @c std::locale(),
* the global C++ locale.
*/
locale
getloc() const
{ return _M_ios_locale; }
/**
* @brief Locale access
* @return A reference to the current locale.
*
* Like getloc above, but returns a reference instead of
* generating a copy.
*/
const locale&
_M_getloc() const
{ return _M_ios_locale; }
// [27.4.2.5] ios_base storage functions
/**
* @brief Access to unique indices.
* @return An integer different from all previous calls.
*
* This function returns a unique integer every time it is called. It
* can be used for any purpose, but is primarily intended to be a unique
* index for the iword and pword functions. The expectation is that an
* application calls xalloc in order to obtain an index in the iword and
* pword arrays that can be used without fear of conflict.
*
* The implementation maintains a static variable that is incremented and
* returned on each invocation. xalloc is guaranteed to return an index
* that is safe to use in the iword and pword arrays.
*/
static int
xalloc() throw();
/**
* @brief Access to integer array.
* @param __ix Index into the array.
* @return A reference to an integer associated with the index.
*
* The iword function provides access to an array of integers that can be
* used for any purpose. The array grows as required to hold the
* supplied index. All integers in the array are initialized to 0.
*
* The implementation reserves several indices. You should use xalloc to
* obtain an index that is safe to use. Also note that since the array
* can grow dynamically, it is not safe to hold onto the reference.
*/
long&
iword(int __ix)
{
_Words& __word = (__ix < _M_word_size)
? _M_word[__ix] : _M_grow_words(__ix, true);
return __word._M_iword;
}
/**
* @brief Access to void pointer array.
* @param __ix Index into the array.
* @return A reference to a void* associated with the index.
*
* The pword function provides access to an array of pointers that can be
* used for any purpose. The array grows as required to hold the
* supplied index. All pointers in the array are initialized to 0.
*
* The implementation reserves several indices. You should use xalloc to
* obtain an index that is safe to use. Also note that since the array
* can grow dynamically, it is not safe to hold onto the reference.
*/
void*&
pword(int __ix)
{
_Words& __word = (__ix < _M_word_size)
? _M_word[__ix] : _M_grow_words(__ix, false);
return __word._M_pword;
}
// Destructor
/**
* Invokes each callback with erase_event. Destroys local storage.
*
* Note that the ios_base object for the standard streams never gets
* destroyed. As a result, any callbacks registered with the standard
* streams will not get invoked with erase_event (unless copyfmt is
* used).
*/
virtual ~ios_base();
protected:
ios_base() throw ();
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 50. Copy constructor and assignment operator of ios_base
private:
ios_base(const ios_base&);
ios_base&
operator=(const ios_base&);
};
// [27.4.5.1] fmtflags manipulators
/// Calls base.setf(ios_base::boolalpha).
inline ios_base&
boolalpha(ios_base& __base)
{
__base.setf(ios_base::boolalpha);
return __base;
}
/// Calls base.unsetf(ios_base::boolalpha).
inline ios_base&
noboolalpha(ios_base& __base)
{
__base.unsetf(ios_base::boolalpha);
return __base;
}
/// Calls base.setf(ios_base::showbase).
inline ios_base&
showbase(ios_base& __base)
{
__base.setf(ios_base::showbase);
return __base;
}
/// Calls base.unsetf(ios_base::showbase).
inline ios_base&
noshowbase(ios_base& __base)
{
__base.unsetf(ios_base::showbase);
return __base;
}
/// Calls base.setf(ios_base::showpoint).
inline ios_base&
showpoint(ios_base& __base)
{
__base.setf(ios_base::showpoint);
return __base;
}
/// Calls base.unsetf(ios_base::showpoint).
inline ios_base&
noshowpoint(ios_base& __base)
{
__base.unsetf(ios_base::showpoint);
return __base;
}
/// Calls base.setf(ios_base::showpos).
inline ios_base&
showpos(ios_base& __base)
{
__base.setf(ios_base::showpos);
return __base;
}
/// Calls base.unsetf(ios_base::showpos).
inline ios_base&
noshowpos(ios_base& __base)
{
__base.unsetf(ios_base::showpos);
return __base;
}
/// Calls base.setf(ios_base::skipws).
inline ios_base&
skipws(ios_base& __base)
{
__base.setf(ios_base::skipws);
return __base;
}
/// Calls base.unsetf(ios_base::skipws).
inline ios_base&
noskipws(ios_base& __base)
{
__base.unsetf(ios_base::skipws);
return __base;
}
/// Calls base.setf(ios_base::uppercase).
inline ios_base&
uppercase(ios_base& __base)
{
__base.setf(ios_base::uppercase);
return __base;
}
/// Calls base.unsetf(ios_base::uppercase).
inline ios_base&
nouppercase(ios_base& __base)
{
__base.unsetf(ios_base::uppercase);
return __base;
}
/// Calls base.setf(ios_base::unitbuf).
inline ios_base&
unitbuf(ios_base& __base)
{
__base.setf(ios_base::unitbuf);
return __base;
}
/// Calls base.unsetf(ios_base::unitbuf).
inline ios_base&
nounitbuf(ios_base& __base)
{
__base.unsetf(ios_base::unitbuf);
return __base;
}
// [27.4.5.2] adjustfield manipulators
/// Calls base.setf(ios_base::internal, ios_base::adjustfield).
inline ios_base&
internal(ios_base& __base)
{
__base.setf(ios_base::internal, ios_base::adjustfield);
return __base;
}
/// Calls base.setf(ios_base::left, ios_base::adjustfield).
inline ios_base&
left(ios_base& __base)
{
__base.setf(ios_base::left, ios_base::adjustfield);
return __base;
}
/// Calls base.setf(ios_base::right, ios_base::adjustfield).
inline ios_base&
right(ios_base& __base)
{
__base.setf(ios_base::right, ios_base::adjustfield);
return __base;
}
// [27.4.5.3] basefield manipulators
/// Calls base.setf(ios_base::dec, ios_base::basefield).
inline ios_base&
dec(ios_base& __base)
{
__base.setf(ios_base::dec, ios_base::basefield);
return __base;
}
/// Calls base.setf(ios_base::hex, ios_base::basefield).
inline ios_base&
hex(ios_base& __base)
{
__base.setf(ios_base::hex, ios_base::basefield);
return __base;
}
/// Calls base.setf(ios_base::oct, ios_base::basefield).
inline ios_base&
oct(ios_base& __base)
{
__base.setf(ios_base::oct, ios_base::basefield);
return __base;
}
// [27.4.5.4] floatfield manipulators
/// Calls base.setf(ios_base::fixed, ios_base::floatfield).
inline ios_base&
fixed(ios_base& __base)
{
__base.setf(ios_base::fixed, ios_base::floatfield);
return __base;
}
/// Calls base.setf(ios_base::scientific, ios_base::floatfield).
inline ios_base&
scientific(ios_base& __base)
{
__base.setf(ios_base::scientific, ios_base::floatfield);
return __base;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _IOS_BASE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,469 @@
// List implementation (out of line) -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/list.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{list}
*/
#ifndef _LIST_TCC
#define _LIST_TCC 1
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Tp, typename _Alloc>
void
_List_base<_Tp, _Alloc>::
_M_clear()
{
typedef _List_node<_Tp> _Node;
_Node* __cur = static_cast<_Node*>(_M_impl._M_node._M_next);
while (__cur != &_M_impl._M_node)
{
_Node* __tmp = __cur;
__cur = static_cast<_Node*>(__cur->_M_next);
#if __cplusplus >= 201103L
_M_get_Node_allocator().destroy(__tmp);
#else
_M_get_Tp_allocator().destroy(std::__addressof(__tmp->_M_data));
#endif
_M_put_node(__tmp);
}
}
#if __cplusplus >= 201103L
template<typename _Tp, typename _Alloc>
template<typename... _Args>
typename list<_Tp, _Alloc>::iterator
list<_Tp, _Alloc>::
emplace(iterator __position, _Args&&... __args)
{
_Node* __tmp = _M_create_node(std::forward<_Args>(__args)...);
__tmp->_M_hook(__position._M_node);
return iterator(__tmp);
}
#endif
template<typename _Tp, typename _Alloc>
typename list<_Tp, _Alloc>::iterator
list<_Tp, _Alloc>::
insert(iterator __position, const value_type& __x)
{
_Node* __tmp = _M_create_node(__x);
__tmp->_M_hook(__position._M_node);
return iterator(__tmp);
}
template<typename _Tp, typename _Alloc>
typename list<_Tp, _Alloc>::iterator
list<_Tp, _Alloc>::
erase(iterator __position)
{
iterator __ret = iterator(__position._M_node->_M_next);
_M_erase(__position);
return __ret;
}
#if __cplusplus >= 201103L
template<typename _Tp, typename _Alloc>
void
list<_Tp, _Alloc>::
_M_default_append(size_type __n)
{
size_type __i = 0;
__try
{
for (; __i < __n; ++__i)
emplace_back();
}
__catch(...)
{
for (; __i; --__i)
pop_back();
__throw_exception_again;
}
}
template<typename _Tp, typename _Alloc>
void
list<_Tp, _Alloc>::
resize(size_type __new_size)
{
iterator __i = begin();
size_type __len = 0;
for (; __i != end() && __len < __new_size; ++__i, ++__len)
;
if (__len == __new_size)
erase(__i, end());
else // __i == end()
_M_default_append(__new_size - __len);
}
template<typename _Tp, typename _Alloc>
void
list<_Tp, _Alloc>::
resize(size_type __new_size, const value_type& __x)
{
iterator __i = begin();
size_type __len = 0;
for (; __i != end() && __len < __new_size; ++__i, ++__len)
;
if (__len == __new_size)
erase(__i, end());
else // __i == end()
insert(end(), __new_size - __len, __x);
}
#else
template<typename _Tp, typename _Alloc>
void
list<_Tp, _Alloc>::
resize(size_type __new_size, value_type __x)
{
iterator __i = begin();
size_type __len = 0;
for (; __i != end() && __len < __new_size; ++__i, ++__len)
;
if (__len == __new_size)
erase(__i, end());
else // __i == end()
insert(end(), __new_size - __len, __x);
}
#endif
template<typename _Tp, typename _Alloc>
list<_Tp, _Alloc>&
list<_Tp, _Alloc>::
operator=(const list& __x)
{
if (this != &__x)
{
iterator __first1 = begin();
iterator __last1 = end();
const_iterator __first2 = __x.begin();
const_iterator __last2 = __x.end();
for (; __first1 != __last1 && __first2 != __last2;
++__first1, ++__first2)
*__first1 = *__first2;
if (__first2 == __last2)
erase(__first1, __last1);
else
insert(__last1, __first2, __last2);
}
return *this;
}
template<typename _Tp, typename _Alloc>
void
list<_Tp, _Alloc>::
_M_fill_assign(size_type __n, const value_type& __val)
{
iterator __i = begin();
for (; __i != end() && __n > 0; ++__i, --__n)
*__i = __val;
if (__n > 0)
insert(end(), __n, __val);
else
erase(__i, end());
}
template<typename _Tp, typename _Alloc>
template <typename _InputIterator>
void
list<_Tp, _Alloc>::
_M_assign_dispatch(_InputIterator __first2, _InputIterator __last2,
__false_type)
{
iterator __first1 = begin();
iterator __last1 = end();
for (; __first1 != __last1 && __first2 != __last2;
++__first1, ++__first2)
*__first1 = *__first2;
if (__first2 == __last2)
erase(__first1, __last1);
else
insert(__last1, __first2, __last2);
}
template<typename _Tp, typename _Alloc>
void
list<_Tp, _Alloc>::
remove(const value_type& __value)
{
iterator __first = begin();
iterator __last = end();
iterator __extra = __last;
while (__first != __last)
{
iterator __next = __first;
++__next;
if (*__first == __value)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 526. Is it undefined if a function in the standard changes
// in parameters?
if (std::__addressof(*__first) != std::__addressof(__value))
_M_erase(__first);
else
__extra = __first;
}
__first = __next;
}
if (__extra != __last)
_M_erase(__extra);
}
template<typename _Tp, typename _Alloc>
void
list<_Tp, _Alloc>::
unique()
{
iterator __first = begin();
iterator __last = end();
if (__first == __last)
return;
iterator __next = __first;
while (++__next != __last)
{
if (*__first == *__next)
_M_erase(__next);
else
__first = __next;
__next = __first;
}
}
template<typename _Tp, typename _Alloc>
void
list<_Tp, _Alloc>::
#if __cplusplus >= 201103L
merge(list&& __x)
#else
merge(list& __x)
#endif
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 300. list::merge() specification incomplete
if (this != &__x)
{
_M_check_equal_allocators(__x);
iterator __first1 = begin();
iterator __last1 = end();
iterator __first2 = __x.begin();
iterator __last2 = __x.end();
while (__first1 != __last1 && __first2 != __last2)
if (*__first2 < *__first1)
{
iterator __next = __first2;
_M_transfer(__first1, __first2, ++__next);
__first2 = __next;
}
else
++__first1;
if (__first2 != __last2)
_M_transfer(__last1, __first2, __last2);
}
}
template<typename _Tp, typename _Alloc>
template <typename _StrictWeakOrdering>
void
list<_Tp, _Alloc>::
#if __cplusplus >= 201103L
merge(list&& __x, _StrictWeakOrdering __comp)
#else
merge(list& __x, _StrictWeakOrdering __comp)
#endif
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 300. list::merge() specification incomplete
if (this != &__x)
{
_M_check_equal_allocators(__x);
iterator __first1 = begin();
iterator __last1 = end();
iterator __first2 = __x.begin();
iterator __last2 = __x.end();
while (__first1 != __last1 && __first2 != __last2)
if (__comp(*__first2, *__first1))
{
iterator __next = __first2;
_M_transfer(__first1, __first2, ++__next);
__first2 = __next;
}
else
++__first1;
if (__first2 != __last2)
_M_transfer(__last1, __first2, __last2);
}
}
template<typename _Tp, typename _Alloc>
void
list<_Tp, _Alloc>::
sort()
{
// Do nothing if the list has length 0 or 1.
if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
&& this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
{
list __carry;
list __tmp[64];
list * __fill = &__tmp[0];
list * __counter;
do
{
__carry.splice(__carry.begin(), *this, begin());
for(__counter = &__tmp[0];
__counter != __fill && !__counter->empty();
++__counter)
{
__counter->merge(__carry);
__carry.swap(*__counter);
}
__carry.swap(*__counter);
if (__counter == __fill)
++__fill;
}
while ( !empty() );
for (__counter = &__tmp[1]; __counter != __fill; ++__counter)
__counter->merge(*(__counter - 1));
swap( *(__fill - 1) );
}
}
template<typename _Tp, typename _Alloc>
template <typename _Predicate>
void
list<_Tp, _Alloc>::
remove_if(_Predicate __pred)
{
iterator __first = begin();
iterator __last = end();
while (__first != __last)
{
iterator __next = __first;
++__next;
if (__pred(*__first))
_M_erase(__first);
__first = __next;
}
}
template<typename _Tp, typename _Alloc>
template <typename _BinaryPredicate>
void
list<_Tp, _Alloc>::
unique(_BinaryPredicate __binary_pred)
{
iterator __first = begin();
iterator __last = end();
if (__first == __last)
return;
iterator __next = __first;
while (++__next != __last)
{
if (__binary_pred(*__first, *__next))
_M_erase(__next);
else
__first = __next;
__next = __first;
}
}
template<typename _Tp, typename _Alloc>
template <typename _StrictWeakOrdering>
void
list<_Tp, _Alloc>::
sort(_StrictWeakOrdering __comp)
{
// Do nothing if the list has length 0 or 1.
if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
&& this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
{
list __carry;
list __tmp[64];
list * __fill = &__tmp[0];
list * __counter;
do
{
__carry.splice(__carry.begin(), *this, begin());
for(__counter = &__tmp[0];
__counter != __fill && !__counter->empty();
++__counter)
{
__counter->merge(__carry, __comp);
__carry.swap(*__counter);
}
__carry.swap(*__counter);
if (__counter == __fill)
++__fill;
}
while ( !empty() );
for (__counter = &__tmp[1]; __counter != __fill; ++__counter)
__counter->merge(*(__counter - 1), __comp);
swap(*(__fill - 1));
}
}
_GLIBCXX_END_NAMESPACE_CONTAINER
} // namespace std
#endif /* _LIST_TCC */

View File

@@ -0,0 +1,789 @@
// Locale support -*- C++ -*-
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/locale_classes.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.1 Locales
//
#ifndef _LOCALE_CLASSES_H
#define _LOCALE_CLASSES_H 1
#pragma GCC system_header
#include <bits/localefwd.h>
#include <string>
#include <ext/atomicity.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// 22.1.1 Class locale
/**
* @brief Container class for localization functionality.
* @ingroup locales
*
* The locale class is first a class wrapper for C library locales. It is
* also an extensible container for user-defined localization. A locale is
* a collection of facets that implement various localization features such
* as money, time, and number printing.
*
* Constructing C++ locales does not change the C library locale.
*
* This library supports efficient construction and copying of locales
* through a reference counting implementation of the locale class.
*/
class locale
{
public:
// Types:
/// Definition of locale::category.
typedef int category;
// Forward decls and friends:
class facet;
class id;
class _Impl;
friend class facet;
friend class _Impl;
template<typename _Facet>
friend bool
has_facet(const locale&) throw();
template<typename _Facet>
friend const _Facet&
use_facet(const locale&);
template<typename _Cache>
friend struct __use_cache;
//@{
/**
* @brief Category values.
*
* The standard category values are none, ctype, numeric, collate, time,
* monetary, and messages. They form a bitmask that supports union and
* intersection. The category all is the union of these values.
*
* NB: Order must match _S_facet_categories definition in locale.cc
*/
static const category none = 0;
static const category ctype = 1L << 0;
static const category numeric = 1L << 1;
static const category collate = 1L << 2;
static const category time = 1L << 3;
static const category monetary = 1L << 4;
static const category messages = 1L << 5;
static const category all = (ctype | numeric | collate |
time | monetary | messages);
//@}
// Construct/copy/destroy:
/**
* @brief Default constructor.
*
* Constructs a copy of the global locale. If no locale has been
* explicitly set, this is the C locale.
*/
locale() throw();
/**
* @brief Copy constructor.
*
* Constructs a copy of @a other.
*
* @param __other The locale to copy.
*/
locale(const locale& __other) throw();
/**
* @brief Named locale constructor.
*
* Constructs a copy of the named C library locale.
*
* @param __s Name of the locale to construct.
* @throw std::runtime_error if __s is null or an undefined locale.
*/
explicit
locale(const char* __s);
/**
* @brief Construct locale with facets from another locale.
*
* Constructs a copy of the locale @a base. The facets specified by @a
* cat are replaced with those from the locale named by @a s. If base is
* named, this locale instance will also be named.
*
* @param __base The locale to copy.
* @param __s Name of the locale to use facets from.
* @param __cat Set of categories defining the facets to use from __s.
* @throw std::runtime_error if __s is null or an undefined locale.
*/
locale(const locale& __base, const char* __s, category __cat);
/**
* @brief Construct locale with facets from another locale.
*
* Constructs a copy of the locale @a base. The facets specified by @a
* cat are replaced with those from the locale @a add. If @a base and @a
* add are named, this locale instance will also be named.
*
* @param __base The locale to copy.
* @param __add The locale to use facets from.
* @param __cat Set of categories defining the facets to use from add.
*/
locale(const locale& __base, const locale& __add, category __cat);
/**
* @brief Construct locale with another facet.
*
* Constructs a copy of the locale @a __other. The facet @a __f
* is added to @a __other, replacing an existing facet of type
* Facet if there is one. If @a __f is null, this locale is a
* copy of @a __other.
*
* @param __other The locale to copy.
* @param __f The facet to add in.
*/
template<typename _Facet>
locale(const locale& __other, _Facet* __f);
/// Locale destructor.
~locale() throw();
/**
* @brief Assignment operator.
*
* Set this locale to be a copy of @a other.
*
* @param __other The locale to copy.
* @return A reference to this locale.
*/
const locale&
operator=(const locale& __other) throw();
/**
* @brief Construct locale with another facet.
*
* Constructs and returns a new copy of this locale. Adds or replaces an
* existing facet of type Facet from the locale @a other into the new
* locale.
*
* @tparam _Facet The facet type to copy from other
* @param __other The locale to copy from.
* @return Newly constructed locale.
* @throw std::runtime_error if __other has no facet of type _Facet.
*/
template<typename _Facet>
locale
combine(const locale& __other) const;
// Locale operations:
/**
* @brief Return locale name.
* @return Locale name or "*" if unnamed.
*/
string
name() const;
/**
* @brief Locale equality.
*
* @param __other The locale to compare against.
* @return True if other and this refer to the same locale instance, are
* copies, or have the same name. False otherwise.
*/
bool
operator==(const locale& __other) const throw();
/**
* @brief Locale inequality.
*
* @param __other The locale to compare against.
* @return ! (*this == __other)
*/
bool
operator!=(const locale& __other) const throw()
{ return !(this->operator==(__other)); }
/**
* @brief Compare two strings according to collate.
*
* Template operator to compare two strings using the compare function of
* the collate facet in this locale. One use is to provide the locale to
* the sort function. For example, a vector v of strings could be sorted
* according to locale loc by doing:
* @code
* std::sort(v.begin(), v.end(), loc);
* @endcode
*
* @param __s1 First string to compare.
* @param __s2 Second string to compare.
* @return True if collate<_Char> facet compares __s1 < __s2, else false.
*/
template<typename _Char, typename _Traits, typename _Alloc>
bool
operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
const basic_string<_Char, _Traits, _Alloc>& __s2) const;
// Global locale objects:
/**
* @brief Set global locale
*
* This function sets the global locale to the argument and returns a
* copy of the previous global locale. If the argument has a name, it
* will also call std::setlocale(LC_ALL, loc.name()).
*
* @param __loc The new locale to make global.
* @return Copy of the old global locale.
*/
static locale
global(const locale& __loc);
/**
* @brief Return reference to the C locale.
*/
static const locale&
classic();
private:
// The (shared) implementation
_Impl* _M_impl;
// The "C" reference locale
static _Impl* _S_classic;
// Current global locale
static _Impl* _S_global;
// Names of underlying locale categories.
// NB: locale::global() has to know how to modify all the
// underlying categories, not just the ones required by the C++
// standard.
static const char* const* const _S_categories;
// Number of standard categories. For C++, these categories are
// collate, ctype, monetary, numeric, time, and messages. These
// directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE,
// LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE
// 1003.1-2001) specifies LC_MESSAGES.
// In addition to the standard categories, the underlying
// operating system is allowed to define extra LC_*
// macros. For GNU systems, the following are also valid:
// LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT,
// and LC_IDENTIFICATION.
enum { _S_categories_size = 6 + _GLIBCXX_NUM_CATEGORIES };
#ifdef __GTHREADS
static __gthread_once_t _S_once;
#endif
explicit
locale(_Impl*) throw();
static void
_S_initialize();
static void
_S_initialize_once() throw();
static category
_S_normalize_category(category);
void
_M_coalesce(const locale& __base, const locale& __add, category __cat);
};
// 22.1.1.1.2 Class locale::facet
/**
* @brief Localization functionality base class.
* @ingroup locales
*
* The facet class is the base class for a localization feature, such as
* money, time, and number printing. It provides common support for facets
* and reference management.
*
* Facets may not be copied or assigned.
*/
class locale::facet
{
private:
friend class locale;
friend class locale::_Impl;
mutable _Atomic_word _M_refcount;
// Contains data from the underlying "C" library for the classic locale.
static __c_locale _S_c_locale;
// String literal for the name of the classic locale.
static const char _S_c_name[2];
#ifdef __GTHREADS
static __gthread_once_t _S_once;
#endif
static void
_S_initialize_once();
protected:
/**
* @brief Facet constructor.
*
* This is the constructor provided by the standard. If refs is 0, the
* facet is destroyed when the last referencing locale is destroyed.
* Otherwise the facet will never be destroyed.
*
* @param __refs The initial value for reference count.
*/
explicit
facet(size_t __refs = 0) throw() : _M_refcount(__refs ? 1 : 0)
{ }
/// Facet destructor.
virtual
~facet();
static void
_S_create_c_locale(__c_locale& __cloc, const char* __s,
__c_locale __old = 0);
static __c_locale
_S_clone_c_locale(__c_locale& __cloc) throw();
static void
_S_destroy_c_locale(__c_locale& __cloc);
static __c_locale
_S_lc_ctype_c_locale(__c_locale __cloc, const char* __s);
// Returns data from the underlying "C" library data for the
// classic locale.
static __c_locale
_S_get_c_locale();
_GLIBCXX_CONST static const char*
_S_get_c_name() throw();
private:
void
_M_add_reference() const throw()
{ __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); }
void
_M_remove_reference() const throw()
{
// Be race-detector-friendly. For more info see bits/c++config.
_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount);
if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1)
{
_GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount);
__try
{ delete this; }
__catch(...)
{ }
}
}
facet(const facet&); // Not defined.
facet&
operator=(const facet&); // Not defined.
};
// 22.1.1.1.3 Class locale::id
/**
* @brief Facet ID class.
* @ingroup locales
*
* The ID class provides facets with an index used to identify them.
* Every facet class must define a public static member locale::id, or be
* derived from a facet that provides this member, otherwise the facet
* cannot be used in a locale. The locale::id ensures that each class
* type gets a unique identifier.
*/
class locale::id
{
private:
friend class locale;
friend class locale::_Impl;
template<typename _Facet>
friend const _Facet&
use_facet(const locale&);
template<typename _Facet>
friend bool
has_facet(const locale&) throw();
// NB: There is no accessor for _M_index because it may be used
// before the constructor is run; the effect of calling a member
// function (even an inline) would be undefined.
mutable size_t _M_index;
// Last id number assigned.
static _Atomic_word _S_refcount;
void
operator=(const id&); // Not defined.
id(const id&); // Not defined.
public:
// NB: This class is always a static data member, and thus can be
// counted on to be zero-initialized.
/// Constructor.
id() { }
size_t
_M_id() const throw();
};
// Implementation object for locale.
class locale::_Impl
{
public:
// Friends.
friend class locale;
friend class locale::facet;
template<typename _Facet>
friend bool
has_facet(const locale&) throw();
template<typename _Facet>
friend const _Facet&
use_facet(const locale&);
template<typename _Cache>
friend struct __use_cache;
private:
// Data Members.
_Atomic_word _M_refcount;
const facet** _M_facets;
size_t _M_facets_size;
const facet** _M_caches;
char** _M_names;
static const locale::id* const _S_id_ctype[];
static const locale::id* const _S_id_numeric[];
static const locale::id* const _S_id_collate[];
static const locale::id* const _S_id_time[];
static const locale::id* const _S_id_monetary[];
static const locale::id* const _S_id_messages[];
static const locale::id* const* const _S_facet_categories[];
void
_M_add_reference() throw()
{ __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); }
void
_M_remove_reference() throw()
{
// Be race-detector-friendly. For more info see bits/c++config.
_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount);
if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1)
{
_GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount);
__try
{ delete this; }
__catch(...)
{ }
}
}
_Impl(const _Impl&, size_t);
_Impl(const char*, size_t);
_Impl(size_t) throw();
~_Impl() throw();
_Impl(const _Impl&); // Not defined.
void
operator=(const _Impl&); // Not defined.
bool
_M_check_same_name()
{
bool __ret = true;
if (_M_names[1])
// We must actually compare all the _M_names: can be all equal!
for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i)
__ret = __builtin_strcmp(_M_names[__i], _M_names[__i + 1]) == 0;
return __ret;
}
void
_M_replace_categories(const _Impl*, category);
void
_M_replace_category(const _Impl*, const locale::id* const*);
void
_M_replace_facet(const _Impl*, const locale::id*);
void
_M_install_facet(const locale::id*, const facet*);
template<typename _Facet>
void
_M_init_facet(_Facet* __facet)
{ _M_install_facet(&_Facet::id, __facet); }
void
_M_install_cache(const facet*, size_t);
};
/**
* @brief Facet for localized string comparison.
*
* This facet encapsulates the code to compare strings in a localized
* manner.
*
* The collate template uses protected virtual functions to provide
* the actual results. The public accessors forward the call to
* the virtual functions. These virtual functions are hooks for
* developers to implement the behavior they require from the
* collate facet.
*/
template<typename _CharT>
class collate : public locale::facet
{
public:
// Types:
//@{
/// Public typedefs
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
//@}
protected:
// Underlying "C" library locale information saved from
// initialization, needed by collate_byname as well.
__c_locale _M_c_locale_collate;
public:
/// Numpunct facet id.
static locale::id id;
/**
* @brief Constructor performs initialization.
*
* This is the constructor provided by the standard.
*
* @param __refs Passed to the base facet class.
*/
explicit
collate(size_t __refs = 0)
: facet(__refs), _M_c_locale_collate(_S_get_c_locale())
{ }
/**
* @brief Internal constructor. Not for general use.
*
* This is a constructor for use by the library itself to set up new
* locales.
*
* @param __cloc The C locale.
* @param __refs Passed to the base facet class.
*/
explicit
collate(__c_locale __cloc, size_t __refs = 0)
: facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc))
{ }
/**
* @brief Compare two strings.
*
* This function compares two strings and returns the result by calling
* collate::do_compare().
*
* @param __lo1 Start of string 1.
* @param __hi1 End of string 1.
* @param __lo2 Start of string 2.
* @param __hi2 End of string 2.
* @return 1 if string1 > string2, -1 if string1 < string2, else 0.
*/
int
compare(const _CharT* __lo1, const _CharT* __hi1,
const _CharT* __lo2, const _CharT* __hi2) const
{ return this->do_compare(__lo1, __hi1, __lo2, __hi2); }
/**
* @brief Transform string to comparable form.
*
* This function is a wrapper for strxfrm functionality. It takes the
* input string and returns a modified string that can be directly
* compared to other transformed strings. In the C locale, this
* function just returns a copy of the input string. In some other
* locales, it may replace two chars with one, change a char for
* another, etc. It does so by returning collate::do_transform().
*
* @param __lo Start of string.
* @param __hi End of string.
* @return Transformed string_type.
*/
string_type
transform(const _CharT* __lo, const _CharT* __hi) const
{ return this->do_transform(__lo, __hi); }
/**
* @brief Return hash of a string.
*
* This function computes and returns a hash on the input string. It
* does so by returning collate::do_hash().
*
* @param __lo Start of string.
* @param __hi End of string.
* @return Hash value.
*/
long
hash(const _CharT* __lo, const _CharT* __hi) const
{ return this->do_hash(__lo, __hi); }
// Used to abstract out _CharT bits in virtual member functions, below.
int
_M_compare(const _CharT*, const _CharT*) const throw();
size_t
_M_transform(_CharT*, const _CharT*, size_t) const throw();
protected:
/// Destructor.
virtual
~collate()
{ _S_destroy_c_locale(_M_c_locale_collate); }
/**
* @brief Compare two strings.
*
* This function is a hook for derived classes to change the value
* returned. @see compare().
*
* @param __lo1 Start of string 1.
* @param __hi1 End of string 1.
* @param __lo2 Start of string 2.
* @param __hi2 End of string 2.
* @return 1 if string1 > string2, -1 if string1 < string2, else 0.
*/
virtual int
do_compare(const _CharT* __lo1, const _CharT* __hi1,
const _CharT* __lo2, const _CharT* __hi2) const;
/**
* @brief Transform string to comparable form.
*
* This function is a hook for derived classes to change the value
* returned.
*
* @param __lo Start.
* @param __hi End.
* @return transformed string.
*/
virtual string_type
do_transform(const _CharT* __lo, const _CharT* __hi) const;
/**
* @brief Return hash of a string.
*
* This function computes and returns a hash on the input string. This
* function is a hook for derived classes to change the value returned.
*
* @param __lo Start of string.
* @param __hi End of string.
* @return Hash value.
*/
virtual long
do_hash(const _CharT* __lo, const _CharT* __hi) const;
};
template<typename _CharT>
locale::id collate<_CharT>::id;
// Specializations.
template<>
int
collate<char>::_M_compare(const char*, const char*) const throw();
template<>
size_t
collate<char>::_M_transform(char*, const char*, size_t) const throw();
#ifdef _GLIBCXX_USE_WCHAR_T
template<>
int
collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const throw();
template<>
size_t
collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const throw();
#endif
/// class collate_byname [22.2.4.2].
template<typename _CharT>
class collate_byname : public collate<_CharT>
{
public:
//@{
/// Public typedefs
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
//@}
explicit
collate_byname(const char* __s, size_t __refs = 0)
: collate<_CharT>(__refs)
{
if (__builtin_strcmp(__s, "C") != 0
&& __builtin_strcmp(__s, "POSIX") != 0)
{
this->_S_destroy_c_locale(this->_M_c_locale_collate);
this->_S_create_c_locale(this->_M_c_locale_collate, __s);
}
}
protected:
virtual
~collate_byname() { }
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
# include <bits/locale_classes.tcc>
#endif

View File

@@ -0,0 +1,298 @@
// Locale support -*- C++ -*-
// Copyright (C) 2007-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/locale_classes.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.1 Locales
//
#ifndef _LOCALE_CLASSES_TCC
#define _LOCALE_CLASSES_TCC 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Facet>
locale::
locale(const locale& __other, _Facet* __f)
{
_M_impl = new _Impl(*__other._M_impl, 1);
__try
{ _M_impl->_M_install_facet(&_Facet::id, __f); }
__catch(...)
{
_M_impl->_M_remove_reference();
__throw_exception_again;
}
delete [] _M_impl->_M_names[0];
_M_impl->_M_names[0] = 0; // Unnamed.
}
template<typename _Facet>
locale
locale::
combine(const locale& __other) const
{
_Impl* __tmp = new _Impl(*_M_impl, 1);
__try
{
__tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
}
__catch(...)
{
__tmp->_M_remove_reference();
__throw_exception_again;
}
return locale(__tmp);
}
template<typename _CharT, typename _Traits, typename _Alloc>
bool
locale::
operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
const basic_string<_CharT, _Traits, _Alloc>& __s2) const
{
typedef std::collate<_CharT> __collate_type;
const __collate_type& __collate = use_facet<__collate_type>(*this);
return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
__s2.data(), __s2.data() + __s2.length()) < 0);
}
/**
* @brief Test for the presence of a facet.
* @ingroup locales
*
* has_facet tests the locale argument for the presence of the facet type
* provided as the template parameter. Facets derived from the facet
* parameter will also return true.
*
* @tparam _Facet The facet type to test the presence of.
* @param __loc The locale to test.
* @return true if @p __loc contains a facet of type _Facet, else false.
*/
template<typename _Facet>
bool
has_facet(const locale& __loc) throw()
{
const size_t __i = _Facet::id._M_id();
const locale::facet** __facets = __loc._M_impl->_M_facets;
return (__i < __loc._M_impl->_M_facets_size
#ifdef __GXX_RTTI
&& dynamic_cast<const _Facet*>(__facets[__i]));
#else
&& static_cast<const _Facet*>(__facets[__i]));
#endif
}
/**
* @brief Return a facet.
* @ingroup locales
*
* use_facet looks for and returns a reference to a facet of type Facet
* where Facet is the template parameter. If has_facet(locale) is true,
* there is a suitable facet to return. It throws std::bad_cast if the
* locale doesn't contain a facet of type Facet.
*
* @tparam _Facet The facet type to access.
* @param __loc The locale to use.
* @return Reference to facet of type Facet.
* @throw std::bad_cast if @p __loc doesn't contain a facet of type _Facet.
*/
template<typename _Facet>
const _Facet&
use_facet(const locale& __loc)
{
const size_t __i = _Facet::id._M_id();
const locale::facet** __facets = __loc._M_impl->_M_facets;
if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i])
__throw_bad_cast();
#ifdef __GXX_RTTI
return dynamic_cast<const _Facet&>(*__facets[__i]);
#else
return static_cast<const _Facet&>(*__facets[__i]);
#endif
}
// Generic version does nothing.
template<typename _CharT>
int
collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const throw ()
{ return 0; }
// Generic version does nothing.
template<typename _CharT>
size_t
collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const throw ()
{ return 0; }
template<typename _CharT>
int
collate<_CharT>::
do_compare(const _CharT* __lo1, const _CharT* __hi1,
const _CharT* __lo2, const _CharT* __hi2) const
{
// strcoll assumes zero-terminated strings so we make a copy
// and then put a zero at the end.
const string_type __one(__lo1, __hi1);
const string_type __two(__lo2, __hi2);
const _CharT* __p = __one.c_str();
const _CharT* __pend = __one.data() + __one.length();
const _CharT* __q = __two.c_str();
const _CharT* __qend = __two.data() + __two.length();
// strcoll stops when it sees a nul character so we break
// the strings into zero-terminated substrings and pass those
// to strcoll.
for (;;)
{
const int __res = _M_compare(__p, __q);
if (__res)
return __res;
__p += char_traits<_CharT>::length(__p);
__q += char_traits<_CharT>::length(__q);
if (__p == __pend && __q == __qend)
return 0;
else if (__p == __pend)
return -1;
else if (__q == __qend)
return 1;
__p++;
__q++;
}
}
template<typename _CharT>
typename collate<_CharT>::string_type
collate<_CharT>::
do_transform(const _CharT* __lo, const _CharT* __hi) const
{
string_type __ret;
// strxfrm assumes zero-terminated strings so we make a copy
const string_type __str(__lo, __hi);
const _CharT* __p = __str.c_str();
const _CharT* __pend = __str.data() + __str.length();
size_t __len = (__hi - __lo) * 2;
_CharT* __c = new _CharT[__len];
__try
{
// strxfrm stops when it sees a nul character so we break
// the string into zero-terminated substrings and pass those
// to strxfrm.
for (;;)
{
// First try a buffer perhaps big enough.
size_t __res = _M_transform(__c, __p, __len);
// If the buffer was not large enough, try again with the
// correct size.
if (__res >= __len)
{
__len = __res + 1;
delete [] __c, __c = 0;
__c = new _CharT[__len];
__res = _M_transform(__c, __p, __len);
}
__ret.append(__c, __res);
__p += char_traits<_CharT>::length(__p);
if (__p == __pend)
break;
__p++;
__ret.push_back(_CharT());
}
}
__catch(...)
{
delete [] __c;
__throw_exception_again;
}
delete [] __c;
return __ret;
}
template<typename _CharT>
long
collate<_CharT>::
do_hash(const _CharT* __lo, const _CharT* __hi) const
{
unsigned long __val = 0;
for (; __lo < __hi; ++__lo)
__val =
*__lo + ((__val << 7)
| (__val >> (__gnu_cxx::__numeric_traits<unsigned long>::
__digits - 7)));
return static_cast<long>(__val);
}
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class collate<char>;
extern template class collate_byname<char>;
extern template
const collate<char>&
use_facet<collate<char> >(const locale&);
extern template
bool
has_facet<collate<char> >(const locale&);
#ifdef _GLIBCXX_USE_WCHAR_T
extern template class collate<wchar_t>;
extern template class collate_byname<wchar_t>;
extern template
const collate<wchar_t>&
use_facet<collate<wchar_t> >(const locale&);
extern template
bool
has_facet<collate<wchar_t> >(const locale&);
#endif
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,190 @@
// <locale> Forward declarations -*- C++ -*-
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/localefwd.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.1 Locales
//
#ifndef _LOCALE_FWD_H
#define _LOCALE_FWD_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/c++locale.h> // Defines __c_locale, config-specific include
#include <iosfwd> // For ostreambuf_iterator, istreambuf_iterator
#include <cctype>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup locales Locales
*
* Classes and functions for internationalization and localization.
*/
// 22.1.1 Locale
class locale;
template<typename _Facet>
bool
has_facet(const locale&) throw();
template<typename _Facet>
const _Facet&
use_facet(const locale&);
// 22.1.3 Convenience interfaces
template<typename _CharT>
bool
isspace(_CharT, const locale&);
template<typename _CharT>
bool
isprint(_CharT, const locale&);
template<typename _CharT>
bool
iscntrl(_CharT, const locale&);
template<typename _CharT>
bool
isupper(_CharT, const locale&);
template<typename _CharT>
bool
islower(_CharT, const locale&);
template<typename _CharT>
bool
isalpha(_CharT, const locale&);
template<typename _CharT>
bool
isdigit(_CharT, const locale&);
template<typename _CharT>
bool
ispunct(_CharT, const locale&);
template<typename _CharT>
bool
isxdigit(_CharT, const locale&);
template<typename _CharT>
bool
isalnum(_CharT, const locale&);
template<typename _CharT>
bool
isgraph(_CharT, const locale&);
template<typename _CharT>
_CharT
toupper(_CharT, const locale&);
template<typename _CharT>
_CharT
tolower(_CharT, const locale&);
// 22.2.1 and 22.2.1.3 ctype
class ctype_base;
template<typename _CharT>
class ctype;
template<> class ctype<char>;
#ifdef _GLIBCXX_USE_WCHAR_T
template<> class ctype<wchar_t>;
#endif
template<typename _CharT>
class ctype_byname;
// NB: Specialized for char and wchar_t in locale_facets.h.
class codecvt_base;
template<typename _InternT, typename _ExternT, typename _StateT>
class codecvt;
template<> class codecvt<char, char, mbstate_t>;
#ifdef _GLIBCXX_USE_WCHAR_T
template<> class codecvt<wchar_t, char, mbstate_t>;
#endif
template<typename _InternT, typename _ExternT, typename _StateT>
class codecvt_byname;
// 22.2.2 and 22.2.3 numeric
_GLIBCXX_BEGIN_NAMESPACE_LDBL
template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> >
class num_get;
template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
class num_put;
_GLIBCXX_END_NAMESPACE_LDBL
template<typename _CharT> class numpunct;
template<typename _CharT> class numpunct_byname;
// 22.2.4 collation
template<typename _CharT>
class collate;
template<typename _CharT> class
collate_byname;
// 22.2.5 date and time
class time_base;
template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> >
class time_get;
template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> >
class time_get_byname;
template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
class time_put;
template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
class time_put_byname;
// 22.2.6 money
class money_base;
_GLIBCXX_BEGIN_NAMESPACE_LDBL
template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> >
class money_get;
template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
class money_put;
_GLIBCXX_END_NAMESPACE_LDBL
template<typename _CharT, bool _Intl = false>
class moneypunct;
template<typename _CharT, bool _Intl = false>
class moneypunct_byname;
// 22.2.7 message retrieval
class messages_base;
template<typename _CharT>
class messages;
template<typename _CharT>
class messages_byname;
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

View File

@@ -0,0 +1,208 @@
// The template and inlines for the -*- C++ -*- mask_array class.
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/mask_array.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{valarray}
*/
// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
#ifndef _MASK_ARRAY_H
#define _MASK_ARRAY_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup numeric_arrays
* @{
*/
/**
* @brief Reference to selected subset of an array.
*
* A mask_array is a reference to the actual elements of an array specified
* by a bitmask in the form of an array of bool. The way to get a
* mask_array is to call operator[](valarray<bool>) on a valarray. The
* returned mask_array then permits carrying operations out on the
* referenced subset of elements in the original valarray.
*
* For example, if a mask_array is obtained using the array (false, true,
* false, true) as an argument, the mask array has two elements referring
* to array[1] and array[3] in the underlying array.
*
* @param Tp Element type.
*/
template <class _Tp>
class mask_array
{
public:
typedef _Tp value_type;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 253. valarray helper functions are almost entirely useless
/// Copy constructor. Both slices refer to the same underlying array.
mask_array (const mask_array&);
/// Assignment operator. Assigns elements to corresponding elements
/// of @a a.
mask_array& operator=(const mask_array&);
void operator=(const valarray<_Tp>&) const;
/// Multiply slice elements by corresponding elements of @a v.
void operator*=(const valarray<_Tp>&) const;
/// Divide slice elements by corresponding elements of @a v.
void operator/=(const valarray<_Tp>&) const;
/// Modulo slice elements by corresponding elements of @a v.
void operator%=(const valarray<_Tp>&) const;
/// Add corresponding elements of @a v to slice elements.
void operator+=(const valarray<_Tp>&) const;
/// Subtract corresponding elements of @a v from slice elements.
void operator-=(const valarray<_Tp>&) const;
/// Logical xor slice elements with corresponding elements of @a v.
void operator^=(const valarray<_Tp>&) const;
/// Logical and slice elements with corresponding elements of @a v.
void operator&=(const valarray<_Tp>&) const;
/// Logical or slice elements with corresponding elements of @a v.
void operator|=(const valarray<_Tp>&) const;
/// Left shift slice elements by corresponding elements of @a v.
void operator<<=(const valarray<_Tp>&) const;
/// Right shift slice elements by corresponding elements of @a v.
void operator>>=(const valarray<_Tp>&) const;
/// Assign all slice elements to @a t.
void operator=(const _Tp&) const;
// ~mask_array ();
template<class _Dom>
void operator=(const _Expr<_Dom,_Tp>&) const;
template<class _Dom>
void operator*=(const _Expr<_Dom,_Tp>&) const;
template<class _Dom>
void operator/=(const _Expr<_Dom,_Tp>&) const;
template<class _Dom>
void operator%=(const _Expr<_Dom,_Tp>&) const;
template<class _Dom>
void operator+=(const _Expr<_Dom,_Tp>&) const;
template<class _Dom>
void operator-=(const _Expr<_Dom,_Tp>&) const;
template<class _Dom>
void operator^=(const _Expr<_Dom,_Tp>&) const;
template<class _Dom>
void operator&=(const _Expr<_Dom,_Tp>&) const;
template<class _Dom>
void operator|=(const _Expr<_Dom,_Tp>&) const;
template<class _Dom>
void operator<<=(const _Expr<_Dom,_Tp>&) const;
template<class _Dom>
void operator>>=(const _Expr<_Dom,_Tp>&) const;
private:
mask_array(_Array<_Tp>, size_t, _Array<bool>);
friend class valarray<_Tp>;
const size_t _M_sz;
const _Array<bool> _M_mask;
const _Array<_Tp> _M_array;
// not implemented
mask_array();
};
template<typename _Tp>
inline mask_array<_Tp>::mask_array(const mask_array<_Tp>& a)
: _M_sz(a._M_sz), _M_mask(a._M_mask), _M_array(a._M_array) {}
template<typename _Tp>
inline
mask_array<_Tp>::mask_array(_Array<_Tp> __a, size_t __s, _Array<bool> __m)
: _M_sz(__s), _M_mask(__m), _M_array(__a) {}
template<typename _Tp>
inline mask_array<_Tp>&
mask_array<_Tp>::operator=(const mask_array<_Tp>& __a)
{
std::__valarray_copy(__a._M_array, __a._M_mask,
_M_sz, _M_array, _M_mask);
return *this;
}
template<typename _Tp>
inline void
mask_array<_Tp>::operator=(const _Tp& __t) const
{ std::__valarray_fill(_M_array, _M_sz, _M_mask, __t); }
template<typename _Tp>
inline void
mask_array<_Tp>::operator=(const valarray<_Tp>& __v) const
{ std::__valarray_copy(_Array<_Tp>(__v), __v.size(), _M_array, _M_mask); }
template<typename _Tp>
template<class _Ex>
inline void
mask_array<_Tp>::operator=(const _Expr<_Ex, _Tp>& __e) const
{ std::__valarray_copy(__e, __e.size(), _M_array, _M_mask); }
#undef _DEFINE_VALARRAY_OPERATOR
#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \
template<typename _Tp> \
inline void \
mask_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \
{ \
_Array_augmented_##_Name(_M_array, _M_mask, \
_Array<_Tp>(__v), __v.size()); \
} \
\
template<typename _Tp> \
template<class _Dom> \
inline void \
mask_array<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) const\
{ \
_Array_augmented_##_Name(_M_array, _M_mask, __e, __e.size()); \
}
_DEFINE_VALARRAY_OPERATOR(*, __multiplies)
_DEFINE_VALARRAY_OPERATOR(/, __divides)
_DEFINE_VALARRAY_OPERATOR(%, __modulus)
_DEFINE_VALARRAY_OPERATOR(+, __plus)
_DEFINE_VALARRAY_OPERATOR(-, __minus)
_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor)
_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and)
_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or)
_DEFINE_VALARRAY_OPERATOR(<<, __shift_left)
_DEFINE_VALARRAY_OPERATOR(>>, __shift_right)
#undef _DEFINE_VALARRAY_OPERATOR
// @} group numeric_arrays
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _MASK_ARRAY_H */

View File

@@ -0,0 +1,78 @@
// <memory> Forward declarations -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
* Copyright (c) 1996-1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/memoryfwd.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _MEMORYFWD_H
#define _MEMORYFWD_H 1
#pragma GCC system_header
#include <bits/c++config.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup allocators Allocators
* @ingroup memory
*
* Classes encapsulating memory operations.
*
* @{
*/
template<typename>
class allocator;
template<>
class allocator<void>;
/// Declare uses_allocator so it can be specialized in \<queue\> etc.
template<typename, typename>
struct uses_allocator;
/// @} group memory
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

View File

@@ -0,0 +1,198 @@
// Move, forward and identity for C++0x + swap -*- C++ -*-
// Copyright (C) 2007-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/move.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{utility}
*/
#ifndef _MOVE_H
#define _MOVE_H 1
#include <bits/c++config.h>
#include <bits/concept_check.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Used, in C++03 mode too, by allocators, etc.
/**
* @brief Same as C++11 std::addressof
* @ingroup utilities
*/
template<typename _Tp>
inline _Tp*
__addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
{
return reinterpret_cast<_Tp*>
(&const_cast<char&>(reinterpret_cast<const volatile char&>(__r)));
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#if __cplusplus >= 201103L
#include <type_traits> // Brings in std::declval too.
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup utilities
* @{
*/
/**
* @brief Forward an lvalue.
* @return The parameter cast to the specified type.
*
* This function is used to implement "perfect forwarding".
*/
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }
/**
* @brief Forward an rvalue.
* @return The parameter cast to the specified type.
*
* This function is used to implement "perfect forwarding".
*/
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
{
static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
" substituting _Tp is an lvalue reference type");
return static_cast<_Tp&&>(__t);
}
/**
* @brief Convert a value to an rvalue.
* @param __t A thing of arbitrary type.
* @return The parameter cast to an rvalue-reference to allow moving it.
*/
template<typename _Tp>
constexpr typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
template<typename _Tp>
struct __move_if_noexcept_cond
: public __and_<__not_<is_nothrow_move_constructible<_Tp>>,
is_copy_constructible<_Tp>>::type { };
/**
* @brief Conditionally convert a value to an rvalue.
* @param __x A thing of arbitrary type.
* @return The parameter, possibly cast to an rvalue-reference.
*
* Same as std::move unless the type's move constructor could throw and the
* type is copyable, in which case an lvalue-reference is returned instead.
*/
template<typename _Tp>
inline constexpr typename
conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type
move_if_noexcept(_Tp& __x) noexcept
{ return std::move(__x); }
// declval, from type_traits.
/**
* @brief Returns the actual address of the object or function
* referenced by r, even in the presence of an overloaded
* operator&.
* @param __r Reference to an object or function.
* @return The actual address.
*/
template<typename _Tp>
inline _Tp*
addressof(_Tp& __r) noexcept
{ return std::__addressof(__r); }
/// @} group utilities
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#define _GLIBCXX_MOVE(__val) std::move(__val)
#define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val)
#else
#define _GLIBCXX_MOVE(__val) (__val)
#define _GLIBCXX_FORWARD(_Tp, __val) (__val)
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup utilities
* @{
*/
/**
* @brief Swaps two values.
* @param __a A thing of arbitrary type.
* @param __b Another thing of arbitrary type.
* @return Nothing.
*/
template<typename _Tp>
inline void
swap(_Tp& __a, _Tp& __b)
#if __cplusplus >= 201103L
noexcept(__and_<is_nothrow_move_constructible<_Tp>,
is_nothrow_move_assignable<_Tp>>::value)
#endif
{
// concept requirements
__glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
_Tp __tmp = _GLIBCXX_MOVE(__a);
__a = _GLIBCXX_MOVE(__b);
__b = _GLIBCXX_MOVE(__tmp);
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 809. std::swap should be overloaded for array types.
/// Swap the contents of two arrays.
template<typename _Tp, size_t _Nm>
inline void
swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
#if __cplusplus >= 201103L
noexcept(noexcept(swap(*__a, *__b)))
#endif
{
for (size_t __n = 0; __n < _Nm; ++__n)
swap(__a[__n], __b[__n]);
}
/// @} group utilities
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _MOVE_H */

View File

@@ -0,0 +1,166 @@
// Nested Exception support header (nested_exception class) for -*- C++ -*-
// Copyright (C) 2009-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/nested_exception.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{exception}
*/
#ifndef _GLIBCXX_NESTED_EXCEPTION_H
#define _GLIBCXX_NESTED_EXCEPTION_H 1
#pragma GCC visibility push(default)
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
#include <bits/c++config.h>
#if ATOMIC_INT_LOCK_FREE < 2
# error This platform does not support exception propagation.
#endif
extern "C++" {
namespace std
{
/**
* @addtogroup exceptions
* @{
*/
/// Exception class with exception_ptr data member.
class nested_exception
{
exception_ptr _M_ptr;
public:
nested_exception() noexcept : _M_ptr(current_exception()) { }
nested_exception(const nested_exception&) = default;
nested_exception& operator=(const nested_exception&) = default;
virtual ~nested_exception() noexcept;
void
rethrow_nested() const __attribute__ ((__noreturn__))
{ rethrow_exception(_M_ptr); }
exception_ptr
nested_ptr() const
{ return _M_ptr; }
};
template<typename _Except>
struct _Nested_exception : public _Except, public nested_exception
{
explicit _Nested_exception(_Except&& __ex)
: _Except(static_cast<_Except&&>(__ex))
{ }
};
template<typename _Ex>
struct __get_nested_helper
{
static const nested_exception*
_S_get(const _Ex& __ex)
{ return dynamic_cast<const nested_exception*>(&__ex); }
};
template<typename _Ex>
struct __get_nested_helper<_Ex*>
{
static const nested_exception*
_S_get(const _Ex* __ex)
{ return dynamic_cast<const nested_exception*>(__ex); }
};
template<typename _Ex>
inline const nested_exception*
__get_nested_exception(const _Ex& __ex)
{ return __get_nested_helper<_Ex>::_S_get(__ex); }
template<typename _Ex>
void
__throw_with_nested(_Ex&&, const nested_exception* = 0)
__attribute__ ((__noreturn__));
template<typename _Ex>
void
__throw_with_nested(_Ex&&, ...) __attribute__ ((__noreturn__));
// This function should never be called, but is needed to avoid a warning
// about ambiguous base classes when instantiating throw_with_nested<_Ex>()
// with a type that has an accessible nested_exception base.
template<typename _Ex>
inline void
__throw_with_nested(_Ex&& __ex, const nested_exception*)
{ throw __ex; }
template<typename _Ex>
inline void
__throw_with_nested(_Ex&& __ex, ...)
{ throw _Nested_exception<_Ex>(static_cast<_Ex&&>(__ex)); }
template<typename _Ex>
void
throw_with_nested(_Ex __ex) __attribute__ ((__noreturn__));
/// If @p __ex is derived from nested_exception, @p __ex.
/// Else, an implementation-defined object derived from both.
template<typename _Ex>
inline void
throw_with_nested(_Ex __ex)
{
if (__get_nested_exception(__ex))
throw __ex;
__throw_with_nested(static_cast<_Ex&&>(__ex), &__ex);
}
/// If @p __ex is derived from nested_exception, @p __ex.rethrow_nested().
template<typename _Ex>
inline void
rethrow_if_nested(const _Ex& __ex)
{
if (const nested_exception* __nested = __get_nested_exception(__ex))
__nested->rethrow_nested();
}
/// Overload, See N2619
inline void
rethrow_if_nested(const nested_exception& __ex)
{ __ex.rethrow_nested(); }
// @} group exceptions
} // namespace std
} // extern "C++"
#endif // C++11
#pragma GCC visibility pop
#endif // _GLIBCXX_NESTED_EXCEPTION_H

View File

@@ -0,0 +1,407 @@
// ostream classes -*- C++ -*-
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ostream.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ostream}
*/
//
// ISO C++ 14882: 27.6.2 Output streams
//
#ifndef _OSTREAM_TCC
#define _OSTREAM_TCC 1
#pragma GCC system_header
#include <bits/cxxabi_forced.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>::sentry::
sentry(basic_ostream<_CharT, _Traits>& __os)
: _M_ok(false), _M_os(__os)
{
// XXX MT
if (__os.tie() && __os.good())
__os.tie()->flush();
if (__os.good())
_M_ok = true;
else
__os.setstate(ios_base::failbit);
}
template<typename _CharT, typename _Traits>
template<typename _ValueT>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
_M_insert(_ValueT __v)
{
sentry __cerb(*this);
if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
{
const __num_put_type& __np = __check_facet(this->_M_num_put);
if (__np.put(*this, *this, this->fill(), __v).failed())
__err |= ios_base::badbit;
}
__catch(__cxxabiv1::__forced_unwind&)
{
this->_M_setstate(ios_base::badbit);
__throw_exception_again;
}
__catch(...)
{ this->_M_setstate(ios_base::badbit); }
if (__err)
this->setstate(__err);
}
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
operator<<(short __n)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 117. basic_ostream uses nonexistent num_put member functions.
const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
if (__fmt == ios_base::oct || __fmt == ios_base::hex)
return _M_insert(static_cast<long>(static_cast<unsigned short>(__n)));
else
return _M_insert(static_cast<long>(__n));
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
operator<<(int __n)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 117. basic_ostream uses nonexistent num_put member functions.
const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
if (__fmt == ios_base::oct || __fmt == ios_base::hex)
return _M_insert(static_cast<long>(static_cast<unsigned int>(__n)));
else
return _M_insert(static_cast<long>(__n));
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
operator<<(__streambuf_type* __sbin)
{
ios_base::iostate __err = ios_base::goodbit;
sentry __cerb(*this);
if (__cerb && __sbin)
{
__try
{
if (!__copy_streambufs(__sbin, this->rdbuf()))
__err |= ios_base::failbit;
}
__catch(__cxxabiv1::__forced_unwind&)
{
this->_M_setstate(ios_base::badbit);
__throw_exception_again;
}
__catch(...)
{ this->_M_setstate(ios_base::failbit); }
}
else if (!__sbin)
__err |= ios_base::badbit;
if (__err)
this->setstate(__err);
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
put(char_type __c)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 60. What is a formatted input function?
// basic_ostream::put(char_type) is an unformatted output function.
// DR 63. Exception-handling policy for unformatted output.
// Unformatted output functions should catch exceptions thrown
// from streambuf members.
sentry __cerb(*this);
if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
{
const int_type __put = this->rdbuf()->sputc(__c);
if (traits_type::eq_int_type(__put, traits_type::eof()))
__err |= ios_base::badbit;
}
__catch(__cxxabiv1::__forced_unwind&)
{
this->_M_setstate(ios_base::badbit);
__throw_exception_again;
}
__catch(...)
{ this->_M_setstate(ios_base::badbit); }
if (__err)
this->setstate(__err);
}
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
write(const _CharT* __s, streamsize __n)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 60. What is a formatted input function?
// basic_ostream::write(const char_type*, streamsize) is an
// unformatted output function.
// DR 63. Exception-handling policy for unformatted output.
// Unformatted output functions should catch exceptions thrown
// from streambuf members.
sentry __cerb(*this);
if (__cerb)
{
__try
{ _M_write(__s, __n); }
__catch(__cxxabiv1::__forced_unwind&)
{
this->_M_setstate(ios_base::badbit);
__throw_exception_again;
}
__catch(...)
{ this->_M_setstate(ios_base::badbit); }
}
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
flush()
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 60. What is a formatted input function?
// basic_ostream::flush() is *not* an unformatted output function.
ios_base::iostate __err = ios_base::goodbit;
__try
{
if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
__err |= ios_base::badbit;
}
__catch(__cxxabiv1::__forced_unwind&)
{
this->_M_setstate(ios_base::badbit);
__throw_exception_again;
}
__catch(...)
{ this->_M_setstate(ios_base::badbit); }
if (__err)
this->setstate(__err);
return *this;
}
template<typename _CharT, typename _Traits>
typename basic_ostream<_CharT, _Traits>::pos_type
basic_ostream<_CharT, _Traits>::
tellp()
{
pos_type __ret = pos_type(-1);
__try
{
if (!this->fail())
__ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
}
__catch(__cxxabiv1::__forced_unwind&)
{
this->_M_setstate(ios_base::badbit);
__throw_exception_again;
}
__catch(...)
{ this->_M_setstate(ios_base::badbit); }
return __ret;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
seekp(pos_type __pos)
{
ios_base::iostate __err = ios_base::goodbit;
__try
{
if (!this->fail())
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 136. seekp, seekg setting wrong streams?
const pos_type __p = this->rdbuf()->pubseekpos(__pos,
ios_base::out);
// 129. Need error indication from seekp() and seekg()
if (__p == pos_type(off_type(-1)))
__err |= ios_base::failbit;
}
}
__catch(__cxxabiv1::__forced_unwind&)
{
this->_M_setstate(ios_base::badbit);
__throw_exception_again;
}
__catch(...)
{ this->_M_setstate(ios_base::badbit); }
if (__err)
this->setstate(__err);
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
seekp(off_type __off, ios_base::seekdir __dir)
{
ios_base::iostate __err = ios_base::goodbit;
__try
{
if (!this->fail())
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 136. seekp, seekg setting wrong streams?
const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
ios_base::out);
// 129. Need error indication from seekp() and seekg()
if (__p == pos_type(off_type(-1)))
__err |= ios_base::failbit;
}
}
__catch(__cxxabiv1::__forced_unwind&)
{
this->_M_setstate(ios_base::badbit);
__throw_exception_again;
}
__catch(...)
{ this->_M_setstate(ios_base::badbit); }
if (__err)
this->setstate(__err);
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
{
if (!__s)
__out.setstate(ios_base::badbit);
else
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 167. Improper use of traits_type::length()
const size_t __clen = char_traits<char>::length(__s);
__try
{
struct __ptr_guard
{
_CharT *__p;
__ptr_guard (_CharT *__ip): __p(__ip) { }
~__ptr_guard() { delete[] __p; }
_CharT* __get() { return __p; }
} __pg (new _CharT[__clen]);
_CharT *__ws = __pg.__get();
for (size_t __i = 0; __i < __clen; ++__i)
__ws[__i] = __out.widen(__s[__i]);
__ostream_insert(__out, __ws, __clen);
}
__catch(__cxxabiv1::__forced_unwind&)
{
__out._M_setstate(ios_base::badbit);
__throw_exception_again;
}
__catch(...)
{ __out._M_setstate(ios_base::badbit); }
}
return __out;
}
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class basic_ostream<char>;
extern template ostream& endl(ostream&);
extern template ostream& ends(ostream&);
extern template ostream& flush(ostream&);
extern template ostream& operator<<(ostream&, char);
extern template ostream& operator<<(ostream&, unsigned char);
extern template ostream& operator<<(ostream&, signed char);
extern template ostream& operator<<(ostream&, const char*);
extern template ostream& operator<<(ostream&, const unsigned char*);
extern template ostream& operator<<(ostream&, const signed char*);
extern template ostream& ostream::_M_insert(long);
extern template ostream& ostream::_M_insert(unsigned long);
extern template ostream& ostream::_M_insert(bool);
#ifdef _GLIBCXX_USE_LONG_LONG
extern template ostream& ostream::_M_insert(long long);
extern template ostream& ostream::_M_insert(unsigned long long);
#endif
extern template ostream& ostream::_M_insert(double);
extern template ostream& ostream::_M_insert(long double);
extern template ostream& ostream::_M_insert(const void*);
#ifdef _GLIBCXX_USE_WCHAR_T
extern template class basic_ostream<wchar_t>;
extern template wostream& endl(wostream&);
extern template wostream& ends(wostream&);
extern template wostream& flush(wostream&);
extern template wostream& operator<<(wostream&, wchar_t);
extern template wostream& operator<<(wostream&, char);
extern template wostream& operator<<(wostream&, const wchar_t*);
extern template wostream& operator<<(wostream&, const char*);
extern template wostream& wostream::_M_insert(long);
extern template wostream& wostream::_M_insert(unsigned long);
extern template wostream& wostream::_M_insert(bool);
#ifdef _GLIBCXX_USE_LONG_LONG
extern template wostream& wostream::_M_insert(long long);
extern template wostream& wostream::_M_insert(unsigned long long);
#endif
extern template wostream& wostream::_M_insert(double);
extern template wostream& wostream::_M_insert(long double);
extern template wostream& wostream::_M_insert(const void*);
#endif
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

View File

@@ -0,0 +1,129 @@
// Helpers for ostream inserters -*- C++ -*-
// Copyright (C) 2007-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ostream_insert.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ostream}
*/
#ifndef _OSTREAM_INSERT_H
#define _OSTREAM_INSERT_H 1
#pragma GCC system_header
#include <iosfwd>
#include <bits/cxxabi_forced.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
inline void
__ostream_write(basic_ostream<_CharT, _Traits>& __out,
const _CharT* __s, streamsize __n)
{
typedef basic_ostream<_CharT, _Traits> __ostream_type;
typedef typename __ostream_type::ios_base __ios_base;
const streamsize __put = __out.rdbuf()->sputn(__s, __n);
if (__put != __n)
__out.setstate(__ios_base::badbit);
}
template<typename _CharT, typename _Traits>
inline void
__ostream_fill(basic_ostream<_CharT, _Traits>& __out, streamsize __n)
{
typedef basic_ostream<_CharT, _Traits> __ostream_type;
typedef typename __ostream_type::ios_base __ios_base;
const _CharT __c = __out.fill();
for (; __n > 0; --__n)
{
const typename _Traits::int_type __put = __out.rdbuf()->sputc(__c);
if (_Traits::eq_int_type(__put, _Traits::eof()))
{
__out.setstate(__ios_base::badbit);
break;
}
}
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
__ostream_insert(basic_ostream<_CharT, _Traits>& __out,
const _CharT* __s, streamsize __n)
{
typedef basic_ostream<_CharT, _Traits> __ostream_type;
typedef typename __ostream_type::ios_base __ios_base;
typename __ostream_type::sentry __cerb(__out);
if (__cerb)
{
__try
{
const streamsize __w = __out.width();
if (__w > __n)
{
const bool __left = ((__out.flags()
& __ios_base::adjustfield)
== __ios_base::left);
if (!__left)
__ostream_fill(__out, __w - __n);
if (__out.good())
__ostream_write(__out, __s, __n);
if (__left && __out.good())
__ostream_fill(__out, __w - __n);
}
else
__ostream_write(__out, __s, __n);
__out.width(0);
}
__catch(__cxxabiv1::__forced_unwind&)
{
__out._M_setstate(__ios_base::badbit);
__throw_exception_again;
}
__catch(...)
{ __out._M_setstate(__ios_base::badbit); }
}
return __out;
}
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template ostream& __ostream_insert(ostream&, const char*, streamsize);
#ifdef _GLIBCXX_USE_WCHAR_T
extern template wostream& __ostream_insert(wostream&, const wchar_t*,
streamsize);
#endif
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif /* _OSTREAM_INSERT_H */

View File

@@ -0,0 +1,242 @@
// Position types -*- C++ -*-
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/postypes.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/
//
// ISO C++ 14882: 27.4.1 - Types
// ISO C++ 14882: 27.4.3 - Template class fpos
//
#ifndef _GLIBCXX_POSTYPES_H
#define _GLIBCXX_POSTYPES_H 1
#pragma GCC system_header
#include <cwchar> // For mbstate_t
// XXX If <stdint.h> is really needed, make sure to define the macros
// before including it, in order not to break <tr1/cstdint> (and <cstdint>
// in C++0x). Reconsider all this as soon as possible...
#if (defined(_GLIBCXX_HAVE_INT64_T) && !defined(_GLIBCXX_HAVE_INT64_T_LONG) \
&& !defined(_GLIBCXX_HAVE_INT64_T_LONG_LONG))
#ifndef __STDC_LIMIT_MACROS
# define _UNDEF__STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_CONSTANT_MACROS
# define _UNDEF__STDC_CONSTANT_MACROS
# define __STDC_CONSTANT_MACROS
#endif
#include <stdint.h> // For int64_t
#ifdef _UNDEF__STDC_LIMIT_MACROS
# undef __STDC_LIMIT_MACROS
# undef _UNDEF__STDC_LIMIT_MACROS
#endif
#ifdef _UNDEF__STDC_CONSTANT_MACROS
# undef __STDC_CONSTANT_MACROS
# undef _UNDEF__STDC_CONSTANT_MACROS
#endif
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// The types streamoff, streampos and wstreampos and the class
// template fpos<> are described in clauses 21.1.2, 21.1.3, 27.1.2,
// 27.2, 27.4.1, 27.4.3 and D.6. Despite all this verbiage, the
// behaviour of these types is mostly implementation defined or
// unspecified. The behaviour in this implementation is as noted
// below.
/**
* @brief Type used by fpos, char_traits<char>, and char_traits<wchar_t>.
*
* In clauses 21.1.3.1 and 27.4.1 streamoff is described as an
* implementation defined type.
* Note: In versions of GCC up to and including GCC 3.3, streamoff
* was typedef long.
*/
#ifdef _GLIBCXX_HAVE_INT64_T_LONG
typedef long streamoff;
#elif defined(_GLIBCXX_HAVE_INT64_T_LONG_LONG)
typedef long long streamoff;
#elif defined(_GLIBCXX_HAVE_INT64_T)
typedef int64_t streamoff;
#else
typedef long long streamoff;
#endif
/// Integral type for I/O operation counts and buffer sizes.
typedef ptrdiff_t streamsize; // Signed integral type
/**
* @brief Class representing stream positions.
*
* The standard places no requirements upon the template parameter StateT.
* In this implementation StateT must be DefaultConstructible,
* CopyConstructible and Assignable. The standard only requires that fpos
* should contain a member of type StateT. In this implementation it also
* contains an offset stored as a signed integer.
*
* @param StateT Type passed to and returned from state().
*/
template<typename _StateT>
class fpos
{
private:
streamoff _M_off;
_StateT _M_state;
public:
// The standard doesn't require that fpos objects can be default
// constructed. This implementation provides a default
// constructor that initializes the offset to 0 and default
// constructs the state.
fpos()
: _M_off(0), _M_state() { }
// The standard requires that fpos objects can be constructed
// from streamoff objects using the constructor syntax, and
// fails to give any meaningful semantics. In this
// implementation implicit conversion is also allowed, and this
// constructor stores the streamoff as the offset and default
// constructs the state.
/// Construct position from offset.
fpos(streamoff __off)
: _M_off(__off), _M_state() { }
/// Convert to streamoff.
operator streamoff() const { return _M_off; }
/// Remember the value of @a st.
void
state(_StateT __st)
{ _M_state = __st; }
/// Return the last set value of @a st.
_StateT
state() const
{ return _M_state; }
// The standard requires that this operator must be defined, but
// gives no semantics. In this implementation it just adds its
// argument to the stored offset and returns *this.
/// Add offset to this position.
fpos&
operator+=(streamoff __off)
{
_M_off += __off;
return *this;
}
// The standard requires that this operator must be defined, but
// gives no semantics. In this implementation it just subtracts
// its argument from the stored offset and returns *this.
/// Subtract offset from this position.
fpos&
operator-=(streamoff __off)
{
_M_off -= __off;
return *this;
}
// The standard requires that this operator must be defined, but
// defines its semantics only in terms of operator-. In this
// implementation it constructs a copy of *this, adds the
// argument to that copy using operator+= and then returns the
// copy.
/// Add position and offset.
fpos
operator+(streamoff __off) const
{
fpos __pos(*this);
__pos += __off;
return __pos;
}
// The standard requires that this operator must be defined, but
// defines its semantics only in terms of operator+. In this
// implementation it constructs a copy of *this, subtracts the
// argument from that copy using operator-= and then returns the
// copy.
/// Subtract offset from position.
fpos
operator-(streamoff __off) const
{
fpos __pos(*this);
__pos -= __off;
return __pos;
}
// The standard requires that this operator must be defined, but
// defines its semantics only in terms of operator+. In this
// implementation it returns the difference between the offset
// stored in *this and in the argument.
/// Subtract position to return offset.
streamoff
operator-(const fpos& __other) const
{ return _M_off - __other._M_off; }
};
// The standard only requires that operator== must be an
// equivalence relation. In this implementation two fpos<StateT>
// objects belong to the same equivalence class if the contained
// offsets compare equal.
/// Test if equivalent to another position.
template<typename _StateT>
inline bool
operator==(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs)
{ return streamoff(__lhs) == streamoff(__rhs); }
template<typename _StateT>
inline bool
operator!=(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs)
{ return streamoff(__lhs) != streamoff(__rhs); }
// Clauses 21.1.3.1 and 21.1.3.2 describe streampos and wstreampos
// as implementation defined types, but clause 27.2 requires that
// they must both be typedefs for fpos<mbstate_t>
/// File position for char streams.
typedef fpos<mbstate_t> streampos;
/// File position for wchar_t streams.
typedef fpos<mbstate_t> wstreampos;
#if __cplusplus >= 201103L
/// File position for char16_t streams.
typedef fpos<mbstate_t> u16streampos;
/// File position for char32_t streams.
typedef fpos<mbstate_t> u32streampos;
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@@ -0,0 +1,182 @@
// Pointer Traits -*- C++ -*-
// Copyright (C) 2011-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ptr_traits.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _PTR_TRAITS_H
#define _PTR_TRAITS_H 1
#if __cplusplus >= 201103L
#include <type_traits> // For _GLIBCXX_HAS_NESTED_TYPE
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_HAS_NESTED_TYPE(element_type)
_GLIBCXX_HAS_NESTED_TYPE(difference_type)
template<typename _Tp, bool = __has_element_type<_Tp>::value>
struct __ptrtr_elt_type;
template<typename _Tp>
struct __ptrtr_elt_type<_Tp, true>
{
typedef typename _Tp::element_type __type;
};
template<template<typename, typename...> class _SomePtr, typename _Tp,
typename... _Args>
struct __ptrtr_elt_type<_SomePtr<_Tp, _Args...>, false>
{
typedef _Tp __type;
};
template<typename _Tp, bool = __has_difference_type<_Tp>::value>
struct __ptrtr_diff_type
{
typedef typename _Tp::difference_type __type;
};
template<typename _Tp>
struct __ptrtr_diff_type<_Tp, false>
{
typedef ptrdiff_t __type;
};
template<typename _Ptr, typename _Up>
class __ptrtr_rebind_helper
{
template<typename _Ptr2, typename _Up2>
static constexpr bool
_S_chk(typename _Ptr2::template rebind<_Up2>*)
{ return true; }
template<typename, typename>
static constexpr bool
_S_chk(...)
{ return false; }
public:
static const bool __value = _S_chk<_Ptr, _Up>(nullptr);
};
template<typename _Ptr, typename _Up>
const bool __ptrtr_rebind_helper<_Ptr, _Up>::__value;
template<typename _Tp, typename _Up,
bool = __ptrtr_rebind_helper<_Tp, _Up>::__value>
struct __ptrtr_rebind;
template<typename _Tp, typename _Up>
struct __ptrtr_rebind<_Tp, _Up, true>
{
typedef typename _Tp::template rebind<_Up> __type;
};
template<template<typename, typename...> class _SomePtr, typename _Up,
typename _Tp, typename... _Args>
struct __ptrtr_rebind<_SomePtr<_Tp, _Args...>, _Up, false>
{
typedef _SomePtr<_Up, _Args...> __type;
};
template<typename _Tp, typename = typename remove_cv<_Tp>::type>
struct __ptrtr_not_void
{
typedef _Tp __type;
};
template<typename _Tp>
struct __ptrtr_not_void<_Tp, void>
{
struct __type { };
};
template<typename _Ptr>
class __ptrtr_pointer_to
{
typedef typename __ptrtr_elt_type<_Ptr>::__type __orig_type;
typedef typename __ptrtr_not_void<__orig_type>::__type __element_type;
public:
static _Ptr pointer_to(__element_type& __e)
{ return _Ptr::pointer_to(__e); }
};
/**
* @brief Uniform interface to all pointer-like types
* @ingroup pointer_abstractions
*/
template<typename _Ptr>
struct pointer_traits : __ptrtr_pointer_to<_Ptr>
{
/// The pointer type
typedef _Ptr pointer;
/// The type pointed to
typedef typename __ptrtr_elt_type<_Ptr>::__type element_type;
/// Type used to represent the difference between two pointers
typedef typename __ptrtr_diff_type<_Ptr>::__type difference_type;
template<typename _Up>
using rebind = typename __ptrtr_rebind<_Ptr, _Up>::__type;
};
/**
* @brief Partial specialization for built-in pointers.
* @ingroup pointer_abstractions
*/
template<typename _Tp>
struct pointer_traits<_Tp*>
{
/// The pointer type
typedef _Tp* pointer;
/// The type pointed to
typedef _Tp element_type;
/// Type used to represent the difference between two pointers
typedef ptrdiff_t difference_type;
template<typename _Up>
using rebind = _Up*;
/**
* @brief Obtain a pointer to an object
* @param __r A reference to an object of type @c element_type
* @return @c addressof(__r)
*/
static pointer
pointer_to(typename __ptrtr_not_void<element_type>::__type& __r) noexcept
{ return std::addressof(__r); }
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,105 @@
// <range_access.h> -*- C++ -*-
// Copyright (C) 2010-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/range_access.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
#ifndef _GLIBCXX_RANGE_ACCESS_H
#define _GLIBCXX_RANGE_ACCESS_H 1
#pragma GCC system_header
#if __cplusplus >= 201103L
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Return an iterator pointing to the first element of
* the container.
* @param __cont Container.
*/
template<class _Container>
inline auto
begin(_Container& __cont) -> decltype(__cont.begin())
{ return __cont.begin(); }
/**
* @brief Return an iterator pointing to the first element of
* the const container.
* @param __cont Container.
*/
template<class _Container>
inline auto
begin(const _Container& __cont) -> decltype(__cont.begin())
{ return __cont.begin(); }
/**
* @brief Return an iterator pointing to one past the last element of
* the container.
* @param __cont Container.
*/
template<class _Container>
inline auto
end(_Container& __cont) -> decltype(__cont.end())
{ return __cont.end(); }
/**
* @brief Return an iterator pointing to one past the last element of
* the const container.
* @param __cont Container.
*/
template<class _Container>
inline auto
end(const _Container& __cont) -> decltype(__cont.end())
{ return __cont.end(); }
/**
* @brief Return an iterator pointing to the first element of the array.
* @param __arr Array.
*/
template<class _Tp, size_t _Nm>
inline _Tp*
begin(_Tp (&__arr)[_Nm])
{ return __arr; }
/**
* @brief Return an iterator pointing to one past the last element
* of the array.
* @param __arr Array.
*/
template<class _Tp, size_t _Nm>
inline _Tp*
end(_Tp (&__arr)[_Nm])
{ return __arr + _Nm; }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // C++11
#endif // _GLIBCXX_RANGE_ACCESS_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,310 @@
// class template regex -*- C++ -*-
// Copyright (C) 2010-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/**
* @file bits/regex_constants.h
* @brief Constant definitions for the std regex library.
*
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{regex}
*/
namespace std _GLIBCXX_VISIBILITY(default)
{
/**
* @defgroup regex Regular Expressions
*
* A facility for performing regular expression pattern matching.
* @{
*/
/**
* @namespace std::regex_constants
* @brief ISO C++-0x entities sub namespace for regex.
*/
namespace regex_constants
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @name 5.1 Regular Expression Syntax Options
*/
//@{
enum __syntax_option
{
_S_icase,
_S_nosubs,
_S_optimize,
_S_collate,
_S_ECMAScript,
_S_basic,
_S_extended,
_S_awk,
_S_grep,
_S_egrep,
_S_syntax_last
};
/**
* @brief This is a bitmask type indicating how to interpret the regex.
*
* The @c syntax_option_type is implementation defined but it is valid to
* perform bitwise operations on these values and expect the right thing to
* happen.
*
* A valid value of type syntax_option_type shall have exactly one of the
* elements @c ECMAScript, @c basic, @c extended, @c awk, @c grep, @c egrep
* %set.
*/
typedef unsigned int syntax_option_type;
/**
* Specifies that the matching of regular expressions against a character
* sequence shall be performed without regard to case.
*/
constexpr syntax_option_type icase = 1 << _S_icase;
/**
* Specifies that when a regular expression is matched against a character
* container sequence, no sub-expression matches are to be stored in the
* supplied match_results structure.
*/
constexpr syntax_option_type nosubs = 1 << _S_nosubs;
/**
* Specifies that the regular expression engine should pay more attention to
* the speed with which regular expressions are matched, and less to the
* speed with which regular expression objects are constructed. Otherwise
* it has no detectable effect on the program output.
*/
constexpr syntax_option_type optimize = 1 << _S_optimize;
/**
* Specifies that character ranges of the form [a-b] should be locale
* sensitive.
*/
constexpr syntax_option_type collate = 1 << _S_collate;
/**
* Specifies that the grammar recognized by the regular expression engine is
* that used by ECMAScript in ECMA-262 [Ecma International, ECMAScript
* Language Specification, Standard Ecma-262, third edition, 1999], as
* modified in section [28.13]. This grammar is similar to that defined
* in the PERL scripting language but extended with elements found in the
* POSIX regular expression grammar.
*/
constexpr syntax_option_type ECMAScript = 1 << _S_ECMAScript;
/**
* Specifies that the grammar recognized by the regular expression engine is
* that used by POSIX basic regular expressions in IEEE Std 1003.1-2001,
* Portable Operating System Interface (POSIX), Base Definitions and
* Headers, Section 9, Regular Expressions [IEEE, Information Technology --
* Portable Operating System Interface (POSIX), IEEE Standard 1003.1-2001].
*/
constexpr syntax_option_type basic = 1 << _S_basic;
/**
* Specifies that the grammar recognized by the regular expression engine is
* that used by POSIX extended regular expressions in IEEE Std 1003.1-2001,
* Portable Operating System Interface (POSIX), Base Definitions and Headers,
* Section 9, Regular Expressions.
*/
constexpr syntax_option_type extended = 1 << _S_extended;
/**
* Specifies that the grammar recognized by the regular expression engine is
* that used by POSIX utility awk in IEEE Std 1003.1-2001. This option is
* identical to syntax_option_type extended, except that C-style escape
* sequences are supported. These sequences are:
* \\\\, \\a, \\b, \\f, \\n, \\r, \\t , \\v, \\&apos;, &apos;,
* and \\ddd (where ddd is one, two, or three octal digits).
*/
constexpr syntax_option_type awk = 1 << _S_awk;
/**
* Specifies that the grammar recognized by the regular expression engine is
* that used by POSIX utility grep in IEEE Std 1003.1-2001. This option is
* identical to syntax_option_type basic, except that newlines are treated
* as whitespace.
*/
constexpr syntax_option_type grep = 1 << _S_grep;
/**
* Specifies that the grammar recognized by the regular expression engine is
* that used by POSIX utility grep when given the -E option in
* IEEE Std 1003.1-2001. This option is identical to syntax_option_type
* extended, except that newlines are treated as whitespace.
*/
constexpr syntax_option_type egrep = 1 << _S_egrep;
//@}
/**
* @name 5.2 Matching Rules
*
* Matching a regular expression against a sequence of characters [first,
* last) proceeds according to the rules of the grammar specified for the
* regular expression object, modified according to the effects listed
* below for any bitmask elements set.
*
*/
//@{
enum __match_flag
{
_S_not_bol,
_S_not_eol,
_S_not_bow,
_S_not_eow,
_S_any,
_S_not_null,
_S_continuous,
_S_prev_avail,
_S_sed,
_S_no_copy,
_S_first_only,
_S_match_flag_last
};
/**
* @brief This is a bitmask type indicating regex matching rules.
*
* The @c match_flag_type is implementation defined but it is valid to
* perform bitwise operations on these values and expect the right thing to
* happen.
*/
typedef std::bitset<_S_match_flag_last> match_flag_type;
/**
* The default matching rules.
*/
constexpr match_flag_type match_default = 0;
/**
* The first character in the sequence [first, last) is treated as though it
* is not at the beginning of a line, so the character (^) in the regular
* expression shall not match [first, first).
*/
constexpr match_flag_type match_not_bol = 1 << _S_not_bol;
/**
* The last character in the sequence [first, last) is treated as though it
* is not at the end of a line, so the character ($) in the regular
* expression shall not match [last, last).
*/
constexpr match_flag_type match_not_eol = 1 << _S_not_eol;
/**
* The expression \\b is not matched against the sub-sequence
* [first,first).
*/
constexpr match_flag_type match_not_bow = 1 << _S_not_bow;
/**
* The expression \\b should not be matched against the sub-sequence
* [last,last).
*/
constexpr match_flag_type match_not_eow = 1 << _S_not_eow;
/**
* If more than one match is possible then any match is an acceptable
* result.
*/
constexpr match_flag_type match_any = 1 << _S_any;
/**
* The expression does not match an empty sequence.
*/
constexpr match_flag_type match_not_null = 1 << _S_not_null;
/**
* The expression only matches a sub-sequence that begins at first .
*/
constexpr match_flag_type match_continuous = 1 << _S_continuous;
/**
* --first is a valid iterator position. When this flag is set then the
* flags match_not_bol and match_not_bow are ignored by the regular
* expression algorithms 28.11 and iterators 28.12.
*/
constexpr match_flag_type match_prev_avail = 1 << _S_prev_avail;
/**
* When a regular expression match is to be replaced by a new string, the
* new string is constructed using the rules used by the ECMAScript replace
* function in ECMA- 262 [Ecma International, ECMAScript Language
* Specification, Standard Ecma-262, third edition, 1999], part 15.5.4.11
* String.prototype.replace. In addition, during search and replace
* operations all non-overlapping occurrences of the regular expression
* are located and replaced, and sections of the input that did not match
* the expression are copied unchanged to the output string.
*
* Format strings (from ECMA-262 [15.5.4.11]):
* @li $$ The dollar-sign itself ($)
* @li $& The matched substring.
* @li $` The portion of @a string that precedes the matched substring.
* This would be match_results::prefix().
* @li $' The portion of @a string that follows the matched substring.
* This would be match_results::suffix().
* @li $n The nth capture, where n is in [1,9] and $n is not followed by a
* decimal digit. If n <= match_results::size() and the nth capture
* is undefined, use the empty string instead. If n >
* match_results::size(), the result is implementation-defined.
* @li $nn The nnth capture, where nn is a two-digit decimal number on
* [01, 99]. If nn <= match_results::size() and the nth capture is
* undefined, use the empty string instead. If
* nn > match_results::size(), the result is implementation-defined.
*/
constexpr match_flag_type format_default = 0;
/**
* When a regular expression match is to be replaced by a new string, the
* new string is constructed using the rules used by the POSIX sed utility
* in IEEE Std 1003.1- 2001 [IEEE, Information Technology -- Portable
* Operating System Interface (POSIX), IEEE Standard 1003.1-2001].
*/
constexpr match_flag_type format_sed = 1 << _S_sed;
/**
* During a search and replace operation, sections of the character
* container sequence being searched that do not match the regular
* expression shall not be copied to the output string.
*/
constexpr match_flag_type format_no_copy = 1 << _S_no_copy;
/**
* When specified during a search and replace operation, only the first
* occurrence of the regular expression shall be replaced.
*/
constexpr match_flag_type format_first_only = 1 << _S_first_only;
//@}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace regex_constants
/* @} */ // group regex
} // namespace std

View File

@@ -0,0 +1,100 @@
// class template regex -*- C++ -*-
// Copyright (C) 2010-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/**
* @file bits/regex_cursor.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{regex}
*/
namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __detail
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup regex-detail Base and Implementation Classes
* @ingroup regex
* @{
*/
/// ABC for pattern matching
struct _PatternCursor
{
virtual ~_PatternCursor() { };
virtual void _M_next() = 0;
virtual bool _M_at_end() const = 0;
};
/// Provides a cursor into the specific target string.
template<typename _FwdIterT>
class _SpecializedCursor
: public _PatternCursor
{
public:
_SpecializedCursor(const _FwdIterT& __b, const _FwdIterT __e)
: _M_b(__b), _M_c(__b), _M_e(__e)
{ }
typename std::iterator_traits<_FwdIterT>::value_type
_M_current() const
{ return *_M_c; }
void
_M_next()
{ ++_M_c; }
_FwdIterT
_M_pos() const
{ return _M_c; }
const _FwdIterT&
_M_begin() const
{ return _M_b; }
const _FwdIterT&
_M_end() const
{ return _M_e; }
bool
_M_at_end() const
{ return _M_c == _M_e; }
private:
_FwdIterT _M_b;
_FwdIterT _M_c;
_FwdIterT _M_e;
};
// Helper function to create a cursor specialized for an iterator class.
template<typename _FwdIterT>
inline _SpecializedCursor<_FwdIterT>
__cursor(const _FwdIterT& __b, const _FwdIterT __e)
{ return _SpecializedCursor<_FwdIterT>(__b, __e); }
//@} regex-detail
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __detail
} // namespace

View File

@@ -0,0 +1,167 @@
// class template regex -*- C++ -*-
// Copyright (C) 2010-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/**
* @file bits/regex_error.h
* @brief Error and exception objects for the std regex library.
*
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{regex}
*/
namespace std _GLIBCXX_VISIBILITY(default)
{
/**
* @addtogroup regex
* @{
*/
namespace regex_constants
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @name 5.3 Error Types
*/
//@{
enum error_type
{
_S_error_collate,
_S_error_ctype,
_S_error_escape,
_S_error_backref,
_S_error_brack,
_S_error_paren,
_S_error_brace,
_S_error_badbrace,
_S_error_range,
_S_error_space,
_S_error_badrepeat,
_S_error_complexity,
_S_error_stack,
_S_error_last
};
/** The expression contained an invalid collating element name. */
constexpr error_type error_collate(_S_error_collate);
/** The expression contained an invalid character class name. */
constexpr error_type error_ctype(_S_error_ctype);
/**
* The expression contained an invalid escaped character, or a trailing
* escape.
*/
constexpr error_type error_escape(_S_error_escape);
/** The expression contained an invalid back reference. */
constexpr error_type error_backref(_S_error_backref);
/** The expression contained mismatched [ and ]. */
constexpr error_type error_brack(_S_error_brack);
/** The expression contained mismatched ( and ). */
constexpr error_type error_paren(_S_error_paren);
/** The expression contained mismatched { and } */
constexpr error_type error_brace(_S_error_brace);
/** The expression contained an invalid range in a {} expression. */
constexpr error_type error_badbrace(_S_error_badbrace);
/**
* The expression contained an invalid character range,
* such as [b-a] in most encodings.
*/
constexpr error_type error_range(_S_error_range);
/**
* There was insufficient memory to convert the expression into a
* finite state machine.
*/
constexpr error_type error_space(_S_error_space);
/**
* One of <em>*?+{</em> was not preceded by a valid regular expression.
*/
constexpr error_type error_badrepeat(_S_error_badrepeat);
/**
* The complexity of an attempted match against a regular expression
* exceeded a pre-set level.
*/
constexpr error_type error_complexity(_S_error_complexity);
/**
* There was insufficient memory to determine whether the
* regular expression could match the specified character sequence.
*/
constexpr error_type error_stack(_S_error_stack);
//@}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace regex_constants
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// [7.8] Class regex_error
/**
* @brief A regular expression exception class.
* @ingroup exceptions
*
* The regular expression library throws objects of this class on error.
*/
class regex_error : public std::runtime_error
{
regex_constants::error_type _M_code;
public:
/**
* @brief Constructs a regex_error object.
*
* @param __ecode the regex error code.
*/
explicit
regex_error(regex_constants::error_type __ecode);
virtual ~regex_error() throw();
/**
* @brief Gets the regex error code.
*
* @returns the regex error code.
*/
regex_constants::error_type
code() const
{ return _M_code; }
};
//@} // group regex
void
__throw_regex_error(regex_constants::error_type __ecode);
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

View File

@@ -0,0 +1,138 @@
// class template regex -*- C++ -*-
// Copyright (C) 2010-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/**
* @file bits/regex_grep_matcher.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{regex}
*/
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _BiIter>
class sub_match;
template<typename _Bi_iter, typename _Allocator>
class match_results;
_GLIBCXX_END_NAMESPACE_VERSION
namespace __detail
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup regex-detail Base and Implementation Classes
* @ingroup regex
* @{
*/
/// A _Results facade specialized for wrapping a templated match_results.
template<typename _FwdIterT, typename _Alloc>
class _SpecializedResults
: public _Results
{
public:
_SpecializedResults(const _Automaton::_SizeT __size,
const _SpecializedCursor<_FwdIterT>& __cursor,
match_results<_FwdIterT, _Alloc>& __m);
void
_M_set_pos(int __i, int __j, const _PatternCursor& __pc);
void
_M_set_matched(int __i, bool __is_matched)
{ _M_results.at(__i).matched = __is_matched; }
private:
match_results<_FwdIterT, _Alloc>& _M_results;
};
template<typename _FwdIterT, typename _Alloc>
_SpecializedResults<_FwdIterT, _Alloc>::
_SpecializedResults(const _Automaton::_SizeT __size,
const _SpecializedCursor<_FwdIterT>& __cursor,
match_results<_FwdIterT, _Alloc>& __m)
: _M_results(__m)
{
_M_results.clear();
_M_results.reserve(__size + 2);
_M_results.resize(__size);
typename match_results<_FwdIterT, _Alloc>::value_type __sm;
__sm.first = __sm.second = __cursor._M_begin();
_M_results.push_back(__sm);
__sm.first = __sm.second = __cursor._M_end();
_M_results.push_back(__sm);
}
template<typename _FwdIterT, typename _Alloc>
void
_SpecializedResults<_FwdIterT, _Alloc>::
_M_set_pos(int __i, int __j, const _PatternCursor& __pc)
{
typedef const _SpecializedCursor<_FwdIterT>& _CursorT;
_CursorT __c = static_cast<_CursorT>(__pc);
if (__j == 0)
_M_results.at(__i).first = __c._M_pos();
else
_M_results.at(__i).second = __c._M_pos()+1;
}
/// A stack of states used in evaluating the NFA.
typedef std::stack<_StateIdT, std::vector<_StateIdT> > _StateStack;
/// Executes a regular expression NFA/DFA over a range using a
/// variant of the parallel execution algorithm featured in the grep
/// utility, modified to use Laurikari tags.
class _Grep_matcher
{
public:
_Grep_matcher(_PatternCursor& __p,
_Results& __r,
const _AutomatonPtr& __automaton,
regex_constants::match_flag_type __flags);
private:
_StateSet
_M_e_closure(_StateIdT __i);
_StateSet
_M_e_closure(const _StateSet& __s);
_StateSet
_M_e_closure(_StateStack& __stack, const _StateSet& __s);
const std::shared_ptr<_Nfa> _M_nfa;
_PatternCursor& _M_pattern;
_Results& _M_results;
};
//@} regex-detail
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __detail
} // namespace std
#include <bits/regex_grep_matcher.tcc>

View File

@@ -0,0 +1,179 @@
// class template regex -*- C++ -*-
// Copyright (C) 2010-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/**
* @file bits/regex_grep_matcher.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{regex}
*/
#include <regex>
namespace std _GLIBCXX_VISIBILITY(default)
{
namespace
{
// A stack of states used in evaluating the NFA.
typedef std::stack<std::__detail::_StateIdT,
std::vector<std::__detail::_StateIdT>
> _StateStack;
// Obtains the next state set given the current state set __s and the current
// input character.
inline std::__detail::_StateSet
__move(const std::__detail::_PatternCursor& __p,
const std::__detail::_Nfa& __nfa,
const std::__detail::_StateSet& __s)
{
std::__detail::_StateSet __m;
for (std::__detail::_StateSet::const_iterator __i = __s.begin();
__i != __s.end(); ++__i)
{
if (*__i == std::__detail::_S_invalid_state_id)
continue;
const std::__detail::_State& __state = __nfa[*__i];
if (__state._M_opcode == std::__detail::_S_opcode_match
&& __state._M_matches(__p))
__m.insert(__state._M_next);
}
return __m;
}
// returns true if (__s intersect __t) is not empty
inline bool
__includes_some(const std::__detail::_StateSet& __s,
const std::__detail::_StateSet& __t)
{
if (__s.size() > 0 && __t.size() > 0)
{
std::__detail::_StateSet::const_iterator __first = __s.begin();
std::__detail::_StateSet::const_iterator __second = __t.begin();
while (__first != __s.end() && __second != __t.end())
{
if (*__first < *__second)
++__first;
else if (*__second < *__first)
++__second;
else
return true;
}
}
return false;
}
// If an identified state __u is not already in the current state set __e,
// insert it and push it on the current state stack __s.
inline void
__add_visited_state(const std::__detail::_StateIdT __u,
_StateStack& __s,
std::__detail::_StateSet& __e)
{
if (__e.count(__u) == 0)
{
__e.insert(__u);
__s.push(__u);
}
}
} // anonymous namespace
namespace __detail
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
inline _Grep_matcher::
_Grep_matcher(_PatternCursor& __p, _Results& __r,
const _AutomatonPtr& __nfa,
regex_constants::match_flag_type __flags)
: _M_nfa(static_pointer_cast<_Nfa>(__nfa)), _M_pattern(__p), _M_results(__r)
{
__detail::_StateSet __t = this->_M_e_closure(_M_nfa->_M_start());
for (; !_M_pattern._M_at_end(); _M_pattern._M_next())
__t = this->_M_e_closure(__move(_M_pattern, *_M_nfa, __t));
_M_results._M_set_matched(0,
__includes_some(_M_nfa->_M_final_states(), __t));
}
// Creates the e-closure set for the initial state __i.
inline _StateSet _Grep_matcher::
_M_e_closure(_StateIdT __i)
{
_StateSet __s;
__s.insert(__i);
_StateStack __stack;
__stack.push(__i);
return this->_M_e_closure(__stack, __s);
}
// Creates the e-closure set for an arbitrary state set __s.
inline _StateSet _Grep_matcher::
_M_e_closure(const _StateSet& __s)
{
_StateStack __stack;
for (_StateSet::const_iterator __i = __s.begin(); __i != __s.end(); ++__i)
__stack.push(*__i);
return this->_M_e_closure(__stack, __s);
}
inline _StateSet _Grep_matcher::
_M_e_closure(_StateStack& __stack, const _StateSet& __s)
{
_StateSet __e = __s;
while (!__stack.empty())
{
_StateIdT __t = __stack.top(); __stack.pop();
if (__t == _S_invalid_state_id)
continue;
// for each __u with edge from __t to __u labeled e do ...
const _State& __state = _M_nfa->operator[](__t);
switch (__state._M_opcode)
{
case _S_opcode_alternative:
__add_visited_state(__state._M_next, __stack, __e);
__add_visited_state(__state._M_alt, __stack, __e);
break;
case _S_opcode_subexpr_begin:
__add_visited_state(__state._M_next, __stack, __e);
__state._M_tagger(_M_pattern, _M_results);
break;
case _S_opcode_subexpr_end:
__add_visited_state(__state._M_next, __stack, __e);
__state._M_tagger(_M_pattern, _M_results);
_M_results._M_set_matched(__state._M_subexpr, true);
break;
case _S_opcode_accept:
__add_visited_state(__state._M_next, __stack, __e);
break;
default:
break;
}
}
return __e;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __detail
} // namespace

View File

@@ -0,0 +1,415 @@
// class template regex -*- C++ -*-
// Copyright (C) 2010-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/**
* @file bits/regex_nfa.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{regex}
*/
namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __detail
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup regex-detail
* @{
*/
/// Base class for, um, automata. Could be an NFA or a DFA. Your choice.
class _Automaton
{
public:
typedef unsigned int _SizeT;
public:
virtual
~_Automaton() { }
virtual _SizeT
_M_sub_count() const = 0;
#ifdef _GLIBCXX_DEBUG
virtual std::ostream&
_M_dot(std::ostream& __ostr) const = 0;
#endif
};
/// Generic shared pointer to an automaton.
typedef std::shared_ptr<_Automaton> _AutomatonPtr;
/// Operation codes that define the type of transitions within the base NFA
/// that represents the regular expression.
enum _Opcode
{
_S_opcode_unknown = 0,
_S_opcode_alternative = 1,
_S_opcode_subexpr_begin = 4,
_S_opcode_subexpr_end = 5,
_S_opcode_match = 100,
_S_opcode_accept = 255
};
/// Provides a generic facade for a templated match_results.
struct _Results
{
virtual void _M_set_pos(int __i, int __j, const _PatternCursor& __p) = 0;
virtual void _M_set_matched(int __i, bool __is_matched) = 0;
};
/// Tags current state (for subexpr begin/end).
typedef std::function<void (const _PatternCursor&, _Results&)> _Tagger;
/// Start state tag.
template<typename _FwdIterT, typename _TraitsT>
struct _StartTagger
{
explicit
_StartTagger(int __i)
: _M_index(__i)
{ }
void
operator()(const _PatternCursor& __pc, _Results& __r)
{ __r._M_set_pos(_M_index, 0, __pc); }
int _M_index;
};
/// End state tag.
template<typename _FwdIterT, typename _TraitsT>
struct _EndTagger
{
explicit
_EndTagger(int __i)
: _M_index(__i)
{ }
void
operator()(const _PatternCursor& __pc, _Results& __r)
{ __r._M_set_pos(_M_index, 1, __pc); }
int _M_index;
_FwdIterT _M_pos;
};
/// Indicates if current state matches cursor current.
typedef std::function<bool (const _PatternCursor&)> _Matcher;
/// Matches any character
inline bool
_AnyMatcher(const _PatternCursor&)
{ return true; }
/// Matches a single character
template<typename _InIterT, typename _TraitsT>
struct _CharMatcher
{
typedef typename _TraitsT::char_type char_type;
explicit
_CharMatcher(char_type __c, const _TraitsT& __t = _TraitsT())
: _M_traits(__t), _M_c(_M_traits.translate(__c))
{ }
bool
operator()(const _PatternCursor& __pc) const
{
typedef const _SpecializedCursor<_InIterT>& _CursorT;
_CursorT __c = static_cast<_CursorT>(__pc);
return _M_traits.translate(__c._M_current()) == _M_c;
}
const _TraitsT& _M_traits;
char_type _M_c;
};
/// Matches a character range (bracket expression)
template<typename _InIterT, typename _TraitsT>
struct _RangeMatcher
{
typedef typename _TraitsT::char_type _CharT;
typedef std::basic_string<_CharT> _StringT;
explicit
_RangeMatcher(bool __is_non_matching, const _TraitsT& __t = _TraitsT())
: _M_traits(__t), _M_is_non_matching(__is_non_matching)
{ }
bool
operator()(const _PatternCursor& __pc) const
{
typedef const _SpecializedCursor<_InIterT>& _CursorT;
_CursorT __c = static_cast<_CursorT>(__pc);
return true;
}
void
_M_add_char(_CharT __c)
{ }
void
_M_add_collating_element(const _StringT& __s)
{ }
void
_M_add_equivalence_class(const _StringT& __s)
{ }
void
_M_add_character_class(const _StringT& __s)
{ }
void
_M_make_range()
{ }
const _TraitsT& _M_traits;
bool _M_is_non_matching;
};
/// Identifies a state in the NFA.
typedef int _StateIdT;
/// The special case in which a state identifier is not an index.
static const _StateIdT _S_invalid_state_id = -1;
/**
* @brief struct _State
*
* An individual state in an NFA
*
* In this case a "state" is an entry in the NFA definition coupled
* with its outgoing transition(s). All states have a single outgoing
* transition, except for accepting states (which have no outgoing
* transitions) and alt states, which have two outgoing transitions.
*/
struct _State
{
typedef int _OpcodeT;
_OpcodeT _M_opcode; // type of outgoing transition
_StateIdT _M_next; // outgoing transition
_StateIdT _M_alt; // for _S_opcode_alternative
unsigned int _M_subexpr; // for _S_opcode_subexpr_*
_Tagger _M_tagger; // for _S_opcode_subexpr_*
_Matcher _M_matches; // for _S_opcode_match
explicit _State(_OpcodeT __opcode)
: _M_opcode(__opcode), _M_next(_S_invalid_state_id)
{ }
_State(const _Matcher& __m)
: _M_opcode(_S_opcode_match), _M_next(_S_invalid_state_id), _M_matches(__m)
{ }
_State(_OpcodeT __opcode, unsigned int __s, const _Tagger& __t)
: _M_opcode(__opcode), _M_next(_S_invalid_state_id), _M_subexpr(__s),
_M_tagger(__t)
{ }
_State(_StateIdT __next, _StateIdT __alt)
: _M_opcode(_S_opcode_alternative), _M_next(__next), _M_alt(__alt)
{ }
#ifdef _GLIBCXX_DEBUG
std::ostream&
_M_print(std::ostream& ostr) const;
// Prints graphviz dot commands for state.
std::ostream&
_M_dot(std::ostream& __ostr, _StateIdT __id) const;
#endif
};
/// The Grep Matcher works on sets of states. Here are sets of states.
typedef std::set<_StateIdT> _StateSet;
/**
* @brief struct _Nfa
*
* A collection of all states making up an NFA.
*
* An NFA is a 4-tuple M = (K, S, s, F), where
* K is a finite set of states,
* S is the alphabet of the NFA,
* s is the initial state,
* F is a set of final (accepting) states.
*
* This NFA class is templated on S, a type that will hold values of the
* underlying alphabet (without regard to semantics of that alphabet). The
* other elements of the tuple are generated during construction of the NFA
* and are available through accessor member functions.
*/
class _Nfa
: public _Automaton, public std::vector<_State>
{
public:
typedef _State _StateT;
typedef unsigned int _SizeT;
typedef regex_constants::syntax_option_type _FlagT;
_Nfa(_FlagT __f)
: _M_flags(__f), _M_start_state(0), _M_subexpr_count(0)
{ }
~_Nfa()
{ }
_FlagT
_M_options() const
{ return _M_flags; }
_StateIdT
_M_start() const
{ return _M_start_state; }
const _StateSet&
_M_final_states() const
{ return _M_accepting_states; }
_SizeT
_M_sub_count() const
{ return _M_subexpr_count; }
_StateIdT
_M_insert_accept()
{
this->push_back(_StateT(_S_opcode_accept));
_M_accepting_states.insert(this->size()-1);
return this->size()-1;
}
_StateIdT
_M_insert_alt(_StateIdT __next, _StateIdT __alt)
{
this->push_back(_StateT(__next, __alt));
return this->size()-1;
}
_StateIdT
_M_insert_matcher(_Matcher __m)
{
this->push_back(_StateT(__m));
return this->size()-1;
}
_StateIdT
_M_insert_subexpr_begin(const _Tagger& __t)
{
this->push_back(_StateT(_S_opcode_subexpr_begin, _M_subexpr_count++,
__t));
return this->size()-1;
}
_StateIdT
_M_insert_subexpr_end(unsigned int __i, const _Tagger& __t)
{
this->push_back(_StateT(_S_opcode_subexpr_end, __i, __t));
return this->size()-1;
}
#ifdef _GLIBCXX_DEBUG
std::ostream&
_M_dot(std::ostream& __ostr) const;
#endif
private:
_FlagT _M_flags;
_StateIdT _M_start_state;
_StateSet _M_accepting_states;
_SizeT _M_subexpr_count;
};
/// Describes a sequence of one or more %_State, its current start
/// and end(s). This structure contains fragments of an NFA during
/// construction.
class _StateSeq
{
public:
// Constructs a single-node sequence
_StateSeq(_Nfa& __ss, _StateIdT __s, _StateIdT __e = _S_invalid_state_id)
: _M_nfa(__ss), _M_start(__s), _M_end1(__s), _M_end2(__e)
{ }
// Constructs a split sequence from two other sequencces
_StateSeq(const _StateSeq& __e1, const _StateSeq& __e2)
: _M_nfa(__e1._M_nfa),
_M_start(_M_nfa._M_insert_alt(__e1._M_start, __e2._M_start)),
_M_end1(__e1._M_end1), _M_end2(__e2._M_end1)
{ }
// Constructs a split sequence from a single sequence
_StateSeq(const _StateSeq& __e, _StateIdT __id)
: _M_nfa(__e._M_nfa),
_M_start(_M_nfa._M_insert_alt(__id, __e._M_start)),
_M_end1(__id), _M_end2(__e._M_end1)
{ }
// Constructs a copy of a %_StateSeq
_StateSeq(const _StateSeq& __rhs)
: _M_nfa(__rhs._M_nfa), _M_start(__rhs._M_start),
_M_end1(__rhs._M_end1), _M_end2(__rhs._M_end2)
{ }
_StateSeq& operator=(const _StateSeq& __rhs);
_StateIdT
_M_front() const
{ return _M_start; }
// Extends a sequence by one.
void
_M_push_back(_StateIdT __id);
// Extends and maybe joins a sequence.
void
_M_append(_StateIdT __id);
void
_M_append(_StateSeq& __rhs);
// Clones an entire sequence.
_StateIdT
_M_clone();
private:
_Nfa& _M_nfa;
_StateIdT _M_start;
_StateIdT _M_end1;
_StateIdT _M_end2;
};
//@} regex-detail
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __detail
} // namespace std
#include <bits/regex_nfa.tcc>

View File

@@ -0,0 +1,174 @@
// class template regex -*- C++ -*-
// Copyright (C) 2010-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/**
* @file bits/regex_nfa.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{regex}
*/
#include <regex>
namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __detail
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifdef _GLIBCXX_DEBUG
inline std::ostream& _State::
_M_print(std::ostream& ostr) const
{
switch (_M_opcode)
{
case _S_opcode_alternative:
ostr << "alt next=" << _M_next << " alt=" << _M_alt;
break;
case _S_opcode_subexpr_begin:
ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr;
break;
case _S_opcode_subexpr_end:
ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr;
break;
case _S_opcode_match:
ostr << "match next=" << _M_next;
break;
case _S_opcode_accept:
ostr << "accept next=" << _M_next;
break;
default:
ostr << "unknown next=" << _M_next;
break;
}
return ostr;
}
// Prints graphviz dot commands for state.
inline std::ostream& _State::
_M_dot(std::ostream& __ostr, _StateIdT __id) const
{
switch (_M_opcode)
{
case _S_opcode_alternative:
__ostr << __id << " [label=\"" << __id << "\\nALT\"];\n"
<< __id << " -> " << _M_next
<< " [label=\"epsilon\", tailport=\"s\"];\n"
<< __id << " -> " << _M_alt
<< " [label=\"epsilon\", tailport=\"n\"];\n";
break;
case _S_opcode_subexpr_begin:
__ostr << __id << " [label=\"" << __id << "\\nSBEGIN "
<< _M_subexpr << "\"];\n"
<< __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
break;
case _S_opcode_subexpr_end:
__ostr << __id << " [label=\"" << __id << "\\nSEND "
<< _M_subexpr << "\"];\n"
<< __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
break;
case _S_opcode_match:
__ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n"
<< __id << " -> " << _M_next << " [label=\"<match>\"];\n";
break;
case _S_opcode_accept:
__ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ;
break;
default:
__ostr << __id << " [label=\"" << __id << "\\nUNK\"];\n"
<< __id << " -> " << _M_next << " [label=\"?\"];\n";
break;
}
return __ostr;
}
inline std::ostream& _Nfa::
_M_dot(std::ostream& __ostr) const
{
__ostr << "digraph _Nfa {\n"
<< " rankdir=LR;\n";
for (unsigned int __i = 0; __i < this->size(); ++__i)
{ this->at(__i)._M_dot(__ostr, __i); }
__ostr << "}\n";
return __ostr;
}
#endif
inline _StateSeq& _StateSeq::
operator=(const _StateSeq& __rhs)
{
_M_start = __rhs._M_start;
_M_end1 = __rhs._M_end1;
_M_end2 = __rhs._M_end2;
return *this;
}
inline void _StateSeq::
_M_push_back(_StateIdT __id)
{
if (_M_end1 != _S_invalid_state_id)
_M_nfa[_M_end1]._M_next = __id;
_M_end1 = __id;
}
inline void _StateSeq::
_M_append(_StateIdT __id)
{
if (_M_end2 != _S_invalid_state_id)
{
if (_M_end2 == _M_end1)
_M_nfa[_M_end2]._M_alt = __id;
else
_M_nfa[_M_end2]._M_next = __id;
_M_end2 = _S_invalid_state_id;
}
if (_M_end1 != _S_invalid_state_id)
_M_nfa[_M_end1]._M_next = __id;
_M_end1 = __id;
}
inline void _StateSeq::
_M_append(_StateSeq& __rhs)
{
if (_M_end2 != _S_invalid_state_id)
{
if (_M_end2 == _M_end1)
_M_nfa[_M_end2]._M_alt = __rhs._M_start;
else
_M_nfa[_M_end2]._M_next = __rhs._M_start;
_M_end2 = _S_invalid_state_id;
}
if (__rhs._M_end2 != _S_invalid_state_id)
_M_end2 = __rhs._M_end2;
if (_M_end1 != _S_invalid_state_id)
_M_nfa[_M_end1]._M_next = __rhs._M_start;
_M_end1 = __rhs._M_end1;
}
// @todo implement this function.
inline _StateIdT _StateSeq::
_M_clone()
{ return 0; }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __detail
} // namespace

View File

@@ -0,0 +1,632 @@
// shared_ptr and weak_ptr implementation -*- C++ -*-
// Copyright (C) 2007-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
// GCC Note: Based on files from version 1.32.0 of the Boost library.
// shared_count.hpp
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// shared_ptr.hpp
// Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
// Copyright (C) 2001, 2002, 2003 Peter Dimov
// weak_ptr.hpp
// Copyright (C) 2001, 2002, 2003 Peter Dimov
// enable_shared_from_this.hpp
// Copyright (C) 2002 Peter Dimov
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
/** @file bits/shared_ptr.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _SHARED_PTR_H
#define _SHARED_PTR_H 1
#include <bits/shared_ptr_base.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup pointer_abstractions
* @{
*/
/// 2.2.3.7 shared_ptr I/O
template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
inline std::basic_ostream<_Ch, _Tr>&
operator<<(std::basic_ostream<_Ch, _Tr>& __os,
const __shared_ptr<_Tp, _Lp>& __p)
{
__os << __p.get();
return __os;
}
/// 2.2.3.10 shared_ptr get_deleter (experimental)
template<typename _Del, typename _Tp, _Lock_policy _Lp>
inline _Del*
get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
{
#ifdef __GXX_RTTI
return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
#else
return 0;
#endif
}
/**
* @brief A smart pointer with reference-counted copy semantics.
*
* The object pointed to is deleted when the last shared_ptr pointing to
* it is destroyed or reset.
*/
template<typename _Tp>
class shared_ptr : public __shared_ptr<_Tp>
{
public:
/**
* @brief Construct an empty %shared_ptr.
* @post use_count()==0 && get()==0
*/
constexpr shared_ptr() noexcept
: __shared_ptr<_Tp>() { }
shared_ptr(const shared_ptr&) noexcept = default;
/**
* @brief Construct a %shared_ptr that owns the pointer @a __p.
* @param __p A pointer that is convertible to element_type*.
* @post use_count() == 1 && get() == __p
* @throw std::bad_alloc, in which case @c delete @a __p is called.
*/
template<typename _Tp1>
explicit shared_ptr(_Tp1* __p)
: __shared_ptr<_Tp>(__p) { }
/**
* @brief Construct a %shared_ptr that owns the pointer @a __p
* and the deleter @a __d.
* @param __p A pointer.
* @param __d A deleter.
* @post use_count() == 1 && get() == __p
* @throw std::bad_alloc, in which case @a __d(__p) is called.
*
* Requirements: _Deleter's copy constructor and destructor must
* not throw
*
* __shared_ptr will release __p by calling __d(__p)
*/
template<typename _Tp1, typename _Deleter>
shared_ptr(_Tp1* __p, _Deleter __d)
: __shared_ptr<_Tp>(__p, __d) { }
/**
* @brief Construct a %shared_ptr that owns a null pointer
* and the deleter @a __d.
* @param __p A null pointer constant.
* @param __d A deleter.
* @post use_count() == 1 && get() == __p
* @throw std::bad_alloc, in which case @a __d(__p) is called.
*
* Requirements: _Deleter's copy constructor and destructor must
* not throw
*
* The last owner will call __d(__p)
*/
template<typename _Deleter>
shared_ptr(nullptr_t __p, _Deleter __d)
: __shared_ptr<_Tp>(__p, __d) { }
/**
* @brief Construct a %shared_ptr that owns the pointer @a __p
* and the deleter @a __d.
* @param __p A pointer.
* @param __d A deleter.
* @param __a An allocator.
* @post use_count() == 1 && get() == __p
* @throw std::bad_alloc, in which case @a __d(__p) is called.
*
* Requirements: _Deleter's copy constructor and destructor must
* not throw _Alloc's copy constructor and destructor must not
* throw.
*
* __shared_ptr will release __p by calling __d(__p)
*/
template<typename _Tp1, typename _Deleter, typename _Alloc>
shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
: __shared_ptr<_Tp>(__p, __d, std::move(__a)) { }
/**
* @brief Construct a %shared_ptr that owns a null pointer
* and the deleter @a __d.
* @param __p A null pointer constant.
* @param __d A deleter.
* @param __a An allocator.
* @post use_count() == 1 && get() == __p
* @throw std::bad_alloc, in which case @a __d(__p) is called.
*
* Requirements: _Deleter's copy constructor and destructor must
* not throw _Alloc's copy constructor and destructor must not
* throw.
*
* The last owner will call __d(__p)
*/
template<typename _Deleter, typename _Alloc>
shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
: __shared_ptr<_Tp>(__p, __d, std::move(__a)) { }
// Aliasing constructor
/**
* @brief Constructs a %shared_ptr instance that stores @a __p
* and shares ownership with @a __r.
* @param __r A %shared_ptr.
* @param __p A pointer that will remain valid while @a *__r is valid.
* @post get() == __p && use_count() == __r.use_count()
*
* This can be used to construct a @c shared_ptr to a sub-object
* of an object managed by an existing @c shared_ptr.
*
* @code
* shared_ptr< pair<int,int> > pii(new pair<int,int>());
* shared_ptr<int> pi(pii, &pii->first);
* assert(pii.use_count() == 2);
* @endcode
*/
template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p) noexcept
: __shared_ptr<_Tp>(__r, __p) { }
/**
* @brief If @a __r is empty, constructs an empty %shared_ptr;
* otherwise construct a %shared_ptr that shares ownership
* with @a __r.
* @param __r A %shared_ptr.
* @post get() == __r.get() && use_count() == __r.use_count()
*/
template<typename _Tp1, typename = typename
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
shared_ptr(const shared_ptr<_Tp1>& __r) noexcept
: __shared_ptr<_Tp>(__r) { }
/**
* @brief Move-constructs a %shared_ptr instance from @a __r.
* @param __r A %shared_ptr rvalue.
* @post *this contains the old value of @a __r, @a __r is empty.
*/
shared_ptr(shared_ptr&& __r) noexcept
: __shared_ptr<_Tp>(std::move(__r)) { }
/**
* @brief Move-constructs a %shared_ptr instance from @a __r.
* @param __r A %shared_ptr rvalue.
* @post *this contains the old value of @a __r, @a __r is empty.
*/
template<typename _Tp1, typename = typename
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
: __shared_ptr<_Tp>(std::move(__r)) { }
/**
* @brief Constructs a %shared_ptr that shares ownership with @a __r
* and stores a copy of the pointer stored in @a __r.
* @param __r A weak_ptr.
* @post use_count() == __r.use_count()
* @throw bad_weak_ptr when __r.expired(),
* in which case the constructor has no effect.
*/
template<typename _Tp1>
explicit shared_ptr(const weak_ptr<_Tp1>& __r)
: __shared_ptr<_Tp>(__r) { }
#if _GLIBCXX_USE_DEPRECATED
template<typename _Tp1>
shared_ptr(std::auto_ptr<_Tp1>&& __r);
#endif
template<typename _Tp1, typename _Del>
shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
: __shared_ptr<_Tp>(std::move(__r)) { }
/**
* @brief Construct an empty %shared_ptr.
* @param __p A null pointer constant.
* @post use_count() == 0 && get() == nullptr
*/
constexpr shared_ptr(nullptr_t __p) noexcept
: __shared_ptr<_Tp>(__p) { }
shared_ptr& operator=(const shared_ptr&) noexcept = default;
template<typename _Tp1>
shared_ptr&
operator=(const shared_ptr<_Tp1>& __r) noexcept
{
this->__shared_ptr<_Tp>::operator=(__r);
return *this;
}
#if _GLIBCXX_USE_DEPRECATED
template<typename _Tp1>
shared_ptr&
operator=(std::auto_ptr<_Tp1>&& __r)
{
this->__shared_ptr<_Tp>::operator=(std::move(__r));
return *this;
}
#endif
shared_ptr&
operator=(shared_ptr&& __r) noexcept
{
this->__shared_ptr<_Tp>::operator=(std::move(__r));
return *this;
}
template<class _Tp1>
shared_ptr&
operator=(shared_ptr<_Tp1>&& __r) noexcept
{
this->__shared_ptr<_Tp>::operator=(std::move(__r));
return *this;
}
template<typename _Tp1, typename _Del>
shared_ptr&
operator=(std::unique_ptr<_Tp1, _Del>&& __r)
{
this->__shared_ptr<_Tp>::operator=(std::move(__r));
return *this;
}
private:
// This constructor is non-standard, it is used by allocate_shared.
template<typename _Alloc, typename... _Args>
shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
_Args&&... __args)
: __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)
{ }
template<typename _Tp1, typename _Alloc, typename... _Args>
friend shared_ptr<_Tp1>
allocate_shared(const _Alloc& __a, _Args&&... __args);
};
// 20.7.2.2.7 shared_ptr comparisons
template<typename _Tp1, typename _Tp2>
inline bool
operator==(const shared_ptr<_Tp1>& __a,
const shared_ptr<_Tp2>& __b) noexcept
{ return __a.get() == __b.get(); }
template<typename _Tp>
inline bool
operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
{ return !__a; }
template<typename _Tp>
inline bool
operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return !__a; }
template<typename _Tp1, typename _Tp2>
inline bool
operator!=(const shared_ptr<_Tp1>& __a,
const shared_ptr<_Tp2>& __b) noexcept
{ return __a.get() != __b.get(); }
template<typename _Tp>
inline bool
operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
{ return (bool)__a; }
template<typename _Tp>
inline bool
operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return (bool)__a; }
template<typename _Tp1, typename _Tp2>
inline bool
operator<(const shared_ptr<_Tp1>& __a,
const shared_ptr<_Tp2>& __b) noexcept
{
typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT;
return std::less<_CT>()(__a.get(), __b.get());
}
template<typename _Tp>
inline bool
operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
{ return std::less<_Tp*>()(__a.get(), nullptr); }
template<typename _Tp>
inline bool
operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return std::less<_Tp*>()(nullptr, __a.get()); }
template<typename _Tp1, typename _Tp2>
inline bool
operator<=(const shared_ptr<_Tp1>& __a,
const shared_ptr<_Tp2>& __b) noexcept
{ return !(__b < __a); }
template<typename _Tp>
inline bool
operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
{ return !(nullptr < __a); }
template<typename _Tp>
inline bool
operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return !(__a < nullptr); }
template<typename _Tp1, typename _Tp2>
inline bool
operator>(const shared_ptr<_Tp1>& __a,
const shared_ptr<_Tp2>& __b) noexcept
{ return (__b < __a); }
template<typename _Tp>
inline bool
operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
{ return std::less<_Tp*>()(nullptr, __a.get()); }
template<typename _Tp>
inline bool
operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return std::less<_Tp*>()(__a.get(), nullptr); }
template<typename _Tp1, typename _Tp2>
inline bool
operator>=(const shared_ptr<_Tp1>& __a,
const shared_ptr<_Tp2>& __b) noexcept
{ return !(__a < __b); }
template<typename _Tp>
inline bool
operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
{ return !(__a < nullptr); }
template<typename _Tp>
inline bool
operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
{ return !(nullptr < __a); }
template<typename _Tp>
struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>>
{ };
// 20.7.2.2.8 shared_ptr specialized algorithms.
template<typename _Tp>
inline void
swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
{ __a.swap(__b); }
// 20.7.2.2.9 shared_ptr casts.
template<typename _Tp, typename _Tp1>
inline shared_ptr<_Tp>
static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
{ return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); }
template<typename _Tp, typename _Tp1>
inline shared_ptr<_Tp>
const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
{ return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get())); }
template<typename _Tp, typename _Tp1>
inline shared_ptr<_Tp>
dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
{
if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
return shared_ptr<_Tp>(__r, __p);
return shared_ptr<_Tp>();
}
/**
* @brief A smart pointer with weak semantics.
*
* With forwarding constructors and assignment operators.
*/
template<typename _Tp>
class weak_ptr : public __weak_ptr<_Tp>
{
public:
constexpr weak_ptr() noexcept
: __weak_ptr<_Tp>() { }
template<typename _Tp1, typename = typename
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
: __weak_ptr<_Tp>(__r) { }
template<typename _Tp1, typename = typename
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
: __weak_ptr<_Tp>(__r) { }
template<typename _Tp1>
weak_ptr&
operator=(const weak_ptr<_Tp1>& __r) noexcept
{
this->__weak_ptr<_Tp>::operator=(__r);
return *this;
}
template<typename _Tp1>
weak_ptr&
operator=(const shared_ptr<_Tp1>& __r) noexcept
{
this->__weak_ptr<_Tp>::operator=(__r);
return *this;
}
shared_ptr<_Tp>
lock() const noexcept
{
#ifdef __GTHREADS
if (this->expired())
return shared_ptr<_Tp>();
__try
{
return shared_ptr<_Tp>(*this);
}
__catch(const bad_weak_ptr&)
{
return shared_ptr<_Tp>();
}
#else
return this->expired() ? shared_ptr<_Tp>() : shared_ptr<_Tp>(*this);
#endif
}
};
// 20.7.2.3.6 weak_ptr specialized algorithms.
template<typename _Tp>
inline void
swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
{ __a.swap(__b); }
/// Primary template owner_less
template<typename _Tp>
struct owner_less;
/// Partial specialization of owner_less for shared_ptr.
template<typename _Tp>
struct owner_less<shared_ptr<_Tp>>
: public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
{ };
/// Partial specialization of owner_less for weak_ptr.
template<typename _Tp>
struct owner_less<weak_ptr<_Tp>>
: public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
{ };
/**
* @brief Base class allowing use of member function shared_from_this.
*/
template<typename _Tp>
class enable_shared_from_this
{
protected:
constexpr enable_shared_from_this() noexcept { }
enable_shared_from_this(const enable_shared_from_this&) noexcept { }
enable_shared_from_this&
operator=(const enable_shared_from_this&) noexcept
{ return *this; }
~enable_shared_from_this() { }
public:
shared_ptr<_Tp>
shared_from_this()
{ return shared_ptr<_Tp>(this->_M_weak_this); }
shared_ptr<const _Tp>
shared_from_this() const
{ return shared_ptr<const _Tp>(this->_M_weak_this); }
private:
template<typename _Tp1>
void
_M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
{ _M_weak_this._M_assign(__p, __n); }
template<typename _Tp1>
friend void
__enable_shared_from_this_helper(const __shared_count<>& __pn,
const enable_shared_from_this* __pe,
const _Tp1* __px) noexcept
{
if (__pe != 0)
__pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
}
mutable weak_ptr<_Tp> _M_weak_this;
};
/**
* @brief Create an object that is owned by a shared_ptr.
* @param __a An allocator.
* @param __args Arguments for the @a _Tp object's constructor.
* @return A shared_ptr that owns the newly created object.
* @throw An exception thrown from @a _Alloc::allocate or from the
* constructor of @a _Tp.
*
* A copy of @a __a will be used to allocate memory for the shared_ptr
* and the new object.
*/
template<typename _Tp, typename _Alloc, typename... _Args>
inline shared_ptr<_Tp>
allocate_shared(const _Alloc& __a, _Args&&... __args)
{
return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a,
std::forward<_Args>(__args)...);
}
/**
* @brief Create an object that is owned by a shared_ptr.
* @param __args Arguments for the @a _Tp object's constructor.
* @return A shared_ptr that owns the newly created object.
* @throw std::bad_alloc, or an exception thrown from the
* constructor of @a _Tp.
*/
template<typename _Tp, typename... _Args>
inline shared_ptr<_Tp>
make_shared(_Args&&... __args)
{
typedef typename std::remove_const<_Tp>::type _Tp_nc;
return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
std::forward<_Args>(__args)...);
}
/// std::hash specialization for shared_ptr.
template<typename _Tp>
struct hash<shared_ptr<_Tp>>
: public __hash_base<size_t, shared_ptr<_Tp>>
{
size_t
operator()(const shared_ptr<_Tp>& __s) const noexcept
{ return std::hash<_Tp*>()(__s.get()); }
};
// @} group pointer_abstractions
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // _SHARED_PTR_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,274 @@
// The template and inlines for the -*- C++ -*- slice_array class.
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/slice_array.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{valarray}
*/
// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
#ifndef _SLICE_ARRAY_H
#define _SLICE_ARRAY_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup numeric_arrays
* @{
*/
/**
* @brief Class defining one-dimensional subset of an array.
*
* The slice class represents a one-dimensional subset of an array,
* specified by three parameters: start offset, size, and stride. The
* start offset is the index of the first element of the array that is part
* of the subset. The size is the total number of elements in the subset.
* Stride is the distance between each successive array element to include
* in the subset.
*
* For example, with an array of size 10, and a slice with offset 1, size 3
* and stride 2, the subset consists of array elements 1, 3, and 5.
*/
class slice
{
public:
/// Construct an empty slice.
slice();
/**
* @brief Construct a slice.
*
* @param __o Offset in array of first element.
* @param __d Number of elements in slice.
* @param __s Stride between array elements.
*/
slice(size_t __o, size_t __d, size_t __s);
/// Return array offset of first slice element.
size_t start() const;
/// Return size of slice.
size_t size() const;
/// Return array stride of slice.
size_t stride() const;
private:
size_t _M_off; // offset
size_t _M_sz; // size
size_t _M_st; // stride unit
};
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 543. valarray slice default constructor
inline
slice::slice()
: _M_off(0), _M_sz(0), _M_st(0) {}
inline
slice::slice(size_t __o, size_t __d, size_t __s)
: _M_off(__o), _M_sz(__d), _M_st(__s) {}
inline size_t
slice::start() const
{ return _M_off; }
inline size_t
slice::size() const
{ return _M_sz; }
inline size_t
slice::stride() const
{ return _M_st; }
/**
* @brief Reference to one-dimensional subset of an array.
*
* A slice_array is a reference to the actual elements of an array
* specified by a slice. The way to get a slice_array is to call
* operator[](slice) on a valarray. The returned slice_array then permits
* carrying operations out on the referenced subset of elements in the
* original valarray. For example, operator+=(valarray) will add values
* to the subset of elements in the underlying valarray this slice_array
* refers to.
*
* @param Tp Element type.
*/
template<typename _Tp>
class slice_array
{
public:
typedef _Tp value_type;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 253. valarray helper functions are almost entirely useless
/// Copy constructor. Both slices refer to the same underlying array.
slice_array(const slice_array&);
/// Assignment operator. Assigns slice elements to corresponding
/// elements of @a a.
slice_array& operator=(const slice_array&);
/// Assign slice elements to corresponding elements of @a v.
void operator=(const valarray<_Tp>&) const;
/// Multiply slice elements by corresponding elements of @a v.
void operator*=(const valarray<_Tp>&) const;
/// Divide slice elements by corresponding elements of @a v.
void operator/=(const valarray<_Tp>&) const;
/// Modulo slice elements by corresponding elements of @a v.
void operator%=(const valarray<_Tp>&) const;
/// Add corresponding elements of @a v to slice elements.
void operator+=(const valarray<_Tp>&) const;
/// Subtract corresponding elements of @a v from slice elements.
void operator-=(const valarray<_Tp>&) const;
/// Logical xor slice elements with corresponding elements of @a v.
void operator^=(const valarray<_Tp>&) const;
/// Logical and slice elements with corresponding elements of @a v.
void operator&=(const valarray<_Tp>&) const;
/// Logical or slice elements with corresponding elements of @a v.
void operator|=(const valarray<_Tp>&) const;
/// Left shift slice elements by corresponding elements of @a v.
void operator<<=(const valarray<_Tp>&) const;
/// Right shift slice elements by corresponding elements of @a v.
void operator>>=(const valarray<_Tp>&) const;
/// Assign all slice elements to @a t.
void operator=(const _Tp &) const;
// ~slice_array ();
template<class _Dom>
void operator=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator*=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator/=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator%=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator+=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator-=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator^=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator&=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator|=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator<<=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator>>=(const _Expr<_Dom, _Tp>&) const;
private:
friend class valarray<_Tp>;
slice_array(_Array<_Tp>, const slice&);
const size_t _M_sz;
const size_t _M_stride;
const _Array<_Tp> _M_array;
// not implemented
slice_array();
};
template<typename _Tp>
inline
slice_array<_Tp>::slice_array(_Array<_Tp> __a, const slice& __s)
: _M_sz(__s.size()), _M_stride(__s.stride()),
_M_array(__a.begin() + __s.start()) {}
template<typename _Tp>
inline
slice_array<_Tp>::slice_array(const slice_array<_Tp>& a)
: _M_sz(a._M_sz), _M_stride(a._M_stride), _M_array(a._M_array) {}
// template<typename _Tp>
// inline slice_array<_Tp>::~slice_array () {}
template<typename _Tp>
inline slice_array<_Tp>&
slice_array<_Tp>::operator=(const slice_array<_Tp>& __a)
{
std::__valarray_copy(__a._M_array, __a._M_sz, __a._M_stride,
_M_array, _M_stride);
return *this;
}
template<typename _Tp>
inline void
slice_array<_Tp>::operator=(const _Tp& __t) const
{ std::__valarray_fill(_M_array, _M_sz, _M_stride, __t); }
template<typename _Tp>
inline void
slice_array<_Tp>::operator=(const valarray<_Tp>& __v) const
{ std::__valarray_copy(_Array<_Tp>(__v), _M_array, _M_sz, _M_stride); }
template<typename _Tp>
template<class _Dom>
inline void
slice_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const
{ std::__valarray_copy(__e, _M_sz, _M_array, _M_stride); }
#undef _DEFINE_VALARRAY_OPERATOR
#define _DEFINE_VALARRAY_OPERATOR(_Op,_Name) \
template<typename _Tp> \
inline void \
slice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \
{ \
_Array_augmented_##_Name(_M_array, _M_sz, _M_stride, _Array<_Tp>(__v));\
} \
\
template<typename _Tp> \
template<class _Dom> \
inline void \
slice_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\
{ \
_Array_augmented_##_Name(_M_array, _M_stride, __e, _M_sz); \
}
_DEFINE_VALARRAY_OPERATOR(*, __multiplies)
_DEFINE_VALARRAY_OPERATOR(/, __divides)
_DEFINE_VALARRAY_OPERATOR(%, __modulus)
_DEFINE_VALARRAY_OPERATOR(+, __plus)
_DEFINE_VALARRAY_OPERATOR(-, __minus)
_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor)
_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and)
_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or)
_DEFINE_VALARRAY_OPERATOR(<<, __shift_left)
_DEFINE_VALARRAY_OPERATOR(>>, __shift_right)
#undef _DEFINE_VALARRAY_OPERATOR
// @} group numeric_arrays
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _SLICE_ARRAY_H */

View File

@@ -0,0 +1,288 @@
// String based streams -*- C++ -*-
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/sstream.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{sstream}
*/
//
// ISO C++ 14882: 27.7 String-based streams
//
#ifndef _SSTREAM_TCC
#define _SSTREAM_TCC 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template <class _CharT, class _Traits, class _Alloc>
typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
basic_stringbuf<_CharT, _Traits, _Alloc>::
pbackfail(int_type __c)
{
int_type __ret = traits_type::eof();
if (this->eback() < this->gptr())
{
// Try to put back __c into input sequence in one of three ways.
// Order these tests done in is unspecified by the standard.
const bool __testeof = traits_type::eq_int_type(__c, __ret);
if (!__testeof)
{
const bool __testeq = traits_type::eq(traits_type::
to_char_type(__c),
this->gptr()[-1]);
const bool __testout = this->_M_mode & ios_base::out;
if (__testeq || __testout)
{
this->gbump(-1);
if (!__testeq)
*this->gptr() = traits_type::to_char_type(__c);
__ret = __c;
}
}
else
{
this->gbump(-1);
__ret = traits_type::not_eof(__c);
}
}
return __ret;
}
template <class _CharT, class _Traits, class _Alloc>
typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
basic_stringbuf<_CharT, _Traits, _Alloc>::
overflow(int_type __c)
{
const bool __testout = this->_M_mode & ios_base::out;
if (__builtin_expect(!__testout, false))
return traits_type::eof();
const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof());
if (__builtin_expect(__testeof, false))
return traits_type::not_eof(__c);
const __size_type __capacity = _M_string.capacity();
const __size_type __max_size = _M_string.max_size();
const bool __testput = this->pptr() < this->epptr();
if (__builtin_expect(!__testput && __capacity == __max_size, false))
return traits_type::eof();
// Try to append __c into output sequence in one of two ways.
// Order these tests done in is unspecified by the standard.
const char_type __conv = traits_type::to_char_type(__c);
if (!__testput)
{
// NB: Start ostringstream buffers at 512 chars. This is an
// experimental value (pronounced "arbitrary" in some of the
// hipper English-speaking countries), and can be changed to
// suit particular needs.
//
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 169. Bad efficiency of overflow() mandated
// 432. stringbuf::overflow() makes only one write position
// available
const __size_type __opt_len = std::max(__size_type(2 * __capacity),
__size_type(512));
const __size_type __len = std::min(__opt_len, __max_size);
__string_type __tmp;
__tmp.reserve(__len);
if (this->pbase())
__tmp.assign(this->pbase(), this->epptr() - this->pbase());
__tmp.push_back(__conv);
_M_string.swap(__tmp);
_M_sync(const_cast<char_type*>(_M_string.data()),
this->gptr() - this->eback(), this->pptr() - this->pbase());
}
else
*this->pptr() = __conv;
this->pbump(1);
return __c;
}
template <class _CharT, class _Traits, class _Alloc>
typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
basic_stringbuf<_CharT, _Traits, _Alloc>::
underflow()
{
int_type __ret = traits_type::eof();
const bool __testin = this->_M_mode & ios_base::in;
if (__testin)
{
// Update egptr() to match the actual string end.
_M_update_egptr();
if (this->gptr() < this->egptr())
__ret = traits_type::to_int_type(*this->gptr());
}
return __ret;
}
template <class _CharT, class _Traits, class _Alloc>
typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
basic_stringbuf<_CharT, _Traits, _Alloc>::
seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
{
pos_type __ret = pos_type(off_type(-1));
bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
const bool __testboth = __testin && __testout && __way != ios_base::cur;
__testin &= !(__mode & ios_base::out);
__testout &= !(__mode & ios_base::in);
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 453. basic_stringbuf::seekoff need not always fail for an empty stream.
const char_type* __beg = __testin ? this->eback() : this->pbase();
if ((__beg || !__off) && (__testin || __testout || __testboth))
{
_M_update_egptr();
off_type __newoffi = __off;
off_type __newoffo = __newoffi;
if (__way == ios_base::cur)
{
__newoffi += this->gptr() - __beg;
__newoffo += this->pptr() - __beg;
}
else if (__way == ios_base::end)
__newoffo = __newoffi += this->egptr() - __beg;
if ((__testin || __testboth)
&& __newoffi >= 0
&& this->egptr() - __beg >= __newoffi)
{
this->setg(this->eback(), this->eback() + __newoffi,
this->egptr());
__ret = pos_type(__newoffi);
}
if ((__testout || __testboth)
&& __newoffo >= 0
&& this->egptr() - __beg >= __newoffo)
{
_M_pbump(this->pbase(), this->epptr(), __newoffo);
__ret = pos_type(__newoffo);
}
}
return __ret;
}
template <class _CharT, class _Traits, class _Alloc>
typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
basic_stringbuf<_CharT, _Traits, _Alloc>::
seekpos(pos_type __sp, ios_base::openmode __mode)
{
pos_type __ret = pos_type(off_type(-1));
const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
const char_type* __beg = __testin ? this->eback() : this->pbase();
if ((__beg || !off_type(__sp)) && (__testin || __testout))
{
_M_update_egptr();
const off_type __pos(__sp);
const bool __testpos = (0 <= __pos
&& __pos <= this->egptr() - __beg);
if (__testpos)
{
if (__testin)
this->setg(this->eback(), this->eback() + __pos,
this->egptr());
if (__testout)
_M_pbump(this->pbase(), this->epptr(), __pos);
__ret = __sp;
}
}
return __ret;
}
template <class _CharT, class _Traits, class _Alloc>
void
basic_stringbuf<_CharT, _Traits, _Alloc>::
_M_sync(char_type* __base, __size_type __i, __size_type __o)
{
const bool __testin = _M_mode & ios_base::in;
const bool __testout = _M_mode & ios_base::out;
char_type* __endg = __base + _M_string.size();
char_type* __endp = __base + _M_string.capacity();
if (__base != _M_string.data())
{
// setbuf: __i == size of buffer area (_M_string.size() == 0).
__endg += __i;
__i = 0;
__endp = __endg;
}
if (__testin)
this->setg(__base, __base + __i, __endg);
if (__testout)
{
_M_pbump(__base, __endp, __o);
// egptr() always tracks the string end. When !__testin,
// for the correct functioning of the streambuf inlines
// the other get area pointers are identical.
if (!__testin)
this->setg(__endg, __endg, __endg);
}
}
template <class _CharT, class _Traits, class _Alloc>
void
basic_stringbuf<_CharT, _Traits, _Alloc>::
_M_pbump(char_type* __pbeg, char_type* __pend, off_type __off)
{
this->setp(__pbeg, __pend);
while (__off > __gnu_cxx::__numeric_traits<int>::__max)
{
this->pbump(__gnu_cxx::__numeric_traits<int>::__max);
__off -= __gnu_cxx::__numeric_traits<int>::__max;
}
this->pbump(__off);
}
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class basic_stringbuf<char>;
extern template class basic_istringstream<char>;
extern template class basic_ostringstream<char>;
extern template class basic_stringstream<char>;
#ifdef _GLIBCXX_USE_WCHAR_T
extern template class basic_stringbuf<wchar_t>;
extern template class basic_istringstream<wchar_t>;
extern template class basic_ostringstream<wchar_t>;
extern template class basic_stringstream<wchar_t>;
#endif
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,158 @@
// nonstandard construct and destroy functions -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_construct.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _STL_CONSTRUCT_H
#define _STL_CONSTRUCT_H 1
#include <new>
#include <bits/move.h>
#include <ext/alloc_traits.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* Constructs an object in existing memory by invoking an allocated
* object's constructor with an initializer.
*/
#if __cplusplus >= 201103L
template<typename _T1, typename... _Args>
inline void
_Construct(_T1* __p, _Args&&... __args)
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
#else
template<typename _T1, typename _T2>
inline void
_Construct(_T1* __p, const _T2& __value)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 402. wrong new expression in [some_]allocator::construct
::new(static_cast<void*>(__p)) _T1(__value);
}
#endif
/**
* Destroy the object pointed to by a pointer type.
*/
template<typename _Tp>
inline void
_Destroy(_Tp* __pointer)
{ __pointer->~_Tp(); }
template<bool>
struct _Destroy_aux
{
template<typename _ForwardIterator>
static void
__destroy(_ForwardIterator __first, _ForwardIterator __last)
{
for (; __first != __last; ++__first)
std::_Destroy(std::__addressof(*__first));
}
};
template<>
struct _Destroy_aux<true>
{
template<typename _ForwardIterator>
static void
__destroy(_ForwardIterator, _ForwardIterator) { }
};
/**
* Destroy a range of objects. If the value_type of the object has
* a trivial destructor, the compiler should optimize all of this
* away, otherwise the objects' destructors must be invoked.
*/
template<typename _ForwardIterator>
inline void
_Destroy(_ForwardIterator __first, _ForwardIterator __last)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_Value_type;
std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
__destroy(__first, __last);
}
/**
* Destroy a range of objects using the supplied allocator. For
* nondefault allocators we do not optimize away invocation of
* destroy() even if _Tp has a trivial destructor.
*/
template<typename _ForwardIterator, typename _Allocator>
void
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
_Allocator& __alloc)
{
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __first != __last; ++__first)
__traits::destroy(__alloc, std::__addressof(*__first));
}
template<typename _ForwardIterator, typename _Tp>
inline void
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
allocator<_Tp>&)
{
_Destroy(__first, __last);
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif /* _STL_CONSTRUCT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,734 @@
// Functor implementations -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996-1998
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_function.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _STL_FUNCTION_H
#define _STL_FUNCTION_H 1
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// 20.3.1 base classes
/** @defgroup functors Function Objects
* @ingroup utilities
*
* Function objects, or @e functors, are objects with an @c operator()
* defined and accessible. They can be passed as arguments to algorithm
* templates and used in place of a function pointer. Not only is the
* resulting expressiveness of the library increased, but the generated
* code can be more efficient than what you might write by hand. When we
* refer to @a functors, then, generally we include function pointers in
* the description as well.
*
* Often, functors are only created as temporaries passed to algorithm
* calls, rather than being created as named variables.
*
* Two examples taken from the standard itself follow. To perform a
* by-element addition of two vectors @c a and @c b containing @c double,
* and put the result in @c a, use
* \code
* transform (a.begin(), a.end(), b.begin(), a.begin(), plus<double>());
* \endcode
* To negate every element in @c a, use
* \code
* transform(a.begin(), a.end(), a.begin(), negate<double>());
* \endcode
* The addition and negation functions will be inlined directly.
*
* The standard functors are derived from structs named @c unary_function
* and @c binary_function. These two classes contain nothing but typedefs,
* to aid in generic (template) programming. If you write your own
* functors, you might consider doing the same.
*
* @{
*/
/**
* This is one of the @link functors functor base classes@endlink.
*/
template<typename _Arg, typename _Result>
struct unary_function
{
/// @c argument_type is the type of the argument
typedef _Arg argument_type;
/// @c result_type is the return type
typedef _Result result_type;
};
/**
* This is one of the @link functors functor base classes@endlink.
*/
template<typename _Arg1, typename _Arg2, typename _Result>
struct binary_function
{
/// @c first_argument_type is the type of the first argument
typedef _Arg1 first_argument_type;
/// @c second_argument_type is the type of the second argument
typedef _Arg2 second_argument_type;
/// @c result_type is the return type
typedef _Result result_type;
};
/** @} */
// 20.3.2 arithmetic
/** @defgroup arithmetic_functors Arithmetic Classes
* @ingroup functors
*
* Because basic math often needs to be done during an algorithm,
* the library provides functors for those operations. See the
* documentation for @link functors the base classes@endlink
* for examples of their use.
*
* @{
*/
/// One of the @link arithmetic_functors math functors@endlink.
template<typename _Tp>
struct plus : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x + __y; }
};
/// One of the @link arithmetic_functors math functors@endlink.
template<typename _Tp>
struct minus : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x - __y; }
};
/// One of the @link arithmetic_functors math functors@endlink.
template<typename _Tp>
struct multiplies : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x * __y; }
};
/// One of the @link arithmetic_functors math functors@endlink.
template<typename _Tp>
struct divides : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x / __y; }
};
/// One of the @link arithmetic_functors math functors@endlink.
template<typename _Tp>
struct modulus : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x % __y; }
};
/// One of the @link arithmetic_functors math functors@endlink.
template<typename _Tp>
struct negate : public unary_function<_Tp, _Tp>
{
_Tp
operator()(const _Tp& __x) const
{ return -__x; }
};
/** @} */
// 20.3.3 comparisons
/** @defgroup comparison_functors Comparison Classes
* @ingroup functors
*
* The library provides six wrapper functors for all the basic comparisons
* in C++, like @c <.
*
* @{
*/
/// One of the @link comparison_functors comparison functors@endlink.
template<typename _Tp>
struct equal_to : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x == __y; }
};
/// One of the @link comparison_functors comparison functors@endlink.
template<typename _Tp>
struct not_equal_to : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x != __y; }
};
/// One of the @link comparison_functors comparison functors@endlink.
template<typename _Tp>
struct greater : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x > __y; }
};
/// One of the @link comparison_functors comparison functors@endlink.
template<typename _Tp>
struct less : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x < __y; }
};
/// One of the @link comparison_functors comparison functors@endlink.
template<typename _Tp>
struct greater_equal : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x >= __y; }
};
/// One of the @link comparison_functors comparison functors@endlink.
template<typename _Tp>
struct less_equal : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x <= __y; }
};
/** @} */
// 20.3.4 logical operations
/** @defgroup logical_functors Boolean Operations Classes
* @ingroup functors
*
* Here are wrapper functors for Boolean operations: @c &&, @c ||,
* and @c !.
*
* @{
*/
/// One of the @link logical_functors Boolean operations functors@endlink.
template<typename _Tp>
struct logical_and : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x && __y; }
};
/// One of the @link logical_functors Boolean operations functors@endlink.
template<typename _Tp>
struct logical_or : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x || __y; }
};
/// One of the @link logical_functors Boolean operations functors@endlink.
template<typename _Tp>
struct logical_not : public unary_function<_Tp, bool>
{
bool
operator()(const _Tp& __x) const
{ return !__x; }
};
/** @} */
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 660. Missing Bitwise Operations.
template<typename _Tp>
struct bit_and : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x & __y; }
};
template<typename _Tp>
struct bit_or : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x | __y; }
};
template<typename _Tp>
struct bit_xor : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x ^ __y; }
};
// 20.3.5 negators
/** @defgroup negators Negators
* @ingroup functors
*
* The functions @c not1 and @c not2 each take a predicate functor
* and return an instance of @c unary_negate or
* @c binary_negate, respectively. These classes are functors whose
* @c operator() performs the stored predicate function and then returns
* the negation of the result.
*
* For example, given a vector of integers and a trivial predicate,
* \code
* struct IntGreaterThanThree
* : public std::unary_function<int, bool>
* {
* bool operator() (int x) { return x > 3; }
* };
*
* std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree()));
* \endcode
* The call to @c find_if will locate the first index (i) of @c v for which
* <code>!(v[i] > 3)</code> is true.
*
* The not1/unary_negate combination works on predicates taking a single
* argument. The not2/binary_negate combination works on predicates which
* take two arguments.
*
* @{
*/
/// One of the @link negators negation functors@endlink.
template<typename _Predicate>
class unary_negate
: public unary_function<typename _Predicate::argument_type, bool>
{
protected:
_Predicate _M_pred;
public:
explicit
unary_negate(const _Predicate& __x) : _M_pred(__x) { }
bool
operator()(const typename _Predicate::argument_type& __x) const
{ return !_M_pred(__x); }
};
/// One of the @link negators negation functors@endlink.
template<typename _Predicate>
inline unary_negate<_Predicate>
not1(const _Predicate& __pred)
{ return unary_negate<_Predicate>(__pred); }
/// One of the @link negators negation functors@endlink.
template<typename _Predicate>
class binary_negate
: public binary_function<typename _Predicate::first_argument_type,
typename _Predicate::second_argument_type, bool>
{
protected:
_Predicate _M_pred;
public:
explicit
binary_negate(const _Predicate& __x) : _M_pred(__x) { }
bool
operator()(const typename _Predicate::first_argument_type& __x,
const typename _Predicate::second_argument_type& __y) const
{ return !_M_pred(__x, __y); }
};
/// One of the @link negators negation functors@endlink.
template<typename _Predicate>
inline binary_negate<_Predicate>
not2(const _Predicate& __pred)
{ return binary_negate<_Predicate>(__pred); }
/** @} */
// 20.3.7 adaptors pointers functions
/** @defgroup pointer_adaptors Adaptors for pointers to functions
* @ingroup functors
*
* The advantage of function objects over pointers to functions is that
* the objects in the standard library declare nested typedefs describing
* their argument and result types with uniform names (e.g., @c result_type
* from the base classes @c unary_function and @c binary_function).
* Sometimes those typedefs are required, not just optional.
*
* Adaptors are provided to turn pointers to unary (single-argument) and
* binary (double-argument) functions into function objects. The
* long-winded functor @c pointer_to_unary_function is constructed with a
* function pointer @c f, and its @c operator() called with argument @c x
* returns @c f(x). The functor @c pointer_to_binary_function does the same
* thing, but with a double-argument @c f and @c operator().
*
* The function @c ptr_fun takes a pointer-to-function @c f and constructs
* an instance of the appropriate functor.
*
* @{
*/
/// One of the @link pointer_adaptors adaptors for function pointers@endlink.
template<typename _Arg, typename _Result>
class pointer_to_unary_function : public unary_function<_Arg, _Result>
{
protected:
_Result (*_M_ptr)(_Arg);
public:
pointer_to_unary_function() { }
explicit
pointer_to_unary_function(_Result (*__x)(_Arg))
: _M_ptr(__x) { }
_Result
operator()(_Arg __x) const
{ return _M_ptr(__x); }
};
/// One of the @link pointer_adaptors adaptors for function pointers@endlink.
template<typename _Arg, typename _Result>
inline pointer_to_unary_function<_Arg, _Result>
ptr_fun(_Result (*__x)(_Arg))
{ return pointer_to_unary_function<_Arg, _Result>(__x); }
/// One of the @link pointer_adaptors adaptors for function pointers@endlink.
template<typename _Arg1, typename _Arg2, typename _Result>
class pointer_to_binary_function
: public binary_function<_Arg1, _Arg2, _Result>
{
protected:
_Result (*_M_ptr)(_Arg1, _Arg2);
public:
pointer_to_binary_function() { }
explicit
pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2))
: _M_ptr(__x) { }
_Result
operator()(_Arg1 __x, _Arg2 __y) const
{ return _M_ptr(__x, __y); }
};
/// One of the @link pointer_adaptors adaptors for function pointers@endlink.
template<typename _Arg1, typename _Arg2, typename _Result>
inline pointer_to_binary_function<_Arg1, _Arg2, _Result>
ptr_fun(_Result (*__x)(_Arg1, _Arg2))
{ return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); }
/** @} */
template<typename _Tp>
struct _Identity
: public unary_function<_Tp,_Tp>
{
_Tp&
operator()(_Tp& __x) const
{ return __x; }
const _Tp&
operator()(const _Tp& __x) const
{ return __x; }
};
template<typename _Pair>
struct _Select1st
: public unary_function<_Pair, typename _Pair::first_type>
{
typename _Pair::first_type&
operator()(_Pair& __x) const
{ return __x.first; }
const typename _Pair::first_type&
operator()(const _Pair& __x) const
{ return __x.first; }
#if __cplusplus >= 201103L
template<typename _Pair2>
typename _Pair2::first_type&
operator()(_Pair2& __x) const
{ return __x.first; }
template<typename _Pair2>
const typename _Pair2::first_type&
operator()(const _Pair2& __x) const
{ return __x.first; }
#endif
};
template<typename _Pair>
struct _Select2nd
: public unary_function<_Pair, typename _Pair::second_type>
{
typename _Pair::second_type&
operator()(_Pair& __x) const
{ return __x.second; }
const typename _Pair::second_type&
operator()(const _Pair& __x) const
{ return __x.second; }
};
// 20.3.8 adaptors pointers members
/** @defgroup memory_adaptors Adaptors for pointers to members
* @ingroup functors
*
* There are a total of 8 = 2^3 function objects in this family.
* (1) Member functions taking no arguments vs member functions taking
* one argument.
* (2) Call through pointer vs call through reference.
* (3) Const vs non-const member function.
*
* All of this complexity is in the function objects themselves. You can
* ignore it by using the helper function mem_fun and mem_fun_ref,
* which create whichever type of adaptor is appropriate.
*
* @{
*/
/// One of the @link memory_adaptors adaptors for member
/// pointers@endlink.
template<typename _Ret, typename _Tp>
class mem_fun_t : public unary_function<_Tp*, _Ret>
{
public:
explicit
mem_fun_t(_Ret (_Tp::*__pf)())
: _M_f(__pf) { }
_Ret
operator()(_Tp* __p) const
{ return (__p->*_M_f)(); }
private:
_Ret (_Tp::*_M_f)();
};
/// One of the @link memory_adaptors adaptors for member
/// pointers@endlink.
template<typename _Ret, typename _Tp>
class const_mem_fun_t : public unary_function<const _Tp*, _Ret>
{
public:
explicit
const_mem_fun_t(_Ret (_Tp::*__pf)() const)
: _M_f(__pf) { }
_Ret
operator()(const _Tp* __p) const
{ return (__p->*_M_f)(); }
private:
_Ret (_Tp::*_M_f)() const;
};
/// One of the @link memory_adaptors adaptors for member
/// pointers@endlink.
template<typename _Ret, typename _Tp>
class mem_fun_ref_t : public unary_function<_Tp, _Ret>
{
public:
explicit
mem_fun_ref_t(_Ret (_Tp::*__pf)())
: _M_f(__pf) { }
_Ret
operator()(_Tp& __r) const
{ return (__r.*_M_f)(); }
private:
_Ret (_Tp::*_M_f)();
};
/// One of the @link memory_adaptors adaptors for member
/// pointers@endlink.
template<typename _Ret, typename _Tp>
class const_mem_fun_ref_t : public unary_function<_Tp, _Ret>
{
public:
explicit
const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const)
: _M_f(__pf) { }
_Ret
operator()(const _Tp& __r) const
{ return (__r.*_M_f)(); }
private:
_Ret (_Tp::*_M_f)() const;
};
/// One of the @link memory_adaptors adaptors for member
/// pointers@endlink.
template<typename _Ret, typename _Tp, typename _Arg>
class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret>
{
public:
explicit
mem_fun1_t(_Ret (_Tp::*__pf)(_Arg))
: _M_f(__pf) { }
_Ret
operator()(_Tp* __p, _Arg __x) const
{ return (__p->*_M_f)(__x); }
private:
_Ret (_Tp::*_M_f)(_Arg);
};
/// One of the @link memory_adaptors adaptors for member
/// pointers@endlink.
template<typename _Ret, typename _Tp, typename _Arg>
class const_mem_fun1_t : public binary_function<const _Tp*, _Arg, _Ret>
{
public:
explicit
const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const)
: _M_f(__pf) { }
_Ret
operator()(const _Tp* __p, _Arg __x) const
{ return (__p->*_M_f)(__x); }
private:
_Ret (_Tp::*_M_f)(_Arg) const;
};
/// One of the @link memory_adaptors adaptors for member
/// pointers@endlink.
template<typename _Ret, typename _Tp, typename _Arg>
class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret>
{
public:
explicit
mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg))
: _M_f(__pf) { }
_Ret
operator()(_Tp& __r, _Arg __x) const
{ return (__r.*_M_f)(__x); }
private:
_Ret (_Tp::*_M_f)(_Arg);
};
/// One of the @link memory_adaptors adaptors for member
/// pointers@endlink.
template<typename _Ret, typename _Tp, typename _Arg>
class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret>
{
public:
explicit
const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const)
: _M_f(__pf) { }
_Ret
operator()(const _Tp& __r, _Arg __x) const
{ return (__r.*_M_f)(__x); }
private:
_Ret (_Tp::*_M_f)(_Arg) const;
};
// Mem_fun adaptor helper functions. There are only two:
// mem_fun and mem_fun_ref.
template<typename _Ret, typename _Tp>
inline mem_fun_t<_Ret, _Tp>
mem_fun(_Ret (_Tp::*__f)())
{ return mem_fun_t<_Ret, _Tp>(__f); }
template<typename _Ret, typename _Tp>
inline const_mem_fun_t<_Ret, _Tp>
mem_fun(_Ret (_Tp::*__f)() const)
{ return const_mem_fun_t<_Ret, _Tp>(__f); }
template<typename _Ret, typename _Tp>
inline mem_fun_ref_t<_Ret, _Tp>
mem_fun_ref(_Ret (_Tp::*__f)())
{ return mem_fun_ref_t<_Ret, _Tp>(__f); }
template<typename _Ret, typename _Tp>
inline const_mem_fun_ref_t<_Ret, _Tp>
mem_fun_ref(_Ret (_Tp::*__f)() const)
{ return const_mem_fun_ref_t<_Ret, _Tp>(__f); }
template<typename _Ret, typename _Tp, typename _Arg>
inline mem_fun1_t<_Ret, _Tp, _Arg>
mem_fun(_Ret (_Tp::*__f)(_Arg))
{ return mem_fun1_t<_Ret, _Tp, _Arg>(__f); }
template<typename _Ret, typename _Tp, typename _Arg>
inline const_mem_fun1_t<_Ret, _Tp, _Arg>
mem_fun(_Ret (_Tp::*__f)(_Arg) const)
{ return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); }
template<typename _Ret, typename _Tp, typename _Arg>
inline mem_fun1_ref_t<_Ret, _Tp, _Arg>
mem_fun_ref(_Ret (_Tp::*__f)(_Arg))
{ return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }
template<typename _Ret, typename _Tp, typename _Arg>
inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg>
mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const)
{ return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }
/** @} */
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
# include <backward/binders.h>
#endif
#endif /* _STL_FUNCTION_H */

View File

@@ -0,0 +1,592 @@
// Heap implementation -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* Copyright (c) 1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_heap.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{queue}
*/
#ifndef _STL_HEAP_H
#define _STL_HEAP_H 1
#include <debug/debug.h>
#include <bits/move.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup heap_algorithms Heap
* @ingroup sorting_algorithms
*/
template<typename _RandomAccessIterator, typename _Distance>
_Distance
__is_heap_until(_RandomAccessIterator __first, _Distance __n)
{
_Distance __parent = 0;
for (_Distance __child = 1; __child < __n; ++__child)
{
if (__first[__parent] < __first[__child])
return __child;
if ((__child & 1) == 0)
++__parent;
}
return __n;
}
template<typename _RandomAccessIterator, typename _Distance,
typename _Compare>
_Distance
__is_heap_until(_RandomAccessIterator __first, _Distance __n,
_Compare __comp)
{
_Distance __parent = 0;
for (_Distance __child = 1; __child < __n; ++__child)
{
if (__comp(__first[__parent], __first[__child]))
return __child;
if ((__child & 1) == 0)
++__parent;
}
return __n;
}
// __is_heap, a predicate testing whether or not a range is a heap.
// This function is an extension, not part of the C++ standard.
template<typename _RandomAccessIterator, typename _Distance>
inline bool
__is_heap(_RandomAccessIterator __first, _Distance __n)
{ return std::__is_heap_until(__first, __n) == __n; }
template<typename _RandomAccessIterator, typename _Compare,
typename _Distance>
inline bool
__is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n)
{ return std::__is_heap_until(__first, __n, __comp) == __n; }
template<typename _RandomAccessIterator>
inline bool
__is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{ return std::__is_heap(__first, std::distance(__first, __last)); }
template<typename _RandomAccessIterator, typename _Compare>
inline bool
__is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{ return std::__is_heap(__first, __comp, std::distance(__first, __last)); }
// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap,
// + is_heap and is_heap_until in C++0x.
template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
void
__push_heap(_RandomAccessIterator __first,
_Distance __holeIndex, _Distance __topIndex, _Tp __value)
{
_Distance __parent = (__holeIndex - 1) / 2;
while (__holeIndex > __topIndex && *(__first + __parent) < __value)
{
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent));
__holeIndex = __parent;
__parent = (__holeIndex - 1) / 2;
}
*(__first + __holeIndex) = _GLIBCXX_MOVE(__value);
}
/**
* @brief Push an element onto a heap.
* @param __first Start of heap.
* @param __last End of heap + element.
* @ingroup heap_algorithms
*
* This operation pushes the element at last-1 onto the valid heap
* over the range [__first,__last-1). After completion,
* [__first,__last) is a valid heap.
*/
template<typename _RandomAccessIterator>
inline void
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_heap(__first, __last - 1);
_ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
std::__push_heap(__first, _DistanceType((__last - __first) - 1),
_DistanceType(0), _GLIBCXX_MOVE(__value));
}
template<typename _RandomAccessIterator, typename _Distance, typename _Tp,
typename _Compare>
void
__push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
_Distance __topIndex, _Tp __value, _Compare __comp)
{
_Distance __parent = (__holeIndex - 1) / 2;
while (__holeIndex > __topIndex
&& __comp(*(__first + __parent), __value))
{
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent));
__holeIndex = __parent;
__parent = (__holeIndex - 1) / 2;
}
*(__first + __holeIndex) = _GLIBCXX_MOVE(__value);
}
/**
* @brief Push an element onto a heap using comparison functor.
* @param __first Start of heap.
* @param __last End of heap + element.
* @param __comp Comparison functor.
* @ingroup heap_algorithms
*
* This operation pushes the element at __last-1 onto the valid
* heap over the range [__first,__last-1). After completion,
* [__first,__last) is a valid heap. Compare operations are
* performed using comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
inline void
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_heap_pred(__first, __last - 1, __comp);
_ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
std::__push_heap(__first, _DistanceType((__last - __first) - 1),
_DistanceType(0), _GLIBCXX_MOVE(__value), __comp);
}
template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
void
__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
_Distance __len, _Tp __value)
{
const _Distance __topIndex = __holeIndex;
_Distance __secondChild = __holeIndex;
while (__secondChild < (__len - 1) / 2)
{
__secondChild = 2 * (__secondChild + 1);
if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
__secondChild--;
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));
__holeIndex = __secondChild;
}
if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2)
{
__secondChild = 2 * (__secondChild + 1);
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first
+ (__secondChild - 1)));
__holeIndex = __secondChild - 1;
}
std::__push_heap(__first, __holeIndex, __topIndex,
_GLIBCXX_MOVE(__value));
}
template<typename _RandomAccessIterator>
inline void
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_RandomAccessIterator __result)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
_ValueType __value = _GLIBCXX_MOVE(*__result);
*__result = _GLIBCXX_MOVE(*__first);
std::__adjust_heap(__first, _DistanceType(0),
_DistanceType(__last - __first),
_GLIBCXX_MOVE(__value));
}
/**
* @brief Pop an element off a heap.
* @param __first Start of heap.
* @param __last End of heap.
* @pre [__first, __last) is a valid, non-empty range.
* @ingroup heap_algorithms
*
* This operation pops the top of the heap. The elements __first
* and __last-1 are swapped and [__first,__last-1) is made into a
* heap.
*/
template<typename _RandomAccessIterator>
inline void
pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
__glibcxx_requires_non_empty_range(__first, __last);
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_heap(__first, __last);
if (__last - __first > 1)
{
--__last;
std::__pop_heap(__first, __last, __last);
}
}
template<typename _RandomAccessIterator, typename _Distance,
typename _Tp, typename _Compare>
void
__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
_Distance __len, _Tp __value, _Compare __comp)
{
const _Distance __topIndex = __holeIndex;
_Distance __secondChild = __holeIndex;
while (__secondChild < (__len - 1) / 2)
{
__secondChild = 2 * (__secondChild + 1);
if (__comp(*(__first + __secondChild),
*(__first + (__secondChild - 1))))
__secondChild--;
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));
__holeIndex = __secondChild;
}
if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2)
{
__secondChild = 2 * (__secondChild + 1);
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first
+ (__secondChild - 1)));
__holeIndex = __secondChild - 1;
}
std::__push_heap(__first, __holeIndex, __topIndex,
_GLIBCXX_MOVE(__value), __comp);
}
template<typename _RandomAccessIterator, typename _Compare>
inline void
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_RandomAccessIterator __result, _Compare __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
_ValueType __value = _GLIBCXX_MOVE(*__result);
*__result = _GLIBCXX_MOVE(*__first);
std::__adjust_heap(__first, _DistanceType(0),
_DistanceType(__last - __first),
_GLIBCXX_MOVE(__value), __comp);
}
/**
* @brief Pop an element off a heap using comparison functor.
* @param __first Start of heap.
* @param __last End of heap.
* @param __comp Comparison functor to use.
* @ingroup heap_algorithms
*
* This operation pops the top of the heap. The elements __first
* and __last-1 are swapped and [__first,__last-1) is made into a
* heap. Comparisons are made using comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
inline void
pop_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_non_empty_range(__first, __last);
__glibcxx_requires_heap_pred(__first, __last, __comp);
if (__last - __first > 1)
{
--__last;
std::__pop_heap(__first, __last, __last, __comp);
}
}
/**
* @brief Construct a heap over a range.
* @param __first Start of heap.
* @param __last End of heap.
* @ingroup heap_algorithms
*
* This operation makes the elements in [__first,__last) into a heap.
*/
template<typename _RandomAccessIterator>
void
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
if (__last - __first < 2)
return;
const _DistanceType __len = __last - __first;
_DistanceType __parent = (__len - 2) / 2;
while (true)
{
_ValueType __value = _GLIBCXX_MOVE(*(__first + __parent));
std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value));
if (__parent == 0)
return;
__parent--;
}
}
/**
* @brief Construct a heap over a range using comparison functor.
* @param __first Start of heap.
* @param __last End of heap.
* @param __comp Comparison functor to use.
* @ingroup heap_algorithms
*
* This operation makes the elements in [__first,__last) into a heap.
* Comparisons are made using __comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
void
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
if (__last - __first < 2)
return;
const _DistanceType __len = __last - __first;
_DistanceType __parent = (__len - 2) / 2;
while (true)
{
_ValueType __value = _GLIBCXX_MOVE(*(__first + __parent));
std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value),
__comp);
if (__parent == 0)
return;
__parent--;
}
}
/**
* @brief Sort a heap.
* @param __first Start of heap.
* @param __last End of heap.
* @ingroup heap_algorithms
*
* This operation sorts the valid heap in the range [__first,__last).
*/
template<typename _RandomAccessIterator>
void
sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<
typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_heap(__first, __last);
while (__last - __first > 1)
{
--__last;
std::__pop_heap(__first, __last, __last);
}
}
/**
* @brief Sort a heap using comparison functor.
* @param __first Start of heap.
* @param __last End of heap.
* @param __comp Comparison functor to use.
* @ingroup heap_algorithms
*
* This operation sorts the valid heap in the range [__first,__last).
* Comparisons are made using __comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
void
sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_heap_pred(__first, __last, __comp);
while (__last - __first > 1)
{
--__last;
std::__pop_heap(__first, __last, __last, __comp);
}
}
#if __cplusplus >= 201103L
/**
* @brief Search the end of a heap.
* @param __first Start of range.
* @param __last End of range.
* @return An iterator pointing to the first element not in the heap.
* @ingroup heap_algorithms
*
* This operation returns the last iterator i in [__first, __last) for which
* the range [__first, i) is a heap.
*/
template<typename _RandomAccessIterator>
inline _RandomAccessIterator
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
// concept requirements
__glibcxx_function_requires(_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<
typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
return __first + std::__is_heap_until(__first, std::distance(__first,
__last));
}
/**
* @brief Search the end of a heap using comparison functor.
* @param __first Start of range.
* @param __last End of range.
* @param __comp Comparison functor to use.
* @return An iterator pointing to the first element not in the heap.
* @ingroup heap_algorithms
*
* This operation returns the last iterator i in [__first, __last) for which
* the range [__first, i) is a heap. Comparisons are made using __comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
inline _RandomAccessIterator
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
// concept requirements
__glibcxx_function_requires(_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
return __first + std::__is_heap_until(__first, std::distance(__first,
__last),
__comp);
}
/**
* @brief Determines whether a range is a heap.
* @param __first Start of range.
* @param __last End of range.
* @return True if range is a heap, false otherwise.
* @ingroup heap_algorithms
*/
template<typename _RandomAccessIterator>
inline bool
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{ return std::is_heap_until(__first, __last) == __last; }
/**
* @brief Determines whether a range is a heap using comparison functor.
* @param __first Start of range.
* @param __last End of range.
* @param __comp Comparison functor to use.
* @return True if range is a heap, false otherwise.
* @ingroup heap_algorithms
*/
template<typename _RandomAccessIterator, typename _Compare>
inline bool
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{ return std::is_heap_until(__first, __last, __comp) == __last; }
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _STL_HEAP_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,205 @@
// Functions used by iterators -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996-1998
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_iterator_base_funcs.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*
* This file contains all of the general iterator-related utility
* functions, such as distance() and advance().
*/
#ifndef _STL_ITERATOR_BASE_FUNCS_H
#define _STL_ITERATOR_BASE_FUNCS_H 1
#pragma GCC system_header
#include <bits/concept_check.h>
#include <debug/debug.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _InputIterator>
inline typename iterator_traits<_InputIterator>::difference_type
__distance(_InputIterator __first, _InputIterator __last,
input_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
typename iterator_traits<_InputIterator>::difference_type __n = 0;
while (__first != __last)
{
++__first;
++__n;
}
return __n;
}
template<typename _RandomAccessIterator>
inline typename iterator_traits<_RandomAccessIterator>::difference_type
__distance(_RandomAccessIterator __first, _RandomAccessIterator __last,
random_access_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_RandomAccessIteratorConcept<
_RandomAccessIterator>)
return __last - __first;
}
/**
* @brief A generalization of pointer arithmetic.
* @param __first An input iterator.
* @param __last An input iterator.
* @return The distance between them.
*
* Returns @c n such that __first + n == __last. This requires
* that @p __last must be reachable from @p __first. Note that @c
* n may be negative.
*
* For random access iterators, this uses their @c + and @c - operations
* and are constant time. For other %iterator classes they are linear time.
*/
template<typename _InputIterator>
inline typename iterator_traits<_InputIterator>::difference_type
distance(_InputIterator __first, _InputIterator __last)
{
// concept requirements -- taken care of in __distance
return std::__distance(__first, __last,
std::__iterator_category(__first));
}
template<typename _InputIterator, typename _Distance>
inline void
__advance(_InputIterator& __i, _Distance __n, input_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
_GLIBCXX_DEBUG_ASSERT(__n >= 0);
while (__n--)
++__i;
}
template<typename _BidirectionalIterator, typename _Distance>
inline void
__advance(_BidirectionalIterator& __i, _Distance __n,
bidirectional_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_BidirectionalIteratorConcept<
_BidirectionalIterator>)
if (__n > 0)
while (__n--)
++__i;
else
while (__n++)
--__i;
}
template<typename _RandomAccessIterator, typename _Distance>
inline void
__advance(_RandomAccessIterator& __i, _Distance __n,
random_access_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__i += __n;
}
/**
* @brief A generalization of pointer arithmetic.
* @param __i An input iterator.
* @param __n The @a delta by which to change @p __i.
* @return Nothing.
*
* This increments @p i by @p n. For bidirectional and random access
* iterators, @p __n may be negative, in which case @p __i is decremented.
*
* For random access iterators, this uses their @c + and @c - operations
* and are constant time. For other %iterator classes they are linear time.
*/
template<typename _InputIterator, typename _Distance>
inline void
advance(_InputIterator& __i, _Distance __n)
{
// concept requirements -- taken care of in __advance
typename iterator_traits<_InputIterator>::difference_type __d = __n;
std::__advance(__i, __d, std::__iterator_category(__i));
}
#if __cplusplus >= 201103L
template<typename _ForwardIterator>
inline _ForwardIterator
next(_ForwardIterator __x, typename
iterator_traits<_ForwardIterator>::difference_type __n = 1)
{
std::advance(__x, __n);
return __x;
}
template<typename _BidirectionalIterator>
inline _BidirectionalIterator
prev(_BidirectionalIterator __x, typename
iterator_traits<_BidirectionalIterator>::difference_type __n = 1)
{
std::advance(__x, -__n);
return __x;
}
#endif // C++11
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _STL_ITERATOR_BASE_FUNCS_H */

View File

@@ -0,0 +1,236 @@
// Types used in iterator implementation -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996-1998
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_iterator_base_types.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*
* This file contains all of the general iterator-related utility types,
* such as iterator_traits and struct iterator.
*/
#ifndef _STL_ITERATOR_BASE_TYPES_H
#define _STL_ITERATOR_BASE_TYPES_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#if __cplusplus >= 201103L
# include <type_traits> // For _GLIBCXX_HAS_NESTED_TYPE, is_convertible
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup iterators Iterators
* Abstractions for uniform iterating through various underlying types.
*/
//@{
/**
* @defgroup iterator_tags Iterator Tags
* These are empty types, used to distinguish different iterators. The
* distinction is not made by what they contain, but simply by what they
* are. Different underlying algorithms can then be used based on the
* different operations supported by different iterator types.
*/
//@{
/// Marking input iterators.
struct input_iterator_tag { };
/// Marking output iterators.
struct output_iterator_tag { };
/// Forward iterators support a superset of input iterator operations.
struct forward_iterator_tag : public input_iterator_tag { };
/// Bidirectional iterators support a superset of forward iterator
/// operations.
struct bidirectional_iterator_tag : public forward_iterator_tag { };
/// Random-access iterators support a superset of bidirectional
/// iterator operations.
struct random_access_iterator_tag : public bidirectional_iterator_tag { };
//@}
/**
* @brief Common %iterator class.
*
* This class does nothing but define nested typedefs. %Iterator classes
* can inherit from this class to save some work. The typedefs are then
* used in specializations and overloading.
*
* In particular, there are no default implementations of requirements
* such as @c operator++ and the like. (How could there be?)
*/
template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t,
typename _Pointer = _Tp*, typename _Reference = _Tp&>
struct iterator
{
/// One of the @link iterator_tags tag types@endlink.
typedef _Category iterator_category;
/// The type "pointed to" by the iterator.
typedef _Tp value_type;
/// Distance between iterators is represented as this type.
typedef _Distance difference_type;
/// This type represents a pointer-to-value_type.
typedef _Pointer pointer;
/// This type represents a reference-to-value_type.
typedef _Reference reference;
};
/**
* @brief Traits class for iterators.
*
* This class does nothing but define nested typedefs. The general
* version simply @a forwards the nested typedefs from the Iterator
* argument. Specialized versions for pointers and pointers-to-const
* provide tighter, more correct semantics.
*/
#if __cplusplus >= 201103L
_GLIBCXX_HAS_NESTED_TYPE(iterator_category)
template<typename _Iterator,
bool = __has_iterator_category<_Iterator>::value>
struct __iterator_traits { };
template<typename _Iterator>
struct __iterator_traits<_Iterator, true>
{
typedef typename _Iterator::iterator_category iterator_category;
typedef typename _Iterator::value_type value_type;
typedef typename _Iterator::difference_type difference_type;
typedef typename _Iterator::pointer pointer;
typedef typename _Iterator::reference reference;
};
template<typename _Iterator>
struct iterator_traits
: public __iterator_traits<_Iterator> { };
#else
template<typename _Iterator>
struct iterator_traits
{
typedef typename _Iterator::iterator_category iterator_category;
typedef typename _Iterator::value_type value_type;
typedef typename _Iterator::difference_type difference_type;
typedef typename _Iterator::pointer pointer;
typedef typename _Iterator::reference reference;
};
#endif
/// Partial specialization for pointer types.
template<typename _Tp>
struct iterator_traits<_Tp*>
{
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
};
/// Partial specialization for const pointer types.
template<typename _Tp>
struct iterator_traits<const _Tp*>
{
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef const _Tp* pointer;
typedef const _Tp& reference;
};
/**
* This function is not a part of the C++ standard but is syntactic
* sugar for internal library use only.
*/
template<typename _Iter>
inline typename iterator_traits<_Iter>::iterator_category
__iterator_category(const _Iter&)
{ return typename iterator_traits<_Iter>::iterator_category(); }
//@}
// If _Iterator has a base returns it otherwise _Iterator is returned
// untouched
template<typename _Iterator, bool _HasBase>
struct _Iter_base
{
typedef _Iterator iterator_type;
static iterator_type _S_base(_Iterator __it)
{ return __it; }
};
template<typename _Iterator>
struct _Iter_base<_Iterator, true>
{
typedef typename _Iterator::iterator_type iterator_type;
static iterator_type _S_base(_Iterator __it)
{ return __it.base(); }
};
#if __cplusplus >= 201103L
template<typename _InIter>
using _RequireInputIter = typename
enable_if<is_convertible<typename
iterator_traits<_InIter>::iterator_category,
input_iterator_tag>::value>::type;
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _STL_ITERATOR_BASE_TYPES_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,923 @@
// Multimap implementation -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_multimap.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{map}
*/
#ifndef _STL_MULTIMAP_H
#define _STL_MULTIMAP_H 1
#include <bits/concept_check.h>
#if __cplusplus >= 201103L
#include <initializer_list>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/**
* @brief A standard container made up of (key,value) pairs, which can be
* retrieved based on a key, in logarithmic time.
*
* @ingroup associative_containers
*
* @tparam _Key Type of key objects.
* @tparam _Tp Type of mapped objects.
* @tparam _Compare Comparison function object type, defaults to less<_Key>.
* @tparam _Alloc Allocator type, defaults to
* allocator<pair<const _Key, _Tp>.
*
* Meets the requirements of a <a href="tables.html#65">container</a>, a
* <a href="tables.html#66">reversible container</a>, and an
* <a href="tables.html#69">associative container</a> (using equivalent
* keys). For a @c multimap<Key,T> the key_type is Key, the mapped_type
* is T, and the value_type is std::pair<const Key,T>.
*
* Multimaps support bidirectional iterators.
*
* The private tree data is declared exactly the same way for map and
* multimap; the distinction is made entirely in how the tree functions are
* called (*_unique versus *_equal, same as the standard).
*/
template <typename _Key, typename _Tp,
typename _Compare = std::less<_Key>,
typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class multimap
{
public:
typedef _Key key_type;
typedef _Tp mapped_type;
typedef std::pair<const _Key, _Tp> value_type;
typedef _Compare key_compare;
typedef _Alloc allocator_type;
private:
// concept requirements
typedef typename _Alloc::value_type _Alloc_value_type;
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
__glibcxx_class_requires4(_Compare, bool, _Key, _Key,
_BinaryFunctionConcept)
__glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
public:
class value_compare
: public std::binary_function<value_type, value_type, bool>
{
friend class multimap<_Key, _Tp, _Compare, _Alloc>;
protected:
_Compare comp;
value_compare(_Compare __c)
: comp(__c) { }
public:
bool operator()(const value_type& __x, const value_type& __y) const
{ return comp(__x.first, __y.first); }
};
private:
/// This turns a red-black tree into a [multi]map.
typedef typename _Alloc::template rebind<value_type>::other
_Pair_alloc_type;
typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
key_compare, _Pair_alloc_type> _Rep_type;
/// The actual tree structure.
_Rep_type _M_t;
public:
// many of these are specified differently in ISO, but the following are
// "functionally equivalent"
typedef typename _Pair_alloc_type::pointer pointer;
typedef typename _Pair_alloc_type::const_pointer const_pointer;
typedef typename _Pair_alloc_type::reference reference;
typedef typename _Pair_alloc_type::const_reference const_reference;
typedef typename _Rep_type::iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
typedef typename _Rep_type::size_type size_type;
typedef typename _Rep_type::difference_type difference_type;
typedef typename _Rep_type::reverse_iterator reverse_iterator;
typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
// [23.3.2] construct/copy/destroy
// (get_allocator() is also listed in this section)
/**
* @brief Default constructor creates no elements.
*/
multimap()
: _M_t() { }
/**
* @brief Creates a %multimap with no elements.
* @param __comp A comparison object.
* @param __a An allocator object.
*/
explicit
multimap(const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Pair_alloc_type(__a)) { }
/**
* @brief %Multimap copy constructor.
* @param __x A %multimap of identical element and allocator types.
*
* The newly-created %multimap uses a copy of the allocation object
* used by @a __x.
*/
multimap(const multimap& __x)
: _M_t(__x._M_t) { }
#if __cplusplus >= 201103L
/**
* @brief %Multimap move constructor.
* @param __x A %multimap of identical element and allocator types.
*
* The newly-created %multimap contains the exact contents of @a __x.
* The contents of @a __x are a valid, but unspecified %multimap.
*/
multimap(multimap&& __x)
noexcept(is_nothrow_copy_constructible<_Compare>::value)
: _M_t(std::move(__x._M_t)) { }
/**
* @brief Builds a %multimap from an initializer_list.
* @param __l An initializer_list.
* @param __comp A comparison functor.
* @param __a An allocator object.
*
* Create a %multimap consisting of copies of the elements from
* the initializer_list. This is linear in N if the list is already
* sorted, and NlogN otherwise (where N is @a __l.size()).
*/
multimap(initializer_list<value_type> __l,
const _Compare& __comp = _Compare(),
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Pair_alloc_type(__a))
{ _M_t._M_insert_equal(__l.begin(), __l.end()); }
#endif
/**
* @brief Builds a %multimap from a range.
* @param __first An input iterator.
* @param __last An input iterator.
*
* Create a %multimap consisting of copies of the elements from
* [__first,__last). This is linear in N if the range is already sorted,
* and NlogN otherwise (where N is distance(__first,__last)).
*/
template<typename _InputIterator>
multimap(_InputIterator __first, _InputIterator __last)
: _M_t()
{ _M_t._M_insert_equal(__first, __last); }
/**
* @brief Builds a %multimap from a range.
* @param __first An input iterator.
* @param __last An input iterator.
* @param __comp A comparison functor.
* @param __a An allocator object.
*
* Create a %multimap consisting of copies of the elements from
* [__first,__last). This is linear in N if the range is already sorted,
* and NlogN otherwise (where N is distance(__first,__last)).
*/
template<typename _InputIterator>
multimap(_InputIterator __first, _InputIterator __last,
const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Pair_alloc_type(__a))
{ _M_t._M_insert_equal(__first, __last); }
// FIXME There is no dtor declared, but we should have something generated
// by Doxygen. I don't know what tags to add to this paragraph to make
// that happen:
/**
* The dtor only erases the elements, and note that if the elements
* themselves are pointers, the pointed-to memory is not touched in any
* way. Managing the pointer is the user's responsibility.
*/
/**
* @brief %Multimap assignment operator.
* @param __x A %multimap of identical element and allocator types.
*
* All the elements of @a __x are copied, but unlike the copy
* constructor, the allocator object is not copied.
*/
multimap&
operator=(const multimap& __x)
{
_M_t = __x._M_t;
return *this;
}
#if __cplusplus >= 201103L
/**
* @brief %Multimap move assignment operator.
* @param __x A %multimap of identical element and allocator types.
*
* The contents of @a __x are moved into this multimap (without copying).
* @a __x is a valid, but unspecified multimap.
*/
multimap&
operator=(multimap&& __x)
{
// NB: DR 1204.
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
/**
* @brief %Multimap list assignment operator.
* @param __l An initializer_list.
*
* This function fills a %multimap with copies of the elements
* in the initializer list @a __l.
*
* Note that the assignment completely changes the %multimap and
* that the resulting %multimap's size is the same as the number
* of elements assigned. Old data may be lost.
*/
multimap&
operator=(initializer_list<value_type> __l)
{
this->clear();
this->insert(__l.begin(), __l.end());
return *this;
}
#endif
/// Get a copy of the memory allocation object.
allocator_type
get_allocator() const _GLIBCXX_NOEXCEPT
{ return allocator_type(_M_t.get_allocator()); }
// iterators
/**
* Returns a read/write iterator that points to the first pair in the
* %multimap. Iteration is done in ascending order according to the
* keys.
*/
iterator
begin() _GLIBCXX_NOEXCEPT
{ return _M_t.begin(); }
/**
* Returns a read-only (constant) iterator that points to the first pair
* in the %multimap. Iteration is done in ascending order according to
* the keys.
*/
const_iterator
begin() const _GLIBCXX_NOEXCEPT
{ return _M_t.begin(); }
/**
* Returns a read/write iterator that points one past the last pair in
* the %multimap. Iteration is done in ascending order according to the
* keys.
*/
iterator
end() _GLIBCXX_NOEXCEPT
{ return _M_t.end(); }
/**
* Returns a read-only (constant) iterator that points one past the last
* pair in the %multimap. Iteration is done in ascending order according
* to the keys.
*/
const_iterator
end() const _GLIBCXX_NOEXCEPT
{ return _M_t.end(); }
/**
* Returns a read/write reverse iterator that points to the last pair in
* the %multimap. Iteration is done in descending order according to the
* keys.
*/
reverse_iterator
rbegin() _GLIBCXX_NOEXCEPT
{ return _M_t.rbegin(); }
/**
* Returns a read-only (constant) reverse iterator that points to the
* last pair in the %multimap. Iteration is done in descending order
* according to the keys.
*/
const_reverse_iterator
rbegin() const _GLIBCXX_NOEXCEPT
{ return _M_t.rbegin(); }
/**
* Returns a read/write reverse iterator that points to one before the
* first pair in the %multimap. Iteration is done in descending order
* according to the keys.
*/
reverse_iterator
rend() _GLIBCXX_NOEXCEPT
{ return _M_t.rend(); }
/**
* Returns a read-only (constant) reverse iterator that points to one
* before the first pair in the %multimap. Iteration is done in
* descending order according to the keys.
*/
const_reverse_iterator
rend() const _GLIBCXX_NOEXCEPT
{ return _M_t.rend(); }
#if __cplusplus >= 201103L
/**
* Returns a read-only (constant) iterator that points to the first pair
* in the %multimap. Iteration is done in ascending order according to
* the keys.
*/
const_iterator
cbegin() const noexcept
{ return _M_t.begin(); }
/**
* Returns a read-only (constant) iterator that points one past the last
* pair in the %multimap. Iteration is done in ascending order according
* to the keys.
*/
const_iterator
cend() const noexcept
{ return _M_t.end(); }
/**
* Returns a read-only (constant) reverse iterator that points to the
* last pair in the %multimap. Iteration is done in descending order
* according to the keys.
*/
const_reverse_iterator
crbegin() const noexcept
{ return _M_t.rbegin(); }
/**
* Returns a read-only (constant) reverse iterator that points to one
* before the first pair in the %multimap. Iteration is done in
* descending order according to the keys.
*/
const_reverse_iterator
crend() const noexcept
{ return _M_t.rend(); }
#endif
// capacity
/** Returns true if the %multimap is empty. */
bool
empty() const _GLIBCXX_NOEXCEPT
{ return _M_t.empty(); }
/** Returns the size of the %multimap. */
size_type
size() const _GLIBCXX_NOEXCEPT
{ return _M_t.size(); }
/** Returns the maximum size of the %multimap. */
size_type
max_size() const _GLIBCXX_NOEXCEPT
{ return _M_t.max_size(); }
// modifiers
#if __cplusplus >= 201103L
/**
* @brief Build and insert a std::pair into the %multimap.
*
* @param __args Arguments used to generate a new pair instance (see
* std::piecewise_contruct for passing arguments to each
* part of the pair constructor).
*
* @return An iterator that points to the inserted (key,value) pair.
*
* This function builds and inserts a (key, value) %pair into the
* %multimap.
* Contrary to a std::map the %multimap does not rely on unique keys and
* thus multiple pairs with the same key can be inserted.
*
* Insertion requires logarithmic time.
*/
template<typename... _Args>
iterator
emplace(_Args&&... __args)
{ return _M_t._M_emplace_equal(std::forward<_Args>(__args)...); }
/**
* @brief Builds and inserts a std::pair into the %multimap.
*
* @param __pos An iterator that serves as a hint as to where the pair
* should be inserted.
* @param __args Arguments used to generate a new pair instance (see
* std::piecewise_contruct for passing arguments to each
* part of the pair constructor).
* @return An iterator that points to the inserted (key,value) pair.
*
* This function inserts a (key, value) pair into the %multimap.
* Contrary to a std::map the %multimap does not rely on unique keys and
* thus multiple pairs with the same key can be inserted.
* Note that the first parameter is only a hint and can potentially
* improve the performance of the insertion process. A bad hint would
* cause no gains in efficiency.
*
* For more on @a hinting, see:
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html
*
* Insertion requires logarithmic time (if the hint is not taken).
*/
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
return _M_t._M_emplace_hint_equal(__pos,
std::forward<_Args>(__args)...);
}
#endif
/**
* @brief Inserts a std::pair into the %multimap.
* @param __x Pair to be inserted (see std::make_pair for easy creation
* of pairs).
* @return An iterator that points to the inserted (key,value) pair.
*
* This function inserts a (key, value) pair into the %multimap.
* Contrary to a std::map the %multimap does not rely on unique keys and
* thus multiple pairs with the same key can be inserted.
*
* Insertion requires logarithmic time.
*/
iterator
insert(const value_type& __x)
{ return _M_t._M_insert_equal(__x); }
#if __cplusplus >= 201103L
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
iterator
insert(_Pair&& __x)
{ return _M_t._M_insert_equal(std::forward<_Pair>(__x)); }
#endif
/**
* @brief Inserts a std::pair into the %multimap.
* @param __position An iterator that serves as a hint as to where the
* pair should be inserted.
* @param __x Pair to be inserted (see std::make_pair for easy creation
* of pairs).
* @return An iterator that points to the inserted (key,value) pair.
*
* This function inserts a (key, value) pair into the %multimap.
* Contrary to a std::map the %multimap does not rely on unique keys and
* thus multiple pairs with the same key can be inserted.
* Note that the first parameter is only a hint and can potentially
* improve the performance of the insertion process. A bad hint would
* cause no gains in efficiency.
*
* For more on @a hinting, see:
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html
*
* Insertion requires logarithmic time (if the hint is not taken).
*/
iterator
#if __cplusplus >= 201103L
insert(const_iterator __position, const value_type& __x)
#else
insert(iterator __position, const value_type& __x)
#endif
{ return _M_t._M_insert_equal_(__position, __x); }
#if __cplusplus >= 201103L
template<typename _Pair, typename = typename
std::enable_if<std::is_constructible<value_type,
_Pair&&>::value>::type>
iterator
insert(const_iterator __position, _Pair&& __x)
{ return _M_t._M_insert_equal_(__position,
std::forward<_Pair>(__x)); }
#endif
/**
* @brief A template function that attempts to insert a range
* of elements.
* @param __first Iterator pointing to the start of the range to be
* inserted.
* @param __last Iterator pointing to the end of the range.
*
* Complexity similar to that of the range constructor.
*/
template<typename _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{ _M_t._M_insert_equal(__first, __last); }
#if __cplusplus >= 201103L
/**
* @brief Attempts to insert a list of std::pairs into the %multimap.
* @param __l A std::initializer_list<value_type> of pairs to be
* inserted.
*
* Complexity similar to that of the range constructor.
*/
void
insert(initializer_list<value_type> __l)
{ this->insert(__l.begin(), __l.end()); }
#endif
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 130. Associative erase should return an iterator.
/**
* @brief Erases an element from a %multimap.
* @param __position An iterator pointing to the element to be erased.
* @return An iterator pointing to the element immediately following
* @a position prior to the element being erased. If no such
* element exists, end() is returned.
*
* This function erases an element, pointed to by the given iterator,
* from a %multimap. Note that this function only erases the element,
* and that if the element is itself a pointer, the pointed-to memory is
* not touched in any way. Managing the pointer is the user's
* responsibility.
*/
iterator
erase(const_iterator __position)
{ return _M_t.erase(__position); }
// LWG 2059.
_GLIBCXX_ABI_TAG_CXX11
iterator
erase(iterator __position)
{ return _M_t.erase(__position); }
#else
/**
* @brief Erases an element from a %multimap.
* @param __position An iterator pointing to the element to be erased.
*
* This function erases an element, pointed to by the given iterator,
* from a %multimap. Note that this function only erases the element,
* and that if the element is itself a pointer, the pointed-to memory is
* not touched in any way. Managing the pointer is the user's
* responsibility.
*/
void
erase(iterator __position)
{ _M_t.erase(__position); }
#endif
/**
* @brief Erases elements according to the provided key.
* @param __x Key of element to be erased.
* @return The number of elements erased.
*
* This function erases all elements located by the given key from a
* %multimap.
* Note that this function only erases the element, and that if
* the element is itself a pointer, the pointed-to memory is not touched
* in any way. Managing the pointer is the user's responsibility.
*/
size_type
erase(const key_type& __x)
{ return _M_t.erase(__x); }
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 130. Associative erase should return an iterator.
/**
* @brief Erases a [first,last) range of elements from a %multimap.
* @param __first Iterator pointing to the start of the range to be
* erased.
* @param __last Iterator pointing to the end of the range to be
* erased .
* @return The iterator @a __last.
*
* This function erases a sequence of elements from a %multimap.
* Note that this function only erases the elements, and that if
* the elements themselves are pointers, the pointed-to memory is not
* touched in any way. Managing the pointer is the user's
* responsibility.
*/
iterator
erase(const_iterator __first, const_iterator __last)
{ return _M_t.erase(__first, __last); }
#else
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 130. Associative erase should return an iterator.
/**
* @brief Erases a [first,last) range of elements from a %multimap.
* @param __first Iterator pointing to the start of the range to be
* erased.
* @param __last Iterator pointing to the end of the range to
* be erased.
*
* This function erases a sequence of elements from a %multimap.
* Note that this function only erases the elements, and that if
* the elements themselves are pointers, the pointed-to memory is not
* touched in any way. Managing the pointer is the user's
* responsibility.
*/
void
erase(iterator __first, iterator __last)
{ _M_t.erase(__first, __last); }
#endif
/**
* @brief Swaps data with another %multimap.
* @param __x A %multimap of the same element and allocator types.
*
* This exchanges the elements between two multimaps in constant time.
* (It is only swapping a pointer, an integer, and an instance of
* the @c Compare type (which itself is often stateless and empty), so it
* should be quite fast.)
* Note that the global std::swap() function is specialized such that
* std::swap(m1,m2) will feed to this function.
*/
void
swap(multimap& __x)
{ _M_t.swap(__x._M_t); }
/**
* Erases all elements in a %multimap. Note that this function only
* erases the elements, and that if the elements themselves are pointers,
* the pointed-to memory is not touched in any way. Managing the pointer
* is the user's responsibility.
*/
void
clear() _GLIBCXX_NOEXCEPT
{ _M_t.clear(); }
// observers
/**
* Returns the key comparison object out of which the %multimap
* was constructed.
*/
key_compare
key_comp() const
{ return _M_t.key_comp(); }
/**
* Returns a value comparison object, built from the key comparison
* object out of which the %multimap was constructed.
*/
value_compare
value_comp() const
{ return value_compare(_M_t.key_comp()); }
// multimap operations
/**
* @brief Tries to locate an element in a %multimap.
* @param __x Key of (key, value) pair to be located.
* @return Iterator pointing to sought-after element,
* or end() if not found.
*
* This function takes a key and tries to locate the element with which
* the key matches. If successful the function returns an iterator
* pointing to the sought after %pair. If unsuccessful it returns the
* past-the-end ( @c end() ) iterator.
*/
iterator
find(const key_type& __x)
{ return _M_t.find(__x); }
/**
* @brief Tries to locate an element in a %multimap.
* @param __x Key of (key, value) pair to be located.
* @return Read-only (constant) iterator pointing to sought-after
* element, or end() if not found.
*
* This function takes a key and tries to locate the element with which
* the key matches. If successful the function returns a constant
* iterator pointing to the sought after %pair. If unsuccessful it
* returns the past-the-end ( @c end() ) iterator.
*/
const_iterator
find(const key_type& __x) const
{ return _M_t.find(__x); }
/**
* @brief Finds the number of elements with given key.
* @param __x Key of (key, value) pairs to be located.
* @return Number of elements with specified key.
*/
size_type
count(const key_type& __x) const
{ return _M_t.count(__x); }
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
* @return Iterator pointing to first element equal to or greater
* than key, or end().
*
* This function returns the first element of a subsequence of elements
* that matches the given key. If unsuccessful it returns an iterator
* pointing to the first element that has a greater value than given key
* or end() if no such element exists.
*/
iterator
lower_bound(const key_type& __x)
{ return _M_t.lower_bound(__x); }
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
* @return Read-only (constant) iterator pointing to first element
* equal to or greater than key, or end().
*
* This function returns the first element of a subsequence of
* elements that matches the given key. If unsuccessful the
* iterator will point to the next greatest element or, if no
* such greater element exists, to end().
*/
const_iterator
lower_bound(const key_type& __x) const
{ return _M_t.lower_bound(__x); }
/**
* @brief Finds the end of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
* @return Iterator pointing to the first element
* greater than key, or end().
*/
iterator
upper_bound(const key_type& __x)
{ return _M_t.upper_bound(__x); }
/**
* @brief Finds the end of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
* @return Read-only (constant) iterator pointing to first iterator
* greater than key, or end().
*/
const_iterator
upper_bound(const key_type& __x) const
{ return _M_t.upper_bound(__x); }
/**
* @brief Finds a subsequence matching given key.
* @param __x Key of (key, value) pairs to be located.
* @return Pair of iterators that possibly points to the subsequence
* matching given key.
*
* This function is equivalent to
* @code
* std::make_pair(c.lower_bound(val),
* c.upper_bound(val))
* @endcode
* (but is faster than making the calls separately).
*/
std::pair<iterator, iterator>
equal_range(const key_type& __x)
{ return _M_t.equal_range(__x); }
/**
* @brief Finds a subsequence matching given key.
* @param __x Key of (key, value) pairs to be located.
* @return Pair of read-only (constant) iterators that possibly points
* to the subsequence matching given key.
*
* This function is equivalent to
* @code
* std::make_pair(c.lower_bound(val),
* c.upper_bound(val))
* @endcode
* (but is faster than making the calls separately).
*/
std::pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
template<typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
operator==(const multimap<_K1, _T1, _C1, _A1>&,
const multimap<_K1, _T1, _C1, _A1>&);
template<typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
operator<(const multimap<_K1, _T1, _C1, _A1>&,
const multimap<_K1, _T1, _C1, _A1>&);
};
/**
* @brief Multimap equality comparison.
* @param __x A %multimap.
* @param __y A %multimap of the same type as @a __x.
* @return True iff the size and elements of the maps are equal.
*
* This is an equivalence relation. It is linear in the size of the
* multimaps. Multimaps are considered equivalent if their sizes are equal,
* and if corresponding elements compare equal.
*/
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator==(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __x._M_t == __y._M_t; }
/**
* @brief Multimap ordering relation.
* @param __x A %multimap.
* @param __y A %multimap of the same type as @a __x.
* @return True iff @a x is lexicographically less than @a y.
*
* This is a total ordering relation. It is linear in the size of the
* multimaps. The elements must be comparable with @c <.
*
* See std::lexicographical_compare() for how the determination is made.
*/
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator<(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Based on operator==
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator!=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Based on operator<
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator>(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __y < __x; }
/// Based on operator<
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator<=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Based on operator<
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator>=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::multimap::swap().
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline void
swap(multimap<_Key, _Tp, _Compare, _Alloc>& __x,
multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
_GLIBCXX_END_NAMESPACE_CONTAINER
} // namespace std
#endif /* _STL_MULTIMAP_H */

View File

@@ -0,0 +1,798 @@
// Multiset implementation -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_multiset.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{set}
*/
#ifndef _STL_MULTISET_H
#define _STL_MULTISET_H 1
#include <bits/concept_check.h>
#if __cplusplus >= 201103L
#include <initializer_list>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/**
* @brief A standard container made up of elements, which can be retrieved
* in logarithmic time.
*
* @ingroup associative_containers
*
*
* @tparam _Key Type of key objects.
* @tparam _Compare Comparison function object type, defaults to less<_Key>.
* @tparam _Alloc Allocator type, defaults to allocator<_Key>.
*
* Meets the requirements of a <a href="tables.html#65">container</a>, a
* <a href="tables.html#66">reversible container</a>, and an
* <a href="tables.html#69">associative container</a> (using equivalent
* keys). For a @c multiset<Key> the key_type and value_type are Key.
*
* Multisets support bidirectional iterators.
*
* The private tree data is declared exactly the same way for set and
* multiset; the distinction is made entirely in how the tree functions are
* called (*_unique versus *_equal, same as the standard).
*/
template <typename _Key, typename _Compare = std::less<_Key>,
typename _Alloc = std::allocator<_Key> >
class multiset
{
// concept requirements
typedef typename _Alloc::value_type _Alloc_value_type;
__glibcxx_class_requires(_Key, _SGIAssignableConcept)
__glibcxx_class_requires4(_Compare, bool, _Key, _Key,
_BinaryFunctionConcept)
__glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept)
public:
// typedefs:
typedef _Key key_type;
typedef _Key value_type;
typedef _Compare key_compare;
typedef _Compare value_compare;
typedef _Alloc allocator_type;
private:
/// This turns a red-black tree into a [multi]set.
typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type;
typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
key_compare, _Key_alloc_type> _Rep_type;
/// The actual tree structure.
_Rep_type _M_t;
public:
typedef typename _Key_alloc_type::pointer pointer;
typedef typename _Key_alloc_type::const_pointer const_pointer;
typedef typename _Key_alloc_type::reference reference;
typedef typename _Key_alloc_type::const_reference const_reference;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 103. set::iterator is required to be modifiable,
// but this allows modification of keys.
typedef typename _Rep_type::const_iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
typedef typename _Rep_type::size_type size_type;
typedef typename _Rep_type::difference_type difference_type;
// allocation/deallocation
/**
* @brief Default constructor creates no elements.
*/
multiset()
: _M_t() { }
/**
* @brief Creates a %multiset with no elements.
* @param __comp Comparator to use.
* @param __a An allocator object.
*/
explicit
multiset(const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Key_alloc_type(__a)) { }
/**
* @brief Builds a %multiset from a range.
* @param __first An input iterator.
* @param __last An input iterator.
*
* Create a %multiset consisting of copies of the elements from
* [first,last). This is linear in N if the range is already sorted,
* and NlogN otherwise (where N is distance(__first,__last)).
*/
template<typename _InputIterator>
multiset(_InputIterator __first, _InputIterator __last)
: _M_t()
{ _M_t._M_insert_equal(__first, __last); }
/**
* @brief Builds a %multiset from a range.
* @param __first An input iterator.
* @param __last An input iterator.
* @param __comp A comparison functor.
* @param __a An allocator object.
*
* Create a %multiset consisting of copies of the elements from
* [__first,__last). This is linear in N if the range is already sorted,
* and NlogN otherwise (where N is distance(__first,__last)).
*/
template<typename _InputIterator>
multiset(_InputIterator __first, _InputIterator __last,
const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Key_alloc_type(__a))
{ _M_t._M_insert_equal(__first, __last); }
/**
* @brief %Multiset copy constructor.
* @param __x A %multiset of identical element and allocator types.
*
* The newly-created %multiset uses a copy of the allocation object used
* by @a __x.
*/
multiset(const multiset& __x)
: _M_t(__x._M_t) { }
#if __cplusplus >= 201103L
/**
* @brief %Multiset move constructor.
* @param __x A %multiset of identical element and allocator types.
*
* The newly-created %multiset contains the exact contents of @a __x.
* The contents of @a __x are a valid, but unspecified %multiset.
*/
multiset(multiset&& __x)
noexcept(is_nothrow_copy_constructible<_Compare>::value)
: _M_t(std::move(__x._M_t)) { }
/**
* @brief Builds a %multiset from an initializer_list.
* @param __l An initializer_list.
* @param __comp A comparison functor.
* @param __a An allocator object.
*
* Create a %multiset consisting of copies of the elements from
* the list. This is linear in N if the list is already sorted,
* and NlogN otherwise (where N is @a __l.size()).
*/
multiset(initializer_list<value_type> __l,
const _Compare& __comp = _Compare(),
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Key_alloc_type(__a))
{ _M_t._M_insert_equal(__l.begin(), __l.end()); }
#endif
/**
* @brief %Multiset assignment operator.
* @param __x A %multiset of identical element and allocator types.
*
* All the elements of @a __x are copied, but unlike the copy
* constructor, the allocator object is not copied.
*/
multiset&
operator=(const multiset& __x)
{
_M_t = __x._M_t;
return *this;
}
#if __cplusplus >= 201103L
/**
* @brief %Multiset move assignment operator.
* @param __x A %multiset of identical element and allocator types.
*
* The contents of @a __x are moved into this %multiset
* (without copying). @a __x is a valid, but unspecified
* %multiset.
*/
multiset&
operator=(multiset&& __x)
{
// NB: DR 1204.
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
/**
* @brief %Multiset list assignment operator.
* @param __l An initializer_list.
*
* This function fills a %multiset with copies of the elements in the
* initializer list @a __l.
*
* Note that the assignment completely changes the %multiset and
* that the resulting %multiset's size is the same as the number
* of elements assigned. Old data may be lost.
*/
multiset&
operator=(initializer_list<value_type> __l)
{
this->clear();
this->insert(__l.begin(), __l.end());
return *this;
}
#endif
// accessors:
/// Returns the comparison object.
key_compare
key_comp() const
{ return _M_t.key_comp(); }
/// Returns the comparison object.
value_compare
value_comp() const
{ return _M_t.key_comp(); }
/// Returns the memory allocation object.
allocator_type
get_allocator() const _GLIBCXX_NOEXCEPT
{ return allocator_type(_M_t.get_allocator()); }
/**
* Returns a read-only (constant) iterator that points to the first
* element in the %multiset. Iteration is done in ascending order
* according to the keys.
*/
iterator
begin() const _GLIBCXX_NOEXCEPT
{ return _M_t.begin(); }
/**
* Returns a read-only (constant) iterator that points one past the last
* element in the %multiset. Iteration is done in ascending order
* according to the keys.
*/
iterator
end() const _GLIBCXX_NOEXCEPT
{ return _M_t.end(); }
/**
* Returns a read-only (constant) reverse iterator that points to the
* last element in the %multiset. Iteration is done in descending order
* according to the keys.
*/
reverse_iterator
rbegin() const _GLIBCXX_NOEXCEPT
{ return _M_t.rbegin(); }
/**
* Returns a read-only (constant) reverse iterator that points to the
* last element in the %multiset. Iteration is done in descending order
* according to the keys.
*/
reverse_iterator
rend() const _GLIBCXX_NOEXCEPT
{ return _M_t.rend(); }
#if __cplusplus >= 201103L
/**
* Returns a read-only (constant) iterator that points to the first
* element in the %multiset. Iteration is done in ascending order
* according to the keys.
*/
iterator
cbegin() const noexcept
{ return _M_t.begin(); }
/**
* Returns a read-only (constant) iterator that points one past the last
* element in the %multiset. Iteration is done in ascending order
* according to the keys.
*/
iterator
cend() const noexcept
{ return _M_t.end(); }
/**
* Returns a read-only (constant) reverse iterator that points to the
* last element in the %multiset. Iteration is done in descending order
* according to the keys.
*/
reverse_iterator
crbegin() const noexcept
{ return _M_t.rbegin(); }
/**
* Returns a read-only (constant) reverse iterator that points to the
* last element in the %multiset. Iteration is done in descending order
* according to the keys.
*/
reverse_iterator
crend() const noexcept
{ return _M_t.rend(); }
#endif
/// Returns true if the %set is empty.
bool
empty() const _GLIBCXX_NOEXCEPT
{ return _M_t.empty(); }
/// Returns the size of the %set.
size_type
size() const _GLIBCXX_NOEXCEPT
{ return _M_t.size(); }
/// Returns the maximum size of the %set.
size_type
max_size() const _GLIBCXX_NOEXCEPT
{ return _M_t.max_size(); }
/**
* @brief Swaps data with another %multiset.
* @param __x A %multiset of the same element and allocator types.
*
* This exchanges the elements between two multisets in constant time.
* (It is only swapping a pointer, an integer, and an instance of the @c
* Compare type (which itself is often stateless and empty), so it should
* be quite fast.)
* Note that the global std::swap() function is specialized such that
* std::swap(s1,s2) will feed to this function.
*/
void
swap(multiset& __x)
{ _M_t.swap(__x._M_t); }
// insert/erase
#if __cplusplus >= 201103L
/**
* @brief Builds and inserts an element into the %multiset.
* @param __args Arguments used to generate the element instance to be
* inserted.
* @return An iterator that points to the inserted element.
*
* This function inserts an element into the %multiset. Contrary
* to a std::set the %multiset does not rely on unique keys and thus
* multiple copies of the same element can be inserted.
*
* Insertion requires logarithmic time.
*/
template<typename... _Args>
iterator
emplace(_Args&&... __args)
{ return _M_t._M_emplace_equal(std::forward<_Args>(__args)...); }
/**
* @brief Builds and inserts an element into the %multiset.
* @param __pos An iterator that serves as a hint as to where the
* element should be inserted.
* @param __args Arguments used to generate the element instance to be
* inserted.
* @return An iterator that points to the inserted element.
*
* This function inserts an element into the %multiset. Contrary
* to a std::set the %multiset does not rely on unique keys and thus
* multiple copies of the same element can be inserted.
*
* Note that the first parameter is only a hint and can potentially
* improve the performance of the insertion process. A bad hint would
* cause no gains in efficiency.
*
* See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html
* for more on @a hinting.
*
* Insertion requires logarithmic time (if the hint is not taken).
*/
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
return _M_t._M_emplace_hint_equal(__pos,
std::forward<_Args>(__args)...);
}
#endif
/**
* @brief Inserts an element into the %multiset.
* @param __x Element to be inserted.
* @return An iterator that points to the inserted element.
*
* This function inserts an element into the %multiset. Contrary
* to a std::set the %multiset does not rely on unique keys and thus
* multiple copies of the same element can be inserted.
*
* Insertion requires logarithmic time.
*/
iterator
insert(const value_type& __x)
{ return _M_t._M_insert_equal(__x); }
#if __cplusplus >= 201103L
iterator
insert(value_type&& __x)
{ return _M_t._M_insert_equal(std::move(__x)); }
#endif
/**
* @brief Inserts an element into the %multiset.
* @param __position An iterator that serves as a hint as to where the
* element should be inserted.
* @param __x Element to be inserted.
* @return An iterator that points to the inserted element.
*
* This function inserts an element into the %multiset. Contrary
* to a std::set the %multiset does not rely on unique keys and thus
* multiple copies of the same element can be inserted.
*
* Note that the first parameter is only a hint and can potentially
* improve the performance of the insertion process. A bad hint would
* cause no gains in efficiency.
*
* See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html
* for more on @a hinting.
*
* Insertion requires logarithmic time (if the hint is not taken).
*/
iterator
insert(const_iterator __position, const value_type& __x)
{ return _M_t._M_insert_equal_(__position, __x); }
#if __cplusplus >= 201103L
iterator
insert(const_iterator __position, value_type&& __x)
{ return _M_t._M_insert_equal_(__position, std::move(__x)); }
#endif
/**
* @brief A template function that tries to insert a range of elements.
* @param __first Iterator pointing to the start of the range to be
* inserted.
* @param __last Iterator pointing to the end of the range.
*
* Complexity similar to that of the range constructor.
*/
template<typename _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{ _M_t._M_insert_equal(__first, __last); }
#if __cplusplus >= 201103L
/**
* @brief Attempts to insert a list of elements into the %multiset.
* @param __l A std::initializer_list<value_type> of elements
* to be inserted.
*
* Complexity similar to that of the range constructor.
*/
void
insert(initializer_list<value_type> __l)
{ this->insert(__l.begin(), __l.end()); }
#endif
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 130. Associative erase should return an iterator.
/**
* @brief Erases an element from a %multiset.
* @param __position An iterator pointing to the element to be erased.
* @return An iterator pointing to the element immediately following
* @a position prior to the element being erased. If no such
* element exists, end() is returned.
*
* This function erases an element, pointed to by the given iterator,
* from a %multiset. Note that this function only erases the element,
* and that if the element is itself a pointer, the pointed-to memory is
* not touched in any way. Managing the pointer is the user's
* responsibility.
*/
_GLIBCXX_ABI_TAG_CXX11
iterator
erase(const_iterator __position)
{ return _M_t.erase(__position); }
#else
/**
* @brief Erases an element from a %multiset.
* @param __position An iterator pointing to the element to be erased.
*
* This function erases an element, pointed to by the given iterator,
* from a %multiset. Note that this function only erases the element,
* and that if the element is itself a pointer, the pointed-to memory is
* not touched in any way. Managing the pointer is the user's
* responsibility.
*/
void
erase(iterator __position)
{ _M_t.erase(__position); }
#endif
/**
* @brief Erases elements according to the provided key.
* @param __x Key of element to be erased.
* @return The number of elements erased.
*
* This function erases all elements located by the given key from a
* %multiset.
* Note that this function only erases the element, and that if
* the element is itself a pointer, the pointed-to memory is not touched
* in any way. Managing the pointer is the user's responsibility.
*/
size_type
erase(const key_type& __x)
{ return _M_t.erase(__x); }
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 130. Associative erase should return an iterator.
/**
* @brief Erases a [first,last) range of elements from a %multiset.
* @param __first Iterator pointing to the start of the range to be
* erased.
* @param __last Iterator pointing to the end of the range to
* be erased.
* @return The iterator @a last.
*
* This function erases a sequence of elements from a %multiset.
* Note that this function only erases the elements, and that if
* the elements themselves are pointers, the pointed-to memory is not
* touched in any way. Managing the pointer is the user's
* responsibility.
*/
_GLIBCXX_ABI_TAG_CXX11
iterator
erase(const_iterator __first, const_iterator __last)
{ return _M_t.erase(__first, __last); }
#else
/**
* @brief Erases a [first,last) range of elements from a %multiset.
* @param first Iterator pointing to the start of the range to be
* erased.
* @param last Iterator pointing to the end of the range to be erased.
*
* This function erases a sequence of elements from a %multiset.
* Note that this function only erases the elements, and that if
* the elements themselves are pointers, the pointed-to memory is not
* touched in any way. Managing the pointer is the user's
* responsibility.
*/
void
erase(iterator __first, iterator __last)
{ _M_t.erase(__first, __last); }
#endif
/**
* Erases all elements in a %multiset. Note that this function only
* erases the elements, and that if the elements themselves are pointers,
* the pointed-to memory is not touched in any way. Managing the pointer
* is the user's responsibility.
*/
void
clear() _GLIBCXX_NOEXCEPT
{ _M_t.clear(); }
// multiset operations:
/**
* @brief Finds the number of elements with given key.
* @param __x Key of elements to be located.
* @return Number of elements with specified key.
*/
size_type
count(const key_type& __x) const
{ return _M_t.count(__x); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
//@{
/**
* @brief Tries to locate an element in a %set.
* @param __x Element to be located.
* @return Iterator pointing to sought-after element, or end() if not
* found.
*
* This function takes a key and tries to locate the element with which
* the key matches. If successful the function returns an iterator
* pointing to the sought after element. If unsuccessful it returns the
* past-the-end ( @c end() ) iterator.
*/
iterator
find(const key_type& __x)
{ return _M_t.find(__x); }
const_iterator
find(const key_type& __x) const
{ return _M_t.find(__x); }
//@}
//@{
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param __x Key to be located.
* @return Iterator pointing to first element equal to or greater
* than key, or end().
*
* This function returns the first element of a subsequence of elements
* that matches the given key. If unsuccessful it returns an iterator
* pointing to the first element that has a greater value than given key
* or end() if no such element exists.
*/
iterator
lower_bound(const key_type& __x)
{ return _M_t.lower_bound(__x); }
const_iterator
lower_bound(const key_type& __x) const
{ return _M_t.lower_bound(__x); }
//@}
//@{
/**
* @brief Finds the end of a subsequence matching given key.
* @param __x Key to be located.
* @return Iterator pointing to the first element
* greater than key, or end().
*/
iterator
upper_bound(const key_type& __x)
{ return _M_t.upper_bound(__x); }
const_iterator
upper_bound(const key_type& __x) const
{ return _M_t.upper_bound(__x); }
//@}
//@{
/**
* @brief Finds a subsequence matching given key.
* @param __x Key to be located.
* @return Pair of iterators that possibly points to the subsequence
* matching given key.
*
* This function is equivalent to
* @code
* std::make_pair(c.lower_bound(val),
* c.upper_bound(val))
* @endcode
* (but is faster than making the calls separately).
*
* This function probably only makes sense for multisets.
*/
std::pair<iterator, iterator>
equal_range(const key_type& __x)
{ return _M_t.equal_range(__x); }
std::pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
//@}
template<typename _K1, typename _C1, typename _A1>
friend bool
operator==(const multiset<_K1, _C1, _A1>&,
const multiset<_K1, _C1, _A1>&);
template<typename _K1, typename _C1, typename _A1>
friend bool
operator< (const multiset<_K1, _C1, _A1>&,
const multiset<_K1, _C1, _A1>&);
};
/**
* @brief Multiset equality comparison.
* @param __x A %multiset.
* @param __y A %multiset of the same type as @a __x.
* @return True iff the size and elements of the multisets are equal.
*
* This is an equivalence relation. It is linear in the size of the
* multisets.
* Multisets are considered equivalent if their sizes are equal, and if
* corresponding elements compare equal.
*/
template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator==(const multiset<_Key, _Compare, _Alloc>& __x,
const multiset<_Key, _Compare, _Alloc>& __y)
{ return __x._M_t == __y._M_t; }
/**
* @brief Multiset ordering relation.
* @param __x A %multiset.
* @param __y A %multiset of the same type as @a __x.
* @return True iff @a __x is lexicographically less than @a __y.
*
* This is a total ordering relation. It is linear in the size of the
* maps. The elements must be comparable with @c <.
*
* See std::lexicographical_compare() for how the determination is made.
*/
template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator<(const multiset<_Key, _Compare, _Alloc>& __x,
const multiset<_Key, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Returns !(x == y).
template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator!=(const multiset<_Key, _Compare, _Alloc>& __x,
const multiset<_Key, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Returns y < x.
template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator>(const multiset<_Key,_Compare,_Alloc>& __x,
const multiset<_Key,_Compare,_Alloc>& __y)
{ return __y < __x; }
/// Returns !(y < x)
template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator<=(const multiset<_Key, _Compare, _Alloc>& __x,
const multiset<_Key, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Returns !(x < y)
template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator>=(const multiset<_Key, _Compare, _Alloc>& __x,
const multiset<_Key, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::multiset::swap().
template<typename _Key, typename _Compare, typename _Alloc>
inline void
swap(multiset<_Key, _Compare, _Alloc>& __x,
multiset<_Key, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
_GLIBCXX_END_NAMESPACE_CONTAINER
} // namespace std
#endif /* _STL_MULTISET_H */

View File

@@ -0,0 +1,387 @@
// Numeric functions implementation -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_numeric.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{numeric}
*/
#ifndef _STL_NUMERIC_H
#define _STL_NUMERIC_H 1
#include <bits/concept_check.h>
#include <debug/debug.h>
#include <bits/move.h> // For _GLIBCXX_MOVE
#if __cplusplus >= 201103L
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Create a range of sequentially increasing values.
*
* For each element in the range @p [first,last) assigns @p value and
* increments @p value as if by @p ++value.
*
* @param __first Start of range.
* @param __last End of range.
* @param __value Starting value.
* @return Nothing.
*/
template<typename _ForwardIterator, typename _Tp>
void
iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
{
// concept requirements
__glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
_ForwardIterator>)
__glibcxx_function_requires(_ConvertibleConcept<_Tp,
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
{
*__first = __value;
++__value;
}
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_ALGO
/**
* @brief Accumulate values in a range.
*
* Accumulates the values in the range [first,last) using operator+(). The
* initial value is @a init. The values are processed in order.
*
* @param __first Start of range.
* @param __last End of range.
* @param __init Starting value to add other values to.
* @return The final sum.
*/
template<typename _InputIterator, typename _Tp>
inline _Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__init = __init + *__first;
return __init;
}
/**
* @brief Accumulate values in a range with operation.
*
* Accumulates the values in the range [first,last) using the function
* object @p __binary_op. The initial value is @p __init. The values are
* processed in order.
*
* @param __first Start of range.
* @param __last End of range.
* @param __init Starting value to add other values to.
* @param __binary_op Function object to accumulate with.
* @return The final sum.
*/
template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
inline _Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
_BinaryOperation __binary_op)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__init = __binary_op(__init, *__first);
return __init;
}
/**
* @brief Compute inner product of two ranges.
*
* Starting with an initial value of @p __init, multiplies successive
* elements from the two ranges and adds each product into the accumulated
* value using operator+(). The values in the ranges are processed in
* order.
*
* @param __first1 Start of range 1.
* @param __last1 End of range 1.
* @param __first2 Start of range 2.
* @param __init Starting value to add other values to.
* @return The final inner product.
*/
template<typename _InputIterator1, typename _InputIterator2, typename _Tp>
inline _Tp
inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _Tp __init)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_requires_valid_range(__first1, __last1);
for (; __first1 != __last1; ++__first1, ++__first2)
__init = __init + (*__first1 * *__first2);
return __init;
}
/**
* @brief Compute inner product of two ranges.
*
* Starting with an initial value of @p __init, applies @p __binary_op2 to
* successive elements from the two ranges and accumulates each result into
* the accumulated value using @p __binary_op1. The values in the ranges are
* processed in order.
*
* @param __first1 Start of range 1.
* @param __last1 End of range 1.
* @param __first2 Start of range 2.
* @param __init Starting value to add other values to.
* @param __binary_op1 Function object to accumulate with.
* @param __binary_op2 Function object to apply to pairs of input values.
* @return The final inner product.
*/
template<typename _InputIterator1, typename _InputIterator2, typename _Tp,
typename _BinaryOperation1, typename _BinaryOperation2>
inline _Tp
inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _Tp __init,
_BinaryOperation1 __binary_op1,
_BinaryOperation2 __binary_op2)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_requires_valid_range(__first1, __last1);
for (; __first1 != __last1; ++__first1, ++__first2)
__init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
return __init;
}
/**
* @brief Return list of partial sums
*
* Accumulates the values in the range [first,last) using the @c + operator.
* As each successive input value is added into the total, that partial sum
* is written to @p __result. Therefore, the first value in @p __result is
* the first value of the input, the second value in @p __result is the sum
* of the first and second input values, and so on.
*
* @param __first Start of input range.
* @param __last End of input range.
* @param __result Output sum.
* @return Iterator pointing just beyond the values written to __result.
*/
template<typename _InputIterator, typename _OutputIterator>
_OutputIterator
partial_sum(_InputIterator __first, _InputIterator __last,
_OutputIterator __result)
{
typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
if (__first == __last)
return __result;
_ValueType __value = *__first;
*__result = __value;
while (++__first != __last)
{
__value = __value + *__first;
*++__result = __value;
}
return ++__result;
}
/**
* @brief Return list of partial sums
*
* Accumulates the values in the range [first,last) using @p __binary_op.
* As each successive input value is added into the total, that partial sum
* is written to @p __result. Therefore, the first value in @p __result is
* the first value of the input, the second value in @p __result is the sum
* of the first and second input values, and so on.
*
* @param __first Start of input range.
* @param __last End of input range.
* @param __result Output sum.
* @param __binary_op Function object.
* @return Iterator pointing just beyond the values written to __result.
*/
template<typename _InputIterator, typename _OutputIterator,
typename _BinaryOperation>
_OutputIterator
partial_sum(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryOperation __binary_op)
{
typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
if (__first == __last)
return __result;
_ValueType __value = *__first;
*__result = __value;
while (++__first != __last)
{
__value = __binary_op(__value, *__first);
*++__result = __value;
}
return ++__result;
}
/**
* @brief Return differences between adjacent values.
*
* Computes the difference between adjacent values in the range
* [first,last) using operator-() and writes the result to @p __result.
*
* @param __first Start of input range.
* @param __last End of input range.
* @param __result Output sums.
* @return Iterator pointing just beyond the values written to result.
*
* _GLIBCXX_RESOLVE_LIB_DEFECTS
* DR 539. partial_sum and adjacent_difference should mention requirements
*/
template<typename _InputIterator, typename _OutputIterator>
_OutputIterator
adjacent_difference(_InputIterator __first,
_InputIterator __last, _OutputIterator __result)
{
typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
if (__first == __last)
return __result;
_ValueType __value = *__first;
*__result = __value;
while (++__first != __last)
{
_ValueType __tmp = *__first;
*++__result = __tmp - __value;
__value = _GLIBCXX_MOVE(__tmp);
}
return ++__result;
}
/**
* @brief Return differences between adjacent values.
*
* Computes the difference between adjacent values in the range
* [__first,__last) using the function object @p __binary_op and writes the
* result to @p __result.
*
* @param __first Start of input range.
* @param __last End of input range.
* @param __result Output sum.
* @param __binary_op Function object.
* @return Iterator pointing just beyond the values written to result.
*
* _GLIBCXX_RESOLVE_LIB_DEFECTS
* DR 539. partial_sum and adjacent_difference should mention requirements
*/
template<typename _InputIterator, typename _OutputIterator,
typename _BinaryOperation>
_OutputIterator
adjacent_difference(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryOperation __binary_op)
{
typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
if (__first == __last)
return __result;
_ValueType __value = *__first;
*__result = __value;
while (++__first != __last)
{
_ValueType __tmp = *__first;
*++__result = __binary_op(__tmp, __value);
__value = _GLIBCXX_MOVE(__tmp);
}
return ++__result;
}
_GLIBCXX_END_NAMESPACE_ALGO
} // namespace std
#endif /* _STL_NUMERIC_H */

View File

@@ -0,0 +1,295 @@
// Pair implementation -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_pair.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{utility}
*/
#ifndef _STL_PAIR_H
#define _STL_PAIR_H 1
#include <bits/move.h> // for std::move / std::forward, and std::swap
#if __cplusplus >= 201103L
#include <type_traits> // for std::__decay_and_strip too
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup utilities
* @{
*/
#if __cplusplus >= 201103L
/// piecewise_construct_t
struct piecewise_construct_t { };
/// piecewise_construct
constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
// Forward declarations.
template<typename...>
class tuple;
template<std::size_t...>
struct _Index_tuple;
#endif
/**
* @brief Struct holding two objects of arbitrary type.
*
* @tparam _T1 Type of first object.
* @tparam _T2 Type of second object.
*/
template<class _T1, class _T2>
struct pair
{
typedef _T1 first_type; /// @c first_type is the first bound type
typedef _T2 second_type; /// @c second_type is the second bound type
_T1 first; /// @c first is a copy of the first object
_T2 second; /// @c second is a copy of the second object
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 265. std::pair::pair() effects overly restrictive
/** The default constructor creates @c first and @c second using their
* respective default constructors. */
_GLIBCXX_CONSTEXPR pair()
: first(), second() { }
/** Two objects may be passed to a @c pair constructor to be copied. */
_GLIBCXX_CONSTEXPR pair(const _T1& __a, const _T2& __b)
: first(__a), second(__b) { }
/** There is also a templated copy ctor for the @c pair class itself. */
#if __cplusplus < 201103L
template<class _U1, class _U2>
pair(const pair<_U1, _U2>& __p)
: first(__p.first), second(__p.second) { }
#else
template<class _U1, class _U2, class = typename
enable_if<__and_<is_convertible<const _U1&, _T1>,
is_convertible<const _U2&, _T2>>::value>::type>
constexpr pair(const pair<_U1, _U2>& __p)
: first(__p.first), second(__p.second) { }
constexpr pair(const pair&) = default;
constexpr pair(pair&&) = default;
// DR 811.
template<class _U1, class = typename
enable_if<is_convertible<_U1, _T1>::value>::type>
constexpr pair(_U1&& __x, const _T2& __y)
: first(std::forward<_U1>(__x)), second(__y) { }
template<class _U2, class = typename
enable_if<is_convertible<_U2, _T2>::value>::type>
constexpr pair(const _T1& __x, _U2&& __y)
: first(__x), second(std::forward<_U2>(__y)) { }
template<class _U1, class _U2, class = typename
enable_if<__and_<is_convertible<_U1, _T1>,
is_convertible<_U2, _T2>>::value>::type>
constexpr pair(_U1&& __x, _U2&& __y)
: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
template<class _U1, class _U2, class = typename
enable_if<__and_<is_convertible<_U1, _T1>,
is_convertible<_U2, _T2>>::value>::type>
constexpr pair(pair<_U1, _U2>&& __p)
: first(std::forward<_U1>(__p.first)),
second(std::forward<_U2>(__p.second)) { }
template<typename... _Args1, typename... _Args2>
pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
pair&
operator=(const pair& __p)
{
first = __p.first;
second = __p.second;
return *this;
}
pair&
operator=(pair&& __p)
noexcept(__and_<is_nothrow_move_assignable<_T1>,
is_nothrow_move_assignable<_T2>>::value)
{
first = std::forward<first_type>(__p.first);
second = std::forward<second_type>(__p.second);
return *this;
}
template<class _U1, class _U2>
pair&
operator=(const pair<_U1, _U2>& __p)
{
first = __p.first;
second = __p.second;
return *this;
}
template<class _U1, class _U2>
pair&
operator=(pair<_U1, _U2>&& __p)
{
first = std::forward<_U1>(__p.first);
second = std::forward<_U2>(__p.second);
return *this;
}
void
swap(pair& __p)
noexcept(noexcept(swap(first, __p.first))
&& noexcept(swap(second, __p.second)))
{
using std::swap;
swap(first, __p.first);
swap(second, __p.second);
}
private:
template<typename... _Args1, std::size_t... _Indexes1,
typename... _Args2, std::size_t... _Indexes2>
pair(tuple<_Args1...>&, tuple<_Args2...>&,
_Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
#endif
};
/// Two pairs of the same type are equal iff their members are equal.
template<class _T1, class _T2>
inline _GLIBCXX_CONSTEXPR bool
operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{ return __x.first == __y.first && __x.second == __y.second; }
/// <http://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
template<class _T1, class _T2>
inline _GLIBCXX_CONSTEXPR bool
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{ return __x.first < __y.first
|| (!(__y.first < __x.first) && __x.second < __y.second); }
/// Uses @c operator== to find the result.
template<class _T1, class _T2>
inline _GLIBCXX_CONSTEXPR bool
operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{ return !(__x == __y); }
/// Uses @c operator< to find the result.
template<class _T1, class _T2>
inline _GLIBCXX_CONSTEXPR bool
operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{ return __y < __x; }
/// Uses @c operator< to find the result.
template<class _T1, class _T2>
inline _GLIBCXX_CONSTEXPR bool
operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{ return !(__y < __x); }
/// Uses @c operator< to find the result.
template<class _T1, class _T2>
inline _GLIBCXX_CONSTEXPR bool
operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{ return !(__x < __y); }
#if __cplusplus >= 201103L
/// See std::pair::swap().
// Note: no std::swap overloads in C++03 mode, this has performance
// implications, see, eg, libstdc++/38466.
template<class _T1, class _T2>
inline void
swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
noexcept(noexcept(__x.swap(__y)))
{ __x.swap(__y); }
#endif
/**
* @brief A convenience wrapper for creating a pair from two objects.
* @param __x The first object.
* @param __y The second object.
* @return A newly-constructed pair<> object of the appropriate type.
*
* The standard requires that the objects be passed by reference-to-const,
* but LWG issue #181 says they should be passed by const value. We follow
* the LWG by default.
*/
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 181. make_pair() unintended behavior
#if __cplusplus >= 201103L
// NB: DR 706.
template<class _T1, class _T2>
constexpr pair<typename __decay_and_strip<_T1>::__type,
typename __decay_and_strip<_T2>::__type>
make_pair(_T1&& __x, _T2&& __y)
{
typedef typename __decay_and_strip<_T1>::__type __ds_type1;
typedef typename __decay_and_strip<_T2>::__type __ds_type2;
typedef pair<__ds_type1, __ds_type2> __pair_type;
return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
}
#else
template<class _T1, class _T2>
inline pair<_T1, _T2>
make_pair(_T1 __x, _T2 __y)
{ return pair<_T1, _T2>(__x, __y); }
#endif
/// @}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif /* _STL_PAIR_H */

View File

@@ -0,0 +1,569 @@
// Queue implementation -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_queue.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{queue}
*/
#ifndef _STL_QUEUE_H
#define _STL_QUEUE_H 1
#include <bits/concept_check.h>
#include <debug/debug.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief A standard container giving FIFO behavior.
*
* @ingroup sequences
*
* @tparam _Tp Type of element.
* @tparam _Sequence Type of underlying sequence, defaults to deque<_Tp>.
*
* Meets many of the requirements of a
* <a href="tables.html#65">container</a>,
* but does not define anything to do with iterators. Very few of the
* other standard container interfaces are defined.
*
* This is not a true container, but an @e adaptor. It holds another
* container, and provides a wrapper interface to that container. The
* wrapper is what enforces strict first-in-first-out %queue behavior.
*
* The second template parameter defines the type of the underlying
* sequence/container. It defaults to std::deque, but it can be any type
* that supports @c front, @c back, @c push_back, and @c pop_front,
* such as std::list or an appropriate user-defined type.
*
* Members not found in @a normal containers are @c container_type,
* which is a typedef for the second Sequence parameter, and @c push and
* @c pop, which are standard %queue/FIFO operations.
*/
template<typename _Tp, typename _Sequence = deque<_Tp> >
class queue
{
// concept requirements
typedef typename _Sequence::value_type _Sequence_value_type;
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
__glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept)
__glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)
__glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
template<typename _Tp1, typename _Seq1>
friend bool
operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
template<typename _Tp1, typename _Seq1>
friend bool
operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
public:
typedef typename _Sequence::value_type value_type;
typedef typename _Sequence::reference reference;
typedef typename _Sequence::const_reference const_reference;
typedef typename _Sequence::size_type size_type;
typedef _Sequence container_type;
protected:
/**
* 'c' is the underlying container. Maintainers wondering why
* this isn't uglified as per style guidelines should note that
* this name is specified in the standard, [23.2.3.1]. (Why?
* Presumably for the same reason that it's protected instead
* of private: to allow derivation. But none of the other
* containers allow for derivation. Odd.)
*/
_Sequence c;
public:
/**
* @brief Default constructor creates no elements.
*/
#if __cplusplus < 201103L
explicit
queue(const _Sequence& __c = _Sequence())
: c(__c) { }
#else
explicit
queue(const _Sequence& __c)
: c(__c) { }
explicit
queue(_Sequence&& __c = _Sequence())
: c(std::move(__c)) { }
#endif
/**
* Returns true if the %queue is empty.
*/
bool
empty() const
{ return c.empty(); }
/** Returns the number of elements in the %queue. */
size_type
size() const
{ return c.size(); }
/**
* Returns a read/write reference to the data at the first
* element of the %queue.
*/
reference
front()
{
__glibcxx_requires_nonempty();
return c.front();
}
/**
* Returns a read-only (constant) reference to the data at the first
* element of the %queue.
*/
const_reference
front() const
{
__glibcxx_requires_nonempty();
return c.front();
}
/**
* Returns a read/write reference to the data at the last
* element of the %queue.
*/
reference
back()
{
__glibcxx_requires_nonempty();
return c.back();
}
/**
* Returns a read-only (constant) reference to the data at the last
* element of the %queue.
*/
const_reference
back() const
{
__glibcxx_requires_nonempty();
return c.back();
}
/**
* @brief Add data to the end of the %queue.
* @param __x Data to be added.
*
* This is a typical %queue operation. The function creates an
* element at the end of the %queue and assigns the given data
* to it. The time complexity of the operation depends on the
* underlying sequence.
*/
void
push(const value_type& __x)
{ c.push_back(__x); }
#if __cplusplus >= 201103L
void
push(value_type&& __x)
{ c.push_back(std::move(__x)); }
template<typename... _Args>
void
emplace(_Args&&... __args)
{ c.emplace_back(std::forward<_Args>(__args)...); }
#endif
/**
* @brief Removes first element.
*
* This is a typical %queue operation. It shrinks the %queue by one.
* The time complexity of the operation depends on the underlying
* sequence.
*
* Note that no data is returned, and if the first element's
* data is needed, it should be retrieved before pop() is
* called.
*/
void
pop()
{
__glibcxx_requires_nonempty();
c.pop_front();
}
#if __cplusplus >= 201103L
void
swap(queue& __q)
noexcept(noexcept(swap(c, __q.c)))
{
using std::swap;
swap(c, __q.c);
}
#endif
};
/**
* @brief Queue equality comparison.
* @param __x A %queue.
* @param __y A %queue of the same type as @a __x.
* @return True iff the size and elements of the queues are equal.
*
* This is an equivalence relation. Complexity and semantics depend on the
* underlying sequence type, but the expected rules are: this relation is
* linear in the size of the sequences, and queues are considered equivalent
* if their sequences compare equal.
*/
template<typename _Tp, typename _Seq>
inline bool
operator==(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
{ return __x.c == __y.c; }
/**
* @brief Queue ordering relation.
* @param __x A %queue.
* @param __y A %queue of the same type as @a x.
* @return True iff @a __x is lexicographically less than @a __y.
*
* This is an total ordering relation. Complexity and semantics
* depend on the underlying sequence type, but the expected rules
* are: this relation is linear in the size of the sequences, the
* elements must be comparable with @c <, and
* std::lexicographical_compare() is usually used to make the
* determination.
*/
template<typename _Tp, typename _Seq>
inline bool
operator<(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
{ return __x.c < __y.c; }
/// Based on operator==
template<typename _Tp, typename _Seq>
inline bool
operator!=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
{ return !(__x == __y); }
/// Based on operator<
template<typename _Tp, typename _Seq>
inline bool
operator>(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
{ return __y < __x; }
/// Based on operator<
template<typename _Tp, typename _Seq>
inline bool
operator<=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
{ return !(__y < __x); }
/// Based on operator<
template<typename _Tp, typename _Seq>
inline bool
operator>=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y)
{ return !(__x < __y); }
#if __cplusplus >= 201103L
template<typename _Tp, typename _Seq>
inline void
swap(queue<_Tp, _Seq>& __x, queue<_Tp, _Seq>& __y)
noexcept(noexcept(__x.swap(__y)))
{ __x.swap(__y); }
template<typename _Tp, typename _Seq, typename _Alloc>
struct uses_allocator<queue<_Tp, _Seq>, _Alloc>
: public uses_allocator<_Seq, _Alloc>::type { };
#endif
/**
* @brief A standard container automatically sorting its contents.
*
* @ingroup sequences
*
* @tparam _Tp Type of element.
* @tparam _Sequence Type of underlying sequence, defaults to vector<_Tp>.
* @tparam _Compare Comparison function object type, defaults to
* less<_Sequence::value_type>.
*
* This is not a true container, but an @e adaptor. It holds
* another container, and provides a wrapper interface to that
* container. The wrapper is what enforces priority-based sorting
* and %queue behavior. Very few of the standard container/sequence
* interface requirements are met (e.g., iterators).
*
* The second template parameter defines the type of the underlying
* sequence/container. It defaults to std::vector, but it can be
* any type that supports @c front(), @c push_back, @c pop_back,
* and random-access iterators, such as std::deque or an
* appropriate user-defined type.
*
* The third template parameter supplies the means of making
* priority comparisons. It defaults to @c less<value_type> but
* can be anything defining a strict weak ordering.
*
* Members not found in @a normal containers are @c container_type,
* which is a typedef for the second Sequence parameter, and @c
* push, @c pop, and @c top, which are standard %queue operations.
*
* @note No equality/comparison operators are provided for
* %priority_queue.
*
* @note Sorting of the elements takes place as they are added to,
* and removed from, the %priority_queue using the
* %priority_queue's member functions. If you access the elements
* by other means, and change their data such that the sorting
* order would be different, the %priority_queue will not re-sort
* the elements for you. (How could it know to do so?)
*/
template<typename _Tp, typename _Sequence = vector<_Tp>,
typename _Compare = less<typename _Sequence::value_type> >
class priority_queue
{
// concept requirements
typedef typename _Sequence::value_type _Sequence_value_type;
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
__glibcxx_class_requires(_Sequence, _SequenceConcept)
__glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept)
__glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
__glibcxx_class_requires4(_Compare, bool, _Tp, _Tp,
_BinaryFunctionConcept)
public:
typedef typename _Sequence::value_type value_type;
typedef typename _Sequence::reference reference;
typedef typename _Sequence::const_reference const_reference;
typedef typename _Sequence::size_type size_type;
typedef _Sequence container_type;
protected:
// See queue::c for notes on these names.
_Sequence c;
_Compare comp;
public:
/**
* @brief Default constructor creates no elements.
*/
#if __cplusplus < 201103L
explicit
priority_queue(const _Compare& __x = _Compare(),
const _Sequence& __s = _Sequence())
: c(__s), comp(__x)
{ std::make_heap(c.begin(), c.end(), comp); }
#else
explicit
priority_queue(const _Compare& __x,
const _Sequence& __s)
: c(__s), comp(__x)
{ std::make_heap(c.begin(), c.end(), comp); }
explicit
priority_queue(const _Compare& __x = _Compare(),
_Sequence&& __s = _Sequence())
: c(std::move(__s)), comp(__x)
{ std::make_heap(c.begin(), c.end(), comp); }
#endif
/**
* @brief Builds a %queue from a range.
* @param __first An input iterator.
* @param __last An input iterator.
* @param __x A comparison functor describing a strict weak ordering.
* @param __s An initial sequence with which to start.
*
* Begins by copying @a __s, inserting a copy of the elements
* from @a [first,last) into the copy of @a __s, then ordering
* the copy according to @a __x.
*
* For more information on function objects, see the
* documentation on @link functors functor base
* classes@endlink.
*/
#if __cplusplus < 201103L
template<typename _InputIterator>
priority_queue(_InputIterator __first, _InputIterator __last,
const _Compare& __x = _Compare(),
const _Sequence& __s = _Sequence())
: c(__s), comp(__x)
{
__glibcxx_requires_valid_range(__first, __last);
c.insert(c.end(), __first, __last);
std::make_heap(c.begin(), c.end(), comp);
}
#else
template<typename _InputIterator>
priority_queue(_InputIterator __first, _InputIterator __last,
const _Compare& __x,
const _Sequence& __s)
: c(__s), comp(__x)
{
__glibcxx_requires_valid_range(__first, __last);
c.insert(c.end(), __first, __last);
std::make_heap(c.begin(), c.end(), comp);
}
template<typename _InputIterator>
priority_queue(_InputIterator __first, _InputIterator __last,
const _Compare& __x = _Compare(),
_Sequence&& __s = _Sequence())
: c(std::move(__s)), comp(__x)
{
__glibcxx_requires_valid_range(__first, __last);
c.insert(c.end(), __first, __last);
std::make_heap(c.begin(), c.end(), comp);
}
#endif
/**
* Returns true if the %queue is empty.
*/
bool
empty() const
{ return c.empty(); }
/** Returns the number of elements in the %queue. */
size_type
size() const
{ return c.size(); }
/**
* Returns a read-only (constant) reference to the data at the first
* element of the %queue.
*/
const_reference
top() const
{
__glibcxx_requires_nonempty();
return c.front();
}
/**
* @brief Add data to the %queue.
* @param __x Data to be added.
*
* This is a typical %queue operation.
* The time complexity of the operation depends on the underlying
* sequence.
*/
void
push(const value_type& __x)
{
c.push_back(__x);
std::push_heap(c.begin(), c.end(), comp);
}
#if __cplusplus >= 201103L
void
push(value_type&& __x)
{
c.push_back(std::move(__x));
std::push_heap(c.begin(), c.end(), comp);
}
template<typename... _Args>
void
emplace(_Args&&... __args)
{
c.emplace_back(std::forward<_Args>(__args)...);
std::push_heap(c.begin(), c.end(), comp);
}
#endif
/**
* @brief Removes first element.
*
* This is a typical %queue operation. It shrinks the %queue
* by one. The time complexity of the operation depends on the
* underlying sequence.
*
* Note that no data is returned, and if the first element's
* data is needed, it should be retrieved before pop() is
* called.
*/
void
pop()
{
__glibcxx_requires_nonempty();
std::pop_heap(c.begin(), c.end(), comp);
c.pop_back();
}
#if __cplusplus >= 201103L
void
swap(priority_queue& __pq)
noexcept(noexcept(swap(c, __pq.c)) && noexcept(swap(comp, __pq.comp)))
{
using std::swap;
swap(c, __pq.c);
swap(comp, __pq.comp);
}
#endif
};
// No equality/comparison operators are provided for priority_queue.
#if __cplusplus >= 201103L
template<typename _Tp, typename _Sequence, typename _Compare>
inline void
swap(priority_queue<_Tp, _Sequence, _Compare>& __x,
priority_queue<_Tp, _Sequence, _Compare>& __y)
noexcept(noexcept(__x.swap(__y)))
{ __x.swap(__y); }
template<typename _Tp, typename _Sequence, typename _Compare,
typename _Alloc>
struct uses_allocator<priority_queue<_Tp, _Sequence, _Compare>, _Alloc>
: public uses_allocator<_Sequence, _Alloc>::type { };
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _STL_QUEUE_H */

View File

@@ -0,0 +1,108 @@
// -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_raw_storage_iter.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _STL_RAW_STORAGE_ITERATOR_H
#define _STL_RAW_STORAGE_ITERATOR_H 1
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* This iterator class lets algorithms store their results into
* uninitialized memory.
*/
template <class _OutputIterator, class _Tp>
class raw_storage_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
protected:
_OutputIterator _M_iter;
public:
explicit
raw_storage_iterator(_OutputIterator __x)
: _M_iter(__x) {}
raw_storage_iterator&
operator*() { return *this; }
raw_storage_iterator&
operator=(const _Tp& __element)
{
std::_Construct(std::__addressof(*_M_iter), __element);
return *this;
}
raw_storage_iterator<_OutputIterator, _Tp>&
operator++()
{
++_M_iter;
return *this;
}
raw_storage_iterator<_OutputIterator, _Tp>
operator++(int)
{
raw_storage_iterator<_OutputIterator, _Tp> __tmp = *this;
++_M_iter;
return __tmp;
}
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@@ -0,0 +1,134 @@
// std::rel_ops implementation -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the, 2009 Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* Copyright (c) 1996,1997
* Silicon Graphics
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*/
/** @file bits/stl_relops.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{utility}
*
* Inclusion of this file has been removed from
* all of the other STL headers for safety reasons, except std_utility.h.
* For more information, see the thread of about twenty messages starting
* with http://gcc.gnu.org/ml/libstdc++/2001-01/msg00223.html, or
* http://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.ambiguous_overloads
*
* Short summary: the rel_ops operators should be avoided for the present.
*/
#ifndef _STL_RELOPS_H
#define _STL_RELOPS_H 1
namespace std _GLIBCXX_VISIBILITY(default)
{
namespace rel_ops
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/** @namespace std::rel_ops
* @brief The generated relational operators are sequestered here.
*/
/**
* @brief Defines @c != for arbitrary types, in terms of @c ==.
* @param __x A thing.
* @param __y Another thing.
* @return __x != __y
*
* This function uses @c == to determine its result.
*/
template <class _Tp>
inline bool
operator!=(const _Tp& __x, const _Tp& __y)
{ return !(__x == __y); }
/**
* @brief Defines @c > for arbitrary types, in terms of @c <.
* @param __x A thing.
* @param __y Another thing.
* @return __x > __y
*
* This function uses @c < to determine its result.
*/
template <class _Tp>
inline bool
operator>(const _Tp& __x, const _Tp& __y)
{ return __y < __x; }
/**
* @brief Defines @c <= for arbitrary types, in terms of @c <.
* @param __x A thing.
* @param __y Another thing.
* @return __x <= __y
*
* This function uses @c < to determine its result.
*/
template <class _Tp>
inline bool
operator<=(const _Tp& __x, const _Tp& __y)
{ return !(__y < __x); }
/**
* @brief Defines @c >= for arbitrary types, in terms of @c <.
* @param __x A thing.
* @param __y Another thing.
* @return __x >= __y
*
* This function uses @c < to determine its result.
*/
template <class _Tp>
inline bool
operator>=(const _Tp& __x, const _Tp& __y)
{ return !(__x < __y); }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace rel_ops
} // namespace std
#endif /* _STL_RELOPS_H */

View File

@@ -0,0 +1,811 @@
// Set implementation -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_set.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{set}
*/
#ifndef _STL_SET_H
#define _STL_SET_H 1
#include <bits/concept_check.h>
#if __cplusplus >= 201103L
#include <initializer_list>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/**
* @brief A standard container made up of unique keys, which can be
* retrieved in logarithmic time.
*
* @ingroup associative_containers
*
* @tparam _Key Type of key objects.
* @tparam _Compare Comparison function object type, defaults to less<_Key>.
* @tparam _Alloc Allocator type, defaults to allocator<_Key>.
*
* Meets the requirements of a <a href="tables.html#65">container</a>, a
* <a href="tables.html#66">reversible container</a>, and an
* <a href="tables.html#69">associative container</a> (using unique keys).
*
* Sets support bidirectional iterators.
*
* The private tree data is declared exactly the same way for set and
* multiset; the distinction is made entirely in how the tree functions are
* called (*_unique versus *_equal, same as the standard).
*/
template<typename _Key, typename _Compare = std::less<_Key>,
typename _Alloc = std::allocator<_Key> >
class set
{
// concept requirements
typedef typename _Alloc::value_type _Alloc_value_type;
__glibcxx_class_requires(_Key, _SGIAssignableConcept)
__glibcxx_class_requires4(_Compare, bool, _Key, _Key,
_BinaryFunctionConcept)
__glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept)
public:
// typedefs:
//@{
/// Public typedefs.
typedef _Key key_type;
typedef _Key value_type;
typedef _Compare key_compare;
typedef _Compare value_compare;
typedef _Alloc allocator_type;
//@}
private:
typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type;
typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
key_compare, _Key_alloc_type> _Rep_type;
_Rep_type _M_t; // Red-black tree representing set.
public:
//@{
/// Iterator-related typedefs.
typedef typename _Key_alloc_type::pointer pointer;
typedef typename _Key_alloc_type::const_pointer const_pointer;
typedef typename _Key_alloc_type::reference reference;
typedef typename _Key_alloc_type::const_reference const_reference;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 103. set::iterator is required to be modifiable,
// but this allows modification of keys.
typedef typename _Rep_type::const_iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
typedef typename _Rep_type::size_type size_type;
typedef typename _Rep_type::difference_type difference_type;
//@}
// allocation/deallocation
/**
* @brief Default constructor creates no elements.
*/
set()
: _M_t() { }
/**
* @brief Creates a %set with no elements.
* @param __comp Comparator to use.
* @param __a An allocator object.
*/
explicit
set(const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Key_alloc_type(__a)) { }
/**
* @brief Builds a %set from a range.
* @param __first An input iterator.
* @param __last An input iterator.
*
* Create a %set consisting of copies of the elements from
* [__first,__last). This is linear in N if the range is
* already sorted, and NlogN otherwise (where N is
* distance(__first,__last)).
*/
template<typename _InputIterator>
set(_InputIterator __first, _InputIterator __last)
: _M_t()
{ _M_t._M_insert_unique(__first, __last); }
/**
* @brief Builds a %set from a range.
* @param __first An input iterator.
* @param __last An input iterator.
* @param __comp A comparison functor.
* @param __a An allocator object.
*
* Create a %set consisting of copies of the elements from
* [__first,__last). This is linear in N if the range is
* already sorted, and NlogN otherwise (where N is
* distance(__first,__last)).
*/
template<typename _InputIterator>
set(_InputIterator __first, _InputIterator __last,
const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Key_alloc_type(__a))
{ _M_t._M_insert_unique(__first, __last); }
/**
* @brief %Set copy constructor.
* @param __x A %set of identical element and allocator types.
*
* The newly-created %set uses a copy of the allocation object used
* by @a __x.
*/
set(const set& __x)
: _M_t(__x._M_t) { }
#if __cplusplus >= 201103L
/**
* @brief %Set move constructor
* @param __x A %set of identical element and allocator types.
*
* The newly-created %set contains the exact contents of @a x.
* The contents of @a x are a valid, but unspecified %set.
*/
set(set&& __x)
noexcept(is_nothrow_copy_constructible<_Compare>::value)
: _M_t(std::move(__x._M_t)) { }
/**
* @brief Builds a %set from an initializer_list.
* @param __l An initializer_list.
* @param __comp A comparison functor.
* @param __a An allocator object.
*
* Create a %set consisting of copies of the elements in the list.
* This is linear in N if the list is already sorted, and NlogN
* otherwise (where N is @a __l.size()).
*/
set(initializer_list<value_type> __l,
const _Compare& __comp = _Compare(),
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Key_alloc_type(__a))
{ _M_t._M_insert_unique(__l.begin(), __l.end()); }
#endif
/**
* @brief %Set assignment operator.
* @param __x A %set of identical element and allocator types.
*
* All the elements of @a __x are copied, but unlike the copy
* constructor, the allocator object is not copied.
*/
set&
operator=(const set& __x)
{
_M_t = __x._M_t;
return *this;
}
#if __cplusplus >= 201103L
/**
* @brief %Set move assignment operator.
* @param __x A %set of identical element and allocator types.
*
* The contents of @a __x are moved into this %set (without copying).
* @a __x is a valid, but unspecified %set.
*/
set&
operator=(set&& __x)
{
// NB: DR 1204.
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
/**
* @brief %Set list assignment operator.
* @param __l An initializer_list.
*
* This function fills a %set with copies of the elements in the
* initializer list @a __l.
*
* Note that the assignment completely changes the %set and
* that the resulting %set's size is the same as the number
* of elements assigned. Old data may be lost.
*/
set&
operator=(initializer_list<value_type> __l)
{
this->clear();
this->insert(__l.begin(), __l.end());
return *this;
}
#endif
// accessors:
/// Returns the comparison object with which the %set was constructed.
key_compare
key_comp() const
{ return _M_t.key_comp(); }
/// Returns the comparison object with which the %set was constructed.
value_compare
value_comp() const
{ return _M_t.key_comp(); }
/// Returns the allocator object with which the %set was constructed.
allocator_type
get_allocator() const _GLIBCXX_NOEXCEPT
{ return allocator_type(_M_t.get_allocator()); }
/**
* Returns a read-only (constant) iterator that points to the first
* element in the %set. Iteration is done in ascending order according
* to the keys.
*/
iterator
begin() const _GLIBCXX_NOEXCEPT
{ return _M_t.begin(); }
/**
* Returns a read-only (constant) iterator that points one past the last
* element in the %set. Iteration is done in ascending order according
* to the keys.
*/
iterator
end() const _GLIBCXX_NOEXCEPT
{ return _M_t.end(); }
/**
* Returns a read-only (constant) iterator that points to the last
* element in the %set. Iteration is done in descending order according
* to the keys.
*/
reverse_iterator
rbegin() const _GLIBCXX_NOEXCEPT
{ return _M_t.rbegin(); }
/**
* Returns a read-only (constant) reverse iterator that points to the
* last pair in the %set. Iteration is done in descending order
* according to the keys.
*/
reverse_iterator
rend() const _GLIBCXX_NOEXCEPT
{ return _M_t.rend(); }
#if __cplusplus >= 201103L
/**
* Returns a read-only (constant) iterator that points to the first
* element in the %set. Iteration is done in ascending order according
* to the keys.
*/
iterator
cbegin() const noexcept
{ return _M_t.begin(); }
/**
* Returns a read-only (constant) iterator that points one past the last
* element in the %set. Iteration is done in ascending order according
* to the keys.
*/
iterator
cend() const noexcept
{ return _M_t.end(); }
/**
* Returns a read-only (constant) iterator that points to the last
* element in the %set. Iteration is done in descending order according
* to the keys.
*/
reverse_iterator
crbegin() const noexcept
{ return _M_t.rbegin(); }
/**
* Returns a read-only (constant) reverse iterator that points to the
* last pair in the %set. Iteration is done in descending order
* according to the keys.
*/
reverse_iterator
crend() const noexcept
{ return _M_t.rend(); }
#endif
/// Returns true if the %set is empty.
bool
empty() const _GLIBCXX_NOEXCEPT
{ return _M_t.empty(); }
/// Returns the size of the %set.
size_type
size() const _GLIBCXX_NOEXCEPT
{ return _M_t.size(); }
/// Returns the maximum size of the %set.
size_type
max_size() const _GLIBCXX_NOEXCEPT
{ return _M_t.max_size(); }
/**
* @brief Swaps data with another %set.
* @param __x A %set of the same element and allocator types.
*
* This exchanges the elements between two sets in constant
* time. (It is only swapping a pointer, an integer, and an
* instance of the @c Compare type (which itself is often
* stateless and empty), so it should be quite fast.) Note
* that the global std::swap() function is specialized such
* that std::swap(s1,s2) will feed to this function.
*/
void
swap(set& __x)
{ _M_t.swap(__x._M_t); }
// insert/erase
#if __cplusplus >= 201103L
/**
* @brief Attempts to build and insert an element into the %set.
* @param __args Arguments used to generate an element.
* @return A pair, of which the first element is an iterator that points
* to the possibly inserted element, and the second is a bool
* that is true if the element was actually inserted.
*
* This function attempts to build and insert an element into the %set.
* A %set relies on unique keys and thus an element is only inserted if
* it is not already present in the %set.
*
* Insertion requires logarithmic time.
*/
template<typename... _Args>
std::pair<iterator, bool>
emplace(_Args&&... __args)
{ return _M_t._M_emplace_unique(std::forward<_Args>(__args)...); }
/**
* @brief Attempts to insert an element into the %set.
* @param __pos An iterator that serves as a hint as to where the
* element should be inserted.
* @param __args Arguments used to generate the element to be
* inserted.
* @return An iterator that points to the element with key equivalent to
* the one generated from @a __args (may or may not be the
* element itself).
*
* This function is not concerned about whether the insertion took place,
* and thus does not return a boolean like the single-argument emplace()
* does. Note that the first parameter is only a hint and can
* potentially improve the performance of the insertion process. A bad
* hint would cause no gains in efficiency.
*
* For more on @a hinting, see:
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html
*
* Insertion requires logarithmic time (if the hint is not taken).
*/
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
return _M_t._M_emplace_hint_unique(__pos,
std::forward<_Args>(__args)...);
}
#endif
/**
* @brief Attempts to insert an element into the %set.
* @param __x Element to be inserted.
* @return A pair, of which the first element is an iterator that points
* to the possibly inserted element, and the second is a bool
* that is true if the element was actually inserted.
*
* This function attempts to insert an element into the %set. A %set
* relies on unique keys and thus an element is only inserted if it is
* not already present in the %set.
*
* Insertion requires logarithmic time.
*/
std::pair<iterator, bool>
insert(const value_type& __x)
{
std::pair<typename _Rep_type::iterator, bool> __p =
_M_t._M_insert_unique(__x);
return std::pair<iterator, bool>(__p.first, __p.second);
}
#if __cplusplus >= 201103L
std::pair<iterator, bool>
insert(value_type&& __x)
{
std::pair<typename _Rep_type::iterator, bool> __p =
_M_t._M_insert_unique(std::move(__x));
return std::pair<iterator, bool>(__p.first, __p.second);
}
#endif
/**
* @brief Attempts to insert an element into the %set.
* @param __position An iterator that serves as a hint as to where the
* element should be inserted.
* @param __x Element to be inserted.
* @return An iterator that points to the element with key of
* @a __x (may or may not be the element passed in).
*
* This function is not concerned about whether the insertion took place,
* and thus does not return a boolean like the single-argument insert()
* does. Note that the first parameter is only a hint and can
* potentially improve the performance of the insertion process. A bad
* hint would cause no gains in efficiency.
*
* For more on @a hinting, see:
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html
*
* Insertion requires logarithmic time (if the hint is not taken).
*/
iterator
insert(const_iterator __position, const value_type& __x)
{ return _M_t._M_insert_unique_(__position, __x); }
#if __cplusplus >= 201103L
iterator
insert(const_iterator __position, value_type&& __x)
{ return _M_t._M_insert_unique_(__position, std::move(__x)); }
#endif
/**
* @brief A template function that attempts to insert a range
* of elements.
* @param __first Iterator pointing to the start of the range to be
* inserted.
* @param __last Iterator pointing to the end of the range.
*
* Complexity similar to that of the range constructor.
*/
template<typename _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{ _M_t._M_insert_unique(__first, __last); }
#if __cplusplus >= 201103L
/**
* @brief Attempts to insert a list of elements into the %set.
* @param __l A std::initializer_list<value_type> of elements
* to be inserted.
*
* Complexity similar to that of the range constructor.
*/
void
insert(initializer_list<value_type> __l)
{ this->insert(__l.begin(), __l.end()); }
#endif
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 130. Associative erase should return an iterator.
/**
* @brief Erases an element from a %set.
* @param __position An iterator pointing to the element to be erased.
* @return An iterator pointing to the element immediately following
* @a __position prior to the element being erased. If no such
* element exists, end() is returned.
*
* This function erases an element, pointed to by the given iterator,
* from a %set. Note that this function only erases the element, and
* that if the element is itself a pointer, the pointed-to memory is not
* touched in any way. Managing the pointer is the user's
* responsibility.
*/
_GLIBCXX_ABI_TAG_CXX11
iterator
erase(const_iterator __position)
{ return _M_t.erase(__position); }
#else
/**
* @brief Erases an element from a %set.
* @param position An iterator pointing to the element to be erased.
*
* This function erases an element, pointed to by the given iterator,
* from a %set. Note that this function only erases the element, and
* that if the element is itself a pointer, the pointed-to memory is not
* touched in any way. Managing the pointer is the user's
* responsibility.
*/
void
erase(iterator __position)
{ _M_t.erase(__position); }
#endif
/**
* @brief Erases elements according to the provided key.
* @param __x Key of element to be erased.
* @return The number of elements erased.
*
* This function erases all the elements located by the given key from
* a %set.
* Note that this function only erases the element, and that if
* the element is itself a pointer, the pointed-to memory is not touched
* in any way. Managing the pointer is the user's responsibility.
*/
size_type
erase(const key_type& __x)
{ return _M_t.erase(__x); }
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 130. Associative erase should return an iterator.
/**
* @brief Erases a [__first,__last) range of elements from a %set.
* @param __first Iterator pointing to the start of the range to be
* erased.
* @param __last Iterator pointing to the end of the range to
* be erased.
* @return The iterator @a __last.
*
* This function erases a sequence of elements from a %set.
* Note that this function only erases the element, and that if
* the element is itself a pointer, the pointed-to memory is not touched
* in any way. Managing the pointer is the user's responsibility.
*/
_GLIBCXX_ABI_TAG_CXX11
iterator
erase(const_iterator __first, const_iterator __last)
{ return _M_t.erase(__first, __last); }
#else
/**
* @brief Erases a [first,last) range of elements from a %set.
* @param __first Iterator pointing to the start of the range to be
* erased.
* @param __last Iterator pointing to the end of the range to
* be erased.
*
* This function erases a sequence of elements from a %set.
* Note that this function only erases the element, and that if
* the element is itself a pointer, the pointed-to memory is not touched
* in any way. Managing the pointer is the user's responsibility.
*/
void
erase(iterator __first, iterator __last)
{ _M_t.erase(__first, __last); }
#endif
/**
* Erases all elements in a %set. Note that this function only erases
* the elements, and that if the elements themselves are pointers, the
* pointed-to memory is not touched in any way. Managing the pointer is
* the user's responsibility.
*/
void
clear() _GLIBCXX_NOEXCEPT
{ _M_t.clear(); }
// set operations:
/**
* @brief Finds the number of elements.
* @param __x Element to located.
* @return Number of elements with specified key.
*
* This function only makes sense for multisets; for set the result will
* either be 0 (not present) or 1 (present).
*/
size_type
count(const key_type& __x) const
{ return _M_t.find(__x) == _M_t.end() ? 0 : 1; }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
//@{
/**
* @brief Tries to locate an element in a %set.
* @param __x Element to be located.
* @return Iterator pointing to sought-after element, or end() if not
* found.
*
* This function takes a key and tries to locate the element with which
* the key matches. If successful the function returns an iterator
* pointing to the sought after element. If unsuccessful it returns the
* past-the-end ( @c end() ) iterator.
*/
iterator
find(const key_type& __x)
{ return _M_t.find(__x); }
const_iterator
find(const key_type& __x) const
{ return _M_t.find(__x); }
//@}
//@{
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param __x Key to be located.
* @return Iterator pointing to first element equal to or greater
* than key, or end().
*
* This function returns the first element of a subsequence of elements
* that matches the given key. If unsuccessful it returns an iterator
* pointing to the first element that has a greater value than given key
* or end() if no such element exists.
*/
iterator
lower_bound(const key_type& __x)
{ return _M_t.lower_bound(__x); }
const_iterator
lower_bound(const key_type& __x) const
{ return _M_t.lower_bound(__x); }
//@}
//@{
/**
* @brief Finds the end of a subsequence matching given key.
* @param __x Key to be located.
* @return Iterator pointing to the first element
* greater than key, or end().
*/
iterator
upper_bound(const key_type& __x)
{ return _M_t.upper_bound(__x); }
const_iterator
upper_bound(const key_type& __x) const
{ return _M_t.upper_bound(__x); }
//@}
//@{
/**
* @brief Finds a subsequence matching given key.
* @param __x Key to be located.
* @return Pair of iterators that possibly points to the subsequence
* matching given key.
*
* This function is equivalent to
* @code
* std::make_pair(c.lower_bound(val),
* c.upper_bound(val))
* @endcode
* (but is faster than making the calls separately).
*
* This function probably only makes sense for multisets.
*/
std::pair<iterator, iterator>
equal_range(const key_type& __x)
{ return _M_t.equal_range(__x); }
std::pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
//@}
template<typename _K1, typename _C1, typename _A1>
friend bool
operator==(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&);
template<typename _K1, typename _C1, typename _A1>
friend bool
operator<(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&);
};
/**
* @brief Set equality comparison.
* @param __x A %set.
* @param __y A %set of the same type as @a x.
* @return True iff the size and elements of the sets are equal.
*
* This is an equivalence relation. It is linear in the size of the sets.
* Sets are considered equivalent if their sizes are equal, and if
* corresponding elements compare equal.
*/
template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator==(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y)
{ return __x._M_t == __y._M_t; }
/**
* @brief Set ordering relation.
* @param __x A %set.
* @param __y A %set of the same type as @a x.
* @return True iff @a __x is lexicographically less than @a __y.
*
* This is a total ordering relation. It is linear in the size of the
* maps. The elements must be comparable with @c <.
*
* See std::lexicographical_compare() for how the determination is made.
*/
template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator<(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Returns !(x == y).
template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator!=(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Returns y < x.
template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator>(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y)
{ return __y < __x; }
/// Returns !(y < x)
template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator<=(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Returns !(x < y)
template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator>=(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::set::swap().
template<typename _Key, typename _Compare, typename _Alloc>
inline void
swap(set<_Key, _Compare, _Alloc>& __x, set<_Key, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
_GLIBCXX_END_NAMESPACE_CONTAINER
} //namespace std
#endif /* _STL_SET_H */

View File

@@ -0,0 +1,303 @@
// Stack implementation -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_stack.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{stack}
*/
#ifndef _STL_STACK_H
#define _STL_STACK_H 1
#include <bits/concept_check.h>
#include <debug/debug.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief A standard container giving FILO behavior.
*
* @ingroup sequences
*
* @tparam _Tp Type of element.
* @tparam _Sequence Type of underlying sequence, defaults to deque<_Tp>.
*
* Meets many of the requirements of a
* <a href="tables.html#65">container</a>,
* but does not define anything to do with iterators. Very few of the
* other standard container interfaces are defined.
*
* This is not a true container, but an @e adaptor. It holds
* another container, and provides a wrapper interface to that
* container. The wrapper is what enforces strict
* first-in-last-out %stack behavior.
*
* The second template parameter defines the type of the underlying
* sequence/container. It defaults to std::deque, but it can be
* any type that supports @c back, @c push_back, and @c pop_front,
* such as std::list, std::vector, or an appropriate user-defined
* type.
*
* Members not found in @a normal containers are @c container_type,
* which is a typedef for the second Sequence parameter, and @c
* push, @c pop, and @c top, which are standard %stack/FILO
* operations.
*/
template<typename _Tp, typename _Sequence = deque<_Tp> >
class stack
{
// concept requirements
typedef typename _Sequence::value_type _Sequence_value_type;
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
__glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)
__glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
template<typename _Tp1, typename _Seq1>
friend bool
operator==(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
template<typename _Tp1, typename _Seq1>
friend bool
operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
public:
typedef typename _Sequence::value_type value_type;
typedef typename _Sequence::reference reference;
typedef typename _Sequence::const_reference const_reference;
typedef typename _Sequence::size_type size_type;
typedef _Sequence container_type;
protected:
// See queue::c for notes on this name.
_Sequence c;
public:
// XXX removed old def ctor, added def arg to this one to match 14882
/**
* @brief Default constructor creates no elements.
*/
#if __cplusplus < 201103L
explicit
stack(const _Sequence& __c = _Sequence())
: c(__c) { }
#else
explicit
stack(const _Sequence& __c)
: c(__c) { }
explicit
stack(_Sequence&& __c = _Sequence())
: c(std::move(__c)) { }
#endif
/**
* Returns true if the %stack is empty.
*/
bool
empty() const
{ return c.empty(); }
/** Returns the number of elements in the %stack. */
size_type
size() const
{ return c.size(); }
/**
* Returns a read/write reference to the data at the first
* element of the %stack.
*/
reference
top()
{
__glibcxx_requires_nonempty();
return c.back();
}
/**
* Returns a read-only (constant) reference to the data at the first
* element of the %stack.
*/
const_reference
top() const
{
__glibcxx_requires_nonempty();
return c.back();
}
/**
* @brief Add data to the top of the %stack.
* @param __x Data to be added.
*
* This is a typical %stack operation. The function creates an
* element at the top of the %stack and assigns the given data
* to it. The time complexity of the operation depends on the
* underlying sequence.
*/
void
push(const value_type& __x)
{ c.push_back(__x); }
#if __cplusplus >= 201103L
void
push(value_type&& __x)
{ c.push_back(std::move(__x)); }
template<typename... _Args>
void
emplace(_Args&&... __args)
{ c.emplace_back(std::forward<_Args>(__args)...); }
#endif
/**
* @brief Removes first element.
*
* This is a typical %stack operation. It shrinks the %stack
* by one. The time complexity of the operation depends on the
* underlying sequence.
*
* Note that no data is returned, and if the first element's
* data is needed, it should be retrieved before pop() is
* called.
*/
void
pop()
{
__glibcxx_requires_nonempty();
c.pop_back();
}
#if __cplusplus >= 201103L
void
swap(stack& __s)
noexcept(noexcept(swap(c, __s.c)))
{
using std::swap;
swap(c, __s.c);
}
#endif
};
/**
* @brief Stack equality comparison.
* @param __x A %stack.
* @param __y A %stack of the same type as @a __x.
* @return True iff the size and elements of the stacks are equal.
*
* This is an equivalence relation. Complexity and semantics
* depend on the underlying sequence type, but the expected rules
* are: this relation is linear in the size of the sequences, and
* stacks are considered equivalent if their sequences compare
* equal.
*/
template<typename _Tp, typename _Seq>
inline bool
operator==(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return __x.c == __y.c; }
/**
* @brief Stack ordering relation.
* @param __x A %stack.
* @param __y A %stack of the same type as @a x.
* @return True iff @a x is lexicographically less than @a __y.
*
* This is an total ordering relation. Complexity and semantics
* depend on the underlying sequence type, but the expected rules
* are: this relation is linear in the size of the sequences, the
* elements must be comparable with @c <, and
* std::lexicographical_compare() is usually used to make the
* determination.
*/
template<typename _Tp, typename _Seq>
inline bool
operator<(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return __x.c < __y.c; }
/// Based on operator==
template<typename _Tp, typename _Seq>
inline bool
operator!=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return !(__x == __y); }
/// Based on operator<
template<typename _Tp, typename _Seq>
inline bool
operator>(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return __y < __x; }
/// Based on operator<
template<typename _Tp, typename _Seq>
inline bool
operator<=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return !(__y < __x); }
/// Based on operator<
template<typename _Tp, typename _Seq>
inline bool
operator>=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return !(__x < __y); }
#if __cplusplus >= 201103L
template<typename _Tp, typename _Seq>
inline void
swap(stack<_Tp, _Seq>& __x, stack<_Tp, _Seq>& __y)
noexcept(noexcept(__x.swap(__y)))
{ __x.swap(__y); }
template<typename _Tp, typename _Seq, typename _Alloc>
struct uses_allocator<stack<_Tp, _Seq>, _Alloc>
: public uses_allocator<_Seq, _Alloc>::type { };
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _STL_STACK_H */

View File

@@ -0,0 +1,271 @@
// Temporary buffer implementation -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_tempbuf.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _STL_TEMPBUF_H
#define _STL_TEMPBUF_H 1
#include <bits/stl_algobase.h>
#include <bits/stl_construct.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Allocates a temporary buffer.
* @param __len The number of objects of type Tp.
* @return See full description.
*
* Reinventing the wheel, but this time with prettier spokes!
*
* This function tries to obtain storage for @c __len adjacent Tp
* objects. The objects themselves are not constructed, of course.
* A pair<> is returned containing <em>the buffer s address and
* capacity (in the units of sizeof(_Tp)), or a pair of 0 values if
* no storage can be obtained.</em> Note that the capacity obtained
* may be less than that requested if the memory is unavailable;
* you should compare len with the .second return value.
*
* Provides the nothrow exception guarantee.
*/
template<typename _Tp>
pair<_Tp*, ptrdiff_t>
get_temporary_buffer(ptrdiff_t __len) _GLIBCXX_NOEXCEPT
{
const ptrdiff_t __max =
__gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp);
if (__len > __max)
__len = __max;
while (__len > 0)
{
_Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp),
std::nothrow));
if (__tmp != 0)
return std::pair<_Tp*, ptrdiff_t>(__tmp, __len);
__len /= 2;
}
return std::pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0);
}
/**
* @brief The companion to get_temporary_buffer().
* @param __p A buffer previously allocated by get_temporary_buffer.
* @return None.
*
* Frees the memory pointed to by __p.
*/
template<typename _Tp>
inline void
return_temporary_buffer(_Tp* __p)
{ ::operator delete(__p, std::nothrow); }
/**
* This class is used in two places: stl_algo.h and ext/memory,
* where it is wrapped as the temporary_buffer class. See
* temporary_buffer docs for more notes.
*/
template<typename _ForwardIterator, typename _Tp>
class _Temporary_buffer
{
// concept requirements
__glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept)
public:
typedef _Tp value_type;
typedef value_type* pointer;
typedef pointer iterator;
typedef ptrdiff_t size_type;
protected:
size_type _M_original_len;
size_type _M_len;
pointer _M_buffer;
public:
/// As per Table mumble.
size_type
size() const
{ return _M_len; }
/// Returns the size requested by the constructor; may be >size().
size_type
requested_size() const
{ return _M_original_len; }
/// As per Table mumble.
iterator
begin()
{ return _M_buffer; }
/// As per Table mumble.
iterator
end()
{ return _M_buffer + _M_len; }
/**
* Constructs a temporary buffer of a size somewhere between
* zero and the size of the given range.
*/
_Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last);
~_Temporary_buffer()
{
std::_Destroy(_M_buffer, _M_buffer + _M_len);
std::return_temporary_buffer(_M_buffer);
}
private:
// Disable copy constructor and assignment operator.
_Temporary_buffer(const _Temporary_buffer&);
void
operator=(const _Temporary_buffer&);
};
template<bool>
struct __uninitialized_construct_buf_dispatch
{
template<typename _Pointer, typename _ForwardIterator>
static void
__ucr(_Pointer __first, _Pointer __last,
_ForwardIterator __seed)
{
if(__first == __last)
return;
_Pointer __cur = __first;
__try
{
std::_Construct(std::__addressof(*__first),
_GLIBCXX_MOVE(*__seed));
_Pointer __prev = __cur;
++__cur;
for(; __cur != __last; ++__cur, ++__prev)
std::_Construct(std::__addressof(*__cur),
_GLIBCXX_MOVE(*__prev));
*__seed = _GLIBCXX_MOVE(*__prev);
}
__catch(...)
{
std::_Destroy(__first, __cur);
__throw_exception_again;
}
}
};
template<>
struct __uninitialized_construct_buf_dispatch<true>
{
template<typename _Pointer, typename _ForwardIterator>
static void
__ucr(_Pointer, _Pointer, _ForwardIterator) { }
};
// Constructs objects in the range [first, last).
// Note that while these new objects will take valid values,
// their exact value is not defined. In particular they may
// be 'moved from'.
//
// While *__seed may be altered during this algorithm, it will have
// the same value when the algorithm finishes, unless one of the
// constructions throws.
//
// Requirements: _Pointer::value_type(_Tp&&) is valid.
template<typename _Pointer, typename _ForwardIterator>
inline void
__uninitialized_construct_buf(_Pointer __first, _Pointer __last,
_ForwardIterator __seed)
{
typedef typename std::iterator_traits<_Pointer>::value_type
_ValueType;
std::__uninitialized_construct_buf_dispatch<
__has_trivial_constructor(_ValueType)>::
__ucr(__first, __last, __seed);
}
template<typename _ForwardIterator, typename _Tp>
_Temporary_buffer<_ForwardIterator, _Tp>::
_Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last)
: _M_original_len(std::distance(__first, __last)),
_M_len(0), _M_buffer(0)
{
__try
{
std::pair<pointer, size_type> __p(std::get_temporary_buffer<
value_type>(_M_original_len));
_M_buffer = __p.first;
_M_len = __p.second;
if (_M_buffer)
std::__uninitialized_construct_buf(_M_buffer, _M_buffer + _M_len,
__first);
}
__catch(...)
{
std::return_temporary_buffer(_M_buffer);
_M_buffer = 0;
_M_len = 0;
__throw_exception_again;
}
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _STL_TEMPBUF_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,656 @@
// Raw memory manipulators -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/stl_uninitialized.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _STL_UNINITIALIZED_H
#define _STL_UNINITIALIZED_H 1
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<bool _TrivialValueTypes>
struct __uninitialized_copy
{
template<typename _InputIterator, typename _ForwardIterator>
static _ForwardIterator
__uninit_copy(_InputIterator __first, _InputIterator __last,
_ForwardIterator __result)
{
_ForwardIterator __cur = __result;
__try
{
for (; __first != __last; ++__first, ++__cur)
std::_Construct(std::__addressof(*__cur), *__first);
return __cur;
}
__catch(...)
{
std::_Destroy(__result, __cur);
__throw_exception_again;
}
}
};
template<>
struct __uninitialized_copy<true>
{
template<typename _InputIterator, typename _ForwardIterator>
static _ForwardIterator
__uninit_copy(_InputIterator __first, _InputIterator __last,
_ForwardIterator __result)
{ return std::copy(__first, __last, __result); }
};
/**
* @brief Copies the range [first,last) into result.
* @param __first An input iterator.
* @param __last An input iterator.
* @param __result An output iterator.
* @return __result + (__first - __last)
*
* Like copy(), but does not require an initialized output range.
*/
template<typename _InputIterator, typename _ForwardIterator>
inline _ForwardIterator
uninitialized_copy(_InputIterator __first, _InputIterator __last,
_ForwardIterator __result)
{
typedef typename iterator_traits<_InputIterator>::value_type
_ValueType1;
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType2;
return std::__uninitialized_copy<(__is_trivial(_ValueType1)
&& __is_trivial(_ValueType2))>::
__uninit_copy(__first, __last, __result);
}
template<bool _TrivialValueType>
struct __uninitialized_fill
{
template<typename _ForwardIterator, typename _Tp>
static void
__uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __x)
{
_ForwardIterator __cur = __first;
__try
{
for (; __cur != __last; ++__cur)
std::_Construct(std::__addressof(*__cur), __x);
}
__catch(...)
{
std::_Destroy(__first, __cur);
__throw_exception_again;
}
}
};
template<>
struct __uninitialized_fill<true>
{
template<typename _ForwardIterator, typename _Tp>
static void
__uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __x)
{ std::fill(__first, __last, __x); }
};
/**
* @brief Copies the value x into the range [first,last).
* @param __first An input iterator.
* @param __last An input iterator.
* @param __x The source value.
* @return Nothing.
*
* Like fill(), but does not require an initialized output range.
*/
template<typename _ForwardIterator, typename _Tp>
inline void
uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __x)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
std::__uninitialized_fill<__is_trivial(_ValueType)>::
__uninit_fill(__first, __last, __x);
}
template<bool _TrivialValueType>
struct __uninitialized_fill_n
{
template<typename _ForwardIterator, typename _Size, typename _Tp>
static void
__uninit_fill_n(_ForwardIterator __first, _Size __n,
const _Tp& __x)
{
_ForwardIterator __cur = __first;
__try
{
for (; __n > 0; --__n, ++__cur)
std::_Construct(std::__addressof(*__cur), __x);
}
__catch(...)
{
std::_Destroy(__first, __cur);
__throw_exception_again;
}
}
};
template<>
struct __uninitialized_fill_n<true>
{
template<typename _ForwardIterator, typename _Size, typename _Tp>
static void
__uninit_fill_n(_ForwardIterator __first, _Size __n,
const _Tp& __x)
{ std::fill_n(__first, __n, __x); }
};
/**
* @brief Copies the value x into the range [first,first+n).
* @param __first An input iterator.
* @param __n The number of copies to make.
* @param __x The source value.
* @return Nothing.
*
* Like fill_n(), but does not require an initialized output range.
*/
template<typename _ForwardIterator, typename _Size, typename _Tp>
inline void
uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
std::__uninitialized_fill_n<__is_trivial(_ValueType)>::
__uninit_fill_n(__first, __n, __x);
}
// Extensions: versions of uninitialized_copy, uninitialized_fill,
// and uninitialized_fill_n that take an allocator parameter.
// We dispatch back to the standard versions when we're given the
// default allocator. For nondefault allocators we do not use
// any of the POD optimizations.
template<typename _InputIterator, typename _ForwardIterator,
typename _Allocator>
_ForwardIterator
__uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
_ForwardIterator __result, _Allocator& __alloc)
{
_ForwardIterator __cur = __result;
__try
{
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __first != __last; ++__first, ++__cur)
__traits::construct(__alloc, std::__addressof(*__cur), *__first);
return __cur;
}
__catch(...)
{
std::_Destroy(__result, __cur, __alloc);
__throw_exception_again;
}
}
template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
inline _ForwardIterator
__uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
_ForwardIterator __result, allocator<_Tp>&)
{ return std::uninitialized_copy(__first, __last, __result); }
template<typename _InputIterator, typename _ForwardIterator,
typename _Allocator>
inline _ForwardIterator
__uninitialized_move_a(_InputIterator __first, _InputIterator __last,
_ForwardIterator __result, _Allocator& __alloc)
{
return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
_GLIBCXX_MAKE_MOVE_ITERATOR(__last),
__result, __alloc);
}
template<typename _InputIterator, typename _ForwardIterator,
typename _Allocator>
inline _ForwardIterator
__uninitialized_move_if_noexcept_a(_InputIterator __first,
_InputIterator __last,
_ForwardIterator __result,
_Allocator& __alloc)
{
return std::__uninitialized_copy_a
(_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
}
template<typename _ForwardIterator, typename _Tp, typename _Allocator>
void
__uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __x, _Allocator& __alloc)
{
_ForwardIterator __cur = __first;
__try
{
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __cur != __last; ++__cur)
__traits::construct(__alloc, std::__addressof(*__cur), __x);
}
__catch(...)
{
std::_Destroy(__first, __cur, __alloc);
__throw_exception_again;
}
}
template<typename _ForwardIterator, typename _Tp, typename _Tp2>
inline void
__uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __x, allocator<_Tp2>&)
{ std::uninitialized_fill(__first, __last, __x); }
template<typename _ForwardIterator, typename _Size, typename _Tp,
typename _Allocator>
void
__uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
const _Tp& __x, _Allocator& __alloc)
{
_ForwardIterator __cur = __first;
__try
{
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __n > 0; --__n, ++__cur)
__traits::construct(__alloc, std::__addressof(*__cur), __x);
}
__catch(...)
{
std::_Destroy(__first, __cur, __alloc);
__throw_exception_again;
}
}
template<typename _ForwardIterator, typename _Size, typename _Tp,
typename _Tp2>
inline void
__uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
const _Tp& __x, allocator<_Tp2>&)
{ std::uninitialized_fill_n(__first, __n, __x); }
// Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
// __uninitialized_fill_move, __uninitialized_move_fill.
// All of these algorithms take a user-supplied allocator, which is used
// for construction and destruction.
// __uninitialized_copy_move
// Copies [first1, last1) into [result, result + (last1 - first1)), and
// move [first2, last2) into
// [result, result + (last1 - first1) + (last2 - first2)).
template<typename _InputIterator1, typename _InputIterator2,
typename _ForwardIterator, typename _Allocator>
inline _ForwardIterator
__uninitialized_copy_move(_InputIterator1 __first1,
_InputIterator1 __last1,
_InputIterator2 __first2,
_InputIterator2 __last2,
_ForwardIterator __result,
_Allocator& __alloc)
{
_ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
__result,
__alloc);
__try
{
return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
}
__catch(...)
{
std::_Destroy(__result, __mid, __alloc);
__throw_exception_again;
}
}
// __uninitialized_move_copy
// Moves [first1, last1) into [result, result + (last1 - first1)), and
// copies [first2, last2) into
// [result, result + (last1 - first1) + (last2 - first2)).
template<typename _InputIterator1, typename _InputIterator2,
typename _ForwardIterator, typename _Allocator>
inline _ForwardIterator
__uninitialized_move_copy(_InputIterator1 __first1,
_InputIterator1 __last1,
_InputIterator2 __first2,
_InputIterator2 __last2,
_ForwardIterator __result,
_Allocator& __alloc)
{
_ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
__result,
__alloc);
__try
{
return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
}
__catch(...)
{
std::_Destroy(__result, __mid, __alloc);
__throw_exception_again;
}
}
// __uninitialized_fill_move
// Fills [result, mid) with x, and moves [first, last) into
// [mid, mid + (last - first)).
template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
typename _Allocator>
inline _ForwardIterator
__uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
const _Tp& __x, _InputIterator __first,
_InputIterator __last, _Allocator& __alloc)
{
std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
__try
{
return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
}
__catch(...)
{
std::_Destroy(__result, __mid, __alloc);
__throw_exception_again;
}
}
// __uninitialized_move_fill
// Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
// fills [first2 + (last1 - first1), last2) with x.
template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
typename _Allocator>
inline void
__uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
_ForwardIterator __first2,
_ForwardIterator __last2, const _Tp& __x,
_Allocator& __alloc)
{
_ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
__first2,
__alloc);
__try
{
std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
}
__catch(...)
{
std::_Destroy(__first2, __mid2, __alloc);
__throw_exception_again;
}
}
#if __cplusplus >= 201103L
// Extensions: __uninitialized_default, __uninitialized_default_n,
// __uninitialized_default_a, __uninitialized_default_n_a.
template<bool _TrivialValueType>
struct __uninitialized_default_1
{
template<typename _ForwardIterator>
static void
__uninit_default(_ForwardIterator __first, _ForwardIterator __last)
{
_ForwardIterator __cur = __first;
__try
{
for (; __cur != __last; ++__cur)
std::_Construct(std::__addressof(*__cur));
}
__catch(...)
{
std::_Destroy(__first, __cur);
__throw_exception_again;
}
}
};
template<>
struct __uninitialized_default_1<true>
{
template<typename _ForwardIterator>
static void
__uninit_default(_ForwardIterator __first, _ForwardIterator __last)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
std::fill(__first, __last, _ValueType());
}
};
template<bool _TrivialValueType>
struct __uninitialized_default_n_1
{
template<typename _ForwardIterator, typename _Size>
static void
__uninit_default_n(_ForwardIterator __first, _Size __n)
{
_ForwardIterator __cur = __first;
__try
{
for (; __n > 0; --__n, ++__cur)
std::_Construct(std::__addressof(*__cur));
}
__catch(...)
{
std::_Destroy(__first, __cur);
__throw_exception_again;
}
}
};
template<>
struct __uninitialized_default_n_1<true>
{
template<typename _ForwardIterator, typename _Size>
static void
__uninit_default_n(_ForwardIterator __first, _Size __n)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
std::fill_n(__first, __n, _ValueType());
}
};
// __uninitialized_default
// Fills [first, last) with std::distance(first, last) default
// constructed value_types(s).
template<typename _ForwardIterator>
inline void
__uninitialized_default(_ForwardIterator __first,
_ForwardIterator __last)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
std::__uninitialized_default_1<__is_trivial(_ValueType)>::
__uninit_default(__first, __last);
}
// __uninitialized_default_n
// Fills [first, first + n) with n default constructed value_type(s).
template<typename _ForwardIterator, typename _Size>
inline void
__uninitialized_default_n(_ForwardIterator __first, _Size __n)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
std::__uninitialized_default_n_1<__is_trivial(_ValueType)>::
__uninit_default_n(__first, __n);
}
// __uninitialized_default_a
// Fills [first, last) with std::distance(first, last) default
// constructed value_types(s), constructed with the allocator alloc.
template<typename _ForwardIterator, typename _Allocator>
void
__uninitialized_default_a(_ForwardIterator __first,
_ForwardIterator __last,
_Allocator& __alloc)
{
_ForwardIterator __cur = __first;
__try
{
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __cur != __last; ++__cur)
__traits::construct(__alloc, std::__addressof(*__cur));
}
__catch(...)
{
std::_Destroy(__first, __cur, __alloc);
__throw_exception_again;
}
}
template<typename _ForwardIterator, typename _Tp>
inline void
__uninitialized_default_a(_ForwardIterator __first,
_ForwardIterator __last,
allocator<_Tp>&)
{ std::__uninitialized_default(__first, __last); }
// __uninitialized_default_n_a
// Fills [first, first + n) with n default constructed value_types(s),
// constructed with the allocator alloc.
template<typename _ForwardIterator, typename _Size, typename _Allocator>
void
__uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
_Allocator& __alloc)
{
_ForwardIterator __cur = __first;
__try
{
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __n > 0; --__n, ++__cur)
__traits::construct(__alloc, std::__addressof(*__cur));
}
__catch(...)
{
std::_Destroy(__first, __cur, __alloc);
__throw_exception_again;
}
}
template<typename _ForwardIterator, typename _Size, typename _Tp>
inline void
__uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
allocator<_Tp>&)
{ std::__uninitialized_default_n(__first, __n); }
template<typename _InputIterator, typename _Size,
typename _ForwardIterator>
_ForwardIterator
__uninitialized_copy_n(_InputIterator __first, _Size __n,
_ForwardIterator __result, input_iterator_tag)
{
_ForwardIterator __cur = __result;
__try
{
for (; __n > 0; --__n, ++__first, ++__cur)
std::_Construct(std::__addressof(*__cur), *__first);
return __cur;
}
__catch(...)
{
std::_Destroy(__result, __cur);
__throw_exception_again;
}
}
template<typename _RandomAccessIterator, typename _Size,
typename _ForwardIterator>
inline _ForwardIterator
__uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
_ForwardIterator __result,
random_access_iterator_tag)
{ return std::uninitialized_copy(__first, __first + __n, __result); }
/**
* @brief Copies the range [first,first+n) into result.
* @param __first An input iterator.
* @param __n The number of elements to copy.
* @param __result An output iterator.
* @return __result + __n
*
* Like copy_n(), but does not require an initialized output range.
*/
template<typename _InputIterator, typename _Size, typename _ForwardIterator>
inline _ForwardIterator
uninitialized_copy_n(_InputIterator __first, _Size __n,
_ForwardIterator __result)
{ return std::__uninitialized_copy_n(__first, __n, __result,
std::__iterator_category(__first)); }
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _STL_UNINITIALIZED_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,221 @@
// Stream iterators
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/stream_iterator.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
#ifndef _STREAM_ITERATOR_H
#define _STREAM_ITERATOR_H 1
#pragma GCC system_header
#include <debug/debug.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup iterators
* @{
*/
/// Provides input iterator semantics for streams.
template<typename _Tp, typename _CharT = char,
typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t>
class istream_iterator
: public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&>
{
public:
typedef _CharT char_type;
typedef _Traits traits_type;
typedef basic_istream<_CharT, _Traits> istream_type;
private:
istream_type* _M_stream;
_Tp _M_value;
bool _M_ok;
public:
/// Construct end of input stream iterator.
_GLIBCXX_CONSTEXPR istream_iterator()
: _M_stream(0), _M_value(), _M_ok(false) {}
/// Construct start of input stream iterator.
istream_iterator(istream_type& __s)
: _M_stream(&__s)
{ _M_read(); }
istream_iterator(const istream_iterator& __obj)
: _M_stream(__obj._M_stream), _M_value(__obj._M_value),
_M_ok(__obj._M_ok)
{ }
const _Tp&
operator*() const
{
__glibcxx_requires_cond(_M_ok,
_M_message(__gnu_debug::__msg_deref_istream)
._M_iterator(*this));
return _M_value;
}
const _Tp*
operator->() const { return &(operator*()); }
istream_iterator&
operator++()
{
__glibcxx_requires_cond(_M_ok,
_M_message(__gnu_debug::__msg_inc_istream)
._M_iterator(*this));
_M_read();
return *this;
}
istream_iterator
operator++(int)
{
__glibcxx_requires_cond(_M_ok,
_M_message(__gnu_debug::__msg_inc_istream)
._M_iterator(*this));
istream_iterator __tmp = *this;
_M_read();
return __tmp;
}
bool
_M_equal(const istream_iterator& __x) const
{ return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); }
private:
void
_M_read()
{
_M_ok = (_M_stream && *_M_stream) ? true : false;
if (_M_ok)
{
*_M_stream >> _M_value;
_M_ok = *_M_stream ? true : false;
}
}
};
/// Return true if x and y are both end or not end, or x and y are the same.
template<typename _Tp, typename _CharT, typename _Traits, typename _Dist>
inline bool
operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y)
{ return __x._M_equal(__y); }
/// Return false if x and y are both end or not end, or x and y are the same.
template <class _Tp, class _CharT, class _Traits, class _Dist>
inline bool
operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y)
{ return !__x._M_equal(__y); }
/**
* @brief Provides output iterator semantics for streams.
*
* This class provides an iterator to write to an ostream. The type Tp is
* the only type written by this iterator and there must be an
* operator<<(Tp) defined.
*
* @tparam _Tp The type to write to the ostream.
* @tparam _CharT The ostream char_type.
* @tparam _Traits The ostream char_traits.
*/
template<typename _Tp, typename _CharT = char,
typename _Traits = char_traits<_CharT> >
class ostream_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
public:
//@{
/// Public typedef
typedef _CharT char_type;
typedef _Traits traits_type;
typedef basic_ostream<_CharT, _Traits> ostream_type;
//@}
private:
ostream_type* _M_stream;
const _CharT* _M_string;
public:
/// Construct from an ostream.
ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {}
/**
* Construct from an ostream.
*
* The delimiter string @a c is written to the stream after every Tp
* written to the stream. The delimiter is not copied, and thus must
* not be destroyed while this iterator is in use.
*
* @param __s Underlying ostream to write to.
* @param __c CharT delimiter string to insert.
*/
ostream_iterator(ostream_type& __s, const _CharT* __c)
: _M_stream(&__s), _M_string(__c) { }
/// Copy constructor.
ostream_iterator(const ostream_iterator& __obj)
: _M_stream(__obj._M_stream), _M_string(__obj._M_string) { }
/// Writes @a value to underlying ostream using operator<<. If
/// constructed with delimiter string, writes delimiter to ostream.
ostream_iterator&
operator=(const _Tp& __value)
{
__glibcxx_requires_cond(_M_stream != 0,
_M_message(__gnu_debug::__msg_output_ostream)
._M_iterator(*this));
*_M_stream << __value;
if (_M_string) *_M_stream << _M_string;
return *this;
}
ostream_iterator&
operator*()
{ return *this; }
ostream_iterator&
operator++()
{ return *this; }
ostream_iterator&
operator++(int)
{ return *this; }
};
// @} group iterators
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@@ -0,0 +1,175 @@
// Stream buffer classes -*- C++ -*-
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/streambuf.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{streambuf}
*/
//
// ISO C++ 14882: 27.5 Stream buffers
//
#ifndef _STREAMBUF_TCC
#define _STREAMBUF_TCC 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
streamsize
basic_streambuf<_CharT, _Traits>::
xsgetn(char_type* __s, streamsize __n)
{
streamsize __ret = 0;
while (__ret < __n)
{
const streamsize __buf_len = this->egptr() - this->gptr();
if (__buf_len)
{
const streamsize __remaining = __n - __ret;
const streamsize __len = std::min(__buf_len, __remaining);
traits_type::copy(__s, this->gptr(), __len);
__ret += __len;
__s += __len;
this->__safe_gbump(__len);
}
if (__ret < __n)
{
const int_type __c = this->uflow();
if (!traits_type::eq_int_type(__c, traits_type::eof()))
{
traits_type::assign(*__s++, traits_type::to_char_type(__c));
++__ret;
}
else
break;
}
}
return __ret;
}
template<typename _CharT, typename _Traits>
streamsize
basic_streambuf<_CharT, _Traits>::
xsputn(const char_type* __s, streamsize __n)
{
streamsize __ret = 0;
while (__ret < __n)
{
const streamsize __buf_len = this->epptr() - this->pptr();
if (__buf_len)
{
const streamsize __remaining = __n - __ret;
const streamsize __len = std::min(__buf_len, __remaining);
traits_type::copy(this->pptr(), __s, __len);
__ret += __len;
__s += __len;
this->__safe_pbump(__len);
}
if (__ret < __n)
{
int_type __c = this->overflow(traits_type::to_int_type(*__s));
if (!traits_type::eq_int_type(__c, traits_type::eof()))
{
++__ret;
++__s;
}
else
break;
}
}
return __ret;
}
// Conceivably, this could be used to implement buffer-to-buffer
// copies, if this was ever desired in an un-ambiguous way by the
// standard.
template<typename _CharT, typename _Traits>
streamsize
__copy_streambufs_eof(basic_streambuf<_CharT, _Traits>* __sbin,
basic_streambuf<_CharT, _Traits>* __sbout,
bool& __ineof)
{
streamsize __ret = 0;
__ineof = true;
typename _Traits::int_type __c = __sbin->sgetc();
while (!_Traits::eq_int_type(__c, _Traits::eof()))
{
__c = __sbout->sputc(_Traits::to_char_type(__c));
if (_Traits::eq_int_type(__c, _Traits::eof()))
{
__ineof = false;
break;
}
++__ret;
__c = __sbin->snextc();
}
return __ret;
}
template<typename _CharT, typename _Traits>
inline streamsize
__copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin,
basic_streambuf<_CharT, _Traits>* __sbout)
{
bool __ineof;
return __copy_streambufs_eof(__sbin, __sbout, __ineof);
}
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class basic_streambuf<char>;
extern template
streamsize
__copy_streambufs(basic_streambuf<char>*,
basic_streambuf<char>*);
extern template
streamsize
__copy_streambufs_eof(basic_streambuf<char>*,
basic_streambuf<char>*, bool&);
#ifdef _GLIBCXX_USE_WCHAR_T
extern template class basic_streambuf<wchar_t>;
extern template
streamsize
__copy_streambufs(basic_streambuf<wchar_t>*,
basic_streambuf<wchar_t>*);
extern template
streamsize
__copy_streambufs_eof(basic_streambuf<wchar_t>*,
basic_streambuf<wchar_t>*, bool&);
#endif
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

View File

@@ -0,0 +1,412 @@
// Streambuf iterators
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/streambuf_iterator.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
#ifndef _STREAMBUF_ITERATOR_H
#define _STREAMBUF_ITERATOR_H 1
#pragma GCC system_header
#include <streambuf>
#include <debug/debug.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup iterators
* @{
*/
// 24.5.3 Template class istreambuf_iterator
/// Provides input iterator semantics for streambufs.
template<typename _CharT, typename _Traits>
class istreambuf_iterator
: public iterator<input_iterator_tag, _CharT, typename _Traits::off_type,
_CharT*,
#if __cplusplus >= 201103L
// LWG 445.
_CharT>
#else
_CharT&>
#endif
{
public:
// Types:
//@{
/// Public typedefs
typedef _CharT char_type;
typedef _Traits traits_type;
typedef typename _Traits::int_type int_type;
typedef basic_streambuf<_CharT, _Traits> streambuf_type;
typedef basic_istream<_CharT, _Traits> istream_type;
//@}
template<typename _CharT2>
friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
ostreambuf_iterator<_CharT2> >::__type
copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
ostreambuf_iterator<_CharT2>);
template<bool _IsMove, typename _CharT2>
friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
_CharT2*>::__type
__copy_move_a2(istreambuf_iterator<_CharT2>,
istreambuf_iterator<_CharT2>, _CharT2*);
template<typename _CharT2>
friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
istreambuf_iterator<_CharT2> >::__type
find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
const _CharT2&);
private:
// 24.5.3 istreambuf_iterator
// p 1
// If the end of stream is reached (streambuf_type::sgetc()
// returns traits_type::eof()), the iterator becomes equal to
// the "end of stream" iterator value.
// NB: This implementation assumes the "end of stream" value
// is EOF, or -1.
mutable streambuf_type* _M_sbuf;
mutable int_type _M_c;
public:
/// Construct end of input stream iterator.
_GLIBCXX_CONSTEXPR istreambuf_iterator() _GLIBCXX_USE_NOEXCEPT
: _M_sbuf(0), _M_c(traits_type::eof()) { }
#if __cplusplus >= 201103L
istreambuf_iterator(const istreambuf_iterator&) noexcept = default;
~istreambuf_iterator() = default;
#endif
/// Construct start of input stream iterator.
istreambuf_iterator(istream_type& __s) _GLIBCXX_USE_NOEXCEPT
: _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { }
/// Construct start of streambuf iterator.
istreambuf_iterator(streambuf_type* __s) _GLIBCXX_USE_NOEXCEPT
: _M_sbuf(__s), _M_c(traits_type::eof()) { }
/// Return the current character pointed to by iterator. This returns
/// streambuf.sgetc(). It cannot be assigned. NB: The result of
/// operator*() on an end of stream is undefined.
char_type
operator*() const
{
#ifdef _GLIBCXX_DEBUG_PEDANTIC
// Dereferencing a past-the-end istreambuf_iterator is a
// libstdc++ extension
__glibcxx_requires_cond(!_M_at_eof(),
_M_message(__gnu_debug::__msg_deref_istreambuf)
._M_iterator(*this));
#endif
return traits_type::to_char_type(_M_get());
}
/// Advance the iterator. Calls streambuf.sbumpc().
istreambuf_iterator&
operator++()
{
__glibcxx_requires_cond(!_M_at_eof(),
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
if (_M_sbuf)
{
_M_sbuf->sbumpc();
_M_c = traits_type::eof();
}
return *this;
}
/// Advance the iterator. Calls streambuf.sbumpc().
istreambuf_iterator
operator++(int)
{
__glibcxx_requires_cond(!_M_at_eof(),
_M_message(__gnu_debug::__msg_inc_istreambuf)
._M_iterator(*this));
istreambuf_iterator __old = *this;
if (_M_sbuf)
{
__old._M_c = _M_sbuf->sbumpc();
_M_c = traits_type::eof();
}
return __old;
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 110 istreambuf_iterator::equal not const
// NB: there is also number 111 (NAD, Future) pending on this function.
/// Return true both iterators are end or both are not end.
bool
equal(const istreambuf_iterator& __b) const
{ return _M_at_eof() == __b._M_at_eof(); }
private:
int_type
_M_get() const
{
const int_type __eof = traits_type::eof();
int_type __ret = __eof;
if (_M_sbuf)
{
if (!traits_type::eq_int_type(_M_c, __eof))
__ret = _M_c;
else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()),
__eof))
_M_c = __ret;
else
_M_sbuf = 0;
}
return __ret;
}
bool
_M_at_eof() const
{
const int_type __eof = traits_type::eof();
return traits_type::eq_int_type(_M_get(), __eof);
}
};
template<typename _CharT, typename _Traits>
inline bool
operator==(const istreambuf_iterator<_CharT, _Traits>& __a,
const istreambuf_iterator<_CharT, _Traits>& __b)
{ return __a.equal(__b); }
template<typename _CharT, typename _Traits>
inline bool
operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
const istreambuf_iterator<_CharT, _Traits>& __b)
{ return !__a.equal(__b); }
/// Provides output iterator semantics for streambufs.
template<typename _CharT, typename _Traits>
class ostreambuf_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
public:
// Types:
//@{
/// Public typedefs
typedef _CharT char_type;
typedef _Traits traits_type;
typedef basic_streambuf<_CharT, _Traits> streambuf_type;
typedef basic_ostream<_CharT, _Traits> ostream_type;
//@}
template<typename _CharT2>
friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
ostreambuf_iterator<_CharT2> >::__type
copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
ostreambuf_iterator<_CharT2>);
private:
streambuf_type* _M_sbuf;
bool _M_failed;
public:
/// Construct output iterator from ostream.
ostreambuf_iterator(ostream_type& __s) _GLIBCXX_USE_NOEXCEPT
: _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
/// Construct output iterator from streambuf.
ostreambuf_iterator(streambuf_type* __s) _GLIBCXX_USE_NOEXCEPT
: _M_sbuf(__s), _M_failed(!_M_sbuf) { }
/// Write character to streambuf. Calls streambuf.sputc().
ostreambuf_iterator&
operator=(_CharT __c)
{
if (!_M_failed &&
_Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
_M_failed = true;
return *this;
}
/// Return *this.
ostreambuf_iterator&
operator*()
{ return *this; }
/// Return *this.
ostreambuf_iterator&
operator++(int)
{ return *this; }
/// Return *this.
ostreambuf_iterator&
operator++()
{ return *this; }
/// Return true if previous operator=() failed.
bool
failed() const _GLIBCXX_USE_NOEXCEPT
{ return _M_failed; }
ostreambuf_iterator&
_M_put(const _CharT* __ws, streamsize __len)
{
if (__builtin_expect(!_M_failed, true)
&& __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len,
false))
_M_failed = true;
return *this;
}
};
// Overloads for streambuf iterators.
template<typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
ostreambuf_iterator<_CharT> >::__type
copy(istreambuf_iterator<_CharT> __first,
istreambuf_iterator<_CharT> __last,
ostreambuf_iterator<_CharT> __result)
{
if (__first._M_sbuf && !__last._M_sbuf && !__result._M_failed)
{
bool __ineof;
__copy_streambufs_eof(__first._M_sbuf, __result._M_sbuf, __ineof);
if (!__ineof)
__result._M_failed = true;
}
return __result;
}
template<bool _IsMove, typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
ostreambuf_iterator<_CharT> >::__type
__copy_move_a2(_CharT* __first, _CharT* __last,
ostreambuf_iterator<_CharT> __result)
{
const streamsize __num = __last - __first;
if (__num > 0)
__result._M_put(__first, __num);
return __result;
}
template<bool _IsMove, typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
ostreambuf_iterator<_CharT> >::__type
__copy_move_a2(const _CharT* __first, const _CharT* __last,
ostreambuf_iterator<_CharT> __result)
{
const streamsize __num = __last - __first;
if (__num > 0)
__result._M_put(__first, __num);
return __result;
}
template<bool _IsMove, typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
_CharT*>::__type
__copy_move_a2(istreambuf_iterator<_CharT> __first,
istreambuf_iterator<_CharT> __last, _CharT* __result)
{
typedef istreambuf_iterator<_CharT> __is_iterator_type;
typedef typename __is_iterator_type::traits_type traits_type;
typedef typename __is_iterator_type::streambuf_type streambuf_type;
typedef typename traits_type::int_type int_type;
if (__first._M_sbuf && !__last._M_sbuf)
{
streambuf_type* __sb = __first._M_sbuf;
int_type __c = __sb->sgetc();
while (!traits_type::eq_int_type(__c, traits_type::eof()))
{
const streamsize __n = __sb->egptr() - __sb->gptr();
if (__n > 1)
{
traits_type::copy(__result, __sb->gptr(), __n);
__sb->__safe_gbump(__n);
__result += __n;
__c = __sb->underflow();
}
else
{
*__result++ = traits_type::to_char_type(__c);
__c = __sb->snextc();
}
}
}
return __result;
}
template<typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
istreambuf_iterator<_CharT> >::__type
find(istreambuf_iterator<_CharT> __first,
istreambuf_iterator<_CharT> __last, const _CharT& __val)
{
typedef istreambuf_iterator<_CharT> __is_iterator_type;
typedef typename __is_iterator_type::traits_type traits_type;
typedef typename __is_iterator_type::streambuf_type streambuf_type;
typedef typename traits_type::int_type int_type;
if (__first._M_sbuf && !__last._M_sbuf)
{
const int_type __ival = traits_type::to_int_type(__val);
streambuf_type* __sb = __first._M_sbuf;
int_type __c = __sb->sgetc();
while (!traits_type::eq_int_type(__c, traits_type::eof())
&& !traits_type::eq_int_type(__c, __ival))
{
streamsize __n = __sb->egptr() - __sb->gptr();
if (__n > 1)
{
const _CharT* __p = traits_type::find(__sb->gptr(),
__n, __val);
if (__p)
__n = __p - __sb->gptr();
__sb->__safe_gbump(__n);
__c = __sb->sgetc();
}
else
__c = __sb->snextc();
}
if (!traits_type::eq_int_type(__c, traits_type::eof()))
__first._M_c = __c;
else
__first._M_sbuf = 0;
}
return __first;
}
// @} group iterators
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@@ -0,0 +1,89 @@
// <string> Forward declarations -*- C++ -*-
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/stringfwd.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{string}
*/
//
// ISO C++ 14882: 21 Strings library
//
#ifndef _STRINGFWD_H
#define _STRINGFWD_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/memoryfwd.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup strings Strings
*
* @{
*/
template<class _CharT>
struct char_traits;
template<typename _CharT, typename _Traits = char_traits<_CharT>,
typename _Alloc = allocator<_CharT> >
class basic_string;
template<> struct char_traits<char>;
/// A string of @c char
typedef basic_string<char> string;
#ifdef _GLIBCXX_USE_WCHAR_T
template<> struct char_traits<wchar_t>;
/// A string of @c wchar_t
typedef basic_string<wchar_t> wstring;
#endif
#if ((__cplusplus >= 201103L) \
&& defined(_GLIBCXX_USE_C99_STDINT_TR1))
template<> struct char_traits<char16_t>;
template<> struct char_traits<char32_t>;
/// A string of @c char16_t
typedef basic_string<char16_t> u16string;
/// A string of @c char32_t
typedef basic_string<char32_t> u32string;
#endif
/** @} */
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // _STRINGFWD_H

View File

@@ -0,0 +1,615 @@
// unique_ptr implementation -*- C++ -*-
// Copyright (C) 2008-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/unique_ptr.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _UNIQUE_PTR_H
#define _UNIQUE_PTR_H 1
#include <bits/c++config.h>
#include <debug/debug.h>
#include <type_traits>
#include <utility>
#include <tuple>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup pointer_abstractions
* @{
*/
#if _GLIBCXX_USE_DEPRECATED
template<typename> class auto_ptr;
#endif
/// Primary template, default_delete.
template<typename _Tp>
struct default_delete
{
constexpr default_delete() noexcept = default;
template<typename _Up, typename = typename
enable_if<is_convertible<_Up*, _Tp*>::value>::type>
default_delete(const default_delete<_Up>&) noexcept { }
void
operator()(_Tp* __ptr) const
{
static_assert(sizeof(_Tp)>0,
"can't delete pointer to incomplete type");
delete __ptr;
}
};
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 740 - omit specialization for array objects with a compile time length
/// Specialization, default_delete.
template<typename _Tp>
struct default_delete<_Tp[]>
{
private:
template<typename _Up>
using __remove_cv = typename remove_cv<_Up>::type;
// Like is_base_of<_Tp, _Up> but false if unqualified types are the same
template<typename _Up>
using __is_derived_Tp
= __and_< is_base_of<_Tp, _Up>,
__not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
public:
constexpr default_delete() noexcept = default;
template<typename _Up, typename = typename
enable_if<!__is_derived_Tp<_Up>::value>::type>
default_delete(const default_delete<_Up[]>&) noexcept { }
void
operator()(_Tp* __ptr) const
{
static_assert(sizeof(_Tp)>0,
"can't delete pointer to incomplete type");
delete [] __ptr;
}
template<typename _Up>
typename enable_if<__is_derived_Tp<_Up>::value>::type
operator()(_Up*) const = delete;
};
/// 20.7.1.2 unique_ptr for single objects.
template <typename _Tp, typename _Dp = default_delete<_Tp> >
class unique_ptr
{
// use SFINAE to determine whether _Del::pointer exists
class _Pointer
{
template<typename _Up>
static typename _Up::pointer __test(typename _Up::pointer*);
template<typename _Up>
static _Tp* __test(...);
typedef typename remove_reference<_Dp>::type _Del;
public:
typedef decltype(__test<_Del>(0)) type;
};
typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type;
__tuple_type _M_t;
public:
typedef typename _Pointer::type pointer;
typedef _Tp element_type;
typedef _Dp deleter_type;
// Constructors.
constexpr unique_ptr() noexcept
: _M_t()
{ static_assert(!is_pointer<deleter_type>::value,
"constructed with null function pointer deleter"); }
explicit
unique_ptr(pointer __p) noexcept
: _M_t(__p, deleter_type())
{ static_assert(!is_pointer<deleter_type>::value,
"constructed with null function pointer deleter"); }
unique_ptr(pointer __p,
typename conditional<is_reference<deleter_type>::value,
deleter_type, const deleter_type&>::type __d) noexcept
: _M_t(__p, __d) { }
unique_ptr(pointer __p,
typename remove_reference<deleter_type>::type&& __d) noexcept
: _M_t(std::move(__p), std::move(__d))
{ static_assert(!std::is_reference<deleter_type>::value,
"rvalue deleter bound to reference"); }
constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
// Move constructors.
unique_ptr(unique_ptr&& __u) noexcept
: _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
template<typename _Up, typename _Ep, typename = _Require<
is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
__not_<is_array<_Up>>,
typename conditional<is_reference<_Dp>::value,
is_same<_Ep, _Dp>,
is_convertible<_Ep, _Dp>>::type>>
unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
: _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
{ }
#if _GLIBCXX_USE_DEPRECATED
template<typename _Up, typename = _Require<
is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
unique_ptr(auto_ptr<_Up>&& __u) noexcept;
#endif
// Destructor.
~unique_ptr() noexcept
{
auto& __ptr = std::get<0>(_M_t);
if (__ptr != nullptr)
get_deleter()(__ptr);
__ptr = pointer();
}
// Assignment.
unique_ptr&
operator=(unique_ptr&& __u) noexcept
{
reset(__u.release());
get_deleter() = std::forward<deleter_type>(__u.get_deleter());
return *this;
}
template<typename _Up, typename _Ep>
typename enable_if< __and_<
is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
__not_<is_array<_Up>>
>::value,
unique_ptr&>::type
operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
{
reset(__u.release());
get_deleter() = std::forward<_Ep>(__u.get_deleter());
return *this;
}
unique_ptr&
operator=(nullptr_t) noexcept
{
reset();
return *this;
}
// Observers.
typename add_lvalue_reference<element_type>::type
operator*() const
{
_GLIBCXX_DEBUG_ASSERT(get() != pointer());
return *get();
}
pointer
operator->() const noexcept
{
_GLIBCXX_DEBUG_ASSERT(get() != pointer());
return get();
}
pointer
get() const noexcept
{ return std::get<0>(_M_t); }
deleter_type&
get_deleter() noexcept
{ return std::get<1>(_M_t); }
const deleter_type&
get_deleter() const noexcept
{ return std::get<1>(_M_t); }
explicit operator bool() const noexcept
{ return get() == pointer() ? false : true; }
// Modifiers.
pointer
release() noexcept
{
pointer __p = get();
std::get<0>(_M_t) = pointer();
return __p;
}
void
reset(pointer __p = pointer()) noexcept
{
using std::swap;
swap(std::get<0>(_M_t), __p);
if (__p != pointer())
get_deleter()(__p);
}
void
swap(unique_ptr& __u) noexcept
{
using std::swap;
swap(_M_t, __u._M_t);
}
// Disable copy from lvalue.
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;
};
/// 20.7.1.3 unique_ptr for array objects with a runtime length
// [unique.ptr.runtime]
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 740 - omit specialization for array objects with a compile time length
template<typename _Tp, typename _Dp>
class unique_ptr<_Tp[], _Dp>
{
// use SFINAE to determine whether _Del::pointer exists
class _Pointer
{
template<typename _Up>
static typename _Up::pointer __test(typename _Up::pointer*);
template<typename _Up>
static _Tp* __test(...);
typedef typename remove_reference<_Dp>::type _Del;
public:
typedef decltype(__test<_Del>(0)) type;
};
typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type;
__tuple_type _M_t;
template<typename _Up>
using __remove_cv = typename remove_cv<_Up>::type;
// like is_base_of<_Tp, _Up> but false if unqualified types are the same
template<typename _Up>
using __is_derived_Tp
= __and_< is_base_of<_Tp, _Up>,
__not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
template<typename _Up, typename _Ep,
typename _Tp_pointer = typename _Pointer::type,
typename _Up_pointer = typename unique_ptr<_Up, _Ep>::pointer>
using __safe_conversion = __and_<
is_convertible<_Up_pointer, _Tp_pointer>,
is_array<_Up>,
__or_<__not_<is_pointer<_Up_pointer>>,
__not_<is_pointer<_Tp_pointer>>,
__not_<__is_derived_Tp<typename remove_extent<_Up>::type>>
>
>;
public:
typedef typename _Pointer::type pointer;
typedef _Tp element_type;
typedef _Dp deleter_type;
// Constructors.
constexpr unique_ptr() noexcept
: _M_t()
{ static_assert(!std::is_pointer<deleter_type>::value,
"constructed with null function pointer deleter"); }
explicit
unique_ptr(pointer __p) noexcept
: _M_t(__p, deleter_type())
{ static_assert(!is_pointer<deleter_type>::value,
"constructed with null function pointer deleter"); }
template<typename _Up, typename = _Require<is_pointer<pointer>,
is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
explicit
unique_ptr(_Up* __p) = delete;
unique_ptr(pointer __p,
typename conditional<is_reference<deleter_type>::value,
deleter_type, const deleter_type&>::type __d) noexcept
: _M_t(__p, __d) { }
unique_ptr(pointer __p, typename
remove_reference<deleter_type>::type&& __d) noexcept
: _M_t(std::move(__p), std::move(__d))
{ static_assert(!is_reference<deleter_type>::value,
"rvalue deleter bound to reference"); }
// Move constructor.
unique_ptr(unique_ptr&& __u) noexcept
: _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
template<typename _Up, typename _Ep,
typename = _Require<__safe_conversion<_Up, _Ep>,
typename conditional<is_reference<_Dp>::value,
is_same<_Ep, _Dp>,
is_convertible<_Ep, _Dp>>::type
>>
unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
: _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
{ }
// Destructor.
~unique_ptr()
{
auto& __ptr = std::get<0>(_M_t);
if (__ptr != nullptr)
get_deleter()(__ptr);
__ptr = pointer();
}
// Assignment.
unique_ptr&
operator=(unique_ptr&& __u) noexcept
{
reset(__u.release());
get_deleter() = std::forward<deleter_type>(__u.get_deleter());
return *this;
}
template<typename _Up, typename _Ep>
typename
enable_if<__safe_conversion<_Up, _Ep>::value, unique_ptr&>::type
operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
{
reset(__u.release());
get_deleter() = std::forward<_Ep>(__u.get_deleter());
return *this;
}
unique_ptr&
operator=(nullptr_t) noexcept
{
reset();
return *this;
}
// Observers.
typename std::add_lvalue_reference<element_type>::type
operator[](size_t __i) const
{
_GLIBCXX_DEBUG_ASSERT(get() != pointer());
return get()[__i];
}
pointer
get() const noexcept
{ return std::get<0>(_M_t); }
deleter_type&
get_deleter() noexcept
{ return std::get<1>(_M_t); }
const deleter_type&
get_deleter() const noexcept
{ return std::get<1>(_M_t); }
explicit operator bool() const noexcept
{ return get() == pointer() ? false : true; }
// Modifiers.
pointer
release() noexcept
{
pointer __p = get();
std::get<0>(_M_t) = pointer();
return __p;
}
void
reset() noexcept
{ reset(pointer()); }
void
reset(pointer __p) noexcept
{
using std::swap;
swap(std::get<0>(_M_t), __p);
if (__p != nullptr)
get_deleter()(__p);
}
template<typename _Up, typename = _Require<is_pointer<pointer>,
is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
void reset(_Up*) = delete;
void
swap(unique_ptr& __u) noexcept
{
using std::swap;
swap(_M_t, __u._M_t);
}
// Disable copy from lvalue.
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;
// Disable construction from convertible pointer types.
template<typename _Up, typename = _Require<is_pointer<pointer>,
is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
unique_ptr(_Up*, typename
conditional<is_reference<deleter_type>::value,
deleter_type, const deleter_type&>::type) = delete;
template<typename _Up, typename = _Require<is_pointer<pointer>,
is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
unique_ptr(_Up*, typename
remove_reference<deleter_type>::type&&) = delete;
};
template<typename _Tp, typename _Dp>
inline void
swap(unique_ptr<_Tp, _Dp>& __x,
unique_ptr<_Tp, _Dp>& __y) noexcept
{ __x.swap(__y); }
template<typename _Tp, typename _Dp,
typename _Up, typename _Ep>
inline bool
operator==(const unique_ptr<_Tp, _Dp>& __x,
const unique_ptr<_Up, _Ep>& __y)
{ return __x.get() == __y.get(); }
template<typename _Tp, typename _Dp>
inline bool
operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
{ return !__x; }
template<typename _Tp, typename _Dp>
inline bool
operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
{ return !__x; }
template<typename _Tp, typename _Dp,
typename _Up, typename _Ep>
inline bool
operator!=(const unique_ptr<_Tp, _Dp>& __x,
const unique_ptr<_Up, _Ep>& __y)
{ return __x.get() != __y.get(); }
template<typename _Tp, typename _Dp>
inline bool
operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
{ return (bool)__x; }
template<typename _Tp, typename _Dp>
inline bool
operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
{ return (bool)__x; }
template<typename _Tp, typename _Dp,
typename _Up, typename _Ep>
inline bool
operator<(const unique_ptr<_Tp, _Dp>& __x,
const unique_ptr<_Up, _Ep>& __y)
{
typedef typename
std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
return std::less<_CT>()(__x.get(), __y.get());
}
template<typename _Tp, typename _Dp>
inline bool
operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
{ return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
nullptr); }
template<typename _Tp, typename _Dp>
inline bool
operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
{ return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
__x.get()); }
template<typename _Tp, typename _Dp,
typename _Up, typename _Ep>
inline bool
operator<=(const unique_ptr<_Tp, _Dp>& __x,
const unique_ptr<_Up, _Ep>& __y)
{ return !(__y < __x); }
template<typename _Tp, typename _Dp>
inline bool
operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
{ return !(nullptr < __x); }
template<typename _Tp, typename _Dp>
inline bool
operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
{ return !(__x < nullptr); }
template<typename _Tp, typename _Dp,
typename _Up, typename _Ep>
inline bool
operator>(const unique_ptr<_Tp, _Dp>& __x,
const unique_ptr<_Up, _Ep>& __y)
{ return (__y < __x); }
template<typename _Tp, typename _Dp>
inline bool
operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
{ return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
__x.get()); }
template<typename _Tp, typename _Dp>
inline bool
operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
{ return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
nullptr); }
template<typename _Tp, typename _Dp,
typename _Up, typename _Ep>
inline bool
operator>=(const unique_ptr<_Tp, _Dp>& __x,
const unique_ptr<_Up, _Ep>& __y)
{ return !(__x < __y); }
template<typename _Tp, typename _Dp>
inline bool
operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
{ return !(__x < nullptr); }
template<typename _Tp, typename _Dp>
inline bool
operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
{ return !(nullptr < __x); }
/// std::hash specialization for unique_ptr.
template<typename _Tp, typename _Dp>
struct hash<unique_ptr<_Tp, _Dp>>
: public __hash_base<size_t, unique_ptr<_Tp, _Dp>>
{
size_t
operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
{
typedef unique_ptr<_Tp, _Dp> _UP;
return std::hash<typename _UP::pointer>()(__u.get());
}
};
// @} group pointer_abstractions
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _UNIQUE_PTR_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,109 @@
// Uses-allocator Construction -*- C++ -*-
// Copyright (C) 2010-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#ifndef _USES_ALLOCATOR_H
#define _USES_ALLOCATOR_H 1
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
#include <type_traits>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// [allocator.tag]
struct allocator_arg_t { };
constexpr allocator_arg_t allocator_arg = allocator_arg_t();
_GLIBCXX_HAS_NESTED_TYPE(allocator_type)
template<typename _Tp, typename _Alloc,
bool = __has_allocator_type<_Tp>::value>
struct __uses_allocator_helper
: public false_type { };
template<typename _Tp, typename _Alloc>
struct __uses_allocator_helper<_Tp, _Alloc, true>
: public integral_constant<bool, is_convertible<_Alloc,
typename _Tp::allocator_type>::value>
{ };
/// [allocator.uses.trait]
template<typename _Tp, typename _Alloc>
struct uses_allocator
: public integral_constant<bool,
__uses_allocator_helper<_Tp, _Alloc>::value>
{ };
template<typename _Tp, typename _Alloc, typename... _Args>
struct __uses_allocator_arg
: is_constructible<_Tp, _Alloc, _Args...>
{ static_assert( uses_allocator<_Tp, _Alloc>::value, "uses allocator" ); };
struct __uses_alloc_base { };
struct __uses_alloc0 : __uses_alloc_base
{ struct _Anything { _Anything(...) { } } _M_a; };
template<typename _Alloc>
struct __uses_alloc1 : __uses_alloc_base { const _Alloc* _M_a; };
template<typename _Alloc>
struct __uses_alloc2 : __uses_alloc_base { const _Alloc* _M_a; };
template<bool, typename _Alloc, typename... _Args>
struct __uses_alloc;
template<typename _Tp, typename _Alloc, typename... _Args>
struct __uses_alloc<true, _Tp, _Alloc, _Args...>
: conditional<
is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value,
__uses_alloc1<_Alloc>,
__uses_alloc2<_Alloc>>::type
{ };
template<typename _Tp, typename _Alloc, typename... _Args>
struct __uses_alloc<false, _Tp, _Alloc, _Args...>
: __uses_alloc0 { };
template<typename _Tp, typename _Alloc, typename... _Args>
struct __uses_alloc_impl
: __uses_alloc<uses_allocator<_Tp, _Alloc>::value, _Tp, _Alloc, _Args...>
{ };
template<typename _Tp, typename _Alloc, typename... _Args>
__uses_alloc_impl<_Tp, _Alloc, _Args...>
__use_alloc(const _Alloc& __a)
{
__uses_alloc_impl<_Tp, _Alloc, _Args...> __ret;
__ret._M_a = &__a;
return __ret;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif
#endif

View File

@@ -0,0 +1,551 @@
// The template and inlines for the -*- C++ -*- internal _Meta class.
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/valarray_after.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{valarray}
*/
// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
#ifndef _VALARRAY_AFTER_H
#define _VALARRAY_AFTER_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
//
// gslice_array closure.
//
template<class _Dom>
class _GBase
{
public:
typedef typename _Dom::value_type value_type;
_GBase (const _Dom& __e, const valarray<size_t>& __i)
: _M_expr (__e), _M_index(__i) {}
value_type
operator[] (size_t __i) const
{ return _M_expr[_M_index[__i]]; }
size_t
size () const
{ return _M_index.size(); }
private:
const _Dom& _M_expr;
const valarray<size_t>& _M_index;
};
template<typename _Tp>
class _GBase<_Array<_Tp> >
{
public:
typedef _Tp value_type;
_GBase (_Array<_Tp> __a, const valarray<size_t>& __i)
: _M_array (__a), _M_index(__i) {}
value_type
operator[] (size_t __i) const
{ return _M_array._M_data[_M_index[__i]]; }
size_t
size () const
{ return _M_index.size(); }
private:
const _Array<_Tp> _M_array;
const valarray<size_t>& _M_index;
};
template<class _Dom>
struct _GClos<_Expr, _Dom>
: _GBase<_Dom>
{
typedef _GBase<_Dom> _Base;
typedef typename _Base::value_type value_type;
_GClos (const _Dom& __e, const valarray<size_t>& __i)
: _Base (__e, __i) {}
};
template<typename _Tp>
struct _GClos<_ValArray, _Tp>
: _GBase<_Array<_Tp> >
{
typedef _GBase<_Array<_Tp> > _Base;
typedef typename _Base::value_type value_type;
_GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
: _Base (__a, __i) {}
};
//
// indirect_array closure
//
template<class _Dom>
class _IBase
{
public:
typedef typename _Dom::value_type value_type;
_IBase (const _Dom& __e, const valarray<size_t>& __i)
: _M_expr (__e), _M_index (__i) {}
value_type
operator[] (size_t __i) const
{ return _M_expr[_M_index[__i]]; }
size_t
size() const
{ return _M_index.size(); }
private:
const _Dom& _M_expr;
const valarray<size_t>& _M_index;
};
template<class _Dom>
struct _IClos<_Expr, _Dom>
: _IBase<_Dom>
{
typedef _IBase<_Dom> _Base;
typedef typename _Base::value_type value_type;
_IClos (const _Dom& __e, const valarray<size_t>& __i)
: _Base (__e, __i) {}
};
template<typename _Tp>
struct _IClos<_ValArray, _Tp>
: _IBase<valarray<_Tp> >
{
typedef _IBase<valarray<_Tp> > _Base;
typedef _Tp value_type;
_IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
: _Base (__a, __i) {}
};
//
// class _Expr
//
template<class _Clos, typename _Tp>
class _Expr
{
public:
typedef _Tp value_type;
_Expr(const _Clos&);
const _Clos& operator()() const;
value_type operator[](size_t) const;
valarray<value_type> operator[](slice) const;
valarray<value_type> operator[](const gslice&) const;
valarray<value_type> operator[](const valarray<bool>&) const;
valarray<value_type> operator[](const valarray<size_t>&) const;
_Expr<_UnClos<__unary_plus, std::_Expr, _Clos>, value_type>
operator+() const;
_Expr<_UnClos<__negate, std::_Expr, _Clos>, value_type>
operator-() const;
_Expr<_UnClos<__bitwise_not, std::_Expr, _Clos>, value_type>
operator~() const;
_Expr<_UnClos<__logical_not, std::_Expr, _Clos>, bool>
operator!() const;
size_t size() const;
value_type sum() const;
valarray<value_type> shift(int) const;
valarray<value_type> cshift(int) const;
value_type min() const;
value_type max() const;
valarray<value_type> apply(value_type (*)(const value_type&)) const;
valarray<value_type> apply(value_type (*)(value_type)) const;
private:
const _Clos _M_closure;
};
template<class _Clos, typename _Tp>
inline
_Expr<_Clos, _Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {}
template<class _Clos, typename _Tp>
inline const _Clos&
_Expr<_Clos, _Tp>::operator()() const
{ return _M_closure; }
template<class _Clos, typename _Tp>
inline _Tp
_Expr<_Clos, _Tp>::operator[](size_t __i) const
{ return _M_closure[__i]; }
template<class _Clos, typename _Tp>
inline valarray<_Tp>
_Expr<_Clos, _Tp>::operator[](slice __s) const
{
valarray<_Tp> __v = valarray<_Tp>(*this)[__s];
return __v;
}
template<class _Clos, typename _Tp>
inline valarray<_Tp>
_Expr<_Clos, _Tp>::operator[](const gslice& __gs) const
{
valarray<_Tp> __v = valarray<_Tp>(*this)[__gs];
return __v;
}
template<class _Clos, typename _Tp>
inline valarray<_Tp>
_Expr<_Clos, _Tp>::operator[](const valarray<bool>& __m) const
{
valarray<_Tp> __v = valarray<_Tp>(*this)[__m];
return __v;
}
template<class _Clos, typename _Tp>
inline valarray<_Tp>
_Expr<_Clos, _Tp>::operator[](const valarray<size_t>& __i) const
{
valarray<_Tp> __v = valarray<_Tp>(*this)[__i];
return __v;
}
template<class _Clos, typename _Tp>
inline size_t
_Expr<_Clos, _Tp>::size() const
{ return _M_closure.size(); }
template<class _Clos, typename _Tp>
inline valarray<_Tp>
_Expr<_Clos, _Tp>::shift(int __n) const
{
valarray<_Tp> __v = valarray<_Tp>(*this).shift(__n);
return __v;
}
template<class _Clos, typename _Tp>
inline valarray<_Tp>
_Expr<_Clos, _Tp>::cshift(int __n) const
{
valarray<_Tp> __v = valarray<_Tp>(*this).cshift(__n);
return __v;
}
template<class _Clos, typename _Tp>
inline valarray<_Tp>
_Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const
{
valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
return __v;
}
template<class _Clos, typename _Tp>
inline valarray<_Tp>
_Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const
{
valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
return __v;
}
// XXX: replace this with a more robust summation algorithm.
template<class _Clos, typename _Tp>
inline _Tp
_Expr<_Clos, _Tp>::sum() const
{
size_t __n = _M_closure.size();
if (__n == 0)
return _Tp();
else
{
_Tp __s = _M_closure[--__n];
while (__n != 0)
__s += _M_closure[--__n];
return __s;
}
}
template<class _Clos, typename _Tp>
inline _Tp
_Expr<_Clos, _Tp>::min() const
{ return __valarray_min(_M_closure); }
template<class _Clos, typename _Tp>
inline _Tp
_Expr<_Clos, _Tp>::max() const
{ return __valarray_max(_M_closure); }
template<class _Dom, typename _Tp>
inline _Expr<_UnClos<__logical_not, _Expr, _Dom>, bool>
_Expr<_Dom, _Tp>::operator!() const
{
typedef _UnClos<__logical_not, std::_Expr, _Dom> _Closure;
return _Expr<_Closure, bool>(_Closure(this->_M_closure));
}
#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \
template<class _Dom, typename _Tp> \
inline _Expr<_UnClos<_Name, std::_Expr, _Dom>, _Tp> \
_Expr<_Dom, _Tp>::operator _Op() const \
{ \
typedef _UnClos<_Name, std::_Expr, _Dom> _Closure; \
return _Expr<_Closure, _Tp>(_Closure(this->_M_closure)); \
}
_DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus)
_DEFINE_EXPR_UNARY_OPERATOR(-, __negate)
_DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not)
#undef _DEFINE_EXPR_UNARY_OPERATOR
#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \
template<class _Dom1, class _Dom2> \
inline _Expr<_BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2>, \
typename __fun<_Name, typename _Dom1::value_type>::result_type> \
operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \
const _Expr<_Dom2, typename _Dom2::value_type>& __w) \
{ \
typedef typename _Dom1::value_type _Arg; \
typedef typename __fun<_Name, _Arg>::result_type _Value; \
typedef _BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2> _Closure; \
return _Expr<_Closure, _Value>(_Closure(__v(), __w())); \
} \
\
template<class _Dom> \
inline _Expr<_BinClos<_Name, _Expr, _Constant, _Dom, \
typename _Dom::value_type>, \
typename __fun<_Name, typename _Dom::value_type>::result_type> \
operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \
const typename _Dom::value_type& __t) \
{ \
typedef typename _Dom::value_type _Arg; \
typedef typename __fun<_Name, _Arg>::result_type _Value; \
typedef _BinClos<_Name, _Expr, _Constant, _Dom, _Arg> _Closure; \
return _Expr<_Closure, _Value>(_Closure(__v(), __t)); \
} \
\
template<class _Dom> \
inline _Expr<_BinClos<_Name, _Constant, _Expr, \
typename _Dom::value_type, _Dom>, \
typename __fun<_Name, typename _Dom::value_type>::result_type> \
operator _Op(const typename _Dom::value_type& __t, \
const _Expr<_Dom, typename _Dom::value_type>& __v) \
{ \
typedef typename _Dom::value_type _Arg; \
typedef typename __fun<_Name, _Arg>::result_type _Value; \
typedef _BinClos<_Name, _Constant, _Expr, _Arg, _Dom> _Closure; \
return _Expr<_Closure, _Value>(_Closure(__t, __v())); \
} \
\
template<class _Dom> \
inline _Expr<_BinClos<_Name, _Expr, _ValArray, \
_Dom, typename _Dom::value_type>, \
typename __fun<_Name, typename _Dom::value_type>::result_type> \
operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \
const valarray<typename _Dom::value_type>& __v) \
{ \
typedef typename _Dom::value_type _Arg; \
typedef typename __fun<_Name, _Arg>::result_type _Value; \
typedef _BinClos<_Name, _Expr, _ValArray, _Dom, _Arg> _Closure; \
return _Expr<_Closure, _Value>(_Closure(__e(), __v)); \
} \
\
template<class _Dom> \
inline _Expr<_BinClos<_Name, _ValArray, _Expr, \
typename _Dom::value_type, _Dom>, \
typename __fun<_Name, typename _Dom::value_type>::result_type> \
operator _Op(const valarray<typename _Dom::value_type>& __v, \
const _Expr<_Dom, typename _Dom::value_type>& __e) \
{ \
typedef typename _Dom::value_type _Tp; \
typedef typename __fun<_Name, _Tp>::result_type _Value; \
typedef _BinClos<_Name, _ValArray, _Expr, _Tp, _Dom> _Closure; \
return _Expr<_Closure, _Value>(_Closure(__v, __e ())); \
}
_DEFINE_EXPR_BINARY_OPERATOR(+, __plus)
_DEFINE_EXPR_BINARY_OPERATOR(-, __minus)
_DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies)
_DEFINE_EXPR_BINARY_OPERATOR(/, __divides)
_DEFINE_EXPR_BINARY_OPERATOR(%, __modulus)
_DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor)
_DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and)
_DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or)
_DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)
_DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right)
_DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and)
_DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or)
_DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to)
_DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to)
_DEFINE_EXPR_BINARY_OPERATOR(<, __less)
_DEFINE_EXPR_BINARY_OPERATOR(>, __greater)
_DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal)
_DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal)
#undef _DEFINE_EXPR_BINARY_OPERATOR
#define _DEFINE_EXPR_UNARY_FUNCTION(_Name, _UName) \
template<class _Dom> \
inline _Expr<_UnClos<_UName, _Expr, _Dom>, \
typename _Dom::value_type> \
_Name(const _Expr<_Dom, typename _Dom::value_type>& __e) \
{ \
typedef typename _Dom::value_type _Tp; \
typedef _UnClos<_UName, _Expr, _Dom> _Closure; \
return _Expr<_Closure, _Tp>(_Closure(__e())); \
} \
\
template<typename _Tp> \
inline _Expr<_UnClos<_UName, _ValArray, _Tp>, _Tp> \
_Name(const valarray<_Tp>& __v) \
{ \
typedef _UnClos<_UName, _ValArray, _Tp> _Closure; \
return _Expr<_Closure, _Tp>(_Closure(__v)); \
}
_DEFINE_EXPR_UNARY_FUNCTION(abs, _Abs)
_DEFINE_EXPR_UNARY_FUNCTION(cos, _Cos)
_DEFINE_EXPR_UNARY_FUNCTION(acos, _Acos)
_DEFINE_EXPR_UNARY_FUNCTION(cosh, _Cosh)
_DEFINE_EXPR_UNARY_FUNCTION(sin, _Sin)
_DEFINE_EXPR_UNARY_FUNCTION(asin, _Asin)
_DEFINE_EXPR_UNARY_FUNCTION(sinh, _Sinh)
_DEFINE_EXPR_UNARY_FUNCTION(tan, _Tan)
_DEFINE_EXPR_UNARY_FUNCTION(tanh, _Tanh)
_DEFINE_EXPR_UNARY_FUNCTION(atan, _Atan)
_DEFINE_EXPR_UNARY_FUNCTION(exp, _Exp)
_DEFINE_EXPR_UNARY_FUNCTION(log, _Log)
_DEFINE_EXPR_UNARY_FUNCTION(log10, _Log10)
_DEFINE_EXPR_UNARY_FUNCTION(sqrt, _Sqrt)
#undef _DEFINE_EXPR_UNARY_FUNCTION
#define _DEFINE_EXPR_BINARY_FUNCTION(_Fun, _UFun) \
template<class _Dom1, class _Dom2> \
inline _Expr<_BinClos<_UFun, _Expr, _Expr, _Dom1, _Dom2>, \
typename _Dom1::value_type> \
_Fun(const _Expr<_Dom1, typename _Dom1::value_type>& __e1, \
const _Expr<_Dom2, typename _Dom2::value_type>& __e2) \
{ \
typedef typename _Dom1::value_type _Tp; \
typedef _BinClos<_UFun, _Expr, _Expr, _Dom1, _Dom2> _Closure; \
return _Expr<_Closure, _Tp>(_Closure(__e1(), __e2())); \
} \
\
template<class _Dom> \
inline _Expr<_BinClos<_UFun, _Expr, _ValArray, _Dom, \
typename _Dom::value_type>, \
typename _Dom::value_type> \
_Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \
const valarray<typename _Dom::value_type>& __v) \
{ \
typedef typename _Dom::value_type _Tp; \
typedef _BinClos<_UFun, _Expr, _ValArray, _Dom, _Tp> _Closure; \
return _Expr<_Closure, _Tp>(_Closure(__e(), __v)); \
} \
\
template<class _Dom> \
inline _Expr<_BinClos<_UFun, _ValArray, _Expr, \
typename _Dom::value_type, _Dom>, \
typename _Dom::value_type> \
_Fun(const valarray<typename _Dom::valarray>& __v, \
const _Expr<_Dom, typename _Dom::value_type>& __e) \
{ \
typedef typename _Dom::value_type _Tp; \
typedef _BinClos<_UFun, _ValArray, _Expr, _Tp, _Dom> _Closure; \
return _Expr<_Closure, _Tp>(_Closure(__v, __e())); \
} \
\
template<class _Dom> \
inline _Expr<_BinClos<_UFun, _Expr, _Constant, _Dom, \
typename _Dom::value_type>, \
typename _Dom::value_type> \
_Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \
const typename _Dom::value_type& __t) \
{ \
typedef typename _Dom::value_type _Tp; \
typedef _BinClos<_UFun, _Expr, _Constant, _Dom, _Tp> _Closure; \
return _Expr<_Closure, _Tp>(_Closure(__e(), __t)); \
} \
\
template<class _Dom> \
inline _Expr<_BinClos<_UFun, _Constant, _Expr, \
typename _Dom::value_type, _Dom>, \
typename _Dom::value_type> \
_Fun(const typename _Dom::value_type& __t, \
const _Expr<_Dom, typename _Dom::value_type>& __e) \
{ \
typedef typename _Dom::value_type _Tp; \
typedef _BinClos<_UFun, _Constant, _Expr, _Tp, _Dom> _Closure; \
return _Expr<_Closure, _Tp>(_Closure(__t, __e())); \
} \
\
template<typename _Tp> \
inline _Expr<_BinClos<_UFun, _ValArray, _ValArray, _Tp, _Tp>, _Tp> \
_Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
{ \
typedef _BinClos<_UFun, _ValArray, _ValArray, _Tp, _Tp> _Closure;\
return _Expr<_Closure, _Tp>(_Closure(__v, __w)); \
} \
\
template<typename _Tp> \
inline _Expr<_BinClos<_UFun, _ValArray, _Constant, _Tp, _Tp>, _Tp> \
_Fun(const valarray<_Tp>& __v, const _Tp& __t) \
{ \
typedef _BinClos<_UFun, _ValArray, _Constant, _Tp, _Tp> _Closure;\
return _Expr<_Closure, _Tp>(_Closure(__v, __t)); \
} \
\
template<typename _Tp> \
inline _Expr<_BinClos<_UFun, _Constant, _ValArray, _Tp, _Tp>, _Tp> \
_Fun(const _Tp& __t, const valarray<_Tp>& __v) \
{ \
typedef _BinClos<_UFun, _Constant, _ValArray, _Tp, _Tp> _Closure;\
return _Expr<_Closure, _Tp>(_Closure(__t, __v)); \
}
_DEFINE_EXPR_BINARY_FUNCTION(atan2, _Atan2)
_DEFINE_EXPR_BINARY_FUNCTION(pow, _Pow)
#undef _DEFINE_EXPR_BINARY_FUNCTION
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _CPP_VALARRAY_AFTER_H */

View File

@@ -0,0 +1,693 @@
// The template and inlines for the -*- C++ -*- internal _Array helper class.
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/valarray_array.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{valarray}
*/
// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
#ifndef _VALARRAY_ARRAY_H
#define _VALARRAY_ARRAY_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/cpp_type_traits.h>
#include <cstdlib>
#include <new>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
//
// Helper functions on raw pointers
//
// We get memory by the old fashion way
inline void*
__valarray_get_memory(size_t __n)
{ return operator new(__n); }
template<typename _Tp>
inline _Tp*__restrict__
__valarray_get_storage(size_t __n)
{
return static_cast<_Tp*__restrict__>
(std::__valarray_get_memory(__n * sizeof(_Tp)));
}
// Return memory to the system
inline void
__valarray_release_memory(void* __p)
{ operator delete(__p); }
// Turn a raw-memory into an array of _Tp filled with _Tp()
// This is required in 'valarray<T> v(n);'
template<typename _Tp, bool>
struct _Array_default_ctor
{
// Please note that this isn't exception safe. But
// valarrays aren't required to be exception safe.
inline static void
_S_do_it(_Tp* __b, _Tp* __e)
{
while (__b != __e)
new(__b++) _Tp();
}
};
template<typename _Tp>
struct _Array_default_ctor<_Tp, true>
{
// For fundamental types, it suffices to say 'memset()'
inline static void
_S_do_it(_Tp* __b, _Tp* __e)
{ __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); }
};
template<typename _Tp>
inline void
__valarray_default_construct(_Tp* __b, _Tp* __e)
{
_Array_default_ctor<_Tp, __is_scalar<_Tp>::__value>::_S_do_it(__b, __e);
}
// Turn a raw-memory into an array of _Tp filled with __t
// This is the required in valarray<T> v(n, t). Also
// used in valarray<>::resize().
template<typename _Tp, bool>
struct _Array_init_ctor
{
// Please note that this isn't exception safe. But
// valarrays aren't required to be exception safe.
inline static void
_S_do_it(_Tp* __b, _Tp* __e, const _Tp __t)
{
while (__b != __e)
new(__b++) _Tp(__t);
}
};
template<typename _Tp>
struct _Array_init_ctor<_Tp, true>
{
inline static void
_S_do_it(_Tp* __b, _Tp* __e, const _Tp __t)
{
while (__b != __e)
*__b++ = __t;
}
};
template<typename _Tp>
inline void
__valarray_fill_construct(_Tp* __b, _Tp* __e, const _Tp __t)
{
_Array_init_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __t);
}
//
// copy-construct raw array [__o, *) from plain array [__b, __e)
// We can't just say 'memcpy()'
//
template<typename _Tp, bool>
struct _Array_copy_ctor
{
// Please note that this isn't exception safe. But
// valarrays aren't required to be exception safe.
inline static void
_S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o)
{
while (__b != __e)
new(__o++) _Tp(*__b++);
}
};
template<typename _Tp>
struct _Array_copy_ctor<_Tp, true>
{
inline static void
_S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o)
{ __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); }
};
template<typename _Tp>
inline void
__valarray_copy_construct(const _Tp* __b, const _Tp* __e,
_Tp* __restrict__ __o)
{
_Array_copy_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __o);
}
// copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
template<typename _Tp>
inline void
__valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
size_t __s, _Tp* __restrict__ __o)
{
if (__is_trivial(_Tp))
while (__n--)
{
*__o++ = *__a;
__a += __s;
}
else
while (__n--)
{
new(__o++) _Tp(*__a);
__a += __s;
}
}
// copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]]
template<typename _Tp>
inline void
__valarray_copy_construct (const _Tp* __restrict__ __a,
const size_t* __restrict__ __i,
_Tp* __restrict__ __o, size_t __n)
{
if (__is_trivial(_Tp))
while (__n--)
*__o++ = __a[*__i++];
else
while (__n--)
new (__o++) _Tp(__a[*__i++]);
}
// Do the necessary cleanup when we're done with arrays.
template<typename _Tp>
inline void
__valarray_destroy_elements(_Tp* __b, _Tp* __e)
{
if (!__is_trivial(_Tp))
while (__b != __e)
{
__b->~_Tp();
++__b;
}
}
// Fill a plain array __a[<__n>] with __t
template<typename _Tp>
inline void
__valarray_fill(_Tp* __restrict__ __a, size_t __n, const _Tp& __t)
{
while (__n--)
*__a++ = __t;
}
// fill strided array __a[<__n-1 : __s>] with __t
template<typename _Tp>
inline void
__valarray_fill(_Tp* __restrict__ __a, size_t __n,
size_t __s, const _Tp& __t)
{
for (size_t __i = 0; __i < __n; ++__i, __a += __s)
*__a = __t;
}
// fill indirect array __a[__i[<__n>]] with __i
template<typename _Tp>
inline void
__valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i,
size_t __n, const _Tp& __t)
{
for (size_t __j = 0; __j < __n; ++__j, ++__i)
__a[*__i] = __t;
}
// copy plain array __a[<__n>] in __b[<__n>]
// For non-fundamental types, it is wrong to say 'memcpy()'
template<typename _Tp, bool>
struct _Array_copier
{
inline static void
_S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
{
while(__n--)
*__b++ = *__a++;
}
};
template<typename _Tp>
struct _Array_copier<_Tp, true>
{
inline static void
_S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
{ __builtin_memcpy(__b, __a, __n * sizeof (_Tp)); }
};
// Copy a plain array __a[<__n>] into a play array __b[<>]
template<typename _Tp>
inline void
__valarray_copy(const _Tp* __restrict__ __a, size_t __n,
_Tp* __restrict__ __b)
{
_Array_copier<_Tp, __is_trivial(_Tp)>::_S_do_it(__a, __n, __b);
}
// Copy strided array __a[<__n : __s>] in plain __b[<__n>]
template<typename _Tp>
inline void
__valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s,
_Tp* __restrict__ __b)
{
for (size_t __i = 0; __i < __n; ++__i, ++__b, __a += __s)
*__b = *__a;
}
// Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>]
template<typename _Tp>
inline void
__valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b,
size_t __n, size_t __s)
{
for (size_t __i = 0; __i < __n; ++__i, ++__a, __b += __s)
*__b = *__a;
}
// Copy strided array __src[<__n : __s1>] into another
// strided array __dst[< : __s2>]. Their sizes must match.
template<typename _Tp>
inline void
__valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1,
_Tp* __restrict__ __dst, size_t __s2)
{
for (size_t __i = 0; __i < __n; ++__i)
__dst[__i * __s2] = __src[__i * __s1];
}
// Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
template<typename _Tp>
inline void
__valarray_copy(const _Tp* __restrict__ __a,
const size_t* __restrict__ __i,
_Tp* __restrict__ __b, size_t __n)
{
for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i)
*__b = __a[*__i];
}
// Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
template<typename _Tp>
inline void
__valarray_copy(const _Tp* __restrict__ __a, size_t __n,
_Tp* __restrict__ __b, const size_t* __restrict__ __i)
{
for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i)
__b[*__i] = *__a;
}
// Copy the __n first elements of an indexed array __src[<__i>] into
// another indexed array __dst[<__j>].
template<typename _Tp>
inline void
__valarray_copy(const _Tp* __restrict__ __src, size_t __n,
const size_t* __restrict__ __i,
_Tp* __restrict__ __dst, const size_t* __restrict__ __j)
{
for (size_t __k = 0; __k < __n; ++__k)
__dst[*__j++] = __src[*__i++];
}
//
// Compute the sum of elements in range [__f, __l)
// This is a naive algorithm. It suffers from cancelling.
// In the future try to specialize
// for _Tp = float, double, long double using a more accurate
// algorithm.
//
template<typename _Tp>
inline _Tp
__valarray_sum(const _Tp* __f, const _Tp* __l)
{
_Tp __r = _Tp();
while (__f != __l)
__r += *__f++;
return __r;
}
// Compute the product of all elements in range [__f, __l)
template<typename _Tp>
inline _Tp
__valarray_product(const _Tp* __f, const _Tp* __l)
{
_Tp __r = _Tp(1);
while (__f != __l)
__r = __r * *__f++;
return __r;
}
// Compute the min/max of an array-expression
template<typename _Ta>
inline typename _Ta::value_type
__valarray_min(const _Ta& __a)
{
size_t __s = __a.size();
typedef typename _Ta::value_type _Value_type;
_Value_type __r = __s == 0 ? _Value_type() : __a[0];
for (size_t __i = 1; __i < __s; ++__i)
{
_Value_type __t = __a[__i];
if (__t < __r)
__r = __t;
}
return __r;
}
template<typename _Ta>
inline typename _Ta::value_type
__valarray_max(const _Ta& __a)
{
size_t __s = __a.size();
typedef typename _Ta::value_type _Value_type;
_Value_type __r = __s == 0 ? _Value_type() : __a[0];
for (size_t __i = 1; __i < __s; ++__i)
{
_Value_type __t = __a[__i];
if (__t > __r)
__r = __t;
}
return __r;
}
//
// Helper class _Array, first layer of valarray abstraction.
// All operations on valarray should be forwarded to this class
// whenever possible. -- gdr
//
template<typename _Tp>
struct _Array
{
explicit _Array(size_t);
explicit _Array(_Tp* const __restrict__);
explicit _Array(const valarray<_Tp>&);
_Array(const _Tp* __restrict__, size_t);
_Tp* begin() const;
_Tp* const __restrict__ _M_data;
};
// Copy-construct plain array __b[<__n>] from indexed array __a[__i[<__n>]]
template<typename _Tp>
inline void
__valarray_copy_construct(_Array<_Tp> __a, _Array<size_t> __i,
_Array<_Tp> __b, size_t __n)
{ std::__valarray_copy_construct(__a._M_data, __i._M_data,
__b._M_data, __n); }
// Copy-construct plain array __b[<__n>] from strided array __a[<__n : __s>]
template<typename _Tp>
inline void
__valarray_copy_construct(_Array<_Tp> __a, size_t __n, size_t __s,
_Array<_Tp> __b)
{ std::__valarray_copy_construct(__a._M_data, __n, __s, __b._M_data); }
template<typename _Tp>
inline void
__valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t)
{ std::__valarray_fill(__a._M_data, __n, __t); }
template<typename _Tp>
inline void
__valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t)
{ std::__valarray_fill(__a._M_data, __n, __s, __t); }
template<typename _Tp>
inline void
__valarray_fill(_Array<_Tp> __a, _Array<size_t> __i,
size_t __n, const _Tp& __t)
{ std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); }
// Copy a plain array __a[<__n>] into a play array __b[<>]
template<typename _Tp>
inline void
__valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)
{ std::__valarray_copy(__a._M_data, __n, __b._M_data); }
// Copy strided array __a[<__n : __s>] in plain __b[<__n>]
template<typename _Tp>
inline void
__valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b)
{ std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); }
// Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>]
template<typename _Tp>
inline void
__valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s)
{ __valarray_copy(__a._M_data, __b._M_data, __n, __s); }
// Copy strided array __src[<__n : __s1>] into another
// strided array __dst[< : __s2>]. Their sizes must match.
template<typename _Tp>
inline void
__valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1,
_Array<_Tp> __b, size_t __s2)
{ std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); }
// Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
template<typename _Tp>
inline void
__valarray_copy(_Array<_Tp> __a, _Array<size_t> __i,
_Array<_Tp> __b, size_t __n)
{ std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); }
// Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
template<typename _Tp>
inline void
__valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
_Array<size_t> __i)
{ std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); }
// Copy the __n first elements of an indexed array __src[<__i>] into
// another indexed array __dst[<__j>].
template<typename _Tp>
inline void
__valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i,
_Array<_Tp> __dst, _Array<size_t> __j)
{
std::__valarray_copy(__src._M_data, __n, __i._M_data,
__dst._M_data, __j._M_data);
}
template<typename _Tp>
inline
_Array<_Tp>::_Array(size_t __n)
: _M_data(__valarray_get_storage<_Tp>(__n))
{ std::__valarray_default_construct(_M_data, _M_data + __n); }
template<typename _Tp>
inline
_Array<_Tp>::_Array(_Tp* const __restrict__ __p)
: _M_data (__p) {}
template<typename _Tp>
inline
_Array<_Tp>::_Array(const valarray<_Tp>& __v)
: _M_data (__v._M_data) {}
template<typename _Tp>
inline
_Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s)
: _M_data(__valarray_get_storage<_Tp>(__s))
{ std::__valarray_copy_construct(__b, __s, _M_data); }
template<typename _Tp>
inline _Tp*
_Array<_Tp>::begin () const
{ return _M_data; }
#define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \
template<typename _Tp> \
inline void \
_Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \
{ \
for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p) \
*__p _Op##= __t; \
} \
\
template<typename _Tp> \
inline void \
_Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \
{ \
_Tp* __p = __a._M_data; \
for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \
*__p _Op##= *__q; \
} \
\
template<typename _Tp, class _Dom> \
void \
_Array_augmented_##_Name(_Array<_Tp> __a, \
const _Expr<_Dom, _Tp>& __e, size_t __n) \
{ \
_Tp* __p(__a._M_data); \
for (size_t __i = 0; __i < __n; ++__i, ++__p) \
*__p _Op##= __e[__i]; \
} \
\
template<typename _Tp> \
inline void \
_Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s, \
_Array<_Tp> __b) \
{ \
_Tp* __q(__b._M_data); \
for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n; \
__p += __s, ++__q) \
*__p _Op##= *__q; \
} \
\
template<typename _Tp> \
inline void \
_Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b, \
size_t __n, size_t __s) \
{ \
_Tp* __q(__b._M_data); \
for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \
++__p, __q += __s) \
*__p _Op##= *__q; \
} \
\
template<typename _Tp, class _Dom> \
void \
_Array_augmented_##_Name(_Array<_Tp> __a, size_t __s, \
const _Expr<_Dom, _Tp>& __e, size_t __n) \
{ \
_Tp* __p(__a._M_data); \
for (size_t __i = 0; __i < __n; ++__i, __p += __s) \
*__p _Op##= __e[__i]; \
} \
\
template<typename _Tp> \
inline void \
_Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \
_Array<_Tp> __b, size_t __n) \
{ \
_Tp* __q(__b._M_data); \
for (size_t* __j = __i._M_data; __j < __i._M_data + __n; \
++__j, ++__q) \
__a._M_data[*__j] _Op##= *__q; \
} \
\
template<typename _Tp> \
inline void \
_Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \
_Array<_Tp> __b, _Array<size_t> __i) \
{ \
_Tp* __p(__a._M_data); \
for (size_t* __j = __i._M_data; __j<__i._M_data + __n; \
++__j, ++__p) \
*__p _Op##= __b._M_data[*__j]; \
} \
\
template<typename _Tp, class _Dom> \
void \
_Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \
const _Expr<_Dom, _Tp>& __e, size_t __n) \
{ \
size_t* __j(__i._M_data); \
for (size_t __k = 0; __k<__n; ++__k, ++__j) \
__a._M_data[*__j] _Op##= __e[__k]; \
} \
\
template<typename _Tp> \
void \
_Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \
_Array<_Tp> __b, size_t __n) \
{ \
bool* __ok(__m._M_data); \
_Tp* __p(__a._M_data); \
for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; \
++__q, ++__ok, ++__p) \
{ \
while (! *__ok) \
{ \
++__ok; \
++__p; \
} \
*__p _Op##= *__q; \
} \
} \
\
template<typename _Tp> \
void \
_Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \
_Array<_Tp> __b, _Array<bool> __m) \
{ \
bool* __ok(__m._M_data); \
_Tp* __q(__b._M_data); \
for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \
++__p, ++__ok, ++__q) \
{ \
while (! *__ok) \
{ \
++__ok; \
++__q; \
} \
*__p _Op##= *__q; \
} \
} \
\
template<typename _Tp, class _Dom> \
void \
_Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \
const _Expr<_Dom, _Tp>& __e, size_t __n) \
{ \
bool* __ok(__m._M_data); \
_Tp* __p(__a._M_data); \
for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) \
{ \
while (! *__ok) \
{ \
++__ok; \
++__p; \
} \
*__p _Op##= __e[__i]; \
} \
}
_DEFINE_ARRAY_FUNCTION(+, __plus)
_DEFINE_ARRAY_FUNCTION(-, __minus)
_DEFINE_ARRAY_FUNCTION(*, __multiplies)
_DEFINE_ARRAY_FUNCTION(/, __divides)
_DEFINE_ARRAY_FUNCTION(%, __modulus)
_DEFINE_ARRAY_FUNCTION(^, __bitwise_xor)
_DEFINE_ARRAY_FUNCTION(|, __bitwise_or)
_DEFINE_ARRAY_FUNCTION(&, __bitwise_and)
_DEFINE_ARRAY_FUNCTION(<<, __shift_left)
_DEFINE_ARRAY_FUNCTION(>>, __shift_right)
#undef _DEFINE_ARRAY_FUNCTION
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
# include <bits/valarray_array.tcc>
#endif /* _ARRAY_H */

View File

@@ -0,0 +1,244 @@
// The template and inlines for the -*- C++ -*- internal _Array helper class.
// Copyright (C) 1997-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/valarray_array.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{valarray}
*/
// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
#ifndef _VALARRAY_ARRAY_TCC
#define _VALARRAY_ARRAY_TCC 1
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
void
__valarray_fill(_Array<_Tp> __a, size_t __n, _Array<bool> __m,
const _Tp& __t)
{
_Tp* __p = __a._M_data;
bool* __ok (__m._M_data);
for (size_t __i=0; __i < __n; ++__i, ++__ok, ++__p)
{
while (!*__ok)
{
++__ok;
++__p;
}
*__p = __t;
}
}
// Copy n elements of a into consecutive elements of b. When m is
// false, the corresponding element of a is skipped. m must contain
// at least n true elements. a must contain at least n elements and
// enough elements to match up with m through the nth true element
// of m. I.e. if n is 10, m has 15 elements with 5 false followed
// by 10 true, a must have 15 elements.
template<typename _Tp>
void
__valarray_copy(_Array<_Tp> __a, _Array<bool> __m, _Array<_Tp> __b,
size_t __n)
{
_Tp* __p (__a._M_data);
bool* __ok (__m._M_data);
for (_Tp* __q = __b._M_data; __q < __b._M_data + __n;
++__q, ++__ok, ++__p)
{
while (! *__ok)
{
++__ok;
++__p;
}
*__q = *__p;
}
}
// Copy n consecutive elements from a into elements of b. Elements
// of b are skipped if the corresponding element of m is false. m
// must contain at least n true elements. b must have at least as
// many elements as the index of the nth true element of m. I.e. if
// m has 15 elements with 5 false followed by 10 true, b must have
// at least 15 elements.
template<typename _Tp>
void
__valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
_Array<bool> __m)
{
_Tp* __q (__b._M_data);
bool* __ok (__m._M_data);
for (_Tp* __p = __a._M_data; __p < __a._M_data+__n;
++__p, ++__ok, ++__q)
{
while (! *__ok)
{
++__ok;
++__q;
}
*__q = *__p;
}
}
// Copy n elements from a into elements of b. Elements of a are
// skipped if the corresponding element of m is false. Elements of
// b are skipped if the corresponding element of k is false. m and
// k must contain at least n true elements. a and b must have at
// least as many elements as the index of the nth true element of m.
template<typename _Tp>
void
__valarray_copy(_Array<_Tp> __a, _Array<bool> __m, size_t __n,
_Array<_Tp> __b, _Array<bool> __k)
{
_Tp* __p (__a._M_data);
_Tp* __q (__b._M_data);
bool* __srcok (__m._M_data);
bool* __dstok (__k._M_data);
for (size_t __i = 0; __i < __n;
++__srcok, ++__p, ++__dstok, ++__q, ++__i)
{
while (! *__srcok)
{
++__srcok;
++__p;
}
while (! *__dstok)
{
++__dstok;
++__q;
}
*__q = *__p;
}
}
// Copy n consecutive elements of e into consecutive elements of a.
// I.e. a[i] = e[i].
template<typename _Tp, class _Dom>
void
__valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a)
{
_Tp* __p (__a._M_data);
for (size_t __i = 0; __i < __n; ++__i, ++__p)
*__p = __e[__i];
}
// Copy n consecutive elements of e into elements of a using stride
// s. I.e., a[0] = e[0], a[s] = e[1], a[2*s] = e[2].
template<typename _Tp, class _Dom>
void
__valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
_Array<_Tp> __a, size_t __s)
{
_Tp* __p (__a._M_data);
for (size_t __i = 0; __i < __n; ++__i, __p += __s)
*__p = __e[__i];
}
// Copy n consecutive elements of e into elements of a indexed by
// contents of i. I.e., a[i[0]] = e[0].
template<typename _Tp, class _Dom>
void
__valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
_Array<_Tp> __a, _Array<size_t> __i)
{
size_t* __j (__i._M_data);
for (size_t __k = 0; __k < __n; ++__k, ++__j)
__a._M_data[*__j] = __e[__k];
}
// Copy n elements of e indexed by contents of f into elements of a
// indexed by contents of i. I.e., a[i[0]] = e[f[0]].
template<typename _Tp>
void
__valarray_copy(_Array<_Tp> __e, _Array<size_t> __f,
size_t __n,
_Array<_Tp> __a, _Array<size_t> __i)
{
size_t* __g (__f._M_data);
size_t* __j (__i._M_data);
for (size_t __k = 0; __k < __n; ++__k, ++__j, ++__g)
__a._M_data[*__j] = __e._M_data[*__g];
}
// Copy n consecutive elements of e into elements of a. Elements of
// a are skipped if the corresponding element of m is false. m must
// have at least n true elements and a must have at least as many
// elements as the index of the nth true element of m. I.e. if m
// has 5 false followed by 10 true elements and n == 10, a must have
// at least 15 elements.
template<typename _Tp, class _Dom>
void
__valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
_Array<_Tp> __a, _Array<bool> __m)
{
bool* __ok (__m._M_data);
_Tp* __p (__a._M_data);
for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)
{
while (! *__ok)
{
++__ok;
++__p;
}
*__p = __e[__i];
}
}
template<typename _Tp, class _Dom>
void
__valarray_copy_construct(const _Expr<_Dom, _Tp>& __e, size_t __n,
_Array<_Tp> __a)
{
_Tp* __p (__a._M_data);
for (size_t __i = 0; __i < __n; ++__i, ++__p)
new (__p) _Tp(__e[__i]);
}
template<typename _Tp>
void
__valarray_copy_construct(_Array<_Tp> __a, _Array<bool> __m,
_Array<_Tp> __b, size_t __n)
{
_Tp* __p (__a._M_data);
bool* __ok (__m._M_data);
for (_Tp* __q = __b._M_data; __q < __b._M_data+__n; ++__q, ++__ok, ++__p)
{
while (! *__ok)
{
++__ok;
++__p;
}
new (__q) _Tp(*__p);
}
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _VALARRAY_ARRAY_TCC */

Some files were not shown because too many files have changed in this diff Show More