feat():initial version
This commit is contained in:
196
install/boost_1_75_0/include/boost/nowide/args.hpp
Normal file
196
install/boost_1_75_0/include/boost/nowide/args.hpp
Normal file
@@ -0,0 +1,196 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_ARGS_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_ARGS_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_WINDOWS
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
#include <boost/nowide/windows.hpp>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
class args
|
||||
{
|
||||
public:
|
||||
args(int&, char**&)
|
||||
{}
|
||||
args(int&, char**&, char**&)
|
||||
{}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
///
|
||||
/// \brief \c args is a class that temporarily replaces standard main() function arguments with their
|
||||
/// equal, but UTF-8 encoded values under Microsoft Windows for the lifetime of the instance.
|
||||
///
|
||||
/// The class uses \c GetCommandLineW(), \c CommandLineToArgvW() and \c GetEnvironmentStringsW()
|
||||
/// in order to obtain Unicode-encoded values.
|
||||
/// It does not relate to actual values of argc, argv and env under Windows.
|
||||
///
|
||||
/// It restores the original values in its destructor (usually at the end of the \c main function).
|
||||
///
|
||||
/// If any of the system calls fails, an exception of type std::runtime_error will be thrown
|
||||
/// and argc, argv, env remain unchanged.
|
||||
///
|
||||
/// \note The class owns the memory of the newly allocated strings.
|
||||
/// So you need to keep it alive as long as you use the values.
|
||||
///
|
||||
/// Usage:
|
||||
/// \code
|
||||
/// int main(int argc, char** argv, char** env) {
|
||||
/// boost::nowide::args _(argc, argv, env); // Note the _ as a "don't care" name for the instance
|
||||
/// // Use argv and env as usual, they are now UTF-8 encoded on Windows
|
||||
/// return 0; // Memory held by args is released
|
||||
/// }
|
||||
/// \endcode
|
||||
class args
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Fix command line arguments
|
||||
///
|
||||
args(int& argc, char**& argv) :
|
||||
old_argc_(argc), old_argv_(argv), old_env_(0), old_argc_ptr_(&argc), old_argv_ptr_(&argv), old_env_ptr_(0)
|
||||
{
|
||||
fix_args(argc, argv);
|
||||
}
|
||||
///
|
||||
/// Fix command line arguments and environment
|
||||
///
|
||||
args(int& argc, char**& argv, char**& env) :
|
||||
old_argc_(argc), old_argv_(argv), old_env_(env), old_argc_ptr_(&argc), old_argv_ptr_(&argv),
|
||||
old_env_ptr_(&env)
|
||||
{
|
||||
fix_args(argc, argv);
|
||||
fix_env(env);
|
||||
}
|
||||
///
|
||||
/// Restore original argc, argv, env values, if changed
|
||||
///
|
||||
~args()
|
||||
{
|
||||
if(old_argc_ptr_)
|
||||
*old_argc_ptr_ = old_argc_;
|
||||
if(old_argv_ptr_)
|
||||
*old_argv_ptr_ = old_argv_;
|
||||
if(old_env_ptr_)
|
||||
*old_env_ptr_ = old_env_;
|
||||
}
|
||||
|
||||
private:
|
||||
class wargv_ptr
|
||||
{
|
||||
wchar_t** p;
|
||||
int argc;
|
||||
|
||||
public:
|
||||
wargv_ptr()
|
||||
{
|
||||
p = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
}
|
||||
~wargv_ptr()
|
||||
{
|
||||
if(p)
|
||||
LocalFree(p);
|
||||
}
|
||||
wargv_ptr(const wargv_ptr&) = delete;
|
||||
wargv_ptr& operator=(const wargv_ptr&) = delete;
|
||||
|
||||
int size() const
|
||||
{
|
||||
return argc;
|
||||
}
|
||||
operator bool() const
|
||||
{
|
||||
return p != NULL;
|
||||
}
|
||||
const wchar_t* operator[](size_t i) const
|
||||
{
|
||||
return p[i];
|
||||
}
|
||||
};
|
||||
class wenv_ptr
|
||||
{
|
||||
wchar_t* p;
|
||||
|
||||
public:
|
||||
wenv_ptr() : p(GetEnvironmentStringsW())
|
||||
{}
|
||||
~wenv_ptr()
|
||||
{
|
||||
if(p)
|
||||
FreeEnvironmentStringsW(p);
|
||||
}
|
||||
wenv_ptr(const wenv_ptr&) = delete;
|
||||
wenv_ptr& operator=(const wenv_ptr&) = delete;
|
||||
|
||||
operator const wchar_t*() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
void fix_args(int& argc, char**& argv)
|
||||
{
|
||||
const wargv_ptr wargv;
|
||||
if(!wargv)
|
||||
throw std::runtime_error("Could not get command line!");
|
||||
args_.resize(wargv.size() + 1, 0);
|
||||
arg_values_.resize(wargv.size());
|
||||
for(int i = 0; i < wargv.size(); i++)
|
||||
args_[i] = arg_values_[i].convert(wargv[i]);
|
||||
argc = wargv.size();
|
||||
argv = &args_[0];
|
||||
}
|
||||
void fix_env(char**& env)
|
||||
{
|
||||
const wenv_ptr wstrings;
|
||||
if(!wstrings)
|
||||
throw std::runtime_error("Could not get environment strings!");
|
||||
const wchar_t* wstrings_end = 0;
|
||||
int count = 0;
|
||||
for(wstrings_end = wstrings; *wstrings_end; wstrings_end += wcslen(wstrings_end) + 1)
|
||||
count++;
|
||||
env_.convert(wstrings, wstrings_end);
|
||||
envp_.resize(count + 1, 0);
|
||||
char* p = env_.get();
|
||||
int pos = 0;
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
if(*p != '=')
|
||||
envp_[pos++] = p;
|
||||
p += strlen(p) + 1;
|
||||
}
|
||||
env = &envp_[0];
|
||||
}
|
||||
|
||||
std::vector<char*> args_;
|
||||
std::vector<short_stackstring> arg_values_;
|
||||
stackstring env_;
|
||||
std::vector<char*> envp_;
|
||||
|
||||
int old_argc_;
|
||||
char** old_argv_;
|
||||
char** old_env_;
|
||||
|
||||
int* old_argc_ptr_;
|
||||
char*** old_argv_ptr_;
|
||||
char*** old_env_ptr_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
#endif
|
||||
107
install/boost_1_75_0/include/boost/nowide/config.hpp
Normal file
107
install/boost_1_75_0/include/boost/nowide/config.hpp
Normal file
@@ -0,0 +1,107 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2019 - 2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_CONFIG_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_CONFIG_HPP_INCLUDED
|
||||
|
||||
/// @file
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/nowide/replacement.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
// MinGW32 requires a __MSVCRT_VERSION__ defined to make some functions available, e.g. _stat64
|
||||
// Hence define this here to target MSVC 7.0 which has the required functions and do it as early as possible
|
||||
// as including a system header might default this to 0x0600 which is to low
|
||||
#if defined(__MINGW32__) && !defined(__MSVCRT_VERSION__)
|
||||
#define __MSVCRT_VERSION__ 0x0700
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_NOWIDE_DYN_LINK)
|
||||
#ifdef BOOST_NOWIDE_SOURCE
|
||||
#define BOOST_NOWIDE_DECL BOOST_SYMBOL_EXPORT
|
||||
#else
|
||||
#define BOOST_NOWIDE_DECL BOOST_SYMBOL_IMPORT
|
||||
#endif // BOOST_NOWIDE_SOURCE
|
||||
#else
|
||||
#define BOOST_NOWIDE_DECL
|
||||
#endif // BOOST_NOWIDE_DYN_LINK
|
||||
|
||||
//
|
||||
// Automatically link to the correct build variant where possible.
|
||||
//
|
||||
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_NOWIDE_NO_LIB) && !defined(BOOST_NOWIDE_SOURCE)
|
||||
//
|
||||
// Set the name of our library, this will get undef'ed by auto_link.hpp
|
||||
// once it's done with it:
|
||||
//
|
||||
#define BOOST_LIB_NAME boost_nowide
|
||||
//
|
||||
// If we're importing code from a dll, then tell auto_link.hpp about it:
|
||||
//
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_NOWIDE_DYN_LINK)
|
||||
#define BOOST_DYN_LINK
|
||||
#endif
|
||||
//
|
||||
// And include the header that does the work:
|
||||
//
|
||||
#include <boost/config/auto_link.hpp>
|
||||
#endif // auto-linking disabled
|
||||
|
||||
//! @endcond
|
||||
|
||||
/// @def BOOST_NOWIDE_USE_WCHAR_OVERLOADS
|
||||
/// @brief Whether to use the wchar_t* overloads in fstream/filebuf
|
||||
/// Enabled on Windows and Cygwin as the latter may use wchar_t in filesystem::path
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
#define BOOST_NOWIDE_USE_WCHAR_OVERLOADS 1
|
||||
#else
|
||||
#define BOOST_NOWIDE_USE_WCHAR_OVERLOADS 0
|
||||
#endif
|
||||
|
||||
/// @def BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
|
||||
/// @brief Define to 1 to use internal class from filebuf.hpp
|
||||
///
|
||||
/// - On Non-Windows platforms: Define to 1 to use the same class from header <filebuf.hpp>
|
||||
/// that is used on Windows.
|
||||
/// - On Windows: No effect, always overwritten to 1
|
||||
///
|
||||
/// Affects boost::nowide::basic_filebuf,
|
||||
/// boost::nowide::basic_ofstream, boost::nowide::basic_ifstream, boost::nowide::basic_fstream
|
||||
#if defined(BOOST_WINDOWS) || BOOST_NOWIDE_USE_WCHAR_OVERLOADS
|
||||
#ifdef BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
|
||||
#undef BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
|
||||
#endif
|
||||
#define BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT 1
|
||||
#elif !defined(BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT)
|
||||
#define BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT 0
|
||||
#endif
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
#if BOOST_VERSION < 106500 && defined(BOOST_GCC) && __GNUC__ >= 7
|
||||
#define BOOST_NOWIDE_FALLTHROUGH __attribute__((fallthrough))
|
||||
#else
|
||||
#define BOOST_NOWIDE_FALLTHROUGH BOOST_FALLTHROUGH
|
||||
#endif
|
||||
|
||||
//! @endcond
|
||||
|
||||
namespace boost {
|
||||
///
|
||||
/// \brief This namespace includes implementations of the standard library functions and
|
||||
/// classes such that they accept UTF-8 strings on Windows.
|
||||
/// On other platforms (i.e. not on Windows) those functions and classes are just aliases
|
||||
/// of the corresponding ones from the std namespace or behave like them.
|
||||
///
|
||||
namespace nowide {}
|
||||
} // namespace boost
|
||||
|
||||
#endif // boost/nowide/config.hpp
|
||||
129
install/boost_1_75_0/include/boost/nowide/convert.hpp
Normal file
129
install/boost_1_75_0/include/boost/nowide/convert.hpp
Normal file
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_CONVERT_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_CONVERT_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/utf/convert.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
|
||||
///
|
||||
/// Convert wide string (UTF-16/32) in range [begin,end) to NULL terminated narrow string (UTF-8)
|
||||
/// stored in \a output of size \a output_size (including NULL)
|
||||
///
|
||||
/// If there is not enough room NULL is returned, else output is returned.
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
inline char* narrow(char* output, size_t output_size, const wchar_t* begin, const wchar_t* end)
|
||||
{
|
||||
return utf::convert_buffer(output, output_size, begin, end);
|
||||
}
|
||||
///
|
||||
/// Convert NULL terminated wide string (UTF-16/32) to NULL terminated narrow string (UTF-8)
|
||||
/// stored in \a output of size \a output_size (including NULL)
|
||||
///
|
||||
/// If there is not enough room NULL is returned, else output is returned.
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
inline char* narrow(char* output, size_t output_size, const wchar_t* source)
|
||||
{
|
||||
return narrow(output, output_size, source, source + utf::strlen(source));
|
||||
}
|
||||
|
||||
///
|
||||
/// Convert narrow string (UTF-8) in range [begin,end) to NULL terminated wide string (UTF-16/32)
|
||||
/// stored in \a output of size \a output_size (including NULL)
|
||||
///
|
||||
/// If there is not enough room NULL is returned, else output is returned.
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
inline wchar_t* widen(wchar_t* output, size_t output_size, const char* begin, const char* end)
|
||||
{
|
||||
return utf::convert_buffer(output, output_size, begin, end);
|
||||
}
|
||||
///
|
||||
/// Convert NULL terminated narrow string (UTF-8) to NULL terminated wide string (UTF-16/32)
|
||||
/// most output_size (including NULL)
|
||||
///
|
||||
/// If there is not enough room NULL is returned, else output is returned.
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
inline wchar_t* widen(wchar_t* output, size_t output_size, const char* source)
|
||||
{
|
||||
return widen(output, output_size, source, source + utf::strlen(source));
|
||||
}
|
||||
|
||||
///
|
||||
/// Convert wide string (UTF-16/32) to narrow string (UTF-8).
|
||||
///
|
||||
/// \param s Input string
|
||||
/// \param count Number of characters to convert
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
inline std::string narrow(const wchar_t* s, size_t count)
|
||||
{
|
||||
return utf::convert_string<char>(s, s + count);
|
||||
}
|
||||
///
|
||||
/// Convert wide string (UTF-16/32) to narrow string (UTF-8).
|
||||
///
|
||||
/// \param s NULL terminated input string
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
inline std::string narrow(const wchar_t* s)
|
||||
{
|
||||
return narrow(s, utf::strlen(s));
|
||||
}
|
||||
///
|
||||
/// Convert wide string (UTF-16/32) to narrow string (UTF-8).
|
||||
///
|
||||
/// \param s Input string
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
inline std::string narrow(const std::wstring& s)
|
||||
{
|
||||
return narrow(s.c_str(), s.size());
|
||||
}
|
||||
|
||||
///
|
||||
/// Convert narrow string (UTF-8) to wide string (UTF-16/32).
|
||||
///
|
||||
/// \param s Input string
|
||||
/// \param count Number of characters to convert
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
inline std::wstring widen(const char* s, size_t count)
|
||||
{
|
||||
return utf::convert_string<wchar_t>(s, s + count);
|
||||
}
|
||||
///
|
||||
/// Convert narrow string (UTF-8) to wide string (UTF-16/32).
|
||||
///
|
||||
/// \param s NULL terminated input string
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
inline std::wstring widen(const char* s)
|
||||
{
|
||||
return widen(s, utf::strlen(s));
|
||||
}
|
||||
///
|
||||
/// Convert narrow string (UTF-8) to wide string (UTF-16/32).
|
||||
///
|
||||
/// \param s Input string
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
inline std::wstring widen(const std::string& s)
|
||||
{
|
||||
return widen(s.c_str(), s.size());
|
||||
}
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
47
install/boost_1_75_0/include/boost/nowide/cstdio.hpp
Normal file
47
install/boost_1_75_0/include/boost/nowide/cstdio.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_CSTDIO_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_CSTDIO_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/config.hpp>
|
||||
#include <cstdio>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
using std::fopen;
|
||||
using std::freopen;
|
||||
using std::remove;
|
||||
using std::rename;
|
||||
#else
|
||||
|
||||
///
|
||||
/// \brief Same as freopen but file_name and mode are UTF-8 strings
|
||||
///
|
||||
BOOST_NOWIDE_DECL FILE* freopen(const char* file_name, const char* mode, FILE* stream);
|
||||
///
|
||||
/// \brief Same as fopen but file_name and mode are UTF-8 strings
|
||||
///
|
||||
BOOST_NOWIDE_DECL FILE* fopen(const char* file_name, const char* mode);
|
||||
///
|
||||
/// \brief Same as rename but old_name and new_name are UTF-8 strings
|
||||
///
|
||||
BOOST_NOWIDE_DECL int rename(const char* old_name, const char* new_name);
|
||||
///
|
||||
/// \brief Same as rename but name is UTF-8 string
|
||||
///
|
||||
BOOST_NOWIDE_DECL int remove(const char* name);
|
||||
#endif
|
||||
namespace detail {
|
||||
BOOST_NOWIDE_DECL FILE* wfopen(const wchar_t* filename, const wchar_t* mode);
|
||||
}
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
67
install/boost_1_75_0/include/boost/nowide/cstdlib.hpp
Normal file
67
install/boost_1_75_0/include/boost/nowide/cstdlib.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_CSTDLIB_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_CSTDLIB_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/config.hpp>
|
||||
#if !defined(BOOST_WINDOWS)
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
using std::getenv;
|
||||
using std::system;
|
||||
#else
|
||||
///
|
||||
/// \brief UTF-8 aware getenv. Returns 0 if the variable is not set.
|
||||
///
|
||||
/// This function is not thread safe or reenterable as defined by the standard library
|
||||
///
|
||||
BOOST_NOWIDE_DECL char* getenv(const char* key);
|
||||
|
||||
///
|
||||
/// Same as std::system but cmd is UTF-8.
|
||||
///
|
||||
BOOST_NOWIDE_DECL int system(const char* cmd);
|
||||
|
||||
#endif
|
||||
///
|
||||
/// \brief Set environment variable \a key to \a value
|
||||
///
|
||||
/// if overwrite is not 0, that the old value is always overwritten, otherwise,
|
||||
/// if the variable exists it remains unchanged
|
||||
///
|
||||
/// \a key and \a value are UTF-8 on Windows
|
||||
/// \return zero on success, else nonzero
|
||||
///
|
||||
BOOST_NOWIDE_DECL int setenv(const char* key, const char* value, int overwrite);
|
||||
|
||||
///
|
||||
/// \brief Remove environment variable \a key
|
||||
///
|
||||
/// \a key is UTF-8 on Windows
|
||||
/// \return zero on success, else nonzero
|
||||
///
|
||||
BOOST_NOWIDE_DECL int unsetenv(const char* key);
|
||||
|
||||
///
|
||||
/// \brief Adds or changes an environment variable, \a string must be in format KEY=VALUE
|
||||
///
|
||||
/// \a string MAY become part of the environment, hence changes to the value MAY change
|
||||
/// the environment. For portability it is hence recommended NOT to change it.
|
||||
/// \a string is UTF-8 on Windows
|
||||
/// \return zero on success, else nonzero
|
||||
///
|
||||
BOOST_NOWIDE_DECL int putenv(char* string);
|
||||
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
25
install/boost_1_75_0/include/boost/nowide/detail/convert.hpp
Normal file
25
install/boost_1_75_0/include/boost/nowide/detail/convert.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// Copyright (c) 2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_DETAIL_CONVERT_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_DETAIL_CONVERT_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/utf/convert.hpp>
|
||||
|
||||
// Legacy compatibility header only. Include <boost/nowide/utf/convert.hpp> instead
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
namespace detail {
|
||||
using boost::nowide::utf::convert_buffer;
|
||||
using boost::nowide::utf::convert_string;
|
||||
using boost::nowide::utf::strlen;
|
||||
} // namespace detail
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
39
install/boost_1_75_0/include/boost/nowide/detail/is_path.hpp
Normal file
39
install/boost_1_75_0/include/boost/nowide/detail/is_path.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (c) 2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_DETAIL_IS_PATH_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_DETAIL_IS_PATH_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
namespace detail {
|
||||
|
||||
/// Trait to heuristically check for a *\::filesystem::path
|
||||
/// Done by checking for make_preferred and filename member functions with correct signature
|
||||
template<typename T>
|
||||
struct is_path
|
||||
{
|
||||
template<typename U, U& (U::*)(), U (U::*)() const>
|
||||
struct Check;
|
||||
template<typename U>
|
||||
static std::true_type test(Check<U, &U::make_preferred, &U::filename>*);
|
||||
template<typename U>
|
||||
static std::false_type test(...);
|
||||
|
||||
static constexpr bool value = decltype(test<T>(0))::value;
|
||||
};
|
||||
/// SFINAE trait which has a member "type = Result" if the Path is a *\::filesystem::path
|
||||
template<typename Path, typename Result>
|
||||
using enable_if_path_t = typename std::enable_if<is_path<Path>::value, Result>::type;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
23
install/boost_1_75_0/include/boost/nowide/detail/utf.hpp
Normal file
23
install/boost_1_75_0/include/boost/nowide/detail/utf.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright (c) 2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_DETAIL_UTF_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_DETAIL_UTF_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/utf/utf.hpp>
|
||||
|
||||
// Legacy compatibility header only. Include <boost/nowide/utf/utf.hpp> instead
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
namespace detail {
|
||||
namespace utf = boost::nowide::utf;
|
||||
} // namespace detail
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
471
install/boost_1_75_0/include/boost/nowide/filebuf.hpp
Normal file
471
install/boost_1_75_0/include/boost/nowide/filebuf.hpp
Normal file
@@ -0,0 +1,471 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2019-2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_FILEBUF_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_FILEBUF_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/config.hpp>
|
||||
#if BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <ios>
|
||||
#include <limits>
|
||||
#include <locale>
|
||||
#include <stdexcept>
|
||||
#include <streambuf>
|
||||
#else
|
||||
#include <fstream>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
namespace detail {
|
||||
/// Same as std::ftell but potentially with Large File Support
|
||||
BOOST_NOWIDE_DECL std::streampos ftell(FILE* file);
|
||||
/// Same as std::fseek but potentially with Large File Support
|
||||
BOOST_NOWIDE_DECL int fseek(FILE* file, std::streamoff offset, int origin);
|
||||
} // namespace detail
|
||||
|
||||
#if !BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
using std::basic_filebuf;
|
||||
using std::filebuf;
|
||||
#else // Windows
|
||||
///
|
||||
/// \brief This forward declaration defines the basic_filebuf type.
|
||||
///
|
||||
/// it is implemented and specialized for CharType = char, it
|
||||
/// implements std::filebuf over standard C I/O
|
||||
///
|
||||
template<typename CharType, typename Traits = std::char_traits<CharType>>
|
||||
class basic_filebuf;
|
||||
|
||||
///
|
||||
/// \brief This is the implementation of std::filebuf
|
||||
///
|
||||
/// it is implemented and specialized for CharType = char, it
|
||||
/// implements std::filebuf over standard C I/O
|
||||
///
|
||||
template<>
|
||||
class basic_filebuf<char> : public std::basic_streambuf<char>
|
||||
{
|
||||
using Traits = std::char_traits<char>;
|
||||
|
||||
public:
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4351) // new behavior : elements of array will be default initialized
|
||||
#endif
|
||||
///
|
||||
/// Creates new filebuf
|
||||
///
|
||||
basic_filebuf() :
|
||||
buffer_size_(BUFSIZ), buffer_(0), file_(0), owns_buffer_(false), last_char_(),
|
||||
mode_(std::ios_base::openmode(0))
|
||||
{
|
||||
setg(0, 0, 0);
|
||||
setp(0, 0);
|
||||
}
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
basic_filebuf(const basic_filebuf&) = delete;
|
||||
basic_filebuf& operator=(const basic_filebuf&) = delete;
|
||||
basic_filebuf(basic_filebuf&& other) noexcept : basic_filebuf()
|
||||
{
|
||||
swap(other);
|
||||
}
|
||||
basic_filebuf& operator=(basic_filebuf&& other) noexcept
|
||||
{
|
||||
swap(other);
|
||||
return *this;
|
||||
}
|
||||
void swap(basic_filebuf& rhs)
|
||||
{
|
||||
std::basic_streambuf<char>::swap(rhs);
|
||||
using std::swap;
|
||||
swap(buffer_size_, rhs.buffer_size_);
|
||||
swap(buffer_, rhs.buffer_);
|
||||
swap(file_, rhs.file_);
|
||||
swap(owns_buffer_, rhs.owns_buffer_);
|
||||
swap(last_char_[0], rhs.last_char_[0]);
|
||||
swap(mode_, rhs.mode_);
|
||||
// Fixup last_char references
|
||||
if(epptr() == rhs.last_char_)
|
||||
setp(last_char_, last_char_);
|
||||
if(egptr() == rhs.last_char_)
|
||||
rhs.setg(last_char_, gptr() == rhs.last_char_ ? last_char_ : last_char_ + 1, last_char_ + 1);
|
||||
if(rhs.epptr() == last_char_)
|
||||
setp(rhs.last_char_, rhs.last_char_);
|
||||
if(rhs.egptr() == rhs.last_char_)
|
||||
{
|
||||
rhs.setg(rhs.last_char_,
|
||||
rhs.gptr() == last_char_ ? rhs.last_char_ : rhs.last_char_ + 1,
|
||||
rhs.last_char_ + 1);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~basic_filebuf()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
///
|
||||
/// Same as std::filebuf::open but s is UTF-8 string
|
||||
///
|
||||
basic_filebuf* open(const std::string& s, std::ios_base::openmode mode)
|
||||
{
|
||||
return open(s.c_str(), mode);
|
||||
}
|
||||
///
|
||||
/// Same as std::filebuf::open but s is UTF-8 string
|
||||
///
|
||||
basic_filebuf* open(const char* s, std::ios_base::openmode mode)
|
||||
{
|
||||
const wstackstring name(s);
|
||||
return open(name.get(), mode);
|
||||
}
|
||||
/// Opens the file with the given name, see std::filebuf::open
|
||||
basic_filebuf* open(const wchar_t* s, std::ios_base::openmode mode)
|
||||
{
|
||||
if(is_open())
|
||||
return NULL;
|
||||
validate_cvt(this->getloc());
|
||||
const bool ate = (mode & std::ios_base::ate) != 0;
|
||||
if(ate)
|
||||
mode &= ~std::ios_base::ate;
|
||||
const wchar_t* smode = get_mode(mode);
|
||||
if(!smode)
|
||||
return 0;
|
||||
file_ = detail::wfopen(s, smode);
|
||||
if(!file_)
|
||||
return 0;
|
||||
if(ate && detail::fseek(file_, 0, SEEK_END) != 0)
|
||||
{
|
||||
close();
|
||||
return 0;
|
||||
}
|
||||
mode_ = mode;
|
||||
return this;
|
||||
}
|
||||
///
|
||||
/// Same as std::filebuf::close()
|
||||
///
|
||||
basic_filebuf* close()
|
||||
{
|
||||
if(!is_open())
|
||||
return NULL;
|
||||
bool res = sync() == 0;
|
||||
if(std::fclose(file_) != 0)
|
||||
res = false;
|
||||
file_ = NULL;
|
||||
mode_ = std::ios_base::openmode(0);
|
||||
if(owns_buffer_)
|
||||
{
|
||||
delete[] buffer_;
|
||||
buffer_ = NULL;
|
||||
owns_buffer_ = false;
|
||||
}
|
||||
return res ? this : NULL;
|
||||
}
|
||||
///
|
||||
/// Same as std::filebuf::is_open()
|
||||
///
|
||||
bool is_open() const
|
||||
{
|
||||
return file_ != NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
void make_buffer()
|
||||
{
|
||||
if(buffer_)
|
||||
return;
|
||||
if(buffer_size_ > 0)
|
||||
{
|
||||
buffer_ = new char[buffer_size_];
|
||||
owns_buffer_ = true;
|
||||
}
|
||||
}
|
||||
void validate_cvt(const std::locale& loc)
|
||||
{
|
||||
if(!std::use_facet<std::codecvt<char, char, std::mbstate_t>>(loc).always_noconv())
|
||||
throw std::runtime_error("Converting codecvts are not supported");
|
||||
}
|
||||
|
||||
protected:
|
||||
std::streambuf* setbuf(char* s, std::streamsize n) override
|
||||
{
|
||||
assert(n >= 0);
|
||||
// Maximum compatibility: Discard all local buffers and use user-provided values
|
||||
// Users should call sync() before or better use it before any IO is done or any file is opened
|
||||
setg(NULL, NULL, NULL);
|
||||
setp(NULL, NULL);
|
||||
if(owns_buffer_)
|
||||
delete[] buffer_;
|
||||
buffer_ = s;
|
||||
buffer_size_ = (n >= 0) ? static_cast<size_t>(n) : 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
int overflow(int c = EOF) override
|
||||
{
|
||||
if(!(mode_ & std::ios_base::out))
|
||||
return EOF;
|
||||
|
||||
if(!stop_reading())
|
||||
return EOF;
|
||||
|
||||
size_t n = pptr() - pbase();
|
||||
if(n > 0)
|
||||
{
|
||||
if(std::fwrite(pbase(), 1, n, file_) != n)
|
||||
return -1;
|
||||
setp(buffer_, buffer_ + buffer_size_);
|
||||
if(c != EOF)
|
||||
{
|
||||
*buffer_ = Traits::to_char_type(c);
|
||||
pbump(1);
|
||||
}
|
||||
} else if(c != EOF)
|
||||
{
|
||||
if(buffer_size_ > 0)
|
||||
{
|
||||
make_buffer();
|
||||
setp(buffer_, buffer_ + buffer_size_);
|
||||
*buffer_ = Traits::to_char_type(c);
|
||||
pbump(1);
|
||||
} else if(std::fputc(c, file_) == EOF)
|
||||
{
|
||||
return EOF;
|
||||
} else if(!pptr())
|
||||
{
|
||||
// Set to dummy value so we know we have written something
|
||||
setp(last_char_, last_char_);
|
||||
}
|
||||
}
|
||||
return Traits::not_eof(c);
|
||||
}
|
||||
|
||||
int sync() override
|
||||
{
|
||||
if(!file_)
|
||||
return 0;
|
||||
bool result;
|
||||
if(pptr())
|
||||
{
|
||||
result = overflow() != EOF;
|
||||
// Only flush if anything was written, otherwise behavior of fflush is undefined
|
||||
if(std::fflush(file_) != 0)
|
||||
return result = false;
|
||||
} else
|
||||
result = stop_reading();
|
||||
return result ? 0 : -1;
|
||||
}
|
||||
|
||||
int underflow() override
|
||||
{
|
||||
if(!(mode_ & std::ios_base::in))
|
||||
return EOF;
|
||||
if(!stop_writing())
|
||||
return EOF;
|
||||
if(buffer_size_ == 0)
|
||||
{
|
||||
const int c = std::fgetc(file_);
|
||||
if(c == EOF)
|
||||
return EOF;
|
||||
last_char_[0] = Traits::to_char_type(c);
|
||||
setg(last_char_, last_char_, last_char_ + 1);
|
||||
} else
|
||||
{
|
||||
make_buffer();
|
||||
const size_t n = std::fread(buffer_, 1, buffer_size_, file_);
|
||||
setg(buffer_, buffer_, buffer_ + n);
|
||||
if(n == 0)
|
||||
return EOF;
|
||||
}
|
||||
return Traits::to_int_type(*gptr());
|
||||
}
|
||||
|
||||
int pbackfail(int c = EOF) override
|
||||
{
|
||||
if(!(mode_ & std::ios_base::in))
|
||||
return EOF;
|
||||
if(!stop_writing())
|
||||
return EOF;
|
||||
if(gptr() > eback())
|
||||
gbump(-1);
|
||||
else if(seekoff(-1, std::ios_base::cur) != std::streampos(std::streamoff(-1)))
|
||||
{
|
||||
if(underflow() == EOF)
|
||||
return EOF;
|
||||
} else
|
||||
return EOF;
|
||||
|
||||
// Case 1: Caller just wanted space for 1 char
|
||||
if(c == EOF)
|
||||
return Traits::not_eof(c);
|
||||
// Case 2: Caller wants to put back different char
|
||||
// gptr now points to the (potentially newly read) previous char
|
||||
if(*gptr() != c)
|
||||
*gptr() = Traits::to_char_type(c);
|
||||
return Traits::not_eof(c);
|
||||
}
|
||||
|
||||
std::streampos seekoff(std::streamoff off,
|
||||
std::ios_base::seekdir seekdir,
|
||||
std::ios_base::openmode = std::ios_base::in | std::ios_base::out) override
|
||||
{
|
||||
if(!file_)
|
||||
return EOF;
|
||||
// Switching between input<->output requires a seek
|
||||
// So do NOT optimize for seekoff(0, cur) as No-OP
|
||||
|
||||
// On some implementations a seek also flushes, so do a full sync
|
||||
if(sync() != 0)
|
||||
return EOF;
|
||||
int whence;
|
||||
switch(seekdir)
|
||||
{
|
||||
case std::ios_base::beg: whence = SEEK_SET; break;
|
||||
case std::ios_base::cur: whence = SEEK_CUR; break;
|
||||
case std::ios_base::end: whence = SEEK_END; break;
|
||||
default: assert(false); return EOF;
|
||||
}
|
||||
if(detail::fseek(file_, off, whence) != 0)
|
||||
return EOF;
|
||||
return detail::ftell(file_);
|
||||
}
|
||||
std::streampos seekpos(std::streampos pos,
|
||||
std::ios_base::openmode m = std::ios_base::in | std::ios_base::out) override
|
||||
{
|
||||
// Standard mandates "as-if fsetpos", but assume the effect is the same as fseek
|
||||
return seekoff(pos, std::ios_base::beg, m);
|
||||
}
|
||||
void imbue(const std::locale& loc) override
|
||||
{
|
||||
validate_cvt(loc);
|
||||
}
|
||||
|
||||
private:
|
||||
/// Stop reading adjusting the file pointer if necessary
|
||||
/// Postcondition: gptr() == NULL
|
||||
bool stop_reading()
|
||||
{
|
||||
if(!gptr())
|
||||
return true;
|
||||
const auto off = gptr() - egptr();
|
||||
setg(0, 0, 0);
|
||||
if(!off)
|
||||
return true;
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
|
||||
#endif
|
||||
// coverity[result_independent_of_operands]
|
||||
if(off > std::numeric_limits<std::streamoff>::max())
|
||||
return false;
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
return detail::fseek(file_, static_cast<std::streamoff>(off), SEEK_CUR) == 0;
|
||||
}
|
||||
|
||||
/// Stop writing. If any bytes are to be written, writes them to file
|
||||
/// Postcondition: pptr() == NULL
|
||||
bool stop_writing()
|
||||
{
|
||||
if(pptr())
|
||||
{
|
||||
const char* const base = pbase();
|
||||
const size_t n = pptr() - base;
|
||||
setp(0, 0);
|
||||
if(n && std::fwrite(base, 1, n, file_) != n)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void reset(FILE* f = 0)
|
||||
{
|
||||
sync();
|
||||
if(file_)
|
||||
{
|
||||
fclose(file_);
|
||||
file_ = 0;
|
||||
}
|
||||
file_ = f;
|
||||
}
|
||||
|
||||
static const wchar_t* get_mode(std::ios_base::openmode mode)
|
||||
{
|
||||
//
|
||||
// done according to n2914 table 106 27.9.1.4
|
||||
//
|
||||
|
||||
// note can't use switch case as overload operator can't be used
|
||||
// in constant expression
|
||||
if(mode == (std::ios_base::out))
|
||||
return L"w";
|
||||
if(mode == (std::ios_base::out | std::ios_base::app))
|
||||
return L"a";
|
||||
if(mode == (std::ios_base::app))
|
||||
return L"a";
|
||||
if(mode == (std::ios_base::out | std::ios_base::trunc))
|
||||
return L"w";
|
||||
if(mode == (std::ios_base::in))
|
||||
return L"r";
|
||||
if(mode == (std::ios_base::in | std::ios_base::out))
|
||||
return L"r+";
|
||||
if(mode == (std::ios_base::in | std::ios_base::out | std::ios_base::trunc))
|
||||
return L"w+";
|
||||
if(mode == (std::ios_base::in | std::ios_base::out | std::ios_base::app))
|
||||
return L"a+";
|
||||
if(mode == (std::ios_base::in | std::ios_base::app))
|
||||
return L"a+";
|
||||
if(mode == (std::ios_base::binary | std::ios_base::out))
|
||||
return L"wb";
|
||||
if(mode == (std::ios_base::binary | std::ios_base::out | std::ios_base::app))
|
||||
return L"ab";
|
||||
if(mode == (std::ios_base::binary | std::ios_base::app))
|
||||
return L"ab";
|
||||
if(mode == (std::ios_base::binary | std::ios_base::out | std::ios_base::trunc))
|
||||
return L"wb";
|
||||
if(mode == (std::ios_base::binary | std::ios_base::in))
|
||||
return L"rb";
|
||||
if(mode == (std::ios_base::binary | std::ios_base::in | std::ios_base::out))
|
||||
return L"r+b";
|
||||
if(mode == (std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::trunc))
|
||||
return L"w+b";
|
||||
if(mode == (std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::app))
|
||||
return L"a+b";
|
||||
if(mode == (std::ios_base::binary | std::ios_base::in | std::ios_base::app))
|
||||
return L"a+b";
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t buffer_size_;
|
||||
char* buffer_;
|
||||
FILE* file_;
|
||||
bool owns_buffer_;
|
||||
char last_char_[1];
|
||||
std::ios::openmode mode_;
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Convenience typedef
|
||||
///
|
||||
using filebuf = basic_filebuf<char>;
|
||||
|
||||
#endif // windows
|
||||
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
27
install/boost_1_75_0/include/boost/nowide/filesystem.hpp
Normal file
27
install/boost_1_75_0/include/boost/nowide/filesystem.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_INTEGRATION_FILESYSTEM_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_INTEGRATION_FILESYSTEM_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/utf8_codecvt.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
///
|
||||
/// Install utf8_codecvt facet into boost::filesystem::path such all char strings are interpreted as utf-8 strings
|
||||
///
|
||||
inline std::locale nowide_filesystem()
|
||||
{
|
||||
std::locale tmp = std::locale(std::locale(), new boost::nowide::utf8_codecvt<wchar_t>());
|
||||
return boost::filesystem::path::imbue(tmp);
|
||||
}
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
362
install/boost_1_75_0/include/boost/nowide/fstream.hpp
Normal file
362
install/boost_1_75_0/include/boost/nowide/fstream.hpp
Normal file
@@ -0,0 +1,362 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_FSTREAM_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_FSTREAM_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/config.hpp>
|
||||
#include <boost/nowide/detail/is_path.hpp>
|
||||
#include <boost/nowide/filebuf.hpp>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
/// \cond INTERNAL
|
||||
namespace detail {
|
||||
// clang-format off
|
||||
struct StreamTypeIn
|
||||
{
|
||||
static std::ios_base::openmode mode() { return std::ios_base::in; }
|
||||
static std::ios_base::openmode mode_modifier() { return mode(); }
|
||||
template<typename CharType, typename Traits>
|
||||
struct stream_base{
|
||||
using type = std::basic_istream<CharType, Traits>;
|
||||
};
|
||||
};
|
||||
struct StreamTypeOut
|
||||
{
|
||||
static std::ios_base::openmode mode() { return std::ios_base::out; }
|
||||
static std::ios_base::openmode mode_modifier() { return mode(); }
|
||||
template<typename CharType, typename Traits>
|
||||
struct stream_base{
|
||||
using type = std::basic_ostream<CharType, Traits>;
|
||||
};
|
||||
};
|
||||
struct StreamTypeInOut
|
||||
{
|
||||
static std::ios_base::openmode mode() { return std::ios_base::in | std::ios_base::out; }
|
||||
static std::ios_base::openmode mode_modifier() { return std::ios_base::openmode(); }
|
||||
template<typename CharType, typename Traits>
|
||||
struct stream_base{
|
||||
using type = std::basic_iostream<CharType, Traits>;
|
||||
};
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
/// Base class for all basic_*fstream classes
|
||||
/// Contains basic_filebuf instance so its pointer can be used to construct basic_*stream
|
||||
/// Provides common functions to reduce boilerplate code including inheriting from
|
||||
/// the correct std::basic_[io]stream class and initializing it
|
||||
/// \tparam T_StreamType One of StreamType* above.
|
||||
/// Class used instead of value, because openmode::operator| may not be constexpr
|
||||
/// \tparam FileBufType Discriminator to force a differing ABI if depending on the contained filebuf
|
||||
template<typename CharType,
|
||||
typename Traits,
|
||||
typename T_StreamType,
|
||||
int FileBufType = BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT>
|
||||
class fstream_impl;
|
||||
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
///
|
||||
/// \brief Same as std::basic_ifstream<char> but accepts UTF-8 strings under Windows
|
||||
///
|
||||
template<typename CharType, typename Traits = std::char_traits<CharType>>
|
||||
class basic_ifstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeIn>
|
||||
{
|
||||
using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeIn>;
|
||||
|
||||
public:
|
||||
basic_ifstream()
|
||||
{}
|
||||
|
||||
explicit basic_ifstream(const char* file_name, std::ios_base::openmode mode = std::ios_base::in)
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
#if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
|
||||
explicit basic_ifstream(const wchar_t* file_name, std::ios_base::openmode mode = std::ios_base::in)
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
explicit basic_ifstream(const std::string& file_name, std::ios_base::openmode mode = std::ios_base::in)
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
|
||||
template<typename Path>
|
||||
explicit basic_ifstream(const Path& file_name,
|
||||
detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::in)
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
using fstream_impl::open;
|
||||
using fstream_impl::is_open;
|
||||
using fstream_impl::close;
|
||||
using fstream_impl::rdbuf;
|
||||
using fstream_impl::swap;
|
||||
basic_ifstream(const basic_ifstream&) = delete;
|
||||
basic_ifstream& operator=(const basic_ifstream&) = delete;
|
||||
basic_ifstream(basic_ifstream&& other) noexcept : fstream_impl(std::move(other))
|
||||
{}
|
||||
basic_ifstream& operator=(basic_ifstream&& rhs) noexcept
|
||||
{
|
||||
fstream_impl::operator=(std::move(rhs));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Same as std::basic_ofstream<char> but accepts UTF-8 strings under Windows
|
||||
///
|
||||
|
||||
template<typename CharType, typename Traits = std::char_traits<CharType>>
|
||||
class basic_ofstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeOut>
|
||||
{
|
||||
using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeOut>;
|
||||
|
||||
public:
|
||||
basic_ofstream()
|
||||
{}
|
||||
explicit basic_ofstream(const char* file_name, std::ios_base::openmode mode = std::ios_base::out)
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
#if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
|
||||
explicit basic_ofstream(const wchar_t* file_name, std::ios_base::openmode mode = std::ios_base::out)
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
#endif
|
||||
explicit basic_ofstream(const std::string& file_name, std::ios_base::openmode mode = std::ios_base::out)
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
template<typename Path>
|
||||
explicit basic_ofstream(const Path& file_name,
|
||||
detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::out)
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
|
||||
using fstream_impl::open;
|
||||
using fstream_impl::is_open;
|
||||
using fstream_impl::close;
|
||||
using fstream_impl::rdbuf;
|
||||
using fstream_impl::swap;
|
||||
basic_ofstream(const basic_ofstream&) = delete;
|
||||
basic_ofstream& operator=(const basic_ofstream&) = delete;
|
||||
basic_ofstream(basic_ofstream&& other) noexcept : fstream_impl(std::move(other))
|
||||
{}
|
||||
basic_ofstream& operator=(basic_ofstream&& rhs)
|
||||
{
|
||||
fstream_impl::operator=(std::move(rhs));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4250) // <class> : inherits <method> via dominance
|
||||
#endif
|
||||
///
|
||||
/// \brief Same as std::basic_fstream<char> but accepts UTF-8 strings under Windows
|
||||
///
|
||||
template<typename CharType, typename Traits = std::char_traits<CharType>>
|
||||
class basic_fstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut>
|
||||
{
|
||||
using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut>;
|
||||
|
||||
public:
|
||||
basic_fstream()
|
||||
{}
|
||||
explicit basic_fstream(const char* file_name,
|
||||
std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
#if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
|
||||
explicit basic_fstream(const wchar_t* file_name,
|
||||
std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
#endif
|
||||
explicit basic_fstream(const std::string& file_name,
|
||||
std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
template<typename Path>
|
||||
explicit basic_fstream(const Path& file_name,
|
||||
detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::in
|
||||
| std::ios_base::out)
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
|
||||
using fstream_impl::open;
|
||||
using fstream_impl::is_open;
|
||||
using fstream_impl::close;
|
||||
using fstream_impl::rdbuf;
|
||||
using fstream_impl::swap;
|
||||
basic_fstream(const basic_fstream&) = delete;
|
||||
basic_fstream& operator=(const basic_fstream&) = delete;
|
||||
basic_fstream(basic_fstream&& other) noexcept : fstream_impl(std::move(other))
|
||||
{}
|
||||
basic_fstream& operator=(basic_fstream&& rhs)
|
||||
{
|
||||
fstream_impl::operator=(std::move(rhs));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
template<typename CharType, typename Traits>
|
||||
void swap(basic_filebuf<CharType, Traits>& lhs, basic_filebuf<CharType, Traits>& rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
template<typename CharType, typename Traits>
|
||||
void swap(basic_ifstream<CharType, Traits>& lhs, basic_ifstream<CharType, Traits>& rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
template<typename CharType, typename Traits>
|
||||
void swap(basic_ofstream<CharType, Traits>& lhs, basic_ofstream<CharType, Traits>& rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
template<typename CharType, typename Traits>
|
||||
void swap(basic_fstream<CharType, Traits>& lhs, basic_fstream<CharType, Traits>& rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
///
|
||||
/// Same as std::filebuf but accepts UTF-8 strings under Windows
|
||||
///
|
||||
using filebuf = basic_filebuf<char>;
|
||||
///
|
||||
/// Same as std::ifstream but accepts UTF-8 strings under Windows
|
||||
/// and *\::filesystem::path on all systems
|
||||
///
|
||||
using ifstream = basic_ifstream<char>;
|
||||
///
|
||||
/// Same as std::ofstream but accepts UTF-8 strings under Windows
|
||||
/// and *\::filesystem::path on all systems
|
||||
///
|
||||
using ofstream = basic_ofstream<char>;
|
||||
///
|
||||
/// Same as std::fstream but accepts UTF-8 strings under Windows
|
||||
/// and *\::filesystem::path on all systems
|
||||
///
|
||||
using fstream = basic_fstream<char>;
|
||||
|
||||
// Implementation
|
||||
namespace detail {
|
||||
/// Holds an instance of T
|
||||
/// Required to make sure this is constructed first before passing it to sibling classes
|
||||
template<typename T>
|
||||
struct buf_holder
|
||||
{
|
||||
T buf_;
|
||||
};
|
||||
template<typename CharType, typename Traits, typename T_StreamType, int>
|
||||
class fstream_impl : private buf_holder<basic_filebuf<CharType, Traits>>, // must be first due to init order
|
||||
public T_StreamType::template stream_base<CharType, Traits>::type
|
||||
{
|
||||
using internal_buffer_type = basic_filebuf<CharType, Traits>;
|
||||
using base_buf_holder = buf_holder<internal_buffer_type>;
|
||||
using stream_base = typename T_StreamType::template stream_base<CharType, Traits>::type;
|
||||
|
||||
public:
|
||||
using stream_base::setstate;
|
||||
using stream_base::clear;
|
||||
|
||||
protected:
|
||||
using base_buf_holder::buf_;
|
||||
|
||||
fstream_impl() : stream_base(&buf_)
|
||||
{}
|
||||
fstream_impl(const fstream_impl&) = delete;
|
||||
fstream_impl& operator=(const fstream_impl&) = delete;
|
||||
|
||||
// coverity[exn_spec_violation]
|
||||
fstream_impl(fstream_impl&& other) noexcept :
|
||||
base_buf_holder(std::move(other)), stream_base(std::move(other))
|
||||
{
|
||||
this->set_rdbuf(rdbuf());
|
||||
}
|
||||
fstream_impl& operator=(fstream_impl&& rhs) noexcept
|
||||
{
|
||||
base_buf_holder::operator=(std::move(rhs));
|
||||
stream_base::operator=(std::move(rhs));
|
||||
return *this;
|
||||
}
|
||||
void swap(fstream_impl& other)
|
||||
{
|
||||
stream_base::swap(other);
|
||||
rdbuf()->swap(*other.rdbuf());
|
||||
}
|
||||
|
||||
void open(const std::string& file_name, std::ios_base::openmode mode = T_StreamType::mode())
|
||||
{
|
||||
open(file_name.c_str(), mode);
|
||||
}
|
||||
template<typename Path>
|
||||
detail::enable_if_path_t<Path, void> open(const Path& file_name,
|
||||
std::ios_base::openmode mode = T_StreamType::mode())
|
||||
{
|
||||
open(file_name.c_str(), mode);
|
||||
}
|
||||
void open(const char* file_name, std::ios_base::openmode mode = T_StreamType::mode())
|
||||
{
|
||||
if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
|
||||
setstate(std::ios_base::failbit);
|
||||
else
|
||||
clear();
|
||||
}
|
||||
#if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
|
||||
void open(const wchar_t* file_name, std::ios_base::openmode mode = T_StreamType::mode())
|
||||
{
|
||||
if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
|
||||
setstate(std::ios_base::failbit);
|
||||
else
|
||||
clear();
|
||||
}
|
||||
#endif
|
||||
bool is_open()
|
||||
{
|
||||
return rdbuf()->is_open();
|
||||
}
|
||||
bool is_open() const
|
||||
{
|
||||
return rdbuf()->is_open();
|
||||
}
|
||||
void close()
|
||||
{
|
||||
if(!rdbuf()->close())
|
||||
setstate(std::ios_base::failbit);
|
||||
}
|
||||
|
||||
internal_buffer_type* rdbuf() const
|
||||
{
|
||||
return const_cast<internal_buffer_type*>(&buf_);
|
||||
}
|
||||
};
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
} // namespace detail
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
103
install/boost_1_75_0/include/boost/nowide/iostream.hpp
Normal file
103
install/boost_1_75_0/include/boost/nowide/iostream.hpp
Normal file
@@ -0,0 +1,103 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_IOSTREAM_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_IOSTREAM_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/config.hpp>
|
||||
#ifdef BOOST_WINDOWS
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp> // must be the last #include
|
||||
#else
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4251)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::cin;
|
||||
using std::clog;
|
||||
#else
|
||||
|
||||
/// \cond INTERNAL
|
||||
namespace detail {
|
||||
class console_output_buffer;
|
||||
class console_input_buffer;
|
||||
|
||||
class BOOST_NOWIDE_DECL winconsole_ostream : public std::ostream
|
||||
{
|
||||
public:
|
||||
winconsole_ostream(int fd, winconsole_ostream* tieStream);
|
||||
~winconsole_ostream();
|
||||
|
||||
private:
|
||||
std::unique_ptr<console_output_buffer> d;
|
||||
};
|
||||
|
||||
class BOOST_NOWIDE_DECL winconsole_istream : public std::istream
|
||||
{
|
||||
public:
|
||||
explicit winconsole_istream(winconsole_ostream* tieStream);
|
||||
~winconsole_istream();
|
||||
|
||||
private:
|
||||
std::unique_ptr<console_input_buffer> d;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/// \endcond
|
||||
|
||||
///
|
||||
/// \brief Same as std::cin, but uses UTF-8
|
||||
///
|
||||
/// Note, the stream is not synchronized with stdio and not affected by std::ios::sync_with_stdio
|
||||
///
|
||||
extern BOOST_NOWIDE_DECL detail::winconsole_istream cin;
|
||||
///
|
||||
/// \brief Same as std::cout, but uses UTF-8
|
||||
///
|
||||
/// Note, the stream is not synchronized with stdio and not affected by std::ios::sync_with_stdio
|
||||
///
|
||||
extern BOOST_NOWIDE_DECL detail::winconsole_ostream cout;
|
||||
///
|
||||
/// \brief Same as std::cerr, but uses UTF-8
|
||||
///
|
||||
/// Note, the stream is not synchronized with stdio and not affected by std::ios::sync_with_stdio
|
||||
///
|
||||
extern BOOST_NOWIDE_DECL detail::winconsole_ostream cerr;
|
||||
///
|
||||
/// \brief Same as std::clog, but uses UTF-8
|
||||
///
|
||||
/// Note, the stream is not synchronized with stdio and not affected by std::ios::sync_with_stdio
|
||||
///
|
||||
extern BOOST_NOWIDE_DECL detail::winconsole_ostream clog;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_WINDOWS
|
||||
#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
|
||||
#endif
|
||||
|
||||
#endif
|
||||
19
install/boost_1_75_0/include/boost/nowide/replacement.hpp
Normal file
19
install/boost_1_75_0/include/boost/nowide/replacement.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright (c) 2018 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_REPLACEMENT_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_REPLACEMENT_HPP_INCLUDED
|
||||
|
||||
/// @file
|
||||
|
||||
/// \def BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
/// Unicode character to be used to replace invalid UTF-8 sequences
|
||||
#ifndef BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
#define BOOST_NOWIDE_REPLACEMENT_CHARACTER 0xFFFD
|
||||
#endif
|
||||
|
||||
#endif // boost/nowide/replacement.hpp
|
||||
212
install/boost_1_75_0/include/boost/nowide/stackstring.hpp
Normal file
212
install/boost_1_75_0/include/boost/nowide/stackstring.hpp
Normal file
@@ -0,0 +1,212 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_STACKSTRING_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_STACKSTRING_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <boost/nowide/utf/utf.hpp>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
|
||||
///
|
||||
/// \brief A class that allows to create a temporary wide or narrow UTF strings from
|
||||
/// wide or narrow UTF source.
|
||||
///
|
||||
/// It uses a stack buffer if the string is short enough
|
||||
/// otherwise allocates a buffer on the heap.
|
||||
///
|
||||
/// Invalid UTF characters are replaced by the substitution character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
/// If a NULL pointer is passed to the constructor or convert method, NULL will be returned by c_str.
|
||||
/// Similarily a default constructed stackstring will return NULL on calling c_str.
|
||||
///
|
||||
template<typename CharOut = wchar_t, typename CharIn = char, size_t BufferSize = 256>
|
||||
class basic_stackstring
|
||||
{
|
||||
public:
|
||||
/// Size of the stack buffer
|
||||
static const size_t buffer_size = BufferSize;
|
||||
/// Type of the output character (converted to)
|
||||
using output_char = CharOut;
|
||||
/// Type of the input character (converted from)
|
||||
using input_char = CharIn;
|
||||
|
||||
/// Creates a NULL stackstring
|
||||
basic_stackstring() : data_(NULL)
|
||||
{
|
||||
buffer_[0] = 0;
|
||||
}
|
||||
/// Convert the NULL terminated string input and store in internal buffer
|
||||
/// If input is NULL, nothing will be stored
|
||||
explicit basic_stackstring(const input_char* input) : data_(NULL)
|
||||
{
|
||||
convert(input);
|
||||
}
|
||||
/// Convert the sequence [begin, end) and store in internal buffer
|
||||
/// If begin is NULL, nothing will be stored
|
||||
basic_stackstring(const input_char* begin, const input_char* end) : data_(NULL)
|
||||
{
|
||||
convert(begin, end);
|
||||
}
|
||||
/// Copy construct from other
|
||||
basic_stackstring(const basic_stackstring& other) : data_(NULL)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
/// Copy assign from other
|
||||
basic_stackstring& operator=(const basic_stackstring& other)
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
clear();
|
||||
const size_t len = other.length();
|
||||
if(other.uses_stack_memory())
|
||||
data_ = buffer_;
|
||||
else if(other.data_)
|
||||
data_ = new output_char[len + 1];
|
||||
else
|
||||
{
|
||||
data_ = NULL;
|
||||
return *this;
|
||||
}
|
||||
std::memcpy(data_, other.data_, sizeof(output_char) * (len + 1));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~basic_stackstring()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
/// Convert the NULL terminated string input and store in internal buffer
|
||||
/// If input is NULL, the current buffer will be reset to NULL
|
||||
output_char* convert(const input_char* input)
|
||||
{
|
||||
if(input)
|
||||
return convert(input, input + utf::strlen(input));
|
||||
clear();
|
||||
return get();
|
||||
}
|
||||
/// Convert the sequence [begin, end) and store in internal buffer
|
||||
/// If begin is NULL, the current buffer will be reset to NULL
|
||||
output_char* convert(const input_char* begin, const input_char* end)
|
||||
{
|
||||
clear();
|
||||
|
||||
if(begin)
|
||||
{
|
||||
const size_t input_len = end - begin;
|
||||
// Minimum size required: 1 output char per input char + trailing NULL
|
||||
const size_t min_output_size = input_len + 1;
|
||||
// If there is a chance the converted string fits on stack, try it
|
||||
if(min_output_size <= buffer_size && utf::convert_buffer(buffer_, buffer_size, begin, end))
|
||||
data_ = buffer_;
|
||||
else
|
||||
{
|
||||
// Fallback: Allocate a buffer that is surely large enough on heap
|
||||
// Max size: Every input char is transcoded to the output char with maximum with + trailing NULL
|
||||
const size_t max_output_size = input_len * utf::utf_traits<output_char>::max_width + 1;
|
||||
data_ = new output_char[max_output_size];
|
||||
const bool success = utf::convert_buffer(data_, max_output_size, begin, end) == data_;
|
||||
assert(success);
|
||||
(void)success;
|
||||
}
|
||||
}
|
||||
return get();
|
||||
}
|
||||
/// Return the converted, NULL-terminated string or NULL if no string was converted
|
||||
output_char* get()
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
/// Return the converted, NULL-terminated string or NULL if no string was converted
|
||||
const output_char* get() const
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
/// Reset the internal buffer to NULL
|
||||
void clear()
|
||||
{
|
||||
if(!uses_stack_memory())
|
||||
delete[] data_;
|
||||
data_ = NULL;
|
||||
}
|
||||
/// Swap lhs with rhs
|
||||
friend void swap(basic_stackstring& lhs, basic_stackstring& rhs)
|
||||
{
|
||||
if(lhs.uses_stack_memory())
|
||||
{
|
||||
if(rhs.uses_stack_memory())
|
||||
{
|
||||
for(size_t i = 0; i < buffer_size; i++)
|
||||
std::swap(lhs.buffer_[i], rhs.buffer_[i]);
|
||||
} else
|
||||
{
|
||||
lhs.data_ = rhs.data_;
|
||||
rhs.data_ = rhs.buffer_;
|
||||
for(size_t i = 0; i < buffer_size; i++)
|
||||
rhs.buffer_[i] = lhs.buffer_[i];
|
||||
}
|
||||
} else if(rhs.uses_stack_memory())
|
||||
{
|
||||
rhs.data_ = lhs.data_;
|
||||
lhs.data_ = lhs.buffer_;
|
||||
for(size_t i = 0; i < buffer_size; i++)
|
||||
lhs.buffer_[i] = rhs.buffer_[i];
|
||||
} else
|
||||
std::swap(lhs.data_, rhs.data_);
|
||||
}
|
||||
|
||||
protected:
|
||||
/// True if the stack memory is used
|
||||
bool uses_stack_memory() const
|
||||
{
|
||||
return data_ == buffer_;
|
||||
}
|
||||
/// Return the current length of the string excluding the NULL terminator
|
||||
/// If NULL is stored returns NULL
|
||||
size_t length() const
|
||||
{
|
||||
if(!data_)
|
||||
return 0;
|
||||
size_t len = 0;
|
||||
while(data_[len])
|
||||
len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
private:
|
||||
output_char buffer_[buffer_size];
|
||||
output_char* data_;
|
||||
}; // basic_stackstring
|
||||
|
||||
///
|
||||
/// Convenience typedef
|
||||
///
|
||||
using wstackstring = basic_stackstring<wchar_t, char, 256>;
|
||||
///
|
||||
/// Convenience typedef
|
||||
///
|
||||
using stackstring = basic_stackstring<char, wchar_t, 256>;
|
||||
///
|
||||
/// Convenience typedef
|
||||
///
|
||||
using wshort_stackstring = basic_stackstring<wchar_t, char, 16>;
|
||||
///
|
||||
/// Convenience typedef
|
||||
///
|
||||
using short_stackstring = basic_stackstring<char, wchar_t, 16>;
|
||||
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
65
install/boost_1_75_0/include/boost/nowide/stat.hpp
Normal file
65
install/boost_1_75_0/include/boost/nowide/stat.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// Copyright (c) 2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_STAT_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_STAT_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/config.hpp>
|
||||
#include <sys/types.h>
|
||||
// Include after sys/types.h
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(__MINGW32__) && defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x0601
|
||||
/// Forward declaration in case MinGW32 is used and __MSVCRT_VERSION__ is defined lower than 6.1
|
||||
struct __stat64;
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
// Note: `using x = struct ::stat` causes a bogus warning in GCC < 11
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66159
|
||||
|
||||
typedef struct ::stat stat_t;
|
||||
typedef struct ::stat posix_stat_t;
|
||||
|
||||
using ::stat;
|
||||
#else
|
||||
/// \brief Typedef for the file info structure.
|
||||
/// Able to hold 64 bit filesize and timestamps on Windows and usually also on other 64 Bit systems
|
||||
/// This allows to write portable code with option LFS support
|
||||
typedef struct ::__stat64 stat_t;
|
||||
/// \brief Typedef for the file info structure used in the POSIX stat call
|
||||
/// Resolves to `struct _stat` on Windows and `struct stat` otherwise
|
||||
/// This allows to write portable code using the default stat function
|
||||
typedef struct ::_stat posix_stat_t;
|
||||
|
||||
/// \cond INTERNAL
|
||||
namespace detail {
|
||||
BOOST_NOWIDE_DECL int stat(const char* path, posix_stat_t* buffer, size_t buffer_size);
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
///
|
||||
/// \brief UTF-8 aware stat function, returns 0 on success
|
||||
///
|
||||
/// Return information about a file from an UTF-8 encoded path
|
||||
///
|
||||
BOOST_NOWIDE_DECL int stat(const char* path, stat_t* buffer);
|
||||
///
|
||||
/// \brief UTF-8 aware stat function, returns 0 on success
|
||||
///
|
||||
/// Return information about a file from an UTF-8 encoded path
|
||||
///
|
||||
inline int stat(const char* path, posix_stat_t* buffer)
|
||||
{
|
||||
return detail::stat(path, buffer, sizeof(*buffer));
|
||||
}
|
||||
#endif
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
98
install/boost_1_75_0/include/boost/nowide/utf/convert.hpp
Normal file
98
install/boost_1_75_0/include/boost/nowide/utf/convert.hpp
Normal file
@@ -0,0 +1,98 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_UTF_CONVERT_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_UTF_CONVERT_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/replacement.hpp>
|
||||
#include <boost/nowide/utf/utf.hpp>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
namespace utf {
|
||||
///
|
||||
/// Convert a buffer of UTF sequences in the range [source_begin, source_end)
|
||||
/// from \tparam CharIn to \tparam CharOut to the output \a buffer of size \a buffer_size.
|
||||
///
|
||||
/// \return original buffer containing the NULL terminated string or NULL
|
||||
///
|
||||
/// If there is not enough room in the buffer NULL is returned, and the content of the buffer is undefined.
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
template<typename CharOut, typename CharIn>
|
||||
CharOut*
|
||||
convert_buffer(CharOut* buffer, size_t buffer_size, const CharIn* source_begin, const CharIn* source_end)
|
||||
{
|
||||
CharOut* rv = buffer;
|
||||
if(buffer_size == 0)
|
||||
return 0;
|
||||
buffer_size--;
|
||||
while(source_begin != source_end)
|
||||
{
|
||||
code_point c = utf_traits<CharIn>::decode(source_begin, source_end);
|
||||
if(c == illegal || c == incomplete)
|
||||
{
|
||||
c = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
size_t width = utf_traits<CharOut>::width(c);
|
||||
if(buffer_size < width)
|
||||
{
|
||||
rv = NULL;
|
||||
break;
|
||||
}
|
||||
buffer = utf_traits<CharOut>::encode(c, buffer);
|
||||
buffer_size -= width;
|
||||
}
|
||||
*buffer++ = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
///
|
||||
/// Convert the UTF sequences in range [begin, end) from \tparam CharIn to \tparam CharOut
|
||||
/// and return it as a string
|
||||
///
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
template<typename CharOut, typename CharIn>
|
||||
std::basic_string<CharOut> convert_string(const CharIn* begin, const CharIn* end)
|
||||
{
|
||||
std::basic_string<CharOut> result;
|
||||
result.reserve(end - begin);
|
||||
using inserter_type = std::back_insert_iterator<std::basic_string<CharOut>>;
|
||||
inserter_type inserter(result);
|
||||
code_point c;
|
||||
while(begin != end)
|
||||
{
|
||||
c = utf_traits<CharIn>::decode(begin, end);
|
||||
if(c == illegal || c == incomplete)
|
||||
{
|
||||
c = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
utf_traits<CharOut>::encode(c, inserter);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Return the length of the given string in code units.
|
||||
/// That is the number of elements of type Char until the first NULL character
|
||||
/// Equivalent to `std::strlen(s)` but can handle wide-strings
|
||||
template<typename Char>
|
||||
size_t strlen(const Char* s)
|
||||
{
|
||||
const Char* end = s;
|
||||
while(*end)
|
||||
end++;
|
||||
return end - s;
|
||||
}
|
||||
|
||||
} // namespace utf
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
452
install/boost_1_75_0/include/boost/nowide/utf/utf.hpp
Normal file
452
install/boost_1_75_0/include/boost/nowide/utf/utf.hpp
Normal file
@@ -0,0 +1,452 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_UTF_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_UTF_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/config.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
///
|
||||
/// \brief Namespace that holds basic operations on UTF encoded sequences
|
||||
///
|
||||
/// All functions defined in this namespace do not require linking with Boost.Nowide library
|
||||
/// Extracted from Boost.Locale
|
||||
///
|
||||
namespace utf {
|
||||
|
||||
///
|
||||
/// \brief The integral type that can hold a Unicode code point
|
||||
///
|
||||
using code_point = uint32_t;
|
||||
|
||||
///
|
||||
/// \brief Special constant that defines illegal code point
|
||||
///
|
||||
static const code_point illegal = 0xFFFFFFFFu;
|
||||
|
||||
///
|
||||
/// \brief Special constant that defines incomplete code point
|
||||
///
|
||||
static const code_point incomplete = 0xFFFFFFFEu;
|
||||
|
||||
///
|
||||
/// \brief the function checks if \a v is a valid code point
|
||||
///
|
||||
inline bool is_valid_codepoint(code_point v)
|
||||
{
|
||||
if(v > 0x10FFFF)
|
||||
return false;
|
||||
if(0xD800 <= v && v <= 0xDFFF) // surrogates
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef BOOST_NOWIDE_DOXYGEN
|
||||
///
|
||||
/// \brief UTF Traits class - functions to convert UTF sequences to and from Unicode code points
|
||||
///
|
||||
template<typename CharType, int size = sizeof(CharType)>
|
||||
struct utf_traits
|
||||
{
|
||||
///
|
||||
/// The type of the character
|
||||
///
|
||||
using char_type = CharType;
|
||||
///
|
||||
/// Read one code point from the range [p,e) and return it.
|
||||
///
|
||||
/// - If the sequence that was read is incomplete sequence returns \ref incomplete,
|
||||
/// - If illegal sequence detected returns \ref illegal
|
||||
///
|
||||
/// Requirements
|
||||
///
|
||||
/// - Iterator is valid input iterator
|
||||
///
|
||||
/// Postconditions
|
||||
///
|
||||
/// - p points to the last consumed character
|
||||
///
|
||||
template<typename Iterator>
|
||||
static code_point decode(Iterator& p, Iterator e);
|
||||
|
||||
///
|
||||
/// Maximal width of valid sequence in the code units:
|
||||
///
|
||||
/// - UTF-8 - 4
|
||||
/// - UTF-16 - 2
|
||||
/// - UTF-32 - 1
|
||||
///
|
||||
static const int max_width;
|
||||
///
|
||||
/// The width of specific code point in the code units.
|
||||
///
|
||||
/// Requirement: value is a valid Unicode code point
|
||||
/// Returns value in range [1..max_width]
|
||||
///
|
||||
static int width(code_point value);
|
||||
|
||||
///
|
||||
/// Get the size of the trail part of variable length encoded sequence.
|
||||
///
|
||||
/// Returns -1 if C is not valid lead character
|
||||
///
|
||||
static int trail_length(char_type c);
|
||||
///
|
||||
/// Returns true if c is trail code unit, always false for UTF-32
|
||||
///
|
||||
static bool is_trail(char_type c);
|
||||
///
|
||||
/// Returns true if c is lead code unit, always true of UTF-32
|
||||
///
|
||||
static bool is_lead(char_type c);
|
||||
|
||||
///
|
||||
/// Convert valid Unicode code point \a value to the UTF sequence.
|
||||
///
|
||||
/// Requirements:
|
||||
///
|
||||
/// - \a value is valid code point
|
||||
/// - \a out is an output iterator should be able to accept at least width(value) units
|
||||
///
|
||||
/// Returns the iterator past the last written code unit.
|
||||
///
|
||||
template<typename Iterator>
|
||||
static Iterator encode(code_point value, Iterator out);
|
||||
///
|
||||
/// Decodes valid UTF sequence that is pointed by p into code point.
|
||||
///
|
||||
/// If the sequence is invalid or points to end the behavior is undefined
|
||||
///
|
||||
template<typename Iterator>
|
||||
static code_point decode_valid(Iterator& p);
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<typename CharType, int size = sizeof(CharType)>
|
||||
struct utf_traits;
|
||||
|
||||
template<typename CharType>
|
||||
struct utf_traits<CharType, 1>
|
||||
{
|
||||
using char_type = CharType;
|
||||
|
||||
static int trail_length(char_type ci)
|
||||
{
|
||||
unsigned char c = ci;
|
||||
if(c < 128)
|
||||
return 0;
|
||||
if(BOOST_UNLIKELY(c < 194))
|
||||
return -1;
|
||||
if(c < 224)
|
||||
return 1;
|
||||
if(c < 240)
|
||||
return 2;
|
||||
if(BOOST_LIKELY(c <= 244))
|
||||
return 3;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const int max_width = 4;
|
||||
|
||||
static int width(code_point value)
|
||||
{
|
||||
if(value <= 0x7F)
|
||||
{
|
||||
return 1;
|
||||
} else if(value <= 0x7FF)
|
||||
{
|
||||
return 2;
|
||||
} else if(BOOST_LIKELY(value <= 0xFFFF))
|
||||
{
|
||||
return 3;
|
||||
} else
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_trail(char_type ci)
|
||||
{
|
||||
unsigned char c = ci;
|
||||
return (c & 0xC0) == 0x80;
|
||||
}
|
||||
|
||||
static bool is_lead(char_type ci)
|
||||
{
|
||||
return !is_trail(ci);
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
static code_point decode(Iterator& p, Iterator e)
|
||||
{
|
||||
if(BOOST_UNLIKELY(p == e))
|
||||
return incomplete;
|
||||
|
||||
unsigned char lead = *p++;
|
||||
|
||||
// First byte is fully validated here
|
||||
int trail_size = trail_length(lead);
|
||||
|
||||
if(BOOST_UNLIKELY(trail_size < 0))
|
||||
return illegal;
|
||||
|
||||
// OK as only ASCII may be of size = 0
|
||||
// also optimize for ASCII text
|
||||
if(trail_size == 0)
|
||||
return lead;
|
||||
|
||||
code_point c = lead & ((1 << (6 - trail_size)) - 1);
|
||||
|
||||
// Read the rest
|
||||
unsigned char tmp;
|
||||
switch(trail_size)
|
||||
{
|
||||
case 3:
|
||||
if(BOOST_UNLIKELY(p == e))
|
||||
return incomplete;
|
||||
tmp = *p++;
|
||||
if(!is_trail(tmp))
|
||||
return illegal;
|
||||
c = (c << 6) | (tmp & 0x3F);
|
||||
BOOST_NOWIDE_FALLTHROUGH;
|
||||
case 2:
|
||||
if(BOOST_UNLIKELY(p == e))
|
||||
return incomplete;
|
||||
tmp = *p++;
|
||||
if(!is_trail(tmp))
|
||||
return illegal;
|
||||
c = (c << 6) | (tmp & 0x3F);
|
||||
BOOST_NOWIDE_FALLTHROUGH;
|
||||
case 1:
|
||||
if(BOOST_UNLIKELY(p == e))
|
||||
return incomplete;
|
||||
tmp = *p++;
|
||||
if(!is_trail(tmp))
|
||||
return illegal;
|
||||
c = (c << 6) | (tmp & 0x3F);
|
||||
}
|
||||
|
||||
// Check code point validity: no surrogates and
|
||||
// valid range
|
||||
if(BOOST_UNLIKELY(!is_valid_codepoint(c)))
|
||||
return illegal;
|
||||
|
||||
// make sure it is the most compact representation
|
||||
if(BOOST_UNLIKELY(width(c) != trail_size + 1))
|
||||
return illegal;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
static code_point decode_valid(Iterator& p)
|
||||
{
|
||||
unsigned char lead = *p++;
|
||||
if(lead < 192)
|
||||
return lead;
|
||||
|
||||
int trail_size;
|
||||
|
||||
if(lead < 224)
|
||||
trail_size = 1;
|
||||
else if(BOOST_LIKELY(lead < 240)) // non-BMP rare
|
||||
trail_size = 2;
|
||||
else
|
||||
trail_size = 3;
|
||||
|
||||
code_point c = lead & ((1 << (6 - trail_size)) - 1);
|
||||
|
||||
switch(trail_size)
|
||||
{
|
||||
case 3: c = (c << 6) | (static_cast<unsigned char>(*p++) & 0x3F); BOOST_NOWIDE_FALLTHROUGH;
|
||||
case 2: c = (c << 6) | (static_cast<unsigned char>(*p++) & 0x3F); BOOST_NOWIDE_FALLTHROUGH;
|
||||
case 1: c = (c << 6) | (static_cast<unsigned char>(*p++) & 0x3F);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
static Iterator encode(code_point value, Iterator out)
|
||||
{
|
||||
if(value <= 0x7F)
|
||||
{
|
||||
*out++ = static_cast<char_type>(value);
|
||||
} else if(value <= 0x7FF)
|
||||
{
|
||||
*out++ = static_cast<char_type>((value >> 6) | 0xC0);
|
||||
*out++ = static_cast<char_type>((value & 0x3F) | 0x80);
|
||||
} else if(BOOST_LIKELY(value <= 0xFFFF))
|
||||
{
|
||||
*out++ = static_cast<char_type>((value >> 12) | 0xE0);
|
||||
*out++ = static_cast<char_type>(((value >> 6) & 0x3F) | 0x80);
|
||||
*out++ = static_cast<char_type>((value & 0x3F) | 0x80);
|
||||
} else
|
||||
{
|
||||
*out++ = static_cast<char_type>((value >> 18) | 0xF0);
|
||||
*out++ = static_cast<char_type>(((value >> 12) & 0x3F) | 0x80);
|
||||
*out++ = static_cast<char_type>(((value >> 6) & 0x3F) | 0x80);
|
||||
*out++ = static_cast<char_type>((value & 0x3F) | 0x80);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}; // utf8
|
||||
|
||||
template<typename CharType>
|
||||
struct utf_traits<CharType, 2>
|
||||
{
|
||||
using char_type = CharType;
|
||||
|
||||
// See RFC 2781
|
||||
static bool is_first_surrogate(uint16_t x)
|
||||
{
|
||||
return 0xD800 <= x && x <= 0xDBFF;
|
||||
}
|
||||
static bool is_second_surrogate(uint16_t x)
|
||||
{
|
||||
return 0xDC00 <= x && x <= 0xDFFF;
|
||||
}
|
||||
static code_point combine_surrogate(uint16_t w1, uint16_t w2)
|
||||
{
|
||||
return ((code_point(w1 & 0x3FF) << 10) | (w2 & 0x3FF)) + 0x10000;
|
||||
}
|
||||
static int trail_length(char_type c)
|
||||
{
|
||||
if(is_first_surrogate(c))
|
||||
return 1;
|
||||
if(is_second_surrogate(c))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
///
|
||||
/// Returns true if c is trail code unit, always false for UTF-32
|
||||
///
|
||||
static bool is_trail(char_type c)
|
||||
{
|
||||
return is_second_surrogate(c);
|
||||
}
|
||||
///
|
||||
/// Returns true if c is lead code unit, always true of UTF-32
|
||||
///
|
||||
static bool is_lead(char_type c)
|
||||
{
|
||||
return !is_second_surrogate(c);
|
||||
}
|
||||
|
||||
template<typename It>
|
||||
static code_point decode(It& current, It last)
|
||||
{
|
||||
if(BOOST_UNLIKELY(current == last))
|
||||
return incomplete;
|
||||
uint16_t w1 = *current++;
|
||||
if(BOOST_LIKELY(w1 < 0xD800 || 0xDFFF < w1))
|
||||
{
|
||||
return w1;
|
||||
}
|
||||
if(w1 > 0xDBFF)
|
||||
return illegal;
|
||||
if(current == last)
|
||||
return incomplete;
|
||||
uint16_t w2 = *current++;
|
||||
if(w2 < 0xDC00 || 0xDFFF < w2)
|
||||
return illegal;
|
||||
return combine_surrogate(w1, w2);
|
||||
}
|
||||
template<typename It>
|
||||
static code_point decode_valid(It& current)
|
||||
{
|
||||
uint16_t w1 = *current++;
|
||||
if(BOOST_LIKELY(w1 < 0xD800 || 0xDFFF < w1))
|
||||
{
|
||||
return w1;
|
||||
}
|
||||
uint16_t w2 = *current++;
|
||||
return combine_surrogate(w1, w2);
|
||||
}
|
||||
|
||||
static const int max_width = 2;
|
||||
static int width(code_point u)
|
||||
{
|
||||
return u >= 0x10000 ? 2 : 1;
|
||||
}
|
||||
template<typename It>
|
||||
static It encode(code_point u, It out)
|
||||
{
|
||||
if(BOOST_LIKELY(u <= 0xFFFF))
|
||||
{
|
||||
*out++ = static_cast<char_type>(u);
|
||||
} else
|
||||
{
|
||||
u -= 0x10000;
|
||||
*out++ = static_cast<char_type>(0xD800 | (u >> 10));
|
||||
*out++ = static_cast<char_type>(0xDC00 | (u & 0x3FF));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}; // utf16;
|
||||
|
||||
template<typename CharType>
|
||||
struct utf_traits<CharType, 4>
|
||||
{
|
||||
using char_type = CharType;
|
||||
static int trail_length(char_type c)
|
||||
{
|
||||
if(is_valid_codepoint(c))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
static bool is_trail(char_type /*c*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static bool is_lead(char_type /*c*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename It>
|
||||
static code_point decode_valid(It& current)
|
||||
{
|
||||
return *current++;
|
||||
}
|
||||
|
||||
template<typename It>
|
||||
static code_point decode(It& current, It last)
|
||||
{
|
||||
if(BOOST_UNLIKELY(current == last))
|
||||
return incomplete;
|
||||
code_point c = *current++;
|
||||
if(BOOST_UNLIKELY(!is_valid_codepoint(c)))
|
||||
return illegal;
|
||||
return c;
|
||||
}
|
||||
static const int max_width = 1;
|
||||
static int width(code_point /*u*/)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
template<typename It>
|
||||
static It encode(code_point u, It out)
|
||||
{
|
||||
*out++ = static_cast<char_type>(u);
|
||||
return out;
|
||||
}
|
||||
|
||||
}; // utf32
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace utf
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
427
install/boost_1_75_0/include/boost/nowide/utf8_codecvt.hpp
Normal file
427
install/boost_1_75_0/include/boost/nowide/utf8_codecvt.hpp
Normal file
@@ -0,0 +1,427 @@
|
||||
//
|
||||
// Copyright (c) 2015 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_UTF8_CODECVT_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_UTF8_CODECVT_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/replacement.hpp>
|
||||
#include <boost/nowide/utf/utf.hpp>
|
||||
#include <cstdint>
|
||||
#include <locale>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
|
||||
static_assert(sizeof(std::mbstate_t) >= 2, "mbstate_t is to small to store an UTF-16 codepoint");
|
||||
namespace detail {
|
||||
// Avoid including cstring for std::memcpy
|
||||
inline void copy_uint16_t(void* dst, const void* src)
|
||||
{
|
||||
unsigned char* cdst = static_cast<unsigned char*>(dst);
|
||||
const unsigned char* csrc = static_cast<const unsigned char*>(src);
|
||||
cdst[0] = csrc[0];
|
||||
cdst[1] = csrc[1];
|
||||
}
|
||||
inline std::uint16_t read_state(const std::mbstate_t& src)
|
||||
{
|
||||
std::uint16_t dst;
|
||||
copy_uint16_t(&dst, &src);
|
||||
return dst;
|
||||
}
|
||||
inline void write_state(std::mbstate_t& dst, const std::uint16_t src)
|
||||
{
|
||||
copy_uint16_t(&dst, &src);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER < 1700
|
||||
// MSVC do_length is non-standard it counts wide characters instead of narrow and does not change mbstate
|
||||
#define BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
|
||||
#endif
|
||||
|
||||
/// std::codecvt implementation that converts between UTF-8 and UTF-16 or UTF-32
|
||||
///
|
||||
/// @tparam CharSize Determines the encoding: 2 for UTF-16, 4 for UTF-32
|
||||
///
|
||||
/// Invalid sequences are replaced by #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
/// A trailing incomplete sequence will result in a return value of std::codecvt::partial
|
||||
template<typename CharType, int CharSize = sizeof(CharType)>
|
||||
class utf8_codecvt;
|
||||
|
||||
/// Specialization for the UTF-8 <-> UTF-16 variant of the std::codecvt implementation
|
||||
template<typename CharType>
|
||||
class BOOST_SYMBOL_VISIBLE utf8_codecvt<CharType, 2> : public std::codecvt<CharType, char, std::mbstate_t>
|
||||
{
|
||||
public:
|
||||
static_assert(sizeof(CharType) >= 2, "CharType must be able to store UTF16 code point");
|
||||
|
||||
utf8_codecvt(size_t refs = 0) : std::codecvt<CharType, char, std::mbstate_t>(refs)
|
||||
{}
|
||||
|
||||
protected:
|
||||
using uchar = CharType;
|
||||
|
||||
std::codecvt_base::result do_unshift(std::mbstate_t& s, char* from, char* /*to*/, char*& next) const override
|
||||
{
|
||||
if(detail::read_state(s) != 0)
|
||||
return std::codecvt_base::error;
|
||||
next = from;
|
||||
return std::codecvt_base::ok;
|
||||
}
|
||||
int do_encoding() const noexcept override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int do_max_length() const noexcept override
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
bool do_always_noconv() const noexcept override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int do_length(std::mbstate_t
|
||||
#ifdef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
|
||||
const
|
||||
#endif
|
||||
& std_state,
|
||||
const char* from,
|
||||
const char* from_end,
|
||||
size_t max) const override
|
||||
{
|
||||
std::uint16_t state = detail::read_state(std_state);
|
||||
#ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
|
||||
const char* save_from = from;
|
||||
#else
|
||||
size_t save_max = max;
|
||||
#endif
|
||||
while(max > 0 && from < from_end)
|
||||
{
|
||||
const char* prev_from = from;
|
||||
std::uint32_t ch = utf::utf_traits<char>::decode(from, from_end);
|
||||
if(ch == utf::illegal)
|
||||
{
|
||||
ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
} else if(ch == utf::incomplete)
|
||||
{
|
||||
from = prev_from;
|
||||
break;
|
||||
}
|
||||
max--;
|
||||
if(ch > 0xFFFF)
|
||||
{
|
||||
if(state == 0)
|
||||
{
|
||||
from = prev_from;
|
||||
state = 1;
|
||||
} else
|
||||
{
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
|
||||
detail::write_state(std_state, state);
|
||||
return static_cast<int>(from - save_from);
|
||||
#else
|
||||
return static_cast<int>(save_max - max);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::codecvt_base::result do_in(std::mbstate_t& std_state,
|
||||
const char* from,
|
||||
const char* from_end,
|
||||
const char*& from_next,
|
||||
uchar* to,
|
||||
uchar* to_end,
|
||||
uchar*& to_next) const override
|
||||
{
|
||||
std::codecvt_base::result r = std::codecvt_base::ok;
|
||||
|
||||
// mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT())
|
||||
// according to standard. We use it to keep a flag 0/1 for surrogate pair writing
|
||||
//
|
||||
// if 0 no code above >0xFFFF observed, of 1 a code above 0xFFFF observed
|
||||
// and first pair is written, but no input consumed
|
||||
std::uint16_t state = detail::read_state(std_state);
|
||||
while(to < to_end && from < from_end)
|
||||
{
|
||||
const char* from_saved = from;
|
||||
|
||||
uint32_t ch = utf::utf_traits<char>::decode(from, from_end);
|
||||
|
||||
if(ch == utf::illegal)
|
||||
{
|
||||
ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
} else if(ch == utf::incomplete)
|
||||
{
|
||||
from = from_saved;
|
||||
r = std::codecvt_base::partial;
|
||||
break;
|
||||
}
|
||||
// Normal codepoints go directly to stream
|
||||
if(ch <= 0xFFFF)
|
||||
{
|
||||
*to++ = static_cast<CharType>(ch);
|
||||
} else
|
||||
{
|
||||
// for other codepoints we do following
|
||||
//
|
||||
// 1. We can't consume our input as we may find ourself
|
||||
// in state where all input consumed but not all output written,i.e. only
|
||||
// 1st pair is written
|
||||
// 2. We only write first pair and mark this in the state, we also revert back
|
||||
// the from pointer in order to make sure this codepoint would be read
|
||||
// once again and then we would consume our input together with writing
|
||||
// second surrogate pair
|
||||
ch -= 0x10000;
|
||||
std::uint16_t vh = static_cast<std::uint16_t>(ch >> 10);
|
||||
std::uint16_t vl = ch & 0x3FF;
|
||||
std::uint16_t w1 = vh + 0xD800;
|
||||
std::uint16_t w2 = vl + 0xDC00;
|
||||
if(state == 0)
|
||||
{
|
||||
from = from_saved;
|
||||
*to++ = static_cast<CharType>(w1);
|
||||
state = 1;
|
||||
} else
|
||||
{
|
||||
*to++ = static_cast<CharType>(w2);
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
from_next = from;
|
||||
to_next = to;
|
||||
if(r == std::codecvt_base::ok && (from != from_end || state != 0))
|
||||
r = std::codecvt_base::partial;
|
||||
detail::write_state(std_state, state);
|
||||
return r;
|
||||
}
|
||||
|
||||
std::codecvt_base::result do_out(std::mbstate_t& std_state,
|
||||
const uchar* from,
|
||||
const uchar* from_end,
|
||||
const uchar*& from_next,
|
||||
char* to,
|
||||
char* to_end,
|
||||
char*& to_next) const override
|
||||
{
|
||||
std::codecvt_base::result r = std::codecvt_base::ok;
|
||||
// mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT())
|
||||
// according to standard. We assume that sizeof(mbstate_t) >=2 in order
|
||||
// to be able to store first observed surrogate pair
|
||||
//
|
||||
// State: state!=0 - a first surrogate pair was observed (state = first pair),
|
||||
// we expect the second one to come and then zero the state
|
||||
///
|
||||
std::uint16_t state = detail::read_state(std_state);
|
||||
while(to < to_end && from < from_end)
|
||||
{
|
||||
std::uint32_t ch = 0;
|
||||
if(state != 0)
|
||||
{
|
||||
// if the state indicates that 1st surrogate pair was written
|
||||
// we should make sure that the second one that comes is actually
|
||||
// second surrogate
|
||||
std::uint16_t w1 = state;
|
||||
std::uint16_t w2 = *from;
|
||||
// we don't forward from as writing may fail to incomplete or
|
||||
// partial conversion
|
||||
if(0xDC00 <= w2 && w2 <= 0xDFFF)
|
||||
{
|
||||
std::uint16_t vh = w1 - 0xD800;
|
||||
std::uint16_t vl = w2 - 0xDC00;
|
||||
ch = ((uint32_t(vh) << 10) | vl) + 0x10000;
|
||||
} else
|
||||
{
|
||||
ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
} else
|
||||
{
|
||||
ch = *from;
|
||||
if(0xD800 <= ch && ch <= 0xDBFF)
|
||||
{
|
||||
// if this is a first surrogate pair we put
|
||||
// it into the state and consume it, note we don't
|
||||
// go forward as it should be illegal so we increase
|
||||
// the from pointer manually
|
||||
state = static_cast<std::uint16_t>(ch);
|
||||
from++;
|
||||
continue;
|
||||
} else if(0xDC00 <= ch && ch <= 0xDFFF)
|
||||
{
|
||||
// if we observe second surrogate pair and
|
||||
// first only may be expected we should break from the loop with error
|
||||
// as it is illegal input
|
||||
ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
}
|
||||
if(!utf::is_valid_codepoint(ch))
|
||||
{
|
||||
r = std::codecvt_base::error;
|
||||
break;
|
||||
}
|
||||
int len = utf::utf_traits<char>::width(ch);
|
||||
if(to_end - to < len)
|
||||
{
|
||||
r = std::codecvt_base::partial;
|
||||
break;
|
||||
}
|
||||
to = utf::utf_traits<char>::encode(ch, to);
|
||||
state = 0;
|
||||
from++;
|
||||
}
|
||||
from_next = from;
|
||||
to_next = to;
|
||||
if(r == std::codecvt_base::ok && (from != from_end || state != 0))
|
||||
r = std::codecvt_base::partial;
|
||||
detail::write_state(std_state, state);
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
/// Specialization for the UTF-8 <-> UTF-32 variant of the std::codecvt implementation
|
||||
template<typename CharType>
|
||||
class BOOST_SYMBOL_VISIBLE utf8_codecvt<CharType, 4> : public std::codecvt<CharType, char, std::mbstate_t>
|
||||
{
|
||||
public:
|
||||
utf8_codecvt(size_t refs = 0) : std::codecvt<CharType, char, std::mbstate_t>(refs)
|
||||
{}
|
||||
|
||||
protected:
|
||||
using uchar = CharType;
|
||||
|
||||
std::codecvt_base::result
|
||||
do_unshift(std::mbstate_t& /*s*/, char* from, char* /*to*/, char*& next) const override
|
||||
{
|
||||
next = from;
|
||||
return std::codecvt_base::ok;
|
||||
}
|
||||
int do_encoding() const noexcept override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int do_max_length() const noexcept override
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
bool do_always_noconv() const noexcept override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int do_length(std::mbstate_t
|
||||
#ifdef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
|
||||
const
|
||||
#endif
|
||||
& /*state*/,
|
||||
const char* from,
|
||||
const char* from_end,
|
||||
size_t max) const override
|
||||
{
|
||||
#ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
|
||||
const char* start_from = from;
|
||||
#else
|
||||
size_t save_max = max;
|
||||
#endif
|
||||
|
||||
while(max > 0 && from < from_end)
|
||||
{
|
||||
const char* save_from = from;
|
||||
std::uint32_t ch = utf::utf_traits<char>::decode(from, from_end);
|
||||
if(ch == utf::incomplete)
|
||||
{
|
||||
from = save_from;
|
||||
break;
|
||||
} else if(ch == utf::illegal)
|
||||
{
|
||||
ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
max--;
|
||||
}
|
||||
#ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
|
||||
return from - start_from;
|
||||
#else
|
||||
return save_max - max;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::codecvt_base::result do_in(std::mbstate_t& /*state*/,
|
||||
const char* from,
|
||||
const char* from_end,
|
||||
const char*& from_next,
|
||||
uchar* to,
|
||||
uchar* to_end,
|
||||
uchar*& to_next) const override
|
||||
{
|
||||
std::codecvt_base::result r = std::codecvt_base::ok;
|
||||
|
||||
while(to < to_end && from < from_end)
|
||||
{
|
||||
const char* from_saved = from;
|
||||
|
||||
uint32_t ch = utf::utf_traits<char>::decode(from, from_end);
|
||||
|
||||
if(ch == utf::illegal)
|
||||
{
|
||||
ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
} else if(ch == utf::incomplete)
|
||||
{
|
||||
r = std::codecvt_base::partial;
|
||||
from = from_saved;
|
||||
break;
|
||||
}
|
||||
*to++ = ch;
|
||||
}
|
||||
from_next = from;
|
||||
to_next = to;
|
||||
if(r == std::codecvt_base::ok && from != from_end)
|
||||
r = std::codecvt_base::partial;
|
||||
return r;
|
||||
}
|
||||
|
||||
std::codecvt_base::result do_out(std::mbstate_t& /*std_state*/,
|
||||
const uchar* from,
|
||||
const uchar* from_end,
|
||||
const uchar*& from_next,
|
||||
char* to,
|
||||
char* to_end,
|
||||
char*& to_next) const override
|
||||
{
|
||||
std::codecvt_base::result r = std::codecvt_base::ok;
|
||||
while(to < to_end && from < from_end)
|
||||
{
|
||||
std::uint32_t ch = 0;
|
||||
ch = *from;
|
||||
if(!utf::is_valid_codepoint(ch))
|
||||
{
|
||||
ch = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
int len = utf::utf_traits<char>::width(ch);
|
||||
if(to_end - to < len)
|
||||
{
|
||||
r = std::codecvt_base::partial;
|
||||
break;
|
||||
}
|
||||
to = utf::utf_traits<char>::encode(ch, to);
|
||||
from++;
|
||||
}
|
||||
from_next = from;
|
||||
to_next = to;
|
||||
if(r == std::codecvt_base::ok && from != from_end)
|
||||
r = std::codecvt_base::partial;
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
32
install/boost_1_75_0/include/boost/nowide/windows.hpp
Normal file
32
install/boost_1_75_0/include/boost/nowide/windows.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_WINDOWS_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_WINDOWS_HPP_INCLUDED
|
||||
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#else
|
||||
|
||||
//
|
||||
// These are function prototypes... Allow to avoid including windows.h
|
||||
//
|
||||
extern "C" {
|
||||
|
||||
__declspec(dllimport) wchar_t* __stdcall GetEnvironmentStringsW(void);
|
||||
__declspec(dllimport) int __stdcall FreeEnvironmentStringsW(wchar_t*);
|
||||
__declspec(dllimport) wchar_t* __stdcall GetCommandLineW(void);
|
||||
__declspec(dllimport) wchar_t** __stdcall CommandLineToArgvW(const wchar_t*, int*);
|
||||
__declspec(dllimport) unsigned long __stdcall GetLastError();
|
||||
__declspec(dllimport) void* __stdcall LocalFree(void*);
|
||||
__declspec(dllimport) int __stdcall SetEnvironmentVariableW(const wchar_t*, const wchar_t*);
|
||||
__declspec(dllimport) unsigned long __stdcall GetEnvironmentVariableW(const wchar_t*, wchar_t*, unsigned long);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user