Skip to content
Snippets Groups Projects
Commit c09d9c12 authored by Nat Goodspeed's avatar Nat Goodspeed
Browse files

SL-821: Add WSTRINGIZE() and DEWSTRINGIZE() macros for wide strings.

Streamline convenience overload stringize(std::wstring); make convenience
overload wstringize(std::string) symmetrically convert from UTF-8 string.

Also eliminate STRINGIZE() et al. dependency on Boost.Phoenix: use lambdas
instead.

Using lambdas instead of template expansion necessitates reordering some code
in wrapllerrs.h.
parent ed891c60
No related branches found
No related tags found
No related merge requests found
......@@ -30,7 +30,6 @@
#define LL_STRINGIZE_H
#include <sstream>
#include <boost/phoenix/phoenix.hpp>
#include <llstring.h>
/**
......@@ -53,12 +52,7 @@ std::basic_string<CHARTYPE> gstringize(const T& item)
*/
inline std::string stringize(const std::wstring& item)
{
LL_WARNS() << "WARNING: Possible narrowing" << LL_ENDL;
std::string s;
s = wstring_to_utf8str(item);
return gstringize<char>(s);
return wstring_to_utf8str(item);
}
/**
......@@ -76,7 +70,10 @@ std::string stringize(const T& item)
*/
inline std::wstring wstringize(const std::string& item)
{
return gstringize<wchar_t>(item.c_str());
// utf8str_to_wstring() returns LLWString, which isn't necessarily the
// same as std::wstring
LLWString s(utf8str_to_wstring(item));
return std::wstring(s.begin(), s.end());
}
/**
......@@ -91,10 +88,10 @@ std::wstring wstringize(const T& item)
/**
* stringize_f(functor)
*/
template <typename Functor>
std::string stringize_f(Functor const & f)
template <typename CHARTYPE, typename Functor>
std::basic_string<CHARTYPE> stringize_f(Functor const & f)
{
std::ostringstream out;
std::basic_ostringstream<CHARTYPE> out;
f(out);
return out.str();
}
......@@ -108,31 +105,37 @@ std::string stringize_f(Functor const & f)
* return out.str();
* @endcode
*/
#define STRINGIZE(EXPRESSION) (stringize_f(boost::phoenix::placeholders::arg1 << EXPRESSION))
#define STRINGIZE(EXPRESSION) (stringize_f<char>([&](std::ostream& out){ out << EXPRESSION; }))
/**
* WSTRINGIZE() is the wstring equivalent of STRINGIZE()
*/
#define WSTRINGIZE(EXPRESSION) (stringize_f<wchar_t>([&](std::wostream& out){ out << EXPRESSION; }))
/**
* destringize(str)
* defined for symmetry with stringize
* *NOTE - this has distinct behavior from boost::lexical_cast<T> regarding
* @NOTE - this has distinct behavior from boost::lexical_cast<T> regarding
* leading/trailing whitespace and handling of bad_lexical_cast exceptions
* @NOTE - no need for dewstringize(), since passing std::wstring will Do The
* Right Thing
*/
template <typename T>
T destringize(std::string const & str)
template <typename T, typename CHARTYPE>
T destringize(std::basic_string<CHARTYPE> const & str)
{
T val;
std::istringstream in(str);
in >> val;
T val;
std::basic_istringstream<CHARTYPE> in(str);
in >> val;
return val;
}
/**
* destringize_f(str, functor)
*/
template <typename Functor>
void destringize_f(std::string const & str, Functor const & f)
template <typename CHARTYPE, typename Functor>
void destringize_f(std::basic_string<CHARTYPE> const & str, Functor const & f)
{
std::istringstream in(str);
std::basic_istringstream<CHARTYPE> in(str);
f(in);
}
......@@ -143,8 +146,11 @@ void destringize_f(std::string const & str, Functor const & f)
* std::istringstream in(str);
* in >> item1 >> item2 >> item3 ... ;
* @endcode
* @NOTE - once we get generic lambdas, we shouldn't need DEWSTRINGIZE() any
* more since DESTRINGIZE() should do the right thing with a std::wstring. But
* until then, the lambda we pass must accept the right std::basic_istream.
*/
#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), (boost::phoenix::placeholders::arg1 >> EXPRESSION)))
#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::istream& in){in >> EXPRESSION;}))
#define DEWSTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::wistream& in){in >> EXPRESSION;}))
#endif /* ! defined(LL_STRINGIZE_H) */
......@@ -109,6 +109,12 @@ class CaptureLogRecorder : public LLError::Recorder, public boost::noncopyable
mMessages.push_back(message);
}
friend inline
std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
{
return log.streamto(out);
}
/// Don't assume the message we want is necessarily the LAST log message
/// emitted by the underlying code; search backwards through all messages
/// for the sought string.
......@@ -126,7 +132,7 @@ class CaptureLogRecorder : public LLError::Recorder, public boost::noncopyable
throw tut::failure(STRINGIZE("failed to find '" << search
<< "' in captured log messages:\n"
<< boost::ref(*this)));
<< *this));
}
std::ostream& streamto(std::ostream& out) const
......@@ -200,10 +206,4 @@ class CaptureLog : public boost::noncopyable
LLError::RecorderPtr mRecorder;
};
inline
std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
{
return log.streamto(out);
}
#endif /* ! defined(LL_WRAPLLERRS_H) */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment