diff --git a/README.md b/README.md index d41522a..6b1547c 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,11 @@ docker run -it --rm chronolaw/cpp_study * [Bjarne Stroustrup's FAQ](http://www.stroustrup.com/bs_faq.html) * [Bjarne Stroustrup's C++11 FAQ](http://www.stroustrup.com/C++11FAQ.html) +* [Bjarne Stroustrup's C++ HOPL4 (zh-cn)](https://github.com/Cpp-Club/Cxx_HOPL4_zh) * [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines) * [OpenResty Code Style Guide(zh-cn)](http://openresty.org/cn/c-coding-style-guide.html) * [Google Code Style Guide](https://google.github.io/styleguide/cppguide.html) +* [ProtoBuffer C++ Doc](https://developers.google.com/protocol-buffers/docs/reference/cpp-generated) ## Dev Links diff --git a/docker/Dockerfile b/docker/Dockerfile index d217a8a..e141919 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -43,7 +43,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update \ google-perftools libgoogle-perftools-dev \ && pip3 install pybind11 \ && cd \ - && git clone https://github.com/chronolaw/cpp_study \ + && git clone https://github.com/chronolaw/cpp_study --depth=1 \ && cp ~/cpp_study/env/vimrc ~/.vimrc \ && cp ~/cpp_study/env/bashrc ~/.bashrc \ && cp ~/cpp_study/env/gitconfig ~/.gitconfig \ @@ -69,7 +69,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update \ && curl -fsL https://github.com/gperftools/gperftools/releases/download/gperftools-${GPERF_VERSION}/gperftools-${GPERF_VERSION}.tar.gz -o gperf.tgz \ && tar xfz gperf.tgz \ && ln -s ~/github/gperftools-${GPERF_VERSION}/pprof-symbolize /bin/pprof \ - && git clone https://github.com/brendangregg/FlameGraph.git \ + && git clone https://github.com/brendangregg/FlameGraph.git --depth=1 \ && ln -s ~/github/FlameGraph/flamegraph.pl ~/cpp_study/section4/ \ && rm *.tgz \ && DEBIAN_FRONTEND=noninteractive apt-get autoremove -y diff --git a/docker/Dockerfile.new b/docker/Dockerfile.new new file mode 100644 index 0000000..85b1bf1 --- /dev/null +++ b/docker/Dockerfile.new @@ -0,0 +1,22 @@ +# Dockerfile +# chrono@2021-03 + +# curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun +# sudo service docker start +# sudo usermod -aG docker ${USER} + +# docker build -t chronolaw/cpp_study . + +# docker run -it --rm chronolaw/cpp_study + +ARG SRC_IMAGE="gcc:7" + +FROM ${SRC_IMAGE} + +WORKDIR /root + +COPY setup.sh ./ + +RUN ./setup.sh && rm ./setup.sh + +CMD ["/bin/bash"] diff --git a/docker/cpp-study-pod.yml b/docker/cpp-study-pod.yml new file mode 100644 index 0000000..0d627b8 --- /dev/null +++ b/docker/cpp-study-pod.yml @@ -0,0 +1,32 @@ +# kubernetes pod yaml for cpp study +# you could run it in k8s/minikube/kind/... +# chrono @ 2021-03 + +# kubectl apply -f cpp-study-pod.yml +# kubectl delete -f cpp-study-pod.yml +# +# kubectl get pods +# kubectl exec -it k8s-cpp-study -- bash +# kubectl attach -it k8s-cpp-study + +apiVersion: v1 +kind: Pod + +metadata: + name: k8s-cpp-study + labels: + author: chrono + env: study + +spec: + + containers: + + - name: cpp-study + image: chronolaw/cpp_study + workingDir: /root/cpp_study + + # exec or attach into this container + stdin: true + tty: true + diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..4466347 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,24 @@ +# chrono 2021-03 +# +# docker-compose run --rm cpp_study +# +# docker ps +# docker exec -it xxx bash + +version: "3" + +services: + + cpp_study: + + image: chronolaw/cpp_study + + container_name: cpp_study + + working_dir: /root/cpp_study + + stdin_open: true + tty: true + + command: /bin/bash + diff --git a/docker/setup.sh b/docker/setup.sh new file mode 100755 index 0000000..35121d6 --- /dev/null +++ b/docker/setup.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +# chrono @ 2021-03 + +# apt-get +DEBIAN_FRONTEND=noninteractive apt-get install -y \ + vim cmake gdb pstack strace \ + libmsgpack-dev protobuf-compiler libprotobuf-dev libprotoc-dev \ + libcurl4-openssl-dev libzmq3-dev \ + python3-dev python3-pip \ + google-perftools libgoogle-perftools-dev + +DEBIAN_FRONTEND=noninteractive apt-get autoremove -y + +# python3 pybind11 +pip3 install pybind11 + +#WORKDIR='/root/' +#HOME='/root' + +# git source code +git clone https://github.com/chronolaw/cpp_study --depth=1 + +# setup env +cp ${HOME}/cpp_study/env/vimrc ${HOME}/.vimrc \ +cp ${HOME}/cpp_study/env/bashrc ${HOME}/.bashrc \ +cp ${HOME}/cpp_study/env/gitconfig ${HOME}/.gitconfig \ + +# source + +JSON_VERSION="3.9.1" +CPR_VERSION="1.4.0" +LUAJIT_VERSION="2.1-20200102" +LUABRIDAGE_VERSION="2.6" +GPERF_VERSION="2.8" + +#echo ${JSON_VERSION} +#echo ${HOME} + +mkdir ${HOME}/github +cd ${HOME}/github + +# test +#exit + +# json +curl -fsL https://github.com/nlohmann/json/releases/download/v${JSON_VERSION}/json.hpp -o json.hpp +ln -s ~/github/json.hpp ~/cpp_study/common/ + +# curl/cpr +curl -fsL https://github.com/whoshuu/cpr/archive/${CPR_VERSION}.tar.gz -o cpr.tgz +tar xfz cpr.tgz +cd cpr-${CPR_VERSION} +cmake . -DUSE_SYSTEM_CURL=ON -DBUILD_CPR_TESTS=OFF +make && make install && make clean +cd .. + +# luajit +curl -fsL https://github.com/openresty/luajit2/archive/v${LUAJIT_VERSION}.tar.gz -o luajit.tgz +tar xfz luajit.tgz +cd luajit2-${LUAJIT_VERSION} +make && make install && make clean +ln -s /usr/local/lib/libluajit-5.1.so.2 /lib/x86_64-linux-gnu/ +cd .. + +# luabridge +curl -fsL https://github.com/vinniefalco/LuaBridge/archive/${LUABRIDAGE_VERSION}.tar.gz -o LuaBridge.tgz +tar xfz LuaBridge.tgz +ln -s ~/github/LuaBridge-${LUABRIDAGE_VERSION}/Source/LuaBridge/ ~/cpp_study/common/ + +# gperftools +curl -fsL https://github.com/gperftools/gperftools/releases/download/gperftools-${GPERF_VERSION}/gperftools-${GPERF_VERSION}.tar.gz -o gperf.tgz +tar xfz gperf.tgz +ln -s ~/github/gperftools-${GPERF_VERSION}/pprof-symbolize /bin/pprof + +# flame graph +git clone https://github.com/brendangregg/FlameGraph.git --depth=1 +ln -s ~/github/FlameGraph/flamegraph.pl ~/cpp_study/section4/ + +# clean +rm *.tgz + diff --git a/extra/etcd.hpp b/extra/etcd.hpp new file mode 100644 index 0000000..3ded3ed --- /dev/null +++ b/extra/etcd.hpp @@ -0,0 +1,175 @@ +// Copyright (c) 2020 by Chrono +// +// docker pull quay.io/coreos/etcd +// docker pull quay.io/coreos/etcd:v3.3.25 +// +// https://etcd.io/docs/v2/api/ +// +// docker-compose -f etcd.yml -p etcd up -d +// docker-compose -f etcd.yml -p etcd down +// +// curl 127.0.0.1:2379/version +// {"etcdserver":"3.3.8","etcdcluster":"3.3.0"} +// {"etcdserver":"3.3.25","etcdcluster":"3.3.0"} +// +// curl http://127.0.0.1:2379/v2/keys/foo -XPUT -d value="Hello xxx" +// curl http://127.0.0.1:2379/v2/keys/foo + +#ifndef _UTILITY_ETCD_HPP_ +#define _UTILITY_ETCD_HPP_ + +#include +#include +#include + +namespace etcd::v2 { + +// sample output +// Version: +// { +// "etcdcluster": "3.3.0", +// "etcdserver": "3.3.8", +// "statusCode": 200 +// } +// Get: +// { +// "action": "get", +// "node": { +// "createdIndex": 29, +// "key": "/test/xxx", +// "modifiedIndex": 29, +// "value": "etcd" +// }, +// "statusCode": 200 +// } +class Client final { +public: + using string_type = std::string; + using string_ref_type = const std::string&; + + using json_type = nlohmann::json; +public: + Client(string_ref_type addr, int port) noexcept { + + m_url = fmt::format("http://{}:{}", addr, port); + //m_url = "http://" + addr + std::to_string(port); + + m_prefix = m_url + "/v2/keys"; + } + + ~Client() noexcept = default; +public: + json_type Version() noexcept { + + auto res = cpr::Get( + m_url + "/version" + ); + + return wrap_reply(res); + } + + // statusCode=2xx => OK + json_type Set(string_ref_type key, + string_ref_type value) noexcept { + + auto res = cpr::Put( + m_prefix + key, + cpr::Body("value=" + value) + ); + + return wrap_reply(res); + } + + // statusCode=200 => OK + json_type Get(string_ref_type key) noexcept { + + auto res = cpr::Get( + m_prefix + key + ); + + return wrap_reply(res); + } + + // statusCode=200 => OK + json_type Delete(string_ref_type key) noexcept { + + auto res = cpr::Delete( + m_prefix + key + ); + + return wrap_reply(res); + } + +public: + // statusCode=2xx => OK + json_type Set(string_ref_type key, + string_ref_type value, int ttl) noexcept { + + auto res = cpr::Put( + m_prefix + key, + cpr::Body(fmt::format("value={};ttl={}", value, ttl)) + ); + + return wrap_reply(res); + } + +public: + // It will block the thread until event happens + json_type Watch(string_ref_type key) noexcept { + + auto watch_url = m_prefix + key + "?wait=true"; + + // waiting for event + auto res = cpr::Get(watch_url); + + // fatal error + if (res.error.code != cpr::ErrorCode::OK) { + + return json_type { + {"error", res.error.message} + }; + } + + // http ok but timed out + if (res.text.empty()) { + + return json_type { + {"error", "timedout"} + }; + } + + return wrap_reply(res); + } + +private: + template + json_type wrap_reply(const T& res) noexcept { + + //std::cout << res.status_code << std::endl; + + //json_type j; + //j["code"] = res.status_code; + //j["value"] = json_type::parse(res.text); + + if (res.error.code != cpr::ErrorCode::OK) { + + return json_type { + //{"status_code", res.error.code}, + {"error", res.error.message} + }; + } + + auto j = json_type::parse(res.text); + j["statusCode"] = res.status_code; + + return j; + } +private: + string_type m_url; + string_type m_prefix; +}; + +} // namespace etcd::v2 + +#endif //_UTILITY_ETCD_HPP_ + diff --git a/section1/oop.cpp b/section1/oop.cpp index dece5a1..9ad4968 100644 --- a/section1/oop.cpp +++ b/section1/oop.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2050 by Chrono +// Copyright (c) 2020 by Chrono // // g++ oop.cpp -std=c++11 -o a.out;./a.out // g++ oop.cpp -std=c++14 -o a.out;./a.out @@ -9,6 +9,10 @@ #include #include +#if(defined (__MINGW64__) || (defined __MINGW32__)) +#include +#endif + #if 1 class Interface {}; diff --git a/section1/preprocess.cpp b/section1/preprocess.cpp index bbf19f3..20c6c35 100644 --- a/section1/preprocess.cpp +++ b/section1/preprocess.cpp @@ -26,6 +26,8 @@ void case1() # #if __linux__ # define HAS_LINUX 1 +#else +# define HAS_LINUX 0 #endif # cout << "linux is " << HAS_LINUX << endl; diff --git a/section2/auto.cpp b/section2/auto.cpp index 903b04d..4bc872e 100644 --- a/section2/auto.cpp +++ b/section2/auto.cpp @@ -4,12 +4,16 @@ // g++ auto.cpp -std=c++14 -o a.out;./a.out // g++ auto.cpp -std=c++14 -I../common -o a.out;./a.out +#include + #include #include #include #include #include +#include + #include void case1() @@ -97,6 +101,10 @@ void case6() decltype(auto) x1 = (x); decltype(auto) x2 = &x; decltype(auto) x3 = x1; + + assert(std::is_lvalue_reference::value); + assert(std::is_pointer::value); + assert(std::is_lvalue_reference::value); } auto get_a_set() diff --git a/section4/msgpack.cpp b/section4/msgpack.cpp index dc47b9d..7bc83c1 100644 --- a/section4/msgpack.cpp +++ b/section4/msgpack.cpp @@ -97,7 +97,11 @@ void case3() msgpack::sbuffer sbuf; msgpack::pack(sbuf, book1); - auto obj = msgpack::unpack(sbuf.data(), sbuf.size()).get(); + // may cause std::bad_cast error + //auto obj = msgpack::unpack(sbuf.data(), sbuf.size()).get(); + + auto handle = msgpack::unpack(sbuf.data(), sbuf.size()); + auto obj = handle.get(); Book book2; obj.convert(book2);