Author: sebor
Date: Tue Feb 5 20:23:49 2008
New Revision: 618878
URL: http://svn.apache.org/viewvc?rev=618878&view=rev
Log:
2008-02-05 Martin Sebor <[EMAIL PROTECTED]>
* 24.istream.iterator.cpp: New test exercising [istream.iterator],
including STDCXX-645.
Added:
stdcxx/trunk/tests/iterators/
stdcxx/trunk/tests/iterators/24.istream.iterator.cpp (with props)
Added: stdcxx/trunk/tests/iterators/24.istream.iterator.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/trunk/tests/iterators/24.istream.iterator.cpp?rev=618878&view=auto
==============================================================================
--- stdcxx/trunk/tests/iterators/24.istream.iterator.cpp (added)
+++ stdcxx/trunk/tests/iterators/24.istream.iterator.cpp Tue Feb 5 20:23:49
2008
@@ -0,0 +1,395 @@
+/***********************************************************************
+ *
+ * 24.istream.iterator.cpp - test exercising [istream.iterator]
+ *
+ * $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 <sstream> // for stringstream
+#include <iterator> // for istream_iterator
+
+#include <cstddef> // for ptrdiff_t
+
+#include <rw_char.h>
+#include <rw_printf.h>
+#include <driver.h>
+
+/***********************************************************************/
+
+// names of template parameters
+struct ParamNames {
+ const char *tname; // name of the T parameter
+ const char *tfmt; // rw_printf()-style format for T
+ const char *cname; // name of the CharT parameter
+ const char *trname; // name of the Traits parameter
+ const char *dname; // name of the Distance parameter
+};
+
+
+// format the template-id of the iterator
+void fmtnam (const ParamNames &pn)
+{
+ // omit names of unspecified (default) template arguments
+ const char* const id = pn.cname ? pn.trname ? pn.dname ?
+ "<%s, %s, %s, %s>" : "<%s, %s, %s>" : "<%s, %s>" : "<%s>";
+
+ rw_fprintf (0, "%{$ITER!:@}",
+ "[EMAIL PROTECTED]",
+ id, pn.tname, pn.cname, pn.trname, pn.dname);
+}
+
+/***********************************************************************/
+
+// for convenience
+template <class T, class CharT, class Traits, class Dist>
+struct TempParams { ParamNames names; };
+
+
+// exercise istream_iterator ctors
+template <class T, class CharT, class Traits, class Dist>
+void test_ctors (const TempParams<T, CharT, Traits, Dist> ¶ms)
+{
+ typedef std::istream_iterator<T, CharT, Traits, Dist> Iterator;
+ typedef std::basic_stringstream<CharT, Traits> StringStream;
+
+ const Iterator eos1;
+ const Iterator eos2;
+
+ // verify [reverse.iter], p3, i.e., that two end-of-istream
+ // always compare equal, and that no end-of-stream iterator
+ // compares equal to a non-end-of-stream iterator
+
+ fmtnam (params.names);
+
+ rw_assert (eos1 == eos2, 0, __LINE__,
+ "%{$ITER}::istream_iterator() == %{$ITER}::istream_iterator()");
+
+ StringStream strm1;
+
+ // make sure the stream object's locale contains the expected
+ // specialization of the num_get facet (in case CharT isn't
+ // char or wchar_t, or Traits isn't std::char_traits)
+ typedef std::istreambuf_iterator<CharT, Traits> StreambufIterator;
+ typedef std::num_get<CharT, StreambufIterator> NumGet;
+
+ if (false == std::has_facet<NumGet>(strm1.getloc ())) {
+ const std::locale loc (std::locale::classic (), new NumGet);
+ strm1.imbue (loc);
+ }
+
+ // insert a couple of items into the stream, one for each iterator
+ // below, to prevent the iterator ctor from creating an end-of-stream
+ // iterator (in case it doesn't delay extracting a value until it's
+ // needed)
+ strm1.rdbuf ()->sputc (CharT ());
+ strm1.rdbuf ()->sputc (CharT ());
+
+ // verify [reverse.iter], p3, i.e., that two istream_iterators
+ // constructed from the same stream always compare equal
+ const Iterator iter1 (strm1);
+ const Iterator iter2 (strm1);
+
+ rw_assert (iter1 != eos1, 0, __LINE__,
+ "%{$ITER}::istream_iterator(basic_istream&) != "
+ "%{$ITER}()");
+
+ rw_assert (iter1 == iter2, 0, __LINE__,
+ "%{$ITER}::istream_iterator(basic_istream&) == "
+ "%{$ITER}::istream_iterator(basic_istream&)");
+
+ StringStream strm2;
+ strm2.imbue (strm1.getloc ());
+
+ strm2.rdbuf ()->sputc (CharT ());
+
+ const Iterator iter3 (strm2);
+
+ rw_assert (iter3 != eos1, 0, __LINE__,
+ "%{$ITER}::istream_iterator(basic_istream&) != "
+ "%{$ITER}()");
+
+ // verify that iterators into different streams compare unequal
+ rw_assert (iter3 != iter1, 0, __LINE__,
+ "%{$ITER}::istream_iterator(basic_istream& [EMAIL PROTECTED])
!= "
+ "%{$ITER}::istream_iterator(basic_istream& [EMAIL PROTECTED])",
+ &strm2, &strm1);
+}
+
+/***********************************************************************/
+
+// worker to exercise operator*()
+template <class T, class CharT, class Traits, class Dist>
+void test_ops (const TempParams<T, CharT, Traits, Dist> ¶ms,
+ int line,
+ const char *input,
+ T expect,
+ bool is_eos,
+ int state)
+{
+ typedef std::istream_iterator<T, CharT, Traits, Dist> Iterator;
+ typedef std::basic_stringstream<CharT, Traits> StringStream;
+
+ fmtnam (params.names);
+
+ StringStream strm;
+
+ typedef std::istreambuf_iterator<CharT, Traits> StreambufIterator;
+ typedef std::num_get<CharT, StreambufIterator> NumGet;
+
+ if (false == std::has_facet<NumGet>(strm.getloc ())) {
+ const std::locale loc (std::locale::classic (), new NumGet);
+ strm.imbue (loc);
+ }
+
+ if (input && *input)
+ strm << input;
+
+ const Iterator eos;
+
+ const Iterator it (strm);
+
+ rw_assert (is_eos ^ it != eos, 0, line,
+ "line %d: %{$ITER}::operator() != %{$ITER}()", __LINE__);
+
+ if (0 == (strm.rdstate () & (strm.badbit | strm.failbit))) {
+ // operator*() is defined only for non-eos iterators
+ // avoid calling it on a bad or failed stream too
+
+ const T val = *it;
+
+ rw_assert (val == expect, 0, line,
+ "line %d: %{$ITER}::operator*() == [EMAIL PROTECTED], got
[EMAIL PROTECTED]",
+ __LINE__, params.names.tfmt, expect, params.names.tfmt,
val);
+ }
+
+ rw_assert (strm.rdstate () == state, 0, line,
+ "line %d: %{$ITER}::operator*(), rdstate() == %{Is}, got %{Is}",
+ __LINE__, state, strm.rdstate ());
+}
+
+/***********************************************************************/
+
+// exercise operator*()
+template <class T, class CharT, class Traits, class Dist>
+void test_ops (const TempParams<T, CharT, Traits, Dist> ¶ms)
+{
+ // const int Bad = std::ios::badbit;
+ const int Eof = std::ios::eofbit;
+ const int Fail = std::ios::failbit;
+ const int Good = std::ios::goodbit;
+
+#undef TEST
+#define TEST(input, expect, is_eos, state) \
+ test_ops (params, __LINE__, input, T (expect), is_eos, state)
+
+ volatile T one = T (1);
+ volatile T zero = one - one;
+ volatile T two = one + one;
+
+ const bool is_char = sizeof (T) == sizeof (char);
+ const bool is_signed = zero - one < zero;
+ const bool is_exact = one / two == zero;
+
+ if (is_char) {
+ TEST ("", '\0', true, Eof | Fail);
+ TEST ("1", '1', false, Good);
+ TEST ("2", '2', false, Good);
+ }
+ else {
+ TEST ("", 0, true, Eof | Fail);
+ TEST ("1", 1, true, Eof);
+ TEST ("1 ", 1, false, Good);
+ TEST ("+1", 1, true, Eof);
+ TEST (" 1", 1, true, Eof);
+ TEST (" 1 ", 1, false, Good);
+ TEST (" +1", 1, true, Eof);
+ TEST ("2", 2, true, Eof);
+ TEST ("+2", 2, true, Eof);
+ TEST (" 2", 2, true, Eof);
+ TEST (" +2", 2, true, Eof);
+ TEST ("99", 99, true, Eof);
+ TEST ("+99", 99, true, Eof);
+ TEST (" 99", 99, true, Eof);
+ TEST (" +99", 99, true, Eof);
+
+ TEST ("+", 0, true, Eof | Fail);
+ TEST ("-", 0, true, Eof | Fail);
+ TEST (" +", 0, true, Eof | Fail);
+ TEST (" -", 0, true, Eof | Fail);
+ TEST ("++", 0, false, Fail);
+ TEST ("--", 0, false, Fail);
+ TEST (" ++", 0, false, Fail);
+ TEST (" --", 0, false, Fail);
+ TEST ("*", 0, false, Fail);
+ TEST (" *", 0, false, Fail);
+
+ if (is_signed) {
+ TEST ("-1", -1, true, Eof);
+ TEST (" -1", -1, true, Eof);
+ TEST ("-2", -2, true, Eof);
+ TEST (" -2", -2, true, Eof);
+ TEST ("-99", -99, true, Eof);
+ TEST (" -99", -99, true, Eof);
+ }
+
+ if (is_exact) {
+ TEST ("1.2", 1, false, Good);
+ TEST ("2.3 ", 2, false, Good);
+ TEST (" 3.4", 3, false, Good);
+ TEST (" +4.", 4, false, Good);
+ }
+ else {
+ TEST (".1", 0.1, true, Eof);
+ TEST ("+.2", 0.2, true, Eof);
+ TEST ("-.3", -0.3, true, Eof);
+ TEST (" +.4", 0.4, true, Eof);
+ TEST (" -.5", -0.5, true, Eof);
+ TEST ("1..", 1.0, false, Good);
+
+ TEST ("1.234", 1.234, true, Eof);
+ TEST ("+1.235", +1.235, true, Eof);
+ TEST ("-1.236", -1.236, true, Eof);
+ TEST (" +1.237", +1.237, true, Eof);
+ TEST (" -1.238", -1.238, true, Eof);
+ TEST ("1.239e1", 1.239e1, true, Eof);
+ TEST ("1.240e+1", 1.240e+1, true, Eof);
+ TEST ("-1.241e+2", -1.241e+2, true, Eof);
+ TEST ("-1.242e-3 ", -1.242e-3, false, Good);
+
+ TEST ("1.3e", 0, true, Eof | Fail);
+ TEST ("1.4e+", 0, true, Eof | Fail);
+ TEST ("1.5e-", 0, true, Eof | Fail);
+ TEST ("1.6e+ ", 0, false, Fail);
+ }
+ }
+}
+
+/***********************************************************************/
+
+enum TestId { TestCtors, TestOps };
+
+// dispatch to test_ctors to test_ops
+template <class T, class CharT, class Traits, class Dist>
+void do_test (TestId id,
+ const char *tname,
+ const char *tfmt,
+ const char *cname,
+ const char *trname,
+ const char *dname)
+{
+ const ParamNames names = { tname, tfmt, cname, trname, dname };
+ const TempParams<T, CharT, Traits, Dist> params = { names };
+
+ if (TestCtors == id) {
+ test_ctors (params);
+ }
+ else if (TestOps == id) {
+ test_ops (params);
+ }
+}
+
+/***********************************************************************/
+
+// exercise different specializations of T
+template <class CharT, class Traits, class Dist>
+void do_test (TestId id,
+ const char *cname,
+ const char *trname,
+ const char *dname)
+{
+#undef TEST
+#define TEST(T, fmt) \
+ do_test<T, CharT, Traits, Dist>(id, #T, fmt, cname, trname, dname)
+
+ // cannot instantiate basic_istream<CharT>::operator>>(char&)
+ // for any CharT other than char
+ // TEST (char, "%{hhi}");
+
+ TEST (short, "%hi");
+ TEST (int, " %i");
+ TEST (long, "%li");
+ TEST (double, "%g");
+}
+
+
+/***********************************************************************/
+
+// exercise different specializations of Distance
+template <class CharT, class Traits>
+void do_test (TestId id, const char *cname, const char *trname)
+{
+ do_test<CharT, Traits, short>(id, cname, trname, "short");
+ do_test<CharT, Traits, std::ptrdiff_t>(id, cname, trname, 0);
+}
+
+/***********************************************************************/
+
+static int
+run_test (int, char*[])
+{
+ static const TestId test_ids [] = { TestCtors, TestOps };
+
+ typedef std::char_traits<char> Traits;
+ typedef UserTraits<char> UsrTraits;
+
+ for (unsigned i = 0; i != sizeof test_ids / sizeof *test_ids; ++i) {
+
+ const TestId id = test_ids [i];
+
+ // call these helper functions directly to avoid instantiating
+ // basic_istream<CharT>::operator>>(char&) on any CharT other
+ // than char
+ do_test<char, char, Traits, std::ptrdiff_t>(id, "char", "%{hhi}",
+ 0, 0, 0);
+ do_test<char, char, UsrTraits, std::ptrdiff_t>(id, "char", "%{hhi}",
+ 0, "UserTraits<char>",
+ "std::ptrdiff_t");
+
+ do_test<char, Traits>(id, 0, 0);
+ do_test<char, UsrTraits>(id, "char", "UserTraits<char>");
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+ typedef std::char_traits<wchar_t> WTraits;
+ typedef UserTraits<wchar_t> WUsrTraits;
+
+ do_test<wchar_t, WTraits>(id, 0, 0);
+ do_test<wchar_t, WUsrTraits>(id, "wchar_t", "UserTraits<wchar_t>");
+
+#endif // _RWSTD_NO_WCHAR_T
+
+ }
+
+ return 0;
+}
+
+
+/***********************************************************************/
+
+int main (int argc, char *argv[])
+{
+ return rw_test (argc, argv, __FILE__,
+ "lib.istream.iterator",
+ 0 /* no comment */,
+ run_test,
+ "", 0);
+}
Propchange: stdcxx/trunk/tests/iterators/24.istream.iterator.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: stdcxx/trunk/tests/iterators/24.istream.iterator.cpp
------------------------------------------------------------------------------
svn:keywords = Id