diff --git a/.gitignore b/.gitignore index 8d9183d..87bba84 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ a.out *.swp *.pb.* example_*_cpp* +build/ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..2260f40 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,73 @@ +{ + "files.associations": { + "*.log.*": "log", + "vector": "cpp", + "iostream": "cpp", + "ostream": "cpp", + "regex": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "complex": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "shared_mutex": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp", + "strstream": "cpp", + "iomanip": "cpp", + "typeindex": "cpp", + "variant": "cpp" + }, + "cmake.configureOnOpen": true, + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools" +} \ No newline at end of file diff --git a/practice/CMakeLists.txt b/practice/CMakeLists.txt new file mode 100644 index 0000000..10900ef --- /dev/null +++ b/practice/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 2.6) +project(cpp_study) +set(CMAKE_CXX_STANDARD 14) + +include_directories("${PROJECT_BINARY_DIR}") + +include_directories("${PROJECT_SOURCE_DIR}/pratice0") +include_directories("${PROJECT_SOURCE_DIR}/pratice1") +include_directories("${PROJECT_SOURCE_DIR}/lambda") +add_subdirectory(pratice0) +add_subdirectory(pratice1) +add_subdirectory(lambda) +set(EXTRA_LIBS ${EXTRA_LIBS} pratice0) +set(EXTRA_LIBS ${EXTRA_LIBS} pratice1) +set(EXTRA_LIBS ${EXTRA_LIBS} lambda) diff --git a/practice/build.sh b/practice/build.sh new file mode 100755 index 0000000..85ad4af --- /dev/null +++ b/practice/build.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +set -e + +script_dir=$(cd `dirname $0` ; pwd) +source_dir="${script_dir}" +build_dir="${script_dir}/build" + +echo script_dir: ${script_dir} +echo source_dir: ${source_dir} +echo build_dir: ${build_dir} + +if [ ! -d "${source_dir}" ]; then + echo [ERROR] src directory ${source_dir} not found! + # exit 1 +fi + +PROJECT_NAME="CPP_Pratices" +VERSION="V0.1" +CMAKE_OPTION="" + +echo Project: ${PROJECT_NAME}, Version: ${VERSION} + + +# usage +function usage() +{ +cat << EOT + usage : $0 [options] [--] + + Options: +EOT +} + +function build() +{ + echo "building..." + + mkdir $build_dir -p + cd $build_dir + + cmake $CMAKE_OPTION $source_dir + make -j | tee build.log + + echo "build done" +} + + + +while getopts "cdhr" opt +do + case $opt in + + h|help) + usage + exit 0 + ;; + \?) + usage + exit 0 + ;; + esac +done + +build + +cd $script_dir diff --git a/practice/common/common.hpp b/practice/common/common.hpp new file mode 100644 index 0000000..5bc9d7d --- /dev/null +++ b/practice/common/common.hpp @@ -0,0 +1,22 @@ +// Copyright (c) 2020 by Chrono + +#ifndef _COMMON_STD_HPP +#define _COMMON_STD_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" + +//never 'using namespace std;' in c++ header + +#endif //_COMMON_STD_HPP + diff --git a/practice/common/log.h b/practice/common/log.h new file mode 100644 index 0000000..4757418 --- /dev/null +++ b/practice/common/log.h @@ -0,0 +1,38 @@ +/** + * @file log.h + * @brief + * @author BenYuLong + * @date 2020/09/29 + */ + +#ifndef _LOG_H +#define _LOG_H + +#define COLOR(msg, code) "\033[0;1;" #code "m" msg "\033[0m" +#define RED(msg) COLOR(msg, 31) +#define GREEN(msg) COLOR(msg, 32) +#define YELLOW(msg) COLOR(msg, 33) +#define BLUE(msg) COLOR(msg, 34) + +#ifndef LOG_LEVEL +#define LOG_LEVEL 5 +#endif + +#define LOG_MODULE_NULL "N" +#define LOG_MODULE_SECTION0 "SEC0" + + +#define LOG_T(prefix, module, level, ...) \ + if (level < LOG_LEVEL) { \ + printf(prefix module " : " __VA_ARGS__); \ + printf("\n"); \ + } + +#define FATAL(module, ...) LOG_T(RED("[fatal]"), module, 0, __VA_ARGS__) +#define ERROR(module, ...) LOG_T(RED("[error]"), module, 1, __VA_ARGS__) +#define WARN(module, ...) LOG_T(YELLOW("[warn ]"), module, 2, __VA_ARGS__) +#define INFO(module, ...) LOG_T("[info ]", module, 3, __VA_ARGS__) +#define DEBUG(module, ...) LOG_T("[debug]", module, 4, __VA_ARGS__) + + +#endif diff --git a/practice/lambda/CMakeLists.txt b/practice/lambda/CMakeLists.txt new file mode 100644 index 0000000..999c775 --- /dev/null +++ b/practice/lambda/CMakeLists.txt @@ -0,0 +1,25 @@ +project(lambda) + +cmake_minimum_required(VERSION 3.16) + +# find_package(Threads REQUIRED) + +include_directories(${PROJECT_SOURCE_DIR}/../common) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +message("source dirs: ${PROJECT_SOURCE_DIR}") +message("binary dirs: ${PROJECT_BINARY_DIR}") + +add_executable(${PROJECT_NAME} lambda.cpp) + +set (LINK_LIBRARY + pthread +) + +target_link_libraries(${PROJECT_NAME} ${LINK_LIBRARY} -Wall) + +# add_library(${PROJECT_NAME} lambda.cpp) + +# install (TARGETS lambda DESTINATION bin) +# install (FILES lambda.cpp DESTINATION include) diff --git a/practice/lambda/lambda.cpp b/practice/lambda/lambda.cpp new file mode 100644 index 0000000..7829855 --- /dev/null +++ b/practice/lambda/lambda.cpp @@ -0,0 +1,52 @@ +#include "common.hpp" +#include +#include +#include + +namespace tt +{ + enum MyEnum + { + W = 1, + R = 2 + }; +} + +bool divided7(int x) +{ + return (0 == x % 7); +} + + +int main(int argc, char const *argv[]) +{ + std::vector v(100); + std::generate(v.begin(),v.end(),std::rand); + + std::cout << std::endl; + for (auto item : v) + { + std::cout << item << "\t"; + } + std::cout << std::endl; + + int num = std::count_if(v.begin(), v.end(), divided7); + std::cout << "divided7 count : " << num << std::endl; + + // lambda表达式代替divided7函数 + int lambdaNum = std::count_if(v.begin(), v.end(), [](int x){return x % 7 == 0;}); + std::cout << "Lambda divided7 count : " << lambdaNum << std::endl; + + // + int aa = 10; + auto ff = [=]()mutable{return aa *= 10;}; + std::cout << ff() << " " << aa << std::endl; + + // + std::function fun = [&fun](int x) { + return x < 2 ? 1 : fun(x - 1) + fun(x - 2); + }; + std::cout << fun(5) << std::endl; + return 0; +} + diff --git a/practice/lambda/test.cpp b/practice/lambda/test.cpp new file mode 100644 index 0000000..26a901b --- /dev/null +++ b/practice/lambda/test.cpp @@ -0,0 +1,36 @@ +#include +#include + +class Hello +{ + typedef enum + { + A = 1, + B = 2, + }TTTT; +}; + +namespace test +{ + class Hello; + + typedef enum + { + A = 1, + B = 2, + } TTTT; + + enum MyEnum + { + W = 1, + R = 2 + }; +} +int main(int argc, char const *argv[]) +{ + std::cout << test::W << std::endl; + Hello *hello = new Hello(); + std::cout << test::B << std::endl; + return 0; +} + diff --git a/practice/note.md b/practice/note.md new file mode 100644 index 0000000..aa4008e --- /dev/null +++ b/practice/note.md @@ -0,0 +1,4 @@ +#### 预定义的宏查看 +C++版本 ”__cplusplus“、 源文件信息的“FILE”“ LINE”“ DATE”,以及一些语言特性测试宏,比如“__cpp_decltype” “__cpp_decltype_auto” “__cpp_lib_make_unique”等。不过,与优化更密切相关的底层系统信息在 C++ 语言标准里没有定义,但编译器通常都会提供,预定义的宏,可以用 GCC 可以使用一条简单的命令查看: + +`g++ -E -dM - < /dev/null` \ No newline at end of file diff --git a/practice/practice0/CMakeLists.txt b/practice/practice0/CMakeLists.txt new file mode 100644 index 0000000..952443c --- /dev/null +++ b/practice/practice0/CMakeLists.txt @@ -0,0 +1,25 @@ +project(practice0) + +cmake_minimum_required(VERSION 3.16) + +# find_package(Threads REQUIRED) + +include_directories(${PROJECT_SOURCE_DIR}/../common) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +message("source dirs: ${PROJECT_SOURCE_DIR}") +message("binary dirs: ${PROJECT_BINARY_DIR}") + +add_executable(practice0Exec test.cpp) + +set (LINK_LIBRARY + pthread +) + +target_link_libraries(practice0Exec ${LINK_LIBRARY} -Wall) + +add_library(practice0 test.cpp) + +install (TARGETS practice0 DESTINATION bin) +install (FILES test.cpp DESTINATION include) diff --git a/practice/practice0/sort.cpp b/practice/practice0/sort.cpp new file mode 100644 index 0000000..2b1a4df --- /dev/null +++ b/practice/practice0/sort.cpp @@ -0,0 +1,187 @@ +// Copyright (c) 2020 by Chrono +// +// g++ sort.cpp -std=c++11 -o a.out;./a.out +// g++ sort.cpp -std=c++14 -o a.out;./a.out +// g++ sort.cpp -std=c++14 -I../common -o a.out;./a.out + +#include +#include +#include +#include + +using namespace std; + +/* +template +void quick_sort_impl(T& v, int left, int right) +{ + auto quick_partition = [](decltype(v)& arr, int left, int right) + { + // key => value type => int + decltype(v.front()) key = arr[right]; + + int i = left - 1; + int j = left; + + for (; j < right; j++) + { + if (arr[j] < key) + { + std::swap(arr[j], arr[++i]); + } + } + + std::swap(arr[right], arr[++i]); + + return i; + }; + + if (left > right) + { + return; + } + + int mid = quick_partition(v, left, right); + + quick_sort_impl(v, left, mid - 1); + quick_sort_impl(v, mid + 1, right); +} +*/ + +int main() +{ + std::vector v = {42,9,4,2,5,10,1,0}; + int len = v.size(); + + // ----------------------------- + + auto bubble_sort = [=]() mutable + { + for(int i = 0;i < len - 1; i++) + { + for(int j = 0; j < len - i - 1; j++) + { + if (v[j] > v[j + 1]) + { + std::swap(v[j], v[j + 1]); + } + } + } + + for(auto& x : v) + { + cout << x << ','; + } + + cout << endl; + }; + + bubble_sort(); + + // ----------------------------- + + auto select_sort = [=]() mutable + { + for (int i = 0; i < len - 1; i++) + { + int min = i; + for(int j = i + 1; j < len; j ++) + { + if (v[min] > v[j]) + { + min = j; + } + + swap(v[i], v[min]); + } + } + + for(auto& x : v) + { + cout << x << ','; + } + + cout << endl; + }; + + select_sort(); + + // ----------------------------- + + auto insert_sort = [=]() mutable + { + int i, j; + for(i = 0;i < len; i++) + { + int tmp = v[i]; + for(j = i; j > 0 && v[j - 1] > tmp; j--) + { + v[j] = v[j - 1]; + } + + v[j] = tmp; + } + + for(auto& x : v) + { + cout << x << ','; + } + + cout << endl; + }; + + insert_sort(); + + // ----------------------------- + + auto quick_partition = [](decltype(v)& arr, int left, int right) + { + // key => value type => int + decltype(v.front()) key = arr[right]; + + int i = left - 1; + int j = left; + + for (; j < right; j++) + { + if (arr[j] < key) + { + std::swap(arr[j], arr[++i]); + } + } + + std::swap(arr[right], arr[++i]); + + return i; + }; + + std::function quick_sort_impl; + + quick_sort_impl = + [&quick_sort_impl, &quick_partition](decltype(v)& v,int left, int right) + { + if (left > right) + { + return; + } + + int mid = quick_partition(v, left, right); + + quick_sort_impl(v, left, mid - 1); + quick_sort_impl(v, mid + 1, right); + }; + + auto quick_sort = [=]() mutable + { + quick_sort_impl(v, 0, len - 1); + + for(auto& x : v) + { + cout << x << ','; + } + + cout << endl; + }; + + quick_sort(); +} diff --git a/practice/practice0/test.cpp b/practice/practice0/test.cpp new file mode 100644 index 0000000..776bf94 --- /dev/null +++ b/practice/practice0/test.cpp @@ -0,0 +1,53 @@ +/** + * @file test.cpp + * @brief + * @author BenYuLong + * @date 2020/09/29 + */ +#include +#include + +#include "common.hpp" + +void *section0PthreadFun(void *ptr) +{ + using namespace std; + + while(true) + { + INFO(LOG_MODULE_SECTION0, "hhhh"); + WARN(LOG_MODULE_SECTION0, "waring"); + ERROR(LOG_MODULE_SECTION0, "error"); + FATAL(LOG_MODULE_SECTION0, "fatal"); + sleep(3); + } +} + +int main() +{ + using namespace std; + + INFO(LOG_MODULE_NULL, "c++ version = %ld", __cplusplus); + INFO(LOG_MODULE_NULL, "gcc version = %s", __VERSION__); + INFO(LOG_MODULE_NULL, "gcc major = %d", __GNUC__); + INFO(LOG_MODULE_NULL, "gcc minor = %d", __GNUC_MINOR__); + INFO(LOG_MODULE_NULL, "gcc patch = %d", __GNUC_PATCHLEVEL__); + INFO(LOG_MODULE_NULL, "libstdc++ = %d", __GLIBCXX__); + + string test; + + test += "hell"; + test += " "; + test += "hello"; + test += "o"; + + INFO(LOG_MODULE_NULL, "sendVerify : %s\n", test.c_str()); + + pthread_t section0Pthread; + if(0 != pthread_create(§ion0Pthread, nullptr, section0PthreadFun, nullptr)) + { + cout << "error Pthread create" << endl; + } + + pthread_join(section0Pthread, nullptr); +} diff --git a/practice/practice1/CMakeLists.txt b/practice/practice1/CMakeLists.txt new file mode 100644 index 0000000..8722438 --- /dev/null +++ b/practice/practice1/CMakeLists.txt @@ -0,0 +1,10 @@ +project(practice1) +cmake_minimum_required(VERSION 3.16) + +add_executable(p_compile compile.cpp) +add_executable(preprocess preprocess.cpp) + +add_library(practice1 compile.cpp) + +install (TARGETS practice1 DESTINATION bin) +install (FILES compile.cpp DESTINATION include) diff --git a/practice/practice1/compile.cpp b/practice/practice1/compile.cpp new file mode 100644 index 0000000..4847b07 --- /dev/null +++ b/practice/practice1/compile.cpp @@ -0,0 +1,165 @@ +// Copyright (c) 2020 by Chrono +// +// g++ compile.cpp -Wall -Werror -std=c++11 -o a.out;./a.out +// g++ compile.cpp -Wall -Werror -std=c++14 -o a.out;./a.out +// +// g++ compile.cpp -DNDEBUG -std=c++11 -o a.out;./a.out +// +// gcc -E -dM - < /dev/null + +#include + +#include +#include +#include +#include +#include + +template +struct fib +{ + static_assert(N >= 0, "N must be postive"); + + static const int value = + fib::value + fib::value; +}; + +template<> +struct fib<0> +{ + static const int value = 1; +}; + +template<> +struct fib<1> +{ + static const int value = 1; +}; + +#if __cplusplus >= 201402 +constexpr int const_fib(int n) +{ + if (n <= 1) { + return 1; + } + + return const_fib(n - 1) + const_fib(n - 2); +} +#else // C++11 +int const_fib(int n) +{ + return 42; +} +#endif + +//[[deprecated("deadline:2020-12-31")]] // c++14 or later +[[gnu::deprecated]] // c+11 or later +int old_func() +{ + //[[gnu::deprecated("I hate this")]] + int value = 0; + + return value; +} + +[[gnu::constructor]] +void first_func() +{ + // can not use cout! + printf("before main()\n"); +} + +[[gnu::destructor]] +void last_func() +{ + // can not use cout! + printf("after main()\n"); +} + +[[gnu::always_inline]] inline +int get_num() +{ + return 42; +} + +[[noreturn]] +int case1(bool flag) +{ + throw std::runtime_error("XXX"); +} + +void case2() +{ + using namespace std; + + [[gnu::unused]] + int nouse; + + cout << "case2" << endl; +} + +[[gnu::hot]] +void case3() +{ + using namespace std; + + cout << "case3" << endl; +} + +void case4() +{ + static_assert(sizeof(int) == 4, "int must be 32bit"); + static_assert(sizeof(long) == 8, "must run on x64"); +} + +template +void check_type(T v) +{ + using namespace std; + + static_assert(is_integral::value, "int"); + //static_assert(is_pointer::value, "ptr"); + //static_assert(is_default_constructible::value, "is_default_constructible"); + + cout << "static_assert : " << typeid(v).name(); + + cout << ": " << is_void::value << endl; +} + +void case5() +{ + int i = 10; + int *p = &i; + + assert(i > 0 && "i must be greater than zero"); + assert(p != nullptr); + + std::string str = "hello"; + assert(!str.empty()); +} + +int main() +{ + using namespace std; + + cout << fib<2>::value << endl; + cout << fib<3>::value << endl; + cout << fib<4>::value << endl; + cout << fib<5>::value << endl; + + cout << const_fib(10) << endl; + + old_func(); + get_num(); + + case2(); + case3(); + + case4(); + case5(); + + check_type(10); + //check_type((void*)0); + + cout << "compile stage demo" << endl; +} diff --git a/practice/practice1/preprocess.cpp b/practice/practice1/preprocess.cpp new file mode 100644 index 0000000..bbf19f3 --- /dev/null +++ b/practice/practice1/preprocess.cpp @@ -0,0 +1,132 @@ +// Copyright (c) 2020 by Chrono +// +// pre-process source: +// g++ preprocess.cpp -E -o a.cxx +// +// g++ preprocess.cpp -std=c++98 -o a.out;./a.out +// g++ preprocess.cpp -std=c++11 -o a.out;./a.out +// g++ preprocess.cpp -std=c++14 -o a.out;./a.out +// +// g++ preprocess.cpp -DNDEBUG -std=c++11 -o a.out;./a.out +// +// show all predefined macro: +// g++ -E -dM - < /dev/null +// g++ -E -dM - < /dev/null > predef.cxx + +// comment it for better pre-process output +#include + +using namespace std; + +// you can try this +//#include "a.out" + +void case1() +{ +# +#if __linux__ +# define HAS_LINUX 1 +#endif +# + cout << "linux is " << HAS_LINUX << endl; +} + +void case2() +{ +#define CUBE(a) (a) * (a) * (a) + + cout << CUBE(10) << endl; + cout << CUBE(15) << endl; + +#undef CUBE + +#ifdef AUTH_PWD +# undef AUTH_PWD +#endif +#define AUTH_PWD "xxx" + + cout << AUTH_PWD << endl; + +#define MAX_BUF_LEN 65535 +#define VERSION "1.0.18" +} + +// macro for convienient namespace +#define BEGIN_NAMESPACE(x) namespace x { +#define END_NAMESPACE(x) } + +BEGIN_NAMESPACE(my_own) + +class MyClass final +{ +}; + +void case3() +{ + cout << "working in own namespace" << endl; +} + +END_NAMESPACE(my_own) + +#ifdef __cplusplus + extern "C" { +#endif + void a_c_function(int a); +#ifdef __cplusplus + } +#endif + +void case4() +{ + +#if __cplusplus >= 201402 + cout << "c++14 or later" << endl; +#elif __cplusplus >= 201103 + cout << "c++11 or before" << endl; +#else // __cplusplus < 201103 +# error "c++ is too old" +#endif // __cplusplus >= 201402 + +#if __GNUC__ <= 4 + cout << "gcc is too old" << endl; +#else // __GNUC__ > 4 + cout << "gcc is good enough" << endl; +#endif // __GNUC__ <= 4 + +#if defined(__SSE4_2__) && defined(__x86_64) + cout << "we can do more optimization" << endl; +#endif // defined(__SSE4_2__) && defined(__x86_64) + +#if __linux__ + cout << "running on linux" << endl; +#else // not linux + cout << "running on others" << endl; +#endif //__linux__ + + +#if defined(__cpp_decltype_auto) + cout << "decltype(auto) enable" << endl; +#else + cout << "decltype(auto) disable" << endl; +#endif //__cpp_decltype_auto + +#ifndef NDEBUG + cout << "debug mode" << endl; +#endif // NDEBUG + +} + +int main() +{ + case1(); + case2(); + + my_own::case3(); + + [[gnu::unused]] // ignore warning + my_own::MyClass obj; + + case4(); + + cout << "pre-process demo" << endl; +} diff --git a/practice/practice2/CMakeLists.txt b/practice/practice2/CMakeLists.txt new file mode 100644 index 0000000..5e378ad --- /dev/null +++ b/practice/practice2/CMakeLists.txt @@ -0,0 +1,12 @@ +project(practice2) + +add_executable(auto auto.cpp) +add_executable(const const.cpp) +add_executable(exception exception.cpp) +add_executable(lambda lambda.cpp) +add_executable(smart_ptr smart_ptr.cpp) + +# add_library(section2 auto.cpp const.cpp exception.cpp lambda.cpp smart_ptr.cpp) + +# install (TARGETS section2 DESTINATION bin) +# install (FILES auto.cpp const.cpp exception.cpp lambda.cpp smart_ptr.cpp DESTINATION include) diff --git a/practice/practice2/auto.cpp b/practice/practice2/auto.cpp new file mode 100644 index 0000000..903b04d --- /dev/null +++ b/practice/practice2/auto.cpp @@ -0,0 +1,154 @@ +// Copyright (c) 2020 by Chrono +// +// g++ auto.cpp -std=c++11 -o a.out;./a.out +// 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 + +void case1() +{ + + int i = 0; + double x = 1.0; + + std::string str = "hello"; + std::map m = {{1,"a"}, {2,"b"}}; + + std::map::const_iterator iter = m.begin(); + + //using namespace std; + //cout << i << x; +} + +void case2() +{ + auto i = 0; + //auto i{0} ; + auto x = 1.0; + + auto str = "hello"; + //decltype("hello") str = "hello"; + + std::map m = {{1,"a"}, {2,"b"}}; + + auto iter = m.begin(); + + auto f = bind1st(std::less(), 2); + + //using namespace std; + //cout << typeid(str).name() << endl; +} + +void case3() +{ + auto x = 0L; + auto y = &x; + auto z {&x}; +} + +class X final +{ + //auto a = 10; + int a = 10; +}; + +void case4() +{ + auto x = 10L; + + auto& x1 = x; + auto* x2 = &x; + const auto& x3 = x; + auto x4 = &x3; + + using namespace std; + + cout << *x2 << endl; + cout << *x4 << endl; + //cout << typeid(x4).name() << endl; +} + +void case5() +{ + int x = 0; + + decltype(x) x1; + decltype(x)& x2 = x; + decltype(x)* x3; + decltype(&x) x4; + decltype(&x)* x5; + decltype(x2) x6 = x2; + + using int_ptr = decltype(&x); + using int_ref = decltype(x)&; +} + +void case6() +{ + int x = 0; + + decltype(auto) x1 = (x); + decltype(auto) x2 = &x; + decltype(auto) x3 = x1; +} + +auto get_a_set() +{ + std::set s = {1,2,3}; + + return s; +} + +void case7() +{ + using namespace std; + + vector v = {2,3,5,7,11}; + + for(const auto& i : v) { + cout << i << ","; + } + cout << endl; + + for(auto& i : v) { + i++; + cout << i << ","; + } + cout << endl; +} + +class DemoClass final +{ +public: + using sig_func_ptr_t = decltype(&signal) ; +public: + using set_type = std::set; + +private: + set_type m_set; + + using iter_type = decltype(m_set.begin()); + iter_type m_pos; +}; + +int main() +{ + using namespace std; + + case1(); + case2(); + case3(); + case4(); + case5(); + case6(); + case7(); + + cout << "auto/decltype demo" << endl; +} diff --git a/practice/practice2/const.cpp b/practice/practice2/const.cpp new file mode 100644 index 0000000..51dd9e3 --- /dev/null +++ b/practice/practice2/const.cpp @@ -0,0 +1,94 @@ +// Copyright (c) 2020 by Chrono +// +// g++ const.cpp -std=c++11 -o a.out;./a.out +// g++ const.cpp -std=c++14 -o a.out;./a.out +// g++ const.cpp -std=c++14 -I../common -o a.out;./a.out + +#include + +void case1() +{ + using namespace std; + + //const int MAX_LEN = 1024; + const volatile int MAX_LEN = 1024; + const std::string NAME = "metroid"; + + auto ptr = (int*)(&MAX_LEN); + *ptr = 2048; + cout << MAX_LEN << endl; + +} + +void case2() +{ + using namespace std; + + int x = 100; + + const int& rx = x; + const int* px = &x; + + cout << rx << *px << endl; + + string name = "uncharted"; + + const string* ps1 = &name; + //*ps1 = "spiderman"; + + cout << *ps1 << endl; + + string* const ps2 = &name; + *ps2 = "spiderman"; + + cout << *ps2 << endl; + + const string* const ps3 = &name; +} + +class DemoClass final +{ +private: + using mutex_type = int; // dummy type +private: + mutable mutex_type m_mutex; + + const long MAX_SIZE = 256; + int m_value; +public: + int get_value() const + { + return m_value; + } + + void save_data() const + { + m_mutex++; + } +}; + + +constexpr +int fib(int n) +{ + if (n == 0 || n == 1) { + return 1; + } + + return fib(n - 1) + fib(n - 2); +} + +int main() +{ + using namespace std; + + case1(); + case2(); + + constexpr + int fib5 = fib(5); + + cout << fib5 << endl; + + cout << "const demo" << endl; +} diff --git a/practice/practice2/exception.cpp b/practice/practice2/exception.cpp new file mode 100644 index 0000000..f7ffe1e --- /dev/null +++ b/practice/practice2/exception.cpp @@ -0,0 +1,62 @@ +// Copyright (c) 2020 by Chrono +// +// g++ exception.cpp -std=c++11 -o a.out;./a.out +// g++ exception.cpp -std=c++14 -o a.out;./a.out +// g++ exception.cpp -std=c++14 -I../common -o a.out;./a.out + +#include +#include + +using namespace std; + +class my_exception : public std::runtime_error +{ +public: + using this_type = my_exception; + using super_type = std::runtime_error; +public: + my_exception(const char* msg): + super_type(msg) + {} + + my_exception() = default; + ~my_exception() = default; +private: + int code = 0; +}; + +[[noreturn]] +void raise(const char* msg) +{ + throw my_exception(msg); + //throw runtime_error(msg); +} + +void case1() +try +{ + raise("error occured"); +} +catch(const exception& e) +{ + cout << e.what() << endl; +} + +void case2() noexcept +{ + cout << "noexcept" << endl; +} + +void case3() noexcept +{ + throw "Oh My God"; +} + +int main() +{ + case1(); + case2(); + //case3(); + + cout << "exception demo" << endl; +} diff --git a/practice/practice2/lambda.cpp b/practice/practice2/lambda.cpp new file mode 100644 index 0000000..d46305e --- /dev/null +++ b/practice/practice2/lambda.cpp @@ -0,0 +1,176 @@ +// Copyright (c) 2020 by Chrono +// +// g++ lambda.cpp -std=c++14 -o a.out;./a.out +// g++ lambda.cpp -std=c++14 -I../common -o a.out;./a.out + +#include +#include +#include +#include +#include + +using namespace std; + +void my_square(int x) +{ + cout << x*x << endl; +} + +void case1() +{ + auto pfunc = &my_square; + + (*pfunc)(3); + pfunc(3); + + auto func = [](int x) + { + cout << x*x << endl; + }; + + func(3); +} + +void case2() +{ + int n = 10; + + auto func = [=](int x) + { + cout << x*n << endl; + }; + + func(3); +} + +void case3() +{ + auto f1 = [](){}; + + auto f2 = []() + { + cout << "lambda f2" << endl; + + auto f3 = [](int x) + { + return x*x; + };// lambda f3 + + cout << f3(10) << endl; + }; // lambda f2 + + f1(); + f2(); + + //f1 = f2; + + vector v = {3, 1, 8, 5, 0}; + + cout << *find_if(begin(v), end(v), + [](int x) + { + return x >= 5; + } + ) + << endl; +} + +void case4() +{ + int x = 33; + + auto f1 = [=]() + { + //x += 10; + cout << x << endl; + }; + + auto f2 = [&]() + { + x += 10; + }; + + auto f3 = [=, &x]() + { + x += 20; + }; + + f1(); + f2(); + cout << x << endl; + f3(); + cout << x << endl; +} + +class DemoLambda final +{ +public: + DemoLambda() = default; + ~DemoLambda() = default; +private: + int x = 0; +public: + auto print() + { + //auto f = [=]() + + return [this]() + { + cout << "member = " << x << endl; + }; + + } +}; + +void case5() +{ + DemoLambda obj; + + auto f = obj.print(); + + f(); +} + +void case6() +{ + auto f = [](const auto& x) + { + return x + x; + }; + + cout << f(3) << endl; + cout << f(0.618) << endl; + + string str = "matrix"; + cout << f(str) << endl; +} + +// demo for function + lambda +class Demo final +{ +public: + using func_type = std::function; +public: + func_type print = [this]() + { + cout << "value = " << m_value << endl; + cout << "hello function+lambda" << endl; + }; +private: + int m_value = 10; +}; + +int main() +{ + case1(); + case2(); + case3(); + case4(); + case5(); + case6(); + + Demo d; + d.print(); + + cout << "lambda demo" << endl; +} diff --git a/practice/practice2/smart_ptr.cpp b/practice/practice2/smart_ptr.cpp new file mode 100644 index 0000000..af2b947 --- /dev/null +++ b/practice/practice2/smart_ptr.cpp @@ -0,0 +1,155 @@ +// Copyright (c) 2020 by Chrono +// +// g++ smart_ptr.cpp -std=c++11 -o a.out;./a.out +// g++ smart_ptr.cpp -std=c++14 -o a.out;./a.out +// g++ smart_ptr.cpp -std=c++14 -I../common -o a.out;./a.out + +#include + +#include +#include +#include + +template +std::unique_ptr +my_make_unique(Args&&... args) +{ + return std::unique_ptr( + new T(std::forward(args)...)); +} + +void case1() +{ + using namespace std; + + unique_ptr ptr1(new int(10)); + assert(*ptr1 == 10); + assert(ptr1 != nullptr); + + unique_ptr ptr2(new string("hello")); + assert(*ptr2 == "hello"); + assert(ptr2->size() == 5); + + //ptr1++; + //ptr2 += 2; + + //unique_ptr ptr3; + //*ptr3 = 42; + + auto ptr3 = make_unique(42); + assert(ptr3 && *ptr3 == 42); + + auto ptr4 = make_unique("god of war"); + assert(!ptr4->empty()); + + auto ptr5 = my_make_unique(100L); + assert(*ptr5 == 100); +} + +void case2() +{ + using namespace std; + + auto ptr1 = make_unique(42); + assert(ptr1 && *ptr1 == 42); + + auto ptr2 = std::move(ptr1); + assert(!ptr1 && ptr2); +} + +void case3() +{ + using namespace std; + + shared_ptr ptr1(new int(10)); + assert(*ptr1 = 10); + + shared_ptr ptr2(new string("hello")); + assert(*ptr2 == "hello"); + + auto ptr3 = make_shared(42); + assert(ptr3 && *ptr3 == 42); + + auto ptr4 = make_shared("zelda"); + assert(!ptr4->empty()); +} + +void case4() +{ + using namespace std; + + auto ptr1 = make_shared(42); + assert(ptr1 && ptr1.unique() ); + + auto ptr2 = ptr1; + assert(ptr1 && ptr2); + + assert(ptr1 == ptr2); + assert(!ptr1.unique() && ptr1.use_count() == 2); + assert(!ptr2.unique() && ptr2.use_count() == 2); +} + +class DemoShared final +{ +public: + DemoShared() = default; + ~DemoShared() + { + // do some blocking thing ... + } +}; + +class Node final +{ +public: + using this_type = Node; + //using shared_type = std::shared_ptr; + using shared_type = std::weak_ptr; +public: + shared_type next; +public: + Node() = default; + ~Node() + { + using namespace std; + cout << "node dtor" << endl; + } +}; + +void case5() +{ + using namespace std; + + auto n1 = make_shared(); + auto n2 = make_shared(); + + assert(n1.use_count() == 1); + assert(n2.use_count() == 1); + + n1->next = n2; + n2->next = n1; + + assert(n1.use_count() == 1); + assert(n2.use_count() == 1); + + if (!n1->next.expired()) { + auto ptr = n1->next.lock(); + assert(ptr == n2); + } + + //assert(n1.use_count() == 2); + //assert(n2.use_count() == 2); +} + +int main() +{ + using namespace std; + + case1(); + case2(); + case3(); + case4(); + case5(); + + cout << "smart_ptr demo" << endl; +} diff --git a/practice/thread/CMakeLists.txt b/practice/thread/CMakeLists.txt new file mode 100644 index 0000000..b985c58 --- /dev/null +++ b/practice/thread/CMakeLists.txt @@ -0,0 +1,19 @@ +project(thread) + + + +add_executable(mutexCond mutexCond.cpp) +add_executable(producerConsumer producerConsumer.cpp) + +set (LINK_LIBRARY + pthread +) + +target_link_libraries(mutexCond ${LINK_LIBRARY} -Wall) +target_link_libraries(producerConsumer ${LINK_LIBRARY} -Wall) + + +# add_library(section2 auto.cpp const.cpp exception.cpp lambda.cpp smart_ptr.cpp) + +# install (TARGETS section2 DESTINATION bin) +# install (FILES auto.cpp const.cpp exception.cpp lambda.cpp smart_ptr.cpp DESTINATION include) diff --git a/practice/thread/mutexCond.cpp b/practice/thread/mutexCond.cpp new file mode 100644 index 0000000..a544dd2 --- /dev/null +++ b/practice/thread/mutexCond.cpp @@ -0,0 +1,81 @@ + +#include +#include +#include +#include + +#define NUM_OF_TASKS 3 +#define MAX_TASK_QUEUE 11 + +char tasklist[MAX_TASK_QUEUE]="ABCDEFGHIJ"; +int head = 0; +int tail = 0; + +int quit = 0; + +pthread_mutex_t g_task_lock; +pthread_cond_t g_task_cv; + +void *coder(void *notused) +{ + pthread_t tid = pthread_self(); + + while(!quit){ + + pthread_mutex_lock(&g_task_lock); + while(tail == head){ + if(quit){ + pthread_mutex_unlock(&g_task_lock); + pthread_exit((void *)0); + } + printf("No task now! Thread %u is waiting!\n", (unsigned int)tid); + pthread_cond_wait(&g_task_cv, &g_task_lock); + printf("Have task now! Thread %u is grabing the task !\n", (unsigned int)tid); + } + char task = tasklist[head++]; + pthread_mutex_unlock(&g_task_lock); + printf("Thread %u has a task %c now!\n", (unsigned int)tid, task); + sleep(2); + printf("Thread %u finish the task %c!\n", (unsigned int)tid, task); + } + + pthread_exit((void *)0); +} + +int main(int argc, char *argv[]) +{ + pthread_t threads[NUM_OF_TASKS]; + int rc; + int t; + + pthread_mutex_init(&g_task_lock, NULL); + pthread_cond_init(&g_task_cv, NULL); + + for(t=0;t +#include +#include +#include +#include + +class producerConsumer +{ +private: + + pthread_mutex_t myLock = PTHREAD_MUTEX_INITIALIZER; + pthread_cond_t myCond = PTHREAD_COND_INITIALIZER; + +public: + typedef struct LinkNode + { + int data; + struct LinkNode *next; + } Node; + producerConsumer(/* args */); + ~producerConsumer(); + Node *CreatNode(int data); + void InitLink(Node **head); + int IsEmpty(Node *head); + void PushFront(Node *head,int data); + void PopFront(Node *head,int *data); + void DisplayLink(Node *head); + void DestroyLink(Node *head); + void product_run(Node *head); + void consumer_run(Node *head); + void test(void); +}; + +producerConsumer::producerConsumer(/* args */) +{ +} + +producerConsumer::~producerConsumer() +{ +} + +producerConsumer::Node *producerConsumer::CreatNode(int data) +{ + Node *NewNode=(Node *)malloc(sizeof(Node)); + if(NULL == NewNode) + { + perror("malloc"); + return NULL; + } + NewNode->data=data; + NewNode->next=NULL; + return NewNode; +} + +void producerConsumer::InitLink(Node **head) +{ + *head=CreatNode(0); +} + +int producerConsumer::IsEmpty(Node *head) +{ + assert(head); + if(head->next) + return 0; //not empty + else + return 1; //empty +} + +void producerConsumer::PushFront(Node *head,int data) +{ + assert(head); + Node *NewNode=CreatNode(data); + NewNode->next=head->next; + head->next=NewNode; +} + +void producerConsumer::PopFront(Node *head,int *data) +{ + assert(data); + assert(head); + if(IsEmpty(head)) + { + printf("empty link\n"); + return ; + } + Node *del=head->next; + *data=del->data; + head->next=del->next; + free(del); + del=NULL; +} + +void producerConsumer::DisplayLink(Node *head) +{ + assert(head); + Node *cur=head->next; + while(cur) + { + printf("%d ",cur->data); + cur=cur->next; + } + printf("\n"); +} + +void producerConsumer::DestroyLink(Node *head) +{ + int data=0; + assert(head); + while(!IsEmpty(head)) + { + PopFront(head,&data); + } + free(head); +} + +void producerConsumer::product_run(Node *head) +{ + int data=0; + while(1) + { + usleep(100000); + data=rand()%1000; + pthread_mutex_lock(&myLock); + PushFront(head,data); + pthread_mutex_unlock(&myLock); + pthread_cond_signal(&myCond); + printf("product is done,data=%d\n",data); + } +} + +void producerConsumer::consumer_run(Node *head) +{ + int data=0; + while(1) + { + pthread_mutex_lock(&myLock); + while(IsEmpty(head)) + { + pthread_cond_wait(&myCond,&myLock); + } + PopFront(head,&data); + pthread_mutex_unlock(&myLock); + printf("consumer is done,data=%d\n",data); + } +} +producerConsumer *model = new producerConsumer(); + +void *productTask(void *args) +{ + producerConsumer::Node *head = (producerConsumer::Node *)args; + model->product_run(head); + return nullptr; +} +void *consumerTask(void *args) +{ + producerConsumer::Node *head = (producerConsumer::Node *)args; + model->consumer_run(head); + return nullptr; +} + +int main(void) +{ + producerConsumer::Node *head = NULL; + model->InitLink(&head); + pthread_t tid1; + pthread_t tid2; + pthread_create(&tid1, NULL, productTask, head); + pthread_create(&tid2, NULL, consumerTask, head); + pthread_join(tid1,NULL); + pthread_join(tid2,NULL); + model->DestroyLink(head); + // pthread_mutex_destroy(&model->myLock); + // pthread_cond_destroy(&model->myCond); + return 0; +} \ No newline at end of file