Update and release the quoted manipulators

This commit is contained in:
Glen Fernandes
2019-12-14 20:11:54 -05:00
parent f47bf89c19
commit 76ee346773
10 changed files with 286 additions and 327 deletions

View File

@ -1,190 +1,18 @@
// boost/io/quoted_manip.hpp ---------------------------------------------------------//
/*
Copyright 2010 Beman Dawes
// Copyright Beman Dawes 2010
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_IO_DETAIL_QUOTED_MANIP_HPP
#define BOOST_IO_DETAIL_QUOTED_MANIP_HPP
// Library home page http://www.boost.org/libs/io
/*
The new implemenation is public in <boost/io/quoted.hpp>
*/
#include <boost/io/quoted.hpp>
//--------------------------------------------------------------------------------------//
#ifndef BOOST_IO_QUOTED_MANIP
#define BOOST_IO_QUOTED_MANIP
#include <iosfwd>
#include <ios>
#include <string>
#include <iterator>
#include <boost/io/ios_state.hpp>
namespace boost
{
namespace io
{
namespace detail { template <class String, class Char> struct quoted_proxy; }
// ------------ public interface ------------------------------------------------//
// manipulator for const std::basic_string&
template <class Char, class Traits, class Alloc>
detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
quoted(const std::basic_string<Char, Traits, Alloc>& s,
Char escape='\\', Char delim='\"');
// manipulator for non-const std::basic_string&
template <class Char, class Traits, class Alloc>
detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char>
quoted(std::basic_string<Char, Traits, Alloc>& s,
Char escape='\\', Char delim='\"');
// manipulator for const C-string*
template <class Char>
detail::quoted_proxy<const Char*, Char>
quoted(const Char* s, Char escape='\\', Char delim='\"');
// ----------- implementation details -------------------------------------------//
namespace detail
{
// proxy used as an argument pack
template <class String, class Char>
struct quoted_proxy
{
String string;
Char escape;
Char delim;
quoted_proxy(String s_, Char escape_, Char delim_)
: string(s_), escape(escape_), delim(delim_) {}
private:
// String may be a const type, so disable the assignment operator
quoted_proxy& operator=(const quoted_proxy&); // = deleted
};
// abstract away difference between proxies with const or non-const basic_strings
template <class Char, class Traits, class Alloc>
std::basic_ostream<Char, Traits>&
basic_string_inserter_imp(std::basic_ostream<Char, Traits>& os,
std::basic_string<Char, Traits, Alloc> const & string, Char escape, Char delim)
{
os << delim;
typename std::basic_string<Char, Traits, Alloc>::const_iterator
end_it = string.end();
for (typename std::basic_string<Char, Traits, Alloc>::const_iterator
it = string.begin();
it != end_it;
++it )
{
if (*it == delim || *it == escape)
os << escape;
os << *it;
}
os << delim;
return os;
}
// inserter for const std::basic_string& proxies
template <class Char, class Traits, class Alloc>
inline
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
const quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>& proxy)
{
return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim);
}
// inserter for non-const std::basic_string& proxies
template <class Char, class Traits, class Alloc>
inline
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
{
return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim);
}
// inserter for const C-string* proxies
template <class Char, class Traits>
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
const quoted_proxy<const Char*, Char>& proxy)
{
os << proxy.delim;
for (const Char* it = proxy.string;
*it;
++it )
{
if (*it == proxy.delim || *it == proxy.escape)
os << proxy.escape;
os << *it;
}
os << proxy.delim;
return os;
}
// extractor for non-const std::basic_string& proxies
template <class Char, class Traits, class Alloc>
std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& is,
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
{
proxy.string.clear();
Char c;
is >> c;
if (c != proxy.delim)
{
is.unget();
is >> proxy.string;
return is;
}
{
boost::io::ios_flags_saver ifs(is);
is >> std::noskipws;
for (;;)
{
is >> c;
if (!is.good()) // cope with I/O errors or end-of-file
break;
if (c == proxy.escape)
{
is >> c;
if (!is.good()) // cope with I/O errors or end-of-file
break;
}
else if (c == proxy.delim)
break;
proxy.string += c;
}
}
return is;
}
} // namespace detail
// manipulator implementation for const std::basic_string&
template <class Char, class Traits, class Alloc>
inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
quoted(const std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim)
{
return detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
(s, escape, delim);
}
// manipulator implementation for non-const std::basic_string&
template <class Char, class Traits, class Alloc>
inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char>
quoted(std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim)
{
return detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>
(s, escape, delim);
}
// manipulator implementation for const C-string*
template <class Char>
inline detail::quoted_proxy<const Char*, Char>
quoted(const Char* s, Char escape, Char delim)
{
return detail::quoted_proxy<const Char*, Char> (s, escape, delim);
}
} // namespace io
} // namespace boost
#endif // BOOST_IO_QUOTED_MANIP
#endif

