/
unicode_cast.hpp
116 lines (106 loc) · 3.15 KB
/
unicode_cast.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
Copyright (C) 2003 - 2014 by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef SERIALIZATION_UNICODE_CAST_HPP_INCLUDED
#define SERIALIZATION_UNICODE_CAST_HPP_INCLUDED
#include "ucs4_convert_impl.hpp"
#include <iostream> //for std::cerr
#include <iterator>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
namespace ucs4_convert_impl
{
//transforms an outputiterator to a writer for ucs4_convert_impl functions.
template<typename oitor_t>
struct iteratorwriter
{
oitor_t& out_;
iteratorwriter(oitor_t& out) : out_(out) {}
bool can_push(size_t /*count*/)
{
return true;
}
template<typename value_type>
void push(value_type val)
{
*out_++ = val;
}
};
template<typename Tret, typename Tcheck>
struct enableif
{
typedef Tcheck ignore;
typedef Tret type;
};
}
/**
@tparam TD
output, a collection type.
@tparam TS
input, a collection type.
@return an instance of TD
*/
template<typename TD , typename TS>
typename ucs4_convert_impl::enableif<TD, typename TS::value_type>::type unicode_cast(const TS& source)
//TD unicode_cast(const TS& source)
{
using namespace ucs4_convert_impl;
typedef typename convert_impl<typename TD::value_type>::type t_impl_writer;
typedef typename convert_impl<typename TS::value_type>::type t_impl_reader;
typedef typename std::back_insert_iterator<TD> t_outputitor;
typedef typename TS::const_iterator t_inputitor;
TD res;
try
{
t_outputitor inserter(res);
iteratorwriter<t_outputitor> dst(inserter);
t_inputitor i1 = source.begin();
t_inputitor i2 = source.end();
while(i1 != i2) {
t_impl_writer::write (dst, t_impl_reader::read(i1, i2));
}
}
catch(utf8::invalid_utf8_exception&)
{
///TODO: use a ERR_.. stream but i dont know whether i can so to in header easily.
std::cerr << "Failed to convert a string from " << t_impl_reader::get_name() << " to " << t_impl_writer::get_name() << "\n";
return res;
}
return res;
}
/**
@tparam TD
output, a collection type.
@return an instance of TD
*/
template<typename TD>
TD unicode_cast(ucs4::char_t onechar)
{
using namespace ucs4_convert_impl;
typedef typename convert_impl<typename TD::value_type>::type t_impl_writer;
typedef convert_impl<ucs4::char_t>::type t_impl_reader;
typedef typename std::back_insert_iterator<TD> t_outputitor;
TD res;
try
{
t_outputitor inserter(res);
iteratorwriter<t_outputitor> dst(inserter);
t_impl_writer::write (dst, onechar);
}
catch(utf8::invalid_utf8_exception&)
{
///TODO: use a ERR_.. stream but i dont know whether i can so to in header easily.
std::cerr << "Failed to convert a string from " << t_impl_reader::get_name() << " to " << t_impl_writer::get_name() << "\n";
return res;
}
return res;
}
#endif