Macでstdc++.hを用いてC++プログラムを実行したい！

#1. なぜMacでstdc++.hを用いてC++プログラムを実行したい！と思ったのか

C++で簡単な数値計算プログラムを書けるようになりたいなあという思いで、AtCoder公式コンテンツである[AtCoder Programming Guide for beginners (APG4b)](https://atcoder.jp/contests/APG4b)の学習を始めました。
この教材では、`#include < bits/stdc++.h>`をプログラムの１行目に記述するよう推奨しています。これにより、全てのヘッダーファイルをインクルード出来るようです。
APG4bではページ上でプログラムを実行出来たのですが、自分で作ったプログラムをローカルでも実行出来るようにしたいと思いました。
しかし、特に何も設定していないMacではエラーが出たのでいろいろ調べました。調べた結果得た方法を本稿ではまとめています。

#2. gccの準備

gccで実行します。理由はAPG4bがC++14(GCC 5.4.1)という言語を指定していたのと、大学でC言語をちょろっと学んだときgccだったからです。他にclangというのもあるらしいです。

まず、デフォルトのMacにはgccが無いか、バージョンが古いか、何か問題があったような気がします。Xcode、Homebrew、gccなどをキーワードになんとかgccをインストールしてほしいです。「mac gcc」などと検索すれば出てきます。（Xcodeのインストールはとても時間がかかった記憶がします。5〜10GBくらい？）
ターミナルを開いて`gcc --version`と入力して、以下のようになれば僕と一緒です。

```
~ $ gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
```

#3. まずは実行してみよう

この時点でまず実行しようと試みました。ちなみに使用したファイル`gcd_lcm.cpp`は入力2数に対する最大公約数(gcd)と最小公倍数(lcm)を出力する簡単なプログラムです。

```gcd_lcm.cpp
#include <bits/stdc++.h>
using namespace std;

// a > bが前提
int gcd(int a, int b){
   if (a % b == 0){
       return b;
   } else {
       return gcd(b, a % b);
   }
}

int lcm(int a, int b){
   return a * b / gcd(a, b);
}

int main(){
   int a, b;
   cin >> a >> b;

   cout << "最大公約数:" << gcd(a, b) << endl;
   cout << "最小公倍数:" << lcm(a, b) << endl;
}
```

cではgccですが、cppでは.oから.exeを作成するときgccではエラーが出ます。g++で行います。

```
$ g++ -c gcd_lcm.cpp 
gcd_lcm.cpp:1:10: fatal error: 'bits/stdc++.h' file not found
#include <bits/stdc++.h>
         ^~~~~~~~~~~~~~~
1 error generated.
```
無事エラーが出ました。stdc++.hというヘッダーファイルなんて存在しないよ！って意味でしょう。

# 4.stdc++.hを作成

ついに本題！簡単です！
1. Finderを開きます。
2. command + shift + gを押します。
3. `/usr/local/include`と入力してincludeフォルダに移動します。
4. includeフォルダ内にbitsという名前の新規フォルダを作成します。
5. stdc++.hを作成し、bitsの中に入れます。

以上で完成です！stdc++.hの中身は[https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a01040_source.html](https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a01040_source.html)を参考というか写しました。
リンク先を直接コピーすると行数も一緒にコピペされ、そのままではエラーとなるので注意が必要です。

```stdc++.h
// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#endif

// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif
```

# 5.改めて実行

再びターミナル上でgcd_lcm.cppファイルがあるフォルダに移動します。1行目で.cppから.oを作成し、2行目で.oから実行ファイルgcd_lcmを作成、3行目で実行ファイルを実行しています。

```
$ g++ -c gcd_lcm.cpp 
$ g++ -o gcd_lcm gcd_lcm.o
$ ./gcd_lcm 
6
9
最大公約数:3
最小公倍数:18
```
エラーが出ることもなく、無事入力6と9に対する最大公約数3と最小公倍数18が出力されました！