1 // char_conv.hh 2 // This file is part of libpbe; see http://anyterm.org/ 3 // (C) 2008 Philip Endecott 4 5 // Distributed under the Boost Software License, Version 1.0: 6 // 7 // Permission is hereby granted, free of charge, to any person or organization 8 // obtaining a copy of the software and accompanying documentation covered by 9 // this license (the "Software") to use, reproduce, display, distribute, 10 // execute, and transmit the Software, and to prepare derivative works of the 11 // Software, and to permit third-parties to whom the Software is furnished to 12 // do so, all subject to the following: 13 // 14 // The copyright notices in the Software and this entire statement, including 15 // the above license grant, this restriction and the following disclaimer, 16 // must be included in all copies of the Software, in whole or in part, and 17 // all derivative works of the Software, unless such copies or derivative 18 // works are solely in the form of machine-executable object code generated by 19 // a source language processor. 20 // 21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 24 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 25 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 26 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 27 // DEALINGS IN THE SOFTWARE. 28 29 #ifndef libpbe_charset_char_conv_hh 30 #define libpbe_charset_char_conv_hh 31 32 #include "charset_t.hh" 33 #include "charset_traits.hh" 34 #include "error_policy.hh" 35 36 #include <boost/static_assert.hpp> 37 38 #include "compiler_magic.hh" 39 40 41 namespace pbe { 42 43 // Conversion of characters between character sets 44 // ----------------------------------------------- 45 // 46 // This file provides facilities to convert a single character from 47 // one character set to another. It's implemented using specialisations 48 // for character set pairs in other files. 49 // A template parameter specifies a policy for error handling. 50 // Because function templates can't be partially specialised, and 51 // the character-set-pair specialisation will not want to be specialised 52 // on the error handling polocy, we need to wrap the conversion in a 53 // class. 54 // The default implementation here converts to a UCS4 character as an 55 // intermediate step, which will work as long as the necessary supporting 56 // conversions are implemented somehow. 57 // There's also a specialisation here for the null conversion where source 58 // and destination are the same. 59 60 61 // Base template, with default implementation via ucs4: 62 63 template <charset_t from_cs, charset_t to_cs, typename error_policy> 64 struct char_conv { 65 // We shouldn't be here if from_cs or to_cs is ucs4; that indicates recursion. 66 // A specialisation should have been invoked. Maybe the appropriate 67 // specialisation hasn't been #included, or hasn't been written? 68 BOOST_STATIC_ASSERT(from_cs!=cs::ucs4 && to_cs!=cs::ucs4); 69 70 // FIXME shouldn't this be a static member function? 71 typename charset_traits<to_cs>::char_t operator ()pbe::char_conv72 operator() ( typename charset_traits<from_cs>::char_t c, 73 typename charset_traits<from_cs>::state_t& from_state 74 = charset_traits<from_cs>::state_t(), 75 typename charset_traits<to_cs>::state_t& to_state 76 = charset_traits<to_cs>::state_t() ) 77 { 78 charset_traits<cs::ucs4>::state_t ucs4_state; 79 char32_t tmp = char_conv<from_cs, cs::ucs4, error_policy>() (c,from_state,ucs4_state); 80 return char_conv<cs::ucs4, to_cs, error_policy>() (tmp,ucs4_state,to_state); 81 } 82 }; 83 84 85 // Specialisation for trivial conversion to the same character set: 86 template <charset_t cset, typename error_policy> 87 struct char_conv<cset,cset,error_policy> { 88 typename charset_traits<cset>::char_t operator ()pbe::char_conv89 operator() ( typename charset_traits<cset>::char_t c, 90 PBE_UNUSED_ARG(typename charset_traits<cset>::state_t& from_state) 91 = charset_traits<cset>::state_t(), 92 PBE_UNUSED_ARG(typename charset_traits<cset>::state_t& to_state) 93 = charset_traits<cset>::state_t() ) 94 { 95 return c; 96 } 97 }; 98 99 100 // This macro is used elsewhere to define trivial conversions. 101 102 #define IDENTITY_CHAR_CONV(FROM_CS,TO_CS) \ 103 template <typename error_policy> \ 104 struct char_conv<FROM_CS,TO_CS,error_policy> { \ 105 charset_traits<TO_CS>::char_t \ 106 operator() ( charset_traits<FROM_CS>::char_t c, \ 107 charset_traits<FROM_CS>::state_t&, \ 108 charset_traits<TO_CS>::state_t& ) { \ 109 return static_cast<unsigned charset_traits<FROM_CS>::char_t>(c); \ 110 } \ 111 }; 112 113 114 }; 115 116 #endif 117