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.
master
Nat Goodspeed 2018-05-17 05:45:36 -04:00
parent ed891c60de
commit c09d9c12e7
2 changed files with 36 additions and 30 deletions

View File

@ -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) */

View File

@ -109,6 +109,12 @@ public:
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 @@ public:
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 @@ private:
LLError::RecorderPtr mRecorder;
};
inline
std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
{
return log.streamto(out);
}
#endif /* ! defined(LL_WRAPLLERRS_H) */