Skip to content

Commit 4da501f

Browse files
committed
path : operator/=, append, operator/を追加 #513
1 parent 5cd020b commit 4da501f

File tree

5 files changed

+554
-3
lines changed

5 files changed

+554
-3
lines changed

editors_doc/page_names.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ cpprefjpサイトでは、ページファイル名の付け方について、い
2727
| `operator-=` | 減算の複合代入 | `op_minus_assign` | |
2828
| `operator*=` | 乗算の複合代入 | `op_multiply_assign` | |
2929
| `operator/=` | 除算の複合代入 | `op_divide_assign` | |
30+
| `operator/=` | パス要素加算の複合代入 | `op_append_assign` | この演算子はファイルシステムの文脈で特殊な意味を持つ。<br/> 対応するメンバ関数`append()`と合わせた命名 |
3031
| `operator%=` | 剰余の複合代入 | `op_modulo_assign` | |
3132
| `operator<<=` | 左ビットシフトの複合代入 | `op_left_shift_assign` | |
3233
| `operator>>=` | 右ビットシフトの複合代入 | `op_right_shift_assign` | |
@@ -49,6 +50,7 @@ cpprefjpサイトでは、ページファイル名の付け方について、い
4950
| `operator-` (二項) | 減算演算子 | `op_minus` | |
5051
| `operator*` (二項) | 乗算演算子 | `op_multiply` | |
5152
| `operator/` (二項) | 除算演算子 | `op_divide` | |
53+
| `operator/` (二項) | パス要素加算の演算子 | `op_append` | この演算子はファイルシステムの文脈で特殊な意味を持つ |
5254
| `operator%` (二項) | 剰余演算子 | `op_modulo` | |
5355
| `operator&` | ビット論理積演算子 | `op_and` | |
5456
| `operator`<code>&#x7C;</code> | ビット論理和演算子 | `op_or` | |

