diff --git a/README.md b/README.md index 157f0f9..e070059 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,30 @@ # understanding-cpp11 -c++ program examples using c++11. Partly use the gtest framework. +--- +c++ programming examples using c++11. Partly use the gtest framework. +![Solution Overview](http://7xi3zl.com1.z0.glb.clouddn.com/solution_overview.png "Solution Overview") +#项目简介 +此项目是《深入理解c++11》这本书的一个总结。 +由若干个短小的测试用例组成,展示了`c++11`主要的新特性的使用方法和注意事项。其中大部分例子的原型取自该书的代码片段,加入了自己的一些理解和改编。 +当前的文件列表如图: +![Topic Overview](http://7xi3zl.com1.z0.glb.clouddn.com/topic_overview.png "Topic Overview") + + +#开发环境 +`master`分支的开发环境是Visual Studio 2013(windows8.1 64bit, _MSC_VER == 1800),Visual AssistantX 10.9插件. +部分vc++编译器不支持的特性代码(如constexpr,user define literal等),使用了`_MSC_VER`选项进行了条件编译处理。 +`xcode_and_ubuntu`分支将使用`clang++`进行编译测试。 +后面将会只保留一个`master`分支,使用CMake的方式来做到跨平台构建。 + +#测试框架 +测试框架使用的是*Google*的`c++`单元测试框架`gtest`,版本是1.7.0。为了简单,使用静态库+header的方式引入。已经在.sln中配置好了,clone下来即可使用。 +此外,较早提交的文件使用的是自己写的一个小的测试框架,基类叫`Messi`, 待测试的类都继承`class Messi`,并且实现其`run`方法。测试的启动点在main.cpp里面的 +`ELLOOP_TEST`宏。 +内存泄露检查使用了vs自带的`crtdbg`。详见main.cpp. +![Memory Check](http://7xi3zl.com1.z0.glb.clouddn.com/memory_leak_check.png "Memory Check") #License Files under /include/gtest/ and /libs/gtestd.lib is copied and build from Google's unit test framework - gtest. The license is put in root dir called LICENSE-FOR-gtest(Google). -Other parts of this repository are MIT Licensed. +Other parts of this repository are NOT Licensed. ALL FREE. diff --git a/test/test.vcxproj b/test/test.vcxproj new file mode 100644 index 0000000..dba276c --- /dev/null +++ b/test/test.vcxproj @@ -0,0 +1,91 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {83BD9D54-0EB5-4B15-BE3A-E5F6DD8878A2} + Win32Proj + test + + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)\understanding-c++11;$(SolutionDir)\understanding-c++11\include;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\understanding-c++11\libs;%(AdditionalLibraryDirectories) + gtestd.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/test.vcxproj.filters b/test/test.vcxproj.filters new file mode 100644 index 0000000..cba2901 --- /dev/null +++ b/test/test.vcxproj.filters @@ -0,0 +1,19 @@ + + + + + {350266ee-9c90-4d12-b909-f40de58b99f3} + + + + + container + + + + + container + + + + \ No newline at end of file diff --git a/understanding-c++11/compatibility.cpp b/understanding-c++11/compatibility.cpp index 379b39a..beb9b99 100644 --- a/understanding-c++11/compatibility.cpp +++ b/understanding-c++11/compatibility.cpp @@ -15,7 +15,7 @@ void testNoexcept() { } Compatibility * Compatibility::run() { -#ifdef WIN32 +#ifdef _MSC_VER LOGD("in function : %s\n", __FUNCTION__); #else LOGD("in function : %s\n", __func__); @@ -44,7 +44,7 @@ void testC99Macro() { // psln(__STDC_HOSTED__); -#ifndef WIN32 +#ifndef _MSC_VER LOGD("Standard C: %d\n", __STDC__); #endif // psln(__STDC__); diff --git a/understanding-c++11/compatibility.h b/understanding-c++11/compatibility.h index 7c51ec7..0e52fa6 100644 --- a/understanding-c++11/compatibility.h +++ b/understanding-c++11/compatibility.h @@ -1,15 +1,15 @@ -#ifdef WIN32 +#ifdef _MSC_VER #pragma once #else _Pragma("once") -#endif // WIN32 +#endif // _MSC_VER #include "inc.h" #include "messi.h" NS_ELLOOP_BEGIN -#ifdef WIN32 +#ifdef _MSC_VER #if __cplusplus < 201103L #endif @@ -19,49 +19,48 @@ NS_ELLOOP_BEGIN #error "should use c++11 complier." #endif -#endif// WIN32 +#endif// _MSC_VER static_assert(sizeof(int) == 4, "sizeof int should be 4 bytes."); template class Printer; class Compatibility : public Messi { - public: - // using BaseTest::BaseTest(10); - Compatibility * run() final override; - private: - // local init. - int i_ = 0; - float f_ {1.1f}; +public: + // using BaseTest::BaseTest(10); + Compatibility * run() final override; +private: + // local init. + int i_ = 0; + float f_{ 1.1f }; - // new friend grammer. - friend Printer; + // new friend grammar. + friend Printer; }; // test final keyword. class Dc : public Compatibility { - public: - // Dc * run() {return this;} // error: run() is final in base-class Compatibility. +public: + // Dc * run() {return this;} // error: run() is final in base-class Compatibility. }; -// total template definiton. +// total template definition. template class Printer { - public: - void p(const T & t) { - pcln("in Printer"); - } +public: + void p(const T & t) { + pcln("in Printer"); + } }; -// partial sepcialization. +// partial specialization. template <> class Printer { - public: - void p(const Compatibility & t) { - psln(t.i_); - psln(t.f_); - } - private: +public: + void p(const Compatibility & t) { + psln(t.i_); + psln(t.f_); + } }; diff --git a/understanding-c++11/constructor_test.h b/understanding-c++11/constructor_test.h index e9690ea..0a8938e 100644 --- a/understanding-c++11/constructor_test.h +++ b/understanding-c++11/constructor_test.h @@ -1,8 +1,8 @@ -#ifdef WIN32 +#ifdef _MSC_VER #pragma once #else _Pragma("once") -#endif // WIN32 +#endif // _MSC_VER #include "messi.h" NS_ELLOOP_BEGIN diff --git a/understanding-c++11/decltype.h b/understanding-c++11/decltype.h index 05bb13f..b0c71a5 100644 --- a/understanding-c++11/decltype.h +++ b/understanding-c++11/decltype.h @@ -12,7 +12,7 @@ NS_BEGIN(decltype_test) class TypeA {}; class TypeB {}; -// testing anonymouse struct type. +// testing anonymous struct type. struct { int a; } a_struct_value; // testing using decltype in template function. diff --git a/understanding-c++11/initializer_test.h b/understanding-c++11/initializer_test.h index 2eb119f..be86618 100644 --- a/understanding-c++11/initializer_test.h +++ b/understanding-c++11/initializer_test.h @@ -1,8 +1,8 @@ -#ifdef WIN32 +#ifdef _MSC_VER #pragma once #else _Pragma("once") -#endif // WIN32 +#endif // _MSC_VER #include #include diff --git a/understanding-c++11/lambda_test.cpp b/understanding-c++11/lambda_test.cpp index 1a7f8a0..752e395 100644 --- a/understanding-c++11/lambda_test.cpp +++ b/understanding-c++11/lambda_test.cpp @@ -5,7 +5,8 @@ #include #include // accumulate -NS_ELLOOP_BEGIN +NS_BEGIN(elloop) +NS_BEGIN(lambda_test) TEST(Lambda, Simple) { int a(3), b(4); @@ -158,4 +159,5 @@ TEST(Lambda, LimitationOfLambda) { EXPECT_EQ(global_int, func()); } -NS_ELLOOP_END \ No newline at end of file +NS_END(lambda_test) +NS_END(elloop) diff --git a/understanding-c++11/lambda_test.h b/understanding-c++11/lambda_test.h index d01e05c..63f6903 100644 --- a/understanding-c++11/lambda_test.h +++ b/understanding-c++11/lambda_test.h @@ -2,11 +2,12 @@ #pragma once #else _Pragma("once") -#endif // WIN32 +#endif // _MSC_VER -#include "messi.h" +#include "inc.h" +NS_BEGIN(elloop) +NS_BEGIN(lambda_test) -NS_ELLOOP_BEGIN /* lambda formula: [capture](param) [mutable] ->return_type { body; } @@ -52,4 +53,5 @@ class DoubleFunctor { } }; -NS_ELLOOP_END \ No newline at end of file +NS_END(lambda_test) +NS_END(elloop) diff --git a/understanding-c++11/main.cpp b/understanding-c++11/main.cpp index 529bed9..31c467c 100644 --- a/understanding-c++11/main.cpp +++ b/understanding-c++11/main.cpp @@ -1,5 +1,5 @@ // memory leak check. -#ifdef _MSC_VER && _DEBUG +#if defined(_MSC_VER) && defined(_DEBUG) #define _CRTDBG_MAP_ALLOC #include #include @@ -28,7 +28,7 @@ void dummyExitFunction() { int main(int argc, char** argv) { -#ifdef _MSC_VER && _DEBUG +#if defined(_MSC_VER) && defined(_DEBUG) // make program stop when debug. atexit(dummyExitFunction); diff --git a/understanding-c++11/pod_test.h b/understanding-c++11/pod_test.h index e1ad77b..980d74c 100644 --- a/understanding-c++11/pod_test.h +++ b/understanding-c++11/pod_test.h @@ -1,36 +1,36 @@ -#ifdef WIN32 +#ifdef _MSC_VER #pragma once #else _Pragma("once") -#endif // WIN32 - -#include +#endif // _MSC_VER + +#include #include "messi.h" -#include "inc.h" - -NS_ELLOOP_BEGIN - -class PodTest : Messi { - public: - PodTest* run() override; -}; - -class t1 { -}; - -class t2 : public t1 { -}; - -class nt1 { -public: - nt1() { - pln("this is non-trivial"); - } -}; - -class nt2 { -public: - virtual void f() {} -}; - -NS_ELLOOP_END +#include "inc.h" + +NS_ELLOOP_BEGIN + +class PodTest : Messi { + public: + PodTest* run() override; +}; + +class t1 { +}; + +class t2 : public t1 { +}; + +class nt1 { +public: + nt1() { + pln("this is non-trivial"); + } +}; + +class nt2 { +public: + virtual void f() {} +}; + +NS_ELLOOP_END diff --git a/understanding-c++11/print_util.h b/understanding-c++11/print_util.h index bd0c54d..7791b83 100644 --- a/understanding-c++11/print_util.h +++ b/understanding-c++11/print_util.h @@ -1,8 +1,8 @@ -#ifdef WIN32 +#ifdef _MSC_VER #pragma once #else _Pragma("once") -#endif // WIN32 +#endif // _MSC_VER #include diff --git a/understanding-c++11/temp_test.cpp b/understanding-c++11/temp_test.cpp deleted file mode 100644 index c0fe508..0000000 --- a/understanding-c++11/temp_test.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "inc.h" -#include "gtest/gtest.h" -#include -USING_NS_STD; - -TEST(TempTest, Dummy) { - vector vi; - vector vb{ 1, 2, 3 }; - vb.assign(vi.begin(), vi.end()); - psln(vb.size()); -} \ No newline at end of file diff --git a/understanding-c++11/thread_test.cpp b/understanding-c++11/thread_test.cpp index 772985f..1d04bb4 100644 --- a/understanding-c++11/thread_test.cpp +++ b/understanding-c++11/thread_test.cpp @@ -1,6 +1,6 @@ #include "thread_test.h" -#ifndef WIN32 +#ifndef _MSC_VER #include #endif #include diff --git a/understanding-c++11/thread_test.h b/understanding-c++11/thread_test.h index f8b0890..9e2d227 100644 --- a/understanding-c++11/thread_test.h +++ b/understanding-c++11/thread_test.h @@ -1,8 +1,8 @@ -#ifdef WIN32 +#ifdef _MSC_VER #pragma once #else _Pragma("once") -#endif // WIN32 +#endif // _MSC_VER #include "inc.h" #include "messi.h" diff --git a/understanding-c++11/todo_next.h b/understanding-c++11/todo_next.h deleted file mode 100644 index 83b337f..0000000 --- a/understanding-c++11/todo_next.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - -// 2015/3/27 -// 1. rvalue, move semantic -// 2. constexpr -// 3. unicode - -// test tuple, function - -*/ \ No newline at end of file diff --git a/understanding-c++11/understanding-c++11.vcxproj b/understanding-c++11/understanding-c++11.vcxproj index a68833a..5642e59 100644 --- a/understanding-c++11/understanding-c++11.vcxproj +++ b/understanding-c++11/understanding-c++11.vcxproj @@ -96,7 +96,6 @@ - true @@ -113,6 +112,16 @@ + + + + + + + + + + @@ -133,14 +142,17 @@ true - + + + + diff --git a/understanding-c++11/understanding-c++11.vcxproj.filters b/understanding-c++11/understanding-c++11.vcxproj.filters index 7cc1611..e385d68 100644 --- a/understanding-c++11/understanding-c++11.vcxproj.filters +++ b/understanding-c++11/understanding-c++11.vcxproj.filters @@ -50,9 +50,6 @@ c++11 - - temp - c++11 @@ -140,7 +137,6 @@ c++11 - c++11 @@ -162,6 +158,39 @@ c++11 + + c++11 + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + @@ -170,8 +199,10 @@ {f0fb3859-0261-44c5-a9ec-b6687931184a} - - {ba7f57fb-afb5-4381-b9f5-87f0fcf3171e} - + + + + include + \ No newline at end of file diff --git a/understanding-c++11/unicode_support.h b/understanding-c++11/unicode_support.h new file mode 100644 index 0000000..b1b68d7 --- /dev/null +++ b/understanding-c++11/unicode_support.h @@ -0,0 +1,26 @@ +#ifdef _MSC_VER +#pragma once +#else +_Pragma("once") +#endif +#include "inc.h" + +NS_BEGIN(elloop) +NS_BEGIN(unicode_support) + +// ------------------ 3 prefix ------------------ +// 1. u8 : utf8 saved with char. +// 2. u : utf16 saved with char16_t. +// 3. U : utf32 saved with char32_t. + +void test() { +#ifdef _MSC_VER +#else + char utf8[] = u8"\u4F60\u597D\u554A"; + char16_t utf16[] = u"hello"; + char32_t utf32[] = U"hello = \u4F60\u597D\u554A"; +#endif +} + +NS_END(unicode_support) +NS_END(elloop) \ No newline at end of file diff --git a/understanding-c++11/user_define_literal.cpp b/understanding-c++11/user_define_literal.cpp index 3fd076a..ee0ecc1 100644 --- a/understanding-c++11/user_define_literal.cpp +++ b/understanding-c++11/user_define_literal.cpp @@ -5,8 +5,12 @@ NS_ELLOOP_BEGIN #ifdef _MSC_VER #else -Person operator "" _person(const char * name, int age) { - return Person(name, age); +Person operator "" _person(const char * data, unsigned int len) { + // just a demo, no real meaning. + Person p; + p.setName(data); + p.setAge(len); + return p; } #endif @@ -32,5 +36,17 @@ TEST(UserDefineLiteral, Construct) { } +void takePersion(Person p) +{ + +} +TEST(UserDefineLiteral, UsingLiteralConstruct) { +#ifdef _MSC_VER +#else + takePersion("Tom"_person); +#endif +} + + NS_ELLOOP_END \ No newline at end of file diff --git a/understanding-c++11/user_define_literal.h b/understanding-c++11/user_define_literal.h index ad8ba09..e9323dc 100644 --- a/understanding-c++11/user_define_literal.h +++ b/understanding-c++11/user_define_literal.h @@ -25,10 +25,14 @@ class Person { int age() { return age_; } + void setAge(int age) { + age_ = age > 0 ? age : 0; + } private: char name_[20]; int age_; }; +void takePersion(Person p); NS_ELLOOP_END \ No newline at end of file diff --git a/understanding-c++11/using_vs_typedef.cpp b/understanding-c++11/using_vs_typedef.cpp index 8590d5b..f26a7f3 100644 --- a/understanding-c++11/using_vs_typedef.cpp +++ b/understanding-c++11/using_vs_typedef.cpp @@ -5,14 +5,14 @@ NS_ELLOOP_BEGIN USING_NS_STD; TEST(Using, TemplateUsing) { - IntMap age_map{ - { "Tom", 11 }, - { "Jerry", 20 }, - { "David", 30 } - }; - bool same = std::is_same < decltype(age_map) - , std::map < std::string, int >> ::value; - EXPECT_TRUE(same); + IntMap age_map { + { "Tom", 11 }, + { "Jerry", 20 }, + { "David", 30 } + }; + bool same = std::is_same < decltype(age_map) + , std::map < std::string, int >> ::value; + EXPECT_TRUE(same); }