stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From far...@apache.org
Subject svn commit: r522951 [1/2] - in /incubator/stdcxx/trunk/tests/containers: 23.list.assign.cpp 23.list.capacity.cpp 23.list.cons.cpp 23.list.erase.cpp 23.list.insert.cpp 23.list.iterators.cpp 23.list.special.cpp
Date Tue, 27 Mar 2007 15:16:25 GMT
Author: faridz
Date: Tue Mar 27 08:16:23 2007
New Revision: 522951

URL: http://svn.apache.org/viewvc?view=rev&rev=522951
Log:
2007-03-27  Farid Zaripov <Farid_Zaripov@epam.com>

	* 23.list.assign.cpp: New test exercising [lib.list.assign].
	* 23.list.capacity.cpp: New test exercising [lib.list.capacity].
	* 23.list.cons.cpp: New test exercising [lib.list.cons].
	* 23.list.erase.cpp: New test exercising [lib.list.,erase].
	* 23.list.insert.cpp: New test exercising [lib.list.insert].
	* 23.list.iterators.cpp: New test exercising [lib.list.iterators].
	* 23.list.special.cpp: New test exercising [lib.list.special].

Added:
    incubator/stdcxx/trunk/tests/containers/23.list.assign.cpp   (with props)
    incubator/stdcxx/trunk/tests/containers/23.list.capacity.cpp   (with props)
    incubator/stdcxx/trunk/tests/containers/23.list.cons.cpp   (with props)
    incubator/stdcxx/trunk/tests/containers/23.list.erase.cpp   (with props)
    incubator/stdcxx/trunk/tests/containers/23.list.insert.cpp   (with props)
    incubator/stdcxx/trunk/tests/containers/23.list.iterators.cpp   (with props)
    incubator/stdcxx/trunk/tests/containers/23.list.special.cpp   (with props)

Added: incubator/stdcxx/trunk/tests/containers/23.list.assign.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/containers/23.list.assign.cpp?view=auto&rev=522951
==============================================================================
--- incubator/stdcxx/trunk/tests/containers/23.list.assign.cpp (added)
+++ incubator/stdcxx/trunk/tests/containers/23.list.assign.cpp Tue Mar 27 08:16:23 2007
@@ -0,0 +1,557 @@
+/***************************************************************************
+ *
+ * 23.list.assign.cpp - test exercising [lib.list.assign]
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#include <list>           // for list
+#include <cstddef>        // for size_t
+
+#include <23.list.h>      // for ListMembers
+#include <alg_test.h>     // for InputIter
+#include <driver.h>       // for rw_test()
+#include <rw_allocator.h> // for UserAlloc
+#include <rw_new.h>       // for bad_alloc, replacement operator new
+
+/**************************************************************************/
+
+// for convenience and brevity
+#define Assign(sig) ListIds::assign_ ## sig
+
+static const char* const exceptions[] = {
+    "unknown exception", "bad_alloc", "exception"
+};
+
+/**************************************************************************/
+
+// used to exercise:
+// assign (InputIterator, InputIterator)
+static const ContainerTestCase
+range_test_cases [] = {
+
+#undef TEST
+#define TEST(lst, arg, off, size, res, bthrow) {                \
+        __LINE__, -1, -1, off, size, -1,                        \
+        lst, sizeof lst - 1,                                    \
+        arg, sizeof arg - 1, res, sizeof res - 1, bthrow        \
+    }
+
+    //    +------------------------------------------ controlled sequence
+    //    |                +------------------------- sequence to be inserted
+    //    |                |            +------------ assign() pos argument
+    //    |                |            |  +--------- assign() n argument
+    //    |                |            |  |  +------ expected result sequence
+    //    |                |            |  |  |  +--- exception info
+    //    |                |            |  |  |  |        0 - no exception
+    //    |                |            |  |  |  |        1 - out_of_range
+    //    |                |            |  |  |  |        2 - length_error
+    //    |                |            |  |  |  |       -1 - exc. safety
+    //    |                |            |  |  |  |       
+    //    |                |            |  |  |  +--------------------+
+    //    |                |            |  |  +------+                |
+    //    |                |            |  +------+  |                |
+    //    |                |            +---+     |  |                |
+    //    |                |                |     |  |                |
+    //    |                |                |     |  |                |
+    //    V                V                V     V  V                V
+    TEST ("ab",            "c",             0,    1, "c",             0),
+                                               
+    TEST ("",              "",              0,    0, "",              0),
+    TEST ("",              "abc",           1,    1, "b",             0),
+    TEST ("",              "<U0>",          0,    1, "<U0>",          0),
+                                               
+    TEST ("<U0>",          "",              0,    0, "",              0),
+                                               
+    TEST ("abc",           "",              0,    0, "",              0),
+                                               
+    TEST ("<U0>",          "a",             0,    1, "a",             0),
+    TEST ("<U0>",          "<U0>@2",        1,    1, "<U0>",          0),
+    TEST ("<U0>",          "<U0>@2",        0,    2, "<U0>@2",        0),
+    TEST ("<U0>",          "<U0>@2",        1,    5, "<U0>",          0),
+                                               
+    TEST ("cde",           "ab",            0,    2, "ab",            0),
+    TEST ("cde",           "ab",            0,    1, "a",             0),
+    TEST ("cde",           "ab",            1,    5, "b",             0),
+                                               
+    TEST ("ab",            "c<U0>e",        0,    3, "c<U0>e",        0),
+    TEST ("ab",            "c<U0>e",        1,    2, "<U0>e",         0),
+    TEST ("ab",            "c<U0>e",        0,    2, "c<U0>",         0),
+
+    TEST ("<U0>e<U0>",     "<U0>ab<U0>@2c", 0,    9, "<U0>ab<U0>@2c", 0),
+    TEST ("<U0>e<U0>",     "<U0>ab<U0>@2c", 0,    3, "<U0>ab",        0),
+    TEST ("a<U0>b<U0>@2c", "<U0>e<U0>",     0,    3, "<U0>e<U0>",     0),
+    TEST ("a<U0>b<U0>@2c", "<U0>@2e<U0>",   0,    2, "<U0>@2",        0),
+    TEST ("<U0>ab<U0>@2c", "<U0>e<U0>",     2,    1, "<U0>",          0),
+    TEST ("<U0>ab<U0>@2c", "<U0>e<U0>",     2,    9, "<U0>",          0),
+    TEST ("a<U0>bc<U0>@2", "<U0>e",         0,    2, "<U0>e",         0),
+
+    TEST ("x@4096",        "",              0,    0, "",              0),
+    TEST ("",              "x@4096",        9,    2, "xx",            0),
+    TEST ("",              "x@4096",        9,    0, "",              0),
+    TEST ("abc",           "x@4096",        2,    1, "x",             0),
+    TEST ("x@4096",        "x@4096",        2,    3, "xxx",           0),
+    TEST ("",              "x@4096",        0, 4096, "x@4096",        0),
+    TEST ("",              "x@4096",      100, 2000, "x@2000",        0),
+                   
+    TEST ("",              "x@207",         0,  207, "x@207",         0),
+    TEST ("x@128",         "x@334",        10,  207, "x@207",         0),
+    TEST ("x@540",         "x@207",        50,  128, "x@128",         0),
+    TEST ("",              "x@1412",      128,  873, "x@873",         0),
+    TEST ("x@128",         "x@1412",        0, 1412, "x@1412",        0),
+    TEST ("x@3695",        "x@1412",      207,  540, "x@540",         0),
+    TEST ("x@872",         "x@874",         1,  873, "x@873",         0),
+    TEST ("x@873",         "x@3695",       10, 2284, "x@2284",        0),
+                   
+    TEST ("",              "<U0>",          2,    0, "",              1),
+    TEST ("",              "a",             2,    0, "",              1),
+    TEST ("",              "x@4096",     4106,    0, "",              1),
+                                         
+    TEST ("last",          "test",          0,    4, "test",          0)
+};                                       
+                                         
+/**************************************************************************/
+
+// used to exercise:
+// assign (size_type, const value_type&)
+static const ContainerTestCase
+size_cref_test_cases [] = {
+
+#undef TEST
+#define TEST(lst, size, val, res, bthrow) {     \
+        __LINE__, -1, size, -1, -1, val,        \
+        lst, sizeof lst - 1,                    \
+        0, 0, res, sizeof res - 1, bthrow       \
+    }
+
+    //    +----------------------------------------- controlled sequence
+    //    |                +------------------------ assign() count argument
+    //    |                |   +-------------------- character to be assigned
+    //    |                |   |   +---------------- expected result sequence
+    //    |                |   |   |       +-------- exception info
+    //    |                |   |   |       |              0 - no exception
+    //    |                |   |   |       |              1 - out_of_range
+    //    |                |   |   |       |              2 - length_error
+    //    |                |   |   |       |             -1 - exc. safety
+    //    |                |   |   |       |
+    //    |                |   |   |       +--------+
+    //    V                V   V   V                V
+    TEST ("ab",            1, 'c', "c",             0),
+
+    TEST ("",              0, ' ',  "",             0),
+    TEST ("",              1, 'b',  "b",            0),
+    TEST ("",              3, 'b',  "bbb",          0),
+
+    TEST ("<U0>",          0, ' ',  "",             0),
+    TEST ("",              2, '\0', "<U0>@2",       0),
+
+    TEST ("<U0>",          1, 'a',  "a",            0),
+    TEST ("<U0>",          1, '\0', "<U0>",         0),
+    TEST ("<U0>",          2, '\0', "<U0>@2",       0),
+    TEST ("<U0>",          0, '\0', "",             0),
+
+    TEST ("cde",           3, 'a',  "aaa",          0),
+    TEST ("ab",            2, '\0', "<U0>@2",       0),
+    TEST ("ab",            1, '\0', "<U0>",         0),
+
+    TEST ("a<U0>b<U0>@2c", 2, '\0', "<U0>@2",       0),
+    TEST ("a<U0>b<U0>@2c", 1, '\0', "<U0>",         0),
+    TEST ("<U0>ab<U0>@2c", 3, '\0', "<U0>@3",       0),
+    TEST ("a<U0>bc<U0>@2", 2, 'a',  "aa",           0),
+
+    TEST ("",           4096, 'x',  "x@4096",       0),
+    TEST ("x@4096",        0, 'x',  "",             0),
+
+    TEST ("x@127",       128, 'x', "x@128",         0),
+    TEST ("x@200",       207, 'x', "x@207",         0),
+    TEST ("x@334",       128, 'x', "x@128",         0),
+    TEST ("",            540, 'x', "x@540",         0),
+    TEST ("xx",          873, 'x', "x@873",         0),
+    TEST ("x@873",      1412, 'x', "x@1412",        0),
+    TEST ("x@3695",      207, 'x', "x@207",         0),
+    TEST ("x@540",      3695, 'x', "x@3695",        0),
+
+    TEST ("last",          4, 't',  "tttt",         0)
+};
+
+/**************************************************************************/
+
+template <class InputIterator, class Distance>
+static inline void
+_rw_advance (InputIterator& it, Distance dist) {
+
+    while (0 < dist) {
+        --dist;
+        ++it;
+    }
+}
+
+// invokes specializations of the member function template
+// on the required iterator categories
+template <class List, class Iterator>
+struct AssignRange: ContRangeBase<List> {
+
+    typedef typename List::iterator       ListIter;
+    typedef typename List::value_type     ListVal;
+
+    AssignRange () { }
+
+    virtual List&
+    operator() (List &lst, 
+                const ContainerTestCaseData<ListVal>& tdata) const {
+
+        const ListVal* const beg = tdata.arg_ + tdata.off2_;
+        const ListVal* const end = beg + tdata.ext2_;
+
+        const Iterator first (beg, beg, end);
+        const Iterator last  (end, beg, end);
+
+        lst.assign (first, last);
+        return lst;
+    }
+};
+
+/**************************************************************************/
+
+// invokes possible overloads of the member function template
+// on common RandomAccessIterator types
+template <class List, class Iterator>
+struct AssignRangeOverload: ContRangeBase<List>
+{
+    typedef typename List::iterator       ListIter;
+    typedef typename List::value_type     ListVal;
+
+    AssignRangeOverload () { }
+
+    virtual List&
+    operator() (List &lst, 
+                const ContainerTestCaseData<ListVal>& tdata) const {
+
+        const ContainerTestCase &tcase = tdata.tcase_;
+
+        bool reverse_iter = ListIds::ReverseIterator == tdata.func_.iter_id_
+            || ListIds::ConstReverseIterator == tdata.func_.iter_id_;
+
+        const std::size_t off = tdata.arglen_ - tdata.off2_ - tdata.ext2_;
+
+        List str_arg (tdata.arg_, tdata.arg_ + tdata.arglen_);
+
+        Iterator first (this->begin (str_arg, (Iterator*)0));
+        _rw_advance (first, reverse_iter ? off : tdata.off2_);
+
+        Iterator last (first);
+        _rw_advance (last, tdata.ext2_);
+
+        lst.assign (first, last);
+        return lst;
+    }
+};
+
+/**************************************************************************/
+
+// invokes specializations of the member function template
+// on the required iterator categories
+template <class List, class Iterator>
+struct AssignRangePtrOverload: ContRangeBase<List> {
+
+    typedef typename List::value_type     ListVal;
+
+    AssignRangePtrOverload () { }
+
+    virtual List&
+    operator() (List& lst,
+                const ContainerTestCaseData<ListVal>& tdata) const {
+
+        const ListVal* const beg = tdata.arg_ + tdata.off2_;
+        const ListVal* const end = beg + tdata.ext2_;
+
+        const Iterator first = _RWSTD_CONST_CAST (const Iterator, beg);
+        const Iterator last  = _RWSTD_CONST_CAST (const Iterator, end);
+
+        lst.assign (first, last);
+        return lst;
+    }
+};
+
+/**************************************************************************/
+
+template <class T, class Allocator>
+void test_assign (T*, Allocator*,
+                  const ContRangeBase< std::list <T, Allocator> > &rng,
+                  const ContainerTestCaseData<T>                  &tdata)
+{
+    typedef std::list <T, Allocator>      List;
+    typedef typename List::iterator       ListIter;
+    typedef typename List::const_iterator ListCIter;
+    typedef ListState<List>               ListState;
+
+    const ContainerFunc     &func  = tdata.func_;
+    const ContainerTestCase &tcase = tdata.tcase_;
+
+    // construct the list object to be modified
+    List lst (tdata.str_, tdata.str_ + tdata.strlen_);
+
+    std::size_t size = tcase.size >= 0 ? tcase.size : 0;
+
+    rwt_free_store* const pst = rwt_get_free_store (0);
+    SharedAlloc*    const pal = SharedAlloc::instance ();
+
+    // iterate for`throw_after' starting at the next call to operator new,
+    // forcing each call to throw an exception, until the function finally
+    // succeeds (i.e, no exception is thrown)
+    std::size_t throw_count;
+    for (throw_count = 0; ; ++throw_count) {
+
+        // (name of) expected and caught exception
+        const char* expected = 0;
+        const char* caught   = 0;
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+        if (0 == tcase.bthrow) {
+            // by default exercise the exception safety of the function
+            // by iteratively inducing an exception at each call to operator
+            // new or Allocator::allocate() until the call succeeds
+            expected = exceptions [1];      // bad_alloc
+            *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_count + 1;
+            pal->throw_at_calls_ [pal->m_allocate] =
+                pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
+        }
+        else {
+            // exceptions disabled for this test case
+        }
+
+#else   // if defined (_RWSTD_NO_EXCEPTIONS)
+
+        if (tcase.bthrow) 
+            return;
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+        // start checking for memory leaks
+        rw_check_leaks (lst.get_allocator ());
+
+        try {
+            switch (func.which_) {
+
+            case Assign (size_cref): {
+                const T val = T::from_char (char (tcase.val));
+                lst.assign (size, val);
+                break;
+            }
+
+            case Assign (range):
+                rng (lst, tdata);
+                break;
+
+            default:
+                RW_ASSERT (!"test logic error: unknown assign overload");
+            }
+
+            // for convenience
+            static const int cwidth = sizeof (T);
+
+            const size_t got_size = lst.size ();
+            char* const got = new char [got_size + 1];
+
+            size_t index = 0;
+            for (ListCIter it = lst.begin (),
+                end = lst.end (); it != end; ++it) {
+                got [index++] = char (it->data_.val_);
+            }
+
+            got [got_size] = '\0';
+
+            // verify that list length are equal to the expected
+            rw_assert (tdata.reslen_ == got_size, 0, tcase.line,
+                       "line %d. %{$FUNCALL}: expected \"%{X=*}\" with length "
+                       "%zu, got %{/*.*Gs} with length %zu", __LINE__, 
+                       cwidth, int (tdata.reslen_), tdata.res_, tdata.reslen_,
+                       1, int (got_size), got, got_size);
+
+            if (tdata.reslen_ == got_size) {
+                // if the result length matches the expected length
+                // (and only then), also verify that the modified
+                // list matches the expected result
+                const std::size_t match =
+                    rw_match (tcase.res, got, got_size);
+
+                rw_assert (match == tdata.reslen_, 0, tcase.line,
+                           "line %d. %{$FUNCALL}: expected \"%{X=*}\", "
+                           "got %{/*.*Gs}, difference at off %zu",
+                           __LINE__, cwidth, int (tdata.reslen_), tdata.res_,
+                           1, int (got_size), got, match);
+            }
+
+            delete [] got;
+        }
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+        catch (const std::bad_alloc &ex) {
+            caught = exceptions [1];
+            rw_assert (0 == tcase.bthrow, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught std::%s(%#s)",
+                       __LINE__, 0 != expected, expected, caught, ex.what ());
+        }
+        catch (const std::exception &ex) {
+            caught = exceptions [2];
+            rw_assert (0, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught std::%s(%#s)",
+                       __LINE__, 0 != expected, expected, caught, ex.what ());
+        }
+        catch (...) {
+            caught = exceptions [0];
+            rw_assert (0, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught %s",
+                       __LINE__, 0 != expected, expected, caught);
+        }
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+        // FIXME: verify the number of blocks the function call
+        // is expected to allocate and detect any memory leaks
+        rw_check_leaks (lst.get_allocator (), tcase.line,
+                        std::size_t (-1), std::size_t (-1));
+
+        if (caught) {
+            if (0 == tcase.bthrow && caught == exceptions [1]) {
+                // allow this call to operator new to succeed and try
+                // to make the next one to fail during the next call
+                // to the same function again
+                continue;
+            }
+        }
+        else if (0 < tcase.bthrow) {
+            rw_assert (caught == expected, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s, caught %s"
+                       "%{:}unexpectedly caught %s%{;}",
+                       __LINE__, 0 != expected, expected, caught, caught);
+        }
+
+        break;
+    }
+
+    // disable bad_alloc exceptions
+    *pst->throw_at_calls_ [0] = 0;
+    pal->throw_at_calls_ [pal->m_allocate] = 0;
+}
+
+/**************************************************************************/
+
+template <class T, class Allocator>
+void test_assign (T*, Allocator*,
+                  const ContainerTestCaseData<T> &tdata)
+{
+    typedef std::list<T, Allocator> List;
+
+    if (tdata.func_.which_ == Assign (range)) {
+
+        switch (tdata.func_.iter_id_) {
+
+        // exercise possible overloads of the member function template
+        // on common RandomAccessIterator types
+#undef TEST
+#define TEST(Iterator) do {                                                 \
+        typedef typename List::Iterator Iter;                               \
+        static const                                                        \
+        AssignRangePtrOverload<List, Iter> rng;                                \
+        test_assign ((T*)0, (Allocator*)0, rng, tdata);                     \
+    } while (0)
+
+        case ListIds::Pointer: TEST (pointer); break;
+        case ListIds::ConstPointer: TEST (const_pointer); break;
+
+#undef TEST
+#define TEST(Iterator) do {                                                 \
+        typedef typename List::Iterator Iter;                               \
+        static const                                                        \
+        AssignRangeOverload<List, Iter> rng;                                \
+        test_assign ((T*)0, (Allocator*)0, rng, tdata);                     \
+    } while (0)
+
+        case ListIds::Iterator: TEST (iterator); break;
+        case ListIds::ConstIterator: TEST (const_iterator); break;
+
+        case ListIds::ReverseIterator: TEST (reverse_iterator); break;
+        case ListIds::ConstReverseIterator: TEST (const_reverse_iterator);
+            break;
+
+        // exercise specializations of the member function template
+        // on the required iterator categories
+
+#undef TEST
+#define TEST(Iterator) do {                                                 \
+        typedef Iterator<T> Iter;                                           \
+        static const                                                        \
+        AssignRange<List, Iter> rng;                                        \
+        test_assign ((T*)0, (Allocator*)0, rng, tdata);                     \
+    } while (0)
+
+        case ListIds::Input: TEST (InputIter); break;
+        case ListIds::Forward: TEST (ConstFwdIter); break;
+        case ListIds::Bidir: TEST (ConstBidirIter); break;
+        case ListIds::Random: TEST (ConstRandomAccessIter); break;
+
+        default:
+            rw_error (0, 0, __LINE__, "bad iterator id");
+        }
+    }
+    else {
+        // exercise ordinary overloads of the member function
+        static const ContRangeBase<List> rng;
+        test_assign ((T*)0, (Allocator*)0, rng, tdata);
+    }
+}
+
+/**************************************************************************/
+
+DEFINE_CONTAINER_TEST_FUNCTIONS (test_assign);
+
+int main (int argc, char** argv)
+{
+    static const ContainerTest
+    tests [] = {
+
+#undef TEST
+#define TEST(sig) {                                             \
+        Assign (sig), sig ## _test_cases,                       \
+        sizeof sig ## _test_cases / sizeof *sig ## _test_cases  \
+    }
+
+        TEST (size_cref),
+        TEST (range)
+    };
+
+    const std::size_t test_count = sizeof tests / sizeof *tests;
+
+    const int status =
+        rw_run_cont_test (argc, argv, __FILE__,
+                          "lib.list.assign",
+                          ContainerIds::List,
+                          test_assign_func_array, tests, test_count);
+
+    return status;
+}

