Upgrade to Pro — share decks privately, control downloads, hide ads and more …

みんな代替トークン使とる。使てへんのお前だけ。 / alternative tokens

みんな代替トークン使とる。使てへんのお前だけ。 / alternative tokens

C++MIX #7 の発表資料です。

Miutsuru kariya

January 29, 2020
Tweet

More Decks by Miutsuru kariya

Other Decks in Programming

Transcript

  1. 代替トークンとは? 代替 本来 代替 本来 代替 本来 <% { and

    && xor ^ %> } bitand & xor_eq ^= <: [ and_eq &= not ! :> ] or || not_eq != %: # bitor | compl ~ %:%: ## or_eq |= 5 見ての通り、必ずしも「ダイ」(2文字)ではなく、 キーワード型の物も結構ある。 これらの名前も予約語なので、例えば and や or と言った関数名や変数名は使えない。 ダ イ グ ラ フ で は な い 。 代 替 ト ー ク ン と 呼 べ 。
  2. 代替トークンとは? 代替 本来 代替 本来 代替 本来 <% { and

    && xor ^ %> } bitand & xor_eq ^= <: [ and_eq &= not ! :> ] or || not_eq != %: # bitor | compl ~ %:%: ## or_eq |= 6 なお、「トークン」と名前がついている通り、コンパイラが ソースをトークン化する際に処理されるので、文字列中 や他の識別子中では代替トークンとはみなされない。 まぁ当たり前っちゃあ当たり前なんだけど…
  3. 使用例 使用前 #include <iostream> int main() { int a[] =

    { 114, 514, }; for (int i = 0; i < 2; ++i) { std::cout << a[i] << ", "; } std::cout << '\n'; } 8
  4. 使用例 使用後 %:include <iostream> int main() <% int a<::> =

    <% 114, 514, %>; for (int i = 0; i < 2; ++i) <% std::cout << a<:i:> << ", "; %> std::cout << '\n'; %> 9
  5. 使用例 使用後 %:include <iostream> int main() <% int a<::> =

    <% 114, 514, %>; for (int i = 0; i < 2; ++i) <% std::cout << a<:i:> << ", "; %> std::cout << '\n'; %> 10 読みやすい! (異論は認める)
  6. 使用例 使用前 template <class InputIterator, class Predicate> bool all_of(InputIterator first,

    InputIterator last, Predicate pred) { for (; first != last; ++first) if (!pred(*first)) return false; return true; } 13 否定演算子が 見づらい!
  7. 使用例 使用後 template <class InputIterator, class Predicate> bool all_of(InputIterator first,

    InputIterator last, Predicate pred) { for (; first != last; ++first) if (not pred(*first)) return false; return true; } 14 否定演算子が 見やすい! (異論は認めない)
  8. ビット反転演算子が 見づらい! 使用例 使用前 const result_type Yp = (x[i] &

    ~mask) | (x[j] & mask); const size_t k = (i + m) % n; x[i] = x[k] ^ rshift<1>(Yp) ^ (a * (Yp & 1)); result_type z = x[i] ^ (rshift<u>(x[i]) & d); i = j; z ^= lshift<s>(z) & b; z ^= lshift<t>(z) & c; return z ^ rshift<l>(z); 16
  9. ビット反転演算子が 見やすい! (異論は認める) 使用例 使用後 const result_type Yp = (x[i]

    & compl mask) | (x[j] & mask); const size_t k = (i + m) % n; x[i] = x[k] ^ rshift<1>(Yp) ^ (a * (Yp & 1)); result_type z = x[i] ^ (rshift<u>(x[i]) & d); i = j; z ^= lshift<s>(z) & b; z ^= lshift<t>(z) & c; return z ^ rshift<l>(z); 17
  10. 使用例 使用後(過激派) const result_type Yp = (x<:i:> bitand compl mask)

    bitor (x<:j:> bitand mask); const size_t k = (i + m) % n; X<:i:> = x<:k:> xor rshift<1>(Yp) xor (a * (Yp bitand 1)); result_type z = x<:i:> xor (rshift<u>(x<:i:>) bitand d); i = j; z xor_eq lshift<s>(z) bitand b; z xor_eq lshift<t>(z) bitand c; return z xor rshift<l>(z); 18
  11. 何もかもが 見やすい! (異論は認める) 使用例 使用後(過激派) const result_type Yp = (x<:i:>

    bitand compl mask) bitor (x<:j:> bitand mask); const size_t k = (i + m) % n; X<:i:> = x<:k:> xor rshift<1>(Yp) xor (a * (Yp bitand 1)); result_type z = x<:i:> xor (rshift<u>(x<:i:>) bitand d); i = j; z xor_eq lshift<s>(z) bitand b; z xor_eq lshift<t>(z) bitand c; return z xor rshift<l>(z); 19
  12. 使用例 使用前 template <class InputIterator1, class InputIterator2, class BinaryPredicate> pair<InputIterator1,

    InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred) { for (; first1 != last1 && first2 != last2; ++first1, ++first2) if (!pred(*first1, *first2)) break; return pair<InputIterator1, InputIterator2>(first1, first2); } 20
  13. 使用例 使用後 template <class InputIterator1, class InputIterator2, class BinaryPredicate> pair<InputIterator1,

    InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred) { for (; first1 != last1 and first2 != last2; ++first1, ++first2) if (not pred(*first1, *first2)) break; return pair<InputIterator1, InputIterator2>(first1, first2); } 21
  14. 使用例 使用前 struct S { S() = default; S(const S&)

    = default; S(S&&) = default; ~S() = default; }; 23 まっ、まさか…
  15. 使用例 使用後 struct S <% S() = default; S(const S

    bitand) = default; S(S and) = default; compl S() = default; %>; 24 まっ、まさか… そのまさかだ、フハ ハハハハハハハ!
  16. 使用例 使用後 struct S <% S() = default; S(const S

    bitand) = default; S(S and) = default; compl S() = default; %>; 25 まっ、まさか… そのまさかだ、フハ ハハハハハハハ! スゴい! 参照もデストラクタも 見やすい!
  17. まっ、まさか… そのまさかだ、フハ ハハハハハハハ! 使用例 使用後 struct S <% S() =

    default; S(const S bitand) = default; S(S and) = default; compl S() = default; %>; 26 スゴい! 参照もデストラクタも 見やすい! ダメ!ゼッタイ!
  18. 蛇足① 使用前(再掲) #include <iostream> int main() { int a[] =

    { 114, 514, }; for (int i = 0; i < 2; ++i) { std::cout << a[i] << ", "; } std::cout << '\n'; } 30
  19. 蛇足① 使用後(トライグラフ) ??=include <iostream> int main() ??< int a??(??) =

    ??< 114, 514, ??>; for (int i = 0; i < 2; ++i) ??< std::cout << a??(i??) << ", "; ??> std::cout << '\n'; ??> 31
  20. 蛇足① 使用後(トライグラフ) ??=include <iostream> int main() ??< int a??(??) =

    ??< 114, 514, ??>; for (int i = 0; i < 2; ++i) ??< std::cout << a??(i??) << ", "; ??> std::cout << '\n'; ??> 実際某青いI社のメインフレームで見たときは正直キモかった…(個人の感想です) 32 読みづらい! (異論は認める)
  21. 蛇足➁ しかし、代替トークンに関連した以下のような例外がある。 “<::”の後ろに続く文字が“>”でも“:”でもなかった場合、 “<”と“::”と言う2つのトークンになる。 “<:” ⇒ “{” “<::” ⇒ “<”

    と “::” “<::>” ⇒ “{” と “}” “<:::” ⇒ “{” と “::” まぁ普通この規則に引っかかることはおそらく一生のうち1度も無いとは思う… 34
  22. 蛇足➂ C言語では、キーワード型の代替トークンは言語仕様ではな く、ヘッダで提供されている。 35 代替 本来 代替 本来 代替 本来

    <% { and && xor ^ %> } bitand & xor_eq ^= <: [ and_eq &= not ! :> ] or || not_eq != %: # bitor | compl ~ %:%: ## or_eq |= 言語仕様で提供 ヘッダiso646.hで提供