00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026
00027
00028
00029 #include <boost/range.hpp>
00030 #include <sstream>
00031 #include <boost/lexical_cast.hpp>
00032 #include <boost/shared_ptr.hpp>
00033
00034 #define prefix_
00035
00036
00037 template <class ForwardReadableRange>
00038 prefix_ std::string senf::stringJoin(ForwardReadableRange const & range, std::string sep)
00039 {
00040 typename boost::range_const_iterator<ForwardReadableRange>::type i (boost::begin(range));
00041 typename boost::range_const_iterator<ForwardReadableRange>::type const i_end (boost::end(range));
00042 std::stringstream ss;
00043
00044 if (i != i_end) {
00045 for (;;) {
00046 ss << *i;
00047 if ( ++i != i_end ) ss << sep;
00048 else break;
00049 }
00050 }
00051
00052 return ss.str();
00053 }
00054
00055
00056 namespace senf {
00057 namespace detail {
00058 template<typename Target>
00059 class lexical_stream
00060 {
00061 private:
00062 typedef char char_type;
00063
00064 public:
00065 lexical_stream()
00066 {
00067 stream.unsetf(std::ios::skipws);
00068 if (std::numeric_limits<Target>::is_specialized)
00069 stream.precision(std::numeric_limits<Target>::digits10 + 1);
00070 }
00071 template <class Source>
00072 bool operator<<(const Source &input)
00073 {
00074 if (std::numeric_limits<Source>::is_specialized)
00075 stream.precision(std::numeric_limits<Source>::digits10 + 1);
00076 return !(stream << input).fail();
00077 }
00078 template<typename InputStreamable>
00079 bool operator>>(InputStreamable &output)
00080 {
00081 return !boost::is_pointer<InputStreamable>::value &&
00082 stream >> output &&
00083 stream.get() == std::char_traits<char_type>::eof();
00084 }
00085 bool operator>>(std::string &output)
00086 {
00087 output = stream.str();
00088 return true;
00089 }
00090 bool operator>>(std::wstring &output)
00091 {
00092 output = stream.str();
00093 return true;
00094 }
00095 private:
00096 std::basic_stringstream<char_type> stream;
00097 };
00098
00099 template <class Target>
00100 class lexical_caster
00101 {
00102 public:
00103 lexical_caster() : interpreter_ (new senf::detail::lexical_stream<Target>()) {}
00104 template <class Source>
00105 Target operator()(Source const & arg) const
00106 {
00107 Target result;
00108 if (!((*interpreter_) << arg && (*interpreter_) >> result))
00109 boost::throw_exception(boost::bad_lexical_cast(typeid(Source), typeid(Target)));
00110 return result;
00111 }
00112
00113 template <class Mod>
00114 lexical_caster const & operator[](Mod mod) const
00115 {
00116 (*interpreter_) << mod;
00117 return *this;
00118 }
00119
00120 private:
00121 boost::shared_ptr< senf::detail::lexical_stream<Target> > interpreter_;
00122 };
00123 }}
00124
00125 template <class Target, class Source>
00126 prefix_ Target senf::lexical_cast(Source const & arg)
00127 {
00128 senf::detail::lexical_stream<Target> interpreter;
00129 Target result;
00130
00131 if (!(interpreter << arg && interpreter >> result))
00132 boost::throw_exception(boost::bad_lexical_cast(typeid(Source), typeid(Target)));
00133 return result;
00134 }
00135
00136 template <class Target>
00137 prefix_ senf::detail::lexical_caster<Target> senf::lexical_cast()
00138 {
00139 return detail::lexical_caster<Target>();
00140 }
00141
00142
00143 #undef prefix_
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154