[egcs-971008] Internal errors
Hyman Rosen
hymie@prolifics.com
Thu Oct 9 09:58:00 GMT 1997
The following code, compiled as 'g++ -O g.cc', gives this error
in both Linux and Solaris.
g.cc: In function `enum spot * __uninitialized_fill_n_aux<spot *, unsigned int, spot>(enum spot *, unsigned int, const enum spot &, struct __false_type)':
g.cc:2240: Internal compiler error.
g.cc:2240: Please submit a full bug report to `egcs-bugs@cygnus.com'.
When compiled as 'g++ -O6 g.cc' on Solaris, it gives
g.cc: In function `enum spot * __uninitialized_fill_n_aux<spot *, unsigned int, spot>(enum spot *, unsigned int, const enum spot &, struct __false_type)':
g.cc:2240: internal error--insn does not satisfy its constraints:
(insn 353 349 166 (set (reg:SI 10 %o2)
(reg/v:SI 105)) 110 {*movsi_insn} (insn_list 153 (insn_list 156 (insn_list:REG_DEP_ANTI 157 (nil))))
(expr_list:REG_DEAD (const_int -14)
(expr_list:REG_DEAD (const_int 68696)
(nil))))
g.cc:2240: confused by earlier errors, bailing out
///////// Sample data to feed it once it compiles successfully ///////////////
10 10
1 1
1 2
2 1 6
1 9
1 6
1 5
1 5
1 4
1 3
1 4
1 2
2 1 1
1 4
2 2 1
2 3 1
1 8
1 8
1 7
1 5
1 3
///////////////////////////////// g.cc ///////////////////////////////////////
extern "C" {
}
extern "C" {
typedef struct {
int quot;
int rem;
} div_t;
typedef struct {
long quot;
long rem;
} ldiv_t;
typedef struct {
long long quot;
long long rem;
} lldiv_t;
typedef unsigned int size_t;
typedef long uid_t;
typedef __wchar_t wchar_t;
extern unsigned char __ctype[];
extern double atof(const char *);
extern int atoi(const char *);
extern long int atol(const char *);
extern double strtod(const char *, char **);
extern long int strtol(const char *, char **, int);
extern unsigned long int strtoul(const char *, char **, int);
extern int rand(void);
extern void srand(unsigned int);
extern void *calloc(size_t, size_t);
extern void free(void *);
extern void *malloc(size_t);
extern void *realloc(void *, size_t);
extern void abort(void);
extern int atexit(void (*)(void));
extern void exit(int);
extern char *getenv(const char *);
extern int system(const char *);
extern void *bsearch(const void *, const void *, size_t, size_t,
int (*)(const void *, const void *));
extern void qsort(void *, size_t, size_t,
int (*)(const void *, const void *));
extern int abs(int);
extern div_t div(int, int);
extern long int labs(long);
extern ldiv_t ldiv(long, long);
extern int mbtowc(wchar_t *, const char *, size_t);
extern int mblen(const char *, size_t);
extern int wctomb(char *, wchar_t);
extern size_t mbstowcs(wchar_t *, const char *, size_t);
extern size_t wcstombs(char *, const wchar_t *, size_t);
extern double drand48(void);
extern double erand48(unsigned short *);
extern long jrand48(unsigned short *);
extern void lcong48(unsigned short *);
extern long lrand48(void);
extern long mrand48(void);
extern long nrand48(unsigned short *);
extern unsigned short *seed48(unsigned short *);
extern void srand48(long);
extern int putenv(const char *);
extern void setkey(const char *);
extern void swab(const char *, char *, int);
extern long a64l(const char *);
extern int dup2(int, int);
extern char *ecvt(double, int, int *, int *);
extern char *fcvt(double, int, int *, int *);
extern char *qecvt(long double, int, int *, int *);
extern char *qfcvt(long double, int, int *, int *);
extern char *qgcvt(long double, int, char *);
extern char *getcwd(char *, size_t);
extern char *getlogin(void);
extern int getopt(int, char *const *, const char *);
extern int getsubopt(char **, char *const *, char **);
extern char *optarg;
extern int optind, opterr, optopt;
extern char *getpass(const char *);
extern int getpw(uid_t, char *);
extern char *gcvt(double, int, char *);
extern int isatty(int);
extern char *l64a(long);
extern void *memalign(size_t, size_t);
extern char *mktemp(char *);
extern char *realpath(char *, char *);
extern char *ttyname(int);
extern int ttyslot(void);
extern void *valloc(size_t);
extern char *ptsname(int);
extern int grantpt(int);
extern int unlockpt(int);
extern long long atoll(const char *);
extern long long llabs(long long);
extern lldiv_t lldiv(long long, long long);
extern char *lltostr(long long, char *);
extern long long strtoll(const char *, char **, int);
extern unsigned long long strtoull(const char *, char **, int);
extern char *ulltostr(unsigned long long, char *);
}
extern "C" {
}
extern "C" {
extern long _sysconf(int);
}
extern "C" {
extern void *memcpy(void *, const void *, size_t);
extern void *memmove(void *, const void *, size_t);
extern char *strcpy(char *, const char *);
extern char *strncpy(char *, const char *, size_t);
extern char *strcat(char *, const char *);
extern char *strncat(char *, const char *, size_t);
extern int memcmp(const void *, const void *, size_t);
extern int strcmp(const char *, const char *);
extern int strcoll(const char *, const char *);
extern int strncmp(const char *, const char *, size_t);
extern size_t strxfrm(char *, const char *, size_t);
extern void *memchr(const void *, int, size_t);
extern char *strchr(const char *, int);
extern size_t strcspn(const char *, const char *);
extern char *strpbrk(const char *, const char *);
extern char *strrchr(const char *, int);
extern size_t strspn(const char *, const char *);
extern char *strstr(const char *, const char *);
extern char *strtok(char *, const char *);
extern void *memset(void *, int, size_t);
extern char *strerror(int);
extern size_t strlen(const char *);
extern void *memccpy(void *, const void *, int, size_t);
extern char *strdup(const char *);
extern char *strsignal(int);
extern int ffs(const int);
extern int strcasecmp(const char *, const char *);
extern int strncasecmp(const char *, const char *, size_t);
}
typedef int ptrdiff_t;
typedef unsigned int wint_t;
template <class T>
inline bool operator!=(const T& x, const T& y) {
return !(x == y);
}
template <class T>
inline bool operator>(const T& x, const T& y) {
return y < x;
}
template <class T>
inline bool operator<=(const T& x, const T& y) {
return !(y < x);
}
template <class T>
inline bool operator>=(const T& x, const T& y) {
return !(x < y);
}
template <class Arg, class Result>
struct unary_function {
typedef Arg argument_type;
typedef Result result_type;
};
template <class Arg1, class Arg2, class Result>
struct binary_function {
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
template <class T>
struct plus : public binary_function<T, T, T> {
T operator()(const T& x, const T& y) const { return x + y; }
};
template <class T>
struct minus : public binary_function<T, T, T> {
T operator()(const T& x, const T& y) const { return x - y; }
};
template <class T>
struct multiplies : public binary_function<T, T, T> {
T operator()(const T& x, const T& y) const { return x * y; }
};
template <class T>
struct divides : public binary_function<T, T, T> {
T operator()(const T& x, const T& y) const { return x / y; }
};
template <class T> inline T identity_element(plus<T>) { return T(0); }
template <class T> inline T identity_element(multiplies<T>) { return T(1); }
template <class T>
struct modulus : public binary_function<T, T, T> {
T operator()(const T& x, const T& y) const { return x % y; }
};
template <class T>
struct negate : public unary_function<T, T> {
T operator()(const T& x) const { return -x; }
};
template <class T>
struct equal_to : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x == y; }
};
template <class T>
struct not_equal_to : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x != y; }
};
template <class T>
struct greater : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x > y; }
};
template <class T>
struct less : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x < y; }
};
template <class T>
struct greater_equal : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x >= y; }
};
template <class T>
struct less_equal : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x <= y; }
};
template <class T>
struct logical_and : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x && y; }
};
template <class T>
struct logical_or : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x || y; }
};
template <class T>
struct logical_not : public unary_function<T, bool> {
bool operator()(const T& x) const { return !x; }
};
template <class Predicate>
class unary_negate
: public unary_function<typename Predicate::argument_type, bool> {
protected:
Predicate pred;
public:
explicit unary_negate(const Predicate& x) : pred(x) {}
bool operator()(const argument_type& x) const { return !pred(x); }
};
template <class Predicate>
inline unary_negate<Predicate> not1(const Predicate& pred) {
return unary_negate<Predicate>(pred);
}
template <class Predicate>
class binary_negate
: public binary_function<typename Predicate::first_argument_type,
typename Predicate::second_argument_type,
bool> {
protected:
Predicate pred;
public:
explicit binary_negate(const Predicate& x) : pred(x) {}
bool operator()(const first_argument_type& x,
const second_argument_type& y) const {
return !pred(x, y);
}
};
template <class Predicate>
inline binary_negate<Predicate> not2(const Predicate& pred) {
return binary_negate<Predicate>(pred);
}
template <class Operation>
class binder1st
: public unary_function<typename Operation::second_argument_type,
typename Operation::result_type> {
protected:
Operation op;
typename Operation::first_argument_type value;
public:
binder1st(const Operation& x,
const typename Operation::first_argument_type& y)
: op(x), value(y) {}
result_type operator()(const argument_type& x) const {
return op(value, x);
}
};
template <class Operation, class T>
inline binder1st<Operation> bind1st(const Operation& op, const T& x) {
typedef typename Operation::first_argument_type arg1_type;
return binder1st<Operation>(op, arg1_type(x));
}
template <class Operation>
class binder2nd
: public unary_function<typename Operation::first_argument_type,
typename Operation::result_type> {
protected:
Operation op;
typename Operation::second_argument_type value;
public:
binder2nd(const Operation& x,
const typename Operation::second_argument_type& y)
: op(x), value(y) {}
result_type operator()(const argument_type& x) const {
return op(x, value);
}
};
template <class Operation, class T>
inline binder2nd<Operation> bind2nd(const Operation& op, const T& x) {
typedef typename Operation::second_argument_type arg2_type;
return binder2nd<Operation>(op, arg2_type(x));
}
template <class Operation1, class Operation2>
class unary_compose : public unary_function<typename Operation2::argument_type,
typename Operation1::result_type> {
protected:
Operation1 op1;
Operation2 op2;
public:
unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {}
result_type operator()(const argument_type& x) const {
return op1(op2(x));
}
};
template <class Operation1, class Operation2>
inline unary_compose<Operation1, Operation2> compose1(const Operation1& op1,
const Operation2& op2) {
return unary_compose<Operation1, Operation2>(op1, op2);
}
template <class Operation1, class Operation2, class Operation3>
class binary_compose
: public unary_function<typename Operation2::argument_type,
typename Operation1::result_type> {
protected:
Operation1 op1;
Operation2 op2;
Operation3 op3;
public:
binary_compose(const Operation1& x, const Operation2& y,
const Operation3& z) : op1(x), op2(y), op3(z) { }
result_type operator()(const argument_type& x) const {
return op1(op2(x), op3(x));
}
};
template <class Operation1, class Operation2, class Operation3>
inline binary_compose<Operation1, Operation2, Operation3>
compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3) {
return binary_compose<Operation1, Operation2, Operation3>(op1, op2, op3);
}
template <class Arg, class Result>
class pointer_to_unary_function : public unary_function<Arg, Result> {
protected:
Result (*ptr)(Arg);
public:
pointer_to_unary_function() {}
explicit pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {}
Result operator()(Arg x) const { return ptr(x); }
};
template <class Arg, class Result>
inline pointer_to_unary_function<Arg, Result> ptr_fun(Result (*x)(Arg)) {
return pointer_to_unary_function<Arg, Result>(x);
}
template <class Arg1, class Arg2, class Result>
class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result> {
protected:
Result (*ptr)(Arg1, Arg2);
public:
pointer_to_binary_function() {}
explicit pointer_to_binary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {}
Result operator()(Arg1 x, Arg2 y) const { return ptr(x, y); }
};
template <class Arg1, class Arg2, class 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 <class T>
struct identity : public unary_function<T, T> {
const T& operator()(const T& x) const { return x; }
};
template <class Pair>
struct select1st : public unary_function<Pair, typename Pair::first_type> {
const typename Pair::first_type& operator()(const Pair& x) const
{
return x.first;
}
};
template <class Pair>
struct select2nd : public unary_function<Pair, typename Pair::second_type> {
const typename Pair::second_type& operator()(const Pair& x) const
{
return x.second;
}
};
template <class Arg1, class Arg2>
struct project1st : public binary_function<Arg1, Arg2, Arg1> {
Arg1 operator()(const Arg1& x, const Arg2&) const { return x; }
};
template <class Arg1, class Arg2>
struct project2nd : public binary_function<Arg1, Arg2, Arg2> {
Arg2 operator()(const Arg1&, const Arg2& y) const { return y; }
};
template <class Result>
struct constant_void_fun
{
typedef Result result_type;
result_type val;
constant_void_fun(const result_type& v) : val(v) {}
const result_type& operator()() const { return val; }
};
template <class Result, class Argument = Result>
struct constant_unary_fun : public unary_function<Argument, Result> {
result_type val;
constant_unary_fun(const result_type& v) : val(v) {}
const result_type& operator()(const argument_type&) const { return val; }
};
template <class Result, class Arg1 = Result, class Arg2 = Arg1>
struct constant_binary_fun : public binary_function<Arg1, Arg2, Result> {
result_type val;
constant_binary_fun(const result_type& v) : val(v) {}
const result_type& operator()(const first_argument_type&,
const second_argument_type&) const {
return val;
}
};
template <class Result>
inline constant_void_fun<Result> constant0(const Result& val)
{
return constant_void_fun<Result>(val);
}
template <class Result>
inline constant_unary_fun<Result,Result> constant1(const Result& val)
{
return constant_unary_fun<Result,Result>(val);
}
template <class Result>
inline constant_binary_fun<Result,Result,Result> constant2(const Result& val)
{
return constant_binary_fun<Result,Result,Result>(val);
}
class subtractive_rng : public unary_function<unsigned int, unsigned int> {
private:
unsigned int table[55];
size_t index1;
size_t index2;
public:
unsigned int operator()(unsigned int limit) {
index1 = (index1 + 1) % 55;
index2 = (index2 + 1) % 55;
table[index1] = table[index1] - table[index2];
return table[index1] % limit;
}
void initialize(unsigned int seed)
{
unsigned int k = 1;
table[54] = seed;
size_t i;
for (i = 0; i < 54; i++) {
size_t ii = (21 * (i + 1) % 55) - 1;
table[ii] = k;
k = seed - k;
seed = table[ii];
}
for (int loop = 0; loop < 4; loop++) {
for (i = 0; i < 55; i++)
table[i] = table[i] - table[(1 + i + 30) % 55];
}
index1 = 0;
index2 = 31;
}
subtractive_rng(unsigned int seed) { initialize(seed); }
subtractive_rng() { initialize(161803398u); }
};
template <class S, class T>
class mem_fun_t : public unary_function<T*, S> {
public:
explicit mem_fun_t(S (T::*pf)()) : f(pf) {}
S operator()(T* p) const { return (p->*f)(); }
private:
S (T::*f)();
};
template <class S, class T>
class const_mem_fun_t : public unary_function<const T*, S> {
public:
explicit const_mem_fun_t(S (T::*pf)() const) : f(pf) {}
S operator()(const T* p) const { return (p->*f)(); }
private:
S (T::*f)() const;
};
template <class S, class T>
class mem_fun_ref_t : public unary_function<T, S> {
public:
explicit mem_fun_ref_t(S (T::*pf)()) : f(pf) {}
S operator()(T& r) const { return (r.*f)(); }
private:
S (T::*f)();
};
template <class S, class T>
class const_mem_fun_ref_t : public unary_function<T, S> {
public:
explicit const_mem_fun_ref_t(S (T::*pf)() const) : f(pf) {}
S operator()(const T& r) const { return (r.*f)(); }
private:
S (T::*f)() const;
};
template <class S, class T, class A>
class mem_fun1_t : public binary_function<T*, A, S> {
public:
explicit mem_fun1_t(S (T::*pf)(A)) : f(pf) {}
S operator()(T* p, A x) const { return (p->*f)(x); }
private:
S (T::*f)(A);
};
template <class S, class T, class A>
class const_mem_fun1_t : public binary_function<const T*, A, S> {
public:
explicit const_mem_fun1_t(S (T::*pf)(A) const) : f(pf) {}
S operator()(const T* p, A x) const { return (p->*f)(x); }
private:
S (T::*f)(A) const;
};
template <class S, class T, class A>
class mem_fun1_ref_t : public binary_function<T, A, S> {
public:
explicit mem_fun1_ref_t(S (T::*pf)(A)) : f(pf) {}
S operator()(T& r, A x) const { return (r.*f)(x); }
private:
S (T::*f)(A);
};
template <class S, class T, class A>
class const_mem_fun1_ref_t : public binary_function<T, A, S> {
public:
explicit const_mem_fun1_ref_t(S (T::*pf)(A) const) : f(pf) {}
S operator()(const T& r, A x) const { return (r.*f)(x); }
private:
S (T::*f)(A) const;
};
template <class T>
class mem_fun_t<void, T> : public unary_function<T*, void> {
public:
explicit mem_fun_t(void (T::*pf)()) : f(pf) {}
void operator()(T* p) const { (p->*f)(); }
private:
void (T::*f)();
};
template <class T>
class const_mem_fun_t<void, T> : public unary_function<const T*, void> {
public:
explicit const_mem_fun_t(void (T::*pf)() const) : f(pf) {}
void operator()(const T* p) const { (p->*f)(); }
private:
void (T::*f)() const;
};
template <class T>
class mem_fun_ref_t<void, T> : public unary_function<T, void> {
public:
explicit mem_fun_ref_t(void (T::*pf)()) : f(pf) {}
void operator()(T& r) const { (r.*f)(); }
private:
void (T::*f)();
};
template <class T>
class const_mem_fun_ref_t<void, T> : public unary_function<T, void> {
public:
explicit const_mem_fun_ref_t(void (T::*pf)() const) : f(pf) {}
void operator()(const T& r) const { (r.*f)(); }
private:
void (T::*f)() const;
};
template <class T, class A>
class mem_fun1_t<void, T, A> : public binary_function<T*, A, void> {
public:
explicit mem_fun1_t(void (T::*pf)(A)) : f(pf) {}
void operator()(T* p, A x) const { (p->*f)(x); }
private:
void (T::*f)(A);
};
template <class T, class A>
class const_mem_fun1_t<void, T, A> : public binary_function<const T*, A, void> {
public:
explicit const_mem_fun1_t(void (T::*pf)(A) const) : f(pf) {}
void operator()(const T* p, A x) const { (p->*f)(x); }
private:
void (T::*f)(A) const;
};
template <class T, class A>
class mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> {
public:
explicit mem_fun1_ref_t(void (T::*pf)(A)) : f(pf) {}
void operator()(T& r, A x) const { (r.*f)(x); }
private:
void (T::*f)(A);
};
template <class T, class A>
class const_mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> {
public:
explicit const_mem_fun1_ref_t(void (T::*pf)(A) const) : f(pf) {}
void operator()(const T& r, A x) const { (r.*f)(x); }
private:
void (T::*f)(A) const;
};
template <class S, class T>
inline mem_fun_t<S,T> mem_fun(S (T::*f)()) {
return mem_fun_t<S,T>(f);
}
template <class S, class T>
inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const) {
return const_mem_fun_t<S,T>(f);
}
template <class S, class T>
inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()) {
return mem_fun_ref_t<S,T>(f);
}
template <class S, class T>
inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const) {
return const_mem_fun_ref_t<S,T>(f);
}
template <class S, class T, class A>
inline mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A)) {
return mem_fun1_t<S,T,A>(f);
}
template <class S, class T, class A>
inline const_mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A) const) {
return const_mem_fun1_t<S,T,A>(f);
}
template <class S, class T, class A>
inline mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A)) {
return mem_fun1_ref_t<S,T,A>(f);
}
template <class S, class T, class A>
inline const_mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A) const) {
return const_mem_fun1_ref_t<S,T,A>(f);
}
template <class T1, class T2>
struct pair {
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair() : first(T1()), second(T2()) {}
pair(const T1& a, const T2& b) : first(a), second(b) {}
template <class U1, class U2>
pair(const pair<U1, U2>& p) : first(p.first), second(p.second) {}
};
template <class T1, class T2>
inline bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y) {
return x.first == y.first && x.second == y.second;
}
template <class T1, class T2>
inline 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);
}
template <class T1, class T2>
inline pair<T1, T2> make_pair(const T1& x, const T2& y) {
return pair<T1, T2>(x, y);
}
extern "C" {
typedef int _G_int8_t __attribute__((__mode__(__QI__)));
typedef unsigned int _G_uint8_t __attribute__((__mode__(__QI__)));
typedef int _G_int16_t __attribute__((__mode__(__HI__)));
typedef unsigned int _G_uint16_t __attribute__((__mode__(__HI__)));
typedef int _G_int32_t __attribute__((__mode__(__SI__)));
typedef unsigned int _G_uint32_t __attribute__((__mode__(__SI__)));
typedef int _G_int64_t __attribute__((__mode__(__DI__)));
typedef unsigned int _G_uint64_t __attribute__((__mode__(__DI__)));
__extension__ typedef long long _G_llong;
__extension__ typedef unsigned long long _G_ullong;
typedef long _G_clock_t;
typedef unsigned long _G_dev_t;
typedef long _G_fpos_t;
typedef long _G_gid_t;
typedef unsigned long _G_ino_t;
typedef unsigned long _G_mode_t;
typedef unsigned long _G_nlink_t;
typedef long _G_off_t;
typedef long _G_pid_t;
typedef int _G_ptrdiff_t;
typedef int _G_sigset_t;
typedef unsigned int _G_size_t;
typedef long _G_time_t;
typedef long _G_uid_t;
typedef long int _G_wchar_t;
typedef int _G_ssize_t;
typedef unsigned int _G_wint_t;
typedef void * _G_va_list;
struct _IO_jump_t; struct _IO_FILE;
typedef void _IO_lock_t;
struct _IO_marker {
struct _IO_marker *_next;
struct _IO_FILE *_sbuf;
int _pos;
};
struct _IO_FILE {
int _flags;
char* _IO_read_ptr;
char* _IO_read_end;
char* _IO_read_base;
char* _IO_write_base;
char* _IO_write_ptr;
char* _IO_write_end;
char* _IO_buf_base;
char* _IO_buf_end;
char *_IO_save_base;
char *_IO_backup_base;
char *_IO_save_end;
struct _IO_marker *_markers;
struct _IO_FILE *_chain;
int _fileno;
int _blksize;
_G_off_t _offset;
unsigned short _cur_column;
char _unused;
char _shortbuf[1];
};
struct _IO_FILE_plus;
extern struct _IO_FILE_plus _IO_stdin_, _IO_stdout_, _IO_stderr_;
typedef struct
{
_G_ssize_t (*read) (struct _IO_FILE *, void *, _G_ssize_t ) ;
_G_ssize_t (*write) (struct _IO_FILE *, const void *, _G_ssize_t ) ;
_G_fpos_t (*seek) (struct _IO_FILE *, _G_off_t , int) ;
int (*close) (struct _IO_FILE *) ;
} _IO_cookie_io_functions_t;
struct _IO_cookie_file
{
struct _IO_FILE file;
const void *vtable;
void *cookie;
_IO_cookie_io_functions_t io_functions;
};
extern "C" {
extern int __underflow (_IO_FILE *) ;
extern int __uflow (_IO_FILE *) ;
extern int __overflow (_IO_FILE *, int) ;
extern int _IO_getc (_IO_FILE *__fp) ;
extern int _IO_putc (int __c, _IO_FILE *__fp) ;
extern int _IO_feof (_IO_FILE *__fp) ;
extern int _IO_ferror (_IO_FILE *__fp) ;
extern int _IO_peekc_locked (_IO_FILE *__fp) ;
extern void _IO_flockfile (_IO_FILE *) ;
extern void _IO_funlockfile (_IO_FILE *) ;
extern int _IO_ftrylockfile (_IO_FILE *) ;
extern int _IO_vfscanf (_IO_FILE *, const char *, _G_va_list , int *) ;
extern int _IO_vfprintf (_IO_FILE *, const char *, _G_va_list ) ;
extern _G_ssize_t _IO_padn (_IO_FILE *, int, _G_ssize_t ) ;
extern _G_size_t _IO_sgetn (_IO_FILE *, void *, _G_size_t ) ;
extern _G_fpos_t _IO_seekoff (_IO_FILE *, _G_off_t , int, int) ;
extern _G_fpos_t _IO_seekpos (_IO_FILE *, _G_fpos_t , int) ;
extern void _IO_free_backup_area (_IO_FILE *) ;
}
}
extern "C++" {
class istream;
class ostream; class streambuf;
typedef _G_off_t streamoff;
typedef _G_fpos_t streampos;
typedef _G_ssize_t streamsize;
typedef unsigned long __fmtflags;
typedef unsigned char __iostate;
struct _ios_fields
{
streambuf *_strbuf;
ostream* _tie;
int _width;
__fmtflags _flags;
short _fill;
__iostate _state;
__iostate _exceptions;
int _precision;
void *_arrays;
};
class ios : public _ios_fields {
ios& operator=(ios&);
ios (const ios&);
public:
typedef __fmtflags fmtflags;
typedef int iostate;
typedef int openmode;
typedef int streamsize;
enum io_state {
goodbit = 0 ,
eofbit = 1 ,
failbit = 2 ,
badbit = 4 };
enum open_mode {
in = 1 ,
out = 2 ,
ate = 4 ,
app = 8 ,
trunc = 16 ,
nocreate = 32 ,
noreplace = 64 ,
bin = 128 ,
binary = 128 };
enum seek_dir { beg, cur, end};
typedef enum seek_dir seekdir;
enum { skipws= 01 ,
left= 02 , right= 04 , internal= 010 ,
dec= 020 , oct= 040 , hex= 0100 ,
showbase= 0200 , showpoint= 0400 ,
uppercase= 01000 , showpos= 02000 ,
scientific= 04000 , fixed= 010000 ,
unitbuf= 020000 , stdio= 040000
};
enum {
basefield=dec+oct+hex,
floatfield = scientific+fixed,
adjustfield = left+right+internal
};
ostream* tie() const { return _tie; }
ostream* tie(ostream* val) { ostream* save=_tie; _tie=val; return save; }
short fill() const { return (short )_fill; }
short fill(short newf)
{short oldf = (short )_fill; _fill = (char)newf; return oldf;}
fmtflags flags() const { return _flags; }
fmtflags flags(fmtflags new_val) {
fmtflags old_val = _flags; _flags = new_val; return old_val; }
int precision() const { return _precision; }
int precision(int newp) {
unsigned short oldp = _precision; _precision = (unsigned short)newp;
return oldp; }
fmtflags setf(fmtflags val) {
fmtflags oldbits = _flags;
_flags |= val; return oldbits; }
fmtflags setf(fmtflags val, fmtflags mask) {
fmtflags oldbits = _flags;
_flags = (_flags & ~mask) | (val & mask); return oldbits; }
fmtflags unsetf(fmtflags mask) {
fmtflags oldbits = _flags;
_flags &= ~mask; return oldbits; }
int width() const { return _width; }
int width(int val) { int save = _width; _width = val; return save; }
void _throw_failure() const { }
void clear(iostate state = 0) {
_state = _strbuf ? state : state|badbit;
if (_state & _exceptions) _throw_failure(); }
void set(iostate flag) { _state |= flag;
if (_state & _exceptions) _throw_failure(); }
void setstate(iostate flag) { _state |= flag;
if (_state & _exceptions) _throw_failure(); }
int good() const { return _state == 0; }
int eof() const { return _state & ios::eofbit; }
int fail() const { return _state & (ios::badbit|ios::failbit); }
int bad() const { return _state & ios::badbit; }
iostate rdstate() const { return _state; }
operator void*() const { return fail() ? (void*)0 : (void*)(-1); }
int operator!() const { return fail(); }
iostate exceptions() const { return _exceptions; }
void exceptions(iostate enable) {
_exceptions = enable;
if (_state & _exceptions) _throw_failure(); }
streambuf* rdbuf() const { return _strbuf; }
streambuf* rdbuf(streambuf *_s) {
streambuf *_old = _strbuf; _strbuf = _s; clear (); return _old; }
static int sync_with_stdio(int on);
static void sync_with_stdio() { sync_with_stdio(1); }
static fmtflags bitalloc();
static int xalloc();
void*& pword(int);
void* pword(int) const;
long& iword(int);
long iword(int) const;
class Init {
public:
Init () { }
};
protected:
inline ios(streambuf* sb = 0, ostream* tie_to = 0);
inline virtual ~ios();
inline void init(streambuf* sb, ostream* tie = 0);
};
typedef ios::seek_dir _seek_dir;
class streammarker : private _IO_marker {
friend class streambuf;
void set_offset(int offset) { _pos = offset; }
public:
streammarker(streambuf *sb);
~streammarker();
int saving() { return 1; }
int delta(streammarker&);
int delta();
};
struct streambuf : public _IO_FILE {
friend class ios;
friend class istream;
friend class ostream;
friend class streammarker;
const void *&_vtable() { return *(const void**)((_IO_FILE*)this + 1); }
protected:
static streambuf* _list_all;
_IO_FILE*& xchain() { return _chain; }
void _un_link();
void _link_in();
char* gptr() const
{ return _flags & 0x100 ? _IO_save_base : _IO_read_ptr; }
char* pptr() const { return _IO_write_ptr; }
char* egptr() const
{ return _flags & 0x100 ? _IO_save_end : _IO_read_end; }
char* epptr() const { return _IO_write_end; }
char* pbase() const { return _IO_write_base; }
char* eback() const
{ return _flags & 0x100 ? _IO_save_base : _IO_read_base;}
char* base() const { return _IO_buf_base; }
char* ebuf() const { return _IO_buf_end; }
int blen() const { return _IO_buf_end - _IO_buf_base; }
void xput_char(char c) { *_IO_write_ptr++ = c; }
int xflags() { return _flags ; }
int xflags(int f) {int fl = _flags ; _flags = f; return fl;}
void xsetflags(int f) { _flags |= f; }
void xsetflags(int f, int mask)
{ _flags = (_flags & ~mask) | (f & mask); }
void gbump(int n)
{ _flags & 0x100 ? (_IO_save_base+=n):(_IO_read_ptr+=n);}
void pbump(int n) { _IO_write_ptr += n; }
void setb(char* b, char* eb, int a=0);
void setp(char* p, char* ep)
{ _IO_write_base=_IO_write_ptr=p; _IO_write_end=ep; }
void setg(char* eb, char* g, char *eg) {
if (_flags & 0x100 ) _IO_free_backup_area(this);
_IO_read_base = eb; _IO_read_ptr = g; _IO_read_end = eg; }
char *shortbuf() { return _shortbuf; }
int in_backup() { return _flags & 0x100 ; }
char *Gbase() { return in_backup() ? _IO_save_base : _IO_read_base; }
char *eGptr() { return in_backup() ? _IO_save_end : _IO_read_end; }
char *Bbase() { return in_backup() ? _IO_read_base : _IO_save_base; }
char *Bptr() { return _IO_backup_base; }
char *eBptr() { return in_backup() ? _IO_read_end : _IO_save_end; }
char *Nbase() { return _IO_save_base; }
char *eNptr() { return _IO_save_end; }
int have_backup() { return _IO_save_base != __null ; }
int have_markers() { return _markers != __null ; }
void free_backup_area();
void unsave_markers();
int put_mode() { return _flags & 0x800 ; }
int switch_to_get_mode();
streambuf(int flags=0);
public:
static int flush_all();
static void flush_all_linebuffered();
virtual ~streambuf();
virtual int overflow(int c = (-1) );
virtual int underflow();
virtual int uflow();
virtual int pbackfail(int c);
virtual streamsize xsputn(const char* s, streamsize n);
virtual streamsize xsgetn(char* s, streamsize n);
virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
streampos pubseekoff(streamoff o, _seek_dir d, int mode=ios::in|ios::out)
{ return _IO_seekoff (this, o, d, mode); }
streampos pubseekpos(streampos pos, int mode = ios::in|ios::out)
{ return _IO_seekpos (this, pos, mode); }
streampos sseekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
streampos sseekpos(streampos pos, int mode = ios::in|ios::out);
virtual streambuf* setbuf(char* p, int len);
virtual int sync();
virtual int doallocate();
int seekmark(streammarker& mark, int delta = 0);
int sputbackc(char c);
int sungetc();
int unbuffered() { return _flags & 2 ? 1 : 0; }
int linebuffered() { return _flags & 0x200 ? 1 : 0; }
void unbuffered(int i)
{ if (i) _flags |= 2 ; else _flags &= ~2 ; }
void linebuffered(int i)
{ if (i) _flags |= 0x200 ; else _flags &= ~0x200 ; }
int allocate() {
if (base() || unbuffered()) return 0;
else return doallocate(); }
void allocbuf() { if (base() == __null ) doallocbuf(); }
void doallocbuf();
int in_avail() { return _IO_read_end - _IO_read_ptr; }
int out_waiting() { return _IO_write_ptr - _IO_write_base; }
streamsize sputn(const char* s, streamsize n) { return xsputn(s, n); }
streamsize padn(char pad, streamsize n) { return _IO_padn(this, pad, n); }
streamsize sgetn(char* s, streamsize n) { return _IO_sgetn(this, s, n); }
int ignore(int);
int get_column();
int set_column(int);
long sgetline(char* buf, _G_size_t n, char delim, int putback_delim);
int sputc(int c) { return _IO_putc(c, this); }
int sbumpc() { return _IO_getc(this); }
int sgetc() { return (( this )->_IO_read_ptr >= ( this )->_IO_read_end && __underflow ( this ) == (-1) ? (-1) : *(unsigned char *) ( this )->_IO_read_ptr) ; }
int snextc() {
if (_IO_read_ptr >= _IO_read_end && __underflow(this) == (-1) )
return (-1) ;
else return _IO_read_ptr++, sgetc(); }
void stossc() { if (_IO_read_ptr < _IO_read_end) _IO_read_ptr++; }
int vscan(char const *fmt0, _G_va_list ap, ios* stream = __null );
int scan(char const *fmt0 ...);
int vform(char const *fmt0, _G_va_list ap);
int form(char const *fmt0 ...);
virtual streamsize sys_read(char* buf, streamsize size);
virtual streamsize sys_write(const char*, streamsize);
virtual streampos sys_seek(streamoff, _seek_dir);
virtual int sys_close();
virtual int sys_stat(void*);
};
class filebuf : public streambuf {
protected:
void init();
public:
static const int openprot;
filebuf();
filebuf(int fd);
filebuf(int fd, char* p, int len);
~filebuf();
filebuf* attach(int fd);
filebuf* open(const char *filename, const char *mode);
filebuf* open(const char *filename, ios::openmode mode, int prot = 0664);
virtual int underflow();
virtual int overflow(int c = (-1) );
int is_open() const { return _fileno >= 0; }
int fd() const { return is_open() ? _fileno : (-1) ; }
filebuf* close();
virtual int doallocate();
virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
virtual streambuf* setbuf(char* p, int len);
streamsize xsputn(const char* s, streamsize n);
streamsize xsgetn(char* s, streamsize n);
virtual int sync();
protected:
int is_reading() { return eback() != egptr(); }
char* cur_ptr() { return is_reading() ? gptr() : pptr(); }
char* file_ptr() { return eGptr(); }
virtual streamsize sys_read(char* buf, streamsize size);
virtual streampos sys_seek(streamoff, _seek_dir);
virtual streamsize sys_write(const char*, streamsize);
virtual int sys_stat(void*);
virtual int sys_close();
};
inline void ios::init(streambuf* sb, ostream* tie_to) {
_state = sb ? ios::goodbit : ios::badbit; _exceptions=0;
_strbuf=sb; _tie = tie_to; _width=0; _fill=' ';
_flags=ios::skipws|ios::dec;
_precision=6; _arrays = 0; }
inline ios::ios(streambuf* sb, ostream* tie_to) { init(sb, tie_to); }
inline ios::~ios() {
if (_arrays) delete [] _arrays;
}
}
extern "C++" {
class istream; class ostream;
typedef ios& (*__manip)(ios&);
typedef istream& (*__imanip)(istream&);
typedef ostream& (*__omanip)(ostream&);
extern istream& ws(istream& ins);
extern ostream& flush(ostream& outs);
extern ostream& endl(ostream& outs);
extern ostream& ends(ostream& outs);
class ostream : virtual public ios
{
void do_osfx();
public:
ostream() { }
ostream(streambuf* sb, ostream* tied= __null );
int opfx() {
if (!good()) return 0;
else { if (_tie) _tie->flush(); ; return 1;} }
void osfx() { ;
if (flags() & (ios::unitbuf|ios::stdio))
do_osfx(); }
ostream& flush();
ostream& put(char c) { _strbuf->sputc(c); return *this; }
ostream& write(const char *s, streamsize n);
ostream& write(const unsigned char *s, streamsize n)
{ return write((const char*)s, n);}
ostream& write(const signed char *s, streamsize n)
{ return write((const char*)s, n);}
ostream& write(const void *s, streamsize n)
{ return write((const char*)s, n);}
ostream& seekp(streampos);
ostream& seekp(streamoff, _seek_dir);
streampos tellp();
ostream& form(const char *format ...);
ostream& vform(const char *format, _G_va_list args);
ostream& operator<<(char c);
ostream& operator<<(unsigned char c) { return (*this) << (char)c; }
ostream& operator<<(signed char c) { return (*this) << (char)c; }
ostream& operator<<(const char *s);
ostream& operator<<(const unsigned char *s)
{ return (*this) << (const char*)s; }
ostream& operator<<(const signed char *s)
{ return (*this) << (const char*)s; }
ostream& operator<<(const void *p);
ostream& operator<<(int n);
ostream& operator<<(unsigned int n);
ostream& operator<<(long n);
ostream& operator<<(unsigned long n);
__extension__ ostream& operator<<(long long n);
__extension__ ostream& operator<<(unsigned long long n);
ostream& operator<<(short n) {return operator<<((int)n);}
ostream& operator<<(unsigned short n) {return operator<<((unsigned int)n);}
ostream& operator<<(bool b) { return operator<<((int)b); }
ostream& operator<<(double n);
ostream& operator<<(float n) { return operator<<((double)n); }
ostream& operator<<(long double n) { return operator<<((double)n); }
ostream& operator<<(__omanip func) { return (*func)(*this); }
ostream& operator<<(__manip func) {(*func)(*this); return *this;}
ostream& operator<<(streambuf*);
};
class istream : virtual public ios
{
protected:
_G_size_t _gcount;
int _skip_ws();
public:
istream(): _gcount (0) { }
istream(streambuf* sb, ostream*tied= __null );
istream& get(char* ptr, int len, char delim = '\n');
istream& get(unsigned char* ptr, int len, char delim = '\n')
{ return get((char*)ptr, len, delim); }
istream& get(char& c);
istream& get(unsigned char& c) { return get((char&)c); }
istream& getline(char* ptr, int len, char delim = '\n');
istream& getline(unsigned char* ptr, int len, char delim = '\n')
{ return getline((char*)ptr, len, delim); }
istream& get(signed char& c) { return get((char&)c); }
istream& get(signed char* ptr, int len, char delim = '\n')
{ return get((char*)ptr, len, delim); }
istream& getline(signed char* ptr, int len, char delim = '\n')
{ return getline((char*)ptr, len, delim); }
istream& read(char *ptr, streamsize n);
istream& read(unsigned char *ptr, streamsize n)
{ return read((char*)ptr, n); }
istream& read(signed char *ptr, streamsize n)
{ return read((char*)ptr, n); }
istream& read(void *ptr, streamsize n)
{ return read((char*)ptr, n); }
istream& get(streambuf& sb, char delim = '\n');
istream& gets(char **s, char delim = '\n');
int ipfx(int need = 0) {
if (!good()) { set(ios::failbit); return 0; }
else {
;
if (_tie && (need == 0 || rdbuf()->in_avail() < need)) _tie->flush();
if (!need && (flags() & ios::skipws)) return _skip_ws();
else return 1;
}
}
int ipfx0() {
if (!good()) { set(ios::failbit); return 0; }
else {
;
if (_tie) _tie->flush();
if (flags() & ios::skipws) return _skip_ws();
else return 1;
}
}
int ipfx1() {
if (!good()) { set(ios::failbit); return 0; }
else {
;
if (_tie && rdbuf()->in_avail() == 0) _tie->flush();
return 1;
}
}
void isfx() { ; }
int get() { if (!ipfx1()) return (-1) ;
else { int ch = _strbuf->sbumpc();
if (ch == (-1) ) set(ios::eofbit);
return ch;
} }
int peek();
_G_size_t gcount() { return _gcount; }
istream& ignore(int n=1, int delim = (-1) );
int sync ();
istream& seekg(streampos);
istream& seekg(streamoff, _seek_dir);
streampos tellg();
istream& putback(char ch) {
if (good() && _strbuf->sputbackc(ch) == (-1) ) clear(ios::badbit);
return *this;}
istream& unget() {
if (good() && _strbuf->sungetc() == (-1) ) clear(ios::badbit);
return *this;}
istream& scan(const char *format ...);
istream& vscan(const char *format, _G_va_list args);
istream& operator>>(char*);
istream& operator>>(unsigned char* p) { return operator>>((char*)p); }
istream& operator>>(signed char*p) { return operator>>((char*)p); }
istream& operator>>(char& c);
istream& operator>>(unsigned char& c) {return operator>>((char&)c);}
istream& operator>>(signed char& c) {return operator>>((char&)c);}
istream& operator>>(int&);
istream& operator>>(long&);
__extension__ istream& operator>>(long long&);
__extension__ istream& operator>>(unsigned long long&);
istream& operator>>(short&);
istream& operator>>(unsigned int&);
istream& operator>>(unsigned long&);
istream& operator>>(unsigned short&);
istream& operator>>(bool&);
istream& operator>>(float&);
istream& operator>>(double&);
istream& operator>>(long double&);
istream& operator>>( __manip func) {(*func)(*this); return *this;}
istream& operator>>(__imanip func) { return (*func)(*this); }
istream& operator>>(streambuf*);
};
class iostream : public istream, public ostream
{
public:
iostream() { }
iostream(streambuf* sb, ostream*tied= __null );
};
class _IO_istream_withassign : public istream {
public:
_IO_istream_withassign& operator=(istream&);
_IO_istream_withassign& operator=(_IO_istream_withassign& rhs)
{ return operator= (static_cast<istream&> (rhs)); }
};
class _IO_ostream_withassign : public ostream {
public:
_IO_ostream_withassign& operator=(ostream&);
_IO_ostream_withassign& operator=(_IO_ostream_withassign& rhs)
{ return operator= (static_cast<ostream&> (rhs)); }
};
extern _IO_istream_withassign cin;
extern _IO_ostream_withassign cout, cerr;
extern _IO_ostream_withassign clog
;
extern istream& lock(istream& ins);
extern istream& unlock(istream& ins);
extern ostream& lock(ostream& outs);
extern ostream& unlock(ostream& outs);
struct Iostream_init { } ;
inline ios& dec(ios& i)
{ i.setf(ios::dec, ios::dec|ios::hex|ios::oct); return i; }
inline ios& hex(ios& i)
{ i.setf(ios::hex, ios::dec|ios::hex|ios::oct); return i; }
inline ios& oct(ios& i)
{ i.setf(ios::oct, ios::dec|ios::hex|ios::oct); return i; }
}
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
template <class T, class Distance> struct input_iterator {
typedef input_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
struct output_iterator {
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
};
template <class T, class Distance> struct forward_iterator {
typedef forward_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
template <class T, class Distance> struct bidirectional_iterator {
typedef bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
template <class T, class Distance> struct random_access_iterator {
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
template <class 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;
};
template <class T>
struct iterator_traits<T*> {
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
};
template <class T>
struct iterator_traits<const T*> {
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef const T* pointer;
typedef const T& reference;
};
template <class Iterator>
inline iterator_traits<Iterator>::iterator_category
iterator_category(const Iterator&) {
return iterator_traits<Iterator>::iterator_category();
}
template <class Iterator>
inline iterator_traits<Iterator>::difference_type*
distance_type(const Iterator&) {
return static_cast<iterator_traits<Iterator>::difference_type*>(0);
}
template <class Iterator>
inline iterator_traits<Iterator>::value_type*
value_type(const Iterator&) {
return static_cast<iterator_traits<Iterator>::value_type*>(0);
}
template <class Container>
class back_insert_iterator {
protected:
Container* container;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit back_insert_iterator(Container& x) : container(&x) {}
back_insert_iterator<Container>&
operator=(const typename Container::value_type& value) {
container->push_back(value);
return *this;
}
back_insert_iterator<Container>& operator*() { return *this; }
back_insert_iterator<Container>& operator++() { return *this; }
back_insert_iterator<Container>& operator++(int) { return *this; }
};
template <class Container>
inline back_insert_iterator<Container> back_inserter(Container& x) {
return back_insert_iterator<Container>(x);
}
template <class Container>
class front_insert_iterator {
protected:
Container* container;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit front_insert_iterator(Container& x) : container(&x) {}
front_insert_iterator<Container>&
operator=(const typename Container::value_type& value) {
container->push_front(value);
return *this;
}
front_insert_iterator<Container>& operator*() { return *this; }
front_insert_iterator<Container>& operator++() { return *this; }
front_insert_iterator<Container>& operator++(int) { return *this; }
};
template <class Container>
inline front_insert_iterator<Container> front_inserter(Container& x) {
return front_insert_iterator<Container>(x);
}
template <class Container>
class insert_iterator {
protected:
Container* container;
typename Container::iterator iter;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
insert_iterator(Container& x, typename Container::iterator i)
: container(&x), iter(i) {}
insert_iterator<Container>&
operator=(const typename Container::value_type& value) {
iter = container->insert(iter, value);
++iter;
return *this;
}
insert_iterator<Container>& operator*() { return *this; }
insert_iterator<Container>& operator++() { return *this; }
insert_iterator<Container>& operator++(int) { return *this; }
};
template <class Container, class Iterator>
inline insert_iterator<Container> inserter(Container& x, Iterator i) {
typedef typename Container::iterator iter;
return insert_iterator<Container>(x, iter(i));
}
template <class BidirectionalIterator, class T, class Reference = T&,
class Distance = ptrdiff_t>
class reverse_bidirectional_iterator {
typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
Distance> self;
friend bool operator==(const self& x, const self& y);
protected:
BidirectionalIterator current;
public:
typedef bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef Reference reference;
reverse_bidirectional_iterator() {}
explicit reverse_bidirectional_iterator(BidirectionalIterator x)
: current(x) {}
BidirectionalIterator base() { return current; }
Reference operator*() const {
BidirectionalIterator tmp = current;
return *--tmp;
}
pointer operator->() const { return &(operator*()); }
self& operator++() {
--current;
return *this;
}
self operator++(int) {
self tmp = *this;
--current;
return tmp;
}
self& operator--() {
++current;
return *this;
}
self operator--(int) {
self tmp = *this;
++current;
return tmp;
}
};
template <class BidirectionalIterator, class T, class Reference,
class Distance>
inline bool operator==(
const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
Distance>& x,
const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
Distance>& y) {
return x.current == y.current;
}
template <class Iterator>
class reverse_iterator : public iterator_traits<Iterator>
{
protected:
Iterator current;
public:
typedef Iterator iterator_type;
typedef reverse_iterator<Iterator> self;
public:
reverse_iterator() {}
explicit reverse_iterator(iterator_type x) : current(x) {}
reverse_iterator(const self& x) : current(x.current) {}
template <class Iter>
reverse_iterator(const reverse_iterator<Iter>& x) : current(x.current) {}
iterator_type base() const { return current; }
reference operator*() const {
Iterator tmp = current;
return *--tmp;
}
pointer operator->() const { return &(operator*()); }
self& operator++() {
--current;
return *this;
}
self operator++(int) {
self tmp = *this;
--current;
return tmp;
}
self& operator--() {
++current;
return *this;
}
self operator--(int) {
self tmp = *this;
++current;
return tmp;
}
self operator+(difference_type n) const {
return self(current - n);
}
self& operator+=(difference_type n) {
current -= n;
return *this;
}
self operator-(difference_type n) const {
return self(current + n);
}
self& operator-=(difference_type n) {
current += n;
return *this;
}
reference operator[](difference_type n) { return *(*this + n); }
};
template <class Iterator>
inline bool operator==(const reverse_iterator<Iterator>& x,
const reverse_iterator<Iterator>& y) {
return x.base() == y.base();
}
template <class Iterator>
inline bool operator<(const reverse_iterator<Iterator>& x,
const reverse_iterator<Iterator>& y) {
return y.base() < x.base();
}
template <class Iterator>
inline reverse_iterator<Iterator>::difference_type
operator-(const reverse_iterator<Iterator>& x,
const reverse_iterator<Iterator>& y) {
return y.base() - x.base();
}
template <class Iterator>
inline reverse_iterator<Iterator>
operator+(reverse_iterator<Iterator>::difference_type n,
const reverse_iterator<Iterator>& x) {
return reverse_iterator<Iterator>(x.base() - n);
}
template <class ForwardIterator, class T>
class raw_storage_iterator {
protected:
ForwardIterator iter;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit raw_storage_iterator(ForwardIterator x) : iter(x) {}
raw_storage_iterator<ForwardIterator, T>& operator*() { return *this; }
raw_storage_iterator<ForwardIterator, T>& operator=(const T& element) {
construct(&*iter, element);
return *this;
}
raw_storage_iterator<ForwardIterator, T>& operator++() {
++iter;
return *this;
}
raw_storage_iterator<ForwardIterator, T> operator++(int) {
raw_storage_iterator<ForwardIterator, T> tmp = *this;
++iter;
return tmp;
}
};
template <class T, class Distance = ptrdiff_t>
class istream_iterator {
friend bool operator==(const istream_iterator<T, Distance>& x,
const istream_iterator<T, Distance>& y);
protected:
istream* stream;
T value;
bool end_marker;
void read() {
end_marker = (*stream) ? true : false;
if (end_marker) *stream >> value;
end_marker = (*stream) ? true : false;
}
public:
typedef input_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef const T* pointer;
typedef const T& reference;
istream_iterator() : stream(&cin), end_marker(false) {}
istream_iterator(istream& s) : stream(&s) { read(); }
reference operator*() const { return value; }
pointer operator->() const { return &(operator*()); }
istream_iterator<T, Distance>& operator++() {
read();
return *this;
}
istream_iterator<T, Distance> operator++(int) {
istream_iterator<T, Distance> tmp = *this;
read();
return tmp;
}
};
template <class T, class Distance>
bool operator==(const istream_iterator<T, Distance>& x,
const istream_iterator<T, Distance>& y) {
return x.stream == y.stream && x.end_marker == y.end_marker ||
x.end_marker == false && y.end_marker == false;
}
template <class T>
class ostream_iterator {
protected:
ostream* stream;
const char* string;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
ostream_iterator(ostream& s) : stream(&s), string(0) {}
ostream_iterator(ostream& s, const char* c) : stream(&s), string(c) {}
ostream_iterator<T>& operator=(const T& value) {
*stream << value;
if (string) *stream << string;
return *this;
}
ostream_iterator<T>& operator*() { return *this; }
ostream_iterator<T>& operator++() { return *this; }
ostream_iterator<T>& operator++(int) { return *this; }
};
extern "C++" {
class exception {
public:
exception () { }
virtual ~exception () { }
virtual const char* what () const;
};
class bad_exception : public exception {
public:
bad_exception () { }
virtual ~bad_exception () { }
};
typedef void (*terminate_handler) ();
typedef void (*unexpected_handler) ();
terminate_handler set_terminate (terminate_handler);
void terminate (void);
unexpected_handler set_unexpected (unexpected_handler);
void unexpected (void);
bool uncaught_exception ();
}
extern "C++" {
class bad_alloc : public exception {
public:
virtual const char* what() const throw() { return "bad_alloc"; }
};
struct nothrow_t {};
extern const nothrow_t nothrow;
typedef void (*new_handler)();
extern "C" new_handler set_new_handler (new_handler);
extern new_handler __new_handler;
extern "C" void __default_new_handler (void);
void *operator new (size_t);
void *operator new (size_t, const nothrow_t&) throw();
void *operator new[] (size_t);
void *operator new[] (size_t, const nothrow_t&) throw();
void operator delete (void *) throw();
void operator delete[] (void *) throw();
inline void *operator new(size_t, void *place) throw() { return place; }
inline void *operator new[](size_t, void *place) throw() { return place; }
}
struct __true_type {
};
struct __false_type {
};
template <class type>
struct __type_traits {
typedef __true_type this_dummy_member_must_be_first;
typedef __false_type has_trivial_default_constructor;
typedef __false_type has_trivial_copy_constructor;
typedef __false_type has_trivial_assignment_operator;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type;
};
struct __type_traits<char> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<signed char> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<unsigned char> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<short> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<unsigned short> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<int> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<unsigned int> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<long> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<unsigned long> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<float> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<double> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits<long double> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template <class T>
struct __type_traits<T*> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
template <class ForwardIterator1, class ForwardIterator2, class T>
inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*) {
T tmp = *a;
*a = *b;
*b = tmp;
}
template <class ForwardIterator1, class ForwardIterator2>
inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) {
__iter_swap(a, b, value_type(a));
}
template <class T>
inline void swap(T& a, T& b) {
T tmp = a;
a = b;
b = tmp;
}
template <class T>
inline const T& min(const T& a, const T& b) {
return b < a ? b : a;
}
template <class T>
inline const T& max(const T& a, const T& b) {
return a < b ? b : a;
}
template <class T, class Compare>
inline const T& min(const T& a, const T& b, Compare comp) {
return comp(b, a) ? b : a;
}
template <class T, class Compare>
inline const T& max(const T& a, const T& b, Compare comp) {
return comp(a, b) ? b : a;
}
template <class InputIterator, class Distance>
inline void __distance(InputIterator first, InputIterator last, Distance& n,
input_iterator_tag) {
while (first != last) { ++first; ++n; }
}
template <class RandomAccessIterator, class Distance>
inline void __distance(RandomAccessIterator first, RandomAccessIterator last,
Distance& n, random_access_iterator_tag) {
n += last - first;
}
template <class InputIterator, class Distance>
inline void distance(InputIterator first, InputIterator last, Distance& n) {
__distance(first, last, n, iterator_category(first));
}
template <class InputIterator>
inline iterator_traits<InputIterator>::difference_type
__distance(InputIterator first, InputIterator last, input_iterator_tag) {
iterator_traits<InputIterator>::difference_type n = 0;
while (first != last) {
++first; ++n;
}
return n;
}
template <class RandomAccessIterator>
inline iterator_traits<RandomAccessIterator>::difference_type
__distance(RandomAccessIterator first, RandomAccessIterator last,
random_access_iterator_tag) {
return last - first;
}
template <class InputIterator>
inline iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last) {
return __distance(first, last,
iterator_traits<InputIterator>::iterator_category());
}
template <class InputIterator, class Distance>
inline void __advance(InputIterator& i, Distance n, input_iterator_tag) {
while (n--) ++i;
}
template <class BidirectionalIterator, class Distance>
inline void __advance(BidirectionalIterator& i, Distance n,
bidirectional_iterator_tag) {
if (n >= 0)
while (n--) ++i;
else
while (n++) --i;
}
template <class RandomAccessIterator, class Distance>
inline void __advance(RandomAccessIterator& i, Distance n,
random_access_iterator_tag) {
i += n;
}
template <class InputIterator, class Distance>
inline void advance(InputIterator& i, Distance n) {
__advance(i, n, iterator_category(i));
}
template <class InputIterator, class OutputIterator>
inline OutputIterator __copy(InputIterator first, InputIterator last,
OutputIterator result, input_iterator_tag)
{
for ( ; first != last; ++result, ++first)
*result = *first;
return result;
}
template <class RandomAccessIterator, class OutputIterator, class Distance>
inline OutputIterator
__copy_d(RandomAccessIterator first, RandomAccessIterator last,
OutputIterator result, Distance*)
{
for (Distance n = last - first; n > 0; --n, ++result, ++first)
*result = *first;
return result;
}
template <class RandomAccessIterator, class OutputIterator>
inline OutputIterator
__copy(RandomAccessIterator first, RandomAccessIterator last,
OutputIterator result, random_access_iterator_tag)
{
return __copy_d(first, last, result, distance_type(first));
}
template <class InputIterator, class OutputIterator>
struct __copy_dispatch
{
OutputIterator operator()(InputIterator first, InputIterator last,
OutputIterator result) {
return __copy(first, last, result, iterator_category(first));
}
};
template <class T>
inline T* __copy_t(const T* first, const T* last, T* result, __true_type) {
memmove(result, first, sizeof(T) * (last - first));
return result + (last - first);
}
template <class T>
inline T* __copy_t(const T* first, const T* last, T* result, __false_type) {
return __copy_d(first, last, result, (ptrdiff_t*) 0);
}
template <class T>
struct __copy_dispatch<T*, T*>
{
T* operator()(T* first, T* last, T* result) {
return __copy_t(first, last, result,
__type_traits<T>::has_trivial_assignment_operator());
}
};
template <class T>
struct __copy_dispatch<const T*, T*>
{
T* operator()(const T* first, const T* last, T* result) {
return __copy_t(first, last, result,
__type_traits<T>::has_trivial_assignment_operator());
}
};
template <class InputIterator, class OutputIterator>
inline OutputIterator copy(InputIterator first, InputIterator last,
OutputIterator result)
{
return __copy_dispatch<InputIterator,OutputIterator>()(first, last, result);
}
inline char* copy(const char* first, const char* last, char* result) {
memmove(result, first, last - first);
return result + (last - first);
}
inline wchar_t* copy(const wchar_t* first, const wchar_t* last,
wchar_t* result) {
memmove(result, first, sizeof(wchar_t) * (last - first));
return result + (last - first);
}
template <class BidirectionalIterator1, class BidirectionalIterator2>
inline BidirectionalIterator2 __copy_backward(BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result) {
while (first != last) *--result = *--last;
return result;
}
template <class BidirectionalIterator1, class BidirectionalIterator2>
struct __copy_backward_dispatch
{
BidirectionalIterator2 operator()(BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result) {
return __copy_backward(first, last, result);
}
};
template <class T>
inline T* __copy_backward_t(const T* first, const T* last, T* result,
__true_type) {
const ptrdiff_t N = last - first;
memmove(result - N, first, sizeof(T) * N);
return result - N;
}
template <class T>
inline T* __copy_backward_t(const T* first, const T* last, T* result,
__false_type) {
return __copy_backward(first, last, result);
}
template <class T>
struct __copy_backward_dispatch<T*, T*>
{
T* operator()(T* first, T* last, T* result) {
return
__copy_backward_t(first, last, result,
__type_traits<T>::has_trivial_assignment_operator());
}
};
template <class T>
struct __copy_backward_dispatch<const T*, T*>
{
T* operator()(const T* first, const T* last, T* result) {
return
__copy_backward_t(first, last, result,
__type_traits<T>::has_trivial_assignment_operator());
}
};
template <class BidirectionalIterator1, class BidirectionalIterator2>
inline BidirectionalIterator2 copy_backward(BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result) {
return __copy_backward_dispatch<BidirectionalIterator1,
BidirectionalIterator2>()(first, last,
result);
}
template <class InputIterator, class Size, class OutputIterator>
OutputIterator __copy_n(InputIterator first, Size count,
OutputIterator result,
input_iterator_tag) {
for ( ; count > 0; --count, ++first, ++result)
*result = *first;
return result;
}
template <class RandomAccessIterator, class Size, class OutputIterator>
inline OutputIterator __copy_n(RandomAccessIterator first, Size count,
OutputIterator result,
random_access_iterator_tag) {
return copy(first, first + count, result);
}
template <class InputIterator, class Size, class OutputIterator>
inline OutputIterator copy_n(InputIterator first, Size count,
OutputIterator result) {
return __copy_n(first, count, result, iterator_category(first));
}
template <class ForwardIterator, class T>
void fill(ForwardIterator first, ForwardIterator last, const T& value) {
for ( ; first != last; ++first)
*first = value;
}
template <class OutputIterator, class Size, class T>
OutputIterator fill_n(OutputIterator first, Size n, const T& value) {
for ( ; n > 0; --n, ++first)
*first = value;
return first;
}
template <class InputIterator1, class InputIterator2>
pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2) {
while (first1 != last1 && *first1 == *first2) {
++first1;
++first2;
}
return pair<InputIterator1, InputIterator2>(first1, first2);
}
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
BinaryPredicate binary_pred) {
while (first1 != last1 && binary_pred(*first1, *first2)) {
++first1;
++first2;
}
return pair<InputIterator1, InputIterator2>(first1, first2);
}
template <class InputIterator1, class InputIterator2>
inline bool equal(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2) {
for ( ; first1 != last1; ++first1, ++first2)
if (*first1 != *first2)
return false;
return true;
}
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
inline bool equal(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, BinaryPredicate binary_pred) {
for ( ; first1 != last1; ++first1, ++first2)
if (!binary_pred(*first1, *first2))
return false;
return true;
}
template <class InputIterator1, class InputIterator2>
bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2) {
for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) {
if (*first1 < *first2)
return true;
if (*first2 < *first1)
return false;
}
return first1 == last1 && first2 != last2;
}
template <class InputIterator1, class InputIterator2, class Compare>
bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
Compare comp) {
for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) {
if (comp(*first1, *first2))
return true;
if (comp(*first2, *first1))
return false;
}
return first1 == last1 && first2 != last2;
}
inline bool
lexicographical_compare(const unsigned char* first1,
const unsigned char* last1,
const unsigned char* first2,
const unsigned char* last2)
{
const size_t len1 = last1 - first1;
const size_t len2 = last2 - first2;
const int result = memcmp(first1, first2, min(len1, len2));
return result != 0 ? result < 0 : len1 < len2;
}
inline bool lexicographical_compare(const char* first1, const char* last1,
const char* first2, const char* last2)
{
return lexicographical_compare((const signed char*) first1,
(const signed char*) last1,
(const signed char*) first2,
(const signed char*) last2);
}
template <class InputIterator1, class InputIterator2>
int lexicographical_compare_3way(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2)
{
while (first1 != last1 && first2 != last2) {
if (*first1 < *first2) return -1;
if (*first2 < *first1) return 1;
++first1; ++first2;
}
if (first2 == last2) {
return !(first1 == last1);
} else {
return -1;
}
}
inline int
lexicographical_compare_3way(const unsigned char* first1,
const unsigned char* last1,
const unsigned char* first2,
const unsigned char* last2)
{
const int len1 = last1 - first1;
const int len2 = last2 - first2;
const int result = memcmp(first1, first2, min(len1, len2));
return result == 0 ? len1 - len2 : result;
}
inline int lexicographical_compare_3way(const char* first1, const char* last1,
const char* first2, const char* last2)
{
return lexicographical_compare_3way(
(const signed char*) first1,
(const signed char*) last1,
(const signed char*) first2,
(const signed char*) last2);
}
template <class T>
inline void destroy(T* pointer) {
pointer->~T();
}
template <class T1, class T2>
inline void construct(T1* p, const T2& value) {
new (p) T1(value);
}
template <class ForwardIterator>
inline void
__destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) {
for ( ; first < last; ++first)
destroy(&*first);
}
template <class ForwardIterator>
inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {
}
template <class ForwardIterator, class T>
inline void __destroy(ForwardIterator first, ForwardIterator last, T*) {
__destroy_aux(first, last, __type_traits<T>::has_trivial_destructor());
}
template <class ForwardIterator>
inline void destroy(ForwardIterator first, ForwardIterator last) {
__destroy(first, last, value_type(first));
}
inline void destroy(char*, char*) {}
inline void destroy(wchar_t*, wchar_t*) {}
template <class InputIterator, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__true_type) {
return copy(first, last, result);
}
template <class InputIterator, class ForwardIterator>
ForwardIterator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__false_type) {
ForwardIterator cur = result;
try {
for ( ; first != last; ++first, ++cur)
construct(&*cur, *first);
return cur;
}
catch(...) {
destroy(result, cur);
throw;
}
}
template <class InputIterator, class ForwardIterator, class T>
inline ForwardIterator
__uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result, T*) {
return __uninitialized_copy_aux(first, last, result,
__type_traits<T>::is_POD_type());
}
template <class InputIterator, class ForwardIterator>
inline ForwardIterator
uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result) {
return __uninitialized_copy(first, last, result, value_type(result));
}
inline char* uninitialized_copy(const char* first, const char* last,
char* result) {
memmove(result, first, last - first);
return result + (last - first);
}
inline wchar_t* uninitialized_copy(const wchar_t* first, const wchar_t* last,
wchar_t* result) {
memmove(result, first, sizeof(wchar_t) * (last - first));
return result + (last - first);
}
template <class InputIterator, class Size, class ForwardIterator>
ForwardIterator __uninitialized_copy_n(InputIterator first, Size count,
ForwardIterator result,
input_iterator_tag) {
ForwardIterator cur = result;
try {
for ( ; count > 0 ; --count, ++first, ++cur)
construct(&*cur, *first);
return cur;
}
catch(...) {
destroy(result, cur);
throw;
}
}
template <class RandomAccessIterator, class Size, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_n(RandomAccessIterator first, Size count,
ForwardIterator result,
random_access_iterator_tag) {
return uninitialized_copy(first, first + count, result);
}
template <class InputIterator, class Size, class ForwardIterator>
inline ForwardIterator uninitialized_copy_n(InputIterator first, Size count,
ForwardIterator result) {
return __uninitialized_copy_n(first, count, result,
iterator_category(first));
}
template <class ForwardIterator, class T>
inline void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
const T& x, __true_type)
{
fill(first, last, x);
}
template <class ForwardIterator, class T>
void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
const T& x, __false_type)
{
ForwardIterator cur = first;
try {
for ( ; cur != last; ++cur)
construct(&*cur, x);
}
catch(...) {
destroy(first, cur);
throw;
}
}
template <class ForwardIterator, class T, class T1>
inline void __uninitialized_fill(ForwardIterator first, ForwardIterator last,
const T& x, T1*) {
__uninitialized_fill_aux(first, last, x,
__type_traits<T1>::is_POD_type());
}
template <class ForwardIterator, class T>
inline void uninitialized_fill(ForwardIterator first, ForwardIterator last,
const T& x) {
__uninitialized_fill(first, last, x, value_type(first));
}
template <class ForwardIterator, class Size, class T>
inline ForwardIterator
__uninitialized_fill_n_aux(ForwardIterator first, Size n,
const T& x, __true_type) {
return fill_n(first, n, x);
}
template <class ForwardIterator, class Size, class T>
ForwardIterator
__uninitialized_fill_n_aux(ForwardIterator first, Size n,
const T& x, __false_type) {
ForwardIterator cur = first;
try {
for ( ; n > 0; --n, ++cur)
construct(&*cur, x);
return cur;
}
catch(...) {
destroy(first, cur);
throw;
}
}
template <class ForwardIterator, class Size, class T, class T1>
inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n,
const T& x, T1*) {
return __uninitialized_fill_n_aux(first, n, x,
__type_traits<T1>::is_POD_type());
}
template <class ForwardIterator, class Size, class T>
inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n,
const T& x) {
return __uninitialized_fill_n(first, n, x, value_type(first));
}
template <class InputIterator1, class InputIterator2, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
ForwardIterator result) {
ForwardIterator mid = uninitialized_copy(first1, last1, result);
try {
return uninitialized_copy(first2, last2, mid);
}
catch(...) {
destroy(result, mid);
throw;
}
}
template <class ForwardIterator, class T, class InputIterator>
inline ForwardIterator
__uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid,
const T& x,
InputIterator first, InputIterator last) {
uninitialized_fill(result, mid, x);
try {
return uninitialized_copy(first, last, mid);
}
catch(...) {
destroy(result, mid);
throw;
}
}
template <class InputIterator, class ForwardIterator, class T>
inline void
__uninitialized_copy_fill(InputIterator first1, InputIterator last1,
ForwardIterator first2, ForwardIterator last2,
const T& x) {
ForwardIterator mid2 = uninitialized_copy(first1, last1, first2);
try {
uninitialized_fill(mid2, last2, x);
}
catch(...) {
destroy(first2, mid2);
throw;
}
}
template <class RandomAccessIterator, class Distance, class T>
void __push_heap(RandomAccessIterator first, Distance holeIndex,
Distance topIndex, T value) {
Distance parent = (holeIndex - 1) / 2;
while (holeIndex > topIndex && *(first + parent) < value) {
*(first + holeIndex) = *(first + parent);
holeIndex = parent;
parent = (holeIndex - 1) / 2;
}
*(first + holeIndex) = value;
}
template <class RandomAccessIterator, class Distance, class T>
inline void __push_heap_aux(RandomAccessIterator first,
RandomAccessIterator last, Distance*, T*) {
__push_heap(first, Distance((last - first) - 1), Distance(0),
T(*(last - 1)));
}
template <class RandomAccessIterator>
inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) {
__push_heap_aux(first, last, distance_type(first), value_type(first));
}
template <class RandomAccessIterator, class Distance, class T, class Compare>
void __push_heap(RandomAccessIterator first, Distance holeIndex,
Distance topIndex, T value, Compare comp) {
Distance parent = (holeIndex - 1) / 2;
while (holeIndex > topIndex && comp(*(first + parent), value)) {
*(first + holeIndex) = *(first + parent);
holeIndex = parent;
parent = (holeIndex - 1) / 2;
}
*(first + holeIndex) = value;
}
template <class RandomAccessIterator, class Compare, class Distance, class T>
inline void __push_heap_aux(RandomAccessIterator first,
RandomAccessIterator last, Compare comp,
Distance*, T*) {
__push_heap(first, Distance((last - first) - 1), Distance(0),
T(*(last - 1)), comp);
}
template <class RandomAccessIterator, class Compare>
inline void push_heap(RandomAccessIterator first, RandomAccessIterator last,
Compare comp) {
__push_heap_aux(first, last, comp, distance_type(first), value_type(first));
}
template <class RandomAccessIterator, class Distance, class T>
void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
Distance len, T value) {
Distance topIndex = holeIndex;
Distance secondChild = 2 * holeIndex + 2;
while (secondChild < len) {
if (*(first + secondChild) < *(first + (secondChild - 1)))
secondChild--;
*(first + holeIndex) = *(first + secondChild);
holeIndex = secondChild;
secondChild = 2 * (secondChild + 1);
}
if (secondChild == len) {
*(first + holeIndex) = *(first + (secondChild - 1));
holeIndex = secondChild - 1;
}
__push_heap(first, holeIndex, topIndex, value);
}
template <class RandomAccessIterator, class T, class Distance>
inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
RandomAccessIterator result, T value, Distance*) {
*result = *first;
__adjust_heap(first, Distance(0), Distance(last - first), value);
}
template <class RandomAccessIterator, class T>
inline void __pop_heap_aux(RandomAccessIterator first,
RandomAccessIterator last, T*) {
__pop_heap(first, last - 1, last - 1, T(*(last - 1)), distance_type(first));
}
template <class RandomAccessIterator>
inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) {
__pop_heap_aux(first, last, value_type(first));
}
template <class RandomAccessIterator, class Distance, class T, class Compare>
void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
Distance len, T value, Compare comp) {
Distance topIndex = holeIndex;
Distance secondChild = 2 * holeIndex + 2;
while (secondChild < len) {
if (comp(*(first + secondChild), *(first + (secondChild - 1))))
secondChild--;
*(first + holeIndex) = *(first + secondChild);
holeIndex = secondChild;
secondChild = 2 * (secondChild + 1);
}
if (secondChild == len) {
*(first + holeIndex) = *(first + (secondChild - 1));
holeIndex = secondChild - 1;
}
__push_heap(first, holeIndex, topIndex, value, comp);
}
template <class RandomAccessIterator, class T, class Compare, class Distance>
inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
RandomAccessIterator result, T value, Compare comp,
Distance*) {
*result = *first;
__adjust_heap(first, Distance(0), Distance(last - first), value, comp);
}
template <class RandomAccessIterator, class T, class Compare>
inline void __pop_heap_aux(RandomAccessIterator first,
RandomAccessIterator last, T*, Compare comp) {
__pop_heap(first, last - 1, last - 1, T(*(last - 1)), comp,
distance_type(first));
}
template <class RandomAccessIterator, class Compare>
inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last,
Compare comp) {
__pop_heap_aux(first, last, value_type(first), comp);
}
template <class RandomAccessIterator, class T, class Distance>
void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*,
Distance*) {
if (last - first < 2) return;
Distance len = last - first;
Distance parent = (len - 2)/2;
while (true) {
__adjust_heap(first, parent, len, T(*(first + parent)));
if (parent == 0) return;
parent--;
}
}
template <class RandomAccessIterator>
inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) {
__make_heap(first, last, value_type(first), distance_type(first));
}
template <class RandomAccessIterator, class Compare, class T, class Distance>
void __make_heap(RandomAccessIterator first, RandomAccessIterator last,
Compare comp, T*, Distance*) {
if (last - first < 2) return;
Distance len = last - first;
Distance parent = (len - 2)/2;
while (true) {
__adjust_heap(first, parent, len, T(*(first + parent)), comp);
if (parent == 0) return;
parent--;
}
}
template <class RandomAccessIterator, class Compare>
inline void make_heap(RandomAccessIterator first, RandomAccessIterator last,
Compare comp) {
__make_heap(first, last, comp, value_type(first), distance_type(first));
}
template <class RandomAccessIterator>
void sort_heap(RandomAccessIterator first, RandomAccessIterator last) {
while (last - first > 1) pop_heap(first, last--);
}
template <class RandomAccessIterator, class Compare>
void sort_heap(RandomAccessIterator first, RandomAccessIterator last,
Compare comp) {
while (last - first > 1) pop_heap(first, last--, comp);
}
template <class T>
pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t len, T*) {
if (len > ptrdiff_t(2147483647 / sizeof(T)))
len = 2147483647 / sizeof(T);
while (len > 0) {
T* tmp = (T*) malloc((size_t)len * sizeof(T));
if (tmp != 0)
return pair<T*, ptrdiff_t>(tmp, len);
len /= 2;
}
return pair<T*, ptrdiff_t>((T*)0, 0);
}
template <class T>
void return_temporary_buffer(T* p) {
free(p);
}
template <class ForwardIterator,
class T >
class temporary_buffer {
private:
ptrdiff_t original_len;
ptrdiff_t len;
T* buffer;
void allocate_buffer() {
original_len = len;
buffer = 0;
if (len > (ptrdiff_t)(2147483647 / sizeof(T)))
len = 2147483647 / sizeof(T);
while (len > 0) {
buffer = (T*) malloc(len * sizeof(T));
if (buffer)
break;
len /= 2;
}
}
void initialize_buffer(const T&, __true_type) {}
void initialize_buffer(const T& val, __false_type) {
uninitialized_fill_n(buffer, len, val);
}
public:
ptrdiff_t size() const { return len; }
ptrdiff_t requested_size() const { return original_len; }
T* begin() { return buffer; }
T* end() { return buffer + len; }
temporary_buffer(ForwardIterator first, ForwardIterator last) {
try {
len = 0;
distance(first, last, len);
allocate_buffer();
if (len > 0)
initialize_buffer(*first,
__type_traits<T>::has_trivial_default_constructor());
}
catch(...) {
free(buffer);
buffer = 0;
len = 0;
throw;
}
}
~temporary_buffer() {
destroy(buffer, buffer + len);
free(buffer);
}
private:
temporary_buffer(const temporary_buffer&) {}
void operator=(const temporary_buffer&) {}
};
template <class T>
inline const T& __median(const T& a, const T& b, const T& c) {
if (a < b)
if (b < c)
return b;
else if (a < c)
return c;
else
return a;
else if (a < c)
return a;
else if (b < c)
return c;
else
return b;
}
template <class T, class Compare>
inline const T& __median(const T& a, const T& b, const T& c, Compare comp) {
if (comp(a, b))
if (comp(b, c))
return b;
else if (comp(a, c))
return c;
else
return a;
else if (comp(a, c))
return a;
else if (comp(b, c))
return c;
else
return b;
}
template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f) {
for ( ; first != last; ++first)
f(*first);
return f;
}
template <class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T& value) {
while (first != last && *first != value) ++first;
return first;
}
template <class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last,
Predicate pred) {
while (first != last && !pred(*first)) ++first;
return first;
}
template <class ForwardIterator>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) {
if (first == last) return last;
ForwardIterator next = first;
while(++next != last) {
if (*first == *next) return first;
first = next;
}
return last;
}
template <class ForwardIterator, class BinaryPredicate>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last,
BinaryPredicate binary_pred) {
if (first == last) return last;
ForwardIterator next = first;
while(++next != last) {
if (binary_pred(*first, *next)) return first;
first = next;
}
return last;
}
template <class InputIterator, class T, class Size>
void count(InputIterator first, InputIterator last, const T& value,
Size& n) {
for ( ; first != last; ++first)
if (*first == value)
++n;
}
template <class InputIterator, class Predicate, class Size>
void count_if(InputIterator first, InputIterator last, Predicate pred,
Size& n) {
for ( ; first != last; ++first)
if (pred(*first))
++n;
}
template <class InputIterator, class T>
iterator_traits<InputIterator>::difference_type
count(InputIterator first, InputIterator last, const T& value) {
iterator_traits<InputIterator>::difference_type n = 0;
for ( ; first != last; ++first)
if (*first == value)
++n;
return n;
}
template <class InputIterator, class Predicate>
iterator_traits<InputIterator>::difference_type
count_if(InputIterator first, InputIterator last, Predicate pred) {
iterator_traits<InputIterator>::difference_type n = 0;
for ( ; first != last; ++first)
if (pred(*first))
++n;
return n;
}
template <class ForwardIterator1, class ForwardIterator2, class Distance1,
class Distance2>
ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
Distance1*, Distance2*) {
Distance1 d1 = 0;
distance(first1, last1, d1);
Distance2 d2 = 0;
distance(first2, last2, d2);
if (d1 < d2) return last1;
ForwardIterator1 current1 = first1;
ForwardIterator2 current2 = first2;
while (current2 != last2)
if (*current1 == *current2) {
++current1;
++current2;
}
else {
if (d1 == d2)
return last1;
else {
current1 = ++first1;
current2 = first2;
--d1;
}
}
return first1;
}
template <class ForwardIterator1, class ForwardIterator2>
inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2)
{
return __search(first1, last1, first2, last2, distance_type(first1),
distance_type(first2));
}
template <class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate, class Distance1, class Distance2>
ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate binary_pred, Distance1*, Distance2*) {
Distance1 d1 = 0;
distance(first1, last1, d1);
Distance2 d2 = 0;
distance(first2, last2, d2);
if (d1 < d2) return last1;
ForwardIterator1 current1 = first1;
ForwardIterator2 current2 = first2;
while (current2 != last2)
if (binary_pred(*current1, *current2)) {
++current1;
++current2;
}
else {
if (d1 == d2)
return last1;
else {
current1 = ++first1;
current2 = first2;
--d1;
}
}
return first1;
}
template <class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate>
inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate binary_pred) {
return __search(first1, last1, first2, last2, binary_pred,
distance_type(first1), distance_type(first2));
}
template <class ForwardIterator, class Integer, class T>
ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
Integer count, const T& value) {
if (count <= 0)
return first;
else {
first = find(first, last, value);
while (first != last) {
Integer n = count - 1;
ForwardIterator i = first;
++i;
while (i != last && n != 0 && *i == value) {
++i;
--n;
}
if (n == 0)
return first;
else
first = find(i, last, value);
}
return last;
}
}
template <class ForwardIterator, class Integer, class T, class BinaryPredicate>
ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
Integer count, const T& value,
BinaryPredicate binary_pred) {
if (count <= 0)
return first;
else {
while (first != last) {
if (binary_pred(*first, value)) break;
++first;
}
while (first != last) {
Integer n = count - 1;
ForwardIterator i = first;
++i;
while (i != last && n != 0 && binary_pred(*i, value)) {
++i;
--n;
}
if (n == 0)
return first;
else {
while (i != last) {
if (binary_pred(*i, value)) break;
++i;
}
first = i;
}
}
return last;
}
}
template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2) {
for ( ; first1 != last1; ++first1, ++first2)
iter_swap(first1, first2);
return first2;
}
template <class InputIterator, class OutputIterator, class UnaryOperation>
OutputIterator transform(InputIterator first, InputIterator last,
OutputIterator result, UnaryOperation op) {
for ( ; first != last; ++first, ++result)
*result = op(*first);
return result;
}
template <class InputIterator1, class InputIterator2, class OutputIterator,
class BinaryOperation>
OutputIterator transform(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, OutputIterator result,
BinaryOperation binary_op) {
for ( ; first1 != last1; ++first1, ++first2, ++result)
*result = binary_op(*first1, *first2);
return result;
}
template <class ForwardIterator, class T>
void replace(ForwardIterator first, ForwardIterator last, const T& old_value,
const T& new_value) {
for ( ; first != last; ++first)
if (*first == old_value) *first = new_value;
}
template <class ForwardIterator, class Predicate, class T>
void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred,
const T& new_value) {
for ( ; first != last; ++first)
if (pred(*first)) *first = new_value;
}
template <class InputIterator, class OutputIterator, class T>
OutputIterator replace_copy(InputIterator first, InputIterator last,
OutputIterator result, const T& old_value,
const T& new_value) {
for ( ; first != last; ++first, ++result)
*result = *first == old_value ? new_value : *first;
return result;
}
template <class Iterator, class OutputIterator, class Predicate, class T>
OutputIterator replace_copy_if(Iterator first, Iterator last,
OutputIterator result, Predicate pred,
const T& new_value) {
for ( ; first != last; ++first, ++result)
*result = pred(*first) ? new_value : *first;
return result;
}
template <class ForwardIterator, class Generator>
void generate(ForwardIterator first, ForwardIterator last, Generator gen) {
for ( ; first != last; ++first)
*first = gen();
}
template <class OutputIterator, class Size, class Generator>
OutputIterator generate_n(OutputIterator first, Size n, Generator gen) {
for ( ; n > 0; --n, ++first)
*first = gen();
return first;
}
template <class InputIterator, class OutputIterator, class T>
OutputIterator remove_copy(InputIterator first, InputIterator last,
OutputIterator result, const T& value) {
for ( ; first != last; ++first)
if (*first != value) {
*result = *first;
++result;
}
return result;
}
template <class InputIterator, class OutputIterator, class Predicate>
OutputIterator remove_copy_if(InputIterator first, InputIterator last,
OutputIterator result, Predicate pred) {
for ( ; first != last; ++first)
if (!pred(*first)) {
*result = *first;
++result;
}
return result;
}
template <class ForwardIterator, class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last,
const T& value) {
first = find(first, last, value);
ForwardIterator next = first;
return first == last ? first : remove_copy(++next, last, first, value);
}
template <class ForwardIterator, class Predicate>
ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
Predicate pred) {
first = find_if(first, last, pred);
ForwardIterator next = first;
return first == last ? first : remove_copy_if(++next, last, first, pred);
}
template <class InputIterator, class ForwardIterator>
ForwardIterator __unique_copy(InputIterator first, InputIterator last,
ForwardIterator result, forward_iterator_tag) {
*result = *first;
while (++first != last)
if (*result != *first) *++result = *first;
return ++result;
}
template <class InputIterator, class BidirectionalIterator>
inline BidirectionalIterator __unique_copy(InputIterator first,
InputIterator last,
BidirectionalIterator result,
bidirectional_iterator_tag) {
return __unique_copy(first, last, result, forward_iterator_tag());
}
template <class InputIterator, class RandomAccessIterator>
inline RandomAccessIterator __unique_copy(InputIterator first,
InputIterator last,
RandomAccessIterator result,
random_access_iterator_tag) {
return __unique_copy(first, last, result, forward_iterator_tag());
}
template <class InputIterator, class OutputIterator, class T>
OutputIterator __unique_copy(InputIterator first, InputIterator last,
OutputIterator result, T*) {
T value = *first;
*result = value;
while (++first != last)
if (value != *first) {
value = *first;
*++result = value;
}
return ++result;
}
template <class InputIterator, class OutputIterator>
inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
OutputIterator result,
output_iterator_tag) {
return __unique_copy(first, last, result, value_type(first));
}
template <class InputIterator, class OutputIterator>
inline OutputIterator unique_copy(InputIterator first, InputIterator last,
OutputIterator result) {
if (first == last) return result;
return __unique_copy(first, last, result, iterator_category(result));
}
template <class InputIterator, class ForwardIterator, class BinaryPredicate>
ForwardIterator __unique_copy(InputIterator first, InputIterator last,
ForwardIterator result,
BinaryPredicate binary_pred,
forward_iterator_tag) {
*result = *first;
while (++first != last)
if (!binary_pred(*result, *first)) *++result = *first;
return ++result;
}
template <class InputIterator, class BidirectionalIterator,
class BinaryPredicate>
inline BidirectionalIterator __unique_copy(InputIterator first,
InputIterator last,
BidirectionalIterator result,
BinaryPredicate binary_pred,
bidirectional_iterator_tag) {
return __unique_copy(first, last, result, binary_pred,
forward_iterator_tag());
}
template <class InputIterator, class RandomAccessIterator,
class BinaryPredicate>
inline RandomAccessIterator __unique_copy(InputIterator first,
InputIterator last,
RandomAccessIterator result,
BinaryPredicate binary_pred,
random_access_iterator_tag) {
return __unique_copy(first, last, result, binary_pred,
forward_iterator_tag());
}
template <class InputIterator, class OutputIterator, class BinaryPredicate,
class T>
OutputIterator __unique_copy(InputIterator first, InputIterator last,
OutputIterator result,
BinaryPredicate binary_pred, T*) {
T value = *first;
*result = value;
while (++first != last)
if (!binary_pred(value, *first)) {
value = *first;
*++result = value;
}
return ++result;
}
template <class InputIterator, class OutputIterator, class BinaryPredicate>
inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
OutputIterator result,
BinaryPredicate binary_pred,
output_iterator_tag) {
return __unique_copy(first, last, result, binary_pred, value_type(first));
}
template <class InputIterator, class OutputIterator, class BinaryPredicate>
inline OutputIterator unique_copy(InputIterator first, InputIterator last,
OutputIterator result,
BinaryPredicate binary_pred) {
if (first == last) return result;
return __unique_copy(first, last, result, binary_pred,
iterator_category(result));
}
template <class ForwardIterator>
ForwardIterator unique(ForwardIterator first, ForwardIterator last) {
first = adjacent_find(first, last);
return unique_copy(first, last, first);
}
template <class ForwardIterator, class BinaryPredicate>
ForwardIterator unique(ForwardIterator first, ForwardIterator last,
BinaryPredicate binary_pred) {
first = adjacent_find(first, last, binary_pred);
return unique_copy(first, last, first, binary_pred);
}
template <class BidirectionalIterator>
void __reverse(BidirectionalIterator first, BidirectionalIterator last,
bidirectional_iterator_tag) {
while (true)
if (first == last || first == --last)
return;
else
iter_swap(first++, last);
}
template <class RandomAccessIterator>
void __reverse(RandomAccessIterator first, RandomAccessIterator last,
random_access_iterator_tag) {
while (first < last) iter_swap(first++, --last);
}
template <class BidirectionalIterator>
inline void reverse(BidirectionalIterator first, BidirectionalIterator last) {
__reverse(first, last, iterator_category(first));
}
template <class BidirectionalIterator, class OutputIterator>
OutputIterator reverse_copy(BidirectionalIterator first,
BidirectionalIterator last,
OutputIterator result) {
while (first != last) {
--last;
*result = *last;
++result;
}
return result;
}
template <class ForwardIterator, class Distance>
void __rotate(ForwardIterator first, ForwardIterator middle,
ForwardIterator last, Distance*, forward_iterator_tag) {
for (ForwardIterator i = middle; ;) {
iter_swap(first, i);
++first;
++i;
if (first == middle) {
if (i == last) return;
middle = i;
}
else if (i == last)
i = middle;
}
}
template <class BidirectionalIterator, class Distance>
void __rotate(BidirectionalIterator first, BidirectionalIterator middle,
BidirectionalIterator last, Distance*,
bidirectional_iterator_tag) {
reverse(first, middle);
reverse(middle, last);
reverse(first, last);
}
template <class EuclideanRingElement>
EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n)
{
while (n != 0) {
EuclideanRingElement t = m % n;
m = n;
n = t;
}
return m;
}
template <class RandomAccessIterator, class Distance, class T>
void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last,
RandomAccessIterator initial, Distance shift, T*) {
T value = *initial;
RandomAccessIterator ptr1 = initial;
RandomAccessIterator ptr2 = ptr1 + shift;
while (ptr2 != initial) {
*ptr1 = *ptr2;
ptr1 = ptr2;
if (last - ptr2 > shift)
ptr2 += shift;
else
ptr2 = first + (shift - (last - ptr2));
}
*ptr1 = value;
}
template <class RandomAccessIterator, class Distance>
void __rotate(RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last, Distance*,
random_access_iterator_tag) {
Distance n = __gcd(last - first, middle - first);
while (n--)
__rotate_cycle(first, last, first + n, middle - first,
value_type(first));
}
template <class ForwardIterator>
inline void rotate(ForwardIterator first, ForwardIterator middle,
ForwardIterator last) {
if (first == middle || middle == last) return;
__rotate(first, middle, last, distance_type(first),
iterator_category(first));
}
template <class ForwardIterator, class OutputIterator>
OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle,
ForwardIterator last, OutputIterator result) {
return copy(first, middle, copy(middle, last, result));
}
template <class RandomAccessIterator, class Distance>
void __random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
Distance*) {
if (first == last) return;
for (RandomAccessIterator i = first + 1; i != last; ++i)
iter_swap(i, first + Distance(lrand48() % ((i - first) + 1)));
}
template <class RandomAccessIterator>
inline void random_shuffle(RandomAccessIterator first,
RandomAccessIterator last) {
__random_shuffle(first, last, distance_type(first));
}
template <class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
RandomNumberGenerator& rand) {
if (first == last) return;
for (RandomAccessIterator i = first + 1; i != last; ++i)
iter_swap(i, first + rand((i - first) + 1));
}
template <class ForwardIterator, class OutputIterator, class Distance>
OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
OutputIterator out, const Distance n)
{
Distance remaining = 0;
distance(first, last, remaining);
Distance m = min(n, remaining);
while (m > 0) {
if (lrand48() % remaining < m) {
*out = *first;
++out;
--m;
}
--remaining;
++first;
}
return out;
}
template <class ForwardIterator, class OutputIterator, class Distance,
class RandomNumberGenerator>
OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
OutputIterator out, const Distance n,
RandomNumberGenerator& rand)
{
Distance remaining = 0;
distance(first, last, remaining);
Distance m = min(n, remaining);
while (m > 0) {
if (rand(remaining) < m) {
*out = *first;
++out;
--m;
}
--remaining;
++first;
}
return out;
}
template <class InputIterator, class RandomAccessIterator, class Distance>
RandomAccessIterator __random_sample(InputIterator first, InputIterator last,
RandomAccessIterator out,
const Distance n)
{
Distance m = 0;
Distance t = n;
for ( ; first != last && m < n; ++m, ++first)
out[m] = *first;
while (first != last) {
++t;
Distance M = lrand48() % t;
if (M < n)
out[M] = *first;
++first;
}
return out + m;
}
template <class InputIterator, class RandomAccessIterator,
class RandomNumberGenerator, class Distance>
RandomAccessIterator __random_sample(InputIterator first, InputIterator last,
RandomAccessIterator out,
RandomNumberGenerator& rand,
const Distance n)
{
Distance m = 0;
Distance t = n;
for ( ; first != last && m < n; ++m, ++first)
out[m] = *first;
while (first != last) {
++t;
Distance M = rand(t);
if (M < n)
out[M] = *first;
++first;
}
return out + m;
}
template <class InputIterator, class RandomAccessIterator>
inline RandomAccessIterator
random_sample(InputIterator first, InputIterator last,
RandomAccessIterator out_first, RandomAccessIterator out_last)
{
return __random_sample(first, last, out_first, out_last - out_first);
}
template <class InputIterator, class RandomAccessIterator,
class RandomNumberGenerator>
inline RandomAccessIterator
random_sample(InputIterator first, InputIterator last,
RandomAccessIterator out_first, RandomAccessIterator out_last,
RandomNumberGenerator& rand)
{
return __random_sample(first, last, out_first, rand, out_last - out_first);
}
template <class BidirectionalIterator, class Predicate>
BidirectionalIterator partition(BidirectionalIterator first,
BidirectionalIterator last, Predicate pred) {
while (true) {
while (true)
if (first == last)
return first;
else if (pred(*first))
++first;
else
break;
--last;
while (true)
if (first == last)
return first;
else if (!pred(*last))
--last;
else
break;
iter_swap(first, last);
++first;
}
}
template <class ForwardIterator, class Predicate, class Distance>
ForwardIterator __inplace_stable_partition(ForwardIterator first,
ForwardIterator last,
Predicate pred, Distance len) {
if (len == 1) return pred(*first) ? last : first;
ForwardIterator middle = first;
advance(middle, len / 2);
ForwardIterator
first_cut = __inplace_stable_partition(first, middle, pred, len / 2);
ForwardIterator
second_cut = __inplace_stable_partition(middle, last, pred,
len - len / 2);
rotate(first_cut, middle, second_cut);
len = 0;
distance(middle, second_cut, len);
advance(first_cut, len);
return first_cut;
}
template <class ForwardIterator, class Pointer, class Predicate,
class Distance>
ForwardIterator __stable_partition_adaptive(ForwardIterator first,
ForwardIterator last,
Predicate pred, Distance len,
Pointer buffer,
Distance buffer_size) {
if (len <= buffer_size) {
ForwardIterator result1 = first;
Pointer result2 = buffer;
for ( ; first != last ; ++first)
if (pred(*first)) {
*result1 = *first;
++result1;
}
else {
*result2 = *first;
++result2;
}
copy(buffer, result2, result1);
return result1;
}
else {
ForwardIterator middle = first;
advance(middle, len / 2);
ForwardIterator first_cut =
__stable_partition_adaptive(first, middle, pred, len / 2,
buffer, buffer_size);
ForwardIterator second_cut =
__stable_partition_adaptive(middle, last, pred, len - len / 2,
buffer, buffer_size);
rotate(first_cut, middle, second_cut);
len = 0;
distance(middle, second_cut, len);
advance(first_cut, len);
return first_cut;
}
}
template <class ForwardIterator, class Predicate, class T, class Distance>
inline ForwardIterator __stable_partition_aux(ForwardIterator first,
ForwardIterator last,
Predicate pred, T*, Distance*) {
temporary_buffer<ForwardIterator, T> buf(first, last);
if (buf.size() > 0)
return __stable_partition_adaptive(first, last, pred,
Distance(buf.requested_size()),
buf.begin(), buf.size());
else
return __inplace_stable_partition(first, last, pred,
Distance(buf.requested_size()));
}
template <class ForwardIterator, class Predicate>
inline ForwardIterator stable_partition(ForwardIterator first,
ForwardIterator last,
Predicate pred) {
if (first == last)
return first;
else
return __stable_partition_aux(first, last, pred,
value_type(first), distance_type(first));
}
template <class RandomAccessIterator, class T>
RandomAccessIterator __unguarded_partition(RandomAccessIterator first,
RandomAccessIterator last,
T pivot) {
while (1) {
while (*first < pivot) ++first;
--last;
while (pivot < *last) --last;
if (!(first < last)) return first;
iter_swap(first, last);
++first;
}
}
template <class RandomAccessIterator, class T, class Compare>
RandomAccessIterator __unguarded_partition(RandomAccessIterator first,
RandomAccessIterator last,
T pivot, Compare comp) {
while (1) {
while (comp(*first, pivot)) ++first;
--last;
while (comp(pivot, *last)) --last;
if (!(first < last)) return first;
iter_swap(first, last);
++first;
}
}
const int __stl_threshold = 16;
template <class RandomAccessIterator, class T>
void __unguarded_linear_insert(RandomAccessIterator last, T value) {
RandomAccessIterator next = last;
--next;
while (value < *next) {
*last = *next;
last = next;
--next;
}
*last = value;
}
template <class RandomAccessIterator, class T, class Compare>
void __unguarded_linear_insert(RandomAccessIterator last, T value,
Compare comp) {
RandomAccessIterator next = last;
--next;
while (comp(value , *next)) {
*last = *next;
last = next;
--next;
}
*last = value;
}
template <class RandomAccessIterator, class T>
inline void __linear_insert(RandomAccessIterator first,
RandomAccessIterator last, T*) {
T value = *last;
if (value < *first) {
copy_backward(first, last, last + 1);
*first = value;
} else
__unguarded_linear_insert(last, value);
}
template <class RandomAccessIterator, class T, class Compare>
inline void __linear_insert(RandomAccessIterator first,
RandomAccessIterator last, T*, Compare comp) {
T value = *last;
if (comp(value, *first)) {
copy_backward(first, last, last + 1);
*first = value;
} else
__unguarded_linear_insert(last, value, comp);
}
template <class RandomAccessIterator>
void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) {
if (first == last) return;
for (RandomAccessIterator i = first + 1; i != last; ++i)
__linear_insert(first, i, value_type(first));
}
template <class RandomAccessIterator, class Compare>
void __insertion_sort(RandomAccessIterator first,
RandomAccessIterator last, Compare comp) {
if (first == last) return;
for (RandomAccessIterator i = first + 1; i != last; ++i)
__linear_insert(first, i, value_type(first), comp);
}
template <class RandomAccessIterator, class T>
void __unguarded_insertion_sort_aux(RandomAccessIterator first,
RandomAccessIterator last, T*) {
for (RandomAccessIterator i = first; i != last; ++i)
__unguarded_linear_insert(i, T(*i));
}
template <class RandomAccessIterator>
inline void __unguarded_insertion_sort(RandomAccessIterator first,
RandomAccessIterator last) {
__unguarded_insertion_sort_aux(first, last, value_type(first));
}
template <class RandomAccessIterator, class T, class Compare>
void __unguarded_insertion_sort_aux(RandomAccessIterator first,
RandomAccessIterator last,
T*, Compare comp) {
for (RandomAccessIterator i = first; i != last; ++i)
__unguarded_linear_insert(i, T(*i), comp);
}
template <class RandomAccessIterator, class Compare>
inline void __unguarded_insertion_sort(RandomAccessIterator first,
RandomAccessIterator last,
Compare comp) {
__unguarded_insertion_sort_aux(first, last, value_type(first), comp);
}
template <class RandomAccessIterator>
void __final_insertion_sort(RandomAccessIterator first,
RandomAccessIterator last) {
if (last - first > __stl_threshold) {
__insertion_sort(first, first + __stl_threshold);
__unguarded_insertion_sort(first + __stl_threshold, last);
} else
__insertion_sort(first, last);
}
template <class RandomAccessIterator, class Compare>
void __final_insertion_sort(RandomAccessIterator first,
RandomAccessIterator last, Compare comp) {
if (last - first > __stl_threshold) {
__insertion_sort(first, first + __stl_threshold, comp);
__unguarded_insertion_sort(first + __stl_threshold, last, comp);
} else
__insertion_sort(first, last, comp);
}
template <class Size>
Size __lg(Size n) {
Size k;
for (k = 0; n != 1; n = n / 2) ++k;
return k;
}
template <class RandomAccessIterator, class T, class Size>
void __introsort_loop(RandomAccessIterator first,
RandomAccessIterator last, T*,
Size depth_limit) {
while (last - first > __stl_threshold) {
if (depth_limit == 0) {
partial_sort(first, last, last);
return;
}
--depth_limit;
RandomAccessIterator cut = __unguarded_partition
(first, last, T(__median(*first, *(first + (last - first)/2),
*(last - 1))));
__introsort_loop(cut, last, value_type(first), depth_limit);
last = cut;
}
}
template <class RandomAccessIterator, class T, class Size, class Compare>
void __introsort_loop(RandomAccessIterator first,
RandomAccessIterator last, T*,
Size depth_limit, Compare comp) {
while (last - first > __stl_threshold) {
if (depth_limit == 0) {
partial_sort(first, last, last, comp);
return;
}
--depth_limit;
RandomAccessIterator cut = __unguarded_partition
(first, last, T(__median(*first, *(first + (last - first)/2),
*(last - 1), comp)), comp);
__introsort_loop(cut, last, value_type(first), depth_limit, comp);
last = cut;
}
}
template <class RandomAccessIterator>
inline void sort(RandomAccessIterator first, RandomAccessIterator last) {
if (first != last) {
__introsort_loop(first, last, value_type(first), __lg(last - first) * 2);
__final_insertion_sort(first, last);
}
}
template <class RandomAccessIterator, class Compare>
inline void sort(RandomAccessIterator first, RandomAccessIterator last,
Compare comp) {
if (first != last) {
__introsort_loop(first, last, value_type(first), __lg(last - first) * 2,
comp);
__final_insertion_sort(first, last, comp);
}
}
template <class RandomAccessIterator>
void __inplace_stable_sort(RandomAccessIterator first,
RandomAccessIterator last) {
if (last - first < 15) {
__insertion_sort(first, last);
return;
}
RandomAccessIterator middle = first + (last - first) / 2;
__inplace_stable_sort(first, middle);
__inplace_stable_sort(middle, last);
__merge_without_buffer(first, middle, last, middle - first, last - middle);
}
template <class RandomAccessIterator, class Compare>
void __inplace_stable_sort(RandomAccessIterator first,
RandomAccessIterator last, Compare comp) {
if (last - first < 15) {
__insertion_sort(first, last, comp);
return;
}
RandomAccessIterator middle = first + (last - first) / 2;
__inplace_stable_sort(first, middle, comp);
__inplace_stable_sort(middle, last, comp);
__merge_without_buffer(first, middle, last, middle - first,
last - middle, comp);
}
template <class RandomAccessIterator1, class RandomAccessIterator2,
class Distance>
void __merge_sort_loop(RandomAccessIterator1 first,
RandomAccessIterator1 last,
RandomAccessIterator2 result, Distance step_size) {
Distance two_step = 2 * step_size;
while (last - first >= two_step) {
result = merge(first, first + step_size,
first + step_size, first + two_step, result);
first += two_step;
}
step_size = min(Distance(last - first), step_size);
merge(first, first + step_size, first + step_size, last, result);
}
template <class RandomAccessIterator1, class RandomAccessIterator2,
class Distance, class Compare>
void __merge_sort_loop(RandomAccessIterator1 first,
RandomAccessIterator1 last,
RandomAccessIterator2 result, Distance step_size,
Compare comp) {
Distance two_step = 2 * step_size;
while (last - first >= two_step) {
result = merge(first, first + step_size,
first + step_size, first + two_step, result, comp);
first += two_step;
}
step_size = min(Distance(last - first), step_size);
merge(first, first + step_size, first + step_size, last, result, comp);
}
const int __stl_chunk_size = 7;
template <class RandomAccessIterator, class Distance>
void __chunk_insertion_sort(RandomAccessIterator first,
RandomAccessIterator last, Distance chunk_size) {
while (last - first >= chunk_size) {
__insertion_sort(first, first + chunk_size);
first += chunk_size;
}
__insertion_sort(first, last);
}
template <class RandomAccessIterator, class Distance, class Compare>
void __chunk_insertion_sort(RandomAccessIterator first,
RandomAccessIterator last,
Distance chunk_size, Compare comp) {
while (last - first >= chunk_size) {
__insertion_sort(first, first + chunk_size, comp);
first += chunk_size;
}
__insertion_sort(first, last, comp);
}
template <class RandomAccessIterator, class Pointer, class Distance>
void __merge_sort_with_buffer(RandomAccessIterator first,
RandomAccessIterator last,
Pointer buffer, Distance*) {
Distance len = last - first;
Pointer buffer_last = buffer + len;
Distance step_size = __stl_chunk_size;
__chunk_insertion_sort(first, last, step_size);
while (step_size < len) {
__merge_sort_loop(first, last, buffer, step_size);
step_size *= 2;
__merge_sort_loop(buffer, buffer_last, first, step_size);
step_size *= 2;
}
}
template <class RandomAccessIterator, class Pointer, class Distance,
class Compare>
void __merge_sort_with_buffer(RandomAccessIterator first,
RandomAccessIterator last, Pointer buffer,
Distance*, Compare comp) {
Distance len = last - first;
Pointer buffer_last = buffer + len;
Distance step_size = __stl_chunk_size;
__chunk_insertion_sort(first, last, step_size, comp);
while (step_size < len) {
__merge_sort_loop(first, last, buffer, step_size, comp);
step_size *= 2;
__merge_sort_loop(buffer, buffer_last, first, step_size, comp);
step_size *= 2;
}
}
template <class RandomAccessIterator, class Pointer, class Distance>
void __stable_sort_adaptive(RandomAccessIterator first,
RandomAccessIterator last, Pointer buffer,
Distance buffer_size) {
Distance len = (last - first + 1) / 2;
RandomAccessIterator middle = first + len;
if (len > buffer_size) {
__stable_sort_adaptive(first, middle, buffer, buffer_size);
__stable_sort_adaptive(middle, last, buffer, buffer_size);
} else {
__merge_sort_with_buffer(first, middle, buffer, (Distance*)0);
__merge_sort_with_buffer(middle, last, buffer, (Distance*)0);
}
__merge_adaptive(first, middle, last, Distance(middle - first),
Distance(last - middle), buffer, buffer_size);
}
template <class RandomAccessIterator, class Pointer, class Distance,
class Compare>
void __stable_sort_adaptive(RandomAccessIterator first,
RandomAccessIterator last, Pointer buffer,
Distance buffer_size, Compare comp) {
Distance len = (last - first + 1) / 2;
RandomAccessIterator middle = first + len;
if (len > buffer_size) {
__stable_sort_adaptive(first, middle, buffer, buffer_size,
comp);
__stable_sort_adaptive(middle, last, buffer, buffer_size,
comp);
} else {
__merge_sort_with_buffer(first, middle, buffer, (Distance*)0, comp);
__merge_sort_with_buffer(middle, last, buffer, (Distance*)0, comp);
}
__merge_adaptive(first, middle, last, Distance(middle - first),
Distance(last - middle), buffer, buffer_size,
comp);
}
template <class RandomAccessIterator, class T, class Distance>
inline void __stable_sort_aux(RandomAccessIterator first,
RandomAccessIterator last, T*, Distance*) {
temporary_buffer<RandomAccessIterator, T> buf(first, last);
if (buf.begin() == 0)
__inplace_stable_sort(first, last);
else
__stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()));
}
template <class RandomAccessIterator, class T, class Distance, class Compare>
inline void __stable_sort_aux(RandomAccessIterator first,
RandomAccessIterator last, T*, Distance*,
Compare comp) {
temporary_buffer<RandomAccessIterator, T> buf(first, last);
if (buf.begin() == 0)
__inplace_stable_sort(first, last, comp);
else
__stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()),
comp);
}
template <class RandomAccessIterator>
inline void stable_sort(RandomAccessIterator first,
RandomAccessIterator last) {
__stable_sort_aux(first, last, value_type(first), distance_type(first));
}
template <class RandomAccessIterator, class Compare>
inline void stable_sort(RandomAccessIterator first,
RandomAccessIterator last, Compare comp) {
__stable_sort_aux(first, last, value_type(first), distance_type(first),
comp);
}
template <class RandomAccessIterator, class T>
void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last, T*) {
make_heap(first, middle);
for (RandomAccessIterator i = middle; i < last; ++i)
if (*i < *first)
__pop_heap(first, middle, i, T(*i), distance_type(first));
sort_heap(first, middle);
}
template <class RandomAccessIterator>
inline void partial_sort(RandomAccessIterator first,
RandomAccessIterator middle,
RandomAccessIterator last) {
__partial_sort(first, middle, last, value_type(first));
}
template <class RandomAccessIterator, class T, class Compare>
void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last, T*, Compare comp) {
make_heap(first, middle, comp);
for (RandomAccessIterator i = middle; i < last; ++i)
if (comp(*i, *first))
__pop_heap(first, middle, i, T(*i), comp, distance_type(first));
sort_heap(first, middle, comp);
}
template <class RandomAccessIterator, class Compare>
inline void partial_sort(RandomAccessIterator first,
RandomAccessIterator middle,
RandomAccessIterator last, Compare comp) {
__partial_sort(first, middle, last, value_type(first), comp);
}
template <class InputIterator, class RandomAccessIterator, class Distance,
class T>
RandomAccessIterator __partial_sort_copy(InputIterator first,
InputIterator last,
RandomAccessIterator result_first,
RandomAccessIterator result_last,
Distance*, T*) {
if (result_first == result_last) return result_last;
RandomAccessIterator result_real_last = result_first;
while(first != last && result_real_last != result_last) {
*result_real_last = *first;
++result_real_last;
++first;
}
make_heap(result_first, result_real_last);
while (first != last) {
if (*first < *result_first)
__adjust_heap(result_first, Distance(0),
Distance(result_real_last - result_first), T(*first));
++first;
}
sort_heap(result_first, result_real_last);
return result_real_last;
}
template <class InputIterator, class RandomAccessIterator>
inline RandomAccessIterator
partial_sort_copy(InputIterator first, InputIterator last,
RandomAccessIterator result_first,
RandomAccessIterator result_last) {
return __partial_sort_copy(first, last, result_first, result_last,
distance_type(result_first), value_type(first));
}
template <class InputIterator, class RandomAccessIterator, class Compare,
class Distance, class T>
RandomAccessIterator __partial_sort_copy(InputIterator first,
InputIterator last,
RandomAccessIterator result_first,
RandomAccessIterator result_last,
Compare comp, Distance*, T*) {
if (result_first == result_last) return result_last;
RandomAccessIterator result_real_last = result_first;
while(first != last && result_real_last != result_last) {
*result_real_last = *first;
++result_real_last;
++first;
}
make_heap(result_first, result_real_last, comp);
while (first != last) {
if (comp(*first, *result_first))
__adjust_heap(result_first, Distance(0),
Distance(result_real_last - result_first), T(*first),
comp);
++first;
}
sort_heap(result_first, result_real_last, comp);
return result_real_last;
}
template <class InputIterator, class RandomAccessIterator, class Compare>
inline RandomAccessIterator
partial_sort_copy(InputIterator first, InputIterator last,
RandomAccessIterator result_first,
RandomAccessIterator result_last, Compare comp) {
return __partial_sort_copy(first, last, result_first, result_last, comp,
distance_type(result_first), value_type(first));
}
template <class RandomAccessIterator, class T>
void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
RandomAccessIterator last, T*) {
while (last - first > 3) {
RandomAccessIterator cut = __unguarded_partition
(first, last, T(__median(*first, *(first + (last - first)/2),
*(last - 1))));
if (cut <= nth)
first = cut;
else
last = cut;
}
__insertion_sort(first, last);
}
template <class RandomAccessIterator>
inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
RandomAccessIterator last) {
__nth_element(first, nth, last, value_type(first));
}
template <class RandomAccessIterator, class T, class Compare>
void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
RandomAccessIterator last, T*, Compare comp) {
while (last - first > 3) {
RandomAccessIterator cut = __unguarded_partition
(first, last, T(__median(*first, *(first + (last - first)/2),
*(last - 1), comp)), comp);
if (cut <= nth)
first = cut;
else
last = cut;
}
__insertion_sort(first, last, comp);
}
template <class RandomAccessIterator, class Compare>
inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
RandomAccessIterator last, Compare comp) {
__nth_element(first, nth, last, value_type(first), comp);
}
template <class ForwardIterator, class T, class Distance>
ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
const T& value, Distance*,
forward_iterator_tag) {
Distance len = 0;
distance(first, last, len);
Distance half;
ForwardIterator middle;
while (len > 0) {
half = len / 2;
middle = first;
advance(middle, half);
if (*middle < value) {
first = middle;
++first;
len = len - half - 1;
} else
len = half;
}
return first;
}
template <class RandomAccessIterator, class T, class Distance>
RandomAccessIterator __lower_bound(RandomAccessIterator first,
RandomAccessIterator last, const T& value,
Distance*, random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle;
while (len > 0) {
half = len / 2;
middle = first + half;
if (*middle < value) {
first = middle + 1;
len = len - half - 1;
} else
len = half;
}
return first;
}
template <class ForwardIterator, class T>
inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
const T& value) {
return __lower_bound(first, last, value, distance_type(first),
iterator_category(first));
}
template <class ForwardIterator, class T, class Compare, class Distance>
ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
const T& value, Compare comp, Distance*,
forward_iterator_tag) {
Distance len = 0;
distance(first, last, len);
Distance half;
ForwardIterator middle;
while (len > 0) {
half = len / 2;
middle = first;
advance(middle, half);
if (comp(*middle, value)) {
first = middle;
++first;
len = len - half - 1;
} else
len = half;
}
return first;
}
template <class RandomAccessIterator, class T, class Compare, class Distance>
RandomAccessIterator __lower_bound(RandomAccessIterator first,
RandomAccessIterator last,
const T& value, Compare comp, Distance*,
random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle;
while (len > 0) {
half = len / 2;
middle = first + half;
if (comp(*middle, value)) {
first = middle + 1;
len = len - half - 1;
} else
len = half;
}
return first;
}
template <class ForwardIterator, class T, class Compare>
inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
const T& value, Compare comp) {
return __lower_bound(first, last, value, comp, distance_type(first),
iterator_category(first));
}
template <class ForwardIterator, class T, class Distance>
ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
const T& value, Distance*,
forward_iterator_tag) {
Distance len = 0;
distance(first, last, len);
Distance half;
ForwardIterator middle;
while (len > 0) {
half = len / 2;
middle = first;
advance(middle, half);
if (value < *middle)
len = half;
else {
first = middle;
++first;
len = len - half - 1;
}
}
return first;
}
template <class RandomAccessIterator, class T, class Distance>
RandomAccessIterator __upper_bound(RandomAccessIterator first,
RandomAccessIterator last, const T& value,
Distance*, random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle;
while (len > 0) {
half = len / 2;
middle = first + half;
if (value < *middle)
len = half;
else {
first = middle + 1;
len = len - half - 1;
}
}
return first;
}
template <class ForwardIterator, class T>
inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
const T& value) {
return __upper_bound(first, last, value, distance_type(first),
iterator_category(first));
}
template <class ForwardIterator, class T, class Compare, class Distance>
ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
const T& value, Compare comp, Distance*,
forward_iterator_tag) {
Distance len = 0;
distance(first, last, len);
Distance half;
ForwardIterator middle;
while (len > 0) {
half = len / 2;
middle = first;
advance(middle, half);
if (comp(value, *middle))
len = half;
else {
first = middle;
++first;
len = len - half - 1;
}
}
return first;
}
template <class RandomAccessIterator, class T, class Compare, class Distance>
RandomAccessIterator __upper_bound(RandomAccessIterator first,
RandomAccessIterator last,
const T& value, Compare comp, Distance*,
random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle;
while (len > 0) {
half = len / 2;
middle = first + half;
if (comp(value, *middle))
len = half;
else {
first = middle + 1;
len = len - half - 1;
}
}
return first;
}
template <class ForwardIterator, class T, class Compare>
inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
const T& value, Compare comp) {
return __upper_bound(first, last, value, comp, distance_type(first),
iterator_category(first));
}
template <class ForwardIterator, class T, class Distance>
pair<ForwardIterator, ForwardIterator>
__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
Distance*, forward_iterator_tag) {
Distance len = 0;
distance(first, last, len);
Distance half;
ForwardIterator middle, left, right;
while (len > 0) {
half = len / 2;
middle = first;
advance(middle, half);
if (*middle < value) {
first = middle;
++first;
len = len - half - 1;
} else if (value < *middle)
len = half;
else {
left = lower_bound(first, middle, value);
advance(first, len);
right = upper_bound(++middle, first, value);
return pair<ForwardIterator, ForwardIterator>(left, right);
}
}
return pair<ForwardIterator, ForwardIterator>(first, first);
}
template <class RandomAccessIterator, class T, class Distance>
pair<RandomAccessIterator, RandomAccessIterator>
__equal_range(RandomAccessIterator first, RandomAccessIterator last,
const T& value, Distance*, random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle, left, right;
while (len > 0) {
half = len / 2;
middle = first + half;
if (*middle < value) {
first = middle + 1;
len = len - half - 1;
} else if (value < *middle)
len = half;
else {
left = lower_bound(first, middle, value);
right = upper_bound(++middle, first + len, value);
return pair<RandomAccessIterator, RandomAccessIterator>(left,
right);
}
}
return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
}
template <class ForwardIterator, class T>
inline pair<ForwardIterator, ForwardIterator>
equal_range(ForwardIterator first, ForwardIterator last, const T& value) {
return __equal_range(first, last, value, distance_type(first),
iterator_category(first));
}
template <class ForwardIterator, class T, class Compare, class Distance>
pair<ForwardIterator, ForwardIterator>
__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
Compare comp, Distance*, forward_iterator_tag) {
Distance len = 0;
distance(first, last, len);
Distance half;
ForwardIterator middle, left, right;
while (len > 0) {
half = len / 2;
middle = first;
advance(middle, half);
if (comp(*middle, value)) {
first = middle;
++first;
len = len - half - 1;
} else if (comp(value, *middle))
len = half;
else {
left = lower_bound(first, middle, value, comp);
advance(first, len);
right = upper_bound(++middle, first, value, comp);
return pair<ForwardIterator, ForwardIterator>(left, right);
}
}
return pair<ForwardIterator, ForwardIterator>(first, first);
}
template <class RandomAccessIterator, class T, class Compare, class Distance>
pair<RandomAccessIterator, RandomAccessIterator>
__equal_range(RandomAccessIterator first, RandomAccessIterator last,
const T& value, Compare comp, Distance*,
random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle, left, right;
while (len > 0) {
half = len / 2;
middle = first + half;
if (comp(*middle, value)) {
first = middle + 1;
len = len - half - 1;
} else if (comp(value, *middle))
len = half;
else {
left = lower_bound(first, middle, value, comp);
right = upper_bound(++middle, first + len, value, comp);
return pair<RandomAccessIterator, RandomAccessIterator>(left,
right);
}
}
return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
}
template <class ForwardIterator, class T, class Compare>
inline pair<ForwardIterator, ForwardIterator>
equal_range(ForwardIterator first, ForwardIterator last, const T& value,
Compare comp) {
return __equal_range(first, last, value, comp, distance_type(first),
iterator_category(first));
}
template <class ForwardIterator, class T>
bool binary_search(ForwardIterator first, ForwardIterator last,
const T& value) {
ForwardIterator i = lower_bound(first, last, value);
return i != last && !(value < *i);
}
template <class ForwardIterator, class T, class Compare>
bool binary_search(ForwardIterator first, ForwardIterator last, const T& value,
Compare comp) {
ForwardIterator i = lower_bound(first, last, value, comp);
return i != last && !comp(value, *i);
}
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result) {
while (first1 != last1 && first2 != last2) {
if (*first2 < *first1) {
*result = *first2;
++first2;
}
else {
*result = *first1;
++first1;
}
++result;
}
return copy(first2, last2, copy(first1, last1, result));
}
template <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp) {
while (first1 != last1 && first2 != last2) {
if (comp(*first2, *first1)) {
*result = *first2;
++first2;
}
else {
*result = *first1;
++first1;
}
++result;
}
return copy(first2, last2, copy(first1, last1, result));
}
template <class BidirectionalIterator, class Distance>
void __merge_without_buffer(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last,
Distance len1, Distance len2) {
if (len1 == 0 || len2 == 0) return;
if (len1 + len2 == 2) {
if (*middle < *first) iter_swap(first, middle);
return;
}
BidirectionalIterator first_cut = first;
BidirectionalIterator second_cut = middle;
Distance len11 = 0;
Distance len22 = 0;
if (len1 > len2) {
len11 = len1 / 2;
advance(first_cut, len11);
second_cut = lower_bound(middle, last, *first_cut);
distance(middle, second_cut, len22);
} else {
len22 = len2 / 2;
advance(second_cut, len22);
first_cut = upper_bound(first, middle, *second_cut);
distance(first, first_cut, len11);
}
rotate(first_cut, middle, second_cut);
BidirectionalIterator new_middle = first_cut;
advance(new_middle, len22);
__merge_without_buffer(first, first_cut, new_middle, len11, len22);
__merge_without_buffer(new_middle, second_cut, last, len1 - len11,
len2 - len22);
}
template <class BidirectionalIterator, class Distance, class Compare>
void __merge_without_buffer(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last,
Distance len1, Distance len2, Compare comp) {
if (len1 == 0 || len2 == 0) return;
if (len1 + len2 == 2) {
if (comp(*middle, *first)) iter_swap(first, middle);
return;
}
BidirectionalIterator first_cut = first;
BidirectionalIterator second_cut = middle;
Distance len11 = 0;
Distance len22 = 0;
if (len1 > len2) {
len11 = len1 / 2;
advance(first_cut, len11);
second_cut = lower_bound(middle, last, *first_cut, comp);
distance(middle, second_cut, len22);
} else {
len22 = len2 / 2;
advance(second_cut, len22);
first_cut = upper_bound(first, middle, *second_cut, comp);
distance(first, first_cut, len11);
}
rotate(first_cut, middle, second_cut);
BidirectionalIterator new_middle = first_cut;
advance(new_middle, len22);
__merge_without_buffer(first, first_cut, new_middle, len11, len22, comp);
__merge_without_buffer(new_middle, second_cut, last, len1 - len11,
len2 - len22, comp);
}
template <class BidirectionalIterator1, class BidirectionalIterator2,
class Distance>
BidirectionalIterator1 __rotate_adaptive(BidirectionalIterator1 first,
BidirectionalIterator1 middle,
BidirectionalIterator1 last,
Distance len1, Distance len2,
BidirectionalIterator2 buffer,
Distance buffer_size) {
BidirectionalIterator2 buffer_end;
if (len1 > len2 && len2 <= buffer_size) {
buffer_end = copy(middle, last, buffer);
copy_backward(first, middle, last);
return copy(buffer, buffer_end, first);
} else if (len1 <= buffer_size) {
buffer_end = copy(first, middle, buffer);
copy(middle, last, first);
return copy_backward(buffer, buffer_end, last);
} else {
rotate(first, middle, last);
advance(first, len2);
return first;
}
}
template <class BidirectionalIterator1, class BidirectionalIterator2,
class BidirectionalIterator3>
BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
BidirectionalIterator1 last1,
BidirectionalIterator2 first2,
BidirectionalIterator2 last2,
BidirectionalIterator3 result) {
if (first1 == last1) return copy_backward(first2, last2, result);
if (first2 == last2) return copy_backward(first1, last1, result);
--last1;
--last2;
while (true) {
if (*last2 < *last1) {
*--result = *last1;
if (first1 == last1) return copy_backward(first2, ++last2, result);
--last1;
} else {
*--result = *last2;
if (first2 == last2) return copy_backward(first1, ++last1, result);
--last2;
}
}
}
template <class BidirectionalIterator1, class BidirectionalIterator2,
class BidirectionalIterator3, class Compare>
BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
BidirectionalIterator1 last1,
BidirectionalIterator2 first2,
BidirectionalIterator2 last2,
BidirectionalIterator3 result,
Compare comp) {
if (first1 == last1) return copy_backward(first2, last2, result);
if (first2 == last2) return copy_backward(first1, last1, result);
--last1;
--last2;
while (true) {
if (comp(*last2, *last1)) {
*--result = *last1;
if (first1 == last1) return copy_backward(first2, ++last2, result);
--last1;
} else {
*--result = *last2;
if (first2 == last2) return copy_backward(first1, ++last1, result);
--last2;
}
}
}
template <class BidirectionalIterator, class Distance, class Pointer>
void __merge_adaptive(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, Distance len1, Distance len2,
Pointer buffer, Distance buffer_size) {
if (len1 <= len2 && len1 <= buffer_size) {
Pointer end_buffer = copy(first, middle, buffer);
merge(buffer, end_buffer, middle, last, first);
} else if (len2 <= buffer_size) {
Pointer end_buffer = copy(middle, last, buffer);
__merge_backward(first, middle, buffer, end_buffer, last);
} else {
BidirectionalIterator first_cut = first;
BidirectionalIterator second_cut = middle;
Distance len11 = 0;
Distance len22 = 0;
if (len1 > len2) {
len11 = len1 / 2;
advance(first_cut, len11);
second_cut = lower_bound(middle, last, *first_cut);
distance(middle, second_cut, len22);
} else {
len22 = len2 / 2;
advance(second_cut, len22);
first_cut = upper_bound(first, middle, *second_cut);
distance(first, first_cut, len11);
}
BidirectionalIterator new_middle =
__rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
len22, buffer, buffer_size);
__merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
buffer_size);
__merge_adaptive(new_middle, second_cut, last, len1 - len11,
len2 - len22, buffer, buffer_size);
}
}
template <class BidirectionalIterator, class Distance, class Pointer,
class Compare>
void __merge_adaptive(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, Distance len1, Distance len2,
Pointer buffer, Distance buffer_size, Compare comp) {
if (len1 <= len2 && len1 <= buffer_size) {
Pointer end_buffer = copy(first, middle, buffer);
merge(buffer, end_buffer, middle, last, first, comp);
} else if (len2 <= buffer_size) {
Pointer end_buffer = copy(middle, last, buffer);
__merge_backward(first, middle, buffer, end_buffer, last, comp);
} else {
BidirectionalIterator first_cut = first;
BidirectionalIterator second_cut = middle;
Distance len11 = 0;
Distance len22 = 0;
if (len1 > len2) {
len11 = len1 / 2;
advance(first_cut, len11);
second_cut = lower_bound(middle, last, *first_cut, comp);
distance(middle, second_cut, len22);
} else {
len22 = len2 / 2;
advance(second_cut, len22);
first_cut = upper_bound(first, middle, *second_cut, comp);
distance(first, first_cut, len11);
}
BidirectionalIterator new_middle =
__rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
len22, buffer, buffer_size);
__merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
buffer_size, comp);
__merge_adaptive(new_middle, second_cut, last, len1 - len11,
len2 - len22, buffer, buffer_size, comp);
}
}
template <class BidirectionalIterator, class T, class Distance>
inline void __inplace_merge_aux(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, T*, Distance*) {
Distance len1 = 0;
distance(first, middle, len1);
Distance len2 = 0;
distance(middle, last, len2);
temporary_buffer<BidirectionalIterator, T> buf(first, last);
if (buf.begin() == 0)
__merge_without_buffer(first, middle, last, len1, len2);
else
__merge_adaptive(first, middle, last, len1, len2,
buf.begin(), Distance(buf.size()));
}
template <class BidirectionalIterator, class T, class Distance, class Compare>
inline void __inplace_merge_aux(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, T*, Distance*,
Compare comp) {
Distance len1 = 0;
distance(first, middle, len1);
Distance len2 = 0;
distance(middle, last, len2);
temporary_buffer<BidirectionalIterator, T> buf(first, last);
if (buf.begin() == 0)
__merge_without_buffer(first, middle, last, len1, len2, comp);
else
__merge_adaptive(first, middle, last, len1, len2,
buf.begin(), Distance(buf.size()),
comp);
}
template <class BidirectionalIterator>
inline void inplace_merge(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last) {
if (first == middle || middle == last) return;
__inplace_merge_aux(first, middle, last, value_type(first),
distance_type(first));
}
template <class BidirectionalIterator, class Compare>
inline void inplace_merge(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, Compare comp) {
if (first == middle || middle == last) return;
__inplace_merge_aux(first, middle, last, value_type(first),
distance_type(first), comp);
}
template <class InputIterator1, class InputIterator2>
bool includes(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2) {
while (first1 != last1 && first2 != last2)
if (*first2 < *first1)
return false;
else if(*first1 < *first2)
++first1;
else
++first1, ++first2;
return first2 == last2;
}
template <class InputIterator1, class InputIterator2, class Compare>
bool includes(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, Compare comp) {
while (first1 != last1 && first2 != last2)
if (comp(*first2, *first1))
return false;
else if(comp(*first1, *first2))
++first1;
else
++first1, ++first2;
return first2 == last2;
}
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result) {
while (first1 != last1 && first2 != last2) {
if (*first1 < *first2) {
*result = *first1;
++first1;
}
else if (*first2 < *first1) {
*result = *first2;
++first2;
}
else {
*result = *first1;
++first1;
++first2;
}
++result;
}
return copy(first2, last2, copy(first1, last1, result));
}
template <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp) {
while (first1 != last1 && first2 != last2) {
if (comp(*first1, *first2)) {
*result = *first1;
++first1;
}
else if (comp(*first2, *first1)) {
*result = *first2;
++first2;
}
else {
*result = *first1;
++first1;
++first2;
}
++result;
}
return copy(first2, last2, copy(first1, last1, result));
}
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result) {
while (first1 != last1 && first2 != last2)
if (*first1 < *first2)
++first1;
else if (*first2 < *first1)
++first2;
else {
*result = *first1;
++first1;
++first2;
++result;
}
return result;
}
template <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp) {
while (first1 != last1 && first2 != last2)
if (comp(*first1, *first2))
++first1;
else if (comp(*first2, *first1))
++first2;
else {
*result = *first1;
++first1;
++first2;
++result;
}
return result;
}
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result) {
while (first1 != last1 && first2 != last2)
if (*first1 < *first2) {
*result = *first1;
++first1;
++result;
}
else if (*first2 < *first1)
++first2;
else {
++first1;
++first2;
}
return copy(first1, last1, result);
}
template <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp) {
while (first1 != last1 && first2 != last2)
if (comp(*first1, *first2)) {
*result = *first1;
++first1;
++result;
}
else if (comp(*first2, *first1))
++first2;
else {
++first1;
++first2;
}
return copy(first1, last1, result);
}
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_symmetric_difference(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
InputIterator2 last2,
OutputIterator result) {
while (first1 != last1 && first2 != last2)
if (*first1 < *first2) {
*result = *first1;
++first1;
++result;
}
else if (*first2 < *first1) {
*result = *first2;
++first2;
++result;
}
else {
++first1;
++first2;
}
return copy(first2, last2, copy(first1, last1, result));
}
template <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
OutputIterator set_symmetric_difference(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
InputIterator2 last2,
OutputIterator result, Compare comp) {
while (first1 != last1 && first2 != last2)
if (comp(*first1, *first2)) {
*result = *first1;
++first1;
++result;
}
else if (comp(*first2, *first1)) {
*result = *first2;
++first2;
++result;
}
else {
++first1;
++first2;
}
return copy(first2, last2, copy(first1, last1, result));
}
template <class ForwardIterator>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last) {
if (first == last) return first;
ForwardIterator result = first;
while (++first != last)
if (*result < *first) result = first;
return result;
}
template <class ForwardIterator, class Compare>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last,
Compare comp) {
if (first == last) return first;
ForwardIterator result = first;
while (++first != last)
if (comp(*result, *first)) result = first;
return result;
}
template <class ForwardIterator>
ForwardIterator min_element(ForwardIterator first, ForwardIterator last) {
if (first == last) return first;
ForwardIterator result = first;
while (++first != last)
if (*first < *result) result = first;
return result;
}
template <class ForwardIterator, class Compare>
ForwardIterator min_element(ForwardIterator first, ForwardIterator last,
Compare comp) {
if (first == last) return first;
ForwardIterator result = first;
while (++first != last)
if (comp(*first, *result)) result = first;
return result;
}
template <class BidirectionalIterator>
bool next_permutation(BidirectionalIterator first,
BidirectionalIterator last) {
if (first == last) return false;
BidirectionalIterator i = first;
++i;
if (i == last) return false;
i = last;
--i;
for(;;) {
BidirectionalIterator ii = i;
--i;
if (*i < *ii) {
BidirectionalIterator j = last;
while (!(*i < *--j));
iter_swap(i, j);
reverse(ii, last);
return true;
}
if (i == first) {
reverse(first, last);
return false;
}
}
}
template <class BidirectionalIterator, class Compare>
bool next_permutation(BidirectionalIterator first, BidirectionalIterator last,
Compare comp) {
if (first == last) return false;
BidirectionalIterator i = first;
++i;
if (i == last) return false;
i = last;
--i;
for(;;) {
BidirectionalIterator ii = i;
--i;
if (comp(*i, *ii)) {
BidirectionalIterator j = last;
while (!comp(*i, *--j));
iter_swap(i, j);
reverse(ii, last);
return true;
}
if (i == first) {
reverse(first, last);
return false;
}
}
}
template <class BidirectionalIterator>
bool prev_permutation(BidirectionalIterator first,
BidirectionalIterator last) {
if (first == last) return false;
BidirectionalIterator i = first;
++i;
if (i == last) return false;
i = last;
--i;
for(;;) {
BidirectionalIterator ii = i;
--i;
if (*ii < *i) {
BidirectionalIterator j = last;
while (!(*--j < *i));
iter_swap(i, j);
reverse(ii, last);
return true;
}
if (i == first) {
reverse(first, last);
return false;
}
}
}
template <class BidirectionalIterator, class Compare>
bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last,
Compare comp) {
if (first == last) return false;
BidirectionalIterator i = first;
++i;
if (i == last) return false;
i = last;
--i;
for(;;) {
BidirectionalIterator ii = i;
--i;
if (comp(*ii, *i)) {
BidirectionalIterator j = last;
while (!comp(*--j, *i));
iter_swap(i, j);
reverse(ii, last);
return true;
}
if (i == first) {
reverse(first, last);
return false;
}
}
}
template <class InputIterator, class T>
T accumulate(InputIterator first, InputIterator last, T init) {
for ( ; first != last; ++first)
init = init + *first;
return init;
}
template <class InputIterator, class T, class BinaryOperation>
T accumulate(InputIterator first, InputIterator last, T init,
BinaryOperation binary_op) {
for ( ; first != last; ++first)
init = binary_op(init, *first);
return init;
}
template <class InputIterator1, class InputIterator2, class T>
T inner_product(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, T init) {
for ( ; first1 != last1; ++first1, ++first2)
init = init + (*first1 * *first2);
return init;
}
template <class InputIterator1, class InputIterator2, class T,
class BinaryOperation1, class BinaryOperation2>
T inner_product(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, T init, BinaryOperation1 binary_op1,
BinaryOperation2 binary_op2) {
for ( ; first1 != last1; ++first1, ++first2)
init = binary_op1(init, binary_op2(*first1, *first2));
return init;
}
template <class InputIterator, class OutputIterator, class T>
OutputIterator __partial_sum(InputIterator first, InputIterator last,
OutputIterator result, T*) {
T value = *first;
while (++first != last) {
value = value + *first;
*++result = value;
}
return ++result;
}
template <class InputIterator, class OutputIterator>
OutputIterator partial_sum(InputIterator first, InputIterator last,
OutputIterator result) {
if (first == last) return result;
*result = *first;
return __partial_sum(first, last, result, value_type(first));
}
template <class InputIterator, class OutputIterator, class T,
class BinaryOperation>
OutputIterator __partial_sum(InputIterator first, InputIterator last,
OutputIterator result, T*,
BinaryOperation binary_op) {
T value = *first;
while (++first != last) {
value = binary_op(value, *first);
*++result = value;
}
return ++result;
}
template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator partial_sum(InputIterator first, InputIterator last,
OutputIterator result, BinaryOperation binary_op) {
if (first == last) return result;
*result = *first;
return __partial_sum(first, last, result, value_type(first), binary_op);
}
template <class InputIterator, class OutputIterator, class T>
OutputIterator __adjacent_difference(InputIterator first, InputIterator last,
OutputIterator result, T*) {
T value = *first;
while (++first != last) {
T tmp = *first;
*++result = tmp - value;
value = tmp;
}
return ++result;
}
template <class InputIterator, class OutputIterator>
OutputIterator adjacent_difference(InputIterator first, InputIterator last,
OutputIterator result) {
if (first == last) return result;
*result = *first;
return __adjacent_difference(first, last, result, value_type(first));
}
template <class InputIterator, class OutputIterator, class T,
class BinaryOperation>
OutputIterator __adjacent_difference(InputIterator first, InputIterator last,
OutputIterator result, T*,
BinaryOperation binary_op) {
T value = *first;
while (++first != last) {
T tmp = *first;
*++result = binary_op(tmp, value);
value = tmp;
}
return ++result;
}
template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator adjacent_difference(InputIterator first, InputIterator last,
OutputIterator result,
BinaryOperation binary_op) {
if (first == last) return result;
*result = *first;
return __adjacent_difference(first, last, result, value_type(first),
binary_op);
}
template <class InputIterator, class ForwardIterator>
InputIterator find_first_of(InputIterator first1, InputIterator last1,
ForwardIterator first2, ForwardIterator last2)
{
for ( ; first1 != last1; ++first1)
for (ForwardIterator iter = first2; iter != last2; ++iter)
if (*first1 == *iter)
return first1;
return last1;
}
template <class InputIterator, class ForwardIterator, class BinaryPredicate>
InputIterator find_first_of(InputIterator first1, InputIterator last1,
ForwardIterator first2, ForwardIterator last2,
BinaryPredicate comp)
{
for ( ; first1 != last1; ++first1)
for (ForwardIterator iter = first2; iter != last2; ++iter)
if (comp(*first1, *iter))
return first1;
return last1;
}
template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
forward_iterator_tag, forward_iterator_tag)
{
if (first2 == last2)
return last1;
else {
ForwardIterator1 result = last1;
while (1) {
ForwardIterator1 new_result = search(first1, last1, first2, last2);
if (new_result == last1)
return result;
else {
result = new_result;
first1 = new_result;
++first1;
}
}
}
}
template <class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate>
ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
forward_iterator_tag, forward_iterator_tag,
BinaryPredicate comp)
{
if (first2 == last2)
return last1;
else {
ForwardIterator1 result = last1;
while (1) {
ForwardIterator1 new_result = search(first1, last1, first2, last2, comp);
if (new_result == last1)
return result;
else {
result = new_result;
first1 = new_result;
++first1;
}
}
}
}
template <class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator1
__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
BidirectionalIterator2 first2, BidirectionalIterator2 last2,
bidirectional_iterator_tag, bidirectional_iterator_tag)
{
typedef reverse_iterator<BidirectionalIterator1> reviter1;
typedef reverse_iterator<BidirectionalIterator2> reviter2;
reviter1 rlast1(first1);
reviter2 rlast2(first2);
reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2);
if (rresult == rlast1)
return last1;
else {
BidirectionalIterator1 result = rresult.base();
advance(result, -distance(first2, last2));
return result;
}
}
template <class BidirectionalIterator1, class BidirectionalIterator2,
class BinaryPredicate>
BidirectionalIterator1
__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
BidirectionalIterator2 first2, BidirectionalIterator2 last2,
bidirectional_iterator_tag, bidirectional_iterator_tag,
BinaryPredicate comp)
{
typedef reverse_iterator<BidirectionalIterator1> reviter1;
typedef reverse_iterator<BidirectionalIterator2> reviter2;
reviter1 rlast1(first1);
reviter2 rlast2(first2);
reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2,
comp);
if (rresult == rlast1)
return last1;
else {
BidirectionalIterator1 result = rresult.base();
advance(result, -distance(first2, last2));
return result;
}
}
template <class ForwardIterator, class BidirectionalIterator>
inline ForwardIterator
__find_end(ForwardIterator first1, ForwardIterator last1,
BidirectionalIterator first2, BidirectionalIterator last2,
forward_iterator_tag, bidirectional_iterator_tag)
{
return __find_end(first1, last1, first2, last2,
forward_iterator_tag(), forward_iterator_tag());
}
template <class BidirectionalIterator, class ForwardIterator>
inline BidirectionalIterator
__find_end(BidirectionalIterator first1, BidirectionalIterator last1,
ForwardIterator first2, ForwardIterator last2,
bidirectional_iterator_tag, forward_iterator_tag)
{
return __find_end(first1, last1, first2, last2,
forward_iterator_tag(), forward_iterator_tag());
}
template <class ForwardIterator, class BidirectionalIterator,
class BinaryPredicate>
inline ForwardIterator
__find_end(ForwardIterator first1, ForwardIterator last1,
BidirectionalIterator first2, BidirectionalIterator last2,
forward_iterator_tag, bidirectional_iterator_tag,
BinaryPredicate comp)
{
return __find_end(first1, last1, first2, last2,
forward_iterator_tag(), forward_iterator_tag(),
comp);
}
template <class BidirectionalIterator, class ForwardIterator,
class BinaryPredicate>
inline BidirectionalIterator
__find_end(BidirectionalIterator first1, BidirectionalIterator last1,
ForwardIterator first2, ForwardIterator last2,
bidirectional_iterator_tag, forward_iterator_tag,
BinaryPredicate comp)
{
return __find_end(first1, last1, first2, last2,
forward_iterator_tag(), forward_iterator_tag(),
comp);
}
template <class ForwardIterator1, class ForwardIterator2>
inline ForwardIterator1
find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2)
{
return __find_end(first1, last1, first2, last2,
iterator_traits<ForwardIterator1>::iterator_category(),
iterator_traits<ForwardIterator2>::iterator_category());
}
template <class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate>
inline ForwardIterator1
find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate comp)
{
return __find_end(first1, last1, first2, last2,
iterator_traits<ForwardIterator1>::iterator_category(),
iterator_traits<ForwardIterator2>::iterator_category(),
comp);
}
template <class T, class Integer, class MonoidOperation>
T power(T x, Integer n, MonoidOperation op) {
if (n == 0)
return identity_element(op);
else {
while ((n & 1) == 0) {
n >>= 1;
x = op(x, x);
}
T result = x;
n >>= 1;
while (n != 0) {
x = op(x, x);
if ((n & 1) != 0)
result = op(result, x);
n >>= 1;
}
return result;
}
}
template <class T, class Integer>
inline T power(T x, Integer n) {
return power(x, n, multiplies<T>());
}
template <class ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T value) {
while (first != last) *first++ = value++;
}
template <class RandomAccessIterator, class Distance>
bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
Distance*)
{
const Distance n = last - first;
Distance parent = 0;
for (Distance child = 1; child < n; ++child) {
if (first[parent] < first[child])
return false;
if (child % 2 == 0)
++parent;
}
return true;
}
template <class RandomAccessIterator>
inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last)
{
return __is_heap(first, last, distance_type(first));
}
template <class RandomAccessIterator, class Distance, class StrictWeakOrdering>
bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
StrictWeakOrdering comp,
Distance*)
{
const Distance n = last - first;
Distance parent = 0;
for (Distance child = 1; child < n; ++child) {
if (comp(first[parent], first[child]))
return false;
if (child % 2 == 0)
++parent;
}
return true;
}
template <class RandomAccessIterator, class StrictWeakOrdering>
inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last,
StrictWeakOrdering comp)
{
return __is_heap(first, last, comp, distance_type(first));
}
template <class ForwardIterator>
bool is_sorted(ForwardIterator first, ForwardIterator last)
{
if (first == last)
return true;
ForwardIterator next = first;
for (++next; next != last; first = next, ++next) {
if (*next < *first)
return false;
}
return true;
}
template <class ForwardIterator, class StrictWeakOrdering>
bool is_sorted(ForwardIterator first, ForwardIterator last,
StrictWeakOrdering comp)
{
if (first == last)
return true;
ForwardIterator next = first;
for (++next; next != last; first = next, ++next) {
if (comp(*next, *first))
return false;
}
return true;
}
extern "C" {
extern void __eprintf (const char *, const char *, unsigned, const char *)
__attribute__ ((noreturn));
}
template <int inst>
class __malloc_alloc_template {
private:
static void *oom_malloc(size_t);
static void *oom_realloc(void *, size_t);
static void (* __malloc_alloc_oom_handler)();
public:
static void * allocate(size_t n)
{
void *result = malloc(n);
if (0 == result) result = oom_malloc(n);
return result;
}
static void deallocate(void *p, size_t )
{
free(p);
}
static void * reallocate(void *p, size_t , size_t new_sz)
{
void * result = realloc(p, new_sz);
if (0 == result) result = oom_realloc(p, new_sz);
return result;
}
static void (* set_malloc_handler(void (*f)()))()
{
void (* old)() = __malloc_alloc_oom_handler;
__malloc_alloc_oom_handler = f;
return(old);
}
};
template <int inst>
void (* __malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0;
template <int inst>
void * __malloc_alloc_template<inst>::oom_malloc(size_t n)
{
void (* my_malloc_handler)();
void *result;
for (;;) {
my_malloc_handler = __malloc_alloc_oom_handler;
if (0 == my_malloc_handler) { cerr << "out of memory" << endl; exit(1) ; }
(*my_malloc_handler)();
result = malloc(n);
if (result) return(result);
}
}
template <int inst>
void * __malloc_alloc_template<inst>::oom_realloc(void *p, size_t n)
{
void (* my_malloc_handler)();
void *result;
for (;;) {
my_malloc_handler = __malloc_alloc_oom_handler;
if (0 == my_malloc_handler) { cerr << "out of memory" << endl; exit(1) ; }
(*my_malloc_handler)();
result = realloc(p, n);
if (result) return(result);
}
}
typedef __malloc_alloc_template<0> malloc_alloc;
template<class T, class Alloc>
class simple_alloc {
public:
static T *allocate(size_t n)
{ return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); }
static T *allocate(void)
{ return (T*) Alloc::allocate(sizeof (T)); }
static void deallocate(T *p, size_t n)
{ if (0 != n) Alloc::deallocate(p, n * sizeof (T)); }
static void deallocate(T *p)
{ Alloc::deallocate(p, sizeof (T)); }
};
template <class Alloc>
class debug_alloc {
private:
enum {extra = 8};
public:
static void * allocate(size_t n)
{
char *result = (char *)Alloc::allocate(n + extra);
*(size_t *)result = n;
return result + extra;
}
static void deallocate(void *p, size_t n)
{
char * real_p = (char *)p - extra;
((void) (( *(size_t *)real_p == n ) ? 0 : (__eprintf ("%s:%u: failed assertion `%s'\n", "/u/home/hymie/egcs/include/g++/alloc.h" , 250 , "*(size_t *)real_p == n" ), 0) )) ;
Alloc::deallocate(real_p, n + extra);
}
static void * reallocate(void *p, size_t old_sz, size_t new_sz)
{
char * real_p = (char *)p - extra;
((void) (( *(size_t *)real_p == old_sz ) ? 0 : (__eprintf ("%s:%u: failed assertion `%s'\n", "/u/home/hymie/egcs/include/g++/alloc.h" , 257 , "*(size_t *)real_p == old_sz" ), 0) )) ;
char * result = (char *)
Alloc::reallocate(real_p, old_sz + extra, new_sz + extra);
*(size_t *)result = new_sz;
return result + extra;
}
};
template <bool threads, int inst>
class __default_alloc_template {
private:
enum {__ALIGN = 8};
enum {__MAX_BYTES = 128};
enum {__NFREELISTS = __MAX_BYTES/__ALIGN};
static size_t ROUND_UP(size_t bytes) {
return (((bytes) + __ALIGN-1) & ~(__ALIGN - 1));
}
private :
union obj {
union obj * free_list_link;
char client_data[1];
};
private:
static obj * free_list[__NFREELISTS];
static size_t FREELIST_INDEX(size_t bytes) {
return (((bytes) + __ALIGN-1)/__ALIGN - 1);
}
static void *refill(size_t n);
static char *chunk_alloc(size_t size, int &nobjs);
static char *start_free;
static char *end_free;
static size_t heap_size;
class lock {
public:
lock() { ; }
~lock() { ; }
};
friend class lock;
public:
static void * allocate(size_t n)
{
obj * * my_free_list;
obj * result;
if (n > (size_t) __MAX_BYTES) {
return(malloc_alloc::allocate(n));
}
my_free_list = free_list + FREELIST_INDEX(n);
result = *my_free_list;
if (result == 0) {
void *r = refill(ROUND_UP(n));
return r;
}
*my_free_list = result -> free_list_link;
return (result);
};
static void deallocate(void *p, size_t n)
{
obj *q = (obj *)p;
obj * * my_free_list;
if (n > (size_t) __MAX_BYTES) {
malloc_alloc::deallocate(p, n);
return;
}
my_free_list = free_list + FREELIST_INDEX(n);
q -> free_list_link = *my_free_list;
*my_free_list = q;
}
static void * reallocate(void *p, size_t old_sz, size_t new_sz);
} ;
typedef __default_alloc_template< false , 0> alloc;
typedef __default_alloc_template<false, 0> single_client_alloc;
template <bool threads, int inst>
char*
__default_alloc_template<threads, inst>::chunk_alloc(size_t size, int& nobjs)
{
char * result;
size_t total_bytes = size * nobjs;
size_t bytes_left = end_free - start_free;
if (bytes_left >= total_bytes) {
result = start_free;
start_free += total_bytes;
return(result);
} else if (bytes_left >= size) {
nobjs = bytes_left/size;
total_bytes = size * nobjs;
result = start_free;
start_free += total_bytes;
return(result);
} else {
size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
if (bytes_left > 0) {
obj * * my_free_list =
free_list + FREELIST_INDEX(bytes_left);
((obj *)start_free) -> free_list_link = *my_free_list;
*my_free_list = (obj *)start_free;
}
start_free = (char *)malloc(bytes_to_get);
if (0 == start_free) {
int i;
obj * * my_free_list, *p;
for (i = size; i <= __MAX_BYTES; i += __ALIGN) {
my_free_list = free_list + FREELIST_INDEX(i);
p = *my_free_list;
if (0 != p) {
*my_free_list = p -> free_list_link;
start_free = (char *)p;
end_free = start_free + i;
return(chunk_alloc(size, nobjs));
}
}
end_free = 0;
start_free = (char *)malloc_alloc::allocate(bytes_to_get);
}
heap_size += bytes_to_get;
end_free = start_free + bytes_to_get;
return(chunk_alloc(size, nobjs));
}
}
template <bool threads, int inst>
void* __default_alloc_template<threads, inst>::refill(size_t n)
{
int nobjs = 20;
char * chunk = chunk_alloc(n, nobjs);
obj * * my_free_list;
obj * result;
obj * current_obj, * next_obj;
int i;
if (1 == nobjs) return(chunk);
my_free_list = free_list + FREELIST_INDEX(n);
result = (obj *)chunk;
*my_free_list = next_obj = (obj *)(chunk + n);
for (i = 1; ; i++) {
current_obj = next_obj;
next_obj = (obj *)((char *)next_obj + n);
if (nobjs - 1 == i) {
current_obj -> free_list_link = 0;
break;
} else {
current_obj -> free_list_link = next_obj;
}
}
return(result);
}
template <bool threads, int inst>
void*
__default_alloc_template<threads, inst>::reallocate(void *p,
size_t old_sz,
size_t new_sz)
{
void * result;
size_t copy_sz;
if (old_sz > (size_t) __MAX_BYTES && new_sz > (size_t) __MAX_BYTES) {
return(realloc(p, new_sz));
}
if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p);
result = allocate(new_sz);
copy_sz = new_sz > old_sz? old_sz : new_sz;
memcpy(result, p, copy_sz);
deallocate(p, old_sz);
return(result);
}
template <bool threads, int inst>
char *__default_alloc_template<threads, inst>::start_free = 0;
template <bool threads, int inst>
char *__default_alloc_template<threads, inst>::end_free = 0;
template <bool threads, int inst>
size_t __default_alloc_template<threads, inst>::heap_size = 0;
template <bool threads, int inst>
__default_alloc_template<threads, inst>::obj *
__default_alloc_template<threads, inst> ::free_list[
__default_alloc_template<threads, inst>::__NFREELISTS
] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
inline size_t __deque_buf_size(size_t n, size_t sz)
{
return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1));
}
template <class T, class Ref, class Ptr, size_t BufSiz>
struct __deque_iterator {
typedef __deque_iterator<T, T&, T*, BufSiz> iterator;
typedef __deque_iterator<T, const T&, const T*, BufSiz> const_iterator;
static size_t buffer_size() {return __deque_buf_size(BufSiz, sizeof(T)); }
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T** map_pointer;
typedef __deque_iterator self;
T* cur;
T* first;
T* last;
map_pointer node;
__deque_iterator(T* x, map_pointer y)
: cur(x), first(*y), last(*y + buffer_size()), node(y) {}
__deque_iterator() : cur(0), first(0), last(0), node(0) {}
__deque_iterator(const iterator& x)
: cur(x.cur), first(x.first), last(x.last), node(x.node) {}
reference operator*() const { return *cur; }
pointer operator->() const { return &(operator*()); }
difference_type operator-(const self& x) const {
return buffer_size() * (node - x.node - 1) +
(cur - first) + (x.last - x.cur);
}
self& operator++() {
++cur;
if (cur == last) {
set_node(node + 1);
cur = first;
}
return *this;
}
self operator++(int) {
self tmp = *this;
++*this;
return tmp;
}
self& operator--() {
if (cur == first) {
set_node(node - 1);
cur = last;
}
--cur;
return *this;
}
self operator--(int) {
self tmp = *this;
--*this;
return tmp;
}
self& operator+=(difference_type n) {
difference_type offset = n + (cur - first);
if (offset >= 0 && offset < buffer_size())
cur += n;
else {
difference_type node_offset =
offset > 0 ? offset / buffer_size()
: -difference_type((-offset - 1) / buffer_size()) - 1;
set_node(node + node_offset);
cur = first + (offset - node_offset * buffer_size());
}
return *this;
}
self operator+(difference_type n) const {
self tmp = *this;
return tmp += n;
}
self& operator-=(difference_type n) { return *this += -n; }
self operator-(difference_type n) const {
self tmp = *this;
return tmp -= n;
}
reference operator[](difference_type n) const { return *(*this + n); }
bool operator==(const self& x) const { return cur == x.cur; }
bool operator!=(const self& x) const { return !(*this == x); }
bool operator<(const self& x) const {
return (node == x.node) ? (cur < x.cur) : (node < x.node);
}
void set_node(map_pointer new_node) {
node = new_node;
first = *new_node;
last = first + buffer_size();
}
};
template <class T, class Alloc = alloc, size_t BufSiz = 0>
class deque {
public:
typedef T value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
public:
typedef __deque_iterator<T, T&, T*, BufSiz> iterator;
typedef __deque_iterator<T, const T&, const T&, BufSiz> const_iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
protected:
typedef pointer* map_pointer;
typedef simple_alloc<value_type, Alloc> data_allocator;
typedef simple_alloc<pointer, Alloc> map_allocator;
static size_type buffer_size() {
return __deque_buf_size(BufSiz, sizeof(value_type));
}
static size_type initial_map_size() { return 8; }
protected:
iterator start;
iterator finish;
map_pointer map;
size_type map_size;
public:
iterator begin() { return start; }
iterator end() { return finish; }
const_iterator begin() const { return start; }
const_iterator end() const { return finish; }
reverse_iterator rbegin() { return reverse_iterator(finish); }
reverse_iterator rend() { return reverse_iterator(start); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(finish);
}
const_reverse_iterator rend() const {
return const_reverse_iterator(start);
}
reference operator[](size_type n) { return start[n]; }
const_reference operator[](size_type n) const { return start[n]; }
reference front() { return *start; }
reference back() {
iterator tmp = finish;
--tmp;
return *tmp;
}
const_reference front() const { return *start; }
const_reference back() const {
const_iterator tmp = finish;
--tmp;
return *tmp;
}
size_type size() const { return finish - start;; }
size_type max_size() const { return size_type(-1); }
bool empty() const { return finish == start; }
public:
deque()
: start(), finish(), map(0), map_size(0)
{
create_map_and_nodes(0);
}
deque(const deque& x)
: start(), finish(), map(0), map_size(0)
{
create_map_and_nodes(x.size());
try {
uninitialized_copy(x.begin(), x.end(), start);
}
catch(...) {
destroy_map_and_nodes();
throw;
}
}
deque(size_type n, const value_type& value)
: start(), finish(), map(0), map_size(0) {
fill_initialize(n, value);
}
deque(int n, const value_type& value)
: start(), finish(), map(0), map_size(0) {
fill_initialize(n, value);
}
deque(long n, const value_type& value)
: start(), finish(), map(0), map_size(0) {
fill_initialize(n, value);
}
explicit deque(size_type n)
: start(), finish(), map(0), map_size(0) {
fill_initialize(n, value_type());
}
template <class InputIterator>
deque(InputIterator first, InputIterator last)
: start(), finish(), map(0), map_size(0)
{
range_initialize(first, last, iterator_category(first));
}
~deque() {
destroy(start, finish);
destroy_map_and_nodes();
}
deque& operator= (const deque& x) {
const size_type len = size();
if (&x != this) {
if (len >= x.size())
erase(copy(x.begin(), x.end(), start), finish);
else {
const_iterator mid = x.begin() + len;
copy(x.begin(), mid, start);
insert(finish, mid, x.end());
}
}
return *this;
}
void swap(deque& x) {
::swap(start, x.start);
::swap(finish, x.finish);
::swap(map, x.map);
::swap(map_size, x.map_size);
}
public:
void push_back(const value_type& t) {
if (finish.cur != finish.last - 1) {
construct(finish.cur, t);
++finish.cur;
}
else
push_back_aux(t);
}
void push_front(const value_type& t) {
if (start.cur != start.first) {
construct(start.cur - 1, t);
--start.cur;
}
else
push_front_aux(t);
}
void pop_back() {
if (finish.cur != finish.first) {
--finish.cur;
destroy(finish.cur);
}
else
pop_back_aux();
}
void pop_front() {
if (start.cur != start.last - 1) {
destroy(start.cur);
++start.cur;
}
else
pop_front_aux();
}
public:
iterator insert(iterator position, const value_type& x) {
if (position.cur == start.cur) {
push_front(x);
return start;
}
else if (position.cur == finish.cur) {
push_back(x);
iterator tmp = finish;
--tmp;
return tmp;
}
else {
return insert_aux(position, x);
}
}
iterator insert(iterator position) { return insert(position, value_type()); }
void insert(iterator pos, size_type n, const value_type& x);
void insert(iterator pos, int n, const value_type& x) {
insert(pos, (size_type) n, x);
}
void insert(iterator pos, long n, const value_type& x) {
insert(pos, (size_type) n, x);
}
template <class InputIterator>
void insert(iterator pos, InputIterator first, InputIterator last) {
insert(pos, first, last, iterator_category(first));
}
void resize(size_type new_size, const value_type& x) {
const size_type len = size();
if (new_size < len)
erase(start + new_size, finish);
else
insert(finish, new_size - len, x);
}
void resize(size_type new_size) { resize(new_size, value_type()); }
public:
void erase(iterator pos) {
iterator next = pos;
++next;
if (pos - start < size() / 2) {
copy_backward(start, pos, next);
pop_front();
}
else {
copy(next, finish, pos);
pop_back();
}
}
void erase(iterator first, iterator last);
void clear();
protected:
void create_map_and_nodes(size_type num_elements);
void destroy_map_and_nodes();
void fill_initialize(size_type n, const value_type& value);
template <class InputIterator>
void range_initialize(InputIterator first, InputIterator last,
input_iterator_tag);
template <class ForwardIterator>
void range_initialize(ForwardIterator first, ForwardIterator last,
forward_iterator_tag);
protected:
void push_back_aux(const value_type& t);
void push_front_aux(const value_type& t);
void pop_back_aux();
void pop_front_aux();
protected:
template <class InputIterator>
void insert(iterator pos, InputIterator first, InputIterator last,
input_iterator_tag);
template <class ForwardIterator>
void insert(iterator pos, ForwardIterator first, ForwardIterator last,
forward_iterator_tag);
iterator insert_aux(iterator pos, const value_type& x);
void insert_aux(iterator pos, size_type n, const value_type& x);
template <class ForwardIterator>
void insert_aux(iterator pos, ForwardIterator first, ForwardIterator last,
size_type n);
iterator reserve_elements_at_front(size_type n) {
size_type vacancies = start.cur - start.first;
if (n > vacancies)
new_elements_at_front(n - vacancies);
return start - n;
}
iterator reserve_elements_at_back(size_type n) {
size_type vacancies = (finish.last - finish.cur) - 1;
if (n > vacancies)
new_elements_at_back(n - vacancies);
return finish + n;
}
void new_elements_at_front(size_type new_elements);
void new_elements_at_back(size_type new_elements);
void destroy_nodes_at_front(iterator before_start);
void destroy_nodes_at_back(iterator after_finish);
protected:
void reserve_map_at_back (size_type nodes_to_add = 1) {
if (nodes_to_add + 1 > map_size - (finish.node - map))
reallocate_map(nodes_to_add, false);
}
void reserve_map_at_front (size_type nodes_to_add = 1) {
if (nodes_to_add > start.node - map)
reallocate_map(nodes_to_add, true);
}
void reallocate_map(size_type nodes_to_add, bool add_at_front);
pointer allocate_node() { return data_allocator::allocate(buffer_size()); }
void deallocate_node(pointer n) {
data_allocator::deallocate(n, buffer_size());
}
};
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert(iterator pos,
size_type n, const value_type& x) {
if (pos.cur == start.cur) {
iterator new_start = reserve_elements_at_front(n);
uninitialized_fill(new_start, start, x);
start = new_start;
}
else if (pos.cur == finish.cur) {
iterator new_finish = reserve_elements_at_back(n);
uninitialized_fill(finish, new_finish, x);
finish = new_finish;
}
else
insert_aux(pos, n, x);
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::erase(iterator first, iterator last) {
if (first == start && last == finish)
clear();
else {
difference_type n = last - first;
difference_type elems_before = first - start;
if (elems_before < (size() - n) / 2) {
copy_backward(start, first, last);
iterator new_start = start + n;
destroy(start, new_start);
for (map_pointer cur = start.node; cur < new_start.node; ++cur)
data_allocator::deallocate(*cur, buffer_size());
start = new_start;
}
else {
copy(last, finish, first);
iterator new_finish = finish - n;
destroy(new_finish, finish);
for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur)
data_allocator::deallocate(*cur, buffer_size());
finish = new_finish;
}
}
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::clear() {
for (map_pointer node = start.node + 1; node < finish.node; ++node) {
destroy(*node, *node + buffer_size());
data_allocator::deallocate(*node, buffer_size());
}
if (start.node != finish.node) {
destroy(start.cur, start.last);
destroy(finish.first, finish.cur);
data_allocator::deallocate(finish.first, buffer_size());
}
else
destroy(start.cur, finish.cur);
finish = start;
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::create_map_and_nodes(size_type num_elements) {
size_type num_nodes = num_elements / buffer_size() + 1;
map_size = max(initial_map_size(), num_nodes + 2);
map = map_allocator::allocate(map_size);
map_pointer nstart = map + (map_size - num_nodes) / 2;
map_pointer nfinish = nstart + num_nodes - 1;
map_pointer cur;
try {
for (cur = nstart; cur <= nfinish; ++cur)
*cur = allocate_node();
}
catch(...) {
for (map_pointer n = nstart; n < cur; ++n)
deallocate_node(*n);
map_allocator::deallocate(map, map_size);
throw;
}
start.set_node(nstart);
finish.set_node(nfinish);
start.cur = start.first;
finish.cur = finish.first + num_elements % buffer_size();
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::destroy_map_and_nodes() {
for (map_pointer cur = start.node; cur <= finish.node; ++cur)
deallocate_node(*cur);
map_allocator::deallocate(map, map_size);
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::fill_initialize(size_type n,
const value_type& value) {
create_map_and_nodes(n);
map_pointer cur;
try {
for (cur = start.node; cur < finish.node; ++cur)
uninitialized_fill(*cur, *cur + buffer_size(), value);
uninitialized_fill(finish.first, finish.cur, value);
}
catch(...) {
for (map_pointer n = start.node; n < cur; ++n)
destroy(*n, *n + buffer_size());
destroy_map_and_nodes();
throw;
}
}
template <class T, class Alloc, size_t BufSize>
template <class InputIterator>
void deque<T, Alloc, BufSize>::range_initialize(InputIterator first,
InputIterator last,
input_iterator_tag) {
create_map_and_nodes(0);
for ( ; first != last; ++first)
push_back(*first);
}
template <class T, class Alloc, size_t BufSize>
template <class ForwardIterator>
void deque<T, Alloc, BufSize>::range_initialize(ForwardIterator first,
ForwardIterator last,
forward_iterator_tag) {
size_type n = 0;
distance(first, last, n);
create_map_and_nodes(n);
try {
uninitialized_copy(first, last, start);
}
catch(...) {
destroy_map_and_nodes();
throw;
}
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::push_back_aux(const value_type& t) {
value_type t_copy = t;
reserve_map_at_back();
*(finish.node + 1) = allocate_node();
try {
construct(finish.cur, t_copy);
finish.set_node(finish.node + 1);
finish.cur = finish.first;
}
catch(...) {
deallocate_node(*(finish.node + 1));
throw;
}
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::push_front_aux(const value_type& t) {
value_type t_copy = t;
reserve_map_at_front();
*(start.node - 1) = allocate_node();
try {
start.set_node(start.node - 1);
start.cur = start.last - 1;
construct(start.cur, t_copy);
}
catch(...) {
start.set_node(start.node + 1);
start.cur = start.first;
deallocate_node(*(start.node - 1));
throw;
}
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>:: pop_back_aux() {
deallocate_node(finish.first);
finish.set_node(finish.node - 1);
finish.cur = finish.last - 1;
destroy(finish.cur);
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::pop_front_aux() {
destroy(start.cur);
deallocate_node(start.first);
start.set_node(start.node + 1);
start.cur = start.first;
}
template <class T, class Alloc, size_t BufSize>
template <class InputIterator>
void deque<T, Alloc, BufSize>::insert(iterator pos,
InputIterator first, InputIterator last,
input_iterator_tag) {
copy(first, last, inserter(*this, pos));
}
template <class T, class Alloc, size_t BufSize>
template <class ForwardIterator>
void deque<T, Alloc, BufSize>::insert(iterator pos,
ForwardIterator first,
ForwardIterator last,
forward_iterator_tag) {
size_type n = 0;
distance(first, last, n);
if (pos.cur == start.cur) {
iterator new_start = reserve_elements_at_front(n);
try {
uninitialized_copy(first, last, new_start);
start = new_start;
}
catch(...) {
destroy_nodes_at_front(new_start);
throw;
}
}
else if (pos.cur == finish.cur) {
iterator new_finish = reserve_elements_at_back(n);
try {
uninitialized_copy(first, last, finish);
finish = new_finish;
}
catch(...) {
destroy_nodes_at_back(new_finish);
throw;
}
}
else
insert_aux(pos, first, last, n);
}
template <class T, class Alloc, size_t BufSize>
deque<T, Alloc, BufSize>::iterator
deque<T, Alloc, BufSize>::insert_aux(iterator pos, const value_type& x) {
difference_type index = pos - start;
value_type x_copy = x;
if (index < size() / 2) {
push_front(front());
iterator front1 = start;
++front1;
iterator front2 = front1;
++front2;
pos = start + index;
iterator pos1 = pos;
++pos1;
copy(front2, pos1, front1);
}
else {
push_back(back());
iterator back1 = finish;
--back1;
iterator back2 = back1;
--back2;
pos = start + index;
copy_backward(pos, back2, back1);
}
*pos = x_copy;
return pos;
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
size_type n, const value_type& x) {
const difference_type elems_before = pos - start;
size_type length = size();
value_type x_copy = x;
if (elems_before < length / 2) {
iterator new_start = reserve_elements_at_front(n);
iterator old_start = start;
pos = start + elems_before;
try {
if (elems_before >= n) {
iterator start_n = start + n;
uninitialized_copy(start, start_n, new_start);
start = new_start;
copy(start_n, pos, old_start);
fill(pos - n, pos, x_copy);
}
else {
__uninitialized_copy_fill(start, pos, new_start, start, x_copy);
start = new_start;
fill(old_start, pos, x_copy);
}
}
catch(...) {
destroy_nodes_at_front(new_start);
throw;
}
}
else {
iterator new_finish = reserve_elements_at_back(n);
iterator old_finish = finish;
const difference_type elems_after = length - elems_before;
pos = finish - elems_after;
try {
if (elems_after > n) {
iterator finish_n = finish - n;
uninitialized_copy(finish_n, finish, finish);
finish = new_finish;
copy_backward(pos, finish_n, old_finish);
fill(pos, pos + n, x_copy);
}
else {
__uninitialized_fill_copy(finish, pos + n, x_copy, pos, finish);
finish = new_finish;
fill(pos, old_finish, x_copy);
}
}
catch(...) {
destroy_nodes_at_back(new_finish);
throw;
}
}
}
template <class T, class Alloc, size_t BufSize>
template <class ForwardIterator>
void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
ForwardIterator first,
ForwardIterator last,
size_type n)
{
const difference_type elems_before = pos - start;
size_type length = size();
if (elems_before < length / 2) {
iterator new_start = reserve_elements_at_front(n);
iterator old_start = start;
pos = start + elems_before;
try {
if (elems_before >= n) {
iterator start_n = start + n;
uninitialized_copy(start, start_n, new_start);
start = new_start;
copy(start_n, pos, old_start);
copy(first, last, pos - n);
}
else {
ForwardIterator mid = first;
advance(mid, n - elems_before);
__uninitialized_copy_copy(start, pos, first, mid, new_start);
start = new_start;
copy(mid, last, old_start);
}
}
catch(...) {
destroy_nodes_at_front(new_start);
throw;
}
}
else {
iterator new_finish = reserve_elements_at_back(n);
iterator old_finish = finish;
const difference_type elems_after = length - elems_before;
pos = finish - elems_after;
try {
if (elems_after > n) {
iterator finish_n = finish - n;
uninitialized_copy(finish_n, finish, finish);
finish = new_finish;
copy_backward(pos, finish_n, old_finish);
copy(first, last, pos);
}
else {
ForwardIterator mid = first;
advance(mid, elems_after);
__uninitialized_copy_copy(mid, last, pos, finish, finish);
finish = new_finish;
copy(first, mid, pos);
}
}
catch(...) {
destroy_nodes_at_back(new_finish);
throw;
}
}
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::new_elements_at_front(size_type new_elements) {
size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();
reserve_map_at_front(new_nodes);
size_type i;
try {
for (i = 1; i <= new_nodes; ++i)
*(start.node - i) = allocate_node();
}
catch(...) {
for (size_type j = 1; j < i; ++j)
deallocate_node(*(start.node - j));
throw;
}
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::new_elements_at_back(size_type new_elements) {
size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();
reserve_map_at_back(new_nodes);
size_type i;
try {
for (i = 1; i <= new_nodes; ++i)
*(finish.node + i) = allocate_node();
}
catch(...) {
for (size_type j = 1; j < i; ++j)
deallocate_node(*(finish.node + j));
throw;
}
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::destroy_nodes_at_front(iterator before_start) {
for (map_pointer n = before_start.node; n < start.node; ++n)
deallocate_node(*n);
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::destroy_nodes_at_back(iterator after_finish) {
for (map_pointer n = after_finish.node; n > finish.node; --n)
deallocate_node(*n);
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::reallocate_map(size_type nodes_to_add,
bool add_at_front) {
size_type old_num_nodes = finish.node - start.node + 1;
size_type new_num_nodes = old_num_nodes + nodes_to_add;
map_pointer new_nstart;
if (map_size > 2 * new_num_nodes) {
new_nstart = map + (map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0);
if (new_nstart < start.node)
copy(start.node, finish.node + 1, new_nstart);
else
copy_backward(start.node, finish.node + 1, new_nstart + old_num_nodes);
}
else {
size_type new_map_size = map_size + max(map_size, nodes_to_add) + 2;
map_pointer new_map = map_allocator::allocate(new_map_size);
new_nstart = new_map + (new_map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0);
copy(start.node, finish.node + 1, new_nstart);
map_allocator::deallocate(map, map_size);
map = new_map;
map_size = new_map_size;
}
start.set_node(new_nstart);
finish.set_node(new_nstart + old_num_nodes - 1);
}
template <class T, class Alloc, size_t BufSiz>
bool operator==(const deque<T, Alloc, BufSiz>& x,
const deque<T, Alloc, BufSiz>& y) {
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}
template <class T, class Alloc, size_t BufSiz>
bool operator<(const deque<T, Alloc, BufSiz>& x,
const deque<T, Alloc, BufSiz>& y) {
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
template <class T>
struct __list_node {
typedef void* void_pointer;
void_pointer next;
void_pointer prev;
T data;
};
template<class T, class Ref, class Ptr>
struct __list_iterator {
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
typedef __list_iterator<T, Ref, Ptr> self;
typedef bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef __list_node<T>* link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
link_type node;
__list_iterator(link_type x) : node(x) {}
__list_iterator() {}
__list_iterator(const iterator& x) : node(x.node) {}
bool operator==(const self& x) const { return node == x.node; }
bool operator!=(const self& x) const { return node != x.node; }
reference operator*() const { return (*node).data; }
pointer operator->() const { return &(operator*()); }
self& operator++() {
node = (link_type)((*node).next);
return *this;
}
self operator++(int) {
self tmp = *this;
++*this;
return tmp;
}
self& operator--() {
node = (link_type)((*node).prev);
return *this;
}
self operator--(int) {
self tmp = *this;
--*this;
return tmp;
}
};
template <class T, class Alloc = alloc>
class list {
protected:
typedef void* void_pointer;
typedef __list_node<T> list_node;
typedef simple_alloc<list_node, Alloc> list_node_allocator;
public:
typedef T value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef list_node* link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
public:
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
protected:
link_type get_node() { return list_node_allocator::allocate(); }
void put_node(link_type p) { list_node_allocator::deallocate(p); }
link_type create_node(const T& x) {
link_type p = get_node();
try {
construct(&p->data, x);
return p;
}
catch(...) {
put_node(p);
throw;
}
}
void destroy_node(link_type p) {
destroy(&p->data);
put_node(p);
}
protected:
void empty_initialize() {
node = get_node();
node->next = node;
node->prev = node;
}
void fill_initialize(size_type n, const T& value) {
empty_initialize();
try {
insert(begin(), n, value);
}
catch(...) {
clear();
put_node(node);
throw;
}
}
template <class InputIterator>
void range_initialize(InputIterator first, InputIterator last) {
empty_initialize();
try {
insert(begin(), first, last);
}
catch(...) {
clear();
put_node(node);
throw;
}
}
protected:
link_type node;
public:
list() { empty_initialize(); }
iterator begin() { return (link_type)((*node).next); }
const_iterator begin() const { return (link_type)((*node).next); }
iterator end() { return node; }
const_iterator end() const { return node; }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
bool empty() const { return node->next == node; }
size_type size() const {
size_type result = 0;
distance(begin(), end(), result);
return result;
}
size_type max_size() const { return size_type(-1); }
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *(--end()); }
const_reference back() const { return *(--end()); }
void swap(list<T, Alloc>& x) { ::swap(node, x.node); }
iterator insert(iterator position, const T& x) {
link_type tmp = create_node(x);
tmp->next = position.node;
tmp->prev = position.node->prev;
(link_type(position.node->prev))->next = tmp;
position.node->prev = tmp;
return tmp;
}
iterator insert(iterator position) { return insert(position, T()); }
template <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last);
void insert(iterator pos, size_type n, const T& x);
void insert(iterator pos, int n, const T& x) {
insert(pos, (size_type)n, x);
}
void insert(iterator pos, long n, const T& x) {
insert(pos, (size_type)n, x);
}
void push_front(const T& x) { insert(begin(), x); }
void push_back(const T& x) { insert(end(), x); }
void erase(iterator position) {
(link_type(position.node->prev))->next = position.node->next;
(link_type(position.node->next))->prev = position.node->prev;
destroy_node(position.node);
}
void erase(iterator first, iterator last);
void resize(size_type new_size, const T& x);
void resize(size_type new_size) { resize(new_size, T()); }
void clear();
void pop_front() { erase(begin()); }
void pop_back() {
iterator tmp = end();
erase(--tmp);
}
list(size_type n, const T& value) { fill_initialize(n, value); }
list(int n, const T& value) { fill_initialize(n, value); }
list(long n, const T& value) { fill_initialize(n, value); }
explicit list(size_type n) { fill_initialize(n, T()); }
template <class InputIterator>
list(InputIterator first, InputIterator last) {
range_initialize(first, last);
}
list(const list<T, Alloc>& x) {
range_initialize(x.begin(), x.end());
}
~list() {
clear();
put_node(node);
}
list<T, Alloc>& operator=(const list<T, Alloc>& x);
protected:
void transfer(iterator position, iterator first, iterator last) {
if (position != last) {
(*(link_type((*last.node).prev))).next = position.node;
(*(link_type((*first.node).prev))).next = last.node;
(*(link_type((*position.node).prev))).next = first.node;
link_type tmp = link_type((*position.node).prev);
(*position.node).prev = (*last.node).prev;
(*last.node).prev = (*first.node).prev;
(*first.node).prev = tmp;
}
}
public:
void splice(iterator position, list& x) {
if (!x.empty())
transfer(position, x.begin(), x.end());
}
void splice(iterator position, list&, iterator i) {
iterator j = i;
++j;
if (position == i || position == j) return;
transfer(position, i, j);
}
void splice(iterator position, list&, iterator first, iterator last) {
if (first != last)
transfer(position, first, last);
}
void remove(const T& value);
void unique();
void merge(list& x);
void reverse();
void sort();
template <class Predicate> void remove_if(Predicate);
template <class BinaryPredicate> void unique(BinaryPredicate);
template <class StrictWeakOrdering> void merge(list&, StrictWeakOrdering);
template <class StrictWeakOrdering> void sort(StrictWeakOrdering);
friend bool operator== (const list& x, const list& y);
};
template <class T, class Alloc>
inline bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y) {
typedef list<T,Alloc>::link_type link_type;
link_type e1 = x.node;
link_type e2 = y.node;
link_type n1 = (link_type) e1->next;
link_type n2 = (link_type) e2->next;
for ( ; n1 != e1 && n2 != e2 ;
n1 = (link_type) n1->next, n2 = (link_type) n2->next)
if (n1->data != n2->data)
return false;
return n1 == e1 && n2 == e2;
}
template <class T, class Alloc>
inline bool operator<(const list<T, Alloc>& x, const list<T, Alloc>& y) {
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
template <class T, class Alloc> template <class InputIterator>
void list<T, Alloc>::insert(iterator position,
InputIterator first, InputIterator last) {
for ( ; first != last; ++first)
insert(position, *first);
}
template <class T, class Alloc>
void list<T, Alloc>::insert(iterator position, size_type n, const T& x) {
for ( ; n > 0; --n)
insert(position, x);
}
template <class T, class Alloc>
void list<T, Alloc>::erase(iterator first, iterator last) {
while (first != last) erase(first++);
}
template <class T, class Alloc>
void list<T, Alloc>::resize(size_type new_size, const T& x)
{
size_type len = size();
if (new_size < len) {
iterator f;
if (new_size < len / 2) {
f = begin();
advance(f, new_size);
}
else {
f = end();
advance(f, difference_type(len) - difference_type(new_size));
}
erase(f, end());
}
else
insert(end(), new_size - len, x);
}
template <class T, class Alloc>
void list<T, Alloc>::clear()
{
link_type cur = (link_type) node->next;
while (cur != node) {
link_type tmp = cur;
cur = (link_type) cur->next;
destroy_node(tmp);
}
node->next = node;
node->prev = node;
}
template <class T, class Alloc>
list<T, Alloc>& list<T, Alloc>::operator=(const list<T, Alloc>& x) {
if (this != &x) {
iterator first1 = begin();
iterator last1 = end();
const_iterator first2 = x.begin();
const_iterator last2 = x.end();
while (first1 != last1 && first2 != last2) *first1++ = *first2++;
if (first2 == last2)
erase(first1, last1);
else
insert(last1, first2, last2);
}
return *this;
}
template <class T, class Alloc>
void list<T, Alloc>::remove(const T& value) {
iterator first = begin();
iterator last = end();
while (first != last) {
iterator next = first;
++next;
if (*first == value) erase(first);
first = next;
}
}
template <class T, class Alloc>
void list<T, Alloc>::unique() {
iterator first = begin();
iterator last = end();
if (first == last) return;
iterator next = first;
while (++next != last) {
if (*first == *next)
erase(next);
else
first = next;
next = first;
}
}
template <class T, class Alloc>
void list<T, Alloc>::merge(list<T, Alloc>& 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;
transfer(first1, first2, ++next);
first2 = next;
}
else
++first1;
if (first2 != last2) transfer(last1, first2, last2);
}
template <class T, class Alloc>
void list<T, Alloc>::reverse() {
if (node->next == node || link_type(node->next)->next == node) return;
iterator first = begin();
++first;
while (first != end()) {
iterator old = first;
++first;
transfer(begin(), old, first);
}
}
template <class T, class Alloc>
void list<T, Alloc>::sort() {
if (node->next == node || link_type(node->next)->next == node) return;
list<T, Alloc> carry;
list<T, Alloc> counter[64];
int fill = 0;
while (!empty()) {
carry.splice(carry.begin(), *this, begin());
int i = 0;
while(i < fill && !counter[i].empty()) {
counter[i].merge(carry);
carry.swap(counter[i++]);
}
carry.swap(counter[i]);
if (i == fill) ++fill;
}
for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1]);
swap(counter[fill-1]);
}
template <class T, class Alloc> template <class Predicate>
void list<T, Alloc>::remove_if(Predicate pred) {
iterator first = begin();
iterator last = end();
while (first != last) {
iterator next = first;
++next;
if (pred(*first)) erase(first);
first = next;
}
}
template <class T, class Alloc> template <class BinaryPredicate>
void list<T, 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))
erase(next);
else
first = next;
next = first;
}
}
template <class T, class Alloc> template <class StrictWeakOrdering>
void list<T, Alloc>::merge(list<T, Alloc>& x, StrictWeakOrdering comp) {
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;
transfer(first1, first2, ++next);
first2 = next;
}
else
++first1;
if (first2 != last2) transfer(last1, first2, last2);
}
template <class T, class Alloc> template <class StrictWeakOrdering>
void list<T, Alloc>::sort(StrictWeakOrdering comp) {
if (node->next == node || link_type(node->next)->next == node) return;
list<T, Alloc> carry;
list<T, Alloc> counter[64];
int fill = 0;
while (!empty()) {
carry.splice(carry.begin(), *this, begin());
int i = 0;
while(i < fill && !counter[i].empty()) {
counter[i].merge(carry, comp);
carry.swap(counter[i++]);
}
carry.swap(counter[i]);
if (i == fill) ++fill;
}
for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1], comp);
swap(counter[fill-1]);
}
typedef bool __rb_tree_color_type;
const __rb_tree_color_type __rb_tree_red = false;
const __rb_tree_color_type __rb_tree_black = true;
struct __rb_tree_node_base
{
typedef __rb_tree_color_type color_type;
typedef __rb_tree_node_base* base_ptr;
color_type color;
base_ptr parent;
base_ptr left;
base_ptr right;
static base_ptr minimum(base_ptr x)
{
while (x->left != 0) x = x->left;
return x;
}
static base_ptr maximum(base_ptr x)
{
while (x->right != 0) x = x->right;
return x;
}
};
template <class Value>
struct __rb_tree_node : public __rb_tree_node_base
{
typedef __rb_tree_node<Value>* link_type;
Value value_field;
};
struct __rb_tree_base_iterator
{
typedef __rb_tree_node_base::base_ptr base_ptr;
typedef bidirectional_iterator_tag iterator_category;
typedef ptrdiff_t difference_type;
base_ptr node;
void increment()
{
if (node->right != 0) {
node = node->right;
while (node->left != 0)
node = node->left;
}
else {
base_ptr y = node->parent;
while (node == y->right) {
node = y;
y = y->parent;
}
if (node->right != y)
node = y;
}
}
void decrement()
{
if (node->color == __rb_tree_red &&
node->parent->parent == node)
node = node->right;
else if (node->left != 0) {
base_ptr y = node->left;
while (y->right != 0)
y = y->right;
node = y;
}
else {
base_ptr y = node->parent;
while (node == y->left) {
node = y;
y = y->parent;
}
node = y;
}
}
};
template <class Value, class Ref, class Ptr>
struct __rb_tree_iterator : public __rb_tree_base_iterator
{
typedef Value value_type;
typedef Value& reference;
typedef Value* pointer;
typedef __rb_tree_iterator<Value, Value&, Value*> iterator;
typedef __rb_tree_iterator<Value, const Value&, const Value*> const_iterator;
typedef __rb_tree_iterator<Value, Ref, Ptr> self;
typedef __rb_tree_node<Value>* link_type;
__rb_tree_iterator() {}
__rb_tree_iterator(link_type x) { node = x; }
__rb_tree_iterator(const iterator& it) { node = it.node; }
reference operator*() const { return link_type(node)->value_field; }
pointer operator->() const { return &(operator*()); }
self& operator++() { increment(); return *this; }
self operator++(int) {
self tmp = *this;
increment();
return tmp;
}
self& operator--() { decrement(); return *this; }
self operator--(int) {
self tmp = *this;
decrement();
return tmp;
}
};
inline bool operator==(const __rb_tree_base_iterator& x,
const __rb_tree_base_iterator& y) {
return x.node == y.node;
}
inline bool operator!=(const __rb_tree_base_iterator& x,
const __rb_tree_base_iterator& y) {
return x.node != y.node;
}
inline void
__rb_tree_rotate_left(__rb_tree_node_base* x, __rb_tree_node_base*& root)
{
__rb_tree_node_base* y = x->right;
x->right = y->left;
if (y->left !=0)
y->left->parent = x;
y->parent = x->parent;
if (x == root)
root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y;
}
inline void
__rb_tree_rotate_right(__rb_tree_node_base* x, __rb_tree_node_base*& root)
{
__rb_tree_node_base* y = x->left;
x->left = y->right;
if (y->right != 0)
y->right->parent = x;
y->parent = x->parent;
if (x == root)
root = y;
else if (x == x->parent->right)
x->parent->right = y;
else
x->parent->left = y;
y->right = x;
x->parent = y;
}
inline void
__rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root)
{
x->color = __rb_tree_red;
while (x != root && x->parent->color == __rb_tree_red) {
if (x->parent == x->parent->parent->left) {
__rb_tree_node_base* y = x->parent->parent->right;
if (y && y->color == __rb_tree_red) {
x->parent->color = __rb_tree_black;
y->color = __rb_tree_black;
x->parent->parent->color = __rb_tree_red;
x = x->parent->parent;
}
else {
if (x == x->parent->right) {
x = x->parent;
__rb_tree_rotate_left(x, root);
}
x->parent->color = __rb_tree_black;
x->parent->parent->color = __rb_tree_red;
__rb_tree_rotate_right(x->parent->parent, root);
}
}
else {
__rb_tree_node_base* y = x->parent->parent->left;
if (y && y->color == __rb_tree_red) {
x->parent->color = __rb_tree_black;
y->color = __rb_tree_black;
x->parent->parent->color = __rb_tree_red;
x = x->parent->parent;
}
else {
if (x == x->parent->left) {
x = x->parent;
__rb_tree_rotate_right(x, root);
}
x->parent->color = __rb_tree_black;
x->parent->parent->color = __rb_tree_red;
__rb_tree_rotate_left(x->parent->parent, root);
}
}
}
root->color = __rb_tree_black;
}
inline __rb_tree_node_base*
__rb_tree_rebalance_for_erase(__rb_tree_node_base* z,
__rb_tree_node_base*& root,
__rb_tree_node_base*& leftmost,
__rb_tree_node_base*& rightmost)
{
__rb_tree_node_base* y = z;
__rb_tree_node_base* x = 0;
__rb_tree_node_base* x_parent = 0;
if (y->left == 0)
x = y->right;
else
if (y->right == 0)
x = y->left;
else {
y = y->right;
while (y->left != 0)
y = y->left;
x = y->right;
}
if (y != z) {
z->left->parent = y;
y->left = z->left;
if (y != z->right) {
x_parent = y->parent;
if (x) x->parent = y->parent;
y->parent->left = x;
y->right = z->right;
z->right->parent = y;
}
else
x_parent = y;
if (root == z)
root = y;
else if (z->parent->left == z)
z->parent->left = y;
else
z->parent->right = y;
y->parent = z->parent;
::swap(y->color, z->color);
y = z;
}
else {
x_parent = y->parent;
if (x) x->parent = y->parent;
if (root == z)
root = x;
else
if (z->parent->left == z)
z->parent->left = x;
else
z->parent->right = x;
if (leftmost == z)
if (z->right == 0)
leftmost = z->parent;
else
leftmost = __rb_tree_node_base::minimum(x);
if (rightmost == z)
if (z->left == 0)
rightmost = z->parent;
else
rightmost = __rb_tree_node_base::maximum(x);
}
if (y->color != __rb_tree_red) {
while (x != root && (x == 0 || x->color == __rb_tree_black))
if (x == x_parent->left) {
__rb_tree_node_base* w = x_parent->right;
if (w->color == __rb_tree_red) {
w->color = __rb_tree_black;
x_parent->color = __rb_tree_red;
__rb_tree_rotate_left(x_parent, root);
w = x_parent->right;
}
if ((w->left == 0 || w->left->color == __rb_tree_black) &&
(w->right == 0 || w->right->color == __rb_tree_black)) {
w->color = __rb_tree_red;
x = x_parent;
x_parent = x_parent->parent;
} else {
if (w->right == 0 || w->right->color == __rb_tree_black) {
if (w->left) w->left->color = __rb_tree_black;
w->color = __rb_tree_red;
__rb_tree_rotate_right(w, root);
w = x_parent->right;
}
w->color = x_parent->color;
x_parent->color = __rb_tree_black;
if (w->right) w->right->color = __rb_tree_black;
__rb_tree_rotate_left(x_parent, root);
break;
}
} else {
__rb_tree_node_base* w = x_parent->left;
if (w->color == __rb_tree_red) {
w->color = __rb_tree_black;
x_parent->color = __rb_tree_red;
__rb_tree_rotate_right(x_parent, root);
w = x_parent->left;
}
if ((w->right == 0 || w->right->color == __rb_tree_black) &&
(w->left == 0 || w->left->color == __rb_tree_black)) {
w->color = __rb_tree_red;
x = x_parent;
x_parent = x_parent->parent;
} else {
if (w->left == 0 || w->left->color == __rb_tree_black) {
if (w->right) w->right->color = __rb_tree_black;
w->color = __rb_tree_red;
__rb_tree_rotate_left(w, root);
w = x_parent->left;
}
w->color = x_parent->color;
x_parent->color = __rb_tree_black;
if (w->left) w->left->color = __rb_tree_black;
__rb_tree_rotate_right(x_parent, root);
break;
}
}
if (x) x->color = __rb_tree_black;
}
return y;
}
template <class Key, class Value, class KeyOfValue, class Compare,
class Alloc = alloc>
class rb_tree {
protected:
typedef void* void_pointer;
typedef __rb_tree_node_base* base_ptr;
typedef __rb_tree_node<Value> rb_tree_node;
typedef simple_alloc<rb_tree_node, Alloc> rb_tree_node_allocator;
typedef __rb_tree_color_type color_type;
public:
typedef Key key_type;
typedef Value value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef rb_tree_node* link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
protected:
link_type get_node() { return rb_tree_node_allocator::allocate(); }
void put_node(link_type p) { rb_tree_node_allocator::deallocate(p); }
link_type create_node(const value_type& x) {
link_type tmp = get_node();
try {
construct(&tmp->value_field, x);
return tmp;
}
catch(...) {
put_node(tmp);
throw;
}
}
link_type clone_node(link_type x) {
link_type tmp = create_node(x->value_field);
tmp->color = x->color;
tmp->left = 0;
tmp->right = 0;
return tmp;
}
void destroy_node(link_type p) {
destroy(&p->value_field);
put_node(p);
}
protected:
size_type node_count;
link_type header;
Compare key_compare;
link_type& root() const { return (link_type&) header->parent; }
link_type& leftmost() const { return (link_type&) header->left; }
link_type& rightmost() const { return (link_type&) header->right; }
static link_type& left(link_type x) { return (link_type&)(x->left); }
static link_type& right(link_type x) { return (link_type&)(x->right); }
static link_type& parent(link_type x) { return (link_type&)(x->parent); }
static reference value(link_type x) { return x->value_field; }
static const Key& key(link_type x) { return KeyOfValue()(value(x)); }
static color_type& color(link_type x) { return (color_type&)(x->color); }
static link_type& left(base_ptr x) { return (link_type&)(x->left); }
static link_type& right(base_ptr x) { return (link_type&)(x->right); }
static link_type& parent(base_ptr x) { return (link_type&)(x->parent); }
static reference value(base_ptr x) { return ((link_type)x)->value_field; }
static const Key& key(base_ptr x) { return KeyOfValue()(value(link_type(x)));}
static color_type& color(base_ptr x) { return (color_type&)(link_type(x)->color); }
static link_type minimum(link_type x) {
return (link_type) __rb_tree_node_base::minimum(x);
}
static link_type maximum(link_type x) {
return (link_type) __rb_tree_node_base::maximum(x);
}
public:
typedef __rb_tree_iterator<value_type, reference, pointer> iterator;
typedef __rb_tree_iterator<value_type, const_reference, const_pointer>
const_iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
private:
iterator __insert(base_ptr x, base_ptr y, const value_type& v);
link_type __copy(link_type x, link_type p);
void __erase(link_type x);
void init() {
header = get_node();
color(header) = __rb_tree_red;
root() = 0;
leftmost() = header;
rightmost() = header;
}
public:
rb_tree(const Compare& comp = Compare())
: key_compare(comp), node_count(0) { init(); }
rb_tree(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x)
: key_compare(x.key_compare), node_count(0) {
header = get_node();
color(header) = __rb_tree_red;
if (x.root() == 0) {
root() = 0;
leftmost() = header;
rightmost() = header;
}
else {
try {
root() = __copy(x.root(), header);
}
catch(...) {
put_node(header);
throw;
}
leftmost() = minimum(root());
rightmost() = maximum(root());
}
node_count = x.node_count;
}
~rb_tree() {
clear();
put_node(header);
}
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>&
operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x);
public:
Compare key_comp() const { return key_compare; }
iterator begin() { return leftmost(); }
const_iterator begin() const { return leftmost(); }
iterator end() { return header; }
const_iterator end() const { return header; }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
bool empty() const { return node_count == 0; }
size_type size() const { return node_count; }
size_type max_size() const { return size_type(-1); }
void swap(rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& t) {
::swap(header, t.header);
::swap(node_count, t.node_count);
::swap(key_compare, t.key_compare);
}
public:
pair<iterator,bool> insert_unique(const value_type& x);
iterator insert_equal(const value_type& x);
iterator insert_unique(iterator position, const value_type& x);
iterator insert_equal(iterator position, const value_type& x);
template <class InputIterator>
void insert_unique(InputIterator first, InputIterator last);
template <class InputIterator>
void insert_equal(InputIterator first, InputIterator last);
void erase(iterator position);
size_type erase(const key_type& x);
void erase(iterator first, iterator last);
void erase(const key_type* first, const key_type* last);
void clear() {
if (node_count != 0) {
__erase(root());
leftmost() = header;
root() = 0;
rightmost() = header;
node_count = 0;
}
}
public:
iterator find(const key_type& x);
const_iterator find(const key_type& x) const;
size_type count(const key_type& x) const;
iterator lower_bound(const key_type& x);
const_iterator lower_bound(const key_type& x) const;
iterator upper_bound(const key_type& x);
const_iterator upper_bound(const key_type& x) const;
pair<iterator,iterator> equal_range(const key_type& x);
pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
public:
bool __rb_verify() const;
};
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline bool operator==(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x,
const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) {
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline bool operator<(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x,
const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) {
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>&
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::
operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) {
if (this != &x) {
clear();
node_count = 0;
key_compare = x.key_compare;
if (x.root() == 0) {
root() = 0;
leftmost() = header;
rightmost() = header;
}
else {
root() = __copy(x.root(), header);
leftmost() = minimum(root());
rightmost() = maximum(root());
node_count = x.node_count;
}
}
return *this;
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::
__insert(base_ptr x_, base_ptr y_, const Value& v) {
link_type x = (link_type) x_;
link_type y = (link_type) y_;
link_type z;
if (y == header || x != 0 || key_compare(KeyOfValue()(v), key(y))) {
z = create_node(v);
left(y) = z;
if (y == header) {
root() = z;
rightmost() = z;
}
else if (y == leftmost())
leftmost() = z;
}
else {
z = create_node(v);
right(y) = z;
if (y == rightmost())
rightmost() = z;
}
parent(z) = y;
left(z) = 0;
right(z) = 0;
__rb_tree_rebalance(z, header->parent);
++node_count;
return iterator(z);
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_equal(const Value& v)
{
link_type y = header;
link_type x = root();
while (x != 0) {
y = x;
x = key_compare(KeyOfValue()(v), key(x)) ? left(x) : right(x);
}
return __insert(x, y, v);
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
pair<rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, bool>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_unique(const Value& v)
{
link_type y = header;
link_type x = root();
bool comp = true;
while (x != 0) {
y = x;
comp = key_compare(KeyOfValue()(v), key(x));
x = comp ? left(x) : right(x);
}
iterator j = iterator(y);
if (comp)
if (j == begin())
return pair<iterator,bool>(__insert(x, y, v), true);
else
--j;
if (key_compare(key(j.node), KeyOfValue()(v)))
return pair<iterator,bool>(__insert(x, y, v), true);
return pair<iterator,bool>(j, false);
}
template <class Key, class Val, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::iterator
rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::insert_unique(iterator position,
const Val& v) {
if (position.node == header->left)
if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node)))
return __insert(position.node, position.node, v);
else
return insert_unique(v).first;
else if (position.node == header)
if (key_compare(key(rightmost()), KeyOfValue()(v)))
return __insert(0, rightmost(), v);
else
return insert_unique(v).first;
else {
iterator before = position;
--before;
if (key_compare(key(before.node), KeyOfValue()(v))
&& key_compare(KeyOfValue()(v), key(position.node)))
if (right(before.node) == 0)
return __insert(0, before.node, v);
else
return __insert(position.node, position.node, v);
else
return insert_unique(v).first;
}
}
template <class Key, class Val, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::iterator
rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::insert_equal(iterator position,
const Val& v) {
if (position.node == header->left)
if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node)))
return __insert(position.node, position.node, v);
else
return insert_equal(v);
else if (position.node == header)
if (!key_compare(KeyOfValue()(v), key(rightmost())))
return __insert(0, rightmost(), v);
else
return insert_equal(v);
else {
iterator before = position;
--before;
if (!key_compare(KeyOfValue()(v), key(before.node))
&& !key_compare(key(position.node), KeyOfValue()(v)))
if (right(before.node) == 0)
return __insert(0, before.node, v);
else
return __insert(position.node, position.node, v);
else
return insert_equal(v);
}
}
template <class K, class V, class KoV, class Cmp, class Al> template<class II>
void rb_tree<K, V, KoV, Cmp, Al>::insert_equal(II first, II last) {
for ( ; first != last; ++first)
insert_equal(*first);
}
template <class K, class V, class KoV, class Cmp, class Al> template<class II>
void rb_tree<K, V, KoV, Cmp, Al>::insert_unique(II first, II last) {
for ( ; first != last; ++first)
insert_unique(*first);
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline void
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator position) {
link_type y = (link_type) __rb_tree_rebalance_for_erase(position.node,
header->parent,
header->left,
header->right);
destroy_node(y);
--node_count;
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(const Key& x) {
pair<iterator,iterator> p = equal_range(x);
size_type n = 0;
distance(p.first, p.second, n);
erase(p.first, p.second);
return n;
}
template <class K, class V, class KeyOfValue, class Compare, class Alloc>
rb_tree<K, V, KeyOfValue, Compare, Alloc>::link_type
rb_tree<K, V, KeyOfValue, Compare, Alloc>::__copy(link_type x, link_type p) {
link_type top = clone_node(x);
top->parent = p;
try {
if (x->right)
top->right = __copy(right(x), top);
p = top;
x = left(x);
while (x != 0) {
link_type y = clone_node(x);
p->left = y;
y->parent = p;
if (x->right)
y->right = __copy(right(x), y);
p = y;
x = left(x);
}
}
catch(...) {
__erase(top);
throw;
}
return top;
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__erase(link_type x) {
while (x != 0) {
__erase(right(x));
link_type y = left(x);
destroy_node(x);
x = y;
}
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator first,
iterator last) {
if (first == begin() && last == end())
clear();
else
while (first != last) erase(first++);
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(const Key* first,
const Key* last) {
while (first != last) erase(*first++);
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find(const Key& k) {
link_type y = header;
link_type x = root();
while (x != 0)
if (!key_compare(key(x), k))
y = x, x = left(x);
else
x = right(x);
iterator j = iterator(y);
return (j == end() || key_compare(k, key(j.node))) ? end() : j;
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find(const Key& k) const {
link_type y = header;
link_type x = root();
while (x != 0) {
if (!key_compare(key(x), k))
y = x, x = left(x);
else
x = right(x);
}
const_iterator j = const_iterator(y);
return (j == end() || key_compare(k, key(j.node))) ? end() : j;
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::count(const Key& k) const {
pair<const_iterator, const_iterator> p = equal_range(k);
size_type n = 0;
distance(p.first, p.second, n);
return n;
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::lower_bound(const Key& k) {
link_type y = header;
link_type x = root();
while (x != 0)
if (!key_compare(key(x), k))
y = x, x = left(x);
else
x = right(x);
return iterator(y);
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::lower_bound(const Key& k) const {
link_type y = header;
link_type x = root();
while (x != 0)
if (!key_compare(key(x), k))
y = x, x = left(x);
else
x = right(x);
return const_iterator(y);
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::upper_bound(const Key& k) {
link_type y = header;
link_type x = root();
while (x != 0)
if (key_compare(k, key(x)))
y = x, x = left(x);
else
x = right(x);
return iterator(y);
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::upper_bound(const Key& k) const {
link_type y = header;
link_type x = root();
while (x != 0)
if (key_compare(k, key(x)))
y = x, x = left(x);
else
x = right(x);
return const_iterator(y);
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline pair<rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator,
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::equal_range(const Key& k) {
return pair<iterator, iterator>(lower_bound(k), upper_bound(k));
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline pair<rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator,
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::equal_range(const Key& k) const {
return pair<const_iterator,const_iterator>(lower_bound(k), upper_bound(k));
}
inline int __black_count(__rb_tree_node_base* node, __rb_tree_node_base* root)
{
if (node == 0)
return 0;
else {
int bc = node->color == __rb_tree_black ? 1 : 0;
if (node == root)
return bc;
else
return bc + __black_count(node->parent, root);
}
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
bool
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__rb_verify() const
{
if (node_count == 0 || begin() == end())
return node_count == 0 && begin() == end() &&
header->left == header && header->right == header;
int len = __black_count(leftmost(), root());
for (const_iterator it = begin(); it != end(); ++it) {
link_type x = (link_type) it.node;
link_type L = left(x);
link_type R = right(x);
if (x->color == __rb_tree_red)
if ((L && L->color == __rb_tree_red) ||
(R && R->color == __rb_tree_red))
return false;
if (L && key_compare(key(x), key(L)))
return false;
if (R && key_compare(key(R), key(x)))
return false;
if (!L && !R && __black_count(x, root()) != len)
return false;
}
if (leftmost() != __rb_tree_node_base::minimum(root()))
return false;
if (rightmost() != __rb_tree_node_base::maximum(root()))
return false;
return true;
}
template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
class map {
public:
typedef Key key_type;
typedef T data_type;
typedef pair<const Key, T> value_type;
typedef Compare key_compare;
class value_compare
: public binary_function<value_type, value_type, bool> {
friend class map<Key, T, 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:
typedef rb_tree<key_type, value_type,
select1st<value_type>, key_compare, Alloc> rep_type;
rep_type t;
public:
typedef rep_type::pointer pointer;
typedef rep_type::reference reference;
typedef rep_type::const_reference const_reference;
typedef rep_type::iterator iterator;
typedef rep_type::const_iterator const_iterator;
typedef rep_type::reverse_iterator reverse_iterator;
typedef rep_type::const_reverse_iterator const_reverse_iterator;
typedef rep_type::size_type size_type;
typedef rep_type::difference_type difference_type;
map() : t(Compare()) {}
explicit map(const Compare& comp) : t(comp) {}
template <class InputIterator>
map(InputIterator first, InputIterator last)
: t(Compare()) { t.insert_unique(first, last); }
template <class InputIterator>
map(InputIterator first, InputIterator last, const Compare& comp)
: t(comp) { t.insert_unique(first, last); }
map(const map<Key, T, Compare, Alloc>& x) : t(x.t) {}
map<Key, T, Compare, Alloc>& operator=(const map<Key, T, Compare, Alloc>& x)
{
t = x.t;
return *this;
}
key_compare key_comp() const { return t.key_comp(); }
value_compare value_comp() const { return value_compare(t.key_comp()); }
iterator begin() { return t.begin(); }
const_iterator begin() const { return t.begin(); }
iterator end() { return t.end(); }
const_iterator end() const { return t.end(); }
reverse_iterator rbegin() { return t.rbegin(); }
const_reverse_iterator rbegin() const { return t.rbegin(); }
reverse_iterator rend() { return t.rend(); }
const_reverse_iterator rend() const { return t.rend(); }
bool empty() const { return t.empty(); }
size_type size() const { return t.size(); }
size_type max_size() const { return t.max_size(); }
T& operator[](const key_type& k) {
return (*((insert(value_type(k, T()))).first)).second;
}
void swap(map<Key, T, Compare, Alloc>& x) { t.swap(x.t); }
pair<iterator,bool> insert(const value_type& x) { return t.insert_unique(x); }
iterator insert(iterator position, const value_type& x) {
return t.insert_unique(position, x);
}
template <class InputIterator>
void insert(InputIterator first, InputIterator last) {
t.insert_unique(first, last);
}
void erase(iterator position) { t.erase(position); }
size_type erase(const key_type& x) { return t.erase(x); }
void erase(iterator first, iterator last) { t.erase(first, last); }
void clear() { t.clear(); }
iterator find(const key_type& x) { return t.find(x); }
const_iterator find(const key_type& x) const { return t.find(x); }
size_type count(const key_type& x) const { return t.count(x); }
iterator lower_bound(const key_type& x) {return t.lower_bound(x); }
const_iterator lower_bound(const key_type& x) const {
return t.lower_bound(x);
}
iterator upper_bound(const key_type& x) {return t.upper_bound(x); }
const_iterator upper_bound(const key_type& x) const {
return t.upper_bound(x);
}
pair<iterator,iterator> equal_range(const key_type& x) {
return t.equal_range(x);
}
pair<const_iterator,const_iterator> equal_range(const key_type& x) const {
return t.equal_range(x);
}
friend bool operator==(const map&, const map&);
friend bool operator<(const map&, const map&);
};
template <class Key, class T, class Compare, class Alloc>
inline bool operator==(const map<Key, T, Compare, Alloc>& x,
const map<Key, T, Compare, Alloc>& y) {
return x.t == y.t;
}
template <class Key, class T, class Compare, class Alloc>
inline bool operator<(const map<Key, T, Compare, Alloc>& x,
const map<Key, T, Compare, Alloc>& y) {
return x.t < y.t;
}
template <class T>
inline T* allocate(ptrdiff_t size, T*) {
set_new_handler(0);
T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
if (tmp == 0) {
cerr << "out of memory" << endl;
exit(1);
}
return tmp;
}
template <class T>
inline void deallocate(T* buffer) {
::operator delete(buffer);
}
template <class T>
class allocator {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
pointer allocate(size_type n) {
return ::allocate((difference_type)n, (pointer)0);
}
void deallocate(pointer p) { ::deallocate(p); }
pointer address(reference x) { return (pointer)&x; }
const_pointer const_address(const_reference x) {
return (const_pointer)&x;
}
size_type init_page_size() {
return max(size_type(1), size_type(4096/sizeof(T)));
}
size_type max_size() const {
return max(size_type(1), size_type((2147483647 * 2U + 1) /sizeof(T)));
}
};
class allocator<void> {
public:
typedef void* pointer;
};
template <class Key, class Compare = less<Key>, class Alloc = alloc>
class set {
public:
typedef Key key_type;
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
private:
typedef rb_tree<key_type, value_type,
identity<value_type>, key_compare, Alloc> rep_type;
rep_type t;
public:
typedef rep_type::const_pointer pointer;
typedef rep_type::const_reference reference;
typedef rep_type::const_reference const_reference;
typedef rep_type::const_iterator iterator;
typedef rep_type::const_iterator const_iterator;
typedef rep_type::const_reverse_iterator reverse_iterator;
typedef rep_type::const_reverse_iterator const_reverse_iterator;
typedef rep_type::size_type size_type;
typedef rep_type::difference_type difference_type;
set() : t(Compare()) {}
explicit set(const Compare& comp) : t(comp) {}
template <class InputIterator>
set(InputIterator first, InputIterator last)
: t(Compare()) { t.insert_unique(first, last); }
template <class InputIterator>
set(InputIterator first, InputIterator last, const Compare& comp)
: t(comp) { t.insert_unique(first, last); }
set(const set<Key, Compare, Alloc>& x) : t(x.t) {}
set<Key, Compare, Alloc>& operator=(const set<Key, Compare, Alloc>& x) {
t = x.t;
return *this;
}
key_compare key_comp() const { return t.key_comp(); }
value_compare value_comp() const { return t.key_comp(); }
iterator begin() const { return t.begin(); }
iterator end() const { return t.end(); }
reverse_iterator rbegin() const { return t.rbegin(); }
reverse_iterator rend() const { return t.rend(); }
bool empty() const { return t.empty(); }
size_type size() const { return t.size(); }
size_type max_size() const { return t.max_size(); }
void swap(set<Key, Compare, Alloc>& x) { t.swap(x.t); }
typedef pair<iterator, bool> pair_iterator_bool;
pair<iterator,bool> insert(const value_type& x) {
pair<rep_type::iterator, bool> p = t.insert_unique(x);
return pair<iterator, bool>(p.first, p.second);
}
iterator insert(iterator position, const value_type& x) {
return t.insert_unique((rep_type::iterator&)position, x);
}
template <class InputIterator>
void insert(InputIterator first, InputIterator last) {
t.insert_unique(first, last);
}
void erase(iterator position) {
t.erase((rep_type::iterator&)position);
}
size_type erase(const key_type& x) {
return t.erase(x);
}
void erase(iterator first, iterator last) {
t.erase((rep_type::iterator&)first,
(rep_type::iterator&)last);
}
void clear() { t.clear(); }
iterator find(const key_type& x) const { return t.find(x); }
size_type count(const key_type& x) const { return t.count(x); }
iterator lower_bound(const key_type& x) const {
return t.lower_bound(x);
}
iterator upper_bound(const key_type& x) const {
return t.upper_bound(x);
}
pair<iterator,iterator> equal_range(const key_type& x) const {
return t.equal_range(x);
}
friend bool operator==(const set&, const set&);
friend bool operator<(const set&, const set&);
};
template <class Key, class Compare, class Alloc>
inline bool operator==(const set<Key, Compare, Alloc>& x,
const set<Key, Compare, Alloc>& y) {
return x.t == y.t;
}
template <class Key, class Compare, class Alloc>
inline bool operator<(const set<Key, Compare, Alloc>& x,
const set<Key, Compare, Alloc>& y) {
return x.t < y.t;
}
template <class T, class Alloc = alloc>
class vector {
public:
typedef T value_type;
typedef value_type* pointer;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
protected:
typedef simple_alloc<value_type, Alloc> data_allocator;
iterator start;
iterator finish;
iterator end_of_storage;
void insert_aux(iterator position, const T& x);
void deallocate() {
if (start) data_allocator::deallocate(start, end_of_storage - start);
}
public:
iterator begin() { return start; }
const_iterator begin() const { return start; }
iterator end() { return finish; }
const_iterator end() const { return finish; }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
size_type size() const { return size_type(end() - begin()); }
size_type max_size() const { return size_type(-1); }
size_type capacity() const { return size_type(end_of_storage - begin()); }
bool empty() const { return begin() == end(); }
reference operator[](size_type n) { return *(begin() + n); }
const_reference operator[](size_type n) const { return *(begin() + n); }
vector() : start(0), finish(0), end_of_storage(0) {}
vector(size_type n, const T& value) {
start = allocate_and_fill(n, value);
finish = start + n;
end_of_storage = finish;
}
explicit vector(size_type n) {
start = allocate_and_fill(n, T());
finish = start + n;
end_of_storage = finish;
}
vector(const vector<T, Alloc>& x) {
start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end());
finish = start + (x.end() - x.begin());
end_of_storage = finish;
}
template <class InputIterator>
vector(InputIterator first, InputIterator last) :
start(0), finish(0), end_of_storage(0) {
range_initialize(first, last, iterator_category(first));
}
~vector() {
destroy(start, finish);
deallocate();
}
vector<T, Alloc>& operator=(const vector<T, Alloc>& x);
void reserve(size_type n) {
if (capacity() < n) {
const size_type old_size = size();
const iterator tmp = allocate_and_copy(n, start, finish);
destroy(start, finish);
deallocate();
start = tmp;
finish = tmp + old_size;
end_of_storage = start + n;
}
}
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *(end() - 1); }
const_reference back() const { return *(end() - 1); }
void push_back(const T& x) {
if (finish != end_of_storage) {
construct(finish, x);
++finish;
} else
insert_aux(end(), x);
}
void swap(vector<T, Alloc>& x) {
::swap(start, x.start);
::swap(finish, x.finish);
::swap(end_of_storage, x.end_of_storage);
}
iterator insert(iterator position, const T& x) {
size_type n = position - begin();
if (finish != end_of_storage && position == end()) {
construct(finish, x);
++finish;
} else
insert_aux(position, x);
return begin() + n;
}
iterator insert(iterator position) { return insert(position, T()); }
template <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last) {
range_insert(position, first, last, iterator_category(first));
}
void insert (iterator position, size_type n, const T& x);
void pop_back() {
--finish;
destroy(finish);
}
void erase(iterator position) {
if (position + 1 != end())
copy(position + 1, finish, position);
--finish;
destroy(finish);
}
void erase(iterator first, iterator last) {
iterator i = copy(last, finish, first);
destroy(i, finish);
finish = finish - (last - first);
}
void resize(size_type new_size, const T& x) {
if (new_size < size())
erase(begin() + new_size, end());
else
insert(end(), new_size - size(), x);
}
void resize(size_type new_size) { resize(new_size, T()); }
void clear() { erase(begin(), end()); }
protected:
iterator allocate_and_fill(size_type n, const T& x) {
iterator result = data_allocator::allocate(n);
try {
uninitialized_fill_n(result, n, x);
return result;
}
catch(...) {
data_allocator::deallocate(result, n);
throw;
}
}
template <class ForwardIterator>
iterator allocate_and_copy(size_type n,
ForwardIterator first, ForwardIterator last) {
iterator result = data_allocator::allocate(n);
try {
uninitialized_copy(first, last, result);
return result;
}
catch(...) {
data_allocator::deallocate(result, n);
throw;
}
}
template <class InputIterator>
void range_initialize(InputIterator first, InputIterator last,
input_iterator_tag) {
for ( ; first != last; ++first)
push_back(*first);
}
template <class ForwardIterator>
void range_initialize(ForwardIterator first, ForwardIterator last,
forward_iterator_tag) {
size_type n = 0;
distance(first, last, n);
start = allocate_and_copy(n, first, last);
finish = start + n;
end_of_storage = finish;
}
template <class InputIterator>
void range_insert(iterator pos,
InputIterator first, InputIterator last,
input_iterator_tag);
template <class ForwardIterator>
void range_insert(iterator pos,
ForwardIterator first, ForwardIterator last,
forward_iterator_tag);
};
template <class T, class Alloc>
inline bool operator==(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}
template <class T, class Alloc>
inline bool operator<(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
template <class T, class Alloc>
vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x) {
if (&x != this) {
if (x.size() > capacity()) {
const iterator tmp = allocate_and_copy(x.end() - x.begin(),
x.begin(), x.end());
destroy(start, finish);
deallocate();
start = tmp;
end_of_storage = start + (x.end() - x.begin());
}
else if (size() >= x.size()) {
iterator i = copy(x.begin(), x.end(), begin());
destroy(i, finish);
}
else {
copy(x.begin(), x.begin() + size(), start);
uninitialized_copy(x.begin() + size(), x.end(), finish);
}
finish = start + x.size();
}
return *this;
}
template <class T, class Alloc>
void vector<T, Alloc>::insert_aux(iterator position, const T& x) {
if (finish != end_of_storage) {
construct(finish, *(finish - 1));
++finish;
T x_copy = x;
copy_backward(position, finish - 2, finish - 1);
*position = x_copy;
}
else {
const size_type old_size = size();
const size_type len = old_size != 0 ? 2 * old_size : 1;
const iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
try {
new_finish = uninitialized_copy(start, position, new_start);
construct(new_finish, x);
++new_finish;
new_finish = uninitialized_copy(position, finish, new_finish);
}
catch(...) {
destroy(new_start, new_finish);
data_allocator::deallocate(new_start, len);
throw;
}
destroy(begin(), end());
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
template <class T, class Alloc>
void vector<T, Alloc>::insert(iterator position, size_type n, const T& x) {
if (n != 0) {
if (size_type (end_of_storage - finish) >= n) {
T x_copy = x;
const size_type elems_after = finish - position;
const iterator old_finish = finish;
if (elems_after > n) {
uninitialized_copy(finish - n, finish, finish);
finish += n;
copy_backward(position, old_finish - n, old_finish);
fill(position, position + n, x_copy);
}
else {
uninitialized_fill_n(finish, n - elems_after, x_copy);
finish += n - elems_after;
uninitialized_copy(position, old_finish, finish);
finish += elems_after;
fill(position, old_finish, x_copy);
}
}
else {
const size_type old_size = size();
const size_type len = old_size + max(old_size, n);
const iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
try {
new_finish = uninitialized_copy(start, position, new_start);
new_finish = uninitialized_fill_n(new_finish, n, x);
new_finish = uninitialized_copy(position, finish, new_finish);
}
catch(...) {
destroy(new_start, new_finish);
data_allocator::deallocate(new_start, len);
throw;
}
destroy(start, finish);
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
}
template <class T, class Alloc> template <class InputIterator>
void vector<T, Alloc>::range_insert(iterator pos,
InputIterator first, InputIterator last,
input_iterator_tag) {
for ( ; first != last; ++first) {
pos = insert(pos, *first);
++pos;
}
}
template <class T, class Alloc> template <class ForwardIterator>
void vector<T, Alloc>::range_insert(iterator position,
ForwardIterator first,
ForwardIterator last,
forward_iterator_tag) {
if (first != last) {
size_type n = 0;
distance(first, last, n);
if (size_type (end_of_storage - finish) >= n) {
const size_type elems_after = finish - position;
const iterator old_finish = finish;
if (elems_after > n) {
uninitialized_copy(finish - n, finish, finish);
finish += n;
copy_backward(position, old_finish - n, old_finish);
copy(first, last, position);
}
else {
ForwardIterator mid = first;
advance(mid, elems_after);
uninitialized_copy(mid, last, finish);
finish += n - elems_after;
uninitialized_copy(position, old_finish, finish);
finish += elems_after;
copy(first, mid, position);
}
}
else {
const size_type old_size = size();
const size_type len = old_size + max(old_size, n);
const iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
try {
new_finish = uninitialized_copy(start, position, new_start);
new_finish = uninitialized_copy(first, last, new_finish);
new_finish = uninitialized_copy(position, finish, new_finish);
}
catch(...) {
destroy(new_start, new_finish);
data_allocator::deallocate(new_start, len);
throw;
}
destroy(start, finish);
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
}
template <class T, class Sequence = deque<T> >
class stack {
friend bool operator==(const stack<T, Sequence>& x,
const stack<T, Sequence>& y);
friend bool operator<(const stack<T, Sequence>& x,
const stack<T, Sequence>& y);
public:
typedef typename Sequence::value_type value_type;
typedef typename Sequence::size_type size_type;
protected:
Sequence c;
public:
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
value_type& top() { return c.back(); }
const value_type& top() const { return c.back(); }
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_back(); }
};
template <class T, class Sequence>
bool operator==(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
return x.c == y.c;
}
template <class T, class Sequence>
bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
return x.c < y.c;
}
template <class T, class Sequence = deque<T> >
class queue {
friend bool operator==(const queue<T, Sequence>& x, const queue<T, Sequence>& y);
friend bool operator<(const queue<T, Sequence>& x, const queue<T, Sequence>& y);
public:
typedef typename Sequence::value_type value_type;
typedef typename Sequence::size_type size_type;
protected:
Sequence c;
public:
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
value_type& front() { return c.front(); }
const value_type& front() const { return c.front(); }
value_type& back() { return c.back(); }
const value_type& back() const { return c.back(); }
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_front(); }
};
template <class T, class Sequence>
bool operator==(const queue<T, Sequence>& x, const queue<T, Sequence>& y) {
return x.c == y.c;
}
template <class T, class Sequence>
bool operator<(const queue<T, Sequence>& x, const queue<T, Sequence>& y) {
return x.c < y.c;
}
template <class T, class Sequence = vector<T>,
class Compare = less<typename Sequence::value_type> >
class priority_queue {
public:
typedef typename Sequence::value_type value_type;
typedef typename Sequence::size_type size_type;
protected:
Sequence c;
Compare comp;
public:
priority_queue() : c() {}
explicit priority_queue(const Compare& x) : c(), comp(x) {}
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last, const Compare& x)
: c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); }
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last)
: c(first, last) { make_heap(c.begin(), c.end(), comp); }
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
const value_type& top() const { return c.front(); }
void push(const value_type& x) {
try {
c.push_back(x);
push_heap(c.begin(), c.end(), comp);
}
catch(...) {
c.clear();
throw;
}
}
void pop() {
try {
pop_heap(c.begin(), c.end(), comp);
c.pop_back();
}
catch(...) {
c.clear();
throw;
}
}
};
template <class S>
struct keep
{
S &s;
keep(S &_s) : s(_s) { }
operator S &() { return s; }
};
template <class A>
struct left : public keep<ostream>
{
left(ostream &_s) : keep<ostream>(_s) { }
void operator ()(const A &v) { s << v; }
};
template <class A>
struct right : public keep<istream>
{
right(istream &_s) : keep<istream>(_s) { }
void operator ()(A &v) { s >> v; }
};
template <class A>
struct perline : public keep<ostream>
{
perline(ostream &_s) : keep<ostream>(_s) { }
void operator ()(const A &v) { s << v << endl; }
};
template <class T>
static istream &
operator>>(istream &in, vector<T> &a)
{
int n;
in >> n;
a.reserve(n);
a.erase(&a[n], a.end());
return for_each(a.begin(), a.end(), right<T>(in));
}
template <class T>
static ostream &
operator<<(ostream &out, const vector<T> &a)
{
return for_each(a.begin(), a.end(), perline<T>(out));
}
template <class T>
static ostream &
operator<<(ostream &out, const list<T> &a)
{
return for_each(a.begin(), a.end(), perline<T>(out));
}
enum spot { sp_none = 0, sp_white = 1, sp_black = 2, sp_either = 3 };
static ostream &
operator<<(ostream &out, const spot &s)
{
return out << "> *."[s];
}
typedef vector<spot> line_conf;
static ostream &
operator<<(ostream &out, const line_conf &a)
{
return for_each(a.begin(), a.end(), left<line_conf::value_type>(out));
}
typedef vector<line_conf> solution;
typedef list<solution> solutions;
class line
{
public:
typedef vector<int> shape;
typedef list<line_conf> confs;
private:
shape the_shape;
line_conf the_poss;
confs the_confs;
void generate();
void genrec(line_conf::iterator, line_conf::iterator,
shape::const_iterator, shape::const_iterator);
void color();
friend class puzzle;
public:
line() { }
line(int sz, const shape &shp)
: the_shape(shp), the_poss(sz, sp_none) { generate(); }
};
void
line::generate()
{
the_confs.erase(the_confs.begin(), the_confs.end());
genrec(the_poss.begin(), the_poss.end(),
the_shape.begin(), the_shape.end());
color();
}
void
line::genrec(line_conf::iterator fc, line_conf::iterator lc,
shape::const_iterator fs, shape::const_iterator ls)
{
if (fs == ls)
{
fill(fc, lc, sp_white);
the_confs.push_back(the_poss);
}
else
{
int npos = lc - fc + 2 - accumulate(fs, ls, ls - fs);
for (int i = 0; i < npos; ++i)
{
line_conf::iterator p = fc;
fill(p, p + i, sp_white);
p += i;
fill(p, p + *fs, sp_black);
p += *fs;
if (p != lc)
*p++ = sp_white;
genrec(p, lc, fs + 1, ls);
}
}
}
void
line::color()
{
line_conf::iterator pb = the_poss.begin(), pe = the_poss.end(), q;
confs::const_iterator cb = the_confs.begin(), ce = the_confs.end(), p;
int n;
fill(pb, pe, sp_none);
for (n = 0, q = pb; q != pe; ++q, ++n)
for (p = cb; p != ce; ++p)
if ((*q = static_cast<spot>(*q | (*p)[n])) == sp_either)
break;
}
class puzzle
{
typedef list<line> side;
side cols;
side rows;
bool step(const side &, side &);
operator solution();
enum state { inconsistent, solved, incomplete };
state done();
side::iterator min_row();
public:
void iterate(solutions &);
puzzle(istream &);
};
puzzle::puzzle(istream &in)
{
int i, num_rows, num_cols;
line::shape shape;
in >> num_cols >> num_rows;
for (i = 0; i < num_cols; ++i)
{
in >> shape;
cols.push_back(line(num_rows, shape));
}
for (i = 0; i < num_rows; ++i)
{
in >> shape;
rows.push_back(line(num_cols, shape));
}
}
bool
puzzle::step(const side &gen, side &test)
{
side::iterator tb = test.begin(), te = test.end(), p;
side::const_iterator gb = gen.begin(), ge = gen.end(), r;
int k, n;
bool changed = false;
for (n = 0, p = tb; p != te; ++p, ++n)
{
bool recolor = false;
line::confs &c = (*p).the_confs;
for (k = 0, r = gb; r != ge; ++r, ++k)
{
spot m = (*r).the_poss[n];
if (m == sp_either)
continue;
line::confs::iterator q = c.begin();
while (q != c.end())
{
line::confs::iterator v = q++;
if (((*v)[k] & m) == 0)
{
c.erase(v);
changed = true;
recolor = true;
}
}
}
if (recolor)
(*p).color();
}
return changed;
}
puzzle::side::iterator
puzzle::min_row()
{
side::iterator rb = rows.begin(), re = rows.end(), r, s;
int m = 2147483647 ;
for (r = rb; r != re; ++r)
{
int n = (*r).the_confs.size();
if (n > 1 && n < m)
{
s = r;
m = n;
}
}
return s;
}
void
puzzle::iterate(solutions &results)
{
for (;;)
{
while (step(rows, cols) | step(cols, rows))
{
}
switch (done())
{
case inconsistent:
return;
case solved:
results.push_back(*this);
return;
}
puzzle clone(*this);
side::iterator it_me = min_row(), it_cl = clone.min_row();
line::confs::iterator i;
i = (*it_cl).the_confs.begin();
(*it_cl).the_confs.erase((*it_cl).the_confs.begin(), ++i);
(*it_cl).color();
i = (*it_me).the_confs.begin();
(*it_me).the_confs.erase(++i, (*it_me).the_confs.end());
(*it_me).color();
clone.iterate(results);
}
}
puzzle::state
puzzle::done()
{
side::const_iterator rb = rows.begin(), re = rows.end(), r;
for (r = rb; r != re; ++r)
{
switch ((*r).the_confs.size())
{
case 0: return inconsistent;
case 1: continue;
default:return incomplete;
}
}
return solved;
}
puzzle::operator solution()
{
solution s(rows.size());
side::const_iterator r = rows.begin(), re = rows.end();
int n = 0;
while (r != re)
s[n++] = (*r++).the_poss;
return s;
}
int
main(int, char **)
{
puzzle p(cin);
solutions results;
p.iterate(results);
cout << results;
}
More information about the Gcc-bugs
mailing list