File indexing completed on 2025-01-18 09:28:29
0001 #ifndef BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP
0002 #define BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP
0003
0004
0005 #if defined(_MSC_VER)
0006 # pragma once
0007 #endif
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <boost/assert.hpp>
0020 #include <cstddef> // size_t
0021 #include <cstring> // memcpy
0022 #ifndef BOOST_NO_CWCHAR
0023 #include <cwchar> // mbstate_t
0024 #endif
0025 #include <boost/config.hpp>
0026 #if defined(BOOST_NO_STDC_NAMESPACE)
0027 namespace std{
0028 using ::mbstate_t;
0029 using ::memcpy;
0030 }
0031 #endif
0032
0033 #include <boost/archive/detail/utf8_codecvt_facet.hpp>
0034 #include <boost/iterator/iterator_adaptor.hpp>
0035
0036 namespace boost {
0037 namespace archive {
0038 namespace iterators {
0039
0040
0041
0042
0043 template<class Base>
0044 class mb_from_wchar
0045 : public boost::iterator_adaptor<
0046 mb_from_wchar<Base>,
0047 Base,
0048 wchar_t,
0049 single_pass_traversal_tag,
0050 char
0051 >
0052 {
0053 friend class boost::iterator_core_access;
0054
0055 typedef typename boost::iterator_adaptor<
0056 mb_from_wchar<Base>,
0057 Base,
0058 wchar_t,
0059 single_pass_traversal_tag,
0060 char
0061 > super_t;
0062
0063 typedef mb_from_wchar<Base> this_t;
0064
0065 char dereference_impl() {
0066 if(! m_full){
0067 fill();
0068 m_full = true;
0069 }
0070 return m_buffer[m_bnext];
0071 }
0072
0073 char dereference() const {
0074 return (const_cast<this_t *>(this))->dereference_impl();
0075 }
0076
0077 bool equal(const mb_from_wchar<Base> & rhs) const {
0078
0079
0080 return
0081 0 == m_bend
0082 && 0 == m_bnext
0083 && this->base_reference() == rhs.base_reference()
0084 ;
0085 }
0086
0087 void fill(){
0088 wchar_t value = * this->base_reference();
0089 const wchar_t *wend;
0090 char *bend;
0091 BOOST_VERIFY(
0092 m_codecvt_facet.out(
0093 m_mbs,
0094 & value, & value + 1, wend,
0095 m_buffer, m_buffer + sizeof(m_buffer), bend
0096 )
0097 ==
0098 std::codecvt_base::ok
0099 );
0100 m_bnext = 0;
0101 m_bend = bend - m_buffer;
0102 }
0103
0104 void increment(){
0105 if(++m_bnext < m_bend)
0106 return;
0107 m_bend =
0108 m_bnext = 0;
0109 ++(this->base_reference());
0110 m_full = false;
0111 }
0112
0113 boost::archive::detail::utf8_codecvt_facet m_codecvt_facet;
0114 std::mbstate_t m_mbs;
0115
0116 char m_buffer[9 ];
0117 std::size_t m_bend;
0118 std::size_t m_bnext;
0119 bool m_full;
0120
0121 public:
0122
0123 template<class T>
0124 mb_from_wchar(T start) :
0125 super_t(Base(static_cast< T >(start))),
0126 m_mbs(std::mbstate_t()),
0127 m_bend(0),
0128 m_bnext(0),
0129 m_full(false)
0130 {}
0131
0132 mb_from_wchar(const mb_from_wchar & rhs) :
0133 super_t(rhs.base_reference()),
0134 m_mbs(rhs.m_mbs),
0135 m_bend(rhs.m_bend),
0136 m_bnext(rhs.m_bnext),
0137 m_full(rhs.m_full)
0138 {
0139 std::memcpy(m_buffer, rhs.m_buffer, sizeof(m_buffer));
0140 }
0141 };
0142
0143 }
0144 }
0145 }
0146
0147 #endif