├── .clang-format ├── .gitignore ├── .syntastic_cpp_config ├── README.md ├── scripts ├── build_debug.sh ├── build_release.sh └── run_clang_tidy.sh └── src ├── CMakeLists.txt ├── client ├── CMakeLists.txt └── client.cc ├── factor ├── CMakeLists.txt ├── factor.cc ├── factor.h ├── factor_bench.cc └── factor_test.cc ├── proto ├── CMakeLists.txt └── api.proto ├── server ├── CMakeLists.txt └── server.cc ├── vendor ├── googlebenchmark │ └── CMakeLists.txt ├── googlelog │ └── CMakeLists.txt ├── googletest │ └── CMakeLists.txt ├── zeromq │ └── CMakeLists.txt └── zeromqcpp │ └── CMakeLists.txt └── zeromq_util ├── CMakeLists.txt ├── util.cc └── util.h /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: Google 4 | AccessModifierOffset: -1 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlinesLeft: true 9 | AlignOperands: true 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: true 12 | AllowShortBlocksOnASingleLine: false 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: All 15 | AllowShortIfStatementsOnASingleLine: true 16 | AllowShortLoopsOnASingleLine: true 17 | AlwaysBreakAfterDefinitionReturnType: None 18 | AlwaysBreakAfterReturnType: None 19 | AlwaysBreakBeforeMultilineStrings: true 20 | AlwaysBreakTemplateDeclarations: true 21 | BinPackArguments: true 22 | BinPackParameters: true 23 | BraceWrapping: 24 | AfterClass: false 25 | AfterControlStatement: false 26 | AfterEnum: false 27 | AfterFunction: false 28 | AfterNamespace: false 29 | AfterObjCDeclaration: false 30 | AfterStruct: false 31 | AfterUnion: false 32 | BeforeCatch: false 33 | BeforeElse: false 34 | IndentBraces: false 35 | BreakBeforeBinaryOperators: None 36 | BreakBeforeBraces: Attach 37 | BreakBeforeTernaryOperators: true 38 | BreakConstructorInitializersBeforeComma: false 39 | ColumnLimit: 80 40 | CommentPragmas: '^ IWYU pragma:' 41 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 42 | ConstructorInitializerIndentWidth: 4 43 | ContinuationIndentWidth: 4 44 | Cpp11BracedListStyle: true 45 | DerivePointerAlignment: true 46 | DisableFormat: false 47 | ExperimentalAutoDetectBinPacking: false 48 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 49 | IncludeCategories: 50 | - Regex: '^<.*\.h>' 51 | Priority: 1 52 | - Regex: '^<.*' 53 | Priority: 2 54 | - Regex: '.*' 55 | Priority: 3 56 | IndentCaseLabels: true 57 | IndentWidth: 2 58 | IndentWrappedFunctionNames: false 59 | KeepEmptyLinesAtTheStartOfBlocks: false 60 | MacroBlockBegin: '' 61 | MacroBlockEnd: '' 62 | MaxEmptyLinesToKeep: 1 63 | NamespaceIndentation: None 64 | ObjCBlockIndentWidth: 2 65 | ObjCSpaceAfterProperty: false 66 | ObjCSpaceBeforeProtocolList: false 67 | PenaltyBreakBeforeFirstCallParameter: 1 68 | PenaltyBreakComment: 300 69 | PenaltyBreakFirstLessLess: 120 70 | PenaltyBreakString: 1000 71 | PenaltyExcessCharacter: 1000000 72 | PenaltyReturnTypeOnItsOwnLine: 200 73 | PointerAlignment: Left 74 | ReflowComments: true 75 | SortIncludes: true 76 | SpaceAfterCStyleCast: false 77 | SpaceBeforeAssignmentOperators: true 78 | SpaceBeforeParens: ControlStatements 79 | SpaceInEmptyParentheses: false 80 | SpacesBeforeTrailingComments: 2 81 | SpacesInAngles: false 82 | SpacesInContainerLiterals: true 83 | SpacesInCStyleCastParentheses: false 84 | SpacesInParentheses: false 85 | SpacesInSquareBrackets: false 86 | Standard: Auto 87 | TabWidth: 8 88 | UseTab: Never 89 | ... 90 | 91 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | vendor/gtest/build 3 | vendor/gbenchmark/build 4 | 5 | # ignore compiled byte code 6 | target 7 | 8 | # ignore output files from testing 9 | output* 10 | 11 | # ignore standard Eclipse files 12 | .project 13 | .classpath 14 | .settings 15 | .checkstyle 16 | 17 | # ignore standard IntelliJ files 18 | .idea/ 19 | *.iml 20 | *.iws 21 | 22 | # ignore standard Vim and Emacs temp files 23 | *.swp 24 | *~ 25 | 26 | # ignore standard Mac OS X files/dirs 27 | .DS_Store 28 | 29 | ################################################################################ 30 | # vim 31 | ################################################################################ 32 | # swap 33 | [._]*.s[a-w][a-z] 34 | [._]s[a-w][a-z] 35 | # session 36 | Session.vim 37 | # temporary 38 | .netrwhist 39 | *~ 40 | # auto-generated tag files 41 | tags 42 | # syntastic 43 | .syntastic_clang_tidy_config 44 | .syntastic_cpp_config 45 | 46 | ################################################################################ 47 | # C++ 48 | ################################################################################ 49 | # Prerequisites 50 | *.d 51 | 52 | # Compiled Object files 53 | *.slo 54 | *.lo 55 | *.o 56 | *.obj 57 | 58 | # Precompiled Headers 59 | *.gch 60 | *.pch 61 | 62 | # Compiled Dynamic libraries 63 | *.so 64 | *.dylib 65 | *.dll 66 | 67 | # Fortran module files 68 | *.mod 69 | *.smod 70 | 71 | # Compiled Static libraries 72 | *.lai 73 | *.la 74 | *.a 75 | *.lib 76 | 77 | # Executables 78 | *.exe 79 | *.out 80 | *.app 81 | -------------------------------------------------------------------------------- /.syntastic_cpp_config: -------------------------------------------------------------------------------- 1 | -std=c++11 2 | -Ibuild 3 | -I. 4 | -Ibuild/vendor/googlebenchmark/src/googlebenchmark/include 5 | -Ibuild/vendor/googlelog/src/googlelog/src 6 | -Ibuild/vendor/googletest/src/googletest/googletest/include 7 | -Ibuild/vendor/zeromqcpp/zeromqcpp-prefix/src/zeromqcpp 8 | -Ibuild/vendor/zeromq/src/zeromq/include 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C++ Project Template 2 | This repository is a minimal C++ project template. It is meant to be copied and 3 | augmented. Though minimal, it includes a couple of useful features that can be 4 | tricky to get working: 5 | 6 | - All the code is built with [CMake](https://cmake.org/). Most of the 7 | dependencies are managed with CMake too! 8 | - The code is separated into multiple directories which use code from one 9 | another. 10 | - The project depends on a few third party libraries (e.g. 11 | [zeromq](http://zeromq.org/) and [libtool](https://www.gnu.org/software/libtool/)). 12 | - The project includes unit tests using [Google 13 | Test](https://github.com/google/googletest) 14 | - The project include microbenchmarks using [Google 15 | Benchmark](https://github.com/google/benchmark) 16 | - The project uses [Protocol Buffers](http://clang.llvm.org/extra/clang-tidy/). 17 | - The project uses [Google's `glog` logging library](https://github.com/google/glog). 18 | - The project abides by [Google's C++ Style 19 | Guide](https://google.github.io/styleguide/cppguide.html), which is also 20 | enforced by [`clang-format`](http://clang.llvm.org/docs/ClangFormat.html) 21 | - The project is linted by and 22 | [`clang-tidy`](http://clang.llvm.org/extra/clang-tidy/). 23 | 24 | ## Getting Primal 25 | This repository implements a prime factorization server and a corresponding 26 | client. The client reads numbers from the command line and sends them to the 27 | server, the server sends back their prime factorizations. 28 | 29 | +--------+ 120 +--------+ 30 | | |---------->| | 31 | | client | | server | 32 | | |<----------| | 33 | +--------+ 2,3,4,5 +--------+ 34 | 35 | Building and running the code, tests, and benchmarks is a breeze! 36 | 37 | ```bash 38 | # Building Code. 39 | ./scripts/build_debug.sh # build the code in debug mode 40 | ./scripts/build_release.sh # build the code in release mode 41 | 42 | # Running Code. 43 | ./build/factor/factor_test # run a test 44 | (cd build && make test) # run all the tests 45 | ./build/factor/factor_bench # run a benchmark 46 | ./build/server/server # start the server (in another window) 47 | ./build/client/client # start the client 48 | cat /tmp/client.INFO # view the client's logs 49 | 50 | # Formatting and Linting Code. 51 | clang-format src/server/server.cc # format a file 52 | find src -name '*.cc' -o -name '*.h' | xargs clang-format -i # format all files 53 | ./scripts/run_clang_tidy.sh src/server/server.cc # lint a file 54 | ./scripts/run_clang_tidy.sh $(find src -name '*.cc') # lint all files 55 | ``` 56 | 57 | ## Dependencies 58 | Before you build and run the code, there are a couple of dependencies you'll 59 | have to take care of first. 60 | 61 | - *clang.* First, install a recent version of 62 | [`clang`](http://clang.llvm.org/), [`libc++`](http://libcxx.llvm.org/), 63 | [`clang-format`](http://bit.ly/2dttR1C), and 64 | [`clang-tidy`](http://bit.ly/2dttR1C). If you're running Ubuntu 14.04 or 65 | later, you can run the following command to get things installed: 66 | 67 | sudo apt-get install clang-3.8 clang-format-3.8 clang-tidy-3.8 68 | sudo apt-get install libc++-dev libc++abi-dev 69 | sudo ln -s "$(which clang-3.8)" /usr/bin/clang 70 | sudo ln -s "$(which clang++-3.8)" /usr/bin/clang++ 71 | sudo ln -s "$(which clang-format-3.8)" /usr/bin/clang-format 72 | sudo ln -s "$(which clang-tidy-3.8)" /usr/bin/clang-tidy 73 | - *cmake.* Next, install a recent version of 74 | [CMake](https://cmake.org/download/). For example, 75 | 76 | wget 'https://cmake.org/files/v3.6/cmake-3.6.2-Linux-x86_64.sh' 77 | yes | sh cmake-3.6.2-Linux-x86_64.sh 78 | echo 'export PATH="$PATH:$HOME/cmake-3.6.2-Linux-x86_64/bin"' >> ~/.bashrc 79 | - *libtool.* Next, install libtool 80 | 81 | sudo apt-get install libtool 82 | - *protobuf.* Finally, install the [Protocol 83 | Buffer](https://cmake.org/download/) compiler and libraries. For example, 84 | 85 | local readonly url='https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.zip' 86 | local readonly name='protobuf-2.6.1' 87 | 88 | sudo apt-get install -y autoconf automake libtool curl make g++ unzip 89 | wget "$url" 90 | unzip "$name.zip" 91 | cd "$name" 92 | CXX="clang++" ./configure 93 | make # this takes a while 94 | make check 95 | sudo make install 96 | sudo ldconfig 97 | 98 | ## Resources 99 | - [The Definitive C++ Book Guide and 100 | List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) 101 | - [C++ Reference](http://en.cppreference.com/w/) 102 | - [C++ Open Source Libraries](http://en.cppreference.com/w/cpp/links/libs) 103 | - [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) 104 | 105 | ## TODO 106 | - Given a more in-depth description of how the code works and is organized. 107 | - Describe how to integrate clang-format and clang-tidy with vim, emacs, etc. 108 | - Add continuous integration? 109 | - Add link to the RISE Lab C++ Google Doc. 110 | -------------------------------------------------------------------------------- /scripts/build_debug.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -euo pipefail 4 | 5 | main() { 6 | export CC="clang" 7 | export CXX="clang++" 8 | cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug -Hsrc -Bbuild 9 | cmake --build build 10 | } 11 | 12 | main 13 | -------------------------------------------------------------------------------- /scripts/build_release.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -euo pipefail 4 | 5 | main() { 6 | export CC="clang" 7 | export CXX="clang++" 8 | cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Release -Hsrc -Bbuild 9 | cmake --build build 10 | } 11 | 12 | main 13 | -------------------------------------------------------------------------------- /scripts/run_clang_tidy.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # This script runs clang-tidy on its input arguments with all of clang-tidy's 4 | # flags set up nicely. 5 | 6 | set -euo pipefail 7 | 8 | usage() { 9 | echo "usage: run_clang_tidy.sh ..." 10 | } 11 | 12 | # http://stackoverflow.com/a/17841619/3187068 13 | join() { 14 | local IFS="," 15 | echo "$*" 16 | } 17 | 18 | main() { 19 | if [[ $# -eq 0 ]]; then 20 | usage 21 | return -1 22 | fi 23 | 24 | # Arguments for the `-checks` flag. 25 | checks=() 26 | checks+=('*') 27 | checks+=('-llvm-header-guard') 28 | checks+=('-llvm-include-order') 29 | # Using googletest macros like EXPECT_EQ trigger this check. 30 | checks+=('-cppcoreguidelines-pro-type-vararg') 31 | 32 | # Argument for the header-filter command. We want to run clang-tidy on all 33 | # of our header files, but not on any of the system header files. We also 34 | # do not want to run clang-tidy on any of the generated protobuf headers. 35 | local header_filter='cpp_project_template/src' 36 | 37 | clang-tidy \ 38 | -checks="$(join "${checks[@]}")" \ 39 | -header-filter="$header_filter" \ 40 | -p build/compile_commands.json \ 41 | "$@" 42 | } 43 | 44 | main "$@" 45 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 2 | 3 | PROJECT(cpp_project_template) 4 | SET(CPP_PROJECT_TEMPLATE_VERSION_MAJOR 0) 5 | SET(CPP_PROJECT_TEMPLATE_VERSION_MINOR 1) 6 | SET(CPP_PROJECT_TEMPLATE_VERSION_PATCH 0) 7 | 8 | SET(CMAKE_CXX_FLAGS_COMMON 9 | "-std=c++11 \ 10 | -Wall \ 11 | -Wextra \ 12 | -Werror") 13 | SET(CMAKE_CXX_FLAGS_DEBUG 14 | "${CMAKE_CXX_FLAGS_DEBUG} \ 15 | ${CMAKE_CXX_FLAGS_COMMON}") 16 | SET(CMAKE_CXX_FLAGS_RELEASE 17 | "${CMAKE_CXX_FLAGS_RELEASE} \ 18 | ${CMAKE_CXX_FLAGS_COMMON}") 19 | 20 | ADD_SUBDIRECTORY(vendor/googlebenchmark) 21 | ADD_SUBDIRECTORY(vendor/googlelog) 22 | ADD_SUBDIRECTORY(vendor/googletest) 23 | ADD_SUBDIRECTORY(vendor/zeromq) 24 | ADD_SUBDIRECTORY(vendor/zeromqcpp) 25 | 26 | INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) 27 | INCLUDE_DIRECTORIES(.) 28 | INCLUDE_DIRECTORIES(${GBENCH_INCLUDE_DIRS}) 29 | INCLUDE_DIRECTORIES(${GLOG_INCLUDE_DIRS}) 30 | INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS}) 31 | INCLUDE_DIRECTORIES(${ZEROMQCPP_INCLUDE_DIRS}) 32 | INCLUDE_DIRECTORIES(${ZEROMQ_INCLUDE_DIRS}) 33 | 34 | LINK_DIRECTORIES(${GLOG_LINK_DIRS}) 35 | LINK_DIRECTORIES(${ZEROMQ_LINK_DIRS}) 36 | 37 | ENABLE_TESTING() 38 | ADD_SUBDIRECTORY(client) 39 | ADD_SUBDIRECTORY(factor) 40 | ADD_SUBDIRECTORY(proto) 41 | ADD_SUBDIRECTORY(server) 42 | ADD_SUBDIRECTORY(zeromq_util) 43 | -------------------------------------------------------------------------------- /src/client/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 2 | 3 | ADD_EXECUTABLE(client client.cc) 4 | TARGET_LINK_LIBRARIES(client 5 | api 6 | glog 7 | zeromq_util 8 | zmq 9 | ) 10 | -------------------------------------------------------------------------------- /src/client/client.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include "glog/logging.h" 8 | #include "proto/api.pb.h" 9 | #include "zeromq_util/util.h" 10 | 11 | namespace { 12 | 13 | void prompt() { std::cout << "> " << std::flush; } 14 | 15 | } // namespace 16 | 17 | int main(int, char* argv[]) { 18 | google::InitGoogleLogging(argv[0]); 19 | 20 | zmq::context_t context(1); 21 | zmq::socket_t socket(context, ZMQ_REQ); 22 | const std::string address = "tcp://localhost:5555"; 23 | socket.connect(address); 24 | LOG(INFO) << "Client connected to " << address; 25 | 26 | prompt(); 27 | for (std::string line; std::getline(std::cin, line); prompt()) { 28 | Request request; 29 | long x = std::stol(line); 30 | CHECK_GT(x, 0) << "Cannot factor non-positive value."; 31 | request.set_x(std::stol(line)); 32 | send_proto(request, &socket); 33 | 34 | Reply reply; 35 | recv_proto(&reply, &socket); 36 | for (const int64_t factor : reply.factor()) { 37 | std::cout << factor << std::endl; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/factor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 2 | 3 | ADD_LIBRARY(factor factor.cc) 4 | 5 | ADD_EXECUTABLE(factor_test factor_test.cc factor.cc) 6 | ADD_TEST(factor_test factor_test) 7 | TARGET_LINK_LIBRARIES(factor_test 8 | ${GTEST_LIBS_DIR}/libgtest.a 9 | ${GTEST_LIBS_DIR}/libgtest_main.a 10 | pthread 11 | ) 12 | 13 | ADD_EXECUTABLE(factor_bench factor_bench.cc factor.cc) 14 | TARGET_LINK_LIBRARIES(factor_bench 15 | ${GBENCH_LIBS_DIR}/libbenchmark.a 16 | pthread 17 | ) 18 | -------------------------------------------------------------------------------- /src/factor/factor.cc: -------------------------------------------------------------------------------- 1 | #include "factor/factor.h" 2 | 3 | namespace factor { 4 | 5 | std::vector factor(int64_t x) { 6 | if (x == 1) { 7 | return {1}; 8 | } 9 | 10 | std::vector factors; 11 | while (x != 1) { 12 | for (int64_t i = 2; i <= x; ++i) { 13 | if (x % i == 0) { 14 | x /= i; 15 | factors.push_back(i); 16 | break; 17 | } 18 | } 19 | } 20 | return factors; 21 | } 22 | 23 | } // namespace factor 24 | -------------------------------------------------------------------------------- /src/factor/factor.h: -------------------------------------------------------------------------------- 1 | #ifndef FACTOR_FACTOR_H_ 2 | #define FACTOR_FACTOR_H_ 3 | 4 | #include 5 | #include 6 | 7 | namespace factor { 8 | 9 | // `factor(x)` returns the prime factors of `x` in increading order. It is a 10 | // precondition that `x` is a positive number. 11 | std::vector factor(int64_t x); 12 | 13 | } // namespace factor 14 | 15 | #endif // FACTOR_FACTOR_H_ 16 | -------------------------------------------------------------------------------- /src/factor/factor_bench.cc: -------------------------------------------------------------------------------- 1 | #include "factor/factor.h" 2 | 3 | #include "benchmark/benchmark.h" 4 | 5 | namespace factor { 6 | 7 | void FactorBench(benchmark::State& state) { 8 | while (state.KeepRunning()) { 9 | benchmark::DoNotOptimize(factor(state.range_x())); 10 | } 11 | } 12 | BENCHMARK(FactorBench)->Range(1, 10 << 10); 13 | 14 | } // namespace factor 15 | 16 | int main(int argc, char** argv) { 17 | benchmark::Initialize(&argc, argv); 18 | benchmark::RunSpecifiedBenchmarks(); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /src/factor/factor_test.cc: -------------------------------------------------------------------------------- 1 | #include "factor/factor.h" 2 | 3 | #include 4 | 5 | #include "gtest/gtest.h" 6 | 7 | namespace factor { 8 | 9 | TEST(Factor, SmallNumbers) { 10 | EXPECT_EQ(factor(1), std::vector({1})); 11 | EXPECT_EQ(factor(2), std::vector({2})); 12 | EXPECT_EQ(factor(3), std::vector({3})); 13 | EXPECT_EQ(factor(4), std::vector({2, 2})); 14 | EXPECT_EQ(factor(5), std::vector({5})); 15 | EXPECT_EQ(factor(6), std::vector({2, 3})); 16 | EXPECT_EQ(factor(7), std::vector({7})); 17 | EXPECT_EQ(factor(8), std::vector({2, 2, 2})); 18 | EXPECT_EQ(factor(9), std::vector({3, 3})); 19 | } 20 | 21 | TEST(Factor, BigNumbers) { 22 | EXPECT_EQ(factor(1209), std::vector({3, 13, 31})); 23 | EXPECT_EQ(factor(4242), std::vector({2, 3, 7, 101})); 24 | } 25 | 26 | } // namespace factor 27 | 28 | int main(int argc, char** argv) { 29 | ::testing::InitGoogleTest(&argc, argv); 30 | return RUN_ALL_TESTS(); 31 | } 32 | -------------------------------------------------------------------------------- /src/proto/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 2 | 3 | INCLUDE(FindProtobuf) 4 | FIND_PACKAGE(Protobuf REQUIRED) 5 | INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR}) 6 | PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HEADER api.proto) 7 | ADD_LIBRARY(api ${PROTO_SRC}) 8 | TARGET_LINK_LIBRARIES(api protobuf) 9 | -------------------------------------------------------------------------------- /src/proto/api.proto: -------------------------------------------------------------------------------- 1 | // A request for the prime factorization server. 2 | message Request { 3 | // An arbitrary int. 4 | required int64 x = 1; 5 | } 6 | 7 | // A reply from the prime factorization server. 8 | message Reply { 9 | // The requested int. 10 | required int64 x = 1; 11 | 12 | // The prime factorization of `x`. 13 | repeated int64 factor = 2; 14 | } 15 | -------------------------------------------------------------------------------- /src/server/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 2 | 3 | ADD_EXECUTABLE(server server.cc) 4 | TARGET_LINK_LIBRARIES(server 5 | api 6 | factor 7 | zeromq_util 8 | zmq 9 | ) 10 | -------------------------------------------------------------------------------- /src/server/server.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include "factor/factor.h" 7 | #include "proto/api.pb.h" 8 | #include "zeromq_util/util.h" 9 | 10 | int main() { 11 | zmq::context_t context(1); 12 | zmq::socket_t socket(context, ZMQ_REP); 13 | const std::string address = "tcp://*:5555"; 14 | socket.bind(address); 15 | std::cout << "Listening on " << address << std::endl; 16 | 17 | while (true) { 18 | Request request; 19 | recv_proto(&request, &socket); 20 | 21 | std::vector factors = factor::factor(request.x()); 22 | Reply reply; 23 | reply.set_x(request.x()); 24 | for (const int64_t factor : factors) { 25 | reply.add_factor(factor); 26 | } 27 | 28 | send_proto(reply, &socket); 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /src/vendor/googlebenchmark/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Resources: 2 | # - http://www.kaizou.org/2014/11/gtest-cmake/ 3 | # - http://bit.ly/2cx70Pk 4 | # - https://github.com/snikulov/google-test-examples 5 | 6 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 7 | 8 | include(ExternalProject) 9 | 10 | ExternalProject_Add(googlebenchmark 11 | GIT_REPOSITORY "https://github.com/google/benchmark" 12 | GIT_TAG "v1.0.0" 13 | PREFIX ${CMAKE_CURRENT_BINARY_DIR} 14 | INSTALL_COMMAND "" 15 | ) 16 | 17 | ExternalProject_Get_Property(googlebenchmark SOURCE_DIR) 18 | SET(GBENCH_INCLUDE_DIRS ${SOURCE_DIR}/include PARENT_SCOPE) 19 | 20 | ExternalProject_Get_Property(googlebenchmark BINARY_DIR) 21 | SET(GBENCH_LIBS_DIR ${BINARY_DIR}/src PARENT_SCOPE) 22 | -------------------------------------------------------------------------------- /src/vendor/googlelog/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Resources: 2 | # - https://github.com/rsakamoto/dexter/blob/13bac2f372bf0beeba673187c39d657978d71890/ext/glog/CMakeLists.txt 3 | 4 | CMAKE_MINIMUM_REQUIRED(VERSION 3.0) 5 | 6 | include(ExternalProject) 7 | 8 | ExternalProject_Add(googlelog 9 | GIT_REPOSITORY "https://github.com/google/glog" 10 | GIT_TAG "master" 11 | PREFIX ${CMAKE_CURRENT_BINARY_DIR} 12 | BUILD_IN_SOURCE 1 13 | UPDATE_COMMAND "" 14 | CONFIGURE_COMMAND ./autogen.sh && ./configure 15 | BUILD_COMMAND make 16 | INSTALL_COMMAND "" 17 | ) 18 | 19 | set(GLOG_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/src/googlelog/src PARENT_SCOPE) 20 | set(GLOG_LINK_DIRS ${CMAKE_CURRENT_BINARY_DIR}/src/googlelog/.libs PARENT_SCOPE) 21 | -------------------------------------------------------------------------------- /src/vendor/googletest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Resources: 2 | # - http://www.kaizou.org/2014/11/gtest-cmake/ 3 | # - http://bit.ly/2cx70Pk 4 | # - https://github.com/snikulov/google-test-examples 5 | 6 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 7 | 8 | include(ExternalProject) 9 | 10 | ExternalProject_Add(googletest 11 | GIT_REPOSITORY "https://github.com/google/googletest" 12 | GIT_TAG "release-1.8.0" 13 | PREFIX ${CMAKE_CURRENT_BINARY_DIR} 14 | INSTALL_COMMAND "" 15 | ) 16 | 17 | ExternalProject_Get_Property(googletest SOURCE_DIR) 18 | set(GTEST_INCLUDE_DIRS ${SOURCE_DIR}/googletest/include PARENT_SCOPE) 19 | 20 | ExternalProject_Get_Property(googletest BINARY_DIR) 21 | set(GTEST_LIBS_DIR ${BINARY_DIR}/googlemock/gtest PARENT_SCOPE) 22 | -------------------------------------------------------------------------------- /src/vendor/zeromq/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Resources: 2 | # - http://zeromq.org/intro:get-the-software 3 | # - http://bit.ly/2dK0UBT 4 | # 5 | # Remember to have libtool, pkg-config, build-essential, autoconf, and automake 6 | # installed. 7 | 8 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 9 | 10 | include(ExternalProject) 11 | 12 | SET(CXX "clang++ -stdlib=c++") 13 | 14 | ExternalProject_Add(zeromq 15 | URL "https://github.com/zeromq/zeromq4-1/releases/download/v4.1.5/zeromq-4.1.5.tar.gz" 16 | PREFIX ${CMAKE_CURRENT_BINARY_DIR} 17 | BUILD_IN_SOURCE 1 18 | UPDATE_COMMAND "" 19 | CONFIGURE_COMMAND ./configure 20 | BUILD_COMMAND make 21 | INSTALL_COMMAND "" 22 | ) 23 | 24 | set(ZEROMQ_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/src/zeromq/include PARENT_SCOPE) 25 | set(ZEROMQ_LINK_DIRS ${CMAKE_CURRENT_BINARY_DIR}/src/zeromq/.libs PARENT_SCOPE) 26 | -------------------------------------------------------------------------------- /src/vendor/zeromqcpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Resources: 2 | # - http://zeromq.org/intro:get-the-software 3 | # - http://bit.ly/2dK0UBT 4 | # 5 | # Remember to have libtool, pkg-config, build-essential, autoconf, and automake 6 | # installed. 7 | 8 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 9 | 10 | include(ExternalProject) 11 | 12 | ExternalProject_Add(zeromqcpp 13 | GIT_REPOSITORY "https://github.com/zeromq/cppzmq.git" 14 | GIT_TAG "master" 15 | BUILD_IN_SOURCE 1 16 | UPDATE_COMMAND "" 17 | CONFIGURE_COMMAND "" 18 | BUILD_COMMAND "" 19 | INSTALL_COMMAND "" 20 | ) 21 | 22 | set(ZEROMQCPP_INCLUDE_DIRS 23 | ${CMAKE_CURRENT_BINARY_DIR}/zeromqcpp-prefix/src/zeromqcpp PARENT_SCOPE) 24 | -------------------------------------------------------------------------------- /src/zeromq_util/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 2 | 3 | ADD_LIBRARY(zeromq_util util.cc) 4 | -------------------------------------------------------------------------------- /src/zeromq_util/util.cc: -------------------------------------------------------------------------------- 1 | #include "zeromq_util/util.h" 2 | 3 | std::string message_to_string(const zmq::message_t& message) { 4 | return std::string(static_cast(message.data()), message.size()); 5 | } 6 | -------------------------------------------------------------------------------- /src/zeromq_util/util.h: -------------------------------------------------------------------------------- 1 | #ifndef ZEROMQ_UTIL_H_ 2 | #define ZEROMQ_UTIL_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | // Converts the data within a `zmq::message_t` into a string. 10 | std::string message_to_string(const zmq::message_t& message); 11 | 12 | // Serialize a proto and `send` it over the socket. 13 | template 14 | void send_proto(const RequestProto& request, zmq::socket_t* socket) { 15 | std::string request_str; 16 | request.SerializeToString(&request_str); 17 | zmq::message_t request_msg(request_str.size()); 18 | memcpy(request_msg.data(), request_str.c_str(), request_str.size()); 19 | socket->send(request_msg); 20 | } 21 | 22 | // `recv` a message and unserialize it into a proto. 23 | template 24 | void recv_proto(ResponseProto* reply, zmq::socket_t* socket) { 25 | zmq::message_t reply_msg; 26 | socket->recv(&reply_msg); 27 | std::string reply_str = message_to_string(reply_msg); 28 | reply->ParseFromString(reply_str); 29 | } 30 | 31 | #endif // ZEROMQ_UTIL_H_ 32 | --------------------------------------------------------------------------------