reference/filesystem/path.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ namespace std::filesystem {
3737
3838
| 名前 | 説明 | 対応バージョン |
3939
|------|------|----------------|
40-
| `operator/=` | パス要素を加算する | C++17 |
41-
| `append` | パス要素を加算する | C++17 |
40+
| [`operator/=`](path/op_append_assign.md) | パス要素を加算する | C++17 |
41+
| [`append`](path/append.md) | パス要素を加算する | C++17 |
4242
| `operator+=` | パス文字列を加算する | C++17 |
4343
| `concat` | パス文字列を加算する | C++17 |
4444
@@ -171,7 +171,7 @@ namespace std::filesystem {
171171
172172
| 名前 | 説明 | 対応バージョン |
173173
|------|------|----------------|
174-
| `operator/` | 2つのパスを連結する | C++17 |
174+
| [`operator/`](path/op_append.md) | 2つのパスを連結する | C++17 |
175175
176176
### 入出力
177177
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
# operator/=
2+
* filesystem[meta header]
3+
* std::filesystem[meta namespace]
4+
* path[meta class]
5+
* function[meta id-type]
6+
* cpp17[meta cpp]
7+
8+
```cpp
9+
template <class Source>
10+
path& append(const Source& source); // (1)
11+
12+
template <class InputIterator>
13+
path& append(InputIterator first, InputIterator last); // (2)
14+
```
15+
16+
## 概要
17+
パス要素を加算する。
18+
19+
20+
## 効果
21+
- (1) : `return operator/=(path(source))`と同等
22+
- (2) : `return operator/=(path(first, last))`と同等
23+
24+
25+
## 戻り値
26+
`*this`
27+
28+
29+
## 例
30+
### POSIXベースシステムでの例
31+
```cpp example
32+
#include <iostream>
33+
#include <filesystem>
34+
35+
namespace fs = std::filesystem;
36+
37+
int main()
38+
{
39+
// 通常のユースケース
40+
// 後ろにディレクトリを加算する
41+
{
42+
fs::path p = "foo";
43+
p.append("bar");
44+
std::cout << "a : " << p << std::endl;
45+
}
46+
47+
// 左辺の末尾にディレクトリ区切り文字が付いていてもよい
48+
{
49+
fs::path p = "foo/";
50+
p.append("bar");
51+
std::cout << "b : " << p << std::endl;
52+
}
53+
54+
// 右辺が空のパスだった場合、ディレクトリ区切り文字だけ追加される
55+
{
56+
fs::path p = "foo";
57+
p.append("");
58+
std::cout << "c : " << p << std::endl;
59+
}
60+
61+
// 右辺にルートディレクトリを含むパスを指定した場合、
62+
// 右辺を代入する動作となる
63+
{
64+
fs::path p = "foo";
65+
p.append("/bar");
66+
std::cout << "d : " << p << std::endl;
67+
}
68+
}
69+
```
70+
71+
#### 出力
72+
```
73+
a : "foo/bar"
74+
b : "foo/bar"
75+
c : "foo/"
76+
d : "/bar"
77+
```
78+
79+
### Windowsでの例
80+
```cpp
81+
#include <iostream>
82+
#include <filesystem>
83+
84+
namespace fs = std::filesystem;
85+
86+
int main()
87+
{
88+
// 通常のユースケース
89+
// 後ろにディレクトリを加算する
90+
{
91+
fs::path p = "foo";
92+
p.append("bar");
93+
std::cout << "a : " << p << std::endl;
94+
}
95+
96+
// 左辺の末尾にディレクトリ区切り文字が付いていてもよい
97+
{
98+
fs::path p = "C:/foo/";
99+
p.append("bar");
100+
std::cout << "b : " << p << std::endl;
101+
}
102+
103+
// 右辺が空のパスだった場合、ディレクトリ区切り文字だけ追加される
104+
{
105+
fs::path p = "foo";
106+
p.append("");
107+
std::cout << "c : " << p << std::endl;
108+
}
109+
110+
// 左辺がルート名を持っていて、ルートディレクトリを持たず、
111+
// 右辺が空の場合、ディレクトリ区切り文字は追加されない
112+
{
113+
fs::path p = "C:";
114+
p.append("");
115+
std::cout << "d : " << p << std::endl;
116+
}
117+
118+
// 右辺にルートディレクトリを含むパスを指定した場合、
119+
// 右辺を代入する動作となる
120+
{
121+
fs::path p = "foo";
122+
p.append("C:/bar");
123+
std::cout << "d : " << p << std::endl;
124+
}
125+
126+
// 左辺と右辺のディレクトリ区切り文字の有無に関わらず連結される
127+
// (POSIXと違って、ルートディレクトリが`/`ではないため、
128+
// 右辺の開始をディレクトリ区切り文字にできる)
129+
{
130+
fs::path p = "foo";
131+
p.append("/bar");
132+
std::cout << "e : " << p << std::endl;
133+
}
134+
135+
// 左辺がルート名を持ち、ルートディレクトリを持たないパスで、
136+
// 右辺に空のパスを指定した場合、ディレクトリ区切り文字は追加されない
137+
{
138+
fs::path p = "C:";
139+
p.append("");
140+
std::cout << "f : " << p << std::endl;
141+
}
142+
143+
// 左辺がカレントディレクトリに依存した絶対パスの場合、
144+
// 相対パスを追加するとカレントディレクトリに依存したパス部分が右辺で上書きされる
145+
{
146+
fs::path p = "C:foo";
147+
p.append("/bar");
148+
std::cout << "g : " << p << std::endl;
149+
}
150+
151+
// 左辺がカレントディレクトリに依存した絶対パスで、
152+
// 右辺もカレントディレクトリに依存した絶対パスの場合、
153+
// 左辺のパスに、右辺のカレントディレクトリに依存した部分が加算される
154+
{
155+
fs::path p = "C:foo";
156+
p.append("C:bar");
157+
std::cout << "h : " << p << std::endl;
158+
}
159+
}
160+
```
161+
162+
#### 出力
163+
```
164+
a : "foo\bar"
165+
b : "C:\foo"
166+
c : "foo\"
167+
d : "C:\bar"
168+
e : "foo\bar"
169+
f : "C:"
170+
g : "C:\bar"
171+
h : "C:foo\bar"
172+
```
173+
174+
Windowsでの例は、Visual C++が正式にファイルシステムライブラリをサポートしていないことから、未検証のサンプルコード・出力となっている。
175+
176+
## バージョン
177+
### 言語
178+
- C++17
179+
180+
### 処理系
181+
- [Clang](/implementation.md#clang):
182+
- [GCC, C++17 mode](/implementation.md#gcc): 8.1
183+
- [Visual C++](/implementation.md#visual_cpp):
184+
185+
### 備考
186+
- GCC 8.1 (SVN) の`operator/=`では、ルートディレクトリを持つパスを加算すると、左辺が削除されないバグがある
187+
- [Bug 84159 - `filesystem::path::operator/=` with has root directory path](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84159)
188+
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# operator/
2+
* filesystem[meta header]
3+
* std::filesystem[meta namespace]
4+
* function[meta id-type]
5+
* cpp17[meta cpp]
6+
7+
```cpp
8+
namespace std::filesystem {
9+
path operator/(const path& x, const path& y);
10+
}
11+
```
12+
13+
## 概要
14+
2つのパス要素を連結する。
15+
16+
17+
## 効果
18+
以下と同等の効果を持つ:
19+
20+
```cpp
21+
return path(lhs) /= rhs;
22+
```
23+
* /=[link op_append_assign.md]
24+
25+
26+
##
27+
### POSIXベースシステムでの例
28+
```cpp example
29+
#include <iostream>
30+
#include <filesystem>
31+
32+
namespace fs = std::filesystem;
33+
34+
int main()
35+
{
36+
// 通常のユースケース
37+
// 後ろにディレクトリを加算する
38+
{
39+
fs::path p = fs::path("foo") / "bar";
40+
std::cout << "a : " << p << std::endl;
41+
}
42+
43+
// 左辺の末尾にディレクトリ区切り文字が付いていてもよい
44+
{
45+
fs::path p = fs::path("foo/") / "bar";
46+
std::cout << "b : " << p << std::endl;
47+
}
48+
49+
// 右辺が空のパスだった場合、ディレクトリ区切り文字だけ追加される
50+
{
51+
fs::path p = fs::path("foo") / "";
52+
std::cout << "c : " << p << std::endl;
53+
}
54+
55+
// 右辺にルートディレクトリを含むパスを指定した場合、
56+
// 右辺を代入する動作となる
57+
{
58+
fs::path p = fs::path("foo") / "/bar";
59+
std::cout << "d : " << p << std::endl;
60+
}
61+
}
62+
```
63+
64+
#### 出力
65+
```
66+
a : "foo/bar"
67+
b : "foo/bar"
68+
c : "foo/"
69+
d : "/bar"
70+
```
71+
72+
### Windowsでの例
73+
```cpp
74+
#include <iostream>
75+
#include <filesystem>
76+
77+
namespace fs = std::filesystem;
78+
79+
int main()
80+
{
81+
// 通常のユースケース
82+
// 後ろにディレクトリを加算する
83+
{
84+
fs::path p = fs::path("foo") / "bar";
85+
std::cout << "a : " << p << std::endl;
86+
}
87+
88+
// 左辺の末尾にディレクトリ区切り文字が付いていてもよい
89+
{
90+
fs::path p = fs::path("C:/foo/") / "bar";
91+
std::cout << "b : " << p << std::endl;
92+
}
93+
94+
// 右辺が空のパスだった場合、ディレクトリ区切り文字だけ追加される
95+
{
96+
fs::path p = fs::path("foo") / "";
97+
std::cout << "c : " << p << std::endl;
98+
}
99+
100+
// 左辺がルート名を持っていて、ルートディレクトリを持たず、
101+
// 右辺が空の場合、ディレクトリ区切り文字は追加されない
102+
{
103+
fs::path p = fs::path("C:") / "";
104+
std::cout << "d : " << p << std::endl;
105+
}
106+
107+
// 右辺にルートディレクトリを含むパスを指定した場合、
108+
// 右辺を代入する動作となる
109+
{
110+
fs::path p = fs::path("foo") / "C:/bar";
111+
std::cout << "d : " << p << std::endl;
112+
}
113+
114+
// 左辺と右辺のディレクトリ区切り文字の有無に関わらず連結される
115+
// (POSIXと違って、ルートディレクトリが`/`ではないため、
116+
// 右辺の開始をディレクトリ区切り文字にできる)
117+
{
118+
fs::path p = fs::path("foo") / "/bar";
119+
std::cout << "e : " << p << std::endl;
120+
}
121+
122+
// 左辺がルート名を持ち、ルートディレクトリを持たないパスで、
123+
// 右辺に空のパスを指定した場合、ディレクトリ区切り文字は追加されない
124+
{
125+
fs::path p = fs::path("C:") / "";
126+
std::cout << "f : " << p << std::endl;
127+
}
128+
129+
// 左辺がカレントディレクトリに依存した絶対パスの場合、
130+
// 相対パスを追加するとカレントディレクトリに依存したパス部分が右辺で上書きされる
131+
{
132+
fs::path p = fs::path("C:foo") / "/bar";
133+
std::cout << "g : " << p << std::endl;
134+
}
135+
136+
// 左辺がカレントディレクトリに依存した絶対パスで、
137+
// 右辺もカレントディレクトリに依存した絶対パスの場合、
138+
// 左辺のパスに、右辺のカレントディレクトリに依存した部分が加算される
139+
{
140+
fs::path p = fs::path("C:foo") / "C:bar";
141+
std::cout << "h : " << p << std::endl;
142+
}
143+
}
144+
```
145+
146+
#### 出力
147+
```
148+
a : "foo\bar"
149+
b : "C:\foo"
150+
c : "foo\"
151+
d : "C:\bar"
152+
e : "foo\bar"
153+
f : "C:"
154+
g : "C:\bar"
155+
h : "C:foo\bar"
156+
```
157+
158+
Windowsでの例は、Visual C++が正式にファイルシステムライブラリをサポートしていないことから、未検証のサンプルコード・出力となっている。
159+
160+
## バージョン
161+
### 言語
162+
- C++17
163+
164+
### 処理系
165+
- [Clang](/implementation.md#clang):
166+
- [GCC, C++17 mode](/implementation.md#gcc): 8.1
167+
- [Visual C++](/implementation.md#visual_cpp):

0 commit comments

Comments
 (0)