Skip to content

[libc++] Granularize <locale> #146650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -511,13 +511,19 @@ set(files
__iterator/unreachable_sentinel.h
__iterator/wrap_iter.h
__locale
__locale_dir/check_grouping.h
__locale_dir/get_c_locale.h
__locale_dir/locale_base_api.h
__locale_dir/locale_base_api/android.h
__locale_dir/locale_base_api/bsd_locale_fallbacks.h
__locale_dir/locale_base_api/ibm.h
__locale_dir/locale_base_api/musl.h
__locale_dir/locale_base_api/openbsd.h
__locale_dir/messages.h
__locale_dir/money.h
__locale_dir/num.h
__locale_dir/pad_and_output.h
__locale_dir/scan_keyword.h
__locale_dir/support/apple.h
__locale_dir/support/bsd_like.h
__locale_dir/support/freebsd.h
Expand All @@ -526,6 +532,9 @@ set(files
__locale_dir/support/no_locale/characters.h
__locale_dir/support/no_locale/strtonum.h
__locale_dir/support/windows.h
__locale_dir/time.h
__locale_dir/wbuffer_convert.h
__locale_dir/wstring_convert.h
__math/abs.h
__math/copysign.h
__math/error_functions.h
Expand Down
4 changes: 3 additions & 1 deletion libcxx/include/__chrono/formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@
# include <__format/formatter.h>
# include <__format/parser_std_format_spec.h>
# include <__format/write_escaped.h>
# include <__iterator/istreambuf_iterator.h>
# include <__iterator/ostreambuf_iterator.h>
# include <__locale_dir/time.h>
# include <__memory/addressof.h>
# include <__type_traits/is_specialization.h>
# include <cmath>
# include <ctime>
# include <limits>
# include <locale>
# include <sstream>
# include <string_view>

Expand Down
1 change: 0 additions & 1 deletion libcxx/include/__filesystem/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@

#if _LIBCPP_HAS_LOCALIZATION
# include <iomanip> // for quoted
# include <locale>
#endif

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Expand Down
7 changes: 1 addition & 6 deletions libcxx/include/__filesystem/u8path.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,9 @@
#include <__algorithm/unwrap_iter.h>
#include <__config>
#include <__filesystem/path.h>
#include <__locale>
#include <string>

// Only required on Windows for __widen_from_utf8, and included conservatively
// because it requires support for localization.
#if defined(_LIBCPP_WIN32API)
# include <locale>
#endif

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
Expand Down
31 changes: 31 additions & 0 deletions libcxx/include/__locale_dir/check_grouping.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___LOCALE_DIR_CHECK_GROUPING_H
#define _LIBCPP___LOCALE_DIR_CHECK_GROUPING_H

#include <__config>
#include <__fwd/string.h>
#include <ios>

#if _LIBCPP_HAS_LOCALIZATION

# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif

_LIBCPP_BEGIN_NAMESPACE_STD

_LIBCPP_EXPORTED_FROM_ABI void
__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, ios_base::iostate& __err);

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_HAS_LOCALIZATION

#endif // _LIBCPP___LOCALE_DIR_CHECK_GROUPING_H
40 changes: 40 additions & 0 deletions libcxx/include/__locale_dir/get_c_locale.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___LOCALE_DIR_GET_C_LOCALE_H
#define _LIBCPP___LOCALE_DIR_GET_C_LOCALE_H

#include <__config>
#include <__locale_dir/locale_base_api.h>

#if _LIBCPP_HAS_LOCALIZATION

# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif

_LIBCPP_BEGIN_NAMESPACE_STD

// FIXME: This should really be part of the locale base API

# if defined(__APPLE__) || defined(__FreeBSD__)
# define _LIBCPP_GET_C_LOCALE 0
# elif defined(__NetBSD__)
# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
# else
# define _LIBCPP_GET_C_LOCALE __cloc()
// Get the C locale object
_LIBCPP_EXPORTED_FROM_ABI __locale::__locale_t __cloc();
# define __cloc_defined
# endif

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_HAS_LOCALIZATION

#endif // _LIBCPP___LOCALE_DIR_GET_C_LOCALE_H
143 changes: 143 additions & 0 deletions libcxx/include/__locale_dir/messages.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___LOCALE_DIR_MESSAGES_H
#define _LIBCPP___LOCALE_DIR_MESSAGES_H

#include <__config>
#include <__iterator/back_insert_iterator.h>
#include <__locale>
#include <string>

#if _LIBCPP_HAS_LOCALIZATION

# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif

# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
// Most unix variants have catopen. These are the specific ones that don't.
# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__)
# define _LIBCPP_HAS_CATOPEN 1
# include <nl_types.h>
# else
# define _LIBCPP_HAS_CATOPEN 0
# endif
# else
# define _LIBCPP_HAS_CATOPEN 0
# endif

_LIBCPP_BEGIN_NAMESPACE_STD

class _LIBCPP_EXPORTED_FROM_ABI messages_base {
public:
typedef intptr_t catalog;

_LIBCPP_HIDE_FROM_ABI messages_base() {}
};

template <class _CharT>
class messages : public locale::facet, public messages_base {
public:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;

_LIBCPP_HIDE_FROM_ABI explicit messages(size_t __refs = 0) : locale::facet(__refs) {}

_LIBCPP_HIDE_FROM_ABI catalog open(const basic_string<char>& __nm, const locale& __loc) const {
return do_open(__nm, __loc);
}

_LIBCPP_HIDE_FROM_ABI string_type get(catalog __c, int __set, int __msgid, const string_type& __dflt) const {
return do_get(__c, __set, __msgid, __dflt);
}

_LIBCPP_HIDE_FROM_ABI void close(catalog __c) const { do_close(__c); }

static locale::id id;

protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~messages() override {}

virtual catalog do_open(const basic_string<char>&, const locale&) const;
virtual string_type do_get(catalog, int __set, int __msgid, const string_type& __dflt) const;
virtual void do_close(catalog) const;
};

template <class _CharT>
locale::id messages<_CharT>::id;

template <class _CharT>
typename messages<_CharT>::catalog messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const {
# if _LIBCPP_HAS_CATOPEN
return (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
# else // !_LIBCPP_HAS_CATOPEN
(void)__nm;
return -1;
# endif // _LIBCPP_HAS_CATOPEN
}

template <class _CharT>
typename messages<_CharT>::string_type
messages<_CharT>::do_get(catalog __c, int __set, int __msgid, const string_type& __dflt) const {
# if _LIBCPP_HAS_CATOPEN
string __ndflt;
__narrow_to_utf8<sizeof(char_type) * __CHAR_BIT__>()(
std::back_inserter(__ndflt), __dflt.c_str(), __dflt.c_str() + __dflt.size());
nl_catd __cat = (nl_catd)__c;
static_assert(sizeof(catalog) >= sizeof(nl_catd), "Unexpected nl_catd type");
char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
string_type __w;
__widen_from_utf8<sizeof(char_type) * __CHAR_BIT__>()(std::back_inserter(__w), __n, __n + std::strlen(__n));
return __w;
# else // !_LIBCPP_HAS_CATOPEN
(void)__c;
(void)__set;
(void)__msgid;
return __dflt;
# endif // _LIBCPP_HAS_CATOPEN
}

template <class _CharT>
void messages<_CharT>::do_close(catalog __c) const {
# if _LIBCPP_HAS_CATOPEN
catclose((nl_catd)__c);
# else // !_LIBCPP_HAS_CATOPEN
(void)__c;
# endif // _LIBCPP_HAS_CATOPEN
}

extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<char>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<wchar_t>;
# endif

template <class _CharT>
class messages_byname : public messages<_CharT> {
public:
typedef messages_base::catalog catalog;
typedef basic_string<_CharT> string_type;

_LIBCPP_HIDE_FROM_ABI explicit messages_byname(const char*, size_t __refs = 0) : messages<_CharT>(__refs) {}

_LIBCPP_HIDE_FROM_ABI explicit messages_byname(const string&, size_t __refs = 0) : messages<_CharT>(__refs) {}

protected:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~messages_byname() override {}
};

extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>;
# if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>;
# endif

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_HAS_LOCALIZATION

#endif // _LIBCPP___LOCALE_DIR_MESSAGES_H
Loading
Loading