summaryrefslogtreecommitdiff
path: root/goldfishlocale.h
diff options
context:
space:
mode:
Diffstat (limited to 'goldfishlocale.h')
-rw-r--r--goldfishlocale.h94
1 files changed, 94 insertions, 0 deletions
diff --git a/goldfishlocale.h b/goldfishlocale.h
new file mode 100644
index 0000000..c9448c1
--- /dev/null
+++ b/goldfishlocale.h
@@ -0,0 +1,94 @@
+// Copyright 2022 Benjamin Barenblat
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+// This is goldfishlocale, a library to help you get your terminal output
+// encoded correctly. Use it like this:
+//
+// int main(int argc, char* argv[]) {
+// goldfishlocale::SetLocaleFromEnvironment(); // call this once
+// std::cout << goldfishlocale::ToSystem(u8"These are “curly quotes”.\n");
+// }
+//
+// Running this on most terminals will produce
+//
+// These are “curly quotes”.
+//
+// On terminals that lack curly quote characters, this will gracefully degrade
+// to
+//
+// These are "curly quotes".
+//
+// rather than
+//
+// These are 窶彡urly quotes窶�
+//
+// or something similarly unexpected.
+//
+// LIBRARY ASSUMPTION: Goldfishlocale assumes your system's locale is set once
+// (by goldfishlocale) and does not change during program execution. In
+// practice, this means you should not call std::locale::global or setlocale(3).
+// By default, goldfishlocale detects and throws on locale changes; however,
+// this detection does carry a runtime cost, so it's disabled if you define
+// NDEBUG.
+
+#include <stddef.h>
+
+#include <string>
+#include <string_view>
+
+namespace goldfishlocale_internal {
+
+std::string ToSystem(char*, size_t);
+
+} // namespace goldfishlocale_internal
+
+namespace goldfishlocale {
+
+// Initializes goldfishlocale based on your environment. After this call
+// returns, the C and C++ libraries are aware of the system locale; this may
+// affect some behavior, including the way numbers and dates are formatted.
+//
+// This function must be called exactly once during the execution of your
+// program, ideally near the start of main.
+//
+// Your program must be single-threaded at the time this function is called.
+// Having multiple threads executing triggers undefined behavior.
+void SetLocaleFromEnvironment();
+
+// Converts the specified string to the system locale. Assumes a UTF-8 encoding.
+inline std::string ToSystem(std::string s) {
+ return goldfishlocale_internal::ToSystem(s.data(), s.size());
+}
+inline std::string ToSystem(std::string_view s) {
+ return ToSystem(std::string(s));
+}
+inline std::string ToSystem(const char s[]) { return ToSystem(std::string(s)); }
+
+#if defined(__cpp_char8_t) && defined(__cpp_lib_char8_t)
+
+// Converts the specified string to the system locale.
+inline std::string ToSystem(std::u8string s) {
+ return goldfishlocale_internal::ToSystem(reinterpret_cast<char*>(s.data()),
+ s.size());
+}
+inline std::string ToSystem(std::u8string_view s) {
+ return ToSystem(std::u8string(s));
+}
+inline std::string ToSystem(const char8_t s[]) {
+ return ToSystem(std::u8string(s));
+}
+
+#endif // defined(__cpp_char8_t) && defined(__cpp_lib_char8_t)
+
+} // namespace goldfishlocale