152
include/boost/io/quoted.hpp Normal file
View File

@ -0,0 +1,152 @@
/*
Copyright 2010 Beman Dawes
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_IO_QUOTED_HPP
#define BOOST_IO_QUOTED_HPP
#include <boost/io/ios_state.hpp>
#include <ios>
#include <iterator>
#include <string>
namespace boost {
namespace io {
namespace detail {
template<class String, class Char>
class quoted_proxy {
public:
quoted_proxy(String string_, Char escape_, Char delim_)
: string(string_)
, escape(escape_)
, delim(delim_) { }
String string;
Char escape;
Char delim;
private:
quoted_proxy& operator=(const quoted_proxy&);
};
template<class Char, class Traits>
inline std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& os,
const quoted_proxy<const Char*, Char>& proxy)
{
os << proxy.delim;
for (const Char* it = proxy.string; *it; ++it) {
if (*it == proxy.delim || *it == proxy.escape) {
os << proxy.escape;
}
os << *it;
}
os << proxy.delim;
return os;
}
template<class Char, class Traits, class Alloc>
inline std::basic_ostream<Char, Traits>&
quoted_output(std::basic_ostream<Char, Traits>& os,
const std::basic_string<Char, Traits, Alloc>& string, Char escape,
Char delim)
{
os << delim;
typename std::basic_string<Char, Traits,
Alloc>::const_iterator end = string.end();
for (typename std::basic_string<Char, Traits,
Alloc>::const_iterator it = string.begin(); it != end; ++it) {
if (*it == delim || *it == escape) {
os << escape;
}
os << *it;
}
os << delim;
return os;
}
template <class Char, class Traits, class Alloc>
inline std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& os,
const quoted_proxy<const std::basic_string<Char, Traits, Alloc>&,
Char>& proxy)
{
return boost::io::detail::quoted_output(os, proxy.string, proxy.escape,
proxy.delim);
}
template<class Char, class Traits, class Alloc>
inline std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& os,
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
{
return boost::io::detail::quoted_output(os, proxy.string, proxy.escape,
proxy.delim);
}
template<class Char, class Traits, class Alloc>
inline std::basic_istream<Char, Traits>&
operator>>(std::basic_istream<Char, Traits>& is,
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
{
proxy.string.clear();
Char ch;
if (!(is >> ch).good()) {
return is;
}
if (ch != proxy.delim) {
is.unget();
is >> proxy.string;
return is;
}
{
boost::io::ios_flags_saver ifs(is);
std::noskipws(is);
while ((is >> ch).good() && ch != proxy.delim) {
if (ch == proxy.escape && !(is >> ch).good()) {
break;
}
proxy.string.push_back(ch);
}
}
return is;
}
} /* detail */
template<class Char, class Traits, class Alloc>
inline detail::quoted_proxy<const std::basic_string<Char, Traits, Alloc>&,
Char>
quoted(const std::basic_string<Char, Traits, Alloc>& s, Char escape='\\',
Char delim='\"')
{
return detail::quoted_proxy<const std::basic_string<Char, Traits, Alloc>&,
Char>(s, escape, delim);
}
template<class Char, class Traits, class Alloc>
inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>
quoted(std::basic_string<Char, Traits, Alloc>& s, Char escape='\\',
Char delim='\"')
{
return detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>&,
Char>(s, escape, delim);
}
template<class Char>
inline detail::quoted_proxy<const Char*, Char>
quoted(const Char* s, Char escape='\\', Char delim='\"')
{
return detail::quoted_proxy<const Char*, Char>(s, escape, delim);
}
} /* io */
} /* boost */
#endif