[libc++] Implement format_error.

This is the first step at implementing <format>. It adds the <format> header
and implements the `format_error`. class.

Implemnts parts of:
-P0645 Text Formatting

Reviewed By: ldionne, #libc, miscco, curdeius

Differential Revision: https://reviews.llvm.org/D92214
This commit is contained in:
Mark de Wever 2020-11-26 19:12:18 +01:00
parent 207d4be4d9
commit 081c1db02d
18 changed files with 293 additions and 1 deletions

View File

@ -103,7 +103,7 @@
"`P0466 <https://wg21.link/P0466>`__","LWG","Layout-compatibility and Pointer-interconvertibility Traits","Cologne","",""
"`P0553 <https://wg21.link/P0553>`__","LWG","Bit operations","Cologne","|Complete|","9.0"
"`P0631 <https://wg21.link/P0631>`__","LWG","Math Constants","Cologne","|Complete|","11.0"
"`P0645 <https://wg21.link/P0645>`__","LWG","Text Formatting","Cologne","",""
"`P0645 <https://wg21.link/P0645>`__","LWG","Text Formatting","Cologne","|In Progress|",""
"`P0660 <https://wg21.link/P0660>`__","LWG","Stop Token and Joining Thread, Rev 10","Cologne","",""
"`P0784 <https://wg21.link/P0784>`__","CWG","More constexpr containers","Cologne","|Complete|","12.0"
"`P0980 <https://wg21.link/P0980>`__","LWG","Making std::string constexpr","Cologne","",""

1 Paper # Group Paper Name Meeting Status First released version
103 `P0466 <https://wg21.link/P0466>`__ LWG Layout-compatibility and Pointer-interconvertibility Traits Cologne
104 `P0553 <https://wg21.link/P0553>`__ LWG Bit operations Cologne |Complete| 9.0
105 `P0631 <https://wg21.link/P0631>`__ LWG Math Constants Cologne |Complete| 11.0
106 `P0645 <https://wg21.link/P0645>`__ LWG Text Formatting Cologne |In Progress|
107 `P0660 <https://wg21.link/P0660>`__ LWG Stop Token and Joining Thread, Rev 10 Cologne
108 `P0784 <https://wg21.link/P0784>`__ CWG More constexpr containers Cologne |Complete| 12.0
109 `P0980 <https://wg21.link/P0980>`__ LWG Making std::string constexpr Cologne

View File

@ -234,6 +234,8 @@ Status
------------------------------------------------- -----------------
``__cpp_lib_execution`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_format`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_generic_unordered_lookup`` ``201811L``
------------------------------------------------- -----------------
``__cpp_lib_int_pow2`` ``202002L``

View File

@ -99,6 +99,7 @@ set(files
fenv.h
filesystem
float.h
format
forward_list
fstream
functional

56
libcxx/include/format Normal file
View File

@ -0,0 +1,56 @@
// -*- C++ -*-
//===--------------------------- format -----------------------------------===//
//
// 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_FORMAT
#define _LIBCPP_FORMAT
/*
namespace std {
// [format.error], class format_error
class format_error : public runtime_error {
public:
explicit format_error(const string& what_arg);
explicit format_error(const char* what_arg);
};
}
*/
#include <__config>
#include <stdexcept>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
class _LIBCPP_EXCEPTION_ABI format_error : public runtime_error {
public:
_LIBCPP_INLINE_VISIBILITY explicit format_error(const string& __s)
: runtime_error(__s) {}
_LIBCPP_INLINE_VISIBILITY explicit format_error(const char* __s)
: runtime_error(__s) {}
virtual ~format_error() noexcept;
};
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP_FORMAT

View File

@ -292,6 +292,10 @@ module std [system] {
header "filesystem"
export *
}
module format {
header "format"
export *
}
module forward_list {
header "forward_list"
export initializer_list

View File

@ -72,6 +72,7 @@ __cpp_lib_exchange_function 201304L <utility>
__cpp_lib_execution 201902L <execution>
201603L // C++17
__cpp_lib_filesystem 201703L <filesystem>
__cpp_lib_format 201907L <format>
__cpp_lib_gcd_lcm 201606L <numeric>
__cpp_lib_generic_associative_lookup 201304L <map> <set>
__cpp_lib_generic_unordered_lookup 201811L <unordered_map> <unordered_set>
@ -313,6 +314,7 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_erase_if 202002L
# undef __cpp_lib_execution
// # define __cpp_lib_execution 201902L
// # define __cpp_lib_format 201907L
# define __cpp_lib_generic_unordered_lookup 201811L
# define __cpp_lib_int_pow2 202002L
// # define __cpp_lib_integer_comparison_functions 202002L

View File

@ -1039,6 +1039,9 @@
{'is_defined': True, 'name': '__ZNSt3__112ctype_bynameIwED0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112ctype_bynameIwED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112ctype_bynameIwED2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112format_errorD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112format_errorD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112format_errorD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112future_errorC1ENS_10error_codeE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112future_errorC2ENS_10error_codeE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112future_errorD0Ev', 'type': 'FUNC'}
@ -1985,6 +1988,7 @@
{'is_defined': True, 'name': '__ZTINSt3__112codecvt_baseE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTINSt3__112ctype_bynameIcEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTINSt3__112ctype_bynameIwEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTINSt3__112format_errorE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTINSt3__112future_errorE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTINSt3__112strstreambufE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTINSt3__112system_errorE', 'size': 0, 'type': 'OBJECT'}
@ -2193,6 +2197,7 @@
{'is_defined': True, 'name': '__ZTSNSt3__112codecvt_baseE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTSNSt3__112ctype_bynameIcEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTSNSt3__112ctype_bynameIwEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTSNSt3__112format_errorE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTSNSt3__112future_errorE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTSNSt3__112strstreambufE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTSNSt3__112system_errorE', 'size': 0, 'type': 'OBJECT'}
@ -2377,6 +2382,7 @@
{'is_defined': True, 'name': '__ZTVNSt3__112bad_weak_ptrE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTVNSt3__112ctype_bynameIcEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTVNSt3__112ctype_bynameIwEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTVNSt3__112format_errorE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTVNSt3__112future_errorE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTVNSt3__112strstreambufE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTVNSt3__112system_errorE', 'size': 0, 'type': 'OBJECT'}

View File

@ -726,6 +726,9 @@
{'is_defined': True, 'name': '_ZNSt3__112ctype_bynameIwED0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112ctype_bynameIwED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112ctype_bynameIwED2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112format_errorD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112format_errorD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112format_errorD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112future_errorC1ENS_10error_codeE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112future_errorC2ENS_10error_codeE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112future_errorD0Ev', 'type': 'FUNC'}
@ -1648,6 +1651,7 @@
{'is_defined': True, 'name': '_ZTINSt3__112codecvt_baseE', 'size': 16, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTINSt3__112ctype_bynameIcEE', 'size': 24, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTINSt3__112ctype_bynameIwEE', 'size': 24, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTINSt3__112format_errorE', 'size': 24, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTINSt3__112future_errorE', 'size': 24, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTINSt3__112strstreambufE', 'size': 24, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTINSt3__112system_errorE', 'size': 24, 'type': 'OBJECT'}
@ -1776,6 +1780,7 @@
{'is_defined': True, 'name': '_ZTSNSt3__112codecvt_baseE', 'size': 23, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTSNSt3__112ctype_bynameIcEE', 'size': 26, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTSNSt3__112ctype_bynameIwEE', 'size': 26, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTSNSt3__112format_errorE', 'size': 23, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTSNSt3__112future_errorE', 'size': 23, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTSNSt3__112strstreambufE', 'size': 23, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTSNSt3__112system_errorE', 'size': 23, 'type': 'OBJECT'}
@ -1908,6 +1913,7 @@
{'is_defined': True, 'name': '_ZTVNSt3__112bad_weak_ptrE', 'size': 40, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTVNSt3__112ctype_bynameIcEE', 'size': 104, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTVNSt3__112ctype_bynameIwEE', 'size': 136, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTVNSt3__112format_errorE', 'size': 40, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTVNSt3__112future_errorE', 'size': 40, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTVNSt3__112strstreambufE', 'size': 128, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTVNSt3__112system_errorE', 'size': 40, 'type': 'OBJECT'}

View File

@ -12,6 +12,7 @@ set(LIBCXX_SOURCES
condition_variable.cpp
condition_variable_destructor.cpp
exception.cpp
format.cpp
functional.cpp
future.cpp
hash.cpp

15
libcxx/src/format.cpp Normal file
View File

@ -0,0 +1,15 @@
//===------------------------- format.cpp ---------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "format"
_LIBCPP_BEGIN_NAMESPACE_STD
format_error::~format_error() noexcept = default;
_LIBCPP_END_NAMESPACE_STD

View File

@ -91,6 +91,7 @@
# include <filesystem>
#endif
#include <float.h>
#include <format>
#include <forward_list>
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
# include <fstream>

View File

@ -136,6 +136,8 @@ TEST_MACROS();
#endif
#include <float.h>
TEST_MACROS();
#include <format>
TEST_MACROS();
#include <forward_list>
TEST_MACROS();
#ifndef _LIBCPP_HAS_NO_LOCALIZATION

View File

@ -84,6 +84,7 @@
# include <filesystem>
#endif
#include <float.h>
#include <format>
#include <forward_list>
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
# include <fstream>

View File

@ -0,0 +1,75 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// WARNING: This test was generated by generate_feature_test_macro_components.py
// and should not be edited manually.
//
// clang-format off
// <format>
// Test the feature test macros defined by <format>
/* Constant Value
__cpp_lib_format 201907L [C++20]
*/
#include <format>
#include "test_macros.h"
#if TEST_STD_VER < 14
# ifdef __cpp_lib_format
# error "__cpp_lib_format should not be defined before c++20"
# endif
#elif TEST_STD_VER == 14
# ifdef __cpp_lib_format
# error "__cpp_lib_format should not be defined before c++20"
# endif
#elif TEST_STD_VER == 17
# ifdef __cpp_lib_format
# error "__cpp_lib_format should not be defined before c++20"
# endif
#elif TEST_STD_VER == 20
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_format
# error "__cpp_lib_format should be defined in c++20"
# endif
# if __cpp_lib_format != 201907L
# error "__cpp_lib_format should have the value 201907L in c++20"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_format
# error "__cpp_lib_format should not be defined because it is unimplemented in libc++!"
# endif
# endif
#elif TEST_STD_VER > 20
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_format
# error "__cpp_lib_format should be defined in c++2b"
# endif
# if __cpp_lib_format != 201907L
# error "__cpp_lib_format should have the value 201907L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_format
# error "__cpp_lib_format should not be defined because it is unimplemented in libc++!"
# endif
# endif
#endif // TEST_STD_VER > 20
int main(int, char**) { return 0; }

View File

@ -67,6 +67,7 @@
__cpp_lib_execution 201603L [C++17]
201902L [C++20]
__cpp_lib_filesystem 201703L [C++17]
__cpp_lib_format 201907L [C++20]
__cpp_lib_gcd_lcm 201606L [C++17]
__cpp_lib_generic_associative_lookup 201304L [C++14]
__cpp_lib_generic_unordered_lookup 201811L [C++20]
@ -353,6 +354,10 @@
# error "__cpp_lib_filesystem should not be defined before c++17"
# endif
# ifdef __cpp_lib_format
# error "__cpp_lib_format should not be defined before c++20"
# endif
# ifdef __cpp_lib_gcd_lcm
# error "__cpp_lib_gcd_lcm should not be defined before c++17"
# endif
@ -884,6 +889,10 @@
# error "__cpp_lib_filesystem should not be defined before c++17"
# endif
# ifdef __cpp_lib_format
# error "__cpp_lib_format should not be defined before c++20"
# endif
# ifdef __cpp_lib_gcd_lcm
# error "__cpp_lib_gcd_lcm should not be defined before c++17"
# endif
@ -1541,6 +1550,10 @@
# error "__cpp_lib_filesystem should have the value 201703L in c++17"
# endif
# ifdef __cpp_lib_format
# error "__cpp_lib_format should not be defined before c++20"
# endif
# ifndef __cpp_lib_gcd_lcm
# error "__cpp_lib_gcd_lcm should be defined in c++17"
# endif
@ -2582,6 +2595,19 @@
# error "__cpp_lib_filesystem should have the value 201703L in c++20"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_format
# error "__cpp_lib_format should be defined in c++20"
# endif
# if __cpp_lib_format != 201907L
# error "__cpp_lib_format should have the value 201907L in c++20"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_format
# error "__cpp_lib_format should not be defined because it is unimplemented in libc++!"
# endif
# endif
# ifndef __cpp_lib_gcd_lcm
# error "__cpp_lib_gcd_lcm should be defined in c++20"
# endif
@ -3788,6 +3814,19 @@
# error "__cpp_lib_filesystem should have the value 201703L in c++2b"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_format
# error "__cpp_lib_format should be defined in c++2b"
# endif
# if __cpp_lib_format != 201907L
# error "__cpp_lib_format should have the value 201907L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_format
# error "__cpp_lib_format should not be defined because it is unimplemented in libc++!"
# endif
# endif
# ifndef __cpp_lib_gcd_lcm
# error "__cpp_lib_gcd_lcm should be defined in c++2b"
# endif

View File

@ -0,0 +1,56 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// This test requires the dylib support introduced in D92214.
// XFAIL: with_system_cxx_lib=macosx10.15
// XFAIL: with_system_cxx_lib=macosx10.14
// XFAIL: with_system_cxx_lib=macosx10.13
// XFAIL: with_system_cxx_lib=macosx10.12
// XFAIL: with_system_cxx_lib=macosx10.11
// XFAIL: with_system_cxx_lib=macosx10.10
// XFAIL: with_system_cxx_lib=macosx10.9
// <format>
// class format_error;
#include <format>
#include <type_traits>
#include <cstring>
#include <string>
#include <cassert>
#include "test_macros.h"
int main(int, char**) {
static_assert(std::is_base_of_v<std::runtime_error, std::format_error>);
static_assert(std::is_polymorphic_v<std::format_error>);
{
const char* msg = "format_error message c-string";
std::format_error e(msg);
assert(std::strcmp(e.what(), msg) == 0);
std::format_error e2(e);
assert(std::strcmp(e2.what(), msg) == 0);
e2 = e;
assert(std::strcmp(e2.what(), msg) == 0);
}
{
std::string msg("format_error message std::string");
std::format_error e(msg);
assert(e.what() == msg);
std::format_error e2(e);
assert(e2.what() == msg);
e2 = e;
assert(e2.what() == msg);
}
return 0;
}

View File

@ -0,0 +1,20 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// <format>
#include <format>
#include "test_macros.h"
#ifndef _LIBCPP_VERSION
# error _LIBCPP_VERSION not defined
#endif
// Required for MSVC internal test runner compatibility.
int main(int, char**) { return 0; }

View File

@ -270,6 +270,11 @@ feature_test_macros = [ add_version_header(x) for x in [
"name": "__cpp_lib_filesystem",
"values": { "c++17": 201703 },
"headers": ["filesystem"],
}, {
"name": "__cpp_lib_format",
"values": { "c++20": 201907 },
"headers": ["format"],
"unimplemented": True,
}, {
"name": "__cpp_lib_gcd_lcm",
"values": { "c++17": 201606 },