switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / String.ct
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief String non-inline template implementation  */
30
31 //#include "String.ih"
32
33 // Custom includes
34 #include <boost/range.hpp>
35 #include <sstream>
36 #include <boost/lexical_cast.hpp>
37 #include <boost/shared_ptr.hpp>
38
39 #define prefix_
40 //-/////////////////////////////////////////////////////////////////////////////////////////////////
41
42 template <class ForwardReadableRange>
43 prefix_ std::string senf::stringJoin(ForwardReadableRange const & range, std::string sep)
44 {
45     typename boost::range_const_iterator<ForwardReadableRange>::type i (boost::begin(range));
46     typename boost::range_const_iterator<ForwardReadableRange>::type const i_end (boost::end(range));
47     std::stringstream ss;
48
49     if (i != i_end) {
50         for (;;) {
51             ss << *i;
52             if ( ++i != i_end ) ss << sep;
53             else                break;
54         }
55     }
56
57     return ss.str();
58 }
59
60 // Copied from boost/lexical_cast.hpp
61 namespace senf {
62 namespace detail {
63     template<typename Target>
64     class lexical_stream
65     {
66     private:
67         typedef char char_type;
68
69     public:
70         lexical_stream()
71         {
72             stream.unsetf(std::ios::skipws);
73             if (std::numeric_limits<Target>::is_specialized)
74                 stream.precision(std::numeric_limits<Target>::digits10 + 1);
75         }
76         template <class Source>
77         bool operator<<(const Source &input)
78         {
79             if (std::numeric_limits<Source>::is_specialized)
80                 stream.precision(std::numeric_limits<Source>::digits10 + 1);
81             return !(stream << input).fail();
82         }
83         template<typename InputStreamable>
84         bool operator>>(InputStreamable &output)
85         {
86             return !boost::is_pointer<InputStreamable>::value &&
87                    stream >> output &&
88                    stream.get() == std::char_traits<char_type>::eof();
89         }
90         bool operator>>(std::string &output)
91         {
92             output = stream.str();
93             return true;
94         }
95         bool operator>>(std::wstring &output)
96         {
97             output = stream.str();
98             return true;
99         }
100     private:
101         std::basic_stringstream<char_type> stream;
102     };
103
104     template <class Target>
105     class lexical_caster
106     {
107     public:
108         lexical_caster() : interpreter_ (new senf::detail::lexical_stream<Target>()) {}
109         template <class Source>
110         Target operator()(Source const & arg) const
111             {
112                 Target result;
113                 if (!((*interpreter_) << arg && (*interpreter_) >> result))
114                     boost::throw_exception(boost::bad_lexical_cast(typeid(Source), typeid(Target)));
115                 return result;
116             }
117
118         template <class Mod>
119         lexical_caster const & operator[](Mod mod) const
120             {
121                 (*interpreter_) << mod;
122                 return *this;
123             }
124
125     private:
126         boost::shared_ptr< senf::detail::lexical_stream<Target> > interpreter_;
127     };
128 }}
129
130 template <class Target, class Source>
131 prefix_ Target senf::lexical_cast(Source const & arg)
132 {
133     senf::detail::lexical_stream<Target> interpreter;
134     Target result;
135
136     if (!(interpreter << arg && interpreter >> result))
137         boost::throw_exception(boost::bad_lexical_cast(typeid(Source), typeid(Target)));
138     return result;
139 }
140
141 template <class Target>
142 prefix_ senf::detail::lexical_caster<Target> senf::lexical_cast()
143 {
144     return detail::lexical_caster<Target>();
145 }
146
147 //-/////////////////////////////////////////////////////////////////////////////////////////////////
148 #undef prefix_
149
150 \f
151 // Local Variables:
152 // mode: c++
153 // fill-column: 100
154 // comment-column: 40
155 // c-file-style: "senf"
156 // indent-tabs-mode: nil
157 // ispell-local-dictionary: "american"
158 // compile-command: "scons -u test"
159 // End: