boost/interprocess/detail/char_wchar_holder.hpp
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2020-2021. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTERPROCESS_DETAIL_CHAR_WCHAR_HOLDER_HPP
#define BOOST_INTERPROCESS_DETAIL_CHAR_WCHAR_HOLDER_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <cwchar>
#include <cstring>
namespace boost {
namespace interprocess {
class char_wchar_holder
{
public:
char_wchar_holder()
: m_str(), m_is_wide()
{
m_str.n = 0;
}
char_wchar_holder(const char *nstr)
: m_str(), m_is_wide()
{
m_str.n = new char [std::strlen(nstr)+1];
std::strcpy(m_str.n, nstr);
}
char_wchar_holder(const wchar_t *wstr)
: m_str(), m_is_wide(true)
{
m_str.w = new wchar_t [std::wcslen(wstr)+1];
std::wcscpy(m_str.w, wstr);
}
char_wchar_holder& operator=(const char *nstr)
{
char *tmp = new char [std::strlen(nstr)+1];
this->delete_mem();
m_str.n = tmp;
std::strcpy(m_str.n, nstr);
m_is_wide = false;
return *this;
}
char_wchar_holder& operator=(const wchar_t *wstr)
{
wchar_t *tmp = new wchar_t [std::wcslen(wstr)+1];
this->delete_mem();
m_str.w = tmp;
std::wcscpy(m_str.w, wstr);
m_is_wide = true;
return *this;
}
char_wchar_holder& operator=(const char_wchar_holder &other)
{
if (other.m_is_wide)
*this = other.getw();
else
*this = other.getn();
return *this;
}
~char_wchar_holder()
{
this->delete_mem();
}
wchar_t *getw() const
{ return m_is_wide ? m_str.w : 0; }
char *getn() const
{ return !m_is_wide ? m_str.n : 0; }
void swap(char_wchar_holder& other)
{
char_wchar tmp;
std::memcpy(&tmp, &m_str, sizeof(char_wchar));
std::memcpy(&m_str, &other.m_str, sizeof(char_wchar));
std::memcpy(&other.m_str, &tmp, sizeof(char_wchar));
//
bool b_tmp(m_is_wide);
m_is_wide = other.m_is_wide;
other.m_is_wide = b_tmp;
}
private:
void delete_mem()
{
if(m_is_wide)
delete [] m_str.w;
else
delete [] m_str.n;
}
union char_wchar
{
char *n;
wchar_t *w;
} m_str;
bool m_is_wide;
};
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
#endif //BOOST_INTERPROCESS_DETAIL_CHAR_WCHAR_HOLDER_HPP