Chris@16: // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) Chris@16: // (C) Copyright 2003-2007 Jonathan Turkanis Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) Chris@16: Chris@16: // See http://www.boost.org/libs/iostreams for documentation. Chris@16: Chris@16: // Contains the definition of the template codecvt_helper, useful for Chris@16: // defining specializations of std::codecvt where state_type != mbstate_t. Chris@16: // Compensates for the fact that some standard library implementations Chris@16: // do not derive the primiary codecvt template from locale::facet or Chris@16: // provide the correct member types and functions. Chris@16: Chris@16: // Usage: Chris@16: // Chris@16: // // In global namespace: Chris@16: // BOOST_IOSTREAMS_CODECVT_SPEC(mystate) Chris@16: // Chris@16: // // In user namespace: Chris@16: // template Chris@16: // struct mycodecvt : codecvt_helper { ... }; Chris@16: // Chris@16: // // Or: Chris@16: // struct mycodecvt : codecvt_helper { ... }; Chris@16: // Chris@16: // Etc. Chris@16: Chris@16: #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED Chris@16: #define BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1020) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include // Put size_t in std, BOOST_MSVC, Dinkum. Chris@16: #include Chris@16: #include // min. Chris@16: #include // size_t. Chris@16: #include // locale, codecvt_base, codecvt. Chris@16: #include Chris@16: Chris@16: //------------------Definition of traits--------------------------------------// Chris@16: Chris@16: namespace boost { namespace iostreams { namespace detail { Chris@16: Chris@16: #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-----------------------// Chris@16: Chris@16: template Chris@16: struct codecvt_intern { typedef typename T::intern_type type; }; Chris@16: Chris@16: template Chris@16: struct codecvt_extern { typedef typename T::extern_type type; }; Chris@16: Chris@16: #else // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //--------------// Chris@16: Chris@16: template Chris@16: struct codecvt_intern { typedef typename T::from_type type; }; Chris@16: Chris@16: template Chris@16: struct codecvt_extern { typedef typename T::to_type type; }; Chris@16: Chris@16: #endif // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-------------// Chris@16: Chris@16: template Chris@16: struct codecvt_state { typedef typename T::state_type type; }; Chris@16: Chris@16: } } } // End namespaces detail, iostreams, boost. Chris@16: Chris@16: //------------------Definition of codecvt_impl--------------------------------// Chris@16: Chris@16: #if defined(BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \ Chris@16: defined(BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) || \ Chris@16: defined(BOOST_IOSTREAMS_NO_LOCALE) \ Chris@16: /**/ Chris@16: Chris@16: namespace boost { namespace iostreams { namespace detail { Chris@16: Chris@16: template Chris@16: struct codecvt_impl : std::locale::facet, std::codecvt_base { Chris@16: public: Chris@16: typedef Intern intern_type; Chris@16: typedef Extern extern_type; Chris@16: typedef State state_type; Chris@16: Chris@16: codecvt_impl(std::size_t refs = 0) : std::locale::facet(refs) { } Chris@16: Chris@16: std::codecvt_base::result Chris@16: in( State& state, const Extern* first1, const Extern* last1, Chris@16: const Extern*& next1, Intern* first2, Intern* last2, Chris@16: Intern*& next2 ) const Chris@16: { Chris@16: return do_in(state, first1, last1, next1, first2, last2, next2); Chris@16: } Chris@16: Chris@16: std::codecvt_base::result Chris@16: out( State& state, const Intern* first1, const Intern* last1, Chris@16: const Intern*& next1, Extern* first2, Extern* last2, Chris@16: Extern*& next2 ) const Chris@16: { Chris@16: return do_out(state, first1, last1, next1, first2, last2, next2); Chris@16: } Chris@16: Chris@16: std::codecvt_base::result Chris@16: unshift(State& state, Extern* first2, Extern* last2, Extern*& next2) const Chris@16: { Chris@16: return do_unshift(state, first2, last2, next2); Chris@16: } Chris@16: Chris@16: bool always_noconv() const throw() { return do_always_noconv(); } Chris@16: Chris@16: int max_length() const throw() { return do_max_length(); } Chris@16: Chris@16: int encoding() const throw() { return do_encoding(); } Chris@16: Chris@16: int length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State& state, Chris@16: const Extern* first1, const Extern* last1, Chris@16: std::size_t len2 ) const throw() Chris@16: { Chris@16: return do_length(state, first1, last1, len2); Chris@16: } Chris@16: protected: Chris@16: std::codecvt_base::result Chris@16: virtual do_in( State&, const Extern*, const Extern*, const Extern*&, Chris@16: Intern*, Intern*, Intern*& ) const Chris@16: { Chris@16: return std::codecvt_base::noconv; Chris@16: } Chris@16: Chris@16: std::codecvt_base::result Chris@16: virtual do_out( State&, const Intern*, const Intern*, const Intern*&, Chris@16: Extern*, Extern*, Extern*& ) const Chris@16: { Chris@16: return std::codecvt_base::noconv; Chris@16: } Chris@16: Chris@16: std::codecvt_base::result Chris@16: virtual do_unshift(State&, Extern*, Extern*, Extern*&) const Chris@16: { Chris@16: return std::codecvt_base::ok; Chris@16: } Chris@16: Chris@16: virtual bool do_always_noconv() const throw() { return true; } Chris@16: Chris@16: virtual int do_max_length() const throw() { return 1; } Chris@16: Chris@16: virtual int do_encoding() const throw() { return 1; } Chris@16: Chris@16: virtual int do_length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State&, Chris@16: const Extern* first1, const Extern* last1, Chris@16: std::size_t len2 ) const throw() Chris@16: { Chris@16: return (std::min)(static_cast(last1 - first1), len2); Chris@16: } Chris@16: }; Chris@16: Chris@16: } } } // End namespaces detail, iostreams, boost. Chris@16: Chris@16: #endif // no primary codecvt definition, empty definition. Chris@16: Chris@16: //------------------Definition of BOOST_IOSTREAMS_CODECVT_SPEC----------------// Chris@16: Chris@16: #if defined(BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \ Chris@16: defined(BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) \ Chris@16: /**/ Chris@16: # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION Chris@16: # define BOOST_IOSTREAMS_CODECVT_SPEC(state) \ Chris@16: namespace std { \ Chris@16: template \ Chris@16: class codecvt \ Chris@16: : public ::boost::iostreams::detail::codecvt_impl< \ Chris@16: Intern, Extern, state \ Chris@16: > \ Chris@16: { \ Chris@16: public: \ Chris@16: codecvt(std::size_t refs = 0) \ Chris@16: : ::boost::iostreams::detail::codecvt_impl< \ Chris@16: Intern, Extern, state \ Chris@16: >(refs) \ Chris@16: { } \ Chris@16: static std::locale::id id; \ Chris@16: }; \ Chris@16: template \ Chris@16: std::locale::id codecvt::id; \ Chris@16: } \ Chris@16: /**/ Chris@16: # else Chris@16: # define BOOST_IOSTREAMS_CODECVT_SPEC(state) \ Chris@16: namespace std { \ Chris@16: template<> \ Chris@16: class codecvt \ Chris@16: : public ::boost::iostreams::detail::codecvt_impl< \ Chris@16: wchar_t, char, state \ Chris@16: > \ Chris@16: { \ Chris@16: public: \ Chris@16: codecvt(std::size_t refs = 0) \ Chris@16: : ::boost::iostreams::detail::codecvt_impl< \ Chris@16: wchar_t, char, state \ Chris@16: >(refs) \ Chris@16: { } \ Chris@16: static std::locale::id id; \ Chris@16: }; \ Chris@16: template<> \ Chris@16: std::locale::id codecvt::id; \ Chris@16: } \ Chris@16: /**/ Chris@16: # endif Chris@16: #else Chris@16: # define BOOST_IOSTREAMS_CODECVT_SPEC(state) Chris@16: #endif // no primary codecvt definition, or empty definition. Chris@16: Chris@16: namespace boost { namespace iostreams { namespace detail { Chris@16: Chris@16: //------------------Definition of codecvt_helper------------------------------// Chris@16: Chris@16: template Chris@16: struct codecvt_helper : std::codecvt { Chris@16: typedef Intern intern_type; Chris@16: typedef Extern extern_type; Chris@16: typedef State state_type; Chris@16: codecvt_helper(std::size_t refs = 0) Chris@16: #if !defined(BOOST_IOSTREAMS_NO_CODECVT_CTOR_FROM_SIZE_T) Chris@16: : std::codecvt(refs) Chris@16: #else Chris@16: : std::codecvt() Chris@16: #endif Chris@16: { } Chris@16: #ifdef BOOST_IOSTREAMS_NO_CODECVT_MAX_LENGTH Chris@16: int max_length() const throw() { return do_max_length(); } Chris@16: protected: Chris@16: virtual int do_max_length() const throw() { return 1; } Chris@16: #endif Chris@16: }; Chris@16: Chris@16: } } } // End namespaces detail, iostreams, boost. Chris@16: Chris@16: #endif // #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED