summaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/util/testsuite_character.h
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libstdc++-v3/testsuite/util/testsuite_character.h
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libstdc++-v3/testsuite/util/testsuite_character.h')
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_character.h570
1 files changed, 570 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/util/testsuite_character.h b/libstdc++-v3/testsuite/util/testsuite_character.h
new file mode 100644
index 000000000..ceda1f512
--- /dev/null
+++ b/libstdc++-v3/testsuite/util/testsuite_character.h
@@ -0,0 +1,570 @@
+// -*- C++ -*-
+
+// Testing character type and state type with char_traits and codecvt
+// specializations for the C++ library testsuite.
+//
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+
+#ifndef _GLIBCXX_TESTSUITE_CHARACTER_H
+#define _GLIBCXX_TESTSUITE_CHARACTER_H
+
+#include <climits>
+#include <string> // for char_traits
+#include <locale> // for codecvt
+#include <algorithm> // for transform
+#include <ext/pod_char_traits.h>
+
+namespace __gnu_test
+{
+ struct pod_int
+ {
+ int value;
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ // For std::iota.
+ pod_int&
+ operator++()
+ {
+ ++value;
+ return *this;
+ }
+#endif
+ };
+
+ // For 20.1 requirements for instantiable type: equality comparable
+ // and less than comparable.
+ inline bool
+ operator==(const pod_int& lhs, const pod_int& rhs)
+ { return lhs.value == rhs.value; }
+
+ inline bool
+ operator<(const pod_int& lhs, const pod_int& rhs)
+ { return lhs.value < rhs.value; }
+
+ // For 26 numeric algorithms requirements, need addable,
+ // subtractable, multiplicable.
+ inline pod_int
+ operator+(const pod_int& lhs, const pod_int& rhs)
+ {
+ pod_int ret = { lhs.value + rhs.value };
+ return ret;
+ }
+
+ inline pod_int
+ operator-(const pod_int& lhs, const pod_int& rhs)
+ {
+ pod_int ret = { lhs.value - rhs.value };
+ return ret;
+ }
+
+ inline pod_int
+ operator*(const pod_int& lhs, const pod_int& rhs)
+ {
+ pod_int ret = { lhs.value * rhs.value };
+ return ret;
+ }
+
+ struct pod_state
+ {
+ unsigned long value;
+ };
+
+ inline bool
+ operator==(const pod_state& lhs, const pod_state& rhs)
+ { return lhs.value == rhs.value; }
+
+ inline bool
+ operator<(const pod_state& lhs, const pod_state& rhs)
+ { return lhs.value < rhs.value; }
+
+ // Alternate character types.
+ using __gnu_cxx::character;
+ typedef character<unsigned char, pod_int, pod_state> pod_char;
+ typedef character<unsigned char, unsigned int, pod_state> pod_uchar;
+ typedef character<unsigned short, unsigned int> pod_ushort;
+ typedef character<unsigned int, unsigned long> pod_uint;
+}
+
+namespace __gnu_cxx
+{
+ // Specializations.
+ // pod_char
+ template<>
+ template<typename V2>
+ inline __gnu_test::pod_char::char_type
+ __gnu_test::pod_char::char_type::from(const V2& v)
+ {
+ char_type ret = { static_cast<value_type>(v.value) };
+ return ret;
+ }
+
+ template<>
+ template<typename V2>
+ inline V2
+ __gnu_test::pod_char::char_type::to(const char_type& c)
+ {
+ V2 ret = { c.value };
+ return ret;
+ }
+
+ template<>
+ template<typename V2>
+ inline __gnu_test::pod_uchar::char_type
+ __gnu_test::pod_uchar::char_type::from(const V2& v)
+ {
+ char_type ret;
+ ret.value = (v >> 5);
+ return ret;
+ }
+
+ template<>
+ template<typename V2>
+ inline V2
+ __gnu_test::pod_uchar::char_type::to(const char_type& c)
+ { return static_cast<V2>(c.value << 5); }
+} // namespace __gnu_test
+
+namespace std
+{
+ // codecvt specialization
+ //
+ // The conversion performed by the specialization is not supposed to
+ // be useful, rather it has been designed to demonstrate the
+ // essential features of stateful conversions:
+ // * Number and value of bytes for each internal character depends on the
+ // state in addition to the character itself.
+ // * Unshift produces an unshift sequence and resets the state. On input
+ // the unshift sequence causes the state to be reset.
+ //
+ // The conversion for output is as follows:
+ // 1. Calculate the value tmp by xor-ing the state and the internal
+ // character
+ // 2. Split tmp into either two or three bytes depending on the value of
+ // state. Output those bytes.
+ // 3. tmp becomes the new value of state.
+ template<>
+ class codecvt<__gnu_test::pod_uchar, char, __gnu_test::pod_state>
+ : public __codecvt_abstract_base<__gnu_test::pod_uchar, char,
+ __gnu_test::pod_state>
+ {
+ public:
+ typedef codecvt_base::result result;
+ typedef __gnu_test::pod_uchar intern_type;
+ typedef char extern_type;
+ typedef __gnu_test::pod_state state_type;
+ typedef __codecvt_abstract_base<intern_type, extern_type, state_type>
+ base_type;
+
+ explicit codecvt(size_t refs = 0) : base_type(refs)
+ { }
+
+ static locale::id id;
+
+ protected:
+ ~codecvt()
+ { }
+
+ virtual result
+ do_out(state_type& state, const intern_type* from,
+ const intern_type* from_end, const intern_type*& from_next,
+ extern_type* to, extern_type* to_limit,
+ extern_type*& to_next) const
+ {
+ while (from < from_end && to < to_limit)
+ {
+ unsigned char tmp = (state.value ^ from->value);
+ if (state.value & 0x8)
+ {
+ if (to >= to_limit - 2)
+ break;
+ *to++ = (tmp & 0x7);
+ *to++ = ((tmp >> 3) & 0x7);
+ *to++ = ((tmp >> 6) & 0x3);
+ }
+ else
+ {
+ if (to >= to_limit - 1)
+ break;
+ *to++ = (tmp & 0xf);
+ *to++ = ((tmp >> 4) & 0xf);
+ }
+ state.value = tmp;
+ ++from;
+ }
+
+ from_next = from;
+ to_next = to;
+ return (from < from_end) ? partial : ok;
+ }
+
+ virtual result
+ do_in(state_type& state, const extern_type* from,
+ const extern_type* from_end, const extern_type*& from_next,
+ intern_type* to, intern_type* to_limit,
+ intern_type*& to_next) const
+ {
+ while (from < from_end && to < to_limit)
+ {
+ unsigned char c = *from;
+ if (c & 0xc0)
+ {
+ // Unshift sequence
+ state.value &= c;
+ ++from;
+ continue;
+ }
+
+ unsigned char tmp;
+ if (state.value & 0x8)
+ {
+ if (from >= from_end - 2)
+ break;
+ tmp = (*from++ & 0x7);
+ tmp |= ((*from++ << 3) & 0x38);
+ tmp |= ((*from++ << 6) & 0xc0);
+ }
+ else
+ {
+ if (from >= from_end - 1)
+ break;
+ tmp = (*from++ & 0xf);
+ tmp |= ((*from++ << 4) & 0xf0);
+ }
+ to->value = (tmp ^ state.value);
+ state.value = tmp;
+ ++to;
+ }
+
+ from_next = from;
+ to_next = to;
+ return (from < from_end) ? partial : ok;
+ }
+
+ virtual result
+ do_unshift(state_type& state, extern_type* to, extern_type* to_limit,
+ extern_type*& to_next) const
+ {
+ for (unsigned int i = 0; i < CHAR_BIT; ++i)
+ {
+ unsigned int mask = (1 << i);
+ if (state.value & mask)
+ {
+ if (to == to_limit)
+ {
+ to_next = to;
+ return partial;
+ }
+
+ state.value &= ~mask;
+ *to++ = static_cast<unsigned char>(~mask);
+ }
+ }
+
+ to_next = to;
+ return state.value == 0 ? ok : error;
+ }
+
+ virtual int
+ do_encoding() const throw()
+ { return -1; }
+
+ virtual bool
+ do_always_noconv() const throw()
+ { return false; }
+
+ virtual int
+ do_length(state_type& state, const extern_type* from,
+ const extern_type* end, size_t max) const
+ {
+ const extern_type* beg = from;
+ while (from < end)
+ {
+ unsigned char c = *from;
+ if (c & 0xc0)
+ {
+ // Unshift sequence
+ state.value &= c;
+ ++from;
+ continue;
+ }
+
+ if (max == 0) break;
+
+ unsigned char tmp;
+ if (state.value & 0x8)
+ {
+ if (from >= end - 2)
+ break;
+ tmp = (*from++ & 0x7);
+ tmp |= ((*from++ << 3) & 0x38);
+ tmp |= ((*from++ << 6) & 0xc0);
+ }
+ else
+ {
+ if (from >= end - 1)
+ break;
+ tmp = (*from++ & 0xf);
+ tmp |= ((*from++ << 4) & 0xf0);
+ }
+ state.value = tmp;
+ --max;
+ }
+ return from - beg;
+ }
+
+ // Maximum 8 bytes unshift sequence followed by max 3 bytes for
+ // one character.
+ virtual int
+ do_max_length() const throw()
+ { return 11; }
+ };
+
+ template<>
+ class ctype<__gnu_test::pod_uchar>
+ : public __ctype_abstract_base<__gnu_test::pod_uchar>
+ {
+ public:
+ typedef __gnu_test::pod_uchar char_type;
+
+ explicit ctype(size_t refs = 0)
+ : __ctype_abstract_base<__gnu_test::pod_uchar>(refs) { }
+
+ static locale::id id;
+
+ protected:
+ ~ctype()
+ { }
+
+ virtual bool
+ do_is(mask, char_type) const
+ { return false; }
+
+ virtual const char_type*
+ do_is(const char_type* low, const char_type* high, mask* vec) const
+ {
+ fill_n(vec, high - low, mask());
+ return high;
+ }
+
+ virtual const char_type*
+ do_scan_is(mask, const char_type*, const char_type* high) const
+ { return high; }
+
+ virtual const char_type*
+ do_scan_not(mask, const char_type* low, const char_type*) const
+ { return low; }
+
+ virtual char_type
+ do_toupper(char_type c) const
+ { return c; }
+
+ virtual const char_type*
+ do_toupper(char_type*, const char_type* high) const
+ { return high; }
+
+ virtual char_type
+ do_tolower(char_type c) const
+ { return c; }
+
+ virtual const char_type*
+ do_tolower(char_type*, const char_type* high) const
+ { return high; }
+
+ virtual char_type
+ do_widen(char c) const
+ { return __gnu_test::pod_uchar::from<char>(c); }
+
+ virtual const char*
+ do_widen(const char* low, const char* high, char_type* dest) const
+ {
+ transform(low, high, dest, &__gnu_test::pod_uchar::from<char>);
+ return high;
+ }
+
+ virtual char
+ do_narrow(char_type, char dfault) const
+ { return dfault; }
+
+ virtual const char_type*
+ do_narrow(const char_type* low, const char_type* high,
+ char dfault, char* dest) const
+ {
+ fill_n(dest, high - low, dfault);
+ return high;
+ }
+ };
+
+ // numpunct specializations
+ template<>
+ class numpunct<__gnu_test::pod_uint>
+ : public locale::facet
+ {
+ public:
+ typedef __gnu_test::pod_uint char_type;
+ typedef basic_string<char_type> string_type;
+
+ static locale::id id;
+
+ explicit
+ numpunct(size_t refs = 0)
+ : locale::facet(refs)
+ { }
+
+ char_type
+ decimal_point() const
+ { return this->do_decimal_point(); }
+
+ char_type
+ thousands_sep() const
+ { return this->do_thousands_sep(); }
+
+ string
+ grouping() const
+ { return this->do_grouping(); }
+
+ string_type
+ truename() const
+ { return this->do_truename(); }
+
+ string_type
+ falsename() const
+ { return this->do_falsename(); }
+
+ protected:
+ ~numpunct()
+ { }
+
+ virtual char_type
+ do_decimal_point() const
+ { return char_type(); }
+
+ virtual char_type
+ do_thousands_sep() const
+ { return char_type(); }
+
+ virtual string
+ do_grouping() const
+ { return string(); }
+
+ virtual string_type
+ do_truename() const
+ { return string_type(); }
+
+ virtual string_type
+ do_falsename() const
+ { return string_type(); }
+ };
+
+ template<>
+ class moneypunct<__gnu_test::pod_uint>
+ : public locale::facet, public money_base
+ {
+ public:
+ typedef __gnu_test::pod_uint char_type;
+ typedef basic_string<char_type> string_type;
+
+ static locale::id id;
+ static const bool intl = false;
+
+ explicit
+ moneypunct(size_t refs = 0)
+ : locale::facet(refs)
+ { }
+
+ char_type
+ decimal_point() const
+ { return this->do_decimal_point(); }
+
+ char_type
+ thousands_sep() const
+ { return this->do_thousands_sep(); }
+
+ string
+ grouping() const
+ { return this->do_grouping(); }
+
+ string_type
+ curr_symbol() const
+ { return this->do_curr_symbol(); }
+
+ string_type
+ positive_sign() const
+ { return this->do_positive_sign(); }
+
+ string_type
+ negative_sign() const
+ { return this->do_negative_sign(); }
+
+ int
+ frac_digits() const
+ { return this->do_frac_digits(); }
+
+ pattern
+ pos_format() const
+ { return this->do_pos_format(); }
+
+ pattern
+ neg_format() const
+ { return this->do_neg_format(); }
+
+ protected:
+ ~moneypunct()
+ { }
+
+ virtual char_type
+ do_decimal_point() const
+ { return char_type(); }
+
+ virtual char_type
+ do_thousands_sep() const
+ { return char_type(); }
+
+ virtual string
+ do_grouping() const
+ { return string(); }
+
+ virtual string_type
+ do_curr_symbol() const
+ { return string_type(); }
+
+ string_type
+ do_positive_sign() const
+ { return string_type(); }
+
+ string_type
+ do_negative_sign() const
+ { return string_type(); }
+
+ int
+ do_frac_digits() const
+ { return 0; }
+
+ pattern
+ do_pos_format() const
+ { return pattern(); }
+
+ pattern
+ do_neg_format() const
+ { return pattern(); }
+ };
+} // namespace std
+
+#endif // _GLIBCXX_TESTSUITE_CHARACTER_H
+