#include <stlsoft/stlsoft.h>
#include <platformstl/platformstl.h>
#if defined(STLSOFT_COMPILER_IS_GCC) && \
( !defined(UNIXSTL_OS_IS_MACOSX) || \
__GNUC__ < 4)
# include <stlsoft/string/shim_string.hpp>
class Person;
class Person_inserter;
namespace stlsoft
{
# ifdef PANTHEIOS_USE_WIDE_STRINGS
PAN_CHAR_T const* c_str_data_w(Person_inserter const& pi);
size_t c_str_len_w(Person_inserter const& pi);
stlsoft::basic_shim_string<PAN_CHAR_T> c_str_data_w(Person const& person);
size_t c_str_len_w(Person const& pi);
# else
char const* c_str_data_a(Person_inserter const& pi);
size_t c_str_len_a(Person_inserter const& pi);
stlsoft::basic_shim_string<char> c_str_data_a(Person const& person);
size_t c_str_len_a(Person const& pi);
# endif
}
#endif
#include <pantheios/pantheios.hpp>
#include <pantheios/inserters/integer.hpp>
#include <pantheios/inserters/w2m.hpp>
#include <pantheios/quality/contract.h>
#include <pantheios/internal/safestr.h>
#include <stlsoft/conversion/char_conversions.hpp>
#include <stlsoft/conversion/integer_to_string.hpp>
#include <pantheios/util/memory/auto_buffer_selector.hpp>
#include <stlsoft/string/shim_string.hpp>
#include <exception>
#include <new>
#include <string>
#include <stdlib.h>
#if defined(STLSOFT_COMPILER_IS_MSVC) && \
defined(PANTHEIOS_USING_SAFE_STR_FUNCTIONS)
# pragma warning(disable : 4996)
#endif
#define PSTR(x) PANTHEIOS_LITERAL_STRING(x)
typedef std::basic_string<char> string_m_t;
typedef std::basic_string<wchar_t> string_w_t;
typedef std::basic_string<PAN_CHAR_T> string_t;
class Person
{
private:
typedef string_w_t string_type;
public:
Person(wchar_t const* forename, wchar_t const* surname, unsigned age)
: m_forename(forename)
, m_surname(surname)
, m_age(age)
{}
public:
string_type const& forename() const
{
return m_forename;
}
string_type const& surname() const
{
return m_surname;
}
unsigned age() const
{
return m_age;
}
private:
const string_type m_forename;
const string_type m_surname;
const unsigned m_age;
private:
Person &operator =(Person const&);
};
PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PANTHEIOS_LITERAL_STRING("example.cpp.misc.custom_type_1");
static void log_with_explicit_conversion_code(Person const& person);
static void log_with_conversion_function(Person const& person);
static void log_with_string_access_shims(Person const& person);
static void log_with_inserter_class(Person const& person);
int main()
{
try
{
Person person(L"Dr", L"Proctor", 38);
log_with_explicit_conversion_code(person);
log_with_conversion_function(person);
log_with_string_access_shims(person);
log_with_inserter_class(person);
return EXIT_SUCCESS;
}
catch(std::bad_alloc&)
{
pantheios::log(pantheios::alert, PSTR("out of memory"));
}
catch(std::exception& x)
{
pantheios::log_CRITICAL(PSTR("Exception: "), x);
}
catch(...)
{
pantheios::logputs(pantheios::emergency, PSTR("Unexpected unknown error"));
}
return EXIT_FAILURE;
}
static void log_with_explicit_conversion_code(Person const& person)
{
if(pantheios::isSeverityLogged(pantheios::notice))
{
pantheios::log_NOTICE(PSTR("Person: "), pantheios::w2m(person.forename().c_str()), PSTR(" "), pantheios::w2m(person.surname().c_str()), PSTR(", aged "), pantheios::integer(person.age()));
}
}
static string_t Person_to_string(Person const& person)
{
string_w_t result;
wchar_t sz[21];
result += person.forename();
result += L' ';
result += person.surname();
result += L", aged ";
result += stlsoft::integer_to_string(sz, STLSOFT_NUM_ELEMENTS(sz), person.age());
# ifdef PANTHEIOS_USE_WIDE_STRINGS
return result;
# else
using ::stlsoft::w2m;
return string_t(stlsoft::w2m(result));
# endif
}
static void log_with_conversion_function(Person const& person)
{
pantheios::log_NOTICE(PSTR("Person: "), Person_to_string(person));
}
namespace stlsoft
{
# ifdef PANTHEIOS_USE_WIDE_STRINGS
inline stlsoft::basic_shim_string<PAN_CHAR_T> c_str_data_w(Person const& person)
# else
inline stlsoft::basic_shim_string<PAN_CHAR_T> c_str_data_a(Person const& person)
# endif
{
string_w_t result;
wchar_t sz[21];
result += person.forename();
result += L' ';
result += person.surname();
result += L", aged ";
result += stlsoft::integer_to_string(sz, STLSOFT_NUM_ELEMENTS(sz), person.age());
# ifdef PANTHEIOS_USE_WIDE_STRINGS
return stlsoft::basic_shim_string<PAN_CHAR_T>(result.c_str());
# else
return stlsoft::basic_shim_string<PAN_CHAR_T>(stlsoft::w2m(result.c_str()));
# endif
}
# ifdef PANTHEIOS_USE_WIDE_STRINGS
inline size_t c_str_len_w(Person const& person)
# else
inline size_t c_str_len_a(Person const& person)
# endif
{
# ifdef PANTHEIOS_USE_WIDE_STRINGS
return c_str_data_w(person);
# else
return c_str_data_a(person);
# endif
}
}
static void log_with_string_access_shims(Person const& person)
{
pantheios::log_NOTICE(PSTR("Person: "), person);
}
class Person_inserter
{
public:
typedef Person_inserter class_type;
public:
Person_inserter(Person const& person)
: m_person(person)
, m_value()
{}
#if defined(STLSOFT_COMPILER_IS_GCC)
Person_inserter(class_type const& rhs)
: m_person(rhs.m_person)
, m_value(rhs.m_value)
{}
#endif
private:
class_type& operator =(class_type const&);
public:
PAN_CHAR_T const* data() const
{
if(m_value.empty())
{
construct_();
}
return m_value.data();
}
size_t size() const
{
if(m_value.empty())
{
construct_();
}
return m_value.size();
}
public:
void construct_() const
{
const_cast<class_type*>(this)->construct_();
}
void construct_()
{
wchar_t sz[21];
size_t cchNumber;
wchar_t const* num = stlsoft::integer_to_string(sz, STLSOFT_NUM_ELEMENTS(sz), m_person.age(), cchNumber);
string_w_t value;
value.reserve(m_person.forename().size() + 1 + m_person.surname().size() + 7 + cchNumber);
value += m_person.forename().c_str();
value += L' ';
value += m_person.surname().c_str();
value += L", aged ";
value += num;
# ifdef PANTHEIOS_USE_WIDE_STRINGS
m_value.swap(value);
# else
string_t t(stlsoft::w2m(value).c_str());
m_value.swap(t);
# endif
}
private:
Person const& m_person;
string_t m_value;
};
namespace stlsoft
{
#ifdef PANTHEIOS_USE_WIDE_STRINGS
inline PAN_CHAR_T const *c_str_data_w(Person_inserter const& pi)
#else
inline char const *c_str_data_a(Person_inserter const& pi)
#endif
{
return pi.data();
}
#ifdef PANTHEIOS_USE_WIDE_STRINGS
inline size_t c_str_len_w(Person_inserter const& pi)
#else
inline size_t c_str_len_a(Person_inserter const& pi)
#endif
{
return pi.size();
}
}
static void log_with_inserter_class(Person const& person)
{
pantheios::log_NOTICE(PSTR("Person: "), Person_inserter(person));
}