Propchange: incubator/stdcxx/trunk/tests/containers/23.list.assign.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/stdcxx/trunk/tests/containers/23.list.assign.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/stdcxx/trunk/tests/containers/23.list.capacity.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/containers/23.list.capacity.cpp?view=auto&rev=522951
==============================================================================
--- incubator/stdcxx/trunk/tests/containers/23.list.capacity.cpp (added)
+++ incubator/stdcxx/trunk/tests/containers/23.list.capacity.cpp Tue Mar 27 08:16:23 2007
@@ -0,0 +1,624 @@
+/***************************************************************************
+ *
+ * 23.list.capacity.cpp - test exercising [lib.list.capacity]
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#include <list>             // for list
+#include <stddef.h>         // for size_t
+#include <stdexcept>        // for exception
+#include <23.list.h>        // for ListMembers
+#include <driver.h>         // for rw_test()
+#include <rw_allocator.h>   // for UserAlloc
+#include <rw_char.h>        // for rw_expand()
+#include <rw_new.h>         // for bad_alloc, replacement operator new
+
+/**************************************************************************/
+
+// for convenience and brevity
+#define Size(sig)                 ListIds::size_ ## sig
+#define MaxSize(sig)              ListIds::max_size_ ## sig
+#define Resize(sig)               ListIds::resize_ ## sig
+#define Clear(sig)                ListIds::clear_ ## sig
+#define Empty(sig)                ListIds::empty_ ## sig
+
+static const char* const exceptions[] = {
+    "unknown exception", "bad_alloc", "exception"
+};
+
+/**************************************************************************/
+
+// used to exercise
+// size ()
+static const ContainerTestCase
+size_void_test_cases [] = {
+
+#undef TEST
+#define TEST(str, res) {                    \
+        __LINE__, -1, -1, -1, -1, -1,       \
+        str, sizeof str - 1, 0, 0,          \
+        0, res, -1                          \
+    }
+
+    //    +--------------------------------------- controlled sequence
+    //    |                    +------------------ expected result
+    //    |                    |                   
+    //    |                    |                   
+    //    V                    V                   
+    TEST (0,                   0),
+    TEST ("",                  0),
+
+    TEST ("<U0>",              1),
+    TEST ("a",                 1),
+    TEST (" ",                 1),
+    TEST ("ab",                2),
+    TEST ("bc",                2),
+
+    TEST ("test string",      11),
+    TEST ("Test String",      11),
+
+    TEST ("t<U0> s",           4),
+    TEST ("Test<U0>string",   11),
+
+    TEST ("<U0>a<U0>b",        4),
+    TEST ("a<U0>@2b",          4),
+    TEST ("a<U0>@3b",          5),
+    TEST ("a<U0>@2b<U0>",      5),
+    TEST ("a<U0>b<U0>@2c",     6),
+    TEST ("a<U0>b<U0>c<U0>@2", 7),
+
+    TEST ("x@128",           128),
+    TEST ("x@207",           207),
+    TEST ("x@334",           334),
+    TEST ("x@540",           540),
+    TEST ("x@873",           873),
+    TEST ("x@1412",         1412),
+    TEST ("x@2284",         2284),
+    TEST ("x@3695",         3695),
+    TEST ("x@4096",         4096),
+
+    TEST ("last",              4)
+};
+
+/**************************************************************************/
+
+// used to exercise
+// max_size ()
+static const ContainerTestCase
+max_size_void_test_cases [] = {
+
+#undef TEST
+#define TEST(str) {                         \
+        __LINE__, -1, -1, -1, -1, -1,       \
+        str, sizeof str - 1, 0, 0,          \
+        0, 0, -1                            \
+    }
+
+    //    +------------------------------ controlled sequence
+    //    |                
+    //    |                               
+    //    |                               
+    //    V                             
+    TEST (0),     
+    TEST (""),   
+
+    TEST ("<U0>"),    
+    TEST ("a"),       
+
+    TEST ("test string"), 
+    TEST ("a<U0>b<U0>c<U0>@2"),  
+
+    TEST ("x@128"),     
+    TEST ("x@207"),    
+    TEST ("x@2284"),   
+    TEST ("x@3695"), 
+
+    TEST ("last")        
+};
+
+/**************************************************************************/
+
+// used to exercise
+// resize (size_type, value_type)
+static const ContainerTestCase
+resize_size_val_test_cases [] = {
+
+#undef TEST
+#define TEST(str, size, val, res, bthrow) {    \
+        __LINE__, -1, size, -1, -1, val,       \
+        str, sizeof str - 1, 0, 0,             \
+        res, sizeof res - 1, bthrow            \
+    }
+
+    //    +------------------------------------------ controlled sequence
+    //    |                      +------------------- new size
+    //    |                      |     +------------- value_type argument
+    //    |                      |     |    +-------- expected result sequence
+    //    |                      |     |    |      +- exception info
+    //    |                      |     |    |      |     0 - no exception
+    //    |                      |     |    |      |     1 - length_error
+    //    |                      |     |    |      |    
+    //    |                      |     |    |      +-----------+
+    //    V                      V     V    V                  V
+    TEST ("",                    0,   'a',  "",                0),
+    TEST ("",                    5,  '\0',  "<U0>@3<U0>@2",    0),
+    TEST ("",                  334,   'x',  "x@334",           0),
+
+    TEST ("<U0>",                0,   'a',  "",                0),
+    TEST ("<U0>",                2,   'a',  "<U0>a",           0),
+    TEST ("<U0>",                1,   'a',  "<U0>",            0),
+    TEST ("<U0>",              128,   'a',  "<U0>a@127",       0),
+
+    TEST ("a",                   0,   'a',  "",                0),
+    TEST ("a",                   2,  '\0',  "a<U0>",           0),
+    TEST ("a",                 540,   'a',  "a@540",           0),
+
+    TEST ("a<U0>@3b",           10,   'a',  "a<U0>@3baaaaa",   0),
+    TEST ("ab<U0>@3",           10,   'a',  "ab<U0>@3aaaaa",   0),
+    TEST ("<U0>@3ab",           10,   'a',  "<U0>@3abaaaaa",   0),
+    TEST ("a<U0>@3b",            7,  '\0',  "a<U0>@3b<U0>@2",  0),
+    TEST ("ab<U0>@3",            7,  '\0',  "ab<U0>@3<U0>@2",  0),
+    TEST ("<U0>@3ba",            7,  '\0',  "<U0>@3ba<U0>@2",  0),
+
+    TEST ("a<U0>b<U0>c<U0>@2",   6,   'a',  "a<U0>b<U0>c<U0>", 0),
+    TEST ("a<U0>b<U0>c<U0>@2",   5,  '\0',  "a<U0>b<U0>c",     0),
+    TEST ("<U0>ba<U0>c<U0>@2",   1,  '\0',  "<U0>",            0),
+    TEST ("<U0>ba<U0>c<U0>@2",   0,  '\0',  "",                0),
+
+    TEST ("x@540",             127,   'a',  "x@127",           0),
+    TEST ("x@873",             127,   'a',  "x@127",           0),
+    TEST ("x@1412",            127,   'a',  "x@127",           0),
+    TEST ("x@2284",            127,   'a',  "x@127",           0),
+
+    TEST ("x@127",             128,   'a',  "x@127a",          0),
+    TEST ("x@128",             207,   'a',  "x@128a@79",       0),
+    TEST ("x@207",             334,   'a',  "x@207a@127",      0),
+    TEST ("x@334",             540,   'a',  "x@334a@206",      0),
+    TEST ("x@540",             873,   'a',  "x@540a@333",      0),
+    TEST ("x@873",            1412,   'a',  "x@873a@539",      0),
+    TEST ("x@1412",           2284,   'a',  "x@1412a@872",     0),
+    TEST ("x@2284",           3695,   'a',  "x@2284a@1411",    0),
+
+    TEST ("last",                4,   't',  "last",            0)
+};
+
+/**************************************************************************/
+
+// used to exercise
+// resize (size_type)
+static const ContainerTestCase
+resize_size_test_cases [] = {
+
+#undef TEST
+#define TEST(str, size, res, bthrow) {      \
+        __LINE__, -1, size, -1, -1, -1,     \
+        str, sizeof str - 1, 0, 0,          \
+        res, sizeof res - 1, bthrow         \
+    }
+
+    //    +------------------------------------------ controlled sequence
+    //    |                      +------------------- new size
+    //    |                      |    +-------------- expected result sequence
+    //    |                      |    |              +-- exception info
+    //    |                      |    |              |      0 - no exception
+    //    |                      |    |              |      1 - length_error
+    //    |                      |    |              |
+    //    V                      V    V              V    
+    TEST ("",                    0,   "",            0),
+    TEST ("",                    5,   "\0@5",        0),
+    TEST ("",                  334,   "\0@334",      0),
+
+    TEST ("<U0>",                0,   "",            0),
+    TEST ("<U0>",                2,   "\0@2",        0),
+    TEST ("<U0>",                1,   "\0",          0),
+    TEST ("<U0>",              127,   "\0@127",      0),
+
+    TEST ("a",                   0,   "",            0),
+    TEST ("a",                   2,   "a\0",         0),
+    TEST ("a",                 539,   "a\0@538",     0),
+
+    TEST ("a<U0>@3b",           10,   "a<U0>@3b\0@5", 0),
+    TEST ("ab<U0>@3",           10,   "ab<U0>@3\0@5", 0),
+    TEST ("<U0>@3ab",           10,   "<U0>@3ab\0@5", 0),
+    TEST ("a<U0>@3b",            7,   "a<U0>@3b\0@2", 0),
+    TEST ("ab<U0>@3",            7,   "ab<U0>@3\0@2", 0),
+    TEST ("<U0>@3ba",            7,   "<U0>@3ba\0@2", 0),
+
+    TEST ("a<U0>b<U0>c<U0>@2",   5,   "a<U0>b<U0>c", 0),
+    TEST ("a<U0>b<U0>c<U0>@2",   4,   "a<U0>b<U0>",  0),
+    TEST ("<U0>ba<U0>c<U0>@2",   1,   "<U0>",        0),
+    TEST ("<U0>ba<U0>c<U0>@2",   0,   "",            0),
+
+    TEST ("x@540",             127,   "x@127",       0),
+    TEST ("x@873",             127,   "x@127",       0),
+    TEST ("x@1412",            127,   "x@127",       0),
+    TEST ("x@2284",            127,   "x@127",       0),
+
+    TEST ("x@127",             128,   "x@127\0",     0),
+    TEST ("x@128",             207,   "x@128\0@79",  0),
+    TEST ("x@207",             334,   "x@207\0@127", 0),
+    TEST ("x@334",             540,   "x@334\0@206", 0),
+    TEST ("x@540",             873,   "x@540\0@333", 0),
+    TEST ("x@873",            1412,   "x@873\0@539", 0),
+    TEST ("x@1412",           2284,   "x@1412\0@872", 0),
+    TEST ("x@2284",           3695,   "x@2284\0@1411", 0),
+
+    TEST ("last",                4,   "last",        0)
+};
+
+/**************************************************************************/
+
+// used to exercise
+// clear ()
+static const ContainerTestCase
+clear_void_test_cases [] = {
+
+#undef TEST
+#define TEST(str) {                         \
+        __LINE__, -1, -1, -1, -1, -1,       \
+        str, sizeof str - 1, 0, 0,          \
+        "", 0, -1                           \
+    }
+
+    //    +------------------------------ controlled sequence
+    //    |                
+    //    |                               
+    //    |                               
+    //    V  
+    TEST (0), 
+    TEST (""),   
+
+    TEST ("<U0>"),    
+    TEST ("a"),       
+
+    TEST ("test string"), 
+    TEST ("a<U0>b<U0>c<U0>@2"),  
+
+    TEST ("x@128"),     
+    TEST ("x@207"),    
+    TEST ("x@334"),
+    TEST ("x@540"),
+    TEST ("x@873"),
+    TEST ("x@1412"),
+    TEST ("x@2284"),   
+    TEST ("x@3695"), 
+    TEST ("x@4096"), 
+
+    TEST ("last") 
+};
+
+/**************************************************************************/
+
+// used to exercise
+// empty ()
+static const ContainerTestCase
+empty_void_test_cases [] = {
+
+#undef TEST
+#define TEST(str, res) {                 \
+    __LINE__, -1, -1, -1, -1, -1,    \
+    str, sizeof str - 1, 0, 0,       \
+    0, res, -1                       \
+}
+
+    //    +------------------------------ controlled sequence
+    //    |              +--------------- expected result              
+    //    |              |                     
+    //    |              |                     
+    //    V              V
+    TEST (0,             1), 
+    TEST ("",            1),   
+
+    TEST ("<U0>",        0),    
+    TEST ("a",           0),       
+    TEST ("<U0>ab<U0>c", 0),  
+
+    TEST ("x@128",       0),     
+    TEST ("x@3695",      0), 
+
+    TEST ("last",        0) 
+};
+
+/**************************************************************************/
+
+template <class T, class Allocator>
+void test_capacity (T*, Allocator*,
+                    const ContainerTestCaseData<T> &tdata)
+{
+    typedef std::list<T, Allocator>       List;
+    typedef typename List::iterator       ListIter;
+    typedef typename List::const_iterator ListCIter;
+    typedef ListState<List>               ListState;
+
+    const ContainerFunc     &func  = tdata.func_;
+    const ContainerTestCase &tcase = tdata.tcase_;
+
+    // construct the list object to be modified and constant one
+          List  lst (tdata.str_, tdata.str_ + tdata.strlen_, Allocator ());
+    const List clst (tdata.str_, tdata.str_ + tdata.strlen_, Allocator ());
+
+    // save the state of the list object before the call
+    // to detect exception safety violations (changes to
+    // the state of the object after an exception)
+    const ListState lst_state (lst);
+
+    const T arg_val = T::from_char (-1 != tcase.val ? char (tcase.val) : char ());
+
+    rwt_free_store* const pst = rwt_get_free_store (0);
+    SharedAlloc*    const pal = SharedAlloc::instance ();
+
+    // iterate for`throw_after' starting at the next call to operator new,
+    // forcing each call to throw an exception, until the function finally
+    // succeeds (i.e, no exception is thrown)
+    size_t throw_count;
+    for (throw_count = 0; ; ++throw_count) {
+
+        // (name of) expected and caught exception
+        const char* expected = 0;
+        const char* caught   = 0;
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+        if (0 == tcase.bthrow) {
+            // by default exercise the exception safety of the function
+            // by iteratively inducing an exception at each call to operator
+            // new or Allocator::allocate() until the call succeeds
+            expected = exceptions [1];      // bad_alloc
+            *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_count + 1;
+            pal->throw_at_calls_ [pal->m_allocate] =
+                pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
+        }
+        else {
+            // exceptions disabled for this test case
+        }
+
+#else   // if defined (_RWSTD_NO_EXCEPTIONS)
+
+        if (tcase.bthrow) {
+            return;
+        }
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+        const bool is_class = ListIds::UserClass == func.elem_id_;
+
+        const size_t x_count_save = UserClass::count_;
+
+        // start checking for memory leaks
+        rw_check_leaks (lst.get_allocator ());
+
+        size_t res = 0;
+
+        try {
+
+            // reset function call counters
+            if (is_class)
+                UserClass::reset_totals ();
+
+            switch (func.which_) {
+
+            case Size (void):
+                res = clst.size ();
+                break;
+
+            case MaxSize (void):
+                res = clst.max_size ();
+                break;
+
+            case Resize (size_val):
+                 lst.resize (tcase.size, arg_val);
+                break;
+
+            case Resize (size):
+                lst.resize (tcase.size);
+                break;
+
+            case Clear (void):
+                lst.clear ();
+                break;
+
+            case Empty (void):
+                res = clst.empty () ? 1 : 0;
+                break;
+
+            default:
+                RW_ASSERT (!"test logic error: unknown capacity overload");
+            }
+
+            if (is_class
+              &&
+                (func.which_ == ListIds::clear_void
+              || func.which_ == ListIds::resize_size
+              || func.which_ == ListIds::resize_size_val)) {
+
+                  size_t nctors = tdata.reslen_ > tdata.strlen_ ? 
+                      tdata.reslen_ - tdata.strlen_ : 0;
+
+                  size_t ndtors = tdata.reslen_ < tdata.strlen_ ? 
+                      tdata.strlen_ - tdata.reslen_ : 0;
+
+                  size_t new_count = x_count_save + nctors - ndtors;
+
+                  size_t ndefctors = 0;
+
+                  if (func.which_ == ListIds::resize_size_val)
+                      ++nctors;
+                  else if (func.which_ == ListIds::resize_size)
+                      ++ndefctors;
+
+                  bool success = UserClass::is_total (new_count, ndefctors,
+                                                      nctors, 0, 0, 0);
+                  rw_assert (success, 0, tcase.line,
+                             "line %d. %{$FUNCALL} called default/copy ctor "
+                             "and operator=() %zu, %zu, and %zu times, "
+                             "respectively, %zu, %zu, 0 expected",
+                             __LINE__,
+                             UserClass::n_total_def_ctor_,
+                             UserClass::n_total_copy_ctor_,
+                             UserClass::n_total_op_assign_,
+                             ndefctors, nctors);
+            }
+
+            // verify the returned value
+            if (func.which_ == ListIds::size_void 
+             || func.which_ == ListIds::empty_void) {
+                rw_assert (res == tcase.nres, 0, tcase.line,
+                           "line %d. %{$FUNCALL} expected %zu, got %zu",
+                           __LINE__, tcase.nres, res);
+            }
+
+            if (func.which_ == ListIds::max_size_void) {
+                size_t cur_sz = clst.size ();
+
+                rw_assert (cur_sz <= res, 0, tcase.line,
+                           "line %d. %{$FUNCALL} == %zu, expected res > %zu",
+                           __LINE__, res, cur_sz);
+            }
+
+            if (func.which_ == ListIds::resize_size_val 
+             || func.which_ == ListIds::resize_size
+             || func.which_ == ListIds::clear_void) {
+
+                 // for convenience
+                static const int cwidth = sizeof (T);
+
+                const size_t got_size = lst.size ();
+                char* const got = new char [got_size + 1];
+
+                size_t index = 0;
+                for (ListCIter it = lst.begin (),
+                    end = lst.end (); it != end; ++it) {
+                    got [index++] = char (it->data_.val_);
+                }
+
+                got [got_size] = '\0';
+
+                // verify that strings length are equal
+                rw_assert (tdata.reslen_ == got_size, 0, tcase.line,
+                           "line %d. %{$FUNCALL} expected \"%{X=*}\" "
+                           "with length %zu, got %{/*.*Gs} with length %zu",
+                           __LINE__, cwidth, int (tdata.reslen_),
+                           tdata.res_, tdata.reslen_,
+                           1, int (got_size), got, got_size);
+
+                if (tdata.reslen_ == got_size) {
+                    // if the result length matches the expected length
+                    // (and only then), also verify that the modified
+                    // list matches the expected result
+                    const size_t match = rw_match (tcase.res, got, got_size);
+
+                    rw_assert (match == tdata.reslen_, 0, tcase.line,
+                               "line %d. %{$FUNCALL} expected \"%{X=*}\", "
+                               "got %{/*.*Gs}, difference at offset %zu",
+                               __LINE__,
+                               cwidth, int (tdata.reslen_), tdata.res_,
+                               1, int (got_size), got, match);
+                }
+
+                delete [] got;
+            }
+        }
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+        catch (const std::bad_alloc &ex) {
+            caught = exceptions [1];
+            rw_assert (0 == tcase.bthrow, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught std::%s(%#s)",
+                       __LINE__, 0 != expected, expected, caught, ex.what ());
+        }
+        catch (const std::exception &ex) {
+            caught = exceptions [2];
+            rw_assert (0, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught std::%s(%#s)",
+                       __LINE__, 0 != expected, expected, caught, ex.what ());
+        }
+        catch (...) {
+            caught = exceptions [0];
+            rw_assert (0, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught %s",
+                       __LINE__, 0 != expected, expected, caught);
+        }
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+        // FIXME: verify the number of blocks the function call
+        // is expected to allocate and detect any memory leaks
+        rw_check_leaks (lst.get_allocator (), tcase.line,
+            size_t (-1), size_t (-1));
+
+        if (caught) {
+            // verify that an exception thrown during allocation
+            // didn't cause a change in the state of the object
+            lst_state.assert_equal (ListState (lst),
+                __LINE__, tcase.line, caught);
+
+            if (0 == tcase.bthrow) {
+                // allow this call to operator new to succeed and try
+                // to make the next one to fail during the next call
+                // to the same function again
+                continue;
+            }
+        }
+
+        break;
+    }
+
+    // disable bad_alloc exceptions
+    *pst->throw_at_calls_ [0] = 0;
+    pal->throw_at_calls_ [pal->m_allocate] = 0;
+}
+
+/**************************************************************************/
+
+DEFINE_CONTAINER_TEST_FUNCTIONS (test_capacity);
+
+int main (int argc, char** argv)
+{
+    static const ContainerTest
+    tests [] = {
+
+#undef TEST
+#define TEST(gsig, sig) {                                   \
+    gsig, sig ## _test_cases,                               \
+    sizeof sig ## _test_cases / sizeof *sig ## _test_cases  \
+}
+
+        TEST (ListIds::size_void, size_void),
+        TEST (ListIds::max_size_void, max_size_void),
+        TEST (ListIds::resize_size_val, resize_size_val),
+        TEST (ListIds::resize_size, resize_size),
+        TEST (ListIds::clear_void, clear_void),
+        TEST (ListIds::empty_void, empty_void)
+    };
+
+    const size_t test_count = sizeof tests / sizeof *tests;
+
+    return rw_run_cont_test (argc, argv, __FILE__,
+                             "lib.list.capacity",
+                             ContainerIds::List,
+                             test_capacity_func_array, tests, test_count);
+}

Propchange: incubator/stdcxx/trunk/tests/containers/23.list.capacity.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/stdcxx/trunk/tests/containers/23.list.capacity.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/stdcxx/trunk/tests/containers/23.list.cons.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/containers/23.list.cons.cpp?view=auto&rev=522951
==============================================================================
--- incubator/stdcxx/trunk/tests/containers/23.list.cons.cpp (added)
+++ incubator/stdcxx/trunk/tests/containers/23.list.cons.cpp Tue Mar 27 08:16:23 2007
@@ -0,0 +1,1001 @@
+/***************************************************************************
+ *
+ * 23.list.cons.cpp - test exercising list constructors [lib.list.cons]
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <list>             // for list
+#include <cstddef>          // for size_t
+
+#include <23.list.h>        // for ListMembers
+#include <alg_test.h>       // for InputIter
+#include <driver.h>         // for rw_test()
+#include <rw_allocator.h>   // for UserAlloc
+#include <rw_new.h>         // for bad_alloc, replacement operator new
+
+/**************************************************************************/
+
+// for convenience and brevity
+#define Cons(sig)               ListIds::ctor_ ## sig
+#define OpSet(sig)              ListIds::op_set_ ## sig
+
+static const char* const exceptions[] = {
+    "unknown exception", "bad_alloc", "exception", "UserClass::CopyCtor"
+};
+
+/**************************************************************************/
+
+// exercises:
+// list (void)
+// list (const allocator_type&)
+#define alloc_test_cases void_test_cases
+static const ContainerTestCase
+void_test_cases [] = { 
+
+#undef TEST
+#define TEST(dummy) {                            \
+        __LINE__, -1, -1, -1, -1, -1,            \
+        0, 0, dummy, sizeof dummy - 1,           \
+        "", 0, 0                                 \
+    }
+
+    //    +--------------------- dummy argument
+    //    |
+    //    V             
+    TEST ("ab"),          
+
+    TEST ("last test")
+};
+
+/**************************************************************************/
+
+// exercises:
+// list (const list&)
+static const ContainerTestCase
+ccont_test_cases [] = {
+
+#undef TEST
+#define TEST(arg, res) {                            \
+        __LINE__, -1, -1, -1, -1, -1,               \
+        0, 0, arg, sizeof arg - 1,                  \
+        res, sizeof res - 1, 0                      \
+    }
+
+    //    +----------------------------------------- source sequence
+    //    |               +------------------------- expected result sequence
+    //    |               |             
+    //    |               |            
+    //    V               V           
+    TEST ("ab",           "ab"),    
+
+    TEST ("",             ""),   
+    TEST ("<U0>",         "<U0>"),
+    TEST ("<U0>@2",       "<U0>@2"),
+
+    TEST ("a",            "a"),       
+    TEST ("bcd",          "bcd"),       
+    TEST ("cdefaihjb",    "cdefaihjb"),      
+
+    TEST ("<U0>@2ab",     "<U0>@2ab"),  
+    TEST ("a<U0>@2b",     "a<U0>@2b"), 
+    TEST ("ab<U0>@2",     "ab<U0>@2"),  
+    TEST ("abefdcc<U0>a", "abefdcc<U0>a"),  
+
+    TEST ("x@128",        "x@128"),
+    TEST ("x@207",        "x@207"),
+    TEST ("x@334",        "x@334"),
+    TEST ("x@540",        "x@540"),
+    TEST ("x@873",        "x@873"),
+    TEST ("x@1412",       "x@1412"),
+    TEST ("x@3695",       "x@3695"),
+    TEST ("x@4096",       "x@4096"),     
+
+    TEST ("last test",    "last test")
+};
+
+/**************************************************************************/
+
+// exercises:
+// list (InputIterator, InputIterator)
+// list (InputIterator, InputIterator, const allocator&)
+#define range_alloc_test_cases range_test_cases
+static const ContainerTestCase
+range_test_cases [] = {
+
+#undef TEST
+#define TEST(arg, off, size, res, bthrow) {         \
+        __LINE__, -1, -1, off, size, -1,            \
+        0, 0, arg, sizeof arg - 1,                  \
+        res, sizeof res - 1, bthrow                 \
+    }
+
+    //    +----------------------------------------- source sequence
+    //    |               +------------------------- ctor off argument
+    //    |               |   +--------------------- ctor n argument
+    //    |               |   |    +---------------- expected result sequence
+    //    |               |   |    |                +--- exception info
+    //    |               |   |    |                |       0 - no exception
+    //    |               |   |    |                |       1 - out_of_range
+    //    |               |   |    |                |
+    //    |               |   |    |                |
+    //    V               V   V    V                V
+    TEST ("ab",           0,  2,   "ab",            0),    
+
+    TEST ("",             0,  0,   "",              0),   
+    TEST ("<U0>",         0,  1,   "<U0>",          0),
+    TEST ("<U0>@2",       0,  2,   "<U0>@2",        0),
+
+    TEST ("a",            0,  1,   "a",             0),       
+    TEST ("bcd",          0,  3,   "bcd",           0),       
+    TEST ("cdefaihjb",    0,  9,   "cdefaihjb",     0),      
+
+    TEST ("<U0>@2ab",     0,  4,   "<U0>@2ab",      0),  
+    TEST ("a<U0>@2b",     0,  4,   "a<U0>@2b",      0), 
+    TEST ("ab<U0>@2",     0,  4,   "ab<U0>@2",      0),  
+    TEST ("abefdcc<U0>a", 0,  9,   "abefdcc<U0>a",  0),  
+
+    TEST ("x@207",        0,  207, "x@207",         0),
+    TEST ("x@334",       10,  207, "x@207",         0),
+    TEST ("x@207",       50,  128, "x@128",         0),
+    TEST ("x@1412",     128,  873, "x@873",         0),
+    TEST ("x@1412",       0, 1412, "x@1412",        0),
+    TEST ("x@1412",     207,  540, "x@540",         0),
+    TEST ("x@874",        1,  873, "x@873",         0),
+    TEST ("x@3695",      10, 2284, "x@2284",        0),
+    TEST ("x@4096",       0, 4096, "x@4096",        0),     
+
+    TEST ("last test",    0,  9,  "last test",      0)
+};
+
+/**************************************************************************/
+
+// exercises:
+// list (size_type)
+static const ContainerTestCase
+size_test_cases [] = {
+
+#undef TEST
+#define TEST(size, res) {                      \
+        __LINE__, -1, size, -1, -1, 0,         \
+        0, 0, 0, 0,                            \
+        res, sizeof res - 1, 0                 \
+    }
+
+    //    +---------------------------------------- ctor n argument 
+    //    |         +------------------------------ expected result sequence
+    //    |         |             
+    //    |         |            
+    //    V         V         
+    TEST (1,        "<U0>"),
+    TEST (2,        "<U0>@2"),
+    TEST (5,        "<U0>@5"),
+    TEST (10,       "<U0>@10"),
+    TEST (128,      "<U0>@128"),
+    TEST (207,      "<U0>@207"),
+    TEST (540,      "<U0>@540"),
+    TEST (873,      "<U0>@873"),
+    TEST (1412,     "<U0>@1412"),
+    TEST (3695,     "<U0>@3695"),
+    TEST (4096,     "<U0>@4096")
+};
+
+/**************************************************************************/
+
+// exercises:
+// list (size_type, const value_type&)
+// list (size_type, const value_type&, const allocator_type&)
+#define size_cref_alloc_test_cases size_cref_test_cases
+static const ContainerTestCase
+size_cref_test_cases [] = {
+
+#undef TEST
+#define TEST(size, val, res) {                      \
+    __LINE__, -1, size, -1, -1, val,            \
+    0, 0, 0, 0,                                 \
+    res, sizeof res - 1, 0                      \
+}
+
+    //    +---------------------------------------- ctor n argument 
+    //    |          +----------------------------- source value
+    //    |          |    +------------------------ expected result sequence
+    //    |          |    |             
+    //    |          |    |            
+    //    V          V    V         
+    TEST (1,        'a',  "a"), 
+    TEST (1,        '\0', "<U0>"),
+
+    TEST (2,        'a',  "aa"), 
+    TEST (2,        '\0', "<U0>@2"),
+
+    TEST (5,        '\0', "<U0>@5"),
+    TEST (10,       'a',  "aaaaaaaaaa"), 
+
+    TEST (128,      'x',  "x@128"),
+    TEST (207,      'x',  "x@207"),
+    TEST (540,      'x',  "x@540"),
+    TEST (873,      'x',  "x@873"),
+    TEST (1412,     'x',  "x@1412"),
+    TEST (3695,     'x',  "x@3695"),
+
+    TEST (4096,     'x',  "x@4096"),
+
+    TEST (4,        't',  "tttt") 
+};
+
+/**************************************************************************/
+// exercises:
+// operator= (const list&)
+static const ContainerTestCase
+ccont_op_set_test_cases [] = {
+
+#undef TEST
+#define TEST(str, arg, res, bthrow) {               \
+    __LINE__, -1, -1, -1, -1, -1,               \
+    str, sizeof str - 1, arg, sizeof arg - 1,   \
+    res, sizeof res - 1, bthrow                 \
+}
+
+    //    +----------------------------------------- source sequence
+    //    |          +------------------------------ argument sequence
+    //    |          |              +--------------- expected result sequence
+    //    |          |              |                +- exception info
+    //    |          |              |                |    0 - no exception
+    //    |          |              |                |   -1 - excpetion safety
+    //    |          |              |                |  
+    //    |          |              |                |            
+    //    V          V              V                V
+    TEST ("",       "ab",           "ab",            0),    
+
+    TEST ("",       "",             "",              0),   
+    TEST ("abc",    "",             "",              0),   
+    TEST ("",       "<U0>",         "<U0>",          0), 
+    TEST ("abc",    "<U0>",         "<U0>",          0),
+
+    TEST ("",       "a",            "a",             0),  
+    TEST ("<U0>@2", "a",            "a",             0), 
+    TEST ("a",      "bcd",          "bcd",           0),       
+    TEST ("x@4096", "bcd",          "bcd",           0), 
+    TEST ("",       "cdefaihjb",    "cdefaihjb",     0),      
+    TEST ("a<U0>b", "cdefaihjb",    "cdefaihjb",     0),
+
+    TEST ("",       "<U0>@2ab",     "<U0>@2ab",      0),  
+    TEST ("c<U0>d", "<U0>@2ab",     "<U0>@2ab",      0),
+    TEST ("",       "a<U0>@2b",     "a<U0>@2b",      0), 
+    TEST ("bcd",    "a<U0>@2b",     "a<U0>@2b",      0), 
+    TEST ("<U0>",   "ab<U0>@2",     "ab<U0>@2",      0), 
+    TEST ("x@4096", "ab<U0>@2",     "ab<U0>@2",      0), 
+    TEST ("<U0>a",  "abefdcc<U0>a", "abefdcc<U0>a",  0),  
+    TEST ("x@4096", "abefdcc<U0>a", "abefdcc<U0>a",  0),
+
+    TEST ("",       "x@207",        "x@207",         0),
+    TEST ("x@128",  "x@207",        "x@207",         0),
+    TEST ("x@540",  "x@207",        "x@207",         0),
+    TEST ("",       "x@1412",       "x@1412",        0),
+    TEST ("x@128",  "x@1412",       "x@1412",        0),
+    TEST ("x@3695", "x@1412",       "x@1412",        0),
+    TEST ("x@872",  "x@873",        "x@873",         0),
+    TEST ("x@873",  "x@3695",       "x@3695",        0),
+
+    TEST ("abc",    "x@4096",       "x@4096",        0),   
+
+    TEST ("",           0,          "",              0),
+    TEST ("a<U0>b<U0>", 0,          "a<U0>b<U0>",    0), 
+    TEST ("x@4096",     0,          "x@4096",        0), 
+
+    TEST ("",       "last test",    "last test",     0)
+};
+
+/**************************************************************************/
+
+// invokes specializations of the member function template
+// on the required iterator categories
+template <class List, class Iterator>
+struct ConsRange: ContRangeBase<List> {
+
+    typedef typename List::value_type     ListVal;
+    typedef typename List::allocator_type ListAlloc;
+
+    ConsRange () { }
+
+    virtual List&
+    operator() (List&, const ContainerTestCaseData<ListVal>& tdata) const {
+
+        const ListVal* const beg = tdata.arg_ + tdata.off2_;
+        const ListVal* const end = beg + tdata.ext2_;
+
+        const Iterator first (beg, beg, end);
+        const Iterator last  (end, beg, end);
+
+        if (Cons (range_alloc) == tdata.func_.which_) {
+            ListAlloc alloc;
+            List* tmp = new List (first, last, alloc);
+            return *tmp;
+        }
+
+        List* tmp = new List (first, last);
+        return *tmp;
+    }
+};
+
+/**************************************************************************/
+
+// invokes specializations of the member function template
+// on the required iterator categories
+template <class List, class Iterator>
+struct ConsRangePtrOverload: ContRangeBase<List> {
+
+    typedef typename List::value_type     ListVal;
+    typedef typename List::allocator_type ListAlloc;
+
+    ConsRangePtrOverload () { }
+
+    virtual List&
+    operator() (List&, const ContainerTestCaseData<ListVal>& tdata) const {
+
+        const ListVal* const beg = tdata.arg_ + tdata.off2_;
+        const ListVal* const end = beg + tdata.ext2_;
+
+        const Iterator first = _RWSTD_CONST_CAST (const Iterator, beg);
+        const Iterator last  = _RWSTD_CONST_CAST (const Iterator, end);
+
+        if (Cons (range_alloc) == tdata.func_.which_) {
+            ListAlloc alloc;
+            List* tmp = new List (first, last, alloc);
+            return *tmp;
+        }
+
+        List* tmp = new List (first, last);
+        return *tmp;
+    }
+};
+
+/**************************************************************************/
+
+template <class InputIterator, class Distance>
+static inline void
+_rw_advance (InputIterator& it, Distance dist) {
+
+    while (0 < dist) {
+        --dist;
+        ++it;
+    }
+}
+
+// invokes possible overloads of the member function template
+// on common RandomAccessIterator types
+template <class List, class Iterator>
+struct ConsRangeOverload: ContRangeBase<List>
+{
+    //typedef typename List::iterator       ListIter;
+    typedef typename List::value_type     ListVal;
+    typedef typename List::allocator_type ListAlloc;
+
+    ConsRangeOverload () { }
+
+    virtual List&
+    operator() (List& list_arg, 
+        const ContainerTestCaseData<ListVal>& tdata) const {
+
+        bool reverse_iter =
+            ContainerIds::ReverseIterator      == tdata.func_.iter_id_
+         || ContainerIds::ConstReverseIterator == tdata.func_.iter_id_;
+
+        const std::size_t off = reverse_iter ? 
+            tdata.arglen_ - tdata.off2_ - tdata.ext2_ : tdata.off2_;
+        const std::size_t ext = tdata.ext2_;
+
+        Iterator first (this->begin (list_arg, (Iterator*)0));
+        _rw_advance (first, off);
+
+        Iterator last (first);
+        _rw_advance (last, ext);
+
+        if (Cons (range_alloc) == tdata.func_.which_) {
+            ListAlloc alloc;
+            List* tmp = new List (first, last, alloc);
+            return *tmp;
+        }
+
+        List* tmp = new List (first, last);
+        return *tmp;
+    }
+};
+
+/**************************************************************************/
+
+template <class T, class Allocator>
+void test_cons (T*, Allocator*, const ContRangeBase<
+                std::list <T, Allocator> > &rng,
+                const ContainerTestCaseData<T>  &tdata)
+{
+    typedef std::list <T, Allocator>      List;
+    typedef typename List::iterator       ListIter;
+    typedef typename List::const_iterator ListCIter;
+
+    const ContainerFunc     &func  = tdata.func_;
+    const ContainerTestCase &tcase = tdata.tcase_;
+
+    // construct the argument list 
+    /* const */ List arg (tdata.arg_, tdata.arg_ + tdata.arglen_);
+
+    // list function argument
+    const List&        arg_list = arg;
+    const T            arg_val = T::from_char (char (tcase.val));
+    const Allocator    arg_alc;
+
+    // have UserClass copy ctor throw an exception during
+    // the copying of the last value
+    for (UserClass::copy_ctor_throw_count_ = tdata.reslen_; ;
+        ++UserClass::copy_ctor_throw_count_) {
+
+        // (name of) expected and caught exception
+        const char* expected = 0;
+        const char* caught   = 0;
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+        if (0 == tcase.bthrow) {
+            // by default exercise the exception safety of the
+            // function by iteratively inducing an exception at
+            // each call to UserClass::UserClass(const UserClass&)
+            // until the call succeeds
+            expected = exceptions [3];      // UserClass::CopyCtor
+        }
+        else {
+            // exceptions disabled for this test case
+        }
+
+#else   // if defined (_RWSTD_NO_EXCEPTIONS)
+
+        if (tcase.bthrow) {
+            return;
+        }
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+
+        // pointer to the returned reference
+        List* ret_ptr = 0;
+
+        // start checking for memory leaks
+        rwt_check_leaks (0, 0);
+
+        const bool is_class = ListIds::UserClass == func.elem_id_;
+
+        const size_t x_count_save = UserClass::count_;
+
+        try {
+            ListIds::OverloadId which =
+                _RWSTD_STATIC_CAST (ListIds::OverloadId, func.which_);
+
+            // reset function call counters
+            if (is_class)
+                UserClass::reset_totals ();
+
+            switch (which) {
+
+            case Cons (void):
+                ret_ptr = new List ();
+                break;
+
+            case Cons (alloc):
+                ret_ptr = new List (arg_alc);
+                break;
+
+            case Cons (ccont):
+                ret_ptr = new List (arg_list);
+                break;
+
+            case Cons (size):
+                ret_ptr = new List (tcase.size);
+                break;
+
+            case Cons (size_cref):
+                ret_ptr = new List (tcase.size, arg_val);
+                break;
+
+            case Cons (size_cref_alloc):
+                ret_ptr = new List (tcase.size, arg_val, arg_alc);
+                break;
+
+            case Cons (range):
+                ret_ptr = &rng (arg, tdata);
+                break;
+
+            case Cons (range_alloc):
+                ret_ptr = &rng (arg, tdata);
+                break;
+
+            default:
+                RW_ASSERT (!"logic error: unknown constructor overload");
+            }
+
+            // for convenience
+            static const int cwidth = sizeof (T);
+
+            // verify that returned pointer is valid
+            rw_assert (0 != ret_ptr, 0, tcase.line,
+                       "line %d. %{$FUNCALL} expected \"%{X=*}\", got null",
+                       __LINE__, cwidth, int (tdata.reslen_), tdata.res_);
+        
+            if (0 != ret_ptr) {
+
+                if (is_class) {
+
+                    size_t def_ctor = (Cons (size) == which);
+
+                    // verify that the list ctor calls only copy ctor
+                    // of UserClass and only the given number of times each
+                    bool success = UserClass::is_total (size_t (-1),
+                                                        def_ctor,
+                                                        tdata.reslen_,
+                                                        0, 0, 0);
+                    rw_assert (success, 0, tcase.line,
+                               "line %d. %{$FUNCALL} called default/copy ctor "
+                               "and operator=() %zu, %zu, and %zu times, "
+                               "respectively, %zu, %zu, 0 expected",
+                               __LINE__,
+                               UserClass::n_total_def_ctor_,
+                               UserClass::n_total_copy_ctor_,
+                               UserClass::n_total_op_assign_,
+                               def_ctor, tdata.reslen_);
+                }
+
+                const size_t got_size = ret_ptr->size ();
+                char* const got = new char [got_size + 1];
+
+                size_t index = 0;
+                for (ListCIter it = ret_ptr->begin (),
+                    end = ret_ptr->end (); it != end; ++it) {
+                    got [index++] = char (it->data_.val_);
+                }
+
+                got [got_size] = '\0';
+
+                // verify that the length of the resulting list
+                rw_assert (tdata.reslen_ == got_size, 0, tcase.line,
+                           "line %d. %{$FUNCALL} expected \"%{X=*}\" with "
+                           "length %zu, got %{/*.*Gs} with length %zu",
+                           __LINE__,
+                           cwidth, int (tdata.reslen_), tdata.res_,
+                           tdata.reslen_,
+                           1, int (got_size), got, got_size);
+
+                if (tdata.reslen_ == got_size) {
+                    // if the result length matches the expected length
+                    // (and only then), also verify that the modified
+                    // list matches the expected result
+                    const std::size_t match =
+                        rw_match (tcase.res, got, got_size);
+
+                    rw_assert (match == tdata.reslen_, 0, tcase.line,
+                               "line %d. %{$FUNCALL} expected \"%{X=*}\", got "
+                               "%{/*.*Gs}, difference at offset %zu",
+                               __LINE__,
+                               cwidth, int (tdata.reslen_), tdata.res_,
+                               1, int (got_size), got, match);
+                }
+
+                delete [] got;
+
+                delete ret_ptr;
+            }
+        }
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+        catch (const UserClass::CopyCtor &ex) {
+            caught = exceptions [3];
+            rw_assert (0 == tcase.bthrow, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught %s (id_ = %d)",
+                       __LINE__, 0 != expected, expected, caught,
+                       ex.id_);
+        }
+        catch (const std::bad_alloc &ex) {
+            caught = exceptions [1];
+            rw_assert (0, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught std::%s(%#s)",
+                       __LINE__, 0 != expected, expected, caught,
+                       ex.what ());
+        }
+        catch (const std::exception &ex) {
+            caught = exceptions [2];
+            rw_assert (0, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught std::%s(%#s)",
+                       __LINE__, 0 != expected, expected, caught,
+                       ex.what ());
+        }
+        catch (...) {
+            caught = exceptions [0];
+            rw_assert (0, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught %s",
+                       __LINE__, 0 != expected, expected, caught);
+        }
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+        // disable UserClass::CopyCtor exception
+        if (!caught)
+            UserClass::copy_ctor_throw_count_ = size_t (-1);
+
+        /* const */ std::size_t nbytes;
+        const       std::size_t nblocks = rwt_check_leaks (&nbytes, 0);
+
+        // FIXME: verify the number of blocks the function call
+        // is expected to allocate and detect any memory leaks
+        const std::size_t expect_blocks = nblocks;
+
+        rw_assert (nblocks == expect_blocks, 0, tcase.line,
+                   "line %d. %{$FUNCALL} allocated %td bytes in %td blocks",
+                   __LINE__, nbytes, expect_blocks);
+
+        if (is_class)
+            rw_assert (x_count_save == UserClass::count_, 0, tcase.line,
+                       "line %d. %{$FUNCALL} leaked %zu value(s) "
+                       "of %zu after %{?}an exception %s%{:}call%{;}",
+                       __LINE__, UserClass::count_ - x_count_save,
+                       tdata.reslen_, 0 != caught, caught);
+
+        if (caught) {
+            if (0 == tcase.bthrow) {
+                // allow this call to operator new to succeed and try
+                // to make the next one to fail during the next call
+                // to the same function again
+                continue;
+            }
+        }
+        else if (0 < tcase.bthrow) {
+            rw_assert (caught == expected, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s, caught %s"
+                       "%{:}unexpectedly caught %s%{;}",
+                       __LINE__, 0 != expected, expected, caught, caught);
+        }
+
+        break;
+    }
+}
+
+/**************************************************************************/
+
+template <class T, class Allocator>
+void test_op_set (T*, Allocator*,
+                  const ContainerTestCaseData<T> &tdata)
+{
+    typedef std::list <T, Allocator>      List;
+    typedef typename List::iterator       ListIter;
+    typedef typename List::const_iterator ListCIter;
+
+    const ContainerFunc     &func  = tdata.func_;
+    const ContainerTestCase &tcase = tdata.tcase_;
+
+    // construct the list object to be modified
+    // and the (possibly unused) argument list
+          List lst (tdata.str_, tdata.str_ + tdata.strlen_, Allocator ());
+    const List arg (tdata.arg_, tdata.arg_ + tdata.arglen_, Allocator ());
+
+    // list function argument
+    const List&  arg_list = tcase.arg ? arg : lst;
+
+    rwt_free_store* const pst = rwt_get_free_store (0);
+    SharedAlloc*    const pal = SharedAlloc::instance ();
+
+    // iterate for`throw_after' starting at the next call to operator new,
+    // forcing each call to throw an exception, until the function finally
+    // succeeds (i.e, no exception is thrown)
+    std::size_t throw_count;
+    for (throw_count = 0; ; ++throw_count) {
+
+        // (name of) expected and caught exception
+        const char* expected = 0;
+        const char* caught   = 0;
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+        if (0 == tcase.bthrow) {
+            // by default exercise the exception safety of the
+            // function by iteratively inducing an exception at
+            // each call to operator new or Allocator::allocate()
+            // until the call succeeds
+            expected = exceptions [1];      // bad_alloc
+            *pst->throw_at_calls_ [0] =
+                pst->new_calls_ [0] + throw_count + 1;
+            pal->throw_at_calls_ [pal->m_allocate] =
+                pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
+        }
+        else {
+            // exceptions disabled for this test case
+        }
+
+#else   // if defined (_RWSTD_NO_EXCEPTIONS)
+
+        if (tcase.bthrow) {
+            return;
+        }
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+        // start checking for memory leaks
+        rw_check_leaks (lst.get_allocator ());
+
+        try {
+            const bool is_class = ListIds::UserClass == func.elem_id_;
+
+            // reset function call counters
+            if (is_class)
+                UserClass::reset_totals ();
+
+            ListIds::OverloadId which =
+                _RWSTD_STATIC_CAST (ListIds::OverloadId, func.which_);
+
+            switch (which) {
+
+            case OpSet (ccont):
+                lst = arg_list;
+                break;
+
+            default:
+                RW_ASSERT (!"logic error: unknown operator= overload");
+            }
+
+            if (is_class && &lst != &arg_list) {
+
+                const size_t total_copy = UserClass::n_total_copy_ctor_ +
+                    UserClass::n_total_op_assign_;
+
+                bool success = 0 == UserClass::n_total_def_ctor_
+                            && total_copy == tdata.reslen_;
+
+                rw_assert (success, 0, tcase.line,
+                           "line %d. %{$FUNCALL} called default ctor and "
+                           "copy ctor + operator=() %zu, and %zu times, "
+                           "respectively, 0, and %zu expected",
+                           __LINE__,
+                           UserClass::n_total_def_ctor_,
+                           total_copy, tdata.reslen_);
+            }
+
+            // for convenience
+            static const int cwidth = sizeof (T);
+
+            const size_t got_size = lst.size ();
+            char* const got = new char [got_size + 1];
+
+            size_t index = 0;
+            for (ListCIter it = lst.begin (),
+                end = lst.end (); it != end; ++it) {
+                got [index++] = char (it->data_.val_);
+            }
+
+            got [got_size] = '\0';
+
+            // verify that the length of the resulting list
+            rw_assert (tdata.reslen_ == got_size, 0, tcase.line,
+                       "line %d. %{$FUNCALL} expected \"%{X=*}\" with "
+                       "length %zu, got %{/*.*Gs} with length %zu",
+                       __LINE__,
+                       cwidth, int (tdata.reslen_), tdata.res_, 
+                       tdata.reslen_, 1, int (got_size), got, got_size);
+
+            if (tdata.reslen_ == got_size) {
+                // if the result length matches the expected length
+                // (and only then), also verify that the modified
+                // list matches the expected result
+                const std::size_t match =
+                    rw_match (tcase.res, got, got_size);
+
+                rw_assert (match == tdata.reslen_, 0, tcase.line,
+                           "line %d. %{$FUNCALL} expected \"%{X=*}\", "
+                           "got %{/*.*Gs}, difference at offset %zu",
+                           __LINE__, cwidth, int (tdata.reslen_),
+                           tdata.res_, 1, int (got_size), got, match);
+            }
+
+            delete [] got;
+        }
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+        catch (const std::bad_alloc &ex) {
+            caught = exceptions [1];
+            rw_assert (0 == tcase.bthrow, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught std::%s(%#s)",
+                       __LINE__, 0 != expected, expected, caught,
+                       ex.what ());
+        }
+        catch (const std::exception &ex) {
+            caught = exceptions [2];
+            rw_assert (0, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught std::%s(%#s)",
+                       __LINE__, 0 != expected, expected, caught,
+                       ex.what ());
+        }
+        catch (...) {
+            caught = exceptions [0];
+            rw_assert (0, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+                       "unexpectedly%{;} caught %s",
+                       __LINE__, 0 != expected, expected, caught);
+        }
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+        // FIXME: verify the number of blocks the function call
+        // is expected to allocate and detect any memory leaks
+        rw_check_leaks (lst.get_allocator (), tcase.line,
+                        std::size_t (-1), std::size_t (-1));
+
+        if (caught) {
+            if (0 == tcase.bthrow) {
+                // allow this call to operator new to succeed and try
+                // to make the next one to fail during the next call
+                // to the same function again
+                continue;
+            }
+        }
+        else if (0 < tcase.bthrow) {
+            rw_assert (caught == expected, 0, tcase.line,
+                       "line %d. %{$FUNCALL} %{?}expected %s, caught %s"
+                       "%{:}unexpectedly caught %s%{;}",
+                       __LINE__, 0 != expected, expected, caught, caught);
+        }
+
+        break;
+    }
+
+    // disable bad_alloc exceptions
+    *pst->throw_at_calls_ [0] = 0;
+    pal->throw_at_calls_ [pal->m_allocate] = 0;
+}
+
+/**************************************************************************/
+
+template <class T, class Allocator>
+void test_cons (T*, Allocator*,
+                const ContainerTestCaseData<T> &tdata)
+{
+    typedef std::list<T, Allocator> List;
+
+    if (ContainerIds::fid_op_set == (tdata.func_.which_ & ContainerIds::fid_mask)) {
+        test_op_set ((T*)0, (Allocator*)0, tdata);
+        return;
+    }
+
+    if (tdata.func_.which_ == Cons (range) 
+     || tdata.func_.which_ == Cons (range_alloc)) {
+
+        switch (tdata.func_.iter_id_) {
+
+        // exercise specializations of the member function template
+        // on the required iterator categories
+
+#undef TEST
+#define TEST(Iterator) do {                             \
+    typedef Iterator<T> Iter;                           \
+    static const                                        \
+    ConsRange<List, Iter> rng;                          \
+    test_cons ((T*)0, (Allocator*)0, rng, tdata);       \
+} while (0)
+
+        case ContainerIds::Input: TEST (InputIter); break;
+        case ContainerIds::Forward: TEST (ConstFwdIter); break;
+        case ContainerIds::Bidir: TEST (ConstBidirIter); break;
+        case ContainerIds::Random: TEST (ConstRandomAccessIter); break;
+
+            // exercise possible overloads of the member function template
+            // on pointer and const_pointer types
+#undef TEST
+#define TEST(Iterator) do {                             \
+    typedef typename List::Iterator Iter;               \
+    static const                                        \
+    ConsRangePtrOverload<List, Iter> rng;               \
+    test_cons ((T*)0, (Allocator*)0, rng, tdata);       \
+} while (0)
+
+        case ContainerIds::Pointer: TEST (pointer); break;
+        case ContainerIds::ConstPointer: TEST (const_pointer); break;
+
+            // exercise possible overloads of the member function template
+            // on common RandomAccessIterator types except
+            // pointer and const_pointer types
+#undef TEST
+#define TEST(Iterator) do {                             \
+    typedef typename List::Iterator Iter;               \
+    static const                                        \
+    ConsRangeOverload<List, Iter> rng;                  \
+    test_cons ((T*)0, (Allocator*)0, rng, tdata);       \
+} while (0)
+
+        case ContainerIds::Iterator: TEST (iterator); break;
+        case ContainerIds::ConstIterator: TEST (const_iterator); break;
+
+        case ContainerIds::ReverseIterator:
+            TEST (reverse_iterator);
+            break;
+        case ContainerIds::ConstReverseIterator:
+            TEST (const_reverse_iterator);
+            break;
+
+        default:
+            rw_error (0, 0, __LINE__, "bad iterator id");
+        }
+    }
+    else {
+        // exercise ordinary overloads of the member function
+        static const ContRangeBase<List> rng;
+        test_cons ((T*)0, (Allocator*)0, rng, tdata);
+    }
+}
+
+/**************************************************************************/
+
+DEFINE_CONTAINER_TEST_FUNCTIONS (test_cons);
+
+int main (int argc, char** argv)
+{
+    std::list<int> lst;
+    std::list<int>::iterator it = lst.begin ();
+
+    static const ContainerTest
+    tests [] = {
+
+#undef TEST
+#define TEST(sig) {                                             \
+        Cons (sig), sig ## _test_cases,                         \
+        sizeof sig ## _test_cases / sizeof *sig ## _test_cases  \
+    }
+
+        TEST (void),
+        TEST (alloc),
+        TEST (ccont),
+        TEST (size),
+        TEST (size_cref),
+        TEST (size_cref_alloc),
+        TEST (range),
+        TEST (range_alloc),
+
+#undef TEST
+#define TEST(sig) {                             \
+        OpSet (sig), sig ## _op_set_test_cases, \
+          sizeof sig ## _op_set_test_cases      \
+        / sizeof *sig ## _op_set_test_cases     \
+    }
+
+        TEST (ccont)
+    };
+
+    const std::size_t test_count = sizeof tests / sizeof *tests;
+
+    const int status =
+        rw_run_cont_test (argc, argv, __FILE__,
+                          "lib.list.cons",
+                          ContainerIds::List,
+                          test_cons_func_array, tests, test_count);
+
+    return status;
+}

Propchange: incubator/stdcxx/trunk/tests/containers/23.list.cons.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/stdcxx/trunk/tests/containers/23.list.cons.cpp
------------------------------------------------------------------------------
    svn:keywords = Id



Mime
View raw message