first commit
This commit is contained in:
420
extern/stdcxx/4.2.1/tests/include/23.containers.h
vendored
Normal file
420
extern/stdcxx/4.2.1/tests/include/23.containers.h
vendored
Normal file
@@ -0,0 +1,420 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* 23.containers.h - definitions of helpers used in clause 23 tests
|
||||
*
|
||||
* $Id: 23.containers.h$
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RW_23_CONTAINERS_H_INCLUDED
|
||||
#define RW_23_CONTAINERS_H_INCLUDED
|
||||
|
||||
#include <testdefs.h>
|
||||
#include <rw_value.h> // for UserClass, UserPOD
|
||||
#include <rw_char.h> // for rw_expand ()
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// defines enumerations identifying the general template arguments,
|
||||
// sets of overloaded functions, member types used in the declarations
|
||||
// of their signatures, and specific overloads of such member functions
|
||||
struct ContainerIds {
|
||||
|
||||
// identifiers for the T template argument
|
||||
enum ElemId { UserPOD, UserClass };
|
||||
|
||||
// identifiers for the Allocator template argument
|
||||
enum AllocId { DefaultAlloc, UserAlloc };
|
||||
|
||||
// identifiers for the Iterator template argument
|
||||
// used with member templates
|
||||
enum IteratorId {
|
||||
None,
|
||||
Input, Forward, Bidir, Random,
|
||||
Pointer, ConstPointer,
|
||||
Iterator, ConstIterator,
|
||||
ReverseIterator, ConstReverseIterator
|
||||
};
|
||||
|
||||
enum ContainerId {
|
||||
List, Vector, Deque, Queue, Stack
|
||||
};
|
||||
|
||||
// identifies a set of overloaded member or non-member
|
||||
// container functions
|
||||
enum FuncId {
|
||||
// 6 bits, 64 functions max
|
||||
// common
|
||||
/* 0 */ fid_ctor,
|
||||
/* 1 */ fid_op_set,
|
||||
/* 2 */ fid_assign,
|
||||
/* 3 */ fid_get_allocator,
|
||||
/* 4 */ fid_begin,
|
||||
/* */ fid_begin_const = fid_begin,
|
||||
/* 5 */ fid_end,
|
||||
/* */ fid_end_const = fid_end,
|
||||
/* 6 */ fid_rbegin,
|
||||
/* */ fid_rbegin_const = fid_rbegin,
|
||||
/* 7 */ fid_rend,
|
||||
/* */ fid_rend_const = fid_rend,
|
||||
/* 8 */ fid_empty,
|
||||
/* 9 */ fid_size,
|
||||
/* 10 */ fid_max_size,
|
||||
/* 11 */ fid_resize,
|
||||
/* 12 */ fid_insert,
|
||||
/* 13 */ fid_erase,
|
||||
/* 14 */ fid_swap,
|
||||
/* 15 */ fid_clear,
|
||||
/* 16 */ fid_op_equal,
|
||||
/* 17 */ fid_op_less,
|
||||
/* 18 */ fid_op_not_equal,
|
||||
/* 19 */ fid_op_greater,
|
||||
/* 20 */ fid_op_greater_equal,
|
||||
/* 21 */ fid_op_less_equal,
|
||||
/* 22 */ fid_push_back,
|
||||
|
||||
// list, deque, vector
|
||||
/* 23 */ fid_front,
|
||||
/* */ fid_front_const = fid_front,
|
||||
/* 24 */ fid_back,
|
||||
/* */ fid_back_const = fid_back,
|
||||
/* 25 */ fid_pop_back,
|
||||
|
||||
// list, deque
|
||||
/* 26 */ fid_push_front,
|
||||
/* 27 */ fid_pop_front,
|
||||
|
||||
// list
|
||||
/* 28 */ fid_splice,
|
||||
/* 29 */ fid_remove,
|
||||
/* 30 */ fid_remove_if,
|
||||
/* 31 */ fid_unique,
|
||||
/* 32 */ fid_merge,
|
||||
/* 33 */ fid_sort,
|
||||
/* 34 */ fid_reverse,
|
||||
|
||||
// vector, string, deque
|
||||
/* 35 */ fid_op_index,
|
||||
/* */ fid_op_index_const = fid_op_index,
|
||||
/* 36 */ fid_at,
|
||||
/* */ fid_at_const = fid_at,
|
||||
|
||||
// vector, string
|
||||
/* 37 */ fid_capacity,
|
||||
/* 38 */ fid_reserve,
|
||||
|
||||
// vector<bool>
|
||||
/* 39 */ fid_flip,
|
||||
|
||||
/* -- */ fid_bits = 6,
|
||||
/* -- */ fid_mask = 63
|
||||
};
|
||||
|
||||
// identifies the type of a function argument, including
|
||||
// the implicit this
|
||||
enum ArgId {
|
||||
// 4 bits, 16 types max
|
||||
/* 0 */ arg_void, // void
|
||||
/* 1 */ arg_size, // size_type
|
||||
/* 2 */ arg_val, // value_type
|
||||
/* 3 */ arg_ref, // reference
|
||||
/* 4 */ arg_cref, // const_reference
|
||||
/* 5 */ arg_iter, // iterator
|
||||
/* 6 */ arg_citer, // const_iterator
|
||||
/* 7 */ arg_range, // Iterator, Iterator
|
||||
/* 8 */ arg_cont, // container& (or this for member functions)
|
||||
/* 9 */ arg_ccont, // const container& (or const this for members)
|
||||
/* 10 */ arg_alloc, // const allocator&
|
||||
/* 11 */ arg_pred, // Predicate
|
||||
/* 12 */ arg_bpred, // BinaryPredicate
|
||||
/* 13 */ arg_comp, // Compare
|
||||
/* -- */ arg_bits = 4,
|
||||
/* -- */ arg_mask = 15
|
||||
};
|
||||
|
||||
enum {
|
||||
// bit designating a member function
|
||||
bit_member = 1 << (fid_bits + 6 * arg_bits)
|
||||
};
|
||||
|
||||
static ArgId arg_type (_RWSTD_SIZE_T id, int argno) {
|
||||
return ArgId (((id >> fid_bits) >> argno * arg_bits) & arg_mask);
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
struct ContainerFunc
|
||||
{
|
||||
ContainerIds::ElemId elem_id_;
|
||||
ContainerIds::AllocId alloc_id_;
|
||||
ContainerIds::IteratorId iter_id_;
|
||||
ContainerIds::ContainerId cont_id_;
|
||||
_RWSTD_SIZE_T which_;
|
||||
};
|
||||
|
||||
|
||||
// describes a single test case for any overload of any container
|
||||
// function (the same test case can be used to exercise more
|
||||
// than one overload of the same function)
|
||||
struct ContainerTestCase
|
||||
{
|
||||
int line; // test case line number
|
||||
|
||||
int off; // offset (position argument)
|
||||
int size; // size (count argument)
|
||||
|
||||
int off2; // offset 2 (position argument)
|
||||
int size2; // size 2 (count argument)
|
||||
|
||||
int val; // value (single character to append)
|
||||
|
||||
const char* str; // controlled sequence
|
||||
_RWSTD_SIZE_T str_len; // length of sequence
|
||||
|
||||
const char* arg; // sequence to insert
|
||||
_RWSTD_SIZE_T arg_len; // length of sequence
|
||||
|
||||
const char* res; // resulting sequence
|
||||
_RWSTD_SIZE_T nres; // length of sequence or expected result value
|
||||
|
||||
int bthrow; // exception expected
|
||||
};
|
||||
|
||||
|
||||
// describes a set of test cases for a single overload of a function
|
||||
struct ContainerTest
|
||||
{
|
||||
// container function overload to exercise
|
||||
_RWSTD_SIZE_T which;
|
||||
|
||||
// test cases to exercise overload with
|
||||
const ContainerTestCase *cases;
|
||||
|
||||
// number of test cases
|
||||
_RWSTD_SIZE_T case_count;
|
||||
};
|
||||
|
||||
|
||||
typedef void ContainerTestFunc (const ContainerFunc&, const ContainerTestCase&);
|
||||
|
||||
_TEST_EXPORT int
|
||||
rw_run_cont_test (int, char**, const char*, const char*,
|
||||
ContainerIds::ContainerId, ContainerTestFunc*,
|
||||
const ContainerTest*, _RWSTD_SIZE_T);
|
||||
|
||||
typedef void VoidFunc ();
|
||||
|
||||
_TEST_EXPORT int
|
||||
rw_run_cont_test (int, char**, const char*, const char*,
|
||||
ContainerIds::ContainerId, VoidFunc* const*,
|
||||
const ContainerTest*, _RWSTD_SIZE_T);
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
class ContainerTestCaseData
|
||||
{
|
||||
private:
|
||||
|
||||
// not defined, not copyable, not assignable
|
||||
ContainerTestCaseData (const ContainerTestCaseData&);
|
||||
void operator= (const ContainerTestCaseData&);
|
||||
|
||||
// for convenience
|
||||
typedef _RWSTD_SIZE_T SizeType;
|
||||
|
||||
public:
|
||||
|
||||
SizeType strlen_; // the length of the expanded string
|
||||
SizeType arglen_; // the length of the expanded argument
|
||||
SizeType reslen_; // the length of the expanded result
|
||||
|
||||
// the offset and extent (the number of elements) of
|
||||
// the first range into the container object being modified
|
||||
SizeType off1_;
|
||||
SizeType ext1_;
|
||||
|
||||
// the offset and extent (the number of elements) of
|
||||
// the argument of the function call
|
||||
SizeType off2_;
|
||||
SizeType ext2_;
|
||||
|
||||
const T* str_; // pointer to the expanded string
|
||||
const T* arg_; // pointer to the expanded argument
|
||||
const T* res_; // pointer to the expanded result
|
||||
|
||||
const ContainerFunc &func_;
|
||||
const ContainerTestCase &tcase_;
|
||||
|
||||
// converts the narrow (and possibly) condensed strings to fully
|
||||
// expanded wide character arrays that can be used to construct
|
||||
// container objects
|
||||
ContainerTestCaseData (const ContainerFunc&,
|
||||
const ContainerTestCase&);
|
||||
|
||||
~ContainerTestCaseData ();
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
ContainerTestCaseData<T>::
|
||||
ContainerTestCaseData (const ContainerFunc &func,
|
||||
const ContainerTestCase &tcase)
|
||||
: func_ (func), tcase_ (tcase)
|
||||
{
|
||||
char buf [256];
|
||||
|
||||
strlen_ = sizeof (buf);
|
||||
char* str = rw_expand (buf, tcase.str, tcase.str_len, &strlen_);
|
||||
str_ = T::from_char (str, strlen_);
|
||||
if (str != buf)
|
||||
delete[] str;
|
||||
|
||||
arglen_ = sizeof (buf);
|
||||
str = rw_expand (buf, tcase.arg, tcase.arg_len, &arglen_);
|
||||
arg_ = T::from_char (str, arglen_);
|
||||
if (str != buf)
|
||||
delete[] str;
|
||||
|
||||
reslen_ = sizeof (buf);
|
||||
str = rw_expand (buf, tcase.res, tcase.nres, &reslen_);
|
||||
res_ = T::from_char (str, reslen_);
|
||||
if (str != buf)
|
||||
delete[] str;
|
||||
|
||||
// compute the offset and extent of the container object
|
||||
// representing the controlled sequence and the offset
|
||||
// and extent of the argument of the function call
|
||||
const SizeType argl = tcase_.arg ? arglen_ : strlen_;
|
||||
|
||||
off1_ = SizeType (tcase_.off) < strlen_ ?
|
||||
SizeType (tcase_.off) : strlen_;
|
||||
|
||||
ext1_ = off1_ + tcase_.size < strlen_ ?
|
||||
SizeType (tcase_.size) : strlen_ - off1_;
|
||||
|
||||
off2_ = SizeType (tcase_.off2) < argl ?
|
||||
SizeType (tcase_.off2) : argl;
|
||||
|
||||
ext2_ = off2_ + tcase_.size2 < argl ?
|
||||
SizeType (tcase_.size2) : argl - off2_;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
ContainerTestCaseData<T>::
|
||||
~ContainerTestCaseData ()
|
||||
{
|
||||
// clean up dynamically allocated memory
|
||||
|
||||
// cast away the constness of the pointers to work around
|
||||
// an HP aCC 6.16 and prior bug described in STDCXX-802
|
||||
delete[] _RWSTD_CONST_CAST (T*, str_);
|
||||
delete[] _RWSTD_CONST_CAST (T*, arg_);
|
||||
delete[] _RWSTD_CONST_CAST (T*, res_);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// base class-functor for the range template overloads testing
|
||||
template <class Cont>
|
||||
struct ContRangeBase {
|
||||
|
||||
typedef typename Cont::value_type ContVal;
|
||||
typedef typename Cont::iterator ContIter;
|
||||
typedef typename Cont::const_iterator ContConstIter;
|
||||
typedef typename Cont::reverse_iterator ContRevIter;
|
||||
typedef typename Cont::const_reverse_iterator ContConstRevIter;
|
||||
|
||||
ContRangeBase () { }
|
||||
|
||||
virtual ~ContRangeBase () { /* silence warnings */ }
|
||||
|
||||
static ContIter
|
||||
begin (Cont &cont, ContIter*) {
|
||||
return cont.begin ();
|
||||
}
|
||||
|
||||
static ContConstIter
|
||||
begin (const Cont &cont, ContConstIter*) {
|
||||
return cont.begin ();
|
||||
}
|
||||
|
||||
static ContRevIter
|
||||
begin (Cont &cont, ContRevIter*) {
|
||||
return cont.rbegin ();
|
||||
}
|
||||
|
||||
static ContConstRevIter
|
||||
begin (const Cont &cont, ContConstRevIter*) {
|
||||
return cont.rbegin ();
|
||||
}
|
||||
|
||||
virtual Cont&
|
||||
operator() (Cont &cont, const ContainerTestCaseData<ContVal>&) const {
|
||||
RW_ASSERT (!"logic error: should be never called");
|
||||
return cont;
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
# define CONTAINER_TEST_DISPATCH(Alloc, fname, func, tcase) \
|
||||
if (ContainerIds::UserPOD == func.elem_id_) \
|
||||
fname (UserPOD (), (Alloc<UserPOD>*)0, func, tcase); \
|
||||
else \
|
||||
fname (UserClass (), (Alloc<UserClass>*)0, func, tcase)
|
||||
|
||||
|
||||
#define DEFINE_CONTAINER_TEST_DISPATCH(fname) \
|
||||
static void \
|
||||
fname (const ContainerFunc &func, \
|
||||
const ContainerTestCase &tcase) { \
|
||||
if (ContainerIds::DefaultAlloc == func.alloc_id_) { \
|
||||
CONTAINER_TEST_DISPATCH (std::allocator, fname, func, tcase); \
|
||||
} \
|
||||
else if (ContainerIds::UserAlloc == func.alloc_id_) { \
|
||||
CONTAINER_TEST_DISPATCH (UserAlloc, fname, func, tcase); \
|
||||
} \
|
||||
else \
|
||||
RW_ASSERT (!"logic error: bad allocator"); \
|
||||
} typedef void rw_unused_typedef
|
||||
|
||||
|
||||
#define CONTAINER_TFUNC(T, Allocator) \
|
||||
void (*)(T*, Allocator<T>*, \
|
||||
const ContainerTestCaseData<T>&)
|
||||
|
||||
#define CONTAINER_TFUNC_ADDR(fname, T, Allocator) \
|
||||
(VoidFunc*)(CONTAINER_TFUNC (T, Allocator)) \
|
||||
&fname<T, Allocator<T> >
|
||||
|
||||
#define DEFINE_CONTAINER_TEST_FUNCTIONS(fname) \
|
||||
static VoidFunc* const fname ## _func_array [] = { \
|
||||
CONTAINER_TFUNC_ADDR (fname, UserPOD, std::allocator), \
|
||||
CONTAINER_TFUNC_ADDR (fname, UserPOD, UserAlloc), \
|
||||
\
|
||||
CONTAINER_TFUNC_ADDR (fname, UserClass, std::allocator), \
|
||||
CONTAINER_TFUNC_ADDR (fname, UserClass, UserAlloc) \
|
||||
}
|
||||
|
||||
#endif // RW_23_CONTAINERS_H_INCLUDED
|
||||
Reference in New Issue
Block a user