Xcode 4.5.2 libc++ std::bad_cast when implementing custom (string)stream

c++, iostream

Solution

Instantiating the IOStreams with a not readily supported stream type requires more than just instantiating it and providing `std::char_traits<cT>`. At the very least you also need to instantiate a number of facets:

- `std::ctype<cT>` gets accessed although not necessarily used in many contexts.

- `std::numpunct<cT>` gets used when formatting or parsing any numeric type.

- `std::num_get<cT>` is needed when parsing sny numeric type.

- `std::num_put<cT>` is beeded when formatting any numeric type.

- If you were to use file streams you'd also need to provide `std::codecvt<cT, char>`.

Off-hand I think these are the facets you need. However, I remember that there were more thing I needed to do to set up my streams than I thought would be necessary.

Problem

I'm having problems implementing my own custom stringbuf and stringstream using char16_t as char type. As test I used a nullstringbuf and nullstringstream that I found in an old, and maybe out dated C++ manual. This nullstringstream acts as "/dev/null" and is a simple implementation. This simple nullstream is working when I use `<char>` but fails with an std::bad_cast exception when I use `<char16_t>`. I know that there must be a `char_traits<char16_t>` available but libc++ seems to have it present. ``` class nullstringbuf : public std::basic_stringbuf<char16_t> { public: nullstringbuf( ) { setp(0,0); setg(0,0,0); } virtual ~nullstringbuf() { } virtual int_type underflow() { setg(0,0,0); return traits_type::eof(); } virtual int overflow(int c) { setp(0,0); if ( c==traits_type::eof() ) return 0; return c; } }; class nullstringstream : virtual public std::basic_stringstream<char16_t> { public: // Constructor(s) nullstringstream(std::ios_base::openmode om = std::ios_base::out | std::ios_base::in) : std::basic_stringstream<char16_t>(om) { init(&m_StreamBuf); } nullstringstream(base::xstring const& val, std::ios_base::openmode om = std::ios_base::out | std::ios_base::in) : std::basic_stringstream<char16_t>(val, om) { init(&m_StreamBuf); } // Destructor virtual ~nullstringstream() { } nullstringbuf* rdbuf() { return &m_StreamBuf; } std::basic_string<char16_t> str() const { return m_StreamBuf.str(); } private: nullstringbuf m_StreamBuf; nullstringstream(nullstringstream const &); // do NOT implement! nullstringstream& operator=(nullstringstream const &); // do NOT implement! }; ``` To get it compiled I also needed to specialize `std::ctype<char16_t>`. My questions?: - Do I need to implement or specialize, besides std::ctype/std::basic_stringbuf/std::basic_stringstream, any more classes or templates? - Has anybody else the same problems using libc++, char16_t and iostreams? Thanks for any help.

Original source