String.ct
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
14 /** \file
15  \brief String non-inline template implementation */
16 
17 //#include "String.ih"
18 
19 // Custom includes
20 #include <boost/range.hpp>
21 #include <sstream>
22 #include <boost/lexical_cast.hpp>
23 #include <boost/shared_ptr.hpp>
24 
25 #define prefix_
26 //-/////////////////////////////////////////////////////////////////////////////////////////////////
27 
28 template <class ForwardReadableRange>
29 prefix_ std::string senf::stringJoin(ForwardReadableRange const & range, std::string sep)
30 {
31  typename boost::range_const_iterator<ForwardReadableRange>::type i (boost::begin(range));
32  typename boost::range_const_iterator<ForwardReadableRange>::type const i_end (boost::end(range));
33  std::stringstream ss;
34 
35  if (i != i_end) {
36  for (;;) {
37  ss << *i;
38  if ( ++i != i_end ) ss << sep;
39  else break;
40  }
41  }
42 
43  return ss.str();
44 }
45 
46 // Copied from boost/lexical_cast.hpp
47 namespace senf {
48 namespace detail {
49  template<typename Target>
50  class lexical_stream
51  {
52  private:
53  typedef char char_type;
54 
55  public:
56  lexical_stream()
57  {
58  stream.unsetf(std::ios::skipws);
59  if (std::numeric_limits<Target>::is_specialized)
60  stream.precision(std::numeric_limits<Target>::digits10 + 1);
61  }
62  template <class Source>
63  bool operator<<(const Source &input)
64  {
65  if (std::numeric_limits<Source>::is_specialized)
66  stream.precision(std::numeric_limits<Source>::digits10 + 1);
67  return !(stream << input).fail();
68  }
69  template<typename InputStreamable>
70  bool operator>>(InputStreamable &output)
71  {
72  return !boost::is_pointer<InputStreamable>::value &&
73  stream >> output &&
74  stream.get() == std::char_traits<char_type>::eof();
75  }
76  bool operator>>(std::string &output)
77  {
78  output = stream.str();
79  return true;
80  }
81  bool operator>>(std::wstring &output)
82  {
83  output = stream.str();
84  return true;
85  }
86  private:
87  std::basic_stringstream<char_type> stream;
88  };
89 
90  template <class Target>
91  class lexical_caster
92  {
93  public:
94  lexical_caster() : interpreter_ (new senf::detail::lexical_stream<Target>()) {}
95  template <class Source>
96  Target operator()(Source const & arg) const
97  {
98  Target result;
99  if (!((*interpreter_) << arg && (*interpreter_) >> result))
100  boost::throw_exception(boost::bad_lexical_cast(typeid(Source), typeid(Target)));
101  return result;
102  }
103 
104  template <class Mod>
105  lexical_caster const & operator[](Mod mod) const
106  {
107  (*interpreter_) << mod;
108  return *this;
109  }
110 
111  private:
112  boost::shared_ptr< senf::detail::lexical_stream<Target> > interpreter_;
113  };
114 }}
115 
116 template <class Target, class Source>
117 prefix_ Target senf::lexical_cast(Source const & arg)
118 {
119  senf::detail::lexical_stream<Target> interpreter;
120  Target result;
121 
122  if (!(interpreter << arg && interpreter >> result))
123  boost::throw_exception(boost::bad_lexical_cast(typeid(Source), typeid(Target)));
124  return result;
125 }
126 
127 template <class Target>
128 prefix_ senf::detail::lexical_caster<Target> senf::lexical_cast()
129 {
130  return detail::lexical_caster<Target>();
131 }
132 
133 //-/////////////////////////////////////////////////////////////////////////////////////////////////
134 #undef prefix_
135 
136 
137 // Local Variables:
138 // mode: c++
139 // fill-column: 100
140 // comment-column: 40
141 // c-file-style: "senf"
142 // indent-tabs-mode: nil
143 // ispell-local-dictionary: "american"
144 // compile-command: "scons -u test"
145 // End: