first commit
This commit is contained in:
482
extern/stdcxx/4.2.1/tests/utilities/20.auto.ptr.cpp
vendored
Normal file
482
extern/stdcxx/4.2.1/tests/utilities/20.auto.ptr.cpp
vendored
Normal file
@@ -0,0 +1,482 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 20.autoptr.cpp - test exercising [lib.auto.ptr]
|
||||
*
|
||||
* $Id: 20.auto.ptr.cpp 596356 2007-11-19 16:23:21Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2000-2007 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <rw/_defs.h>
|
||||
|
||||
#if defined (__IBMCPP__) && !defined (_RWSTD_NO_IMPLICIT_INCLUSION)
|
||||
// disable implicit inclusion to work around
|
||||
// a limitation in IBM VisualAge 5.0.2.0 (see PR #26959)
|
||||
# define _RWSTD_NO_IMPLICIT_INCLUSION
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _RWSTD_EXPLICIT_INSTANTIATION
|
||||
|
||||
// explicitly instantiate
|
||||
|
||||
# if !defined (_RWSTD_NO_NAMESPACE) && !defined (_RWSTD_NO_HONOR_STD)
|
||||
|
||||
// verify that names are declared [only[ in namespace std
|
||||
|
||||
# define TEST_CLASS_DEF(name, Tparam) \
|
||||
template class std::name Tparam \
|
||||
/* void name (void *name) */
|
||||
|
||||
# else // if defined (_RWSTD_NO_NAMESPACE) || defined (_RWSTD_NO_HONOR_STD)
|
||||
|
||||
// verify that names do not collide with function argument names
|
||||
|
||||
# define TEST_CLASS_DEF(name, Tparam) \
|
||||
template class std::name Tparam; \
|
||||
void foo (void *name)
|
||||
|
||||
# endif // !_RWSTD_NO_NAMESPACE && !_RWSTD_NO_HONOR_STD
|
||||
|
||||
#else // if defined (_RWSTD_EXPLICIT_INSTANTIATION)
|
||||
|
||||
// classes will implicitly instantiated below
|
||||
|
||||
# if !defined (_RWSTD_NO_NAMESPACE) && !defined (_RWSTD_NO_HONOR_STD)
|
||||
|
||||
// verify that names are declared [only] in namespace std
|
||||
|
||||
# define TEST_CLASS_DEF(name, ignore) void name (void *name)
|
||||
|
||||
# else // if defined (_RWSTD_NO_NAMESPACE) || defined (_RWSTD_NO_HONOR_STD)
|
||||
|
||||
# define TEST_CLASS_DEF(name, ignore) void foo (void *name)
|
||||
|
||||
# endif // !_RWSTD_NO_NAMESPACE && !_RWSTD_NO_HONOR_STD
|
||||
|
||||
#endif // _RWSTD_EXPLICIT_INSTANTIATION
|
||||
|
||||
|
||||
// auto_ptr_ref instantiated first to prevent bogus MSVC 6.0 warning C4660:
|
||||
// template-class specialization 'auto_ptr_ref<int>' is already instantiated
|
||||
// follows lwg issue 127
|
||||
TEST_CLASS_DEF (auto_ptr_ref, <int>);
|
||||
|
||||
TEST_CLASS_DEF (auto_ptr, <int>);
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#include <cmdopt.h> // for rw_enabled()
|
||||
#include <driver.h> // for rw_assert(), rw_test(), ...
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
struct Base
|
||||
{
|
||||
int i_; // unique object id
|
||||
|
||||
static int cnt_; // object counter
|
||||
static int gen_; // unique id generator
|
||||
|
||||
Base (): i_ (gen_++) { ++cnt_; }
|
||||
|
||||
~Base () {
|
||||
--cnt_;
|
||||
}
|
||||
|
||||
static void sink (std::auto_ptr<Base>) { }
|
||||
};
|
||||
|
||||
int Base::cnt_; // Base object counter
|
||||
int Base::gen_; // Base unique id generator
|
||||
|
||||
struct Derived: Base
|
||||
{
|
||||
static std::auto_ptr<Derived> source () {
|
||||
return std::auto_ptr<Derived> ();
|
||||
}
|
||||
|
||||
static void sink (std::auto_ptr<Derived>) { }
|
||||
};
|
||||
|
||||
|
||||
// helpers to verify that each class' ctor is explicit
|
||||
// not defined since they must not be referenced if test is successful
|
||||
void is_explicit (const std::auto_ptr<Base>&);
|
||||
|
||||
struct has_implicit_ctor
|
||||
{
|
||||
// NOT explicit
|
||||
#ifndef _RWSTD_NO_NATIVE_BOOL
|
||||
|
||||
has_implicit_ctor (bool*) { }
|
||||
|
||||
#endif // _RWSTD_NO_NATIVE_BOOL
|
||||
|
||||
has_implicit_ctor (char*) { }
|
||||
has_implicit_ctor (int*) { }
|
||||
has_implicit_ctor (double*) { }
|
||||
has_implicit_ctor (void**) { }
|
||||
has_implicit_ctor (Base*) { }
|
||||
};
|
||||
|
||||
void is_explicit (const has_implicit_ctor&) { }
|
||||
|
||||
|
||||
template <class T>
|
||||
void test_auto_ptr (T*, const char *tname)
|
||||
{
|
||||
rw_info (0, 0, 0, "std::auto_ptr<%s>", tname);
|
||||
|
||||
if (!rw_enabled (tname)) {
|
||||
rw_note (0, 0, __LINE__, "auto_ptr<%s> test disabled", tname);
|
||||
return;
|
||||
}
|
||||
|
||||
// exercise 20.4.5, p2 - auto_ptr<> interface
|
||||
|
||||
typedef _TYPENAME std::auto_ptr<T>::element_type element_type;
|
||||
|
||||
// verify that element_type is the same as T
|
||||
element_type *elem = (T*)0;
|
||||
|
||||
// verify that default ctor is explicit
|
||||
is_explicit (elem);
|
||||
|
||||
|
||||
// verify that a member function is accessible and has the appropriate
|
||||
// signature, including return type and exception specification
|
||||
#define FUN(result, T, name, arg_list) do { \
|
||||
result (std::auto_ptr<T>::*pf) arg_list = &std::auto_ptr<T>::name; \
|
||||
_RWSTD_UNUSED (pf); \
|
||||
} while (0)
|
||||
|
||||
#if !defined (__HP_aCC) || _RWSTD_HP_aCC_MAJOR > 5
|
||||
|
||||
// working around a bug in aCC (see PR #24430)
|
||||
FUN (std::auto_ptr<T>&, T, operator=, (std::auto_ptr<T>&) _PTR_THROWS(()));
|
||||
|
||||
#endif // HP aCC > 5
|
||||
|
||||
FUN (T&, T, operator*, () const _PTR_THROWS (()));
|
||||
|
||||
#ifndef _RWSTD_NO_NONCLASS_ARROW_RETURN
|
||||
|
||||
FUN (T*, T, operator->, () const _PTR_THROWS (()));
|
||||
|
||||
#endif // _RWSTD_NO_NONCLASS_ARROW_RETURN
|
||||
|
||||
FUN (T*, T, get, () const _PTR_THROWS (()));
|
||||
FUN (T*, T, release, () _PTR_THROWS (()));
|
||||
FUN (void, T, reset, (T*) _PTR_THROWS (()));
|
||||
|
||||
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
||||
|
||||
# if !defined(__GNUG__) || __GNUG__ > 3 || __GNUG__ == 3 && __GNUC_MINOR__ > 2
|
||||
|
||||
// g++ 2.95.2 and HP aCC can't take the address of a template member
|
||||
|
||||
# if !defined (__HP_aCC) || _RWSTD_HP_aCC_MAJOR > 5
|
||||
|
||||
// SunPro incorrectly warns here (see PR #27276)
|
||||
FUN (std::auto_ptr<Base>&, Base,
|
||||
operator=, (std::auto_ptr<Derived>&) _PTR_THROWS (()));
|
||||
|
||||
// SunPro 5.4 can't decide between a ctor template
|
||||
// and a conversion operator (see PR #24476)
|
||||
# if !defined (__SUNPRO_CC) || __SUNPRO_CC > 0x540
|
||||
|
||||
# if !defined (_MSC_VER) || _MSC_VER > 1310 || defined (__INTEL_COMPILER)
|
||||
FUN (std::auto_ptr_ref<Base>, Derived,
|
||||
operator std::auto_ptr_ref<Base>, () _PTR_THROWS (()));
|
||||
|
||||
FUN (std::auto_ptr<Base>, Derived,
|
||||
operator std::auto_ptr<Base>, () _PTR_THROWS (()));
|
||||
|
||||
# endif // MSVC > 7.1
|
||||
|
||||
# endif // SunPro > 5.4
|
||||
|
||||
# endif // HP aCC > 5
|
||||
|
||||
# endif // gcc > 3.2
|
||||
|
||||
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
||||
|
||||
rw_info (0, 0, 0, "[lib.auto.ptr.cons]");
|
||||
|
||||
T *pt = new T ();
|
||||
|
||||
// 20.4.5.1, p1
|
||||
std::auto_ptr<T> ap1 (pt);
|
||||
rw_assert (pt == ap1.get (), 0, __LINE__,
|
||||
"auto_ptr<%s>::auto_ptr (%1$s*)", tname);
|
||||
|
||||
// 20.4.5.1, p2
|
||||
std::auto_ptr<T> ap2 (ap1);
|
||||
rw_assert (0 == ap1.get (), 0, __LINE__,
|
||||
"auto_ptr<%s>::auto_ptr (auto_ptr&", tname);
|
||||
rw_assert (pt == ap2.get (), 0, __LINE__,
|
||||
"auto_ptr<%s>::auto_ptr (auto_ptr&)", tname);
|
||||
|
||||
// 20.4.5.1, p7, 8, 9
|
||||
ap1 = ap2;
|
||||
rw_assert (0 == ap2.get (), 0, __LINE__,
|
||||
"auto_ptr<%s>::operator= (auto_ptr&)", tname);
|
||||
rw_assert (pt == ap1.get (), 0, __LINE__,
|
||||
"auto_ptr<%s>::operator= (auto_ptr&)", tname);
|
||||
|
||||
|
||||
rw_info (0, 0, 0, "[lib.auto.ptr.members]");
|
||||
|
||||
// 20.4.5.2, p2
|
||||
rw_assert (*ap1.get () == ap1.operator*(), 0, __LINE__,
|
||||
"auto_ptr<%s>::operator*()", tname);
|
||||
|
||||
// 20.4.5.2, p3
|
||||
rw_assert (ap1.get () == ap1.operator->(), 0, __LINE__,
|
||||
"auto_ptr<%s>::operator->()", tname);
|
||||
|
||||
// 20.4.5.2, p4
|
||||
rw_assert (pt == ap1.get (), 0, __LINE__,
|
||||
"auto_ptr<%s>::get ()", tname);
|
||||
|
||||
// 20.4.5.2, p5, 6
|
||||
rw_assert (pt == ap1.release () && 0 == ap1.get (), 0, __LINE__,
|
||||
"auto_ptr<%s>::release ()", tname);
|
||||
|
||||
|
||||
// 20.4.5.2, p7
|
||||
ap1.reset (pt);
|
||||
rw_assert (pt == ap1.get (), 0, __LINE__,
|
||||
"auto_ptr<%s>::reset ()", tname);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static void
|
||||
test_auto_ptr_void ()
|
||||
{
|
||||
// note that specializing auto_ptr on void is undefined
|
||||
// due to 17.4.3.6, p2; this is an extension of this
|
||||
// implementation
|
||||
rw_info (0, 0, 0, "std::auto_ptr<void> [extension]");
|
||||
|
||||
std::auto_ptr<void> ap1;
|
||||
std::auto_ptr<void> ap2 ((void*)0);
|
||||
std::auto_ptr<void> ap3 (ap2);
|
||||
|
||||
ap1 = ap1;
|
||||
ap1.operator= (ap1);
|
||||
|
||||
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
||||
|
||||
# if !defined (__HP_aCC) || 6 <= _RWSTD_HP_aCC_MAJOR
|
||||
|
||||
// working around an HP aCC 3 and 5 bug (STDCXX-655)
|
||||
|
||||
ap1.operator=<void>(ap1);
|
||||
|
||||
# endif // !HP aCC or HP aCC 6 and better
|
||||
|
||||
std::auto_ptr<int> ap4;
|
||||
ap1 = ap4;
|
||||
ap1.operator= (ap4);
|
||||
ap1.operator=<int>(ap4);
|
||||
|
||||
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
||||
|
||||
// operator*() cannot be instantiated
|
||||
|
||||
void* pv;
|
||||
|
||||
pv = ap1.operator->();
|
||||
pv = ap1.get ();
|
||||
pv = ap1.release ();
|
||||
|
||||
ap1.reset ();
|
||||
ap1.reset (pv);
|
||||
|
||||
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
||||
|
||||
# if !defined (__HP_aCC) || 6 <= _RWSTD_HP_aCC_MAJOR
|
||||
|
||||
// working around an HP aCC 3 and 5 bug (STDCXX-656)
|
||||
|
||||
const std::auto_ptr_ref<void> ar = ap1.operator std::auto_ptr_ref<void>();
|
||||
const std::auto_ptr<void> ap5 = ap1.operator std::auto_ptr<void>();
|
||||
|
||||
_RWSTD_UNUSED (ar);
|
||||
_RWSTD_UNUSED (ap5);
|
||||
|
||||
# endif // !HP aCC or HP aCC 6 and better
|
||||
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
||||
|
||||
// exercise 20.4.5.4
|
||||
static std::auto_ptr<Derived>
|
||||
test_auto_ptr_conversions ()
|
||||
{
|
||||
rw_info (0, 0, 0, "[lib.auto.ptr.conv]");
|
||||
|
||||
// 20.4.5.1, p4, 5, 6
|
||||
Derived *pd = new Derived;
|
||||
std::auto_ptr<Derived> ap1 (pd);
|
||||
rw_assert (pd == ap1.get (), 0, __LINE__,
|
||||
"auto_ptr::auto_ptr ()");
|
||||
|
||||
std::auto_ptr<Base> ap2 (ap1);
|
||||
|
||||
rw_assert (0 == ap1.get (), 0, __LINE__,
|
||||
"auto_ptr<Base>::auto_ptr(auto_ptr<Derived>&)");
|
||||
rw_assert (_RWSTD_STATIC_CAST (Base*, pd) == ap2.get (), 0, __LINE__,
|
||||
"auto_ptr<Base>::auto_ptr(auto_ptr<Derived>&)");
|
||||
|
||||
ap2.reset (pd);
|
||||
|
||||
// 20.4.5.2, p7 - must not delete owning pointer
|
||||
ap2.reset (pd);
|
||||
rw_assert (pd == ap2.get (), 0, __LINE__, "auto_ptr::reset ()");
|
||||
|
||||
pd = new Derived;
|
||||
ap2.reset (pd); // must delete owning pointer
|
||||
rw_assert (pd == ap2.get (), 0, __LINE__, "auto_ptr::reset ()");
|
||||
|
||||
// 20.4.5.3, p1, 2, 3 - creates an auto_ptr_ref
|
||||
pd = new Derived;
|
||||
std::auto_ptr<Base> ap3 =
|
||||
std::auto_ptr<Base>(std::auto_ptr<Derived>(pd));
|
||||
|
||||
rw_assert ((Base*)pd == ap3.get (), 0, __LINE__,
|
||||
"auto_ptr<>::auto_ptr(std::auto_ptr_ref)");
|
||||
|
||||
#if !defined (__HP_aCC) || _RWSTD_HP_aCC_MAJOR > 5
|
||||
|
||||
pd = new Derived;
|
||||
std::auto_ptr<Derived> ap4 (pd);
|
||||
ap3 = std::auto_ptr<Base> (ap4);
|
||||
|
||||
rw_assert (0 == ap4.get () && (Base*)pd == ap3.get (), 0, __LINE__,
|
||||
"auto_ptr<>::operator auto_ptr<>()");
|
||||
|
||||
#endif // HP aCC > 5
|
||||
|
||||
{
|
||||
// see CWG issue 84 for some background on the sequence below
|
||||
// http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html#84
|
||||
|
||||
std::auto_ptr<Derived> pd1 (Derived::source ());
|
||||
std::auto_ptr<Derived> pd2 (pd1);
|
||||
|
||||
#if !defined (__HP_aCC) || _RWSTD_HP_aCC_MAJOR > 5
|
||||
|
||||
Derived::sink (Derived::source ());
|
||||
|
||||
#endif // HP aCC > 5
|
||||
|
||||
pd1 = pd2;
|
||||
pd1 = Derived::source();
|
||||
std::auto_ptr<Base> pb1 (Derived::source ());
|
||||
std::auto_ptr<Base> pb2 (pd1);
|
||||
|
||||
// conversion sequence:
|
||||
// 1. auto_ptr<Derived>::operator auto_ptr<Base>() [UDC]
|
||||
// 2. auto_ptr<Base>::operator auto_ptr_ref<Base>() [UDC]
|
||||
// 3. auto_ptr<Base>(auto_ptr_ref<Base>) [UDC]
|
||||
|
||||
// since the conversion sequence involves more than one UDC
|
||||
// (User-Defined Conversion), it is illegal
|
||||
// Base::sink (Derived::source ());
|
||||
|
||||
pb1 = pd2;
|
||||
pb1 = Derived::source ();
|
||||
|
||||
return pd1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int rw_opt_no_conversions; // for --no-conversions
|
||||
|
||||
|
||||
static int
|
||||
run_test (int, char**)
|
||||
{
|
||||
|
||||
#ifndef _RWSTD_NO_NATIVE_BOOL
|
||||
|
||||
test_auto_ptr ((bool*)0, "bool");
|
||||
|
||||
#endif // _RWSTD_NO_NATIVE_BOOL
|
||||
|
||||
test_auto_ptr ((char*)0, "char");
|
||||
test_auto_ptr ((int*)0, "int");
|
||||
test_auto_ptr ((double*)0, "double");
|
||||
test_auto_ptr ((void**)0, "void*");
|
||||
|
||||
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
||||
|
||||
int count = Base::cnt_;
|
||||
|
||||
// exercise 20.4.5.4
|
||||
if (rw_opt_no_conversions)
|
||||
rw_note (0, 0, 0, "conversions test disabled");
|
||||
else
|
||||
test_auto_ptr_conversions ();
|
||||
|
||||
// verify that no objects leaked
|
||||
rw_assert (count == Base::cnt_, 0, __LINE__,
|
||||
"autoptr leaked %d objects", Base::cnt_ - count);
|
||||
|
||||
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
||||
|
||||
if (!rw_enabled ("void"))
|
||||
rw_note (0, 0, 0, "auto_ptr<void> test disabled");
|
||||
else
|
||||
test_auto_ptr_void ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"lib.auto.ptr",
|
||||
0 /* no comment */,
|
||||
run_test,
|
||||
"|-no-conversions#",
|
||||
&rw_opt_no_conversions,
|
||||
(void*)0 /* sentinel */);
|
||||
}
|
||||
870
extern/stdcxx/4.2.1/tests/utilities/20.function.objects.cpp
vendored
Normal file
870
extern/stdcxx/4.2.1/tests/utilities/20.function.objects.cpp
vendored
Normal file
@@ -0,0 +1,870 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 20.function.objects.cpp - test exercising [lib.std.function_objects]
|
||||
*
|
||||
* $Id: 20.function.objects.cpp 426701 2006-07-28 23:19:41Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2000-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <functional>
|
||||
#include <driver.h>
|
||||
|
||||
#if defined (__HP_aCC) && _RWSTD_HP_aCC_MAJOR < 6
|
||||
|
||||
// working around an HP aCC bug (see PR #25378)
|
||||
# include <string>
|
||||
|
||||
// working around an HP aCC bug (see PR #24417)
|
||||
_USING (namespace std);
|
||||
|
||||
#endif // HP aCC < 6
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// shut up the idiotic MSVC 6.0 warning C4099:
|
||||
// type name first seen using 'struct' now seen using 'class'
|
||||
# pragma warning (disable: 4099)
|
||||
|
||||
// another bogus warning C4700:
|
||||
// local variable used without having been initialized
|
||||
# pragma warning (disable: 4700)
|
||||
|
||||
# if _MSC_VER <= 1300
|
||||
// work around a bug where the compiler thinks that what's a struct
|
||||
// is really a class with all private members (PR #23795)
|
||||
# define class struct
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _RWSTD_EXPLICIT_INSTANTIATION
|
||||
|
||||
// explicitly instantiate
|
||||
|
||||
# if !defined (_RWSTD_NO_NAMESPACE) && !defined (_RWSTD_NO_HONOR_STD) \
|
||||
&& (!defined (_COMPILER_VERSION) || _COMPILER_VERSION > 730) \
|
||||
&& (!defined (__EDG_VERSION__) || __EDG_VERSION__ > 244)
|
||||
|
||||
// work around an EDG front end bug (see, for example, PR #25292)
|
||||
|
||||
// verify that names are declared [only] in namespace std
|
||||
|
||||
# define TEST_CLASS_DEF(name, Tparam) \
|
||||
template class std::name Tparam; \
|
||||
void name (void *name)
|
||||
# define TEST_CLASS_DEF_2(name, Tparam1, Tparam2) \
|
||||
template class std::name Tparam1, Tparam2; \
|
||||
void name (void *name)
|
||||
# define TEST_CLASS_DEF_3(name, Tparam1, Tparam2, Tparam3) \
|
||||
template class std::name Tparam1, Tparam2, Tparam3; \
|
||||
void name (void *name)
|
||||
|
||||
# else // if defined (_RWSTD_NO_NAMESPACE) || defined (_RWSTD_NO_HONOR_STD)
|
||||
|
||||
// verify that names do not collide with function argument names
|
||||
|
||||
# define TEST_CLASS_DEF(name, Tparam) \
|
||||
template class std::name Tparam; \
|
||||
void foo (void *name)
|
||||
# define TEST_CLASS_DEF_2(name, Tparam1, Tparam2) \
|
||||
template class std::name Tparam1, Tparam2; \
|
||||
void foo (void *name)
|
||||
# define TEST_CLASS_DEF_3(name, Tparam1, Tparam2, Tparam3) \
|
||||
template class std::name Tparam1, Tparam2, Tparam3; \
|
||||
void foo (void *name)
|
||||
# endif // !_RWSTD_NO_NAMESPACE && !_RWSTD_NO_HONOR_STD
|
||||
|
||||
# if defined __GNUG__ && __GNUG__ < 3 && __GNU_MINOR__ < 96
|
||||
|
||||
// working around a bug in g++ 2.95.2 (PR #23151)
|
||||
# define TEST_FUNCTION_DEF(decl) \
|
||||
_RWSTD_NAMESPACE (std) { \
|
||||
template decl; \
|
||||
} /* namespace std */ \
|
||||
typedef void unused_typedef
|
||||
# else
|
||||
# define TEST_FUNCTION_DEF(decl) template decl
|
||||
# endif
|
||||
|
||||
#else // if defined (_RWSTD_EXPLICIT_INSTANTIATION)
|
||||
|
||||
// classes will implicitly instantiated below
|
||||
|
||||
# if !defined (_RWSTD_NO_NAMESPACE) && !defined (_RWSTD_NO_HONOR_STD)
|
||||
|
||||
// verify that names are declared [only[ in namespace std
|
||||
|
||||
# define TEST_CLASS_DEF(name, ignore) void name (void *name)
|
||||
# define TEST_CLASS_DEF_2(name, ign1, ign2) void name (void *name)
|
||||
# define TEST_CLASS_DEF_3(name, ign1, ign2, ign3) void name (void *name)
|
||||
|
||||
# else // if defined (_RWSTD_NO_NAMESPACE) || defined (_RWSTD_NO_HONOR_STD)
|
||||
|
||||
# define TEST_CLASS_DEF(name, ignore) void foo (void *name)
|
||||
# define TEST_CLASS_DEF_2(name, ign1, ign2) void foo (void *name)
|
||||
# define TEST_CLASS_DEF_3(name, ign1, ign2, ign3) void foo (void *name)
|
||||
|
||||
# endif // !_RWSTD_NO_NAMESPACE && !_RWSTD_NO_HONOR_STD
|
||||
|
||||
# define TEST_FUNCTION_DEF(ignore) void unused_typedef
|
||||
|
||||
#endif // _RWSTD_EXPLICIT_INSTANTIATION
|
||||
|
||||
|
||||
TEST_CLASS_DEF_2 (unary_function, <int, int>);
|
||||
TEST_CLASS_DEF_3 (binary_function, <int, int, int>);
|
||||
|
||||
TEST_CLASS_DEF (plus, <int>);
|
||||
TEST_CLASS_DEF (minus, <int>);
|
||||
TEST_CLASS_DEF (multiplies, <int>);
|
||||
TEST_CLASS_DEF (divides, <int>);
|
||||
TEST_CLASS_DEF (modulus, <int>);
|
||||
TEST_CLASS_DEF (negate, <int>);
|
||||
|
||||
TEST_CLASS_DEF (equal_to, <int>);
|
||||
TEST_CLASS_DEF (not_equal_to, <int>);
|
||||
TEST_CLASS_DEF (greater, <int>);
|
||||
TEST_CLASS_DEF (less, <int>);
|
||||
TEST_CLASS_DEF (greater_equal, <int>);
|
||||
TEST_CLASS_DEF (less_equal, <int>);
|
||||
|
||||
TEST_CLASS_DEF (logical_and, <int>);
|
||||
TEST_CLASS_DEF (logical_or, <int>);
|
||||
TEST_CLASS_DEF (logical_not, <int>);
|
||||
|
||||
TEST_CLASS_DEF (unary_negate, <std::negate<int> >);
|
||||
|
||||
TEST_FUNCTION_DEF (
|
||||
std::unary_negate<std::negate<int> >
|
||||
std::not1 (const std::negate<int>&));
|
||||
|
||||
TEST_CLASS_DEF (binary_negate, <std::equal_to<int> >);
|
||||
|
||||
TEST_FUNCTION_DEF (
|
||||
std::binary_negate<std::equal_to<int> >
|
||||
std::not2 (const std::equal_to<int>&));
|
||||
|
||||
TEST_CLASS_DEF (binder1st, <std::plus<int> >);
|
||||
|
||||
TEST_FUNCTION_DEF (
|
||||
std::binder1st<std::plus<int> >
|
||||
std::bind1st (const std::plus<int>&, const int&));
|
||||
|
||||
TEST_CLASS_DEF (binder2nd , <std::plus<int> >);
|
||||
|
||||
TEST_FUNCTION_DEF (
|
||||
std::binder2nd<std::plus<int> >
|
||||
std::bind2nd (const std::plus<int>&, const int&));
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// exercise 20.3.1 [lib.base]
|
||||
static void
|
||||
test_base ()
|
||||
{
|
||||
rw_info (0, 0, __LINE__, "[lib.base]");
|
||||
|
||||
// verify that member types really are of the correct types
|
||||
std::unary_function<int, void>::argument_type *argument = (int*)0;
|
||||
std::unary_function<int, void>::result_type *result = (void*)0;
|
||||
|
||||
std::binary_function<int, char, void>::first_argument_type *a1 = (int*)0;
|
||||
std::binary_function<int, char, void>::second_argument_type *a2 = (char*)0;
|
||||
std::binary_function<int, char, void>::result_type *res = (void*)0;
|
||||
|
||||
_RWSTD_UNUSED (argument);
|
||||
_RWSTD_UNUSED (result);
|
||||
_RWSTD_UNUSED (a1);
|
||||
_RWSTD_UNUSED (a2);
|
||||
_RWSTD_UNUSED (res);
|
||||
}
|
||||
|
||||
|
||||
#define TEST_UNARY_OP(fun, op, x) do { \
|
||||
rw_info (0, 0, __LINE__, "std::" #fun); \
|
||||
N::fun f CTOR_ARG_LIST; \
|
||||
/* verify that fun is copy constructible and assignable */ \
|
||||
const N::fun f_cpy1 (f); \
|
||||
/* const to verify copy ctor const correctness */ \
|
||||
const N::fun f_cpy2 = f; \
|
||||
/* verify that fun publicly derives from unary_function */ \
|
||||
const std::unary_function<N::fun::argument_type, \
|
||||
N::fun::result_type> *pf = &f; \
|
||||
_RWSTD_UNUSED (pf); \
|
||||
/* verify member types and signature of operator () */ \
|
||||
typedef N::fun fun_t; /* in case fun contains commas */ \
|
||||
N::fun::result_type (N::fun::*pfun) \
|
||||
UNARY_OP_ARG_LIST (fun_t) const = &N::fun::operator(); \
|
||||
_RWSTD_UNUSED (pfun); \
|
||||
/* exercise operator() */ \
|
||||
rw_assert (f.operator() (x) == (op x), 0, __LINE__, \
|
||||
#fun "().operator()(%i) == %i, got %i", \
|
||||
x, (op x), f.operator()(x)); \
|
||||
/* exercise operator() of the two copies */ \
|
||||
rw_assert (f_cpy1.operator() (x) == (op x), 0, __LINE__, \
|
||||
#fun "::" #fun "(const " #fun "&)"); \
|
||||
rw_assert (f_cpy2.operator() (x) == (op x), 0, __LINE__, \
|
||||
#fun "::operator=" #fun "(const " #fun "&)"); \
|
||||
} while (0)
|
||||
|
||||
#define TEST_BINARY_OP(fun, op, x, y) do { \
|
||||
rw_info (0, 0, __LINE__, "std::" #fun); \
|
||||
N::fun f CTOR_ARG_LIST; \
|
||||
/* verify that fun is copy constructible and assignable */ \
|
||||
const N::fun f_cpy1 (f); \
|
||||
/* const to verify copy ctor const correctness */ \
|
||||
const N::fun f_cpy2 = f; \
|
||||
/* verify that fun publicly derives from binary_function */ \
|
||||
const std::binary_function<N::fun::first_argument_type, \
|
||||
N::fun::second_argument_type, \
|
||||
N::fun::result_type> *pf = &f; \
|
||||
_RWSTD_UNUSED (pf); \
|
||||
/* verify member types and signature of operator () */ \
|
||||
typedef N::fun fun_t; /* in case fun contains commas */ \
|
||||
N::fun::result_type (N::fun::*pfun) \
|
||||
BINARY_OP_ARG_LIST (fun_t) const = &N::fun::operator(); \
|
||||
_RWSTD_UNUSED (pfun); \
|
||||
rw_assert (f.operator() (x, y) == (x op y), 0, __LINE__, \
|
||||
#fun "().operator()(%i, %i) == %i, got %i", \
|
||||
x, y, (x op y), f.operator()(x, y)); \
|
||||
/* exercise operator() of the two copies */ \
|
||||
rw_assert (f_cpy1.operator() (x, y) == (x op y), 0, __LINE__, \
|
||||
#fun "::" #fun "(const " #fun "&)"); \
|
||||
rw_assert (f_cpy2.operator() (x, y) == (x op y), 0, __LINE__, \
|
||||
#fun "::operator=" #fun "(const " #fun "&)"); \
|
||||
} while (0)
|
||||
|
||||
|
||||
// tested fununctions are in namespace std
|
||||
#define N std
|
||||
|
||||
// most but not all operator() take arguments by const reference
|
||||
#define UNARY_OP_ARG_LIST(fun) (const fun::argument_type&)
|
||||
#define BINARY_OP_ARG_LIST(fun) \
|
||||
(const fun::first_argument_type&, const fun::second_argument_type&)
|
||||
|
||||
// use default ctor in tests below
|
||||
#define CTOR_ARG_LIST
|
||||
|
||||
// exercise 20.3.2 [lib.arithmetic.operations]
|
||||
static void
|
||||
test_arithmetic_operations ()
|
||||
{
|
||||
rw_info (0, 0, __LINE__, "[lib.arithmetic.operations]");
|
||||
|
||||
// 20.3.2, p2
|
||||
TEST_BINARY_OP (plus<int>, +, 1, 2);
|
||||
|
||||
// 20.3.2, p3
|
||||
TEST_BINARY_OP (minus<int>, -, 3, 2);
|
||||
|
||||
// 20.3.2, p4
|
||||
TEST_BINARY_OP (multiplies<int>, *, 2, 3);
|
||||
|
||||
// 20.3.2, p5
|
||||
TEST_BINARY_OP (divides<int>, /, 6, 3);
|
||||
|
||||
// 20.3.2, p6
|
||||
TEST_BINARY_OP (modulus<int>, %, 7, 3);
|
||||
|
||||
// 20.3.2, p7
|
||||
TEST_UNARY_OP (negate<int>, -, 1);
|
||||
|
||||
// exercise extensions
|
||||
|
||||
// tested fununctions are in a private namespace
|
||||
#undef N
|
||||
#define N _RW
|
||||
|
||||
TEST_UNARY_OP (identity<int>, +, 3);
|
||||
TEST_UNARY_OP (unary_plus<int>, +, 4);
|
||||
TEST_UNARY_OP (bitwise_complement<int>, ~, 5);
|
||||
|
||||
TEST_BINARY_OP (bitwise_and<int>, &, 0x0f, 0x05);
|
||||
TEST_BINARY_OP (bitwise_or<int>, |, 0x0f, 0xf0);
|
||||
TEST_BINARY_OP (exclusive_or<int>, ^, 0x0f, 0xf1);
|
||||
|
||||
TEST_BINARY_OP (shift_left<int>, <<, 3, 3);
|
||||
TEST_BINARY_OP (shift_right<int>, >>, 15, 3);
|
||||
|
||||
// remaining tested fununctions are in namespace std
|
||||
#undef N
|
||||
#define N std
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// exercise 20.3.3 [lib.comparisons]
|
||||
static void
|
||||
test_comparisons ()
|
||||
{
|
||||
rw_info (0, 0, __LINE__, "[lib.comparisons]");
|
||||
|
||||
// 20.3.3, p2
|
||||
TEST_BINARY_OP (equal_to<int>, ==, 1, 1);
|
||||
TEST_BINARY_OP (equal_to<double>, ==, 1.0, 2.0);
|
||||
|
||||
// 20.3.3, p3
|
||||
TEST_BINARY_OP (not_equal_to<int>, !=, 1, 1);
|
||||
TEST_BINARY_OP (not_equal_to<double>, !=, 1.0, 2.0);
|
||||
|
||||
// 20.3.3, p4
|
||||
TEST_BINARY_OP (greater<int>, >, 1, 1);
|
||||
TEST_BINARY_OP (greater<double>, >, 2.0, 1.0);
|
||||
|
||||
// 20.3.3, p5
|
||||
TEST_BINARY_OP (less<int>, <, 1, 1);
|
||||
TEST_BINARY_OP (less<double>, <, 1.0, 2.0);
|
||||
|
||||
// 20.3.3, p6
|
||||
TEST_BINARY_OP (greater_equal<int>, >=, 1, 1);
|
||||
TEST_BINARY_OP (greater_equal<double>, >=, 1.0, 2.0);
|
||||
|
||||
// 20.3.3, p7
|
||||
TEST_BINARY_OP (less_equal<int>, <=, 1, 1);
|
||||
TEST_BINARY_OP (less_equal<double>, <=, 2.0, 1.0);
|
||||
|
||||
// 20.3.3, p8
|
||||
// ???
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// exercise 20.3.4 [lib.logical.operations]
|
||||
static void
|
||||
test_logical_operations ()
|
||||
{
|
||||
rw_info (0, 0, __LINE__, "[lib.logical.operations]");
|
||||
|
||||
// 20.3.4, p2
|
||||
TEST_BINARY_OP (logical_and<int>, &&, 0, 1);
|
||||
TEST_BINARY_OP (logical_and<double>, &&, 1.0, 2.0);
|
||||
|
||||
// 20.3.4, p3
|
||||
TEST_BINARY_OP (logical_or<char>, ||, '\0', '\0');
|
||||
TEST_BINARY_OP (logical_or<int>, ||, 0, 1);
|
||||
TEST_BINARY_OP (logical_or<double>, ||, 1.0, 2.0);
|
||||
|
||||
// 20.3.4, p4
|
||||
TEST_UNARY_OP (logical_not<int>, !, 0);
|
||||
TEST_UNARY_OP (logical_not<double>, !, 2.0);
|
||||
}
|
||||
|
||||
|
||||
// helpers to verify that each class' ctor is explicit
|
||||
// not defined since they must not be referenced if test is successful
|
||||
void is_explicit (const std::unary_negate<std::logical_not<int> >&);
|
||||
void is_explicit (const std::binary_negate<std::equal_to<int> >&);
|
||||
void is_explicit (const std::pointer_to_unary_function<int, int>&);
|
||||
void is_explicit (const std::pointer_to_binary_function<int, int, int>&);
|
||||
|
||||
struct has_implicit_ctor
|
||||
{
|
||||
// NOT explicit
|
||||
has_implicit_ctor (const std::logical_not<int>&) { }
|
||||
has_implicit_ctor (const std::equal_to<int>&) { }
|
||||
|
||||
has_implicit_ctor (int (*)(int)) { }
|
||||
has_implicit_ctor (int (*)(int, int)) { }
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
void is_explicit (const has_implicit_ctor&) { }
|
||||
|
||||
|
||||
// exercise 20.3.5 [lib.negators]
|
||||
static void
|
||||
test_negators ()
|
||||
{
|
||||
rw_info (0, 0, __LINE__, "[lib.negators]");
|
||||
|
||||
#ifndef _RWSTD_NO_EXPLICIT
|
||||
|
||||
// verify that std::unary_negate<>() and std::binary_negate<>()
|
||||
// ctors are declared explicit
|
||||
is_explicit (std::logical_not<int>());
|
||||
|
||||
#endif // _RWSTD_NO_EXPLICIT
|
||||
|
||||
// use std::negate<> as an argument in negator ctors
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST \
|
||||
= std::unary_negate<std::logical_not<int> > (std::logical_not<int> ())
|
||||
|
||||
// 20.3.5, p2
|
||||
TEST_UNARY_OP (unary_negate<std::logical_not<int> >, !!, 0);
|
||||
TEST_UNARY_OP (unary_negate<std::logical_not<int> >, !!, 1);
|
||||
|
||||
// exercise the convenience function template std::not1()
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::not1 (std::logical_not<char> ())
|
||||
|
||||
// 20.3.5, p3
|
||||
TEST_UNARY_OP (unary_negate<std::logical_not<char> >, !!, '\0');
|
||||
TEST_UNARY_OP (unary_negate<std::logical_not<char> >, !!, '1');
|
||||
|
||||
// use std::equal_to<> as an argument in negator ctors
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST \
|
||||
= std::binary_negate<std::equal_to<double> > (std::equal_to<double> ())
|
||||
|
||||
// 20.3.5, p4
|
||||
TEST_BINARY_OP (binary_negate<std::equal_to<double> >, !=, 0.0, 1.0);
|
||||
TEST_BINARY_OP (binary_negate<std::equal_to<double> >, !=, 1.0, 2.0);
|
||||
|
||||
// use std::not_equal_to<> as an argument in negator ctors
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST \
|
||||
= std::binary_negate<std::not_equal_to<int> > (std::not_equal_to<int> ())
|
||||
|
||||
TEST_BINARY_OP (binary_negate<std::not_equal_to<int> >, ==, 0, 1);
|
||||
TEST_BINARY_OP (binary_negate<std::not_equal_to<int> >, ==, 1, 2);
|
||||
|
||||
// exercise the convenience function template std::not2()
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::not2 (std::equal_to<int> ())
|
||||
|
||||
// 20.3.5, p5
|
||||
TEST_BINARY_OP (binary_negate<std::equal_to<int> >, !=, 2, 2);
|
||||
TEST_BINARY_OP (binary_negate<std::equal_to<int> >, !=, 3, 4);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// exercise 20.3.6 [lib.binders]
|
||||
static void
|
||||
test_binders ()
|
||||
{
|
||||
rw_info (0, 0, __LINE__, "[lib.binders]");
|
||||
|
||||
// make sure the protected names `op' and `value' are accessible
|
||||
struct binder1st_derivative: std::binder1st<std::minus<int> > {
|
||||
|
||||
binder1st_derivative ()
|
||||
: std::binder1st<std::minus<int> >(std::minus<int> (), 0) {
|
||||
|
||||
// test protected access
|
||||
rw_assert (0 == op (value, value), 0, __LINE__,
|
||||
"binder1st<>::op");
|
||||
rw_assert (0 == operator()(value), 0, __LINE__,
|
||||
"binder1st<>::operator()");
|
||||
|
||||
value = 7;
|
||||
rw_assert (-7 == op (0, value), 0, __LINE__,
|
||||
"binder1st<>::value");
|
||||
rw_assert (7 == operator()(0), 0, __LINE__,
|
||||
"binder1st<>::operator()");
|
||||
}
|
||||
} b1st;
|
||||
|
||||
_RWSTD_UNUSED (b1st);
|
||||
|
||||
// make sure the protected names `op' and `value' are accessible
|
||||
struct binder2nd_derivative: std::binder2nd<std::minus<int> > {
|
||||
binder2nd_derivative ()
|
||||
: std::binder2nd<std::minus<int> >(std::minus<int> (), 0) {
|
||||
|
||||
// test protected access
|
||||
rw_assert (0 == op (value, value), 0, __LINE__,
|
||||
"binder2nd<>::op");
|
||||
rw_assert (0 == operator()(value), 0, __LINE__,
|
||||
"binder2nd<>::operator()");
|
||||
|
||||
value = 7;
|
||||
rw_assert (-7 == op (0, value), 0, __LINE__,
|
||||
"binder2nd<>::value");
|
||||
rw_assert (-7 == operator()(0), 0, __LINE__,
|
||||
"binder2nd<>::operator()");
|
||||
}
|
||||
} b2nd;
|
||||
|
||||
_RWSTD_UNUSED (b2nd);
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
|
||||
// broken out of the macro definition to work around
|
||||
// a bug in g++ 2.95.2 parser
|
||||
std::minus<int> obj_minus;
|
||||
|
||||
// use std::negate<> as an argument in negator ctors
|
||||
#define CTOR_ARG_LIST (obj_minus, 1)
|
||||
|
||||
// 20.3.6.1, p1 and p2
|
||||
TEST_UNARY_OP (binder1st<std::minus<int> >, 1 -, 0);
|
||||
TEST_UNARY_OP (binder1st<std::minus<int> >, 1 -, 1);
|
||||
|
||||
// 20.3.6.3, p1 and p2
|
||||
TEST_UNARY_OP (binder2nd<std::minus<int> >, -1 +, 0);
|
||||
TEST_UNARY_OP (binder2nd<std::minus<int> >, 1 -, 1);
|
||||
|
||||
// exercise the convenience function template std::bind1st<>()
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::bind1st (std::divides<int>(), 6)
|
||||
|
||||
// 20.3.6.2, p1
|
||||
TEST_UNARY_OP (binder1st<std::divides<int> >, 6 /, 3);
|
||||
TEST_UNARY_OP (binder1st<std::divides<int> >, 6 /, 2);
|
||||
|
||||
// exercise the convenience function template std::bind2nd<>()
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::bind2nd (std::plus<int>(), -2)
|
||||
|
||||
// 20.3.6.4, p1
|
||||
TEST_UNARY_OP (binder2nd<std::plus<int> >, -2 +, 0);
|
||||
TEST_UNARY_OP (binder2nd<std::plus<int> >, -2 +, 1);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// helpers to exercise pointer to function adapters
|
||||
int square (int i) { return i * i; }
|
||||
int shift (int i, int n) { return i << n; }
|
||||
|
||||
// exercise 20.3.7 [lib.function.pointer.adaptors]
|
||||
static void
|
||||
test_function_pointer_adaptors ()
|
||||
{
|
||||
rw_info (0, 0, __LINE__, "[lib.function.pointer.adaptors]");
|
||||
|
||||
#ifndef _RWSTD_NO_EXPLICIT
|
||||
|
||||
// verify that the pointer to function adapters' ctors are explicit
|
||||
is_explicit ((int (*)(int))0);
|
||||
is_explicit ((int (*)(int, int))0);
|
||||
|
||||
#endif // _RWSTD_NO_EXPLICIT
|
||||
|
||||
// initialize pointer_to_unary_function with the address of square
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST (&::square)
|
||||
|
||||
// operator() takes a value (as opposed to const reference)
|
||||
#undef UNARY_OP_ARG_LIST
|
||||
#define UNARY_OP_ARG_LIST(fun) (fun::argument_type)
|
||||
|
||||
#define pointer_to_unary_function_int pointer_to_unary_function<int, int>
|
||||
|
||||
// 20.3.7, p2
|
||||
TEST_UNARY_OP (pointer_to_unary_function_int, 4 *, 4);
|
||||
|
||||
// exercise the convenience function template ptr_fun()
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::ptr_fun (&::square)
|
||||
|
||||
// 20.3.7, p3
|
||||
TEST_UNARY_OP (pointer_to_unary_function_int, 5 *, 5);
|
||||
|
||||
// initialize pointer_to_binary_function with the address of shift
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST (&::shift)
|
||||
|
||||
// operator() takes values (as opposed to const references)
|
||||
#undef BINARY_OP_ARG_LIST
|
||||
#define BINARY_OP_ARG_LIST(fun) \
|
||||
(fun::first_argument_type, fun::second_argument_type)
|
||||
|
||||
#define pointer_to_binary_function_int pointer_to_binary_function<int, int, int>
|
||||
|
||||
// 20.3.7, p4
|
||||
TEST_BINARY_OP (pointer_to_binary_function_int, <<, 1, 4);
|
||||
|
||||
// exercise the convenience function template ptr_fun()
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::ptr_fun (&::shift)
|
||||
|
||||
// 20.3.7, p5
|
||||
TEST_BINARY_OP (pointer_to_binary_function_int, <<, 2, 5);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
struct Integer
|
||||
{
|
||||
int i_;
|
||||
|
||||
// for convenience
|
||||
operator int () const { return i_; }
|
||||
|
||||
// non-const members
|
||||
int square () { return i_ * i_; }
|
||||
int div (short n) { return i_ / n; }
|
||||
|
||||
// const versions of the above members
|
||||
int const_square () const { return i_ * i_; }
|
||||
int const_div (short n) const { return i_ / n; }
|
||||
};
|
||||
|
||||
|
||||
// helper to verify that each class' ctor is explicit
|
||||
// not defined since they must not be referenced if test is successful
|
||||
void is_explicit (const std::mem_fun_t<int, Integer>&);
|
||||
|
||||
struct has_implicit_ctor_from_member
|
||||
{
|
||||
// NOT explicit
|
||||
has_implicit_ctor_from_member (int (Integer::*)()) { }
|
||||
has_implicit_ctor_from_member (int (Integer::*)(short)) { }
|
||||
|
||||
has_implicit_ctor_from_member (int (Integer::*)() const) { }
|
||||
has_implicit_ctor_from_member (int (Integer::*)(short) const) { }
|
||||
};
|
||||
|
||||
void is_explicit (const has_implicit_ctor_from_member&) { }
|
||||
|
||||
|
||||
// exercise 20.3.8 [lib.member.pointer.adaptors]
|
||||
static void
|
||||
test_member_pointer_adaptors ()
|
||||
{
|
||||
rw_info (0, 0, __LINE__, "[lib.member.pointer.adaptors]");
|
||||
|
||||
#ifndef _RWSTD_NO_EXPLICIT
|
||||
|
||||
// verify that the pointer to member adapters' ctors are explicit
|
||||
is_explicit ((int (Integer::*)())0);
|
||||
is_explicit ((int (Integer::*)(short))0);
|
||||
is_explicit ((int (Integer::*)() const)0);
|
||||
is_explicit ((int (Integer::*)(short) const)0);
|
||||
|
||||
#endif // _RWSTD_NO_EXPLICIT
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST (&Integer::square)
|
||||
|
||||
#define mem_fun_t_Integer_int mem_fun_t<int, Integer>
|
||||
|
||||
Integer int_obj = { 5 };
|
||||
|
||||
// 20.3.8, p2
|
||||
TEST_UNARY_OP (mem_fun_t_Integer_int, 5 * (int)*, &int_obj);
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::mem_fun (&Integer::square)
|
||||
|
||||
int_obj.i_ = 7;
|
||||
|
||||
// 20.3.8, p4
|
||||
TEST_UNARY_OP (mem_fun_t_Integer_int, 7 * (int)*, &int_obj);
|
||||
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST (&Integer::div)
|
||||
|
||||
#define mem_fun1_t_int_Integer_short mem_fun1_t<int, Integer, short>
|
||||
|
||||
// 20.3.8, p3
|
||||
TEST_BINARY_OP (mem_fun1_t_int_Integer_short, ->operator int() /,
|
||||
(&int_obj), 2);
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::mem_fun (&Integer::div)
|
||||
|
||||
// 20.3.8, p4
|
||||
TEST_BINARY_OP (mem_fun1_t_int_Integer_short, ->operator int() / ,
|
||||
(&int_obj), -1);
|
||||
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST (&Integer::square)
|
||||
|
||||
// operator() takes a reference (as opposed to const reference or value)
|
||||
#undef UNARY_OP_ARG_LIST
|
||||
#define UNARY_OP_ARG_LIST(fun) (fun::argument_type&)
|
||||
|
||||
#define mem_fun_ref_t_Integer_int mem_fun_ref_t<int, Integer>
|
||||
|
||||
int_obj.i_ = -9;
|
||||
|
||||
// 20.3.8, p5
|
||||
TEST_UNARY_OP (mem_fun_ref_t_Integer_int, -9 * (int), int_obj);
|
||||
|
||||
// exercise the convenience function template mem_fun_ref()
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::mem_fun_ref (&Integer::square)
|
||||
|
||||
// 20.3.8, p7
|
||||
TEST_UNARY_OP (mem_fun_ref_t_Integer_int, -9 * (int), int_obj);
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST (&Integer::div)
|
||||
|
||||
// operator() takes a reference and a value
|
||||
#undef BINARY_OP_ARG_LIST
|
||||
#define BINARY_OP_ARG_LIST(fun) \
|
||||
(fun::first_argument_type&, fun::second_argument_type)
|
||||
|
||||
#define mem_fun1_ref_t_int_Integer_short mem_fun1_ref_t<int, Integer, short>
|
||||
|
||||
// 20.3.8, p6
|
||||
TEST_BINARY_OP (mem_fun1_ref_t_int_Integer_short, .operator int() /,
|
||||
int_obj, 3);
|
||||
|
||||
// exercise the convenience function template mem_fun_ref()
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::mem_fun_ref (&Integer::div)
|
||||
|
||||
// 20.3.8, p7
|
||||
TEST_BINARY_OP (mem_fun1_ref_t_int_Integer_short, .operator int() /,
|
||||
int_obj, 3);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST (&Integer::const_square)
|
||||
|
||||
// operator() takes a const reference (as opposed to reference or value)
|
||||
#undef UNARY_OP_ARG_LIST
|
||||
#define UNARY_OP_ARG_LIST(fun) (fun::argument_type)
|
||||
|
||||
#define const_mem_fun_t_Integer_int const_mem_fun_t<int, Integer>
|
||||
|
||||
int_obj.i_ = 5;
|
||||
|
||||
// verify const-correctness
|
||||
const Integer &int_cref = int_obj;
|
||||
|
||||
// 20.3.8, p2
|
||||
TEST_UNARY_OP (const_mem_fun_t_Integer_int, 5 * (int)*, &int_cref);
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::mem_fun (&Integer::const_square)
|
||||
|
||||
int_obj.i_ = 7;
|
||||
|
||||
// 20.3.8, p4
|
||||
TEST_UNARY_OP (const_mem_fun_t_Integer_int, 7 * (int)*, &int_cref);
|
||||
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST (&Integer::const_div)
|
||||
|
||||
// operator() takes a const value and a value
|
||||
#undef BINARY_OP_ARG_LIST
|
||||
#define BINARY_OP_ARG_LIST(fun) \
|
||||
(fun::first_argument_type, fun::second_argument_type)
|
||||
|
||||
#define const_mem_fun1_t_int_Integer_short \
|
||||
const_mem_fun1_t<int, Integer, short>
|
||||
|
||||
// 20.3.8, p3
|
||||
TEST_BINARY_OP (const_mem_fun1_t_int_Integer_short, ->operator int() /,
|
||||
(&int_cref), 2);
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::mem_fun (&Integer::const_div)
|
||||
|
||||
// 20.3.8, p4
|
||||
TEST_BINARY_OP (const_mem_fun1_t_int_Integer_short, ->operator int() / ,
|
||||
(&int_cref), -1);
|
||||
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST (&Integer::const_square)
|
||||
|
||||
// operator() takes a reference (as opposed to const reference or value)
|
||||
#undef UNARY_OP_ARG_LIST
|
||||
#define UNARY_OP_ARG_LIST(fun) (const fun::argument_type&)
|
||||
|
||||
#define const_mem_fun_ref_t_Integer_int const_mem_fun_ref_t<int, Integer>
|
||||
|
||||
int_obj.i_ = -9;
|
||||
|
||||
// 20.3.8, p5
|
||||
TEST_UNARY_OP (const_mem_fun_ref_t_Integer_int, -9 * (int), int_cref);
|
||||
|
||||
// exercise the convenience function template const_mem_fun_ref()
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::mem_fun_ref (&Integer::const_square)
|
||||
|
||||
// 20.3.8, p7
|
||||
TEST_UNARY_OP (const_mem_fun_ref_t_Integer_int, -9 * (int), int_cref);
|
||||
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST (&Integer::const_div)
|
||||
|
||||
// operator() takes a const reference and a value
|
||||
#undef BINARY_OP_ARG_LIST
|
||||
#define BINARY_OP_ARG_LIST(fun) \
|
||||
(const fun::first_argument_type&, fun::second_argument_type)
|
||||
|
||||
#define const_mem_fun1_ref_t_int_Integer_short \
|
||||
const_mem_fun1_ref_t<int, Integer, short>
|
||||
|
||||
// 20.3.8, p6
|
||||
TEST_BINARY_OP (const_mem_fun1_ref_t_int_Integer_short, .operator int() /,
|
||||
int_cref, 3);
|
||||
|
||||
// exercise the convenience function template const_mem_fun_ref()
|
||||
#undef CTOR_ARG_LIST
|
||||
#define CTOR_ARG_LIST = std::mem_fun_ref (&Integer::const_div)
|
||||
|
||||
// 20.3.8, p7
|
||||
TEST_BINARY_OP (const_mem_fun1_ref_t_int_Integer_short, .operator int() /,
|
||||
int_cref, 3);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char**)
|
||||
{
|
||||
// exercise 20.3.1 [lib.base]
|
||||
test_base ();
|
||||
|
||||
// exercise 20.3.2 [lib.arithmetic.operations]
|
||||
test_arithmetic_operations ();
|
||||
|
||||
// exercise 20.3.3 [lib.comparisons]
|
||||
test_comparisons ();
|
||||
|
||||
// exercise 20.3.4 [lib.logical.operations]
|
||||
test_logical_operations ();
|
||||
|
||||
// exercise 20.3.5 [lib.negators]
|
||||
test_negators ();
|
||||
|
||||
// exercise 20.3.6 [lib.binders]
|
||||
test_binders ();
|
||||
|
||||
// exercise 20.3.7 [lib.function.pointer.adaptors]
|
||||
test_function_pointer_adaptors ();
|
||||
|
||||
// exercise 20.3.8 [lib.member.pointer.adaptors]
|
||||
test_member_pointer_adaptors ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"lib.std.function_objects",
|
||||
0 /* no comment */,
|
||||
run_test,
|
||||
"",
|
||||
(void*)0 /* sentinel */);
|
||||
}
|
||||
525
extern/stdcxx/4.2.1/tests/utilities/20.operators.cpp
vendored
Normal file
525
extern/stdcxx/4.2.1/tests/utilities/20.operators.cpp
vendored
Normal file
@@ -0,0 +1,525 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 20.operators.cpp - test exercising [lib.operators]
|
||||
*
|
||||
* $Id: 20.operators.cpp 448928 2006-09-22 13:43:18Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 1994-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
// The test exercises the ability to specialize various components of
|
||||
// the library (algorithms and containers in particular) on user-defined
|
||||
// iterator types in the presence of using directives.
|
||||
|
||||
#include <rw/_config.h>
|
||||
|
||||
#if defined (__IBMCPP__) && !defined (_RWSTD_NO_IMPLICIT_INCLUSION)
|
||||
// Disable implicit inclusion to work around
|
||||
// a limitation in IBM's VisualAge 5.0.2.0 (see PR#26959)
|
||||
|
||||
# define _RWSTD_NO_IMPLICIT_INCLUSION
|
||||
#endif
|
||||
|
||||
#if 0 // def _MSC_VER
|
||||
// disabled (warnings may be meaningful)
|
||||
# pragma warning (disable: 4800)
|
||||
# pragma warning (disable: 4805)
|
||||
#endif // _MSC_VER
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <cstddef> // for std::size_t
|
||||
|
||||
#include <driver.h>
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
_USING (namespace std);
|
||||
_USING (namespace std::rel_ops);
|
||||
|
||||
|
||||
#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
|
||||
|
||||
// explicitly instantiate containers
|
||||
template class
|
||||
std::deque<int, std::allocator<int> >;
|
||||
|
||||
template class
|
||||
std::list<int,std::allocator<int> >;
|
||||
|
||||
template class
|
||||
std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >;
|
||||
|
||||
template class
|
||||
std::set<int>;
|
||||
|
||||
template class
|
||||
std::basic_string<int, std::char_traits<int>, std::allocator<int> >;
|
||||
|
||||
template class
|
||||
std::vector<int, std::allocator<int> >;
|
||||
|
||||
#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#if !defined (__SUNPRO_CC) || __SUNPRO_CC > 0x530
|
||||
# define FUN(ignore, result, name, arg_list) do { \
|
||||
result (*pf) arg_list = &name; \
|
||||
_RWSTD_UNUSED (pf); \
|
||||
} while (0)
|
||||
#else
|
||||
// working around a SunPro 5.3 bug (see PR #25972) that prevents it
|
||||
// from taking the address of a function template in template code
|
||||
# define FUN(T, result, name, arg_list) do { \
|
||||
typedef typename T::iterator Iterator; \
|
||||
typedef typename T::const_iterator ConstIterator; \
|
||||
const Iterator *pi = 0; \
|
||||
const ConstIterator *pci = 0; \
|
||||
name (pi, pi); \
|
||||
name (pci, pci); \
|
||||
} while (0)
|
||||
#endif // SunPro 5.3
|
||||
|
||||
|
||||
#define TEST_INEQUALITY(T) \
|
||||
FUN (T, bool, std::rel_ops::operator!=, \
|
||||
(const T::iterator&, const T::iterator&)); \
|
||||
FUN (T, bool, std::rel_ops::operator!=, \
|
||||
(const T::const_iterator&, const T::const_iterator&))
|
||||
|
||||
#define TEST_OPERATORS(T) \
|
||||
TEST_INEQUALITY (T); \
|
||||
FUN (T, bool, std::rel_ops::operator>, \
|
||||
(const T::iterator&, const T::iterator&)); \
|
||||
FUN (T, bool, std::rel_ops::operator<=, \
|
||||
(const T::iterator&, const T::iterator&)); \
|
||||
FUN (T, bool, std::rel_ops::operator>=, \
|
||||
(const T::iterator&, const T::iterator&)); \
|
||||
FUN (T, bool, std::rel_ops::operator>, \
|
||||
(const T::const_iterator&, const T::const_iterator&)); \
|
||||
FUN (T, bool, std::rel_ops::operator<=, \
|
||||
(const T::const_iterator&, const T::const_iterator&)); \
|
||||
FUN (T, bool, std::rel_ops::operator>=, \
|
||||
(const T::const_iterator&, const T::const_iterator&))
|
||||
|
||||
|
||||
template <class Container, class RandomAccessIterator>
|
||||
void test_iterator (Container, RandomAccessIterator)
|
||||
{
|
||||
TEST_OPERATORS (typename Container);
|
||||
}
|
||||
|
||||
|
||||
template <class Container>
|
||||
void test_iterator (Container, int*)
|
||||
{
|
||||
// cannot specialize std::rel_ops::operators on native types
|
||||
// or pointers to such things
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
struct UnaryPredicate
|
||||
{
|
||||
bool operator() (const T&) const {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct BinaryPredicate
|
||||
{
|
||||
bool operator() (const T&, const T&) const {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct RandomNumberGenerator
|
||||
{
|
||||
T operator() (int) const {
|
||||
return T ();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct Generator
|
||||
{
|
||||
T operator() () const {
|
||||
return T ();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct UnaryFunction
|
||||
{
|
||||
T operator() (const T &t) const {
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct BinaryFunction
|
||||
{
|
||||
T operator() (const T &t, const T&) const {
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T, class InputIterator>
|
||||
void test_input_iterators (T, InputIterator)
|
||||
{
|
||||
// do not run (compile only), prevent warnings about unreachable code
|
||||
static int count = 0;
|
||||
|
||||
if (++count)
|
||||
return;
|
||||
|
||||
typedef InputIterator I;
|
||||
|
||||
std::for_each (I (), I (), UnaryFunction<T>());
|
||||
std::find (I (), I (), T ());
|
||||
std::find_if (I (), I (), UnaryPredicate<T>());
|
||||
|
||||
#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
|
||||
std::count (I (), I (), T ());
|
||||
std::count_if (I (), I (), UnaryPredicate<T>());
|
||||
#else // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
|
||||
std::size_t n = 0;
|
||||
std::count (I (), I (), T (), n);
|
||||
std::count_if (I (), I (), UnaryPredicate<T>(), n);
|
||||
#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
|
||||
|
||||
std::mismatch (I (), I (), I ());
|
||||
std::mismatch (I (), I (), I (), BinaryPredicate<T>());
|
||||
std::equal (I (), I (), I ());
|
||||
std::equal (I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::includes (I (), I (), I (), I ());
|
||||
std::includes (I (), I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::lexicographical_compare (I (), I (), I (), I ());
|
||||
std::lexicographical_compare (I (), I (), I (), I (), BinaryPredicate<T>());
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T, class OutputIterator>
|
||||
void test_output_iterators (T, OutputIterator)
|
||||
{
|
||||
// do not run (compile only), prevent warnings about unreachable code
|
||||
static int count = 0;
|
||||
|
||||
if (++count)
|
||||
return;
|
||||
|
||||
typedef OutputIterator I;
|
||||
|
||||
std::copy (I (), I (), I ());
|
||||
std::copy_backward (I (), I (), I ());
|
||||
|
||||
std::transform (I (), I (), I (), UnaryFunction<T>());
|
||||
std::transform (I (), I (), I (), I (), BinaryFunction<T>());
|
||||
|
||||
std::replace_copy (I (), I (), I (), T (), T ());
|
||||
std::replace_copy_if (I (), I (), I (), UnaryPredicate<T>(), T ());
|
||||
|
||||
std::merge (I (), I (), I (), I (), I ());
|
||||
std::merge (I (), I (), I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::set_union (I (), I (), I (), I (), I ());
|
||||
std::set_union (I (), I (), I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::set_intersection (I (), I (), I (), I (), I ());
|
||||
std::set_intersection (I (), I (), I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::set_difference (I (), I (), I (), I (), I ());
|
||||
std::set_difference (I (), I (), I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::set_symmetric_difference (I (), I (), I (), I (), I ());
|
||||
std::set_symmetric_difference (I (), I (), I (), I (), I (),
|
||||
BinaryPredicate<T>());
|
||||
|
||||
std::fill_n (I (), 0, T ());
|
||||
|
||||
std::generate_n (I (), 0, Generator<T>());
|
||||
|
||||
std::remove_copy (I (), I (), I (), T ());
|
||||
std::remove_copy_if (I (), I (), I (), UnaryPredicate<T>());
|
||||
|
||||
std::unique_copy (I (), I (), I ());
|
||||
std::unique_copy (I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::reverse_copy (I (), I (), I ());
|
||||
|
||||
std::rotate_copy (I (), I (), I (), I ());
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T, class ForwardIterator>
|
||||
void test_forward_iterators (T, ForwardIterator)
|
||||
{
|
||||
// do not run (compile only), prevent warnings about unreachable code
|
||||
static int count = 0;
|
||||
|
||||
if (++count)
|
||||
return;
|
||||
|
||||
typedef ForwardIterator I;
|
||||
|
||||
std::find_end (I (), I (), I (), I ());
|
||||
std::find_end (I (), I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::find_first_of (I (), I (), I (), I ());
|
||||
std::find_first_of (I (), I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::adjacent_find (I (), I ());
|
||||
std::adjacent_find (I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::search (I (), I (), I (), I ());
|
||||
std::search (I (), I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::search_n (I (), I (), 0, T ());
|
||||
std::search_n (I (), I (), 0, T (), BinaryPredicate<T>());
|
||||
|
||||
std::swap_ranges (I (), I (), I ());
|
||||
std::iter_swap (I (), I ());
|
||||
|
||||
std::replace (I (), I (), T (), T ());
|
||||
std::replace_if (I (), I (), UnaryPredicate<T>(), T ());
|
||||
|
||||
std::equal_range (I (), I (), T ());
|
||||
std::equal_range (I (), I (), T (), BinaryPredicate<T>());
|
||||
|
||||
std::binary_search (I (), I (), T ());
|
||||
std::binary_search (I (), I (), T (), BinaryPredicate<T>());
|
||||
|
||||
std::min_element (I (), I ());
|
||||
std::min_element (I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::max_element (I (), I ());
|
||||
std::max_element (I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::fill (I (), I (), T ());
|
||||
|
||||
std::generate (I (), I (), Generator<T>());
|
||||
|
||||
std::remove (I (), I (), T ());
|
||||
std::remove_if (I (), I (), UnaryPredicate<T>());
|
||||
|
||||
std::unique (I (), I ());
|
||||
std::unique (I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::reverse (I (), I ());
|
||||
|
||||
std::rotate (I (), I (), I ());
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T, class BidirectionalIterator>
|
||||
void test_bidirectional_iterators (T, BidirectionalIterator)
|
||||
{
|
||||
// do not run (compile only), prevent warnings about unreachable code
|
||||
static int count = 0;
|
||||
|
||||
if (++count)
|
||||
return;
|
||||
|
||||
typedef BidirectionalIterator I;
|
||||
|
||||
std::partition (I (), I (), UnaryPredicate<T>());
|
||||
std::stable_partition (I (), I (), UnaryPredicate<T>());
|
||||
|
||||
std::lower_bound (I (), I (), T ());
|
||||
std::lower_bound (I (), I (), T (), BinaryPredicate<T>());
|
||||
|
||||
std::upper_bound (I (), I (), T ());
|
||||
std::upper_bound (I (), I (), T (), BinaryPredicate<T>());
|
||||
|
||||
std::inplace_merge (I (), I (), I ());
|
||||
std::inplace_merge (I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::next_permutation (I (), I ());
|
||||
std::next_permutation (I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::prev_permutation (I (), I ());
|
||||
std::prev_permutation (I (), I (), BinaryPredicate<T>());
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T, class RandomAccessIterator>
|
||||
void test_random_access_iterators (T, RandomAccessIterator)
|
||||
{
|
||||
// do not run (compile only), prevent warnings about unreachable code
|
||||
static int count = 0;
|
||||
|
||||
if (++count)
|
||||
return;
|
||||
|
||||
typedef RandomAccessIterator I;
|
||||
|
||||
RandomNumberGenerator<T> rndgen;
|
||||
|
||||
std::random_shuffle (I (), I ());
|
||||
std::random_shuffle (I (), I (), rndgen);
|
||||
|
||||
std::sort (I (), I ());
|
||||
std::sort (I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::stable_sort (I (), I ());
|
||||
std::stable_sort (I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::partial_sort (I (), I (), I ());
|
||||
std::partial_sort (I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::partial_sort_copy (I (), I (), I (), I ());
|
||||
std::partial_sort_copy (I (), I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::nth_element (I (), I (), I ());
|
||||
std::nth_element (I (), I (), I (), BinaryPredicate<T>());
|
||||
|
||||
std::push_heap (I (), I (), BinaryPredicate<T>());
|
||||
std::pop_heap (I (), I (), BinaryPredicate<T>());
|
||||
std::make_heap (I (), I (), BinaryPredicate<T>());
|
||||
std::sort_heap (I (), I (), BinaryPredicate<T>());
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char**)
|
||||
{
|
||||
typedef std::map<int, int> Map;
|
||||
typedef std::multimap<int, int> MultiMap;
|
||||
|
||||
// verify that rel_ops operators can be instantiated
|
||||
// on iterators of the containers below
|
||||
TEST_OPERATORS (std::deque<int>);
|
||||
|
||||
TEST_INEQUALITY (std::list<int>);
|
||||
TEST_INEQUALITY (Map);
|
||||
TEST_INEQUALITY (MultiMap);
|
||||
TEST_INEQUALITY (std::set<int>);
|
||||
TEST_INEQUALITY (std::multiset<int>);
|
||||
|
||||
#if !defined (_MSC_VER) || _MSC_VER > 1300
|
||||
// prevent from testing with the braindead MSVC 6 and 7
|
||||
// as a workaround for compiler bugs (PR #16828, 22268)
|
||||
|
||||
// prevent attempts to specialize rel_ops operators on
|
||||
// native types (or pointers to such things)
|
||||
test_iterator (std::basic_string<int>(),
|
||||
std::basic_string<int>::iterator ());
|
||||
|
||||
test_iterator (std::vector<int>(),
|
||||
std::vector<int>::iterator ());
|
||||
#endif // MSVC > 7.0
|
||||
|
||||
TEST_OPERATORS (std::vector<bool>);
|
||||
|
||||
#define TEST_INPUT_ITERATORS(T) \
|
||||
test_input_iterators (T (), std::deque<T>::iterator ()); \
|
||||
test_input_iterators (T (), std::list<T>::iterator ()); \
|
||||
test_input_iterators (std::map<T, T>::value_type (), \
|
||||
std::map<T, T>::iterator ()); \
|
||||
test_input_iterators (std::multimap<T, T>::value_type (), \
|
||||
std::multimap<T, T>::iterator ()); \
|
||||
test_input_iterators (T (), std::set<T>::iterator ()); \
|
||||
test_input_iterators (T (), std::multiset<T, T>::iterator ()); \
|
||||
test_input_iterators (T (), std::basic_string<T>::iterator ()); \
|
||||
test_input_iterators (T (), std::vector<T>::iterator ())
|
||||
|
||||
#define TEST_OUTPUT_ITERATORS(T) \
|
||||
test_output_iterators (T (), std::deque<T>::iterator ()); \
|
||||
test_output_iterators (T (), std::list<T>::iterator ()); \
|
||||
test_output_iterators (T (), std::basic_string<T>::iterator ()); \
|
||||
test_output_iterators (T (), std::vector<T>::iterator ())
|
||||
|
||||
#define TEST_FORWARD_ITERATORS(T) \
|
||||
test_forward_iterators (T (), std::deque<T>::iterator ()); \
|
||||
test_forward_iterators (T (), std::list<T>::iterator ()); \
|
||||
test_forward_iterators (T (), std::basic_string<T>::iterator ()); \
|
||||
test_forward_iterators (T (), std::vector<T>::iterator ())
|
||||
|
||||
#define TEST_BIDIRECTIONAL_ITERATORS(T) \
|
||||
test_bidirectional_iterators (T (), std::deque<T>::iterator ()); \
|
||||
test_bidirectional_iterators (T (), std::list<T>::iterator ()); \
|
||||
test_bidirectional_iterators (T (), std::basic_string<T>::iterator ()); \
|
||||
test_bidirectional_iterators (T (), std::vector<T>::iterator ())
|
||||
|
||||
#define TEST_RANDOM_ACCESS_ITERATORS(T) \
|
||||
test_random_access_iterators (T (), std::deque<T>::iterator ()); \
|
||||
test_random_access_iterators (T (), std::basic_string<T>::iterator ()); \
|
||||
test_random_access_iterators (T (), std::vector<T>::iterator ()); \
|
||||
|
||||
// verify that algorithms can be specialized on container
|
||||
// iterators without causing ambiguities with rel_ops
|
||||
TEST_INPUT_ITERATORS (int);
|
||||
TEST_OUTPUT_ITERATORS (int);
|
||||
TEST_FORWARD_ITERATORS (int);
|
||||
TEST_BIDIRECTIONAL_ITERATORS (int);
|
||||
TEST_RANDOM_ACCESS_ITERATORS (int);
|
||||
|
||||
#if !defined (__HP_aCC) || _RWSTD_HP_aCC_MINOR > 3600
|
||||
|
||||
// working around an HP aCC bug (PR #28331)
|
||||
TEST_INPUT_ITERATORS (bool);
|
||||
TEST_OUTPUT_ITERATORS (bool);
|
||||
TEST_FORWARD_ITERATORS (bool);
|
||||
TEST_BIDIRECTIONAL_ITERATORS (bool);
|
||||
TEST_RANDOM_ACCESS_ITERATORS (bool);
|
||||
|
||||
#endif // HP aCC > x.36
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"lib.operators",
|
||||
"interactions with the rest of the implementation",
|
||||
run_test,
|
||||
0 /* no command line options */);
|
||||
}
|
||||
297
extern/stdcxx/4.2.1/tests/utilities/20.pairs.cpp
vendored
Normal file
297
extern/stdcxx/4.2.1/tests/utilities/20.pairs.cpp
vendored
Normal file
@@ -0,0 +1,297 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* pairs.cpp - test exercising [lib.pairs]
|
||||
*
|
||||
* $Id: 20.pairs.cpp 550991 2007-06-26 23:58:07Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <alg_test.h>
|
||||
#include <rw_value.h> // for UserClass
|
||||
#include <driver.h>
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
struct Y: UserClass { };
|
||||
|
||||
|
||||
int less_used;
|
||||
|
||||
|
||||
_RWSTD_NAMESPACE (std) {
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
bool less<Y>::operator() (const Y &a, const Y &b) const
|
||||
{
|
||||
++less_used;
|
||||
return a < b;
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
||||
|
||||
#ifndef _RWSTD_NO_EXPLICIT_CTOR_INSTANTIATION
|
||||
|
||||
typedef base<def_ctor> DefaultConstructible;
|
||||
typedef base<cpy_ctor> CopyConstructible;
|
||||
|
||||
_RWSTD_NAMESPACE (std) {
|
||||
|
||||
// enclosing explicit instantiation within the declaring namespace
|
||||
// instead of qualifying it with its name to work around compiler
|
||||
// bugs (e.g., SunPro 5.4 -- see PR #28117)
|
||||
|
||||
#ifndef _RWSTD_NO_EMPTY_MEM_INITIALIZER
|
||||
|
||||
template pair<DefaultConstructible, DefaultConstructible>::pair ();
|
||||
|
||||
#endif // _RWSTD_NO_EMPTY_MEM_INITIALIZER
|
||||
|
||||
template pair<CopyConstructible, CopyConstructible>::
|
||||
pair (const CopyConstructible&, const CopyConstructible&);
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // _RWSTD_NO_EXPLICIT_CTOR_INSTANTIATION
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T, class U>
|
||||
void test_pair (T, const char *tname, U, const char *uname)
|
||||
{
|
||||
typedef std::pair<T, U> Pair;
|
||||
|
||||
T *pt = (typename Pair::first_type*)0;
|
||||
U *pu = (typename Pair::second_type*)0;
|
||||
|
||||
rw_info (0, 0, __LINE__, "std::pair<%s, %s> data members", tname, uname);
|
||||
|
||||
if (0) { // compile only
|
||||
|
||||
// verify pair data members and their types
|
||||
Pair *p = 0;
|
||||
pt = &p->first;
|
||||
pu = &p->second;
|
||||
|
||||
_RWSTD_UNUSED (pt);
|
||||
_RWSTD_UNUSED (pu);
|
||||
}
|
||||
|
||||
if (0) { // compile only
|
||||
Pair *p0 = 0;
|
||||
std::pair<long, double> p1 (*p0);
|
||||
|
||||
_RWSTD_UNUSED (p1);
|
||||
}
|
||||
|
||||
{
|
||||
rw_info (0, 0, __LINE__, "std::pair<%s, %s>::pair()", tname, uname);
|
||||
|
||||
UserClass::reset_totals ();
|
||||
|
||||
std::pair<Y, Y> py;
|
||||
|
||||
rw_assert (UserClass::n_total_def_ctor_ == 2, 0, __LINE__,
|
||||
"pair<Y, Y>::pair() called %d default ctors, "
|
||||
"expected 2", UserClass::n_total_def_ctor_, 2);
|
||||
|
||||
#ifndef _RWSTD_NO_EMPTY_MEM_INITIALIZER
|
||||
|
||||
// exercise lwg issue 265
|
||||
rw_assert (UserClass::n_total_copy_ctor_ == 0, 0, __LINE__,
|
||||
"pair<Y, Y>::pair() called %d copy ctors, "
|
||||
"expected 0", UserClass::n_total_copy_ctor_);
|
||||
|
||||
#else // if defined (_RWSTD_NO_EMPTY_MEM_INITIALIZER)
|
||||
|
||||
// 20.2.2, p2: commented out -- calls to copy ctor may be elided
|
||||
// RW_ASSERT (t, UserClass::n_total_copy_ctor_ == 2,
|
||||
// ("std::pair<Y, Y>::pair() called %d copy ctors, "
|
||||
// "expected 2", UserClass::n_total_copy_ctor_));
|
||||
|
||||
#endif // _RWSTD_NO_EMPTY_MEM_INITIALIZER
|
||||
|
||||
rw_info (0, 0, __LINE__,
|
||||
"std::pair<%s, %s>::pair(const %s&, const %s&)",
|
||||
tname, uname, tname, uname);
|
||||
|
||||
UserClass x0;
|
||||
UserClass x1;
|
||||
|
||||
UserClass::reset_totals ();
|
||||
|
||||
// 20.2.2, p3
|
||||
std::pair<UserClass, UserClass> px0 (x0, x1);
|
||||
|
||||
rw_assert (UserClass::n_total_copy_ctor_ == 2, 0, __LINE__,
|
||||
"pair<T, U>::pair (const T&, const U&) called %d cpy "
|
||||
"ctors, expected 2", UserClass::n_total_copy_ctor_);
|
||||
|
||||
|
||||
rw_info (0, 0, __LINE__,
|
||||
"template <class T, class U> "
|
||||
"std::pair<%s, %s>::pair(const pair<T, U>&)",
|
||||
tname, uname);
|
||||
|
||||
UserClass::reset_totals ();
|
||||
|
||||
// 20.2.2, p4
|
||||
std::pair<UserClass, UserClass> px (py);
|
||||
|
||||
rw_assert (UserClass::n_total_copy_ctor_ == 2, 0, __LINE__,
|
||||
"template <class T, class U> pair<UserClass, "
|
||||
"UserClass>::pair(const std::pair<T, U>&) called "
|
||||
"%d cpy ctors, expected 2",
|
||||
UserClass::n_total_copy_ctor_);
|
||||
|
||||
|
||||
rw_info (0, 0, __LINE__,
|
||||
"template <class T, class U> "
|
||||
"std::pair<%s, %s>::operator= (const pair<T, U>&)",
|
||||
tname, uname);
|
||||
|
||||
UserClass::reset_totals ();
|
||||
|
||||
// exercise template assignment if provided,
|
||||
// otherwise template ctor and ordinary assignment
|
||||
px = py;
|
||||
|
||||
rw_assert (UserClass::n_total_copy_ctor_ == 0, 0, __LINE__,
|
||||
"template <class T, class U> pair<UserClass, "
|
||||
"UserClass>::operator=(const pair<T, U>&) "
|
||||
"called %d cpy ctors, expected 0",
|
||||
UserClass::n_total_copy_ctor_);
|
||||
|
||||
rw_assert (UserClass::n_total_op_assign_ == 2, 0, __LINE__,
|
||||
"template <class T, class U> pair<UserClass, "
|
||||
"UserClass>::operator=(const pair<T, U>&) "
|
||||
"called %d assignment operators, "
|
||||
"expected 2", UserClass::n_total_op_assign_);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
// exercise the signature of a nonmember (or static member) function
|
||||
#define FUN(result, name, arg_list) do { \
|
||||
rw_info (0, 0, __LINE__, "%s(const pair<%s, %s>&, " \
|
||||
"const pair<%s, %s>&)", #name, \
|
||||
tname, uname, tname, uname); \
|
||||
/* make name unique to prevent bogus gcc -Wshadow warnings */ \
|
||||
result (*_RWSTD_PASTE (pf, __LINE__)) arg_list = &name; \
|
||||
_RWSTD_UNUSED (_RWSTD_PASTE (pf, __LINE__)); \
|
||||
} while (0)
|
||||
|
||||
FUN (bool, std::operator==, (const Pair&, const Pair&));
|
||||
FUN (bool, std::operator!=, (const Pair&, const Pair&));
|
||||
FUN (bool, std::operator<, (const Pair&, const Pair&));
|
||||
FUN (bool, std::operator<=, (const Pair&, const Pair&));
|
||||
FUN (bool, std::operator>, (const Pair&, const Pair&));
|
||||
FUN (bool, std::operator>=, (const Pair&, const Pair&));
|
||||
|
||||
// 20.2.2, p5
|
||||
std::pair<Y, Y> p0;
|
||||
|
||||
Y::n_total_op_lt_ = 0;
|
||||
|
||||
bool b = p0 == p0;
|
||||
rw_assert (b, 0, __LINE__,
|
||||
"operator== (const pair<UserClass, UserClass>&, "
|
||||
"const pair<UserClass, UserClass>&)");
|
||||
rw_assert (2 == Y::n_total_op_eq_, 0, __LINE__,
|
||||
"operator== (const pair<UserClass, UserClass>&, "
|
||||
"const pair<UserClass, UserClass>&)");
|
||||
|
||||
|
||||
// exercise lwg issue 348
|
||||
// (std::less required to be used in order to satisfy 20.3.3, p8)
|
||||
std::pair<Y, Y> p1;
|
||||
|
||||
p0.first.data_.val_ = 1;
|
||||
p0.second.data_.val_ = 2;
|
||||
|
||||
p1.first.data_.val_ = 3;
|
||||
p1.second.data_.val_ = 4;
|
||||
|
||||
less_used = 0;
|
||||
|
||||
b = p0 < p1;
|
||||
|
||||
rw_assert (b, 0, __LINE__,
|
||||
"operator< (const pair<Y, Y>&, const pair<Y, Y>&)");
|
||||
|
||||
rw_assert (1 == less_used, 0, __LINE__,
|
||||
"less<Y>::operator() called %d time(s), expected 1",
|
||||
less_used);
|
||||
|
||||
p1.first.data_.val_ = 1;
|
||||
|
||||
less_used = 0;
|
||||
|
||||
b = p0 < p1;
|
||||
|
||||
rw_assert (b, 0, __LINE__,
|
||||
"operator< (const pair<Y, Y>&, const pair<Y, Y>&)");
|
||||
|
||||
rw_assert (3 == less_used, 0, __LINE__,
|
||||
"less<Y>::operator() called %d time(s), expected 3",
|
||||
less_used);
|
||||
|
||||
p1.first.data_.val_ = 0;
|
||||
|
||||
less_used = 0;
|
||||
|
||||
b = p0 < p1;
|
||||
|
||||
rw_assert (!b, 0, __LINE__,
|
||||
"operator< (const pair<Y, Y>&, const pair<Y, Y>&)");
|
||||
|
||||
rw_assert (2 == less_used, 0, __LINE__,
|
||||
"less<Y>::operator() called %d time(s), expected 2",
|
||||
less_used);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char**)
|
||||
{
|
||||
test_pair (char (), "char", long (), "long");
|
||||
test_pair (int (), "int", float (), "float");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"lib.pairs",
|
||||
0 /* no comment */,
|
||||
run_test,
|
||||
"",
|
||||
(void*)0 /* sentinel */);
|
||||
}
|
||||
430
extern/stdcxx/4.2.1/tests/utilities/20.specialized.cpp
vendored
Normal file
430
extern/stdcxx/4.2.1/tests/utilities/20.specialized.cpp
vendored
Normal file
@@ -0,0 +1,430 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* specialized.cpp - test exercising 20.4.4 [lib.specialized.algorithms]
|
||||
*
|
||||
* $Id: 20.specialized.cpp 590052 2007-10-30 12:44:14Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <memory>
|
||||
#include <alg_test.h>
|
||||
#include <driver.h>
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _RWSTD_NO_EXCEPTIONS
|
||||
|
||||
struct Y
|
||||
{
|
||||
static int count_;
|
||||
static int ctor_;
|
||||
static int dtor_;
|
||||
static int throw_at_;
|
||||
|
||||
int val_;
|
||||
|
||||
Y (const Y &rhs) : val_ (rhs.val_) {
|
||||
++ctor_;
|
||||
if (count_ + 1 == throw_at_)
|
||||
throw 0;
|
||||
++count_;
|
||||
}
|
||||
|
||||
Y (int val) : val_ (val) {
|
||||
++ctor_;
|
||||
if (count_ + 1 == throw_at_)
|
||||
throw 0;
|
||||
++count_;
|
||||
}
|
||||
|
||||
~Y () {
|
||||
++dtor_;
|
||||
val_ = -2;
|
||||
--count_;
|
||||
}
|
||||
|
||||
private:
|
||||
void operator= (const Y&); // not Assignable
|
||||
};
|
||||
|
||||
|
||||
int Y::count_;
|
||||
int Y::ctor_;
|
||||
int Y::dtor_;
|
||||
int Y::throw_at_;
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
const char* type_name (volatile T*, T*) { return "volatile T*"; }
|
||||
|
||||
template <class T>
|
||||
const char* type_name (const volatile T*, T*) { return "const volatile T*"; }
|
||||
|
||||
// defined as ordinary functions (as opposed to templates)
|
||||
// to avoid tripping up broken compilers on argument deduction
|
||||
inline const volatile int*
|
||||
make_iter (const int *beg, const int*, const int*, const volatile int*)
|
||||
{
|
||||
return beg;
|
||||
}
|
||||
|
||||
inline volatile Y*
|
||||
make_iter (Y *beg, Y*, Y*, volatile Y*)
|
||||
{
|
||||
return beg;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// exercises uninitialized_copy [lib.uninitialized.copy]
|
||||
// with emphasis on exception safety - the function is to have no effect
|
||||
// if an exception is thrown
|
||||
template <class InputIterator, class ForwardIterator>
|
||||
void test_uninitialized_copy (const InputIterator &dummy,
|
||||
const ForwardIterator*)
|
||||
{
|
||||
const char* const i1name = type_name (dummy, (int*)0);
|
||||
const char* const i2name = type_name (ForwardIterator (), (Y*)0);
|
||||
|
||||
rw_info (0, 0, __LINE__, "std::uninitialized_copy(%s, %1$s, %s)",
|
||||
i1name, i2name);
|
||||
|
||||
static const int a[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
};
|
||||
|
||||
const unsigned N = sizeof a / sizeof *a;
|
||||
|
||||
// allocate an uninitialized buffer
|
||||
Y *buf = _RWSTD_STATIC_CAST (Y*, ::operator new (N * sizeof (Y)));
|
||||
|
||||
for (unsigned i = 0; i != N; ++i) {
|
||||
|
||||
Y::count_ = Y::ctor_ = Y::dtor_ = 0;
|
||||
|
||||
// throw during the copy construction of the i-th elem
|
||||
Y::throw_at_ = i;
|
||||
|
||||
try {
|
||||
// constructs i elements, the last ctor throws
|
||||
const InputIterator first =
|
||||
make_iter (a, a, a + i, dummy);
|
||||
const InputIterator last =
|
||||
make_iter (a + i, a, a + i, first);
|
||||
|
||||
const ForwardIterator result =
|
||||
make_iter (buf, buf, buf + i, ForwardIterator ());
|
||||
|
||||
std::uninitialized_copy (first, last, result);
|
||||
|
||||
rw_assert (i == 0, 0, __LINE__,
|
||||
"%zu. expected exception not thrown", i);
|
||||
}
|
||||
catch (int) {
|
||||
// ctor throws an int, this is what's expected
|
||||
}
|
||||
catch (...) {
|
||||
rw_assert (0, 0, __LINE__,
|
||||
"%zu. exception of an unexpected type thrown", i);
|
||||
}
|
||||
|
||||
// verify that all constructed elements were destroyed
|
||||
rw_assert (Y::count_ == 0, 0, __LINE__,
|
||||
"%zu. %d elements not destroyed", i, Y::count_);
|
||||
|
||||
// verify that the expected number of ctor and dtor calls were made
|
||||
rw_assert (Y::ctor_ == Y::throw_at_, 0, __LINE__,
|
||||
"%zu. %d ctor calls expected, got %d",
|
||||
i, Y::throw_at_, Y::ctor_);
|
||||
rw_assert (i ? Y::dtor_ + 1 == Y::throw_at_ : true, 0, __LINE__,
|
||||
"%zu. %d dtor calls expected, got %d",
|
||||
i, Y::throw_at_ - 1, Y::dtor_);
|
||||
}
|
||||
|
||||
::operator delete (buf);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// exercises 20.4.4.2 and 3 - uninitialized_fill [lib.uninitialized.fill]
|
||||
// and uninitialized_fill_n [lib.uninitialized.fill_n] with emphasis on
|
||||
// exception safety - the function is to have no effect if an exception
|
||||
// is thrown
|
||||
template <class ForwardIterator>
|
||||
void test_uninitialized_fill (const ForwardIterator*, bool test_count)
|
||||
{
|
||||
const char* const itname = type_name (ForwardIterator (), (Y*)0);
|
||||
|
||||
rw_info (0, 0, __LINE__,
|
||||
"std::uninitialized_fill%{?}_n%{;}(%s, %{?}size_t%{:}%2$s%{;}, "
|
||||
"const int&)", test_count, itname, test_count);
|
||||
|
||||
const unsigned N = 32;
|
||||
|
||||
// allocate an uninitialized buffer
|
||||
Y *buf = _RWSTD_STATIC_CAST (Y*, ::operator new (N * sizeof (Y)));
|
||||
|
||||
for (unsigned i = 0; i != N; ++i) {
|
||||
|
||||
// prevent ctor below from throwing
|
||||
Y::throw_at_ = -1;
|
||||
|
||||
// create a temporary and reset counters (in that order)
|
||||
Y val (i);
|
||||
|
||||
Y::count_ = Y::ctor_ = Y::dtor_ = 0;
|
||||
|
||||
// throw during the copy construction of the i-th elem
|
||||
Y::throw_at_ = i;
|
||||
|
||||
try {
|
||||
// copy-constructs i elements, the last copy ctor throws
|
||||
const ForwardIterator first =
|
||||
make_iter (buf, buf, buf + i, ForwardIterator ());
|
||||
|
||||
if (test_count) {
|
||||
std::uninitialized_fill_n (first, i, val);
|
||||
}
|
||||
else {
|
||||
const ForwardIterator last =
|
||||
make_iter (buf + i, buf, buf + i, first);
|
||||
|
||||
std::uninitialized_fill (first, last, val);
|
||||
}
|
||||
|
||||
rw_assert (i == 0, 0, __LINE__,
|
||||
"%zu. expected exception not thrown", i);
|
||||
}
|
||||
catch (int) {
|
||||
// ctor throws an int, this is what's expected
|
||||
}
|
||||
catch (...) {
|
||||
rw_assert (0, 0, __LINE__,
|
||||
"%zu. exception of an unexpected type thrown", i);
|
||||
}
|
||||
|
||||
// verify that all constructed elements were destroyed
|
||||
rw_assert (Y::count_ == 0, 0, __LINE__,
|
||||
"%zu. %d elements not destroyed", i, Y::count_);
|
||||
|
||||
// verify that the expected number of ctor and dtor calls were made
|
||||
rw_assert (Y::ctor_ == Y::throw_at_, 0, __LINE__,
|
||||
"%zu. %d ctor calls expected, got %d",
|
||||
i, Y::throw_at_, Y::ctor_);
|
||||
rw_assert (i ? Y::dtor_ + 1 == Y::throw_at_ : true, 0, __LINE__,
|
||||
"%d. %d dtor calls expected, got %d",
|
||||
i, Y::throw_at_ - 1, Y::dtor_);
|
||||
}
|
||||
|
||||
::operator delete (buf);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int opt_copy;
|
||||
int opt_fill;
|
||||
int opt_fill_n;
|
||||
|
||||
int opt_input_iter;
|
||||
int opt_fwd_iter;
|
||||
int opt_bidir_iter;
|
||||
int opt_rnd_iter;
|
||||
int opt_volatile_ptr;
|
||||
|
||||
|
||||
template <class InputIterator>
|
||||
void test_uninitialized_copy (const InputIterator &dummy)
|
||||
{
|
||||
if (-1 < opt_fwd_iter)
|
||||
test_uninitialized_copy (dummy, (FwdIter<Y>*)0);
|
||||
else
|
||||
rw_note (-1 > opt_fwd_iter--, 0, __LINE__,
|
||||
"ForwardIterator tests disabled");
|
||||
|
||||
if (-1 < opt_bidir_iter)
|
||||
test_uninitialized_copy (dummy, (BidirIter<Y>*)0);
|
||||
else
|
||||
rw_note (-1 > opt_bidir_iter--, 0, __LINE__,
|
||||
"BidirectionalIterator tests disabled");
|
||||
|
||||
if (-1 < opt_rnd_iter)
|
||||
test_uninitialized_copy (dummy, (RandomAccessIter<Y>*)0);
|
||||
else
|
||||
rw_note (-1 > opt_rnd_iter--, 0, __LINE__,
|
||||
"RandomAccessIterator tests disabled");
|
||||
|
||||
if (-1 < opt_volatile_ptr) {
|
||||
typedef volatile Y* VolatilePointer;
|
||||
test_uninitialized_copy (dummy, (VolatilePointer*)0);
|
||||
}
|
||||
else
|
||||
rw_note (-1 > opt_volatile_ptr--, 0, __LINE__,
|
||||
"volatile T* tests disabled");
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char**)
|
||||
{
|
||||
typedef const volatile int* ConstVolatilePointer;
|
||||
typedef /* */ volatile Y* VolatilePointer;
|
||||
|
||||
if (-1 < opt_copy) {
|
||||
if (-1 < opt_input_iter)
|
||||
test_uninitialized_copy (InputIter<int>(0, 0, 0));
|
||||
else
|
||||
rw_note (-1 > opt_input_iter--, 0, __LINE__,
|
||||
"InputIterator tests disabled");
|
||||
|
||||
if (-1 < opt_fwd_iter)
|
||||
test_uninitialized_copy (ConstFwdIter<int>());
|
||||
else
|
||||
rw_note (-1 > opt_fwd_iter--, 0, __LINE__,
|
||||
"ForwardIterator tests disabled");
|
||||
|
||||
if (-1 < opt_bidir_iter)
|
||||
test_uninitialized_copy (ConstBidirIter<int>());
|
||||
else
|
||||
rw_note (-1 > opt_bidir_iter--, 0, __LINE__,
|
||||
"BidirectionalIterator tests disabled");
|
||||
|
||||
if (-1 < opt_rnd_iter)
|
||||
test_uninitialized_copy (ConstRandomAccessIter<int>());
|
||||
else
|
||||
rw_note (-1 > opt_rnd_iter--, 0, __LINE__,
|
||||
"RandomAccessIterator tests disabled");
|
||||
|
||||
if (-1 < opt_volatile_ptr)
|
||||
test_uninitialized_copy (ConstVolatilePointer ());
|
||||
else
|
||||
rw_note (-1 > opt_volatile_ptr--, 0, __LINE__,
|
||||
"volatile T* tests disabled");
|
||||
}
|
||||
else
|
||||
rw_note (0, 0, 0, "tests of std::uninitialized_copy disabled");
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
if (-1 < opt_fill) {
|
||||
if (-1 < opt_fwd_iter)
|
||||
test_uninitialized_fill ((FwdIter<Y>*)0, false);
|
||||
else
|
||||
rw_note (-1 > opt_fwd_iter--, 0, __LINE__,
|
||||
"ForwardIterator tests disabled");
|
||||
|
||||
if (-1 < opt_bidir_iter)
|
||||
test_uninitialized_fill ((BidirIter<Y>*)0, false);
|
||||
else
|
||||
rw_note (-1 > opt_bidir_iter--, 0, __LINE__,
|
||||
"BidirectionalIterator tests disabled");
|
||||
|
||||
if (-1 < opt_bidir_iter)
|
||||
test_uninitialized_fill ((RandomAccessIter<Y>*)0, false);
|
||||
else
|
||||
rw_note (-1 > opt_bidir_iter--, 0, __LINE__,
|
||||
"RandomAccessIterator tests disabled");
|
||||
|
||||
if (-1 < opt_volatile_ptr) {
|
||||
test_uninitialized_fill ((VolatilePointer*)0, false);
|
||||
}
|
||||
else
|
||||
rw_note (-1 > opt_volatile_ptr++,
|
||||
0, 0, "volatile T* tests disabled");
|
||||
}
|
||||
else
|
||||
rw_note (0, 0, 0, "tests of std::uninitialized_fill disabled");
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
if (-1 < opt_fill) {
|
||||
if (-1 < opt_fwd_iter)
|
||||
test_uninitialized_fill ((FwdIter<Y>*)0, true);
|
||||
else
|
||||
rw_note (-1 > opt_fwd_iter--, 0, __LINE__,
|
||||
"ForwardIterator tests disabled");
|
||||
|
||||
if (-1 < opt_bidir_iter)
|
||||
test_uninitialized_fill ((BidirIter<Y>*)0, true);
|
||||
else
|
||||
rw_note (-1 > opt_bidir_iter--, 0, __LINE__,
|
||||
"BidirectionalIterator tests disabled");
|
||||
|
||||
if (-1 < opt_bidir_iter)
|
||||
test_uninitialized_fill ((RandomAccessIter<Y>*)0, true);
|
||||
else
|
||||
rw_note (-1 > opt_bidir_iter--, 0, __LINE__,
|
||||
"RandomAccessIterator tests disabled");
|
||||
|
||||
if (-1 < opt_volatile_ptr) {
|
||||
test_uninitialized_fill ((VolatilePointer*)0, true);
|
||||
}
|
||||
else
|
||||
rw_note (-1 > opt_volatile_ptr--, 0, __LINE__,
|
||||
"volatile T* tests disabled");
|
||||
}
|
||||
else
|
||||
rw_note (0, 0, 0, "tests of std::uninitialized_fill disabled");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // _RWSTD_NO_EXCEPTIONS
|
||||
|
||||
static int
|
||||
run_test (int, char**)
|
||||
{
|
||||
rw_note (0, 0, 0,
|
||||
"exceptions disabled (_RWSTD_NO_EXCEPTIONS #defined), "
|
||||
"cannot test");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // _RWSTD_NO_EXCEPTIONS
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"lib.specialized.algorithms",
|
||||
0 /* no comment */,
|
||||
run_test,
|
||||
"|-uninitialized_copy~ "
|
||||
"|-uninitialized_fill~ "
|
||||
"|-uninitialized_fill_n~ "
|
||||
"|-InputIterator~ "
|
||||
"|-ForwardIterator~ "
|
||||
"|-BidirectionalIterator~ "
|
||||
"|-RandomAccessIterator~ "
|
||||
"|-volatile-pointer",
|
||||
&opt_copy,
|
||||
&opt_fill,
|
||||
&opt_fill_n,
|
||||
&opt_input_iter,
|
||||
&opt_fwd_iter,
|
||||
&opt_bidir_iter,
|
||||
&opt_rnd_iter,
|
||||
&opt_volatile_ptr);
|
||||
}
|
||||
492
extern/stdcxx/4.2.1/tests/utilities/20.temp.buffer.cpp
vendored
Normal file
492
extern/stdcxx/4.2.1/tests/utilities/20.temp.buffer.cpp
vendored
Normal file
@@ -0,0 +1,492 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 20.temp.buffer.cpp - test exercising lib.temporary.buffer
|
||||
*
|
||||
* $Id: 20.temp.buffer.cpp 648752 2008-04-16 17:01:56Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2003-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <memory> // for get_temporary_buffer()
|
||||
|
||||
#include <cerrno> // for errno
|
||||
#include <cstddef> // for ptrdiff_t, size_t
|
||||
#include <cstdio> // for sprintf()
|
||||
#include <cstring> // for memset()
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <climits> // for INT_MAX
|
||||
# include <crtdbg.h> // for _CrtSetReportMode()
|
||||
#endif
|
||||
|
||||
#include <rw_new.h>
|
||||
#include <rw_printf.h>
|
||||
#include <driver.h>
|
||||
|
||||
#ifndef _RWSTD_NO_SETRLIMIT
|
||||
// #undef works around SunPro bug #568
|
||||
# undef _TIME_T
|
||||
# include <sys/resource.h> // for setrlimit()
|
||||
# include <unistd.h> // for sbrk()
|
||||
#endif // _RWSTD_NO_SETRLIMIT
|
||||
|
||||
#ifdef _AIX
|
||||
|
||||
// declare the loader symbol _edata defined by the AIX loader:
|
||||
// The first address following the initialized data region.
|
||||
extern "C" {
|
||||
extern void* _edata;
|
||||
} // extern "C"
|
||||
|
||||
#endif // _AIX
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int compare (const void *beg, const void *end, int val)
|
||||
{
|
||||
typedef unsigned char UChar;
|
||||
|
||||
const UChar ucval = UChar (val);
|
||||
|
||||
for (const UChar *pc = (const UChar*)beg; pc != end; ++pc) {
|
||||
if (*pc != ucval)
|
||||
return *pc - ucval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
void test_success (T*, const char *tname)
|
||||
{
|
||||
RW_ASSERT (0 != tname);
|
||||
|
||||
rw_info (0, 0, __LINE__, "std::get_temporary_buffer<%s>(ptrdiff_t)",
|
||||
tname);
|
||||
|
||||
// verify that passing 0 as the argument either returns pair (0, 0)
|
||||
// or pair (p, N) with p being a unique pointer in consecutive calls
|
||||
// and N >= 0
|
||||
|
||||
static const unsigned pa_size = 32;
|
||||
|
||||
#ifndef __HP_aCC
|
||||
|
||||
std::pair<T*, std::ptrdiff_t> pa [pa_size];
|
||||
|
||||
#else // if defined (__HP_aCC)
|
||||
|
||||
// working around an HP aCC bug (PR #27302)
|
||||
std::pair<T*, std::ptrdiff_t>* const pa =
|
||||
new std::pair<T*, std::ptrdiff_t>[pa_size];
|
||||
|
||||
#endif // __HP_aCC
|
||||
|
||||
// establish a checkpoint for memory leaks
|
||||
rwt_check_leaks (0, 0);
|
||||
|
||||
pa [0] = std::get_temporary_buffer<T>(0);
|
||||
|
||||
if (pa [0].first) {
|
||||
|
||||
std::memset (pa [0].first, ~0U, pa [0].second * sizeof (T));
|
||||
|
||||
pa [1] = std::get_temporary_buffer<T>(0);
|
||||
|
||||
if (pa [1].first)
|
||||
std::memset (pa [1].first, ~1U, pa [1].second * sizeof (T));
|
||||
|
||||
rw_assert (pa [0].first != pa [1].first, 0, __LINE__,
|
||||
"get_temporary_buffer<%s>(0).first not unique: "
|
||||
"got %#p and %#p", tname, pa [0].first, pa [1].first);
|
||||
}
|
||||
else {
|
||||
rw_assert (0 == pa [0].second, 0, __LINE__,
|
||||
"get_temporary_buffer<%s>(0) == { 0, 0 }, got "
|
||||
"{ %#p, %td }", tname, pa [0].first, pa [0].second);
|
||||
}
|
||||
|
||||
pa [2] = std::get_temporary_buffer<T>(2);
|
||||
|
||||
rw_assert (0 != pa [2].first, 0, __LINE__,
|
||||
"get_temporary_buffer<%s>(2).first != 0, got 0", tname);
|
||||
|
||||
if (0 == pa [2].first)
|
||||
return;
|
||||
|
||||
std::memset (pa [2].first, ~2U, pa [2].second * sizeof (T));
|
||||
|
||||
rw_assert (2 <= pa [2].second, 0, __LINE__,
|
||||
"get_temporary_buffer<%s>(2).second >= 2, got %td",
|
||||
tname, pa [2].second);
|
||||
|
||||
pa [3] = std::get_temporary_buffer<T>(3);
|
||||
|
||||
|
||||
rw_assert (0 != pa [3].first, 0, __LINE__,
|
||||
"get_temporary_buffer<%s>(3).first != 0, got 0", tname);
|
||||
|
||||
if (!pa [3].first)
|
||||
return;
|
||||
|
||||
rw_assert (3 <= pa [3].second, 0, __LINE__,
|
||||
"get_temporary_buffer<%s>(3).second >= 3, got %td",
|
||||
tname, pa [3].second);
|
||||
|
||||
// verify correct alignment (if the storage isn't properly aligned,
|
||||
// expect SIGBUS on RISC machines, or SIGSEGV on HP-UX/PA-RISC)
|
||||
pa [3].first [0] = T ();
|
||||
pa [3].first [1] = T ();
|
||||
pa [3].first [2] = T ();
|
||||
|
||||
std::memset (pa [3].first, ~3U, pa [3].second * sizeof (T));
|
||||
|
||||
// get the remaining temporary buffers and verify that they
|
||||
// are each distinct from one another
|
||||
for (unsigned i = 4; i != pa_size; ++i) {
|
||||
|
||||
const std::ptrdiff_t size =
|
||||
std::ptrdiff_t (i % 2 ? i : _RWSTD_TMPBUF_SIZE + i);
|
||||
|
||||
pa [i] = std::get_temporary_buffer<T>(size);
|
||||
|
||||
if (pa [i].first)
|
||||
std::memset (pa [i].first, ~i, pa [i].second * sizeof (T));
|
||||
}
|
||||
|
||||
// verify the uniqueness of all ranges
|
||||
for (unsigned i = 0; i < pa_size; ++i) {
|
||||
for (unsigned j = 0; j < pa_size; ++j) {
|
||||
const bool fail =
|
||||
i != j && pa [i].first
|
||||
&& pa [i].first >= pa [j].first
|
||||
&& pa [i].first < pa [j].first + pa [j].second;
|
||||
|
||||
rw_assert (!fail, 0, __LINE__,
|
||||
"pair { %#p, %td } returned from call %u overlaps "
|
||||
"pair { %#p, %td } returned from call %u",
|
||||
pa [i].first, pa [i].second, i,
|
||||
pa [j].first, pa [j].second, j);
|
||||
|
||||
if (fail) {
|
||||
// break out of both loops
|
||||
i = j = unsigned (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rw_info (0, 0, __LINE__,
|
||||
"std::return_temporary_buffer<%s>(%1$s*)", tname);
|
||||
|
||||
// call return_temporary_buffer() on each returned pointer
|
||||
// and verify that the contents of the buffers pointed to
|
||||
// by all remaining unallocated pointers are unchanged
|
||||
for (unsigned i = 0; i < pa_size; ++i) {
|
||||
|
||||
std::return_temporary_buffer (pa [i].first);
|
||||
|
||||
for (unsigned j = i + 1; j < pa_size; ++j) {
|
||||
|
||||
const bool success =
|
||||
0 == compare (pa [j].first, pa [j].first + pa [j].second, ~j);
|
||||
|
||||
rw_assert (success, 0, __LINE__,
|
||||
"return_temporary_buffer<%s>(%#p) corrupted "
|
||||
"a buffer designated by { %#p %td }",
|
||||
tname, pa [i].first, pa [j].first, pa [j].second);
|
||||
|
||||
if (!success) {
|
||||
// break out of both loops
|
||||
i = j = unsigned (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t nbytes;
|
||||
const std::size_t nblocks = rwt_check_leaks (&nbytes, 0);
|
||||
|
||||
// verify the absence of memory leaks
|
||||
rw_assert (!nblocks && !nbytes, 0, __LINE__,
|
||||
"temporary buffer leaked %d bytes in %d blocks",
|
||||
nbytes, nblocks);
|
||||
|
||||
#ifdef __HP_aCC
|
||||
|
||||
delete[] pa;
|
||||
|
||||
#endif // __HP_aCC
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
void test_failure (T*, const char *tname)
|
||||
{
|
||||
if (0 == tname) {
|
||||
static char buf [40];
|
||||
rw_sprintf (buf, "char[%zu]", sizeof (T));
|
||||
tname = buf;
|
||||
}
|
||||
|
||||
rw_info (0, 0, __LINE__,
|
||||
"std::get_temporary_buffer<%s>(ptrdiff_t) on arithmetic overflow",
|
||||
tname);
|
||||
|
||||
std::ptrdiff_t nelems = -1;
|
||||
|
||||
std::pair<T*, std::ptrdiff_t> pa;
|
||||
|
||||
pa = std::get_temporary_buffer<T>(nelems);
|
||||
|
||||
rw_assert (0 == pa.first && 0 == pa.second, 0, __LINE__,
|
||||
"std::get_temporary_buffer<%s>(%td) == { 0, 0 }, "
|
||||
"got { %#p, %td }",
|
||||
tname, nelems, pa.first, pa.second);
|
||||
|
||||
for (std::size_t i = 2; i && i < sizeof (T); i <<= 1) {
|
||||
// exercise arithmetic overflow (not to be confused
|
||||
// with the out-of-memory tests below)
|
||||
|
||||
// attempts to allocate space for an array of elements
|
||||
// with a total size that exceeds SIZE_MAX must fail
|
||||
nelems = (_RWSTD_PTRDIFF_MAX / i) + 1;
|
||||
|
||||
pa = std::get_temporary_buffer<T>(nelems);
|
||||
|
||||
rw_assert (0 == pa.first && 0 == pa.second, 0, __LINE__,
|
||||
"get_temporary_buffer<%s>(%ld) == { 0, 0 }, "
|
||||
"got { %#p, %td }",
|
||||
tname, nelems, pa.first, pa.second);
|
||||
}
|
||||
|
||||
#ifndef _RWSTD_NO_SETRLIMIT
|
||||
|
||||
// exercise get_temporary_buffer in the presence of allocation
|
||||
// failure (caused by setting the soft data limit to the current
|
||||
// value)
|
||||
|
||||
// retrieve the current soft (rlim_cur) and hard (rlim_max) limits
|
||||
struct rlimit rlim_old;
|
||||
if (getrlimit (RLIMIT_DATA, &rlim_old)) {
|
||||
rw_warn (0, 0, __LINE__,
|
||||
"getrlimit(RLIMIT_DATA, { .rlim_max=%zu, .rlim_cur=%zu}) "
|
||||
"failed: %{#m}: %m", rlim_old.rlim_max, rlim_old.rlim_cur);
|
||||
return;
|
||||
}
|
||||
|
||||
// set the soft limit to 0, leaving the hard limit unchanged
|
||||
struct rlimit rlim_new = rlim_old;
|
||||
|
||||
#ifdef _AIX
|
||||
{
|
||||
// AIX setrlimit() fails to lower the limit for resource
|
||||
// whose current usage is already higher than the new limit.
|
||||
// Instead of setting the limit to 0, compute the current
|
||||
// usage and use it to set the soft limit
|
||||
const char* const brk_min = (char*)_edata;
|
||||
const char* const brk_cur = (char*)sbrk (0);
|
||||
|
||||
rlim_new.rlim_cur = brk_cur - brk_min;
|
||||
}
|
||||
#else // if !defined (_AIX)
|
||||
rlim_new.rlim_cur = 0;
|
||||
#endif // _AIX
|
||||
|
||||
errno = 0;
|
||||
|
||||
// IEEE Std 1003.1, 2004 Edition (SUSv3):
|
||||
// RLIMIT_DATA
|
||||
// ...is the maximum size of a process' data segment, in bytes.
|
||||
// If this limit is exceeded, the malloc() function shall fail
|
||||
// with errno set to [ENOMEM].
|
||||
if (setrlimit (RLIMIT_DATA, &rlim_new)) {
|
||||
rw_warn (0, 0, __LINE__,
|
||||
"setrlimit(RLIMIT_DATA, { .rlim_max=%zu, .rlim_cur=%zu}) "
|
||||
"failed to lower the soft limit: %{#m}: %m",
|
||||
rlim_new.rlim_max, rlim_new.rlim_cur);
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t nbytes = rlim_old.rlim_max;
|
||||
|
||||
#if 0 < _RWSTD_TMPBUF_SIZE
|
||||
|
||||
// make sure the size is larger than the size of the temp buff
|
||||
if (nbytes <= _RWSTD_TMPBUF_SIZE)
|
||||
nbytes = _RWSTD_TMPBUF_SIZE + 1;
|
||||
|
||||
#else // if _RWSTD_TMPBUF_SIZE <= 0
|
||||
|
||||
nbytes = 65536;
|
||||
|
||||
#endif // _RWSTD_TMPBUF_SIZE
|
||||
|
||||
if (nbytes < _RWSTD_SIZE_MAX)
|
||||
++nbytes;
|
||||
|
||||
if (nbytes <= std::size_t (_RWSTD_PTRDIFF_MAX))
|
||||
nelems = std::ptrdiff_t (nbytes);
|
||||
else
|
||||
nelems = _RWSTD_PTRDIFF_MAX;
|
||||
|
||||
nelems /= sizeof (T);
|
||||
|
||||
// retrieve the current limit just to show it in the info message
|
||||
// ignore any errors
|
||||
getrlimit (RLIMIT_DATA, &rlim_new);
|
||||
|
||||
rw_info (0, 0, __LINE__,
|
||||
"std::get_temporary_buffer<%s>(%td) in low memory conditions "
|
||||
": { .rlim_max = %zu, .rlim_cur = %zu }",
|
||||
tname, nelems, rlim_new.rlim_max, rlim_new.rlim_cur);
|
||||
|
||||
// expect the function to fail
|
||||
pa = std::get_temporary_buffer<T>(nelems);
|
||||
|
||||
// reset the soft limit to the original value (do it before any
|
||||
// test output in case memory needs to be allocated during the
|
||||
// output)
|
||||
if (setrlimit (RLIMIT_DATA, &rlim_old)) {
|
||||
rw_warn (0, 0, __LINE__,
|
||||
"setrlimit(RLIMIT_DATA, { .rlim_max=%zu, .rlim_cur=%zu }) "
|
||||
"failed to restore the soft limit: %{#m}: %m",
|
||||
rlim_old.rlim_max, rlim_old.rlim_cur);
|
||||
}
|
||||
|
||||
rw_assert (0 == pa.first && 0 == pa.second, 0, __LINE__,
|
||||
"get_temporary_buffer<%s>(%td) == { 0, 0 } "
|
||||
"in low memory conditions, got { %#p, %td }",
|
||||
tname, nbytes, pa.first, pa.second);
|
||||
|
||||
#endif // _RWSTD_NO_SETRLIMIT
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
typedef void (*FunctionPointer)();
|
||||
|
||||
struct MyStruct { };
|
||||
typedef void (MyStruct::*MemberPointer)();
|
||||
|
||||
template <std::size_t N>
|
||||
struct BigStruct { char dummy [N]; };
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
void test_get_temporary_buffer (T *dummy, const char *tname)
|
||||
{
|
||||
RW_ASSERT (0 != tname);
|
||||
|
||||
test_success (dummy, tname);
|
||||
test_failure (dummy, tname);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char**)
|
||||
{
|
||||
test_get_temporary_buffer ((char*)0, "char");
|
||||
|
||||
test_get_temporary_buffer ((int*)0, "int");
|
||||
|
||||
#ifdef _RWSTD_LONG_LONG
|
||||
|
||||
test_get_temporary_buffer ((_RWSTD_LONG_LONG*)0, "long long");
|
||||
|
||||
#else // if !defined (_RWSTD_LONG_LONG)
|
||||
|
||||
test_get_temporary_buffer ((long*)0, "long");
|
||||
|
||||
#endif // _RWSTD_LONG_LONG
|
||||
|
||||
#ifndef _RWSTD_NO_LONG_DOUBLE
|
||||
|
||||
test_get_temporary_buffer ((long double*)0, "long double");
|
||||
|
||||
#else // if defined (_RWSTD_NO_LONG_DOUBLE)
|
||||
|
||||
test_get_temporary_buffer ((double*)0, "double");
|
||||
|
||||
#endif // _RWSTD_NO_LONG_DOUBLE
|
||||
|
||||
// exercise ordinary pointers
|
||||
test_get_temporary_buffer ((void**)0, "void*");
|
||||
|
||||
// exercise function pointers
|
||||
test_get_temporary_buffer ((FunctionPointer*)0, "void (*)()");
|
||||
|
||||
// exercise pointers to members
|
||||
test_get_temporary_buffer ((MemberPointer*)0, "void (struct::*)()");
|
||||
|
||||
#if (!defined (__IBMCPP__) || __IBMCPP__ > 700) \
|
||||
&& !defined (__HP_aCC)
|
||||
|
||||
# ifndef _MSC_VER
|
||||
const std::size_t MAX_SIZE = _RWSTD_PTRDIFF_MAX;
|
||||
# else
|
||||
// the MSVC and ICC/Windows has maximum size of
|
||||
// the array equal to 0x7fffffff bytes
|
||||
const std::size_t MAX_SIZE = INT_MAX;
|
||||
# endif
|
||||
|
||||
// avoid instantiating test on very large structs
|
||||
// to prevent failures (at compile or run-time) due
|
||||
// to compiler bugs
|
||||
test_failure ((BigStruct<MAX_SIZE / 2>*)0, 0);
|
||||
test_failure ((BigStruct<MAX_SIZE - 1>*)0, 0);
|
||||
test_failure ((BigStruct<MAX_SIZE>*)0, 0);
|
||||
|
||||
#else
|
||||
|
||||
// work around VAC++ 7.0 (and prior) bug #549
|
||||
// work around HP aCC 3,5,6 bug #565
|
||||
rw_warn (0, 0, __LINE__, "get_temp_buffer<large-struct>() "
|
||||
"not tested due to a compiler bug");
|
||||
|
||||
#endif // VAC++ > 7.0
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
// disable "Invalid allocation size: 4294967292 bytes"
|
||||
// message box from malloc()
|
||||
_CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_DEBUG);
|
||||
#endif
|
||||
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"lib.temporary.buffer",
|
||||
0 /* no comment */,
|
||||
run_test,
|
||||
"",
|
||||
(void*)0 /* sentinel */);
|
||||
}
|
||||
251
extern/stdcxx/4.2.1/tests/utilities/20.temp.buffer.mt.cpp
vendored
Normal file
251
extern/stdcxx/4.2.1/tests/utilities/20.temp.buffer.mt.cpp
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 20.temp.buffer.mt.cpp - test exercising the thread safety
|
||||
* of std::get_temporary_buffer() and
|
||||
* std::return_temporary_buffer()
|
||||
*
|
||||
* $Id: 20.temp.buffer.mt.cpp 650350 2008-04-22 01:35:17Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2005-2008 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <memory> // for get_temporary_buffer
|
||||
#include <utility> // for pair
|
||||
|
||||
#include <cassert> // for assert
|
||||
#include <cstddef> // for ptrdiff_t
|
||||
#include <cstdio> // for printf()
|
||||
#include <cstring> // for memset()
|
||||
|
||||
#include <driver.h> // for rw_test(), ...
|
||||
#include <rw_thread.h> // for rw_thread_create(), ...
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _RWSTD_REENTRANT
|
||||
# define MAX_THREADS 0
|
||||
#else
|
||||
# define MAX_THREADS 32
|
||||
#endif
|
||||
|
||||
/* extern */ unsigned rw_opt_nthreads = 4 <= MAX_THREADS ? 4 : MAX_THREADS;
|
||||
/* extern */ unsigned rw_opt_nloops = 1024 * 1024;
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
struct thr_args
|
||||
{
|
||||
unsigned threadno_; // thread ordinal number
|
||||
unsigned ngets_; // number of calls to get_temporary_buffer
|
||||
unsigned nreturns_; // number of calls to return_temporary_buffer
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
std::pair<T*, std::ptrdiff_t>
|
||||
test_get_buffer (thr_args *args, T*, unsigned nobjs)
|
||||
{
|
||||
++args->ngets_;
|
||||
|
||||
std::pair<T*, std::ptrdiff_t> buf =
|
||||
std::get_temporary_buffer<T>(std::ptrdiff_t (nobjs));
|
||||
|
||||
// std::printf ("T%u: get %s: { %p, %d } == %u\n",
|
||||
// args->threadno_, type_name (T ()),
|
||||
// buf.first, buf.second, buf.second * sizeof (T));
|
||||
|
||||
if (buf.first && buf.second) {
|
||||
|
||||
const std::size_t nbytes = buf.second * sizeof (T);
|
||||
|
||||
std::memset (buf.first, args->threadno_ + 1, nbytes);
|
||||
|
||||
*((char*)buf.first + nbytes - 1) = '\0';
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
void
|
||||
test_return_buffer (thr_args *args, std::pair<T*, std::ptrdiff_t> &buf)
|
||||
{
|
||||
++args->nreturns_;
|
||||
|
||||
std::size_t len = 0;
|
||||
|
||||
if (buf.first) {
|
||||
|
||||
typedef unsigned char UChar;
|
||||
|
||||
for (const UChar *pb = (const UChar*)buf.first; ; ++pb, ++len) {
|
||||
|
||||
if (*pb != (args->threadno_ + 1)) {
|
||||
if (0 == *pb)
|
||||
++len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// std::printf ("T%u: return %s: { %p, %d } == %u\n",
|
||||
// args->threadno_, type_name (T ()),
|
||||
// buf.first, buf.second, len);
|
||||
|
||||
assert (len == buf.second * sizeof (T));
|
||||
|
||||
std::return_temporary_buffer<T>(buf.first);
|
||||
buf.first = 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
extern "C" void* thr_func (void *arg)
|
||||
{
|
||||
thr_args* const targs = (thr_args*)arg;
|
||||
|
||||
std::printf ("thread %u starting...\n", targs->threadno_);
|
||||
|
||||
#ifndef _RWSTD_INT64_T
|
||||
|
||||
typedef char Type64 [8];
|
||||
|
||||
#else // if defined (_RWSTD_INT64_T)
|
||||
|
||||
typedef _RWSTD_INT64_T Type64;
|
||||
|
||||
#endif // _RWSTD_INT64_T
|
||||
|
||||
std::pair<_RWSTD_INT8_T*, std::ptrdiff_t> buf0;
|
||||
std::pair<_RWSTD_INT16_T*, std::ptrdiff_t> buf1;
|
||||
std::pair<_RWSTD_INT32_T*, std::ptrdiff_t> buf2;
|
||||
std::pair<Type64*, std::ptrdiff_t> buf3;
|
||||
|
||||
for (unsigned i = 0; i != rw_opt_nloops; ++i) {
|
||||
|
||||
const unsigned nelems = (i + targs->threadno_) % 32;
|
||||
|
||||
switch ((i + targs->threadno_) % 8) {
|
||||
|
||||
case 0:
|
||||
buf0 = test_get_buffer (targs, (_RWSTD_INT8_T*)0, nelems);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
buf1 = test_get_buffer (targs, (_RWSTD_INT16_T*)0, nelems);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
buf2 = test_get_buffer (targs, (_RWSTD_INT32_T*)0, nelems);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
buf3 = test_get_buffer (targs, (Type64*)0, nelems);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
test_return_buffer (targs, buf0);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
test_return_buffer (targs, buf2);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
test_return_buffer (targs, buf1);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
test_return_buffer (targs, buf3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// free any buffers that remain allocated
|
||||
if (buf0.first) test_return_buffer (targs, buf0);
|
||||
if (buf1.first) test_return_buffer (targs, buf1);
|
||||
if (buf2.first) test_return_buffer (targs, buf2);
|
||||
if (buf3.first) test_return_buffer (targs, buf3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char*[])
|
||||
{
|
||||
rw_info (0, 0, 0, "std::get_temporary_buffer(ptrdiff_t)");
|
||||
rw_info (0, 0, 0, "std::return_temporary_buffer(ptrdiff_t)");
|
||||
|
||||
if (0 < rw_opt_nthreads) {
|
||||
|
||||
rw_thread_t tid [MAX_THREADS + 1];
|
||||
|
||||
thr_args targs [MAX_THREADS + 1];
|
||||
|
||||
std::memset (targs, 0, sizeof targs);
|
||||
|
||||
for (unsigned i = 0; i != rw_opt_nthreads; ++i) {
|
||||
|
||||
targs [i].threadno_ = i;
|
||||
|
||||
rw_fatal (0 == rw_thread_create (tid + i, 0, thr_func, targs + i),
|
||||
0, 0, "thread_create() failed");
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i != rw_opt_nthreads; ++i) {
|
||||
|
||||
rw_error (0 == rw_thread_join (tid [i], 0), 0, 0,
|
||||
"thread_join() failed");
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
thr_args targs;
|
||||
|
||||
std::memset (&targs, 0, sizeof targs);
|
||||
|
||||
thr_func (&targs);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"lib.temporary.buffer",
|
||||
0 /* no comment */,
|
||||
run_test,
|
||||
"|-nloops#0 " // must be non-negative
|
||||
"|-nthreads#0-*", // must be in specified range
|
||||
&rw_opt_nloops,
|
||||
int (MAX_THREADS),
|
||||
&rw_opt_nthreads);
|
||||
}
|
||||
Reference in New Issue
Block a user