From c33125843ac290c65dbeb693fcade3ee89a563ae Mon Sep 17 00:00:00 2001
From: onihusube <mona-@live.jp>
Date: Wed, 22 May 2019 16:18:38 +0900
Subject: [PATCH 1/6] =?UTF-8?q?C++20=20=E3=81=AE=E6=96=B0=E6=A9=9F?=
 =?UTF-8?q?=E8=83=BD=20:=20constexpr=E9=96=A2=E4=BF=82=E8=BF=BD=E5=8A=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 docs/standardization/cpp20.md | 257 ++++++++++++++++++++++++++++++++++
 1 file changed, 257 insertions(+)

diff --git a/docs/standardization/cpp20.md b/docs/standardization/cpp20.md
index 36a1b6d..4e36147 100644
--- a/docs/standardization/cpp20.md
+++ b/docs/standardization/cpp20.md
@@ -201,6 +201,202 @@ int main()
 
 ```
 
+### 定数式で仮想関数呼び出しが可能に [(P1064R0)](https://wg21.link/P1064)
+従来の実行時の仮想関数呼び出しは、ポインタや参照を介してさえいればスタック領域にあるオブジェクトであっても呼び出し可能です。従って、仮想関数を呼び出すだけであれば`new`による動的確保や不正なポインタのキャストは必要なく、定数式でも実行可能であるはずです。  
+そのため、定数式で仮想関数呼び出しを禁止している制限は不要であるとして撤廃され、定数式でも仮想関数による動的ポリモーフィズムを利用可能になります。
+
+```C++
+struct cpp {
+  constexpr virtual unsigned int version() const = 0;
+};
+
+struct cpp17 : public cpp {
+  constexpr unsigned int version() const override {
+    return 17;
+  }
+};
+
+struct cpp20 : public cpp {
+  constexpr unsigned int version() const override {
+    return 20;
+  }
+};
+
+constexpr auto check_version(const cpp* a) {
+  return a->version();
+}
+
+int main()
+{
+  constexpr cpp17 c17{};
+  constexpr cpp20 c20{};
+  
+  constexpr auto ver1 = check_version(&c17);
+  constexpr auto ver2 = check_version(&c20);
+  
+  static_assert(ver1 == 17);
+  static_assert(ver2 == 20);
+  
+  std::cout << ver1 << std::endl;
+  std::cout << ver2 << std::endl;
+}
+```
+```
+17
+20
+```
+
+### 定数式でのRTTI [(P1327R1)](https://wg21.link/P1327)
+仮想関数呼び出しと同様に、`dynamic_cast`や`type_id`もポインタや参照を介してさえいればスタック領域にあるオブジェクトに対して行うことができます。また、型に対する`type_id`は定数実行できない理由がありません。  
+そのため、定数式で`dynamic_cast`や`type_id`を禁じていた制限もまた不要であるとして削除されます。
+
+また、この変更に伴って`std::type_info`の`operator==`と`operator!=`がconstexpr指定され定数式で使用可能になります。
+
+```C++
+#include <typeinfo>
+
+//組み込み型に対するtypeid
+{
+  constexpr auto&& int_t  = typeid(int);
+  constexpr auto&& char_t = typeid(char);
+
+  constexpr bool is_same = int_t == char_t;
+  static_assert(is_same == false);
+}
+
+struct base {
+  virtual int f() const = 0;
+};
+
+struct derived1 : public base {
+  constexpr int f() const override {
+    return 10;
+  }
+};
+
+struct derived2 : public base {
+  constexpr int f() const override {
+    return 20;
+  }
+};
+
+//polymorphicな型に対するtypeid
+{
+  constexpr derived1 d1{};
+  constexpr derived2 d2{};
+
+  constexpr auto&& b1_t = typeid(&d1);
+  constexpr auto&& b2_t = typeid(&d2);
+
+  constexpr bool is_same = b1_t == b2_t;
+  static_assert(is_same == false);
+}
+
+struct base2 {
+  virtual int g() const = 0;
+};
+
+struct derived3 : public base, public base2 {
+  constexpr int f() const override {
+    return 20;
+  }
+  
+  constexpr int g() const override {
+    return 30;
+  }
+};
+
+//dynamic_cast
+{
+  constexpr derived3 d{};
+  constexpr const base* b1 = &d;
+  //side cast
+  constexpr const base2 b2 = dynamic_cast<const base2*>(b1);
+}
+```
+
+ただし、`dynamic_cast`や`type_id`の定数実行が例外を投げる場合は定数式で実行できずにコンパイルエラーとなります。  
+例えば、`dynamic_cast`なら参照のキャスト失敗時、`type_id`は`nullptr`を渡されたときに例外を投げます。
+
+```C++
+//typeid
+{
+  constexpr int* nullp = nullptr;
+  constexpr auto&& t = typeid(nullp);  //例外を投げるため定数実行できない
+}
+
+//dynamic_cast
+{
+  constexpr derived1 d1{};
+  constexpr const base& b1 = d1;  //b1はderived1のオブジェクトを指す
+
+  //down cast
+  constexpr const derived2& d2 = dynamic_cast<const derived2&>(b1);  //例外を投げるため定数実行できない
+}
+```
+
+### 定数式での共用体アクティブメンバの切り替え [(P1330R0)](https://wg21.link/P1330)
+
+共用体のアクティブメンバとは、ある時点において最後に初期化されたメンバの事です。  
+共用体の構築と初期化及びアクティブメンバへのアクセスは定数式で行うことができますが、アクティブメンバの切り替えは行うことができませんでした。
+
+しかし、共用体は`std::string`や`std::optional`、`std::variant`の実装に利用されており、そこではアクティブメンバの切り替えが必要になります。  
+これらのクラスをよりconstexprで利用可能にするための準備として、定数式での共用体アクティブメンバの切り替えが許可されます。
+
+```C++
+union U {
+  int n;
+  double d = 3.1415;
+};
+
+constexpr double change_U() {
+  U u{};  //u.dをアクティブメンバとして初期化
+  double d = u.d;
+  u.n = 0;  //u.nへアクティブメンバを切り替え、C++20より可能
+  return d;
+}
+
+int main()
+{
+  constexpr double d = change_U();
+  static_assert(d == 3.1415);
+  
+  std::cout << d << std::endl;
+}
+```
+```
+3.1415
+```
+
+ただし、非アクティブメンバへのアクセスは未定義動作であり、定数式で行うとコンパイルエラーとなります。
+
+### 定数式における`try-catch`ブロック [(P1002R1)](https://wg21.link/P1002)
+
+これまではconstexpr関数の中などの定数式として実行されうる場所に`try-catch`ブロックを書くことができませんでした。  
+しかし、`std::vector`等のコンテナをconstexpr対応するにあたって`try-catch`ブロックが表れたとしても定数式として実行できるようにするために、`try-catch`ブロックを定数式内に書くことができるようになります。
+
+ただし、例外処理が定数式で行われるわけではなく、定数実行中に例外が投げられた場合はコンパイルエラーとなります。つまり、定数式における`try-catch`ブロックは単に無視されます。
+
+```cpp
+constexpr int f(const int n) {
+	try {
+		return n + 1;
+	} catch(...) {
+		return 0;
+	}
+}
+
+constexpr int g(const int n) {
+	try {
+		throw std::exception{};  //ここでコンパイルエラー
+	} catch (const std::exception& except) {
+		return 0;  //コンパイル時にここに来る事は無い
+	}
+}
+```
+
+C++20の仕様としては単に無視することにしただけで、将来的なコンパイル時例外処理のサポートへの道が閉ざされたわけではありません。
+
 
 ## 標準ライブラリ
 
@@ -549,3 +745,64 @@ size_type find(const T& t, size_type pos = 0) const noexcept(is_nothrow_converti
 ### `<complex>` ヘッダの関数の `constexpr` 対応を強化 [(P0415R1)](https://wg21.link/P0415R1)
 
 `<complex>` ヘッダが提供する関数のうち、複素数の四則演算、ノルムの取得、共役複素数の取得など、`constexpr` 非対応の数学関数 (sqrt など) を使わずに実装できるものが `constexpr` 化されます。
+
+### コンパイル時と実行時の判定を行う `std::is_constant_evaluated()` 関数 [(P0595R2)](https://wg21.link/P0595)
+
+C++17までは、あるコードが実行されているときにそれがコンパイル時と実行時のどちらで実行中なのかを判定する方法はありませんでした。
+その判断ができれば、コンパイル時と実行時それぞれで最適なアルゴリズム及びコードを選択して実行することができます。  
+特にこれは、`<cmath>`にある数学関数を`constexpr`で実装する際に必要となります。
+
+C++20では`<type_traits>`ヘッダに新たに追加される`std::is_constant_evaluated()`関数の利用によってそれが可能になります。  
+`std::is_constant_evaluated()`関数は確実にコンパイル時に評価される個所でだけ`true`を返し、その他の場合には`false`を返す関数です。
+
+例えば以下のように利用できます。
+
+```cpp
+#include <type_traits>
+#include <cmath>
+#include <iostream>
+
+template<typename T>
+constexpr auto my_sin(T theta) {
+  if (std::is_constant_evaluated()) {
+    //コンパイル時の処理、マクローリン級数の計算
+
+    auto fabs = [](T v) -> T { return (v < T(0.0))?(-v):(v); };
+    T x_sq = -(theta * theta);
+    T series = theta;
+    T tmp = theta;
+    T fact = T(2.0);
+
+    do {
+      tmp *= x_sq / (fact * (fact+T(1.0)));
+      series += tmp;
+      fact += T(2.0);
+    } while(fabs(tmp) >= std::numeric_limits<T>::epsilon());
+    
+    return series;
+  } else {
+    //実行時の処理、<cmath>の関数を利用
+    return std::sin(theta);
+  }
+}
+
+int main()
+{
+  constexpr double pi = 3.1415926535897932384626433832795;
+  
+  std::cout << std::setprecision(16);
+  
+  //sin(60°)を求める
+  constexpr auto sin_static = my_sin(pi/3.0); //コンパイル時計算
+  auto sin_dynamic = my_sin(pi/3.0);  //実行時計算
+  
+  std::cout << sin_static << std::endl;
+  std::cout << sin_dynamic << std::endl;
+}
+```
+```
+0.8660254037844385
+0.8660254037844386
+```
+
+`if constexpr`や`static_assert`の条件式では必ず`true`に評価されるので注意が必要です。
\ No newline at end of file
-- 
GitLab


From 8e304e02383f531d0acd145912da54cca9283f37 Mon Sep 17 00:00:00 2001
From: onihusube <44743040+onihusube@users.noreply.github.com>
Date: Wed, 22 May 2019 20:33:45 +0900
Subject: [PATCH 2/6] =?UTF-8?q?C++20=20=E3=81=AE=E6=96=B0=E6=A9=9F?=
 =?UTF-8?q?=E8=83=BD=20:=20typeid=E3=81=AB=E3=81=A4=E3=81=84=E3=81=A6?=
 =?UTF-8?q?=E4=BF=AE=E6=AD=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 docs/standardization/cpp20.md | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/docs/standardization/cpp20.md b/docs/standardization/cpp20.md
index 4e36147..c0c957b 100644
--- a/docs/standardization/cpp20.md
+++ b/docs/standardization/cpp20.md
@@ -247,23 +247,14 @@ int main()
 ```
 
 ### 定数式でのRTTI [(P1327R1)](https://wg21.link/P1327)
-仮想関数呼び出しと同様に、`dynamic_cast`や`type_id`もポインタや参照を介してさえいればスタック領域にあるオブジェクトに対して行うことができます。また、型に対する`type_id`は定数実行できない理由がありません。  
-そのため、定数式で`dynamic_cast`や`type_id`を禁じていた制限もまた不要であるとして削除されます。
+仮想関数呼び出しと同様に、`dynamic_cast`や`type_id`もポインタや参照を介してさえいればスタック領域にあるオブジェクトに対して行うことができます。  
+そのため、定数式で`dynamic_cast`や多態的なオブジェクトに対する`type_id`を禁じていた制限もまた不要であるとして削除されます。
 
 また、この変更に伴って`std::type_info`の`operator==`と`operator!=`がconstexpr指定され定数式で使用可能になります。
 
 ```C++
 #include <typeinfo>
 
-//組み込み型に対するtypeid
-{
-  constexpr auto&& int_t  = typeid(int);
-  constexpr auto&& char_t = typeid(char);
-
-  constexpr bool is_same = int_t == char_t;
-  static_assert(is_same == false);
-}
-
 struct base {
   virtual int f() const = 0;
 };
@@ -284,9 +275,12 @@ struct derived2 : public base {
 {
   constexpr derived1 d1{};
   constexpr derived2 d2{};
+  
+  constexpr base* b1 = &d1;
+  constexpr base* b2 = &d2;
 
-  constexpr auto&& b1_t = typeid(&d1);
-  constexpr auto&& b2_t = typeid(&d2);
+  constexpr auto&& b1_t = typeid(*b1);
+  constexpr auto&& b2_t = typeid(*b2);
 
   constexpr bool is_same = b1_t == b2_t;
   static_assert(is_same == false);
@@ -805,4 +799,4 @@ int main()
 0.8660254037844386
 ```
 
-`if constexpr`や`static_assert`の条件式では必ず`true`に評価されるので注意が必要です。
\ No newline at end of file
+`if constexpr`や`static_assert`の条件式では必ず`true`に評価されるので注意が必要です。
-- 
GitLab


From e9c849653451c5fb9cc6d5d4073394378be7a90c Mon Sep 17 00:00:00 2001
From: Ryo Suzuki <reputeless+github@gmail.com>
Date: Thu, 23 May 2019 12:34:08 +0900
Subject: [PATCH 3/6] Update [WIP]
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

文章のスタイル調整
---
 docs/standardization/cpp20.md | 212 +++++++++++++++-------------------
 1 file changed, 94 insertions(+), 118 deletions(-)

diff --git a/docs/standardization/cpp20.md b/docs/standardization/cpp20.md
index c0c957b..8411ff7 100644
--- a/docs/standardization/cpp20.md
+++ b/docs/standardization/cpp20.md
@@ -36,8 +36,8 @@ int main()
 15, 3, false
 ```
 
-### メンバポインタ演算子の仕様を一貫性のために修正 [(P0704R1)](http://wg21.link/p0704r1)
 
+### メンバポインタ演算子の仕様を一貫性のために修正 [(P0704R1)](http://wg21.link/p0704r1)
 C++17 までのメンバポインタ演算子 `.*` は「右辺値オブジェクトから、左辺値参照修飾されたメンバ関数ポインタに使うことは不適格」という規格文面になっていました。そのため、同じ意味をもつ次の 2 つのプログラムで後者だけ不適格とされ、一貫性がありませんでした。
 ```C++
 #include <iostream>
@@ -136,8 +136,8 @@ int main()
 }
 ```
 
-### 型名であることが明らかな文脈で `typename` を省略可能に [(P0634R3)](https://wg21.link/P0634R3)
 
+### 型名であることが明らかな文脈で `typename` を省略可能に [(P0634R3)](https://wg21.link/P0634R3)
 C++17 で依存名が型である場合に `typename` を付けないのは、派生クラス定義時の基底クラスの指定と、初期化子リストでの基底クラスの指定のみでした(厳密にはこの 2 つには `typename` を付けられません)。C++20 では、型名しか使えないさらにいくつかの文脈で `typename` が省略可能になります。次のサンプルコードの左右タブで比較できます。
 
 ```C++ tab="C++17"
@@ -166,7 +166,7 @@ template <class T> typename T::size_type MaxSize();
 
 int main()
 {
-    S<std::vector<std::string>> s;
+	S<std::vector<std::string>> s;
 }
 ```
 
@@ -201,141 +201,127 @@ int main()
 
 ```
 
-### 定数式で仮想関数呼び出しが可能に [(P1064R0)](https://wg21.link/P1064)
-従来の実行時の仮想関数呼び出しは、ポインタや参照を介してさえいればスタック領域にあるオブジェクトであっても呼び出し可能です。従って、仮想関数を呼び出すだけであれば`new`による動的確保や不正なポインタのキャストは必要なく、定数式でも実行可能であるはずです。  
-そのため、定数式で仮想関数呼び出しを禁止している制限は不要であるとして撤廃され、定数式でも仮想関数による動的ポリモーフィズムを利用可能になります。
+
+### 定数式での仮想関数呼び出しが可能に [(P1064R0)](https://wg21.link/P1064)
+コンパイル時に決定可能であれば、参照やポインタを通した仮想関数の呼び出しを `constexpr` にできるようになります。`constexpr` 修飾された仮想関数を非 `constexpr` 関数でオーバーライドすることや、その逆も可能です。
 
 ```C++
-struct cpp {
-  constexpr virtual unsigned int version() const = 0;
+struct Cpp
+{
+	virtual int version() const = 0;
 };
 
-struct cpp17 : public cpp {
-  constexpr unsigned int version() const override {
-    return 17;
-  }
+struct Cpp17 : Cpp
+{
+	constexpr int version() const override
+	{
+		return 17;
+	}
 };
 
-struct cpp20 : public cpp {
-  constexpr unsigned int version() const override {
-    return 20;
-  }
+struct Cpp20 : Cpp
+{
+	constexpr int version() const override
+	{
+		return 20;
+	}
 };
 
-constexpr auto check_version(const cpp* a) {
-  return a->version();
+constexpr int GetVersion(const Cpp& a)
+{
+	return a.version();
 }
 
 int main()
 {
-  constexpr cpp17 c17{};
-  constexpr cpp20 c20{};
-  
-  constexpr auto ver1 = check_version(&c17);
-  constexpr auto ver2 = check_version(&c20);
-  
-  static_assert(ver1 == 17);
-  static_assert(ver2 == 20);
-  
-  std::cout << ver1 << std::endl;
-  std::cout << ver2 << std::endl;
+	constexpr Cpp17 cpp17;
+	constexpr Cpp20 cpp20;
+
+	static_assert(GetVersion(cpp17) == 17);
+	static_assert(GetVersion(cpp20) == 20);
 }
 ```
-```
-17
-20
-```
 
-### 定数式でのRTTI [(P1327R1)](https://wg21.link/P1327)
-仮想関数呼び出しと同様に、`dynamic_cast`や`type_id`もポインタや参照を介してさえいればスタック領域にあるオブジェクトに対して行うことができます。  
-そのため、定数式で`dynamic_cast`や多態的なオブジェクトに対する`type_id`を禁じていた制限もまた不要であるとして削除されます。
 
-また、この変更に伴って`std::type_info`の`operator==`と`operator!=`がconstexpr指定され定数式で使用可能になります。
+### `type_id` と `dynamic_cast` が例外を投げない場合 constexpr に [(P1327R1)](https://wg21.link/P1327)
+`dynamic_cast` と `type_id` が、例外を投げるケースを除いて `constexpr` になります。
 
 ```C++
 #include <typeinfo>
 
-struct base {
-  virtual int f() const = 0;
+struct Cpp
+{
+	virtual int version() const = 0;
 };
 
-struct derived1 : public base {
-  constexpr int f() const override {
-    return 10;
-  }
+struct Cpp17 : Cpp
+{
+	constexpr int version() const override
+	{
+		return 17;
+	}
 };
 
-struct derived2 : public base {
-  constexpr int f() const override {
-    return 20;
-  }
+struct Cpp20 : Cpp
+{
+	constexpr int version() const override
+	{
+		return 20;
+	}
 };
 
-//polymorphicな型に対するtypeid
+int main()
 {
-  constexpr derived1 d1{};
-  constexpr derived2 d2{};
-  
-  constexpr base* b1 = &d1;
-  constexpr base* b2 = &d2;
+	constexpr static Cpp17 cpp17;
+	constexpr const Cpp* pCpp = &cpp17;
+	constexpr auto& cpptype = typeid(*pCpp);
 
-  constexpr auto&& b1_t = typeid(*b1);
-  constexpr auto&& b2_t = typeid(*b2);
-
-  constexpr bool is_same = b1_t == b2_t;
-  static_assert(is_same == false);
+	constexpr const Cpp& refCpp = cpp17;
+	constexpr const Cpp17& redCpp2 = dynamic_cast<const Cpp17&>(refCpp);
 }
+```
 
-struct base2 {
-  virtual int g() const = 0;
-};
+次のように例外を投げるケースでは `constexpr` にできずコンパイルエラーになります。
 
-struct derived3 : public base, public base2 {
-  constexpr int f() const override {
-    return 20;
-  }
-  
-  constexpr int g() const override {
-    return 30;
-  }
-};
+```C++
+#include <typeinfo>
 
-//dynamic_cast
+struct Cpp
 {
-  constexpr derived3 d{};
-  constexpr const base* b1 = &d;
-  //side cast
-  constexpr const base2 b2 = dynamic_cast<const base2*>(b1);
-}
-```
+	virtual int version() const = 0;
+};
 
-ただし、`dynamic_cast`や`type_id`の定数実行が例外を投げる場合は定数式で実行できずにコンパイルエラーとなります。  
-例えば、`dynamic_cast`なら参照のキャスト失敗時、`type_id`は`nullptr`を渡されたときに例外を投げます。
+struct Cpp17 : Cpp
+{
+	constexpr int version() const override
+	{
+		return 17;
+	}
+};
 
-```C++
-//typeid
+struct Cpp20 : Cpp
 {
-  constexpr int* nullp = nullptr;
-  constexpr auto&& t = typeid(nullp);  //例外を投げるため定数実行できない
-}
+	constexpr int version() const override
+	{
+		return 20;
+	}
+};
 
-//dynamic_cast
+int main()
 {
-  constexpr derived1 d1{};
-  constexpr const base& b1 = d1;  //b1はderived1のオブジェクトを指す
+	constexpr Cpp* pCpp = nullptr;
+	constexpr auto& cpptype = typeid(*pCpp); //コンパイルエラー: 例外 std::bad_typeid を投げるため constexpr 不可
 
-  //down cast
-  constexpr const derived2& d2 = dynamic_cast<const derived2&>(b1);  //例外を投げるため定数実行できない
+	constexpr static Cpp17 cpp17;
+	constexpr const Cpp& refCpp = cpp17;
+	constexpr const Cpp20& redCpp2 = dynamic_cast<const Cpp20&>(refCpp); // コンパイルエラー: 例外 std::bad_cast を投げるため constexpr 不可
 }
 ```
 
-### 定数式での共用体アクティブメンバの切り替え [(P1330R0)](https://wg21.link/P1330)
-
-共用体のアクティブメンバとは、ある時点において最後に初期化されたメンバの事です。  
-共用体の構築と初期化及びアクティブメンバへのアクセスは定数式で行うことができますが、アクティブメンバの切り替えは行うことができませんでした。
 
-しかし、共用体は`std::string`や`std::optional`、`std::variant`の実装に利用されており、そこではアクティブメンバの切り替えが必要になります。  
-これらのクラスをよりconstexprで利用可能にするための準備として、定数式での共用体アクティブメンバの切り替えが許可されます。
+### 定数式での共用体アクティブメンバの切り替えが可能に [(P1330R0)](https://wg21.link/P1330)
+共用体のアクティブメンバとは、ある時点において最後に初期化されたメンバの事です。C++17 では共用体の構築や初期化、アクティブメンバへのアクセスを定数式で行えましたが、アクティブメンバの切り替えできませんでした。  
+定数式でのアクティブメンバの切り替えが可能になると、共用体を使って実装される `std::string` や `std::optional`, `std::variant` のより多くの処理を `constexpr` 対応させることができます。
 
 ```C++
 union U {
@@ -362,14 +348,13 @@ int main()
 3.1415
 ```
 
-ただし、非アクティブメンバへのアクセスは未定義動作であり、定数式で行うとコンパイルエラーとなります。
+ただし、非アクティブメンバへのアクセスは未定義動作なので、定数式で行うとコンパイルエラーになります。
 
-### 定数式における`try-catch`ブロック [(P1002R1)](https://wg21.link/P1002)
 
-これまではconstexpr関数の中などの定数式として実行されうる場所に`try-catch`ブロックを書くことができませんでした。  
-しかし、`std::vector`等のコンテナをconstexpr対応するにあたって`try-catch`ブロックが表れたとしても定数式として実行できるようにするために、`try-catch`ブロックを定数式内に書くことができるようになります。
-
-ただし、例外処理が定数式で行われるわけではなく、定数実行中に例外が投げられた場合はコンパイルエラーとなります。つまり、定数式における`try-catch`ブロックは単に無視されます。
+### 定数式の文脈では `try-catch` を無視できるように [(P1002R1)](https://wg21.link/P1002)
+これまでは constexpr 関数の中などの定数式として実行されうる場所に `try-catch` ブロックを書くことができませんでした。  
+しかし、`std::vector` 等のコンテナを `constexpr` 対応するにあたって `try-catch` ブロックが表れたとしても定数式として実行できるようにするために、`try-catch` ブロックを定数式内に書くことができるようになります。  
+ただし、例外処理が定数式で行われるわけではなく、定数実行中に例外が投げられた場合はコンパイルエラーとなります。つまり、定数式における `try-catch` ブロックは単に無視されます。
 
 ```cpp
 constexpr int f(const int n) {
@@ -389,7 +374,7 @@ constexpr int g(const int n) {
 }
 ```
 
-C++20の仕様としては単に無視することにしただけで、将来的なコンパイル時例外処理のサポートへの道が閉ざされたわけではありません。
+C++20 の仕様としては単に無視することにしただけで、将来的なコンパイル時例外処理のサポートへの道が閉ざされたわけではありません。
 
 
 ## 標準ライブラリ
@@ -422,7 +407,6 @@ false
 
 
 ### `operator>>(basic_istream&, charT*)` の第二引数を `charT(&)[N]` に変更して安全に [(P0487R1)](https://wg21.link/P0487R1)
-
 C++17 までの `operator>>(basic_istream&, charT*)` は、関数にバッファのサイズが渡されないため、次のようなプログラムでバッファオーバーフローへの対策が必要でした。
 ```C++
 #include <iostream>
@@ -475,6 +459,7 @@ int main()
 }
 ```
 
+
 ### 戻り値の無視が不具合をもたらす関数に `[[nodiscard]]` を付与 [(P0600R1)](https://wg21.link/P0600R1)
 C++17 で導入された `[[nodiscard]]` 属性を標準ライブラリで活用するようになります。C++20 では付与基準を「戻り値の無視がトラブルやメモリリークなどの重大なエラーを引き起こす C++ の関数」とし、`async()`, `launder()`, `allocate()`, `empty()`, `operator new()` が対象となっています。
 ```C++
@@ -494,7 +479,6 @@ MSVC の標準ライブラリでは Visual Studio 2017 15.6 以降、規格の
 
 
 ### `<array>` ヘッダのすべての関数が constexpr に [(P1023R0)](https://wg21.link/P1023R0), [(P1032R1)](https://wg21.link/P1032R1)
-
 C++17 の `<array>` ヘッダでは、比較演算子、`swap()`, `fill()` 以外のすべての関数が constexpr でした。C++20 ではさらに、array の比較演算の実装に使われている `std::equal()` と `std::lexicographical_compare()` が [constexpr になった (P0202R3)](https://wg21.link/P0202R3) ことにともない、array の比較演算子を constexpr とし、また `swap()` と `fill()` についても constexpr にすることを決め、array ヘッダのすべての関数が constexpr で提供されます。
 
 
@@ -507,7 +491,6 @@ C++17 の `<array>` ヘッダでは、比較演算子、`swap()`, `fill()` 以
 
 
 ### ポインタのアライメントを最適化ヒントとしてコンパイラに伝える `assume_aligned()` 関数 [(P1007R3)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1007r3.pdf)
-
 データのアドレスが 16 バイトなどのサイズにアライメントされている場合、コンパイラが SIMD を使った最適なコードを生成できる可能性があります。あるポインタの指すデータがアライメントされていることをコンパイラに伝える方法として、GCC や Clang では `__builtin_assume_aligned()` や `__attribute__((assume_aligned(alignment)))`, ICC では `__assume_aligned()` などの独自拡張がありますが、標準化された方法はありませんでした。C++20 では、これらの差異を吸収する次のような関数テンプレートが提供されます。
 ```C++
 template <size_t N, class T>
@@ -528,7 +511,6 @@ void Multiply(float* x, size_t size, float factor)
 
 
 ### スマートポインタの作成時に値をデフォルト初期化する make 関数を追加 [(P1020R1)](https://wg21.link/P1020R1)
-
 実行時性能のために、`float` や `unsigned char` など組み込み型の配列の値をデフォルト初期化させたい(ゼロ初期化しない)ケースがあります。しかし、`make_unique` や `make_shared`, `allocate_shared` でスマートポインタを作成した場合には値初期化が実行されます。C++20 では、値初期化をせずにデフォルト初期化でスマートポインタを作成する関数 `make_unique_default_init`, `make_shared_default_init`, `allocate_shared_default_init` が追加されました。
 ```C++
 #include <iostream>
@@ -577,7 +559,6 @@ int main()
 
 
 ### 非順序連想コンテナのルックアップ操作で、`key_type` と比較可能な型を変換せずに使えるように [(P0919R3)](http://wg21.link/P0919r3)
-
 C++17 までの `unorderd_map` や `unordered_set` など非順序連想コンテナでは、`find()`, `count()`, `equal_range()` などルックアップを行うメンバ関数は引数に `key_type` をとり、例えば次のようなケースで `std::string` 型の一時オブジェクトが作成されて非効率でした。
 
 ```C++
@@ -622,7 +603,6 @@ int main()
 
 
 ### 非順序連想コンテナのルックアップ操作に、計算済みハッシュ値を渡せるように [(P0920R2)](https://wg21.link/P0920R2)
-
 同じ種類の非順序連想コンテナを複数扱い、同じキーを用いたルックアップ操作をそれらのコンテナに対して行うようなケースでは、キーのハッシュ値の計算を毎回行うのは冗長です。C++20 ではメンバ関数 `find()`, `count()`, `contains()`, `equal_range()` に、計算済みのハッシュ値を渡せるオーバーロードが追加されます。
 ```C++
 #include <iostream>
@@ -649,7 +629,6 @@ int main()
 
 
 ### 2 つの値の中点を計算する `std::midpoint()` 関数 [(P0811R3)](https://wg21.link/P0811R3)
-
 2 つの値 `a`, `b` の中点を計算する際に、単純な `(a + b) / 2` という式ではオーバーフローを起こす可能性があります。C++20 で追加される `std::midpoint()` 関数では、整数に対して
 ```C++
 constexpr Integer midpoint(Integer a, Integer b) noexcept
@@ -684,7 +663,6 @@ int main()
 
 
 ### 2 つの値の線形補間を計算する `std::lerp()` 関数 [(P0811R3)](https://wg21.link/P0811R3)
-
 2 点 `a`, `b` の間をパラメータ `t` によって線形補間する関数が提供されます。計算結果 `r` は `a + t * (b - a)` によって求められますが、実装により `isfinite(a) && isfinite(b)` のとき
 
 - `lerp(a, b, 0) == a && lerp(a, b, 1) == b`
@@ -712,7 +690,6 @@ int main()
 
 
 ### 実装固有の情報をまとめる `<version>` ヘッダを追加 [(P0754R2)](https://wg21.link/P0754R2)
-
 `__cpp_lib_byte`, `__cpp_lib_void_t` のような標準ライブラリの機能テストマクロ、その他ライブラリのバージョンや実装固有の情報をまとめる目的の `<version>` ヘッダが追加されました。
 例えば C++20 以前の MSVC の標準ライブラリでは、`<yvals_core.h>` という独自ヘッダに標準ライブラリの機能テストマクロがまとめられていましたが、C++20 以降ではあらゆる実装において、`<version>` ヘッダを見ることで、こうした実装固有の情報にアクセスできるため利便性が高まります。
 
@@ -733,21 +710,20 @@ size_type find(const T& t, size_type pos = 0) const noexcept(is_nothrow_converti
 ```
 
 ### ポインタライクなオブジェクトからアドレスを取得する `std::to_address()` 関数 [(P0653R2)](https://wg21.link/P0653R2)
-
 ポインタライクなオブジェクトを引数にとり、それが表すのと同じアドレスを生ポインタで返す関数 `std::to_address(p)` が追加されます。オブジェクトがポインタ型の場合はその値を返し、それ以外の場合、`std::pointer_traits<Ptr>::to_address(p)` の特殊化が定義されていて使えればその戻り値を、そうでない場合は `std::to_address(p.operator->())` の戻り値を返します。
 
-### `<complex>` ヘッダの関数の `constexpr` 対応を強化 [(P0415R1)](https://wg21.link/P0415R1)
 
+### `<complex>` ヘッダの関数の `constexpr` 対応を強化 [(P0415R1)](https://wg21.link/P0415R1)
 `<complex>` ヘッダが提供する関数のうち、複素数の四則演算、ノルムの取得、共役複素数の取得など、`constexpr` 非対応の数学関数 (sqrt など) を使わずに実装できるものが `constexpr` 化されます。
 
-### コンパイル時と実行時の判定を行う `std::is_constant_evaluated()` 関数 [(P0595R2)](https://wg21.link/P0595)
 
-C++17までは、あるコードが実行されているときにそれがコンパイル時と実行時のどちらで実行中なのかを判定する方法はありませんでした。
+### コンパイル時処理と実行時処理を分けられる `std::is_constant_evaluated()` 関数 [(P0595R2)](https://wg21.link/P0595)
+C++17 までは、あるコードが実行されているときにそれがコンパイル時と実行時のどちらで実行中なのかを判定する方法はありませんでした。
 その判断ができれば、コンパイル時と実行時それぞれで最適なアルゴリズム及びコードを選択して実行することができます。  
-特にこれは、`<cmath>`にある数学関数を`constexpr`で実装する際に必要となります。
+特にこれは、`<cmath>` にある数学関数を `constexpr` で実装する際に必要となります。
 
-C++20では`<type_traits>`ヘッダに新たに追加される`std::is_constant_evaluated()`関数の利用によってそれが可能になります。  
-`std::is_constant_evaluated()`関数は確実にコンパイル時に評価される個所でだけ`true`を返し、その他の場合には`false`を返す関数です。
+C++20 では `<type_traits>` ヘッダに新たに追加される `std::is_constant_evaluated()` 関数の利用によってそれが可能になります。  
+`std::is_constant_evaluated()` 関数は確実にコンパイル時に評価される個所でだけ `true` を返し、その他の場合には `false` を返す関数です。
 
 例えば以下のように利用できます。
 
-- 
GitLab


From 83ca9801ce1a9826944213ed98a1c66a12da479d Mon Sep 17 00:00:00 2001
From: Ryo Suzuki <reputeless+github@gmail.com>
Date: Thu, 23 May 2019 16:03:49 +0900
Subject: [PATCH 4/6] Update [WIP]
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

文章のスタイルを調整
---
 docs/standardization/cpp20.md | 97 +++++++++++++++++++----------------
 1 file changed, 52 insertions(+), 45 deletions(-)

diff --git a/docs/standardization/cpp20.md b/docs/standardization/cpp20.md
index 8411ff7..d5afa43 100644
--- a/docs/standardization/cpp20.md
+++ b/docs/standardization/cpp20.md
@@ -320,61 +320,75 @@ int main()
 
 
 ### 定数式での共用体アクティブメンバの切り替えが可能に [(P1330R0)](https://wg21.link/P1330)
-共用体のアクティブメンバとは、ある時点において最後に初期化されたメンバの事です。C++17 では共用体の構築や初期化、アクティブメンバへのアクセスを定数式で行えましたが、アクティブメンバの切り替えできませんでした。  
-定数式でのアクティブメンバの切り替えが可能になると、共用体を使って実装される `std::string` や `std::optional`, `std::variant` のより多くの処理を `constexpr` 対応させることができます。
+共用体において、最後に初期化または値が代入されたメンバがアクティブメンバです。C++17 では共用体の初期化やアクティブメンバへのアクセスを定数式で行えましたが、アクティブメンバの切り替えはできませんでした。定数式でのアクティブメンバの切り替えが可能になると、共用体によって実装される `std::string` や `std::optional` などの標準ライブラリクラスの、より多くのメンバ関数を `constexpr` 対応させることにつながります。非アクティブメンバへのアクセスは未定義動作なので、定数式で行うとコンパイルエラーになります。
 
 ```C++
-union U {
-  int n;
-  double d = 3.1415;
+#include <cstdint>
+
+union Value
+{
+	float f;
+	std::uint32_t i;
 };
 
-constexpr double change_U() {
-  U u{};  //u.dをアクティブメンバとして初期化
-  double d = u.d;
-  u.n = 0;  //u.nへアクティブメンバを切り替え、C++20より可能
-  return d;
+constexpr Value GetFloat(float x)
+{
+	return Value{ x }; // value.f がアクティブメンバ
+}
+
+constexpr Value GetUint(std::uint32_t x)
+{
+	Value value = GetFloat(0.0f); // value.f がアクティブメンバ
+	value.i = x; // value.i がアクティブメンバに
+	return value;
 }
 
 int main()
 {
-  constexpr double d = change_U();
-  static_assert(d == 3.1415);
-  
-  std::cout << d << std::endl;
+	static_assert(GetUint(123).i == 123);
 }
 ```
-```
-3.1415
-```
-
-ただし、非アクティブメンバへのアクセスは未定義動作なので、定数式で行うとコンパイルエラーになります。
 
 
-### 定数式の文脈では `try-catch` を無視できるように [(P1002R1)](https://wg21.link/P1002)
-これまでは constexpr 関数の中などの定数式として実行されうる場所に `try-catch` ブロックを書くことができませんでした。  
-しかし、`std::vector` 等のコンテナを `constexpr` 対応するにあたって `try-catch` ブロックが表れたとしても定数式として実行できるようにするために、`try-catch` ブロックを定数式内に書くことができるようになります。  
-ただし、例外処理が定数式で行われるわけではなく、定数実行中に例外が投げられた場合はコンパイルエラーとなります。つまり、定数式における `try-catch` ブロックは単に無視されます。
+### 定数式の文脈では `try-catch` を無視するように [(P1002R1)](https://wg21.link/P1002)
+これまで `constexpr` 関数の中には `try-catch` ブロックを書くことができませんでした。しかし、`std::vector` 等のコンテナを `constexpr` 対応するにあたっては、この制限が障壁となるため、C++20 では `constexpr` 関数の中の `try-catch` は、定数式として評価されるときには無視するよう仕様が改められます。定数式の評価中に例外を投げるようであればコンパイルエラーになります。`std::vector` などを `constexpr` 対応させるための措置で、将来の C++ におけるコンパイル時例外処理の実現を否定するものではありません。
 
 ```cpp
-constexpr int f(const int n) {
-	try {
-		return n + 1;
-	} catch(...) {
-		return 0;
+#include <cstdint> 
+#include <iostream> 
+#include <exception> 
+
+constexpr std::uint32_t AddU8(std::uint32_t a, std::uint32_t b)
+{
+	if ((a + b) >= 256)
+	{
+		throw std::exception{};
 	}
+
+	return a + b;
 }
 
-constexpr int g(const int n) {
-	try {
-		throw std::exception{};  //ここでコンパイルエラー
-	} catch (const std::exception& except) {
-		return 0;  //コンパイル時にここに来る事は無い
+constexpr std::uint32_t DoubleU8(std::uint32_t n)
+{
+	try
+	{
+		return AddU8(n, n);
+	}
+	catch (const std::exception& except)
+	{
+		return 0;
 	}
 }
-```
 
-C++20 の仕様としては単に無視することにしただけで、将来的なコンパイル時例外処理のサポートへの道が閉ざされたわけではありません。
+int main()
+{
+	static_assert(DoubleU8(123) == 246); // OK: 例外を投げずに定数式として評価可能
+
+	//static_assert(DoubleU8(200) > 0); // コンパイルエラー: 定数式として評価される constexpr 関数内で例外を投げるため
+
+	std::cout << "result: " << DoubleU8(200) << '\n'; // OK: 実行時に評価される関数で例外が発生する
+}
+```
 
 
 ## 標準ライブラリ
@@ -717,15 +731,8 @@ size_type find(const T& t, size_type pos = 0) const noexcept(is_nothrow_converti
 `<complex>` ヘッダが提供する関数のうち、複素数の四則演算、ノルムの取得、共役複素数の取得など、`constexpr` 非対応の数学関数 (sqrt など) を使わずに実装できるものが `constexpr` 化されます。
 
 
-### コンパイル時処理と実行時処理を分けられる `std::is_constant_evaluated()` 関数 [(P0595R2)](https://wg21.link/P0595)
-C++17 までは、あるコードが実行されているときにそれがコンパイル時と実行時のどちらで実行中なのかを判定する方法はありませんでした。
-その判断ができれば、コンパイル時と実行時それぞれで最適なアルゴリズム及びコードを選択して実行することができます。  
-特にこれは、`<cmath>` にある数学関数を `constexpr` で実装する際に必要となります。
-
-C++20 では `<type_traits>` ヘッダに新たに追加される `std::is_constant_evaluated()` 関数の利用によってそれが可能になります。  
-`std::is_constant_evaluated()` 関数は確実にコンパイル時に評価される個所でだけ `true` を返し、その他の場合には `false` を返す関数です。
-
-例えば以下のように利用できます。
+### コンパイル時処理と実行時処理を判別できる `std::is_constant_evaluated()` 関数 [(P0595R2)](https://wg21.link/P0595)
+C++17 までは、実行するコードを、コンパイル時評価か実行時評価かに応じて使い分ける方法はありませんでした。C++20 で `<type_traits>` ヘッダに追加される `std::is_constant_evaluated()` 関数は、コンパイル時評価されている文脈では `true` を、それ以外の場合では `false` を返します。これを例えば数学関数で使うことで、コンパイル時評価では `constexpr` 版の実装を、実行時には非 `constexpr` の標準ライブラリの実装を実行するよう選択させることができます。`std::is_constant_evaluated()` を `if constexpr` の `( )` 内や `static_assert` 内で使うと常に `true` に評価されてしまうので注意が必要です。基本的には `if (std::is_constant_evaluated())` と書きます。
 
 ```cpp
 #include <type_traits>
@@ -775,4 +782,4 @@ int main()
 0.8660254037844386
 ```
 
-`if constexpr`や`static_assert`の条件式では必ず`true`に評価されるので注意が必要です。
+
-- 
GitLab


From 0be280dbd360bf89bc441473aa2acd8e2ab01dc4 Mon Sep 17 00:00:00 2001
From: Ryo Suzuki <reputeless+github@gmail.com>
Date: Thu, 23 May 2019 16:51:32 +0900
Subject: [PATCH 5/6] Update cpp20.md

---
 docs/standardization/cpp20.md | 73 ++++++++++++++++-------------------
 1 file changed, 33 insertions(+), 40 deletions(-)

diff --git a/docs/standardization/cpp20.md b/docs/standardization/cpp20.md
index d5afa43..ea55884 100644
--- a/docs/standardization/cpp20.md
+++ b/docs/standardization/cpp20.md
@@ -320,7 +320,7 @@ int main()
 
 
 ### 定数式での共用体アクティブメンバの切り替えが可能に [(P1330R0)](https://wg21.link/P1330)
-共用体において、最後に初期化または値が代入されたメンバがアクティブメンバです。C++17 では共用体の初期化やアクティブメンバへのアクセスを定数式で行えましたが、アクティブメンバの切り替えはできませんでした。定数式でのアクティブメンバの切り替えが可能になると、共用体によって実装される `std::string` や `std::optional` などの標準ライブラリクラスの、より多くのメンバ関数を `constexpr` 対応させることにつながります。非アクティブメンバへのアクセスは未定義動作なので、定数式で行うとコンパイルエラーになります。
+共用体のアクティブメンバとは、最後に初期化または値を代入したメンバのことです。C++17 では共用体の初期化やアクティブメンバへのアクセスを定数式で行えましたが、アクティブメンバの切り替えはできませんでした。定数式でのアクティブメンバの切り替えが可能になると、共用体によって実装される `std::string` や `std::optional` などの標準ライブラリクラスのメンバ関数の `constexpr` 対応を拡充できます。非アクティブメンバへのアクセスは未定義動作なので、定数式で行うとコンパイルエラーになります。
 
 ```C++
 #include <cstdint>
@@ -351,7 +351,7 @@ int main()
 
 
 ### 定数式の文脈では `try-catch` を無視するように [(P1002R1)](https://wg21.link/P1002)
-これまで `constexpr` 関数の中には `try-catch` ブロックを書くことができませんでした。しかし、`std::vector` 等のコンテナを `constexpr` 対応するにあたっては、この制限が障壁となるため、C++20 では `constexpr` 関数の中の `try-catch` は、定数式として評価されるときには無視するよう仕様が改められます。定数式の評価中に例外を投げるようであればコンパイルエラーになります。`std::vector` などを `constexpr` 対応させるための措置で、将来の C++ におけるコンパイル時例外処理の実現を否定するものではありません。
+これまで `constexpr` 関数の中には `try-catch` ブロックを書くことができませんでした。しかし、`std::vector` 等のコンテナを `constexpr` 対応するにあたっては、この制限が障壁となるため、C++20 では `constexpr` 関数の中の `try-catch` は、定数式として評価されるときには無視するよう仕様が改められます。定数式の評価中に例外を投げるようであればコンパイルエラーになります。`std::vector` などを `constexpr` 対応させるための措置であり、将来の C++ におけるコンパイル時例外処理の実現を否定するものではありません。
 
 ```cpp
 #include <cstdint> 
@@ -731,55 +731,48 @@ size_type find(const T& t, size_type pos = 0) const noexcept(is_nothrow_converti
 `<complex>` ヘッダが提供する関数のうち、複素数の四則演算、ノルムの取得、共役複素数の取得など、`constexpr` 非対応の数学関数 (sqrt など) を使わずに実装できるものが `constexpr` 化されます。
 
 
-### コンパイル時処理と実行時処理を判別できる `std::is_constant_evaluated()` 関数 [(P0595R2)](https://wg21.link/P0595)
-C++17 までは、実行するコードを、コンパイル時評価か実行時評価かに応じて使い分ける方法はありませんでした。C++20 で `<type_traits>` ヘッダに追加される `std::is_constant_evaluated()` 関数は、コンパイル時評価されている文脈では `true` を、それ以外の場合では `false` を返します。これを例えば数学関数で使うことで、コンパイル時評価では `constexpr` 版の実装を、実行時には非 `constexpr` の標準ライブラリの実装を実行するよう選択させることができます。`std::is_constant_evaluated()` を `if constexpr` の `( )` 内や `static_assert` 内で使うと常に `true` に評価されてしまうので注意が必要です。基本的には `if (std::is_constant_evaluated())` と書きます。
+### コンパイル時評価の文脈か実行時評価の文脈かを判別できる `std::is_constant_evaluated()` 関数 [(P0595R2)](https://wg21.link/P0595)
+C++17 までは、実行するコードを、コンパイル時評価か実行時評価かに応じて使い分ける方法はありませんでした。C++20 では、コンパイル時評価されている文脈では `true` を、それ以外の場合では `false` を返す `std::is_constant_evaluated()` 関数が `<type_traits>` ヘッダに追加されます。例えば標準ライブラリで `constexpr` 対応していないような数学関数を提供する際、コンパイル時評価では `constexpr` 版の実装を、実行時には非 `constexpr` の標準ライブラリの実装を実行するよう選択させることができます。なお、`std::is_constant_evaluated()` を `if constexpr` の `( )` 内や `static_assert` 内で使うと常に `true` に評価されてしまうので注意が必要です。基本的には `if (std::is_constant_evaluated())` と書きます。
 
 ```cpp
-#include <type_traits>
 #include <cmath>
+#include <type_traits>
 #include <iostream>
+#include <iomanip>
 
-template<typename T>
-constexpr auto my_sin(T theta) {
-  if (std::is_constant_evaluated()) {
-    //コンパイル時の処理、マクローリン級数の計算
-
-    auto fabs = [](T v) -> T { return (v < T(0.0))?(-v):(v); };
-    T x_sq = -(theta * theta);
-    T series = theta;
-    T tmp = theta;
-    T fact = T(2.0);
-
-    do {
-      tmp *= x_sq / (fact * (fact+T(1.0)));
-      series += tmp;
-      fact += T(2.0);
-    } while(fabs(tmp) >= std::numeric_limits<T>::epsilon());
-    
-    return series;
-  } else {
-    //実行時の処理、<cmath>の関数を利用
-    return std::sin(theta);
-  }
+constexpr float Sin_impl(float x2, int i, int k, float xn, long long nf)
+{
+	return (i > 10) ? 0.0f : (k * xn / nf + Sin_impl(x2, i + 2, -k, xn * x2, nf * (i + 1) * (i + 2)));
+}
+
+constexpr float Sin(float x)
+{
+	if (std::is_constant_evaluated())
+	{
+		return Sin_impl(x * x, 1, 1, x, 1);
+	}
+	else
+	{
+		return std::sin(x);
+	}
 }
 
 int main()
 {
-  constexpr double pi = 3.1415926535897932384626433832795;
-  
-  std::cout << std::setprecision(16);
-  
-  //sin(60°)を求める
-  constexpr auto sin_static = my_sin(pi/3.0); //コンパイル時計算
-  auto sin_dynamic = my_sin(pi/3.0);  //実行時計算
-  
-  std::cout << sin_static << std::endl;
-  std::cout << sin_dynamic << std::endl;
+	constexpr float Pi = 3.14159265f;
+	constexpr float theta = Pi / 4.0;
+
+	constexpr float x1 = Sin(theta); // コンパイル時計算	
+	float x2 = Sin(theta);  // 実行時計算
+
+	std::cout << std::setprecision(16);
+	std::cout << x1 << '\n';
+	std::cout << x2 << '\n';
 }
 ```
+出力
 ```
-0.8660254037844385
-0.8660254037844386
+0.7071068286895752
+0.7071067690849304
 ```
 
-
-- 
GitLab


From 4c9d31f8d678e4811003e9bef7880c50b77b058e Mon Sep 17 00:00:00 2001
From: Ryo Suzuki <reputeless+github@gmail.com>
Date: Thu, 23 May 2019 17:00:21 +0900
Subject: [PATCH 6/6] =?UTF-8?q?=E6=96=87=E9=9D=A2=E8=AA=BF=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 docs/standardization/cpp20.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/docs/standardization/cpp20.md b/docs/standardization/cpp20.md
index ea55884..a22ffdf 100644
--- a/docs/standardization/cpp20.md
+++ b/docs/standardization/cpp20.md
@@ -243,7 +243,7 @@ int main()
 ```
 
 
-### `type_id` と `dynamic_cast` が例外を投げない場合 constexpr に [(P1327R1)](https://wg21.link/P1327)
+### `type_id` と `dynamic_cast` が constexpr に [(P1327R1)](https://wg21.link/P1327)
 `dynamic_cast` と `type_id` が、例外を投げるケースを除いて `constexpr` になります。
 
 ```C++
@@ -319,7 +319,7 @@ int main()
 ```
 
 
-### 定数式での共用体アクティブメンバの切り替えが可能に [(P1330R0)](https://wg21.link/P1330)
+### 定数式において共用体のアクティブメンバの切り替えが可能に [(P1330R0)](https://wg21.link/P1330)
 共用体のアクティブメンバとは、最後に初期化または値を代入したメンバのことです。C++17 では共用体の初期化やアクティブメンバへのアクセスを定数式で行えましたが、アクティブメンバの切り替えはできませんでした。定数式でのアクティブメンバの切り替えが可能になると、共用体によって実装される `std::string` や `std::optional` などの標準ライブラリクラスのメンバ関数の `constexpr` 対応を拡充できます。非アクティブメンバへのアクセスは未定義動作なので、定数式で行うとコンパイルエラーになります。
 
 ```C++
@@ -732,7 +732,7 @@ size_type find(const T& t, size_type pos = 0) const noexcept(is_nothrow_converti
 
 
 ### コンパイル時評価の文脈か実行時評価の文脈かを判別できる `std::is_constant_evaluated()` 関数 [(P0595R2)](https://wg21.link/P0595)
-C++17 までは、実行するコードを、コンパイル時評価か実行時評価かに応じて使い分ける方法はありませんでした。C++20 では、コンパイル時評価されている文脈では `true` を、それ以外の場合では `false` を返す `std::is_constant_evaluated()` 関数が `<type_traits>` ヘッダに追加されます。例えば標準ライブラリで `constexpr` 対応していないような数学関数を提供する際、コンパイル時評価では `constexpr` 版の実装を、実行時には非 `constexpr` の標準ライブラリの実装を実行するよう選択させることができます。なお、`std::is_constant_evaluated()` を `if constexpr` の `( )` 内や `static_assert` 内で使うと常に `true` に評価されてしまうので注意が必要です。基本的には `if (std::is_constant_evaluated())` と書きます。
+C++17 までは、実行するコードを、コンパイル時評価か実行時評価かに応じて使い分ける方法はありませんでした。C++20 では、コンパイル時評価されている文脈では `true` を、それ以外の場合では `false` を返す `std::is_constant_evaluated()` 関数が `<type_traits>` ヘッダに追加されます。例えば標準ライブラリで `constexpr` 対応していないような数学関数を提供する際、コンパイル時評価では `constexpr` 版の実装を、実行時には非 `constexpr` の標準ライブラリの実装を提供するよう選択させることができます。なお、`std::is_constant_evaluated()` を `if constexpr` の `( )` 内や `static_assert` 内で使うと常に `true` に評価されてしまうので注意が必要です。基本的には `if (std::is_constant_evaluated())` と書きます。
 
 ```cpp
 #include <cmath>
-- 
GitLab