Boost GIL


path_spec.hpp
1//
2// Copyright 2007-2008 Andreas Pokorny, Christian Henning
3// Copyright 2024 Dirk Stolle
4//
5// Distributed under the Boost Software License, Version 1.0
6// See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt
8//
9#ifndef BOOST_GIL_IO_PATH_SPEC_HPP
10#define BOOST_GIL_IO_PATH_SPEC_HPP
11
12#include <boost/gil/io/detail/filesystem.hpp>
13
14#include <cstdlib>
15#include <cstring>
16#include <cwchar>
17#include <string>
18#include <type_traits>
19
20#if defined(_WIN32)
21#ifndef WIN32_LEAN_AND_MEAN
22#define WIN32_LEAN_AND_MEAN
23#endif
24#ifndef NOMINMAX
25#define NOMINMAX
26#endif
27#include <windows.h>
28#endif
29
30namespace boost { namespace gil { namespace detail {
31
32#if defined(_WIN32)
33// Converts a wide string (UTF-16 on Windows) to UTF-8 without relying on
34// the current C/global locale. wcstombs/wcsrtombs depend on setlocale()
35// state, and MSVC's setlocale() parser is stricter than std::locale's own
36// constructor about which locale-name strings it accepts, so a locale that
37// constructs successfully can still leave the C runtime on the system ANSI
38// codepage instead of UTF-8. WideCharToMultiByte with CP_UTF8 sidesteps
39// that mismatch entirely.
40inline std::string wide_to_utf8(wchar_t const* str, std::size_t len)
41{
42 if (len == 0)
43 {
44 return std::string();
45 }
46 int const size = ::WideCharToMultiByte(
47 CP_UTF8, 0, str, static_cast<int>(len), nullptr, 0, nullptr, nullptr);
48 std::string result(static_cast<std::size_t>(size), '\0');
49 ::WideCharToMultiByte(
50 CP_UTF8, 0, str, static_cast<int>(len), &result[0], size, nullptr, nullptr);
51 return result;
52}
53#endif
54
55template<typename P> struct is_supported_path_spec : std::false_type {};
56template<> struct is_supported_path_spec< std::string > : std::true_type {};
57template<> struct is_supported_path_spec< const std::string > : std::true_type {};
58template<> struct is_supported_path_spec< std::wstring > : std::true_type {};
59template<> struct is_supported_path_spec< const std::wstring > : std::true_type {};
60template<> struct is_supported_path_spec< char const* > : std::true_type {};
61template<> struct is_supported_path_spec< char* > : std::true_type {};
62template<> struct is_supported_path_spec< const wchar_t* > : std::true_type {};
63template<> struct is_supported_path_spec< wchar_t* > : std::true_type {};
64
65template<int i> struct is_supported_path_spec<const char [i]> : std::true_type {};
66template<int i> struct is_supported_path_spec<char [i]> : std::true_type {};
67template<int i> struct is_supported_path_spec<const wchar_t [i]> : std::true_type {};
68template<int i> struct is_supported_path_spec<wchar_t [i]> : std::true_type {};
69
70template<> struct is_supported_path_spec<filesystem::path> : std::true_type {};
71template<> struct is_supported_path_spec<filesystem::path const> : std::true_type {};
72
73inline std::string convert_to_string( std::string const& obj)
74{
75 return obj;
76}
77
78inline std::string convert_to_string( std::wstring const& s )
79{
80#if defined(_WIN32)
81 return wide_to_utf8( s.c_str(), s.size() );
82#else
83 std::mbstate_t state = std::mbstate_t();
84 const wchar_t* str = s.c_str();
85 const std::size_t len = std::wcsrtombs(nullptr, &str, 0, &state);
86 std::string result(len, '\0');
87 std::wcstombs( &result[0], s.c_str(), len );
88
89 return result;
90#endif
91}
92
93inline std::string convert_to_string( char const* str )
94{
95 return std::string( str );
96}
97
98inline std::string convert_to_string( char* str )
99{
100 return std::string( str );
101}
102
103inline std::string convert_to_string(filesystem::path const& path)
104{
105 return convert_to_string(path.string());
106}
107
108inline char const* convert_to_native_string( char* str )
109{
110 return str;
111}
112
113inline char const* convert_to_native_string( char const* str )
114{
115 return str;
116}
117
118inline char const* convert_to_native_string( const std::string& str )
119{
120 return str.c_str();
121}
122
123inline char const* convert_to_native_string( const wchar_t* str )
124{
125#if defined(_WIN32)
126 std::string const utf8 = wide_to_utf8( str, std::wcslen( str ) );
127 char* c = new char[utf8.size() + 1];
128 std::memcpy( c, utf8.c_str(), utf8.size() + 1 );
129
130 return c;
131#else
132 std::mbstate_t state = std::mbstate_t();
133 const std::size_t len = std::wcsrtombs(nullptr, &str, 0, &state) + 1;
134 char* c = new char[len];
135 std::wcstombs( c, str, len );
136
137 return c;
138#endif
139}
140
141inline char const* convert_to_native_string( std::wstring const& str )
142{
143#if defined(_WIN32)
144 return convert_to_native_string( str.c_str() );
145#else
146 std::mbstate_t state = std::mbstate_t();
147 const wchar_t* wstr = str.c_str();
148 const std::size_t len = std::wcsrtombs(nullptr, &wstr, 0, &state) + 1;
149 char* c = new char[len];
150 std::wcstombs( c, str.c_str(), len );
151
152 return c;
153#endif
154}
155
156}}} // namespace boost::gil::detail
157
158#endif
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
Definition algorithm.hpp:36