//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
// As a special exception, you may use this file as part of a free software
namespace __gnu_test
{
- // Character type
- struct character
+ struct pod_int
{
- unsigned char val;
-
- static character from_char(char c)
- {
- character ret;
- ret.val = c;
- return ret;
- }
+ int value;
};
-
+
inline bool
- operator==(const character& lhs, const character& rhs)
- { return lhs.val == rhs.val; }
-
- // State type.
- struct conversion_state
- {
- unsigned int state;
- };
+ 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; }
- // Test data types.
- struct pod_char
+ struct pod_state
{
- unsigned char c;
+ unsigned long value;
};
inline bool
- operator==(const pod_char& lhs, const pod_char& rhs)
- { return lhs.c == rhs.c; }
-
- struct pod_int
- {
- int i;
- };
-
- struct state
- {
- unsigned long l;
- unsigned long l2;
- };
+ operator==(const pod_state& lhs, const pod_state& rhs)
+ { return lhs.value == rhs.value; }
- typedef unsigned short value_type;
- typedef unsigned int int_type;
- typedef __gnu_cxx::character<value_type, int_type> pod_type;
-}; // namespace __gnu_test
-
-namespace std
-{
- // A std::char_traits specialization. Meets the additional
- // requirements for basic_filebuf.
+ 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;
+
+ // Specializations.
+ // pod_char
template<>
- struct char_traits<__gnu_test::character>
- {
- typedef __gnu_test::character char_type;
- typedef unsigned int int_type;
- typedef __gnu_test::conversion_state state_type;
- typedef streamoff off_type;
- typedef fpos<state_type> pos_type;
-
- static void
- assign(char_type& c1, const char_type& c2)
- { c1 = c2; }
-
- static bool
- eq(const char_type& c1, const char_type& c2)
- { return c1.val == c2.val; }
-
- static bool
- lt(const char_type& c1, const char_type& c2)
- { return c1.val < c2.val; }
-
- static int
- compare(const char_type* s1, const char_type* s2, size_t n)
- {
- for (size_t i = 0; i < n; ++i)
- {
- if (lt(s1[i], s2[i]))
- return -1;
- else if (lt(s2[i], s1[i]))
- return 1;
- }
- return 0;
- }
-
- static size_t
- length(const char_type* s)
+ template<typename V2>
+ inline pod_char::char_type
+ pod_char::char_type::from(const V2& v)
{
- size_t n = 0;
- while (!eq(s[n], char_type()))
- ++n;
- return n;
- }
-
- static const char_type*
- find(const char_type* s, size_t n, const char_type& a)
- {
- for (size_t i = 0; i < n; ++i)
- {
- if (eq(s[i], a))
- return s + i;
- }
- return NULL;
- }
-
- static char_type*
- move(char_type* s1, const char_type* s2, size_t n)
- {
- if (s1 > s2)
- {
- for (size_t i = 0; i < n; ++i)
- assign(s1[n - i - 1], s2[n - i - 1]);
- }
- else
- {
- for (size_t i = 0; i < n; ++i)
- assign(s1[i], s2[i]);
- }
- return s1;
- }
-
- static char_type*
- copy(char_type* s1, const char_type* s2, size_t n)
- {
- for (size_t i = 0; i < n; ++i)
- assign(s1[i], s2[i]);
- return s1;
- }
-
- static char_type*
- assign(char_type* s, size_t n, char_type a)
- {
- for (size_t i = 0; i < n; ++i)
- assign(s[i], a);
- return s;
+ char_type ret = { static_cast<value_type>(v.value) };
+ return ret;
}
- static int_type
- not_eof(const int_type& c)
+ template<>
+ template<typename V2>
+ inline V2
+ pod_char::char_type::to(const char_type& c)
{
- if (eq_int_type(c, eof()))
- return 0;
- return c;
+ V2 ret = { c.value };
+ return ret;
}
-
- // Note non-trivial conversion to maximize chance of catching bugs
- static char_type
- to_char_type(const int_type& c)
+
+ // pod_uchar
+ template<>
+ template<typename V2>
+ inline pod_uchar::char_type
+ pod_uchar::char_type::from(const V2& v)
{
char_type ret;
- ret.val = (c >> 5);
+ ret.value = (v >> 5);
return ret;
}
- static int_type
- to_int_type(const char_type& c)
- {
- return c.val << 5;
- }
-
- static bool
- eq_int_type(const int_type& c1, const int_type& c2)
- { return c1 == c2; }
-
- static int_type eof()
- { return 0xf; }
- };
+ template<>
+ template<typename V2>
+ inline V2
+ 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
// state. Output those bytes.
// 3. tmp becomes the new value of state.
template<>
- class codecvt<__gnu_test::character, char, __gnu_test::conversion_state>
- : public locale::facet, public codecvt_base
+ 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 __gnu_test::character intern_type;
- typedef char extern_type;
- typedef __gnu_test::conversion_state state_type;
-
- explicit codecvt(size_t refs = 0)
- : locale::facet(refs)
+ 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)
{ }
- result
- 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
- {
- return do_out(state, from, from_end, from_next,
- to, to_limit, to_next);
- }
-
- result
- unshift(state_type& state, extern_type* to, extern_type* to_limit,
- extern_type*& to_next) const
- { return do_unshift(state, to, to_limit, to_next); }
-
- result
- 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
- {
- return do_in(state, from, from_end, from_next,
- to, to_limit, to_next);
- }
-
- int
- encoding() const throw()
- { return do_encoding(); }
-
- bool
- always_noconv() const throw()
- { return do_always_noconv(); }
-
- int
- length(state_type& state, const extern_type* from,
- const extern_type* end, size_t max) const
- { return do_length(state, from, end, max); }
-
- int
- max_length() const throw()
- { return do_max_length(); }
-
static locale::id id;
protected:
{
while (from < from_end && to < to_limit)
{
- unsigned char tmp = (state.state ^ from->val);
- if (state.state & 0x8)
+ unsigned char tmp = (state.value ^ from->value);
+ if (state.value & 0x8)
{
if (to >= to_limit - 2)
break;
*to++ = (tmp & 0xf);
*to++ = ((tmp >> 4) & 0xf);
}
- state.state = tmp;
+ state.value = tmp;
++from;
}
if (c & 0xc0)
{
// Unshift sequence
- state.state &= c;
+ state.value &= c;
++from;
continue;
}
unsigned char tmp;
- if (state.state & 0x8)
+ if (state.value & 0x8)
{
if (from >= from_end - 2)
break;
tmp = (*from++ & 0xf);
tmp |= ((*from++ << 4) & 0xf0);
}
- to->val = (tmp ^ state.state);
- state.state = tmp;
+ to->value = (tmp ^ state.value);
+ state.value = tmp;
++to;
}
for (unsigned int i = 0; i < CHAR_BIT; ++i)
{
unsigned int mask = (1 << i);
- if (state.state & mask)
+ if (state.value & mask)
{
if (to == to_limit)
{
return partial;
}
- state.state &= ~mask;
+ state.value &= ~mask;
*to++ = static_cast<unsigned char>(~mask);
}
}
to_next = to;
- return state.state == 0 ? ok : error;
+ return state.value == 0 ? ok : error;
}
virtual int
if (c & 0xc0)
{
// Unshift sequence
- state.state &= c;
+ state.value &= c;
++from;
continue;
}
unsigned char tmp;
- if (state.state & 0x8)
+ if (state.value & 0x8)
{
if (from >= end - 2)
break;
tmp = (*from++ & 0xf);
tmp |= ((*from++ << 4) & 0xf0);
}
- state.state = tmp;
+ state.value = tmp;
--max;
}
return from - beg;
{ return 11; }
};
-
- // A std::char_traits specialization with POD types for char_type,
- // int_type, and state_type.
template<>
- struct char_traits<__gnu_test::pod_char>
+ class ctype<__gnu_test::pod_uchar>
+ : public __ctype_abstract_base<__gnu_test::pod_uchar>
{
- typedef __gnu_test::pod_char char_type;
- typedef __gnu_test::pod_int int_type;
- typedef __gnu_test::state state_type;
- typedef fpos<state_type> pos_type;
- typedef streamoff off_type;
-
- static void
- assign(char_type& c1, const char_type& c2)
- { c1.c = c2.c; }
-
- static bool
- eq(const char_type& c1, const char_type& c2)
- { return c1.c == c2.c; }
+ public:
+ typedef __gnu_test::pod_uchar char_type;
- static bool
- lt(const char_type& c1, const char_type& c2)
- { return c1.c < c2.c; }
+ explicit ctype(size_t refs = 0)
+ : __ctype_abstract_base<__gnu_test::pod_uchar>(refs) { }
- static int
- compare(const char_type* s1, const char_type* s2, size_t n)
- { return memcmp(s1, s2, n); }
+ static locale::id id;
- static size_t
- length(const char_type* s)
- { return strlen(reinterpret_cast<const char*>(s)); }
+ protected:
+ ~ctype()
+ { }
- static const char_type*
- find(const char_type* s, size_t n, const char_type& a)
- { return static_cast<const char_type*>(memchr(s, a.c, n)); }
+ virtual bool
+ do_is(mask m, char_type c) const
+ { return false; }
- static char_type*
- move(char_type* s1, const char_type* s2, size_t n)
+ virtual const char_type*
+ do_is(const char_type* low, const char_type* high, mask* vec) const
{
- memmove(s1, s2, n);
- return s1;
+ fill_n(vec, high - low, mask());
+ return high;
}
- static char_type*
- copy(char_type* s1, const char_type* s2, size_t n)
- {
- memcpy(s1, s2, n);
- return s1;
- }
+ virtual const char_type*
+ do_scan_is(mask m, const char_type* low, const char_type* high) const
+ { return high; }
- static char_type*
- assign(char_type* s, size_t n, char_type a)
- {
- memset(s, a.c, n);
- return s;
- }
+ virtual const char_type*
+ do_scan_not(mask m, const char_type* low, const char_type* high) const
+ { return low; }
- static char_type
- to_char_type(const int_type& c)
- {
- char_type ret;
- ret.c = static_cast<unsigned char>(c.i);
- return ret;
- }
+ virtual char_type
+ do_toupper(char_type c) const
+ { return c; }
- static int_type
- to_int_type(const char_type& c)
- {
- int_type ret;
- ret.i = c.c;
- return ret;
- }
+ virtual const char_type*
+ do_toupper(char_type* low, const char_type* high) const
+ { return high; }
- static bool
- eq_int_type(const int_type& c1, const int_type& c2)
- { return c1.i == c2.i; }
+ virtual char_type
+ do_tolower(char_type c) const
+ { return c; }
- static int_type
- eof()
+ virtual const char_type*
+ do_tolower(char_type* low, 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
{
- int_type n;
- n.i = -10;
- return n;
+ transform(low, high, dest, &__gnu_test::pod_uchar::from<char>);
+ return high;
}
- static int_type
- not_eof(const int_type& c)
+ 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
{
- if (eq_int_type(c, eof()))
- return int_type();
- return c;
+ 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