Skip to content

Commit 9d89e50

Browse files
committed
不足していた関数is_string_literal, reflect_constant_array, reflect_constant_stringを追加
1 parent d9136a1 commit 9d89e50

File tree

8 files changed

+241
-13
lines changed

8 files changed

+241
-13
lines changed

lang/cpp26/reflection.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ template for (constexpr auto m :
256256
257257
258258
## `define_static_string` / `define_static_array` / `define_static_object`
259-
これらは、コンパイル時に計算した値を静的ストレージに配置し、実行時に使用可能にするための関数群である。[`std::meta::define_static_string()`](/reference/meta/define_static_string.md)は文字列を、[`std::meta::define_static_array()`](/reference/meta/define_static_array.md)は配列を、[`std::meta::define_static_object()`](/reference/meta/define_static_object.md)はオブジェクトをそれぞれ静的ストレージに配置する。
259+
これらは、コンパイル時に計算した値を静的ストレージに配置し、実行時に使用可能にするための関数群である。[`std::define_static_string()`](/reference/meta/define_static_string.md)は文字列を、[`std::define_static_array()`](/reference/meta/define_static_array.md)は配列を、[`std::define_static_object()`](/reference/meta/define_static_object.md)はオブジェクトをそれぞれ静的ストレージに配置する。これらは`<meta>`ヘッダで提供されるが、`std`名前空間に定義される(`std::meta`名前空間ではない)
260260
261261
```cpp
262262
// コンパイル時に計算した文字列を実行時に使用する
@@ -265,15 +265,15 @@ template <typename E>
265265
constexpr std::string_view enum_to_string(E value) {
266266
template for (constexpr auto e : std::meta::enumerators_of(^^E)) {
267267
if (value == [:e:]) {
268-
return std::meta::define_static_string(std::meta::identifier_of(e));
268+
return std::define_static_string(std::meta::identifier_of(e));
269269
}
270270
}
271271
return "<unknown>";
272272
}
273273
```
274274
* std::meta::enumerators_of[link /reference/meta/enumerators_of.md]
275275
* std::meta::identifier_of[link /reference/meta/identifier_of.md]
276-
* std::meta::define_static_string[link /reference/meta/define_static_string.md]
276+
* std::define_static_string[link /reference/meta/define_static_string.md]
277277

278278

279279
## リフレクションのエラー処理

reference/meta.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,16 @@
231231

232232
## 静的ストレージへの配置
233233

234+
以下の`define_static_*``is_string_literal``std`名前空間に定義される(`std::meta`名前空間ではない)。`reflect_constant_*``std::meta`名前空間に定義される。
235+
234236
| 名前 | 説明 | 対応バージョン |
235237
|------|------|-------|
236238
| [`define_static_string`](meta/define_static_string.md) | コンパイル時文字列を静的ストレージに配置し`const CharT*`を返す | C++26 |
237239
| [`define_static_array`](meta/define_static_array.md) | コンパイル時配列を静的ストレージに配置し`span<const T>`を返す | C++26 |
238240
| [`define_static_object`](meta/define_static_object.md) | コンパイル時オブジェクトを静的ストレージに配置し`const T*`を返す | C++26 |
241+
| [`reflect_constant_string`](meta/reflect_constant_string.md) | コンパイル時文字列のリフレクションを生成する | C++26 |
242+
| [`reflect_constant_array`](meta/reflect_constant_array.md) | コンパイル時配列のリフレクションを生成する | C++26 |
243+
| [`is_string_literal`](meta/is_string_literal.md) | ポインタが文字列リテラルを指しているかを判定する | C++26 |
239244

240245

241246
## アノテーション

reference/meta/define_static_array.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# define_static_array
22
* meta[meta header]
3-
* std::meta[meta namespace]
3+
* std[meta namespace]
44
* function template[meta id-type]
55
* cpp26[meta cpp]
66

77
```cpp
8-
namespace std::meta {
8+
namespace std {
99
template <ranges::input_range R>
1010
consteval std::span<const ranges::range_value_t<R>> define_static_array(R&& r);
1111
}
@@ -26,7 +26,7 @@ namespace std::meta {
2626
#include <array>
2727
2828
int main() {
29-
constexpr auto arr = std::meta::define_static_array(std::array{1, 2, 3, 4, 5});
29+
constexpr auto arr = std::define_static_array(std::array{1, 2, 3, 4, 5});
3030
for (auto v : arr) {
3131
std::println("{}", v);
3232
}

reference/meta/define_static_object.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# define_static_object
22
* meta[meta header]
3-
* std::meta[meta namespace]
3+
* std[meta namespace]
44
* function template[meta id-type]
55
* cpp26[meta cpp]
66

77
```cpp
8-
namespace std::meta {
8+
namespace std {
99
template <class T>
10-
consteval const T* define_static_object(T&& t);
10+
consteval const remove_cvref_t<T>* define_static_object(T&& t);
1111
}
1212
```
1313
@@ -30,7 +30,7 @@ struct Config {
3030
};
3131
3232
int main() {
33-
constexpr auto* p = std::meta::define_static_object(Config{1920, 1080});
33+
constexpr auto* p = std::define_static_object(Config{1920, 1080});
3434
std::println("{}x{}", p->width, p->height);
3535
}
3636
```

reference/meta/define_static_string.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# define_static_string
22
* meta[meta header]
3-
* std::meta[meta namespace]
3+
* std[meta namespace]
44
* function template[meta id-type]
55
* cpp26[meta cpp]
66

77
```cpp
8-
namespace std::meta {
8+
namespace std {
99
template <ranges::input_range R>
1010
consteval const ranges::range_value_t<R>* define_static_string(R&& r);
1111
}
@@ -30,7 +30,7 @@ template <typename E>
3030
constexpr std::string_view to_string(E value) {
3131
template for (constexpr auto e : std::meta::enumerators_of(^^E)) {
3232
if (value == [:e:]) {
33-
return std::meta::define_static_string(std::meta::identifier_of(e));
33+
return std::define_static_string(std::meta::identifier_of(e));
3434
}
3535
}
3636
return "<unknown>";
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# is_string_literal
2+
* meta[meta header]
3+
* std[meta namespace]
4+
* function[meta id-type]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
namespace std {
9+
consteval bool is_string_literal(const char* p); // (1) C++26
10+
consteval bool is_string_literal(const wchar_t* p); // (2) C++26
11+
consteval bool is_string_literal(const char8_t* p); // (3) C++26
12+
consteval bool is_string_literal(const char16_t* p); // (4) C++26
13+
consteval bool is_string_literal(const char32_t* p); // (5) C++26
14+
}
15+
```
16+
17+
## 概要
18+
ポインタが文字列リテラル(またはそのサブオブジェクト)を指しているかどうかを判定する。
19+
20+
主に[`reflect_constant_string()`](reflect_constant_string.md)の内部実装で使用される。`reflect_constant_string()`は入力が既にヌル終端された文字列リテラルであればヌル終端文字を追加せず、そうでなければ追加する必要があるため、この関数で文字列リテラルかどうかを判定する。
21+
22+
ユーザーが直接使用する場合は、`const char*`の出自をコンパイル時に検査して、文字列リテラルに由来するポインタとそうでないポインタを区別する用途が考えられる。
23+
24+
- (1) : 通常の文字列リテラル(`"hello"`)を判定する
25+
- (2) : ワイド文字列リテラル(`L"hello"`)を判定する
26+
- (3) : UTF-8文字列リテラル(`u8"hello"`)を判定する
27+
- (4) : UTF-16文字列リテラル(`u"hello"`)を判定する
28+
- (5) : UTF-32文字列リテラル(`U"hello"`)を判定する
29+
30+
31+
## 戻り値
32+
`p`が文字列リテラルまたはそのサブオブジェクトを指している場合に`true`を返す。そうでなければ`false`を返す。
33+
34+
35+
## 備考
36+
この関数は`std`名前空間に定義される(`std::meta`名前空間ではない)。
37+
38+
39+
## 例
40+
```cpp example
41+
#include <meta>
42+
#include <print>
43+
44+
// 文字列リテラルならそのまま使い、そうでなければコピーして使う
45+
consteval const char* ensure_static(const char* p) {
46+
if (std::is_string_literal(p)) {
47+
return p; // 文字列リテラルは静的ストレージに既に存在する
48+
}
49+
return std::define_static_string(std::string_view(p));
50+
}
51+
52+
int main() {
53+
// 文字列リテラル
54+
constexpr auto s1 = ensure_static("hello");
55+
std::println("{}", s1);
56+
57+
// 文字列リテラルの部分文字列(サブオブジェクト)
58+
static_assert(std::is_string_literal("hello" + 2)); // "llo"を指す
59+
}
60+
```
61+
* std::is_string_literal[color ff0000]
62+
* std::define_static_string[link define_static_string.md]
63+
64+
### 出力
65+
```
66+
hello
67+
```
68+
69+
## バージョン
70+
### 言語
71+
- C++26
72+
73+
### 処理系
74+
- [Clang](/implementation.md#clang): ??
75+
- [GCC](/implementation.md#gcc): ??
76+
- [Visual C++](/implementation.md#visual_cpp): ??
77+
78+
79+
## 関連項目
80+
- [`define_static_string`](define_static_string.md)
81+
82+
83+
## 参照
84+
- [P3491R3 `define_static_{string,object,array}`](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3491r3.html)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# reflect_constant_array
2+
* meta[meta header]
3+
* std::meta[meta namespace]
4+
* function template[meta id-type]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
namespace std::meta {
9+
template <ranges::input_range R>
10+
consteval info reflect_constant_array(R&& r);
11+
}
12+
```
13+
* info[link info.md]
14+
15+
## 概要
16+
構造的型の要素を持つRangeから、静的配列のリフレクションを生成する。
17+
18+
[`define_static_array()`](define_static_array.md)は[`span`](/reference/span/span.md)を返すため実行時のアクセスには便利だが、`span`は構造化束縛によるパック展開ができない。この関数は配列のリフレクションを返すため、スプライスして構造化束縛でパック展開する用途に使用できる。
19+
20+
また、[`define_static_array()`](define_static_array.md)はこの関数を内部で使用して実装されている。
21+
22+
23+
## 戻り値
24+
`r`の要素をコピーした`const T[N]`のテンプレートパラメータオブジェクトのリフレクションを返す。
25+
26+
27+
## 例
28+
```cpp example
29+
#include <meta>
30+
#include <array>
31+
32+
consteval int sum() {
33+
// 配列のリフレクションをスプライスし、構造化束縛でパック展開
34+
constexpr auto [...elems] =
35+
[:std::meta::reflect_constant_array(std::array{1, 2, 3}):];
36+
return (... + elems);
37+
}
38+
39+
int main() {
40+
static_assert(sum() == 6);
41+
}
42+
```
43+
* std::meta::reflect_constant_array[color ff0000]
44+
45+
### 出力
46+
```
47+
```
48+
49+
## バージョン
50+
### 言語
51+
- C++26
52+
53+
### 処理系
54+
- [Clang](/implementation.md#clang): ??
55+
- [GCC](/implementation.md#gcc): ??
56+
- [Visual C++](/implementation.md#visual_cpp): ??
57+
58+
59+
## 関連項目
60+
- [`define_static_array`](define_static_array.md)
61+
- [`reflect_constant_string`](reflect_constant_string.md)
62+
63+
64+
## 参照
65+
- [P3491R3 `define_static_{string,object,array}`](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3491r3.html)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# reflect_constant_string
2+
* meta[meta header]
3+
* std::meta[meta namespace]
4+
* function template[meta id-type]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
namespace std::meta {
9+
template <ranges::input_range R>
10+
consteval info reflect_constant_string(R&& r);
11+
}
12+
```
13+
* info[link info.md]
14+
15+
## 概要
16+
文字のRangeからヌル終端文字配列のリフレクションを生成する。
17+
18+
[`define_static_string()`](define_static_string.md)は`const CharT*`を返すため配列のサイズ情報が失われるが、この関数はサイズ情報を保持した配列のリフレクションを返す。そのため、サイズをテンプレートパラメータとして推論する必要がある型(`FixedString<N>`など)にスプライスで渡すことができる。
19+
20+
また、[`define_static_string()`](define_static_string.md)はこの関数を内部で使用して実装されている。
21+
22+
23+
## 戻り値
24+
`r`の要素をコピーしたヌル終端文字配列`const CharT[sizeof...(V)+1]`のテンプレートパラメータオブジェクトのリフレクションを返す。
25+
26+
27+
## 例
28+
```cpp example
29+
#include <meta>
30+
#include <algorithm>
31+
#include <cstddef>
32+
33+
template <std::size_t N>
34+
struct FixedString {
35+
char data[N] = {};
36+
constexpr FixedString(const char (&str)[N]) {
37+
std::ranges::copy(str, str + N, data);
38+
}
39+
};
40+
41+
template <FixedString S>
42+
struct Named {};
43+
44+
int main() {
45+
// define_static_stringはconst char*を返すためFixedStringのサイズを推論できない
46+
// using Err = Named<std::define_static_string("hello")>; // エラー
47+
48+
// reflect_constant_stringはサイズ付き配列のリフレクションを返すため推論できる
49+
using Ok = Named<[:std::meta::reflect_constant_string("hello"):]>;
50+
}
51+
```
52+
* std::meta::reflect_constant_string[color ff0000]
53+
54+
### 出力
55+
```
56+
```
57+
58+
## バージョン
59+
### 言語
60+
- C++26
61+
62+
### 処理系
63+
- [Clang](/implementation.md#clang): ??
64+
- [GCC](/implementation.md#gcc): ??
65+
- [Visual C++](/implementation.md#visual_cpp): ??
66+
67+
68+
## 関連項目
69+
- [`define_static_string`](define_static_string.md)
70+
- [`reflect_constant_array`](reflect_constant_array.md)
71+
72+
73+
## 参照
74+
- [P3491R3 `define_static_{string,object,array}`](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3491r3.html)

0 commit comments

Comments
 (0)