├── Code ├── Exceptions │ ├── performance_fun.hpp │ ├── compile_performance_13.sh │ ├── CMakeLists.txt │ ├── performance_fun.cxx │ ├── math_12.cpp │ ├── exception_specification_old_5.cpp │ ├── exception_destructor_9.cpp │ ├── exception_specification_new_6.cpp │ ├── rethrow_exception_4.cpp │ ├── get_current_exception_3.cpp │ ├── exception_constructor_8.cpp │ ├── stack_unwinding_1.cpp │ ├── performance_13.cxx │ ├── exception_inheritance_2.cpp │ ├── exception_specification_opt_7.cpp │ └── uncaught_exception_dctor_10.cpp ├── TypesAndValues │ ├── BrokenABI │ │ ├── library_old.hpp │ │ ├── library.hpp │ │ ├── library.cpp │ │ ├── CMakeLists.txt │ │ ├── pair1.hpp │ │ ├── pair2.hpp │ │ └── broken.cpp │ ├── copy_initialization2.cpp │ ├── C.cpp │ ├── CMakeLists.txt │ ├── member_initializer.cpp │ ├── array_vector_example.cpp │ ├── tuple.cpp │ ├── defaultdelete.cpp │ ├── value_initialization.cpp │ ├── initializer_list.cpp │ ├── zero_initialization.cpp.cpp │ ├── bitfield.cpp │ ├── copy_initialization.cpp │ ├── POD.cpp │ └── aggregate.cpp ├── STL │ ├── tuple │ │ ├── CMakeLists.txt │ │ ├── std_tuple.cpp │ │ ├── tie.cpp │ │ └── tuple_main.cpp │ ├── containers │ │ ├── vector_vs_list.cpp │ │ ├── deque.cpp │ │ ├── CMakeLists.txt │ │ ├── vector_vs_deque.cpp │ │ ├── list.cpp │ │ ├── set.cpp │ │ ├── vector_bool.cpp │ │ ├── vector_capacity.cpp │ │ ├── map.cpp │ │ ├── array.cpp │ │ └── emplace.cpp │ ├── allocator │ │ ├── CMakeLists.txt │ │ ├── stack.hpp │ │ ├── heap.hpp │ │ └── allocators.cpp │ ├── iterators │ │ ├── CMakeLists.txt │ │ ├── reverse_iterator.cpp │ │ ├── inserter.cpp │ │ ├── back_inserter.cpp │ │ ├── iterators_algebra.cpp │ │ ├── move_iterator.cpp │ │ └── vector_invalidation.cpp │ ├── integer_sequence │ │ ├── CMakeLists.txt │ │ └── tuple_to_pack.cpp │ └── CMakeLists.txt ├── StaticVariables │ ├── linking │ │ ├── init_static.hpp │ │ ├── init_static.cpp │ │ └── test_static.cpp │ └── initialization │ │ ├── static_init.cpp │ │ ├── const_init.cpp │ │ └── first_touch_init.cpp ├── TypeDeduction │ ├── qvsunq.cpp │ ├── first.cpp │ ├── CMakeLists.txt │ ├── overload.cpp │ ├── overloadv2.cpp │ ├── ADL2.cpp │ ├── usefulADL.cpp │ ├── overloadv3.cpp │ ├── ADL3.cpp │ ├── ADL1.cpp │ ├── conversion.cpp │ ├── ADL.cpp │ ├── decltype.cpp │ └── auto.cpp ├── tinysimd │ ├── test │ │ └── unit.cc │ ├── example │ │ ├── README.md │ │ ├── ex_mul_indexed.cc │ │ ├── ex_scatter_add.cc │ │ └── ex_sma.cc │ ├── README.md │ ├── include │ │ ├── tinysimd │ │ │ └── generic.h │ │ └── helpers.h │ └── bench │ │ └── bench_sma.cc ├── Constexpr │ ├── basic.cpp │ ├── Storage │ │ ├── stop_rec.cpp │ │ ├── index.cpp │ │ ├── strides.cpp │ │ ├── solution │ │ │ ├── storage.hpp │ │ │ ├── layout_map.hpp │ │ │ ├── storage_info_sol.hpp │ │ │ ├── storage_info.hpp │ │ │ └── storage_main.cpp │ │ └── storage_main.cpp │ ├── possible_exceptions.cpp │ ├── cxx17.cxx │ ├── ET │ │ ├── CMakeLists.txt │ │ ├── p.hpp │ │ ├── constant.hpp │ │ ├── expressions.hpp │ │ ├── automatic_differentiation.cpp │ │ ├── expr_times.hpp │ │ ├── expr_times_cxx11.hpp │ │ ├── expr_plus.hpp │ │ └── expr_plus_cxx11.hpp │ ├── CMakeLists.txt │ ├── use_with_const.cpp │ ├── static_const.cpp │ ├── constexpr_object_cxx11.cpp │ ├── check_if_constexpr.cpp │ ├── more_complex.cpp │ ├── constexpr_object.cpp │ └── tmp_vs_constexpr.cpp ├── CRTP │ └── CMakeLists.txt ├── Intro │ ├── CMakeLists.txt │ └── mm.cpp ├── Proxy │ ├── CMakeLists.txt │ ├── stream_proxy.cpp │ └── proxy_iterator.cpp ├── Random │ ├── CMakeLists.txt │ ├── random_cpp11_1.cpp │ ├── random_c_0.cpp │ ├── distributions_api_3.cpp │ └── generators_api_2.cpp ├── Threads │ ├── Intro │ │ ├── hello_world_1.cpp │ │ ├── CMakeLists.txt │ │ ├── exception_7.cpp │ │ ├── thread_guard_8.cpp │ │ ├── hello_world_callable_2.cpp │ │ ├── identification_6.cpp │ │ ├── passing_args_4.cpp │ │ ├── join_vs_detach_3.cpp │ │ └── ownership_5.cpp │ ├── DataSharing │ │ └── CMakeLists.txt │ ├── Synchronization │ │ ├── CMakeLists.txt │ │ ├── future_2.cpp │ │ ├── packaged_task_3.cpp │ │ └── promises_4.cpp │ └── CMakeLists.txt ├── Traits │ └── CMakeLists.txt ├── move_examples │ ├── qualified_member_functions.cpp │ ├── CMakeLists.txt │ ├── rvaluestemplate.cpp │ ├── call_copy_contructor.cpp │ ├── rvalues.cpp │ ├── copy_only.cpp │ ├── move_only.cpp │ ├── move_only_fail.cpp │ ├── real_world.cpp │ ├── move_and_copy.cpp │ ├── forward.cpp │ ├── move_constructor_automatic.cpp │ ├── move_constructor_fail.cpp │ ├── qualified_member_functions_II.cpp │ └── move_constructor.cpp ├── EnumClasses │ ├── CMakeLists.txt │ └── enum_classes.cpp ├── Generic │ ├── CMakeLists.txt │ └── graphtest.cpp ├── Lambdas │ ├── CMakeLists.txt │ ├── generic.cpp │ ├── function.cpp │ ├── return.cpp │ ├── lambdas_2.cpp │ ├── lambdas_1.cpp │ └── capture.cpp ├── SmartPtrs │ ├── CMakeLists.txt │ ├── dynamic_polymorph_3.cpp │ ├── object_cycle_2_1.cpp │ ├── mix_smart_raw_2.cpp │ ├── caching_factory_6.cpp │ ├── deleters_7.cpp │ ├── unique_ptr_5.cpp │ ├── this_8.cpp │ └── casting_4.cpp ├── Templates │ ├── CMakeLists.txt │ ├── violate_constness.cpp │ ├── structured_bindings.cpp │ ├── patternT.cpp │ ├── order.cpp │ ├── function_templates.cpp │ ├── specialization_partial_order.cpp.cpp │ ├── SFINAE.cpp │ ├── defaults.cpp │ ├── min.cpp │ ├── templates_02.cpp │ ├── void_t.cpp │ ├── templates_03.cpp │ ├── functionsastemplates.cpp │ ├── enable_if.cpp │ ├── templates_01.cpp │ ├── Deduction.cpp │ ├── alias.cpp │ ├── variadic.cpp │ ├── void_t_library.cpp │ ├── templatetemplate.cpp │ └── templates_04.cpp ├── TemplateMetaProgramming │ ├── CMakeLists.txt │ ├── integral_constant.cpp │ ├── factorial.cpp │ ├── fibonacci.cpp │ ├── check_member.cpp │ ├── factorial_protected.cpp │ └── max_size.cpp ├── CountDigits │ └── CMakeLists.txt ├── Alignment │ └── CMakeLists.txt ├── show.h ├── Concepts │ ├── pipes.hpp │ ├── cursor │ │ ├── range_loop.hpp │ │ └── any.hpp │ └── compose.hpp └── CMakeLists.txt ├── README.md ├── .gitmodules └── Exercises ├── TemplateMetaProgramming └── max_size.cpp ├── STL ├── tuple │ ├── constexpr_if.hpp │ └── tuple.cpp └── allocator │ └── allocator.cpp ├── SmartPtrs ├── dynamic_polymorph_3.cpp ├── deleters_7.cpp ├── mix_smart_raw_2.cpp ├── caching_factory_6.cpp ├── unique_ptr_5.cpp └── casting_4.cpp ├── Templates ├── exercise01.cpp ├── templates_02.cpp ├── templates_03.cpp └── templates_01.cpp ├── Constexpr └── Storage │ └── layout_map.hpp ├── Lambdas ├── lambdas_2.cpp ├── function_1.cpp └── lambdas_1.cpp ├── Proxy └── proxy_exercise.cpp ├── Exceptions ├── exception_constructor_8.cpp ├── uncaught_exceptions_dctor_11.cxx └── exception_specification_opt_7.cpp └── CRTP └── crtp_exercise.cpp /Code/Exceptions/performance_fun.hpp: -------------------------------------------------------------------------------- 1 | int test_fun(bool error); 2 | void test_fun_exc(bool error); 3 | -------------------------------------------------------------------------------- /Code/TypesAndValues/BrokenABI/library_old.hpp: -------------------------------------------------------------------------------- 1 | #include "pair1.hpp" 2 | 3 | void f(pair p); 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | After cloning 2 | 3 | ``` 4 | mkdir build 5 | cd build 6 | cmake ../Code 7 | make 8 | ``` 9 | -------------------------------------------------------------------------------- /Code/STL/tuple/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | add_executable( tuple_main tuple_main.cpp ) 4 | add_executable( tie tie.cpp) 5 | -------------------------------------------------------------------------------- /Code/TypesAndValues/BrokenABI/library.hpp: -------------------------------------------------------------------------------- 1 | #include "pair2.hpp" 2 | #include 3 | 4 | void f(pair p); 5 | -------------------------------------------------------------------------------- /Code/StaticVariables/linking/init_static.hpp: -------------------------------------------------------------------------------- 1 | template 2 | struct register_product{ 3 | static bool reg; 4 | }; 5 | -------------------------------------------------------------------------------- /Code/TypesAndValues/BrokenABI/library.cpp: -------------------------------------------------------------------------------- 1 | #include "library.hpp" 2 | 3 | void f(pair p) { 4 | std::cout << p.first << ", " << p.second << "\n"; 5 | } -------------------------------------------------------------------------------- /Code/TypeDeduction/qvsunq.cpp: -------------------------------------------------------------------------------- 1 | struct A { 2 | static int n; 3 | }; 4 | 5 | int A::n; 6 | 7 | int main() { 8 | int A; A=10; 9 | A::n = 42; 10 | //A b; 11 | } 12 | -------------------------------------------------------------------------------- /Code/tinysimd/test/unit.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) { 4 | ::testing::InitGoogleTest(&argc, argv); 5 | return RUN_ALL_TESTS(); 6 | } 7 | -------------------------------------------------------------------------------- /Code/Constexpr/basic.cpp: -------------------------------------------------------------------------------- 1 | constexpr double f(){return 13.2;} 2 | int main(){ 3 | constexpr double d=13.2; 4 | static_assert(d==13.2, ""); 5 | static_assert(f()==13.2, ""); 6 | } 7 | -------------------------------------------------------------------------------- /Code/TypeDeduction/first.cpp: -------------------------------------------------------------------------------- 1 | struct A { 2 | static int n; 3 | }; 4 | 5 | int A::n = 10; 6 | 7 | int main() { 8 | int A; A = 10; 9 | A::n = 42; 10 | // A b; 11 | } 12 | -------------------------------------------------------------------------------- /Code/Constexpr/Storage/stop_rec.cpp: -------------------------------------------------------------------------------- 1 | template 2 | constexpr int idx_impl(std::integer_sequence< int, Index > , Coord coord_) const{ 3 | return coord_; 4 | } 5 | -------------------------------------------------------------------------------- /Code/Exceptions/compile_performance_13.sh: -------------------------------------------------------------------------------- 1 | g++ -c performance_fun.cxx -I./ -DSKIP_ERR -O3 2 | g++ -c performance_13.cxx -I./ -O3 3 | g++ -o performance_13 performance_13.o performance_fun.o -DSKIP_ERR -O3 4 | 5 | -------------------------------------------------------------------------------- /Code/STL/tuple/std_tuple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | auto t_=std::make_tuple( std::string("my string"), 1.1, 'b'); 6 | std::cout<(t_)<<"\n"; 7 | } 8 | -------------------------------------------------------------------------------- /Code/Constexpr/Storage/index.cpp: -------------------------------------------------------------------------------- 1 | template 2 | constexpr int index(Ints ... coords_) const{ 3 | return idx_impl(std::make_integer_sequence(), coords_ ... ); 4 | } 5 | -------------------------------------------------------------------------------- /Code/STL/containers/vector_vs_list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(){ 4 | 5 | std::vector< int > l_(1e5); 6 | 7 | for(auto i=0; i < 1e5; i++){ 8 | l_.insert(l_.begin()+2*i, 8); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Code/TypesAndValues/BrokenABI/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(my_f SHARED library.cpp library.hpp pair1.hpp pair2.hpp) 2 | 3 | add_executable(broken broken.cpp library.hpp pair1.hpp pair2.hpp) 4 | target_link_libraries(broken my_f) 5 | -------------------------------------------------------------------------------- /Code/TypesAndValues/BrokenABI/pair1.hpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | template < typename F, typename S > 4 | struct pair { 5 | F first; 6 | S second; 7 | 8 | pair(F f, S s) : first{f}, second{s} {} 9 | 10 | ~pair() {} 11 | }; 12 | -------------------------------------------------------------------------------- /Code/Constexpr/possible_exceptions.cpp: -------------------------------------------------------------------------------- 1 | constexpr int divide(int id) { 2 | return id>0 ? id+id/divide(id-1) : id; 3 | }; 4 | int main(){ 5 | // The following line would fail 6 | // static_assert(divide(4)>0, "error"); //error 7 | } 8 | -------------------------------------------------------------------------------- /Code/TypesAndValues/BrokenABI/pair2.hpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | template < typename F, typename S > 4 | struct pair { 5 | F first; 6 | S second; 7 | 8 | pair(F f, S s) : first{f}, second{s} {} 9 | 10 | ~pair() = default; 11 | }; 12 | -------------------------------------------------------------------------------- /Code/CRTP/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/Intro/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/Proxy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/Random/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/STL/containers/deque.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(){ 4 | 5 | std::deque< int > l_(1e8); 6 | 7 | for(auto i=1; i < 1e8; i++){ 8 | l_.push_back(8); 9 | //l_.insert(l_.begin(), 8); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Code/Threads/Intro/hello_world_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | void hello() 6 | { 7 | std::cout<<"Hello world!"<int{ return 5;}; 7 | static_assert(f()==5, "error"); // this does not work 8 | } 9 | -------------------------------------------------------------------------------- /Code/EnumClasses/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/Exceptions/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/Generic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/Lambdas/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/SmartPtrs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/Templates/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/Constexpr/ET/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/STL/allocator/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/STL/containers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/STL/containers/vector_vs_deque.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(){ 4 | 5 | std::vector< int > l_(1e8); 6 | 7 | for(auto i=1; i < 1e8; i++){ 8 | l_.push_back(8); 9 | //l_.insert(l_.begin(), 8); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Code/STL/iterators/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/Threads/Intro/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/TypeDeduction/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/move_examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/STL/integer_sequence/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/Threads/DataSharing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/TemplateMetaProgramming/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /Code/Threads/Synchronization/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Code/tinysimd/import/gbench"] 2 | path = Code/tinysimd/import/gbench 3 | url = https://github.com/google/benchmark 4 | [submodule "Code/tinysimd/import/gtest"] 5 | path = Code/tinysimd/import/gtest 6 | url = https://github.com/google/googletest 7 | -------------------------------------------------------------------------------- /Code/Constexpr/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | 7 | add_subdirectory(ET) 8 | -------------------------------------------------------------------------------- /Code/STL/containers/list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(){ 7 | std::list< int > l_(1e5); 8 | 9 | for(auto i=l_.begin(); i != l_.end(); i++){ 10 | l_.insert(i, 8); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Code/STL/iterators/reverse_iterator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(){ 6 | std::vector v{0,1,2,3}; 7 | for(auto i=v.rbegin(); i!=v.rend(); ++i) 8 | std::cout<<*i<<" "; 9 | std::cout<<"\n"; 10 | } 11 | -------------------------------------------------------------------------------- /Code/Constexpr/use_with_const.cpp: -------------------------------------------------------------------------------- 1 | template class A {}; 2 | 3 | constexpr int sqr1(int arg) 4 | { return arg * arg; } 5 | 6 | int sqr2(int arg) 7 | { return arg * arg; } 8 | 9 | int main() 10 | { 11 | const int X = 2; 12 | A mylist1; 13 | //A mylist2; 14 | } 15 | -------------------------------------------------------------------------------- /Code/TemplateMetaProgramming/integral_constant.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct integral_constant { 3 | typedef T value_type; 4 | static constexpr value_type value = v; 5 | }; 6 | 7 | 8 | 9 | int main() { 10 | static_assert(integral_constant::value == 7, "Error"); 11 | } 12 | -------------------------------------------------------------------------------- /Code/TypesAndValues/copy_initialization2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct T { 4 | T() = default; 5 | T(T const&) = default; 6 | T(T&&, int =10) {} 7 | }; 8 | 9 | void f(T x) {} 10 | 11 | int main() { 12 | T y; 13 | f(y); 14 | f(T{}); 15 | f(std::move(y)); 16 | } 17 | -------------------------------------------------------------------------------- /Code/CountDigits/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | target_link_libraries( ${target_n} ${Boost_LIBRARIES} ) 6 | endforeach() 7 | -------------------------------------------------------------------------------- /Code/Constexpr/static_const.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int foo(int a) { return a*a; }; 4 | constexpr int fooc(int a) { return a*a; }; 5 | 6 | static const int x = fooc(10); 7 | 8 | constexpr int y = fooc(10); 9 | 10 | int main() { 11 | std::cout << x << "\n"; 12 | std::cout << y << "\n"; 13 | } 14 | -------------------------------------------------------------------------------- /Code/StaticVariables/linking/init_static.cpp: -------------------------------------------------------------------------------- 1 | #include "init_static.hpp" 2 | #include 3 | template<> 4 | bool register_product::reg = [](){std::cout<<"initializing double\n"; return true;}(); 5 | template<> 6 | bool register_product::reg = [](){std::cout<<"initializing float\n"; return true;}(); 7 | -------------------------------------------------------------------------------- /Code/Random/random_cpp11_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | std::default_random_engine e(232323); 6 | std::uniform_real_distribution d{0,1}; 7 | for(unsigned int i=0;i<10;++i){ 8 | double rnd = d(e); 9 | std::cout<<"Random number value: "< 2 | #include 3 | 4 | int main(){ 5 | std::set< double > m_; 6 | 7 | m_.insert( 0. ); 8 | m_.insert( 1. ); 9 | m_.insert( 1. ); 10 | 11 | auto val=m_.find(1.); 12 | 13 | std::cout<<*val<<"\n"; 14 | std::cout<<"size: "< 2 | 3 | struct C { 4 | C(int) { std::cout << "C(int)\n"; } 5 | C(int, int) { std::cout << "C(int)\n"; } 6 | C(std::initializer_list && ) { std::cout << "C(std::initializer_list&&)\n"; } 7 | }; 8 | 9 | int main() { 10 | C a(10); 11 | C b{10}; 12 | } 13 | -------------------------------------------------------------------------------- /Code/tinysimd/example/README.md: -------------------------------------------------------------------------------- 1 | ## Example code for asm generation 2 | 3 | Source `*.cc` in this directory will be compiled to assembly and filtered 4 | for readability, to produce corresponding files `*.asm` in the build directory. 5 | 6 | `make examples` will compile all examples; `make ex_foo.asm` will produce 7 | just `ex_foo.asm`. 8 | -------------------------------------------------------------------------------- /Code/TypesAndValues/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | 3 | message(${CMAKE_CXX_FLAGS}) 4 | foreach( target_s ${SOURCES} ) 5 | string( REPLACE ".cpp" "" target_n ${target_s} ) 6 | add_executable( ${target_n} ${target_s} ) 7 | endforeach() 8 | 9 | add_subdirectory(BrokenABI) 10 | -------------------------------------------------------------------------------- /Code/TypesAndValues/member_initializer.cpp: -------------------------------------------------------------------------------- 1 | #include "../show.h" 2 | 3 | struct X { 4 | int a = 10; 5 | int b = 22; 6 | 7 | X() = default; 8 | X(int x) : a(x) {} 9 | }; 10 | 11 | int main () { 12 | X x(34); 13 | SHOW(x.a); 14 | SHOW(x.b); 15 | 16 | X y; 17 | SHOW(y.a); 18 | SHOW(y.b); 19 | 20 | }; 21 | -------------------------------------------------------------------------------- /Code/Random/random_c_0.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | std::cout<<"RAND_MAX value: "< 2 | struct my_stack_allocator{ 3 | T data[100]; 4 | using value_type=T; 5 | 6 | T* allocate (int n, std::allocator::const_pointer hint=0){ 7 | if(n<100) return data; 8 | else throw(std::bad_alloc()); 9 | } 10 | void deallocate (T* p, int n){/*RAII*/} 11 | }; 12 | -------------------------------------------------------------------------------- /Code/STL/iterators/inserter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(){ 6 | 7 | std::vector v{8,8}; 8 | auto i = std::inserter(v, v.begin()); 9 | for(int j=0; j<5; j++, i) 10 | i=j; 11 | 12 | for(int j : v) 13 | std::cout< 2 | #include 3 | #include 4 | 5 | int main(){ 6 | 7 | std::vector v{8,8}; 8 | auto i = std::back_inserter(v); 9 | for(int j=0; j<5; j++, i) 10 | i=j; 11 | 12 | for(int j : v) 13 | std::cout< 2 | struct my_heap_allocator{ 3 | using value_type=T; 4 | 5 | T* allocate (int n, std::allocator::const_pointer hint=0){ 6 | if(n<100) return static_cast(malloc(n*sizeof(T))); 7 | else throw(std::bad_alloc()); 8 | } 9 | void deallocate (T* p, int n){free(p);} 10 | }; 11 | -------------------------------------------------------------------------------- /Code/Alignment/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | if ( NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) 6 | target_link_libraries( ${target_n} "-latomic") 7 | endif() 8 | endforeach() 9 | -------------------------------------------------------------------------------- /Code/Constexpr/Storage/strides.cpp: -------------------------------------------------------------------------------- 1 | template 3 | constexpr int idx_impl(std::integer_sequence< int, CurK, RestK ... > 4 | , CurC first_coord_ , RestC ... coords_) const { 5 | return first_coord_ 6 | + m_dims[CurK] 7 | * idx_impl(std::integer_sequence(), coords_ ...); 8 | } 9 | -------------------------------------------------------------------------------- /Code/TemplateMetaProgramming/factorial.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | struct factorial { 5 | static constexpr unsigned value = N * factorial::value; 6 | }; 7 | 8 | template <> 9 | struct factorial<1> { 10 | static constexpr unsigned value=1; 11 | }; 12 | 13 | 14 | int main() { 15 | std::cout << factorial<5>::value << "\n"; // movl $120, %esi 16 | } -------------------------------------------------------------------------------- /Code/STL/containers/vector_bool.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(){ 6 | 7 | std::vector< bool > v_={true, false, true}; 8 | std::cout< b_(0b101); 10 | std::cout< 2 | #include 3 | #include 4 | 5 | int main(){ 6 | std::vector m{0,1,2,3}; 7 | auto it=std::begin(m); 8 | auto it2=std::next(it); 9 | assert(*it == 0); 10 | assert(*it2 == 1); 11 | assert(std::distance(it, it2)==1); 12 | assert(*std::prev(it2) == 0); 13 | assert(*std::prev(std::end(m)) == 3); 14 | } 15 | -------------------------------------------------------------------------------- /Code/Constexpr/constexpr_object_cxx11.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct my_const_struct{ 5 | int m_i; 6 | 7 | constexpr my_const_struct(int x) : m_i(x) { } 8 | constexpr int get() const {return m_i;} 9 | }; 10 | 11 | int main(){ 12 | constexpr my_const_struct my_struct(10); 13 | std::cout< 2 | #include "../show.h" 3 | 4 | template 5 | int inc(T const& x) { 6 | return ++x; 7 | } 8 | 9 | int main() { 10 | int y = 10; 11 | 12 | // foo(10): does not compile since ++x requires a mutable object 13 | // foo(y): does not compile since ++x requires a mutable object 14 | 15 | SHOW(inc(y)); 16 | SHOW(y); 17 | } 18 | -------------------------------------------------------------------------------- /Exercises/TemplateMetaProgramming/max_size.cpp: -------------------------------------------------------------------------------- 1 | // A metafunction that finds the type in a sequence of types 2 | // that has the biggest sizeof value, plus it should return the size 3 | 4 | #include "../../Code/show.h" 5 | 6 | int main() { 7 | SHOW((find_max_size::value)); 8 | static_assert((std::is_same::type>::value), "not ok"); 9 | } 10 | -------------------------------------------------------------------------------- /Code/STL/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file( GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) 2 | foreach( target_s ${SOURCES} ) 3 | string( REPLACE ".cpp" "" target_n ${target_s} ) 4 | add_executable( ${target_n} ${target_s} ) 5 | endforeach() 6 | 7 | add_subdirectory( iterators ) 8 | add_subdirectory( tuple ) 9 | add_subdirectory( containers ) 10 | add_subdirectory( integer_sequence ) 11 | add_subdirectory( allocator ) 12 | -------------------------------------------------------------------------------- /Code/STL/containers/vector_capacity.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | std::vector< char > v_(2001); 6 | std::cout< 2 | #include 3 | #include 4 | 5 | struct my_class{ 6 | my_class() = default; 7 | my_class(my_class const&){std::cout<<"Copy\n";}; 8 | my_class(my_class &&){std::cout<<"Move\n";}; 9 | }; 10 | 11 | int main(){ 12 | std::vector v(1); 13 | auto it = v.begin(); 14 | //auto it = make_move_iterator(v.begin()); 15 | auto moved=my_class(*it); 16 | } 17 | -------------------------------------------------------------------------------- /Exercises/STL/tuple/constexpr_if.hpp: -------------------------------------------------------------------------------- 1 | template 2 | struct constexpr_if; 3 | 4 | template<> 5 | struct constexpr_if{ 6 | template 7 | static constexpr Left apply(Left l_, Right r_) 8 | {return l_;} 9 | }; 10 | 11 | template<> 12 | struct constexpr_if{ 13 | template 14 | static constexpr Right apply(Left l_, Right r_) 15 | {return r_;} 16 | }; 17 | -------------------------------------------------------------------------------- /Code/STL/containers/map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | std::map< std::string, double > m_; 6 | 7 | m_.insert(std::make_pair("first", 0.)); 8 | m_.insert(std::make_pair("second", 1.)); 9 | m_.insert(std::make_pair("third", 1.)); 10 | m_.insert(std::make_pair("third", 10.)); 11 | 12 | double val=m_.find("third")->second; 13 | std::cout< struct p { 5 | 6 | using value_type = U; 7 | constexpr p(){}; 8 | 9 | template constexpr T operator()(T t_) const { return t_; } 10 | std::string to_string() const { return std::string(" x "); } 11 | 12 | constexpr int sum_ops() const { return 0; } 13 | constexpr int mult_ops() const { return 0; } 14 | }; 15 | 16 | constexpr auto x = p(); 17 | } 18 | -------------------------------------------------------------------------------- /Code/StaticVariables/initialization/static_init.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | struct S { 3 | static int s_c; 4 | }; 5 | struct D{ 6 | static int s_d ; 7 | }; 8 | struct F{ 9 | static int s_f ; 10 | }; 11 | int F::s_f = 10 * D::s_d; 12 | int D::s_d = 10 * S::s_c; 13 | int S::s_c = 5; 14 | int main(){ 15 | std::cout << "s_f = " << F::s_f << '\n'; // 0 16 | std::cout << "s_d = " << D::s_d << '\n'; // 50 17 | std::cout << "s_c = " << S::s_c << '\n';}// 5 18 | -------------------------------------------------------------------------------- /Code/STL/iterators/vector_invalidation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(){ 7 | int t=0; 8 | // std::vector< int > l_(10); 9 | // for(auto i=l_.begin(); i != l_.end() ; i++){ 10 | // l_.insert(i, t); 11 | // } 12 | std::list< int > l_(10); 13 | for(auto i=l_.begin(); i != l_.end() ; i++){ 14 | l_.insert(i, t); 15 | } 16 | std::cout< 2 | int main(){ 3 | constexpr std::array arr_{0,1,2,3,4}; 4 | static_assert(arr_[2] == 2, "error"); 5 | static_assert(std::get<2>(arr_) == 2, "error"); 6 | static_assert(arr_.size() == 5, "error"); 7 | static_assert(arr_.back() == 4, "error"); 8 | static_assert(arr_.front() == 0, "error"); 9 | std::array arr1_{1,0}, arr2_{0,1}; 10 | arr2_.swap(arr1_); 11 | auto out_of_bound=arr1_[5]; 12 | } 13 | -------------------------------------------------------------------------------- /Code/TypeDeduction/overload.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int foo(int, int) {std::cout << __PRETTY_FUNCTION__ << "\n"; return 0;} 4 | 5 | double foo(float, int) {std::cout << __PRETTY_FUNCTION__ << "\n"; return 0.;} 6 | 7 | template 8 | char foo(T, int) {std::cout << __PRETTY_FUNCTION__ << "\n"; return '\n';} 9 | 10 | int main() { 11 | foo(3,4); 12 | foo(3,4.3); 13 | foo(3.4,4); 14 | foo(3.4f,4); 15 | foo(3.4,4.5); 16 | foo(3.4f,4.5f); 17 | } 18 | -------------------------------------------------------------------------------- /Code/Constexpr/ET/constant.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template struct c { 4 | T value; 5 | 6 | constexpr c(T x) : value{x} {}; 7 | 8 | constexpr operator T() const { return value; } 9 | 10 | template constexpr T operator()(U) const { return value; } 11 | 12 | std::string to_string() const { return "{" + std::to_string(value) + "}"; } 13 | 14 | constexpr int sum_ops() const { return 0; } 15 | 16 | constexpr int mult_ops() const { return 0; } 17 | }; 18 | -------------------------------------------------------------------------------- /Code/Exceptions/performance_fun.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int __attribute__ ((noinline)) test_fun(bool error) { 5 | 6 | int error_status = 0; 7 | 8 | if(error){ 9 | #ifdef SKIP_ERR 10 | error_status = 1; 11 | #endif 12 | } 13 | 14 | return error_status; 15 | } 16 | 17 | void __attribute__ ((noinline)) test_fun_exc(bool error) { 18 | 19 | if(error){ 20 | #ifdef SKIP_ERR 21 | throw std::exception(); 22 | #endif 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Code/show.h: -------------------------------------------------------------------------------- 1 | #ifndef _EXAMPLES_CPP_CODE_SHOW_H_ 2 | #define _EXAMPLES_CPP_CODE_SHOW_H_ 3 | #include 4 | 5 | #define SHOW(X) std::cout << #X << " : " << X << "\n"; 6 | #define SHOW_BOOL(X) std::cout << #X << " : " << std::boolalpha << X << "\n"; 7 | #define SHOW_PREFIX(P,X) std::cout << P << "\n" << #X << "\n" << X << "\n"; 8 | #define OUT(B) std::ostream& operator<<(std::ostream &s, B a) 9 | 10 | #define __DODO(x) x 11 | #define DO(x) std::cout << #x << "\n"; __DODO x 12 | #endif 13 | -------------------------------------------------------------------------------- /Code/TypeDeduction/overloadv2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int foo(int, int) {std::cout << __PRETTY_FUNCTION__ << "\n"; return 0;} 4 | 5 | double foo(int, float) {std::cout << __PRETTY_FUNCTION__ << "\n"; return 0.;} 6 | 7 | //template 8 | //char foo(T, int) {std::cout << __PRETTY_FUNCTION__ << "\n"; return '\n';} 9 | 10 | int main() { 11 | foo(3,4); 12 | // foo(3,4.3); 13 | foo(3.4,4); 14 | foo(3.4f,4); 15 | //foo(3.4,4.5); 16 | foo(3.4f,4.5f); 17 | } 18 | -------------------------------------------------------------------------------- /Code/move_examples/rvaluestemplate.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | void foo(T&& x) { 6 | if (std::is_same::value) { 7 | std::cout << "T&\n"; 8 | } else 9 | if (std::is_same::value) { 10 | std::cout << "T&&\n"; 11 | } else { 12 | std::cout << "Something else\n"; 13 | } 14 | } 15 | 16 | int main() { 17 | int i = 19; 18 | foo(i); 19 | foo(i); 20 | foo(42); 21 | } 22 | -------------------------------------------------------------------------------- /Code/TemplateMetaProgramming/fibonacci.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | struct fibonacci { 5 | static constexpr unsigned value = fibonacci::value + fibonacci::value; 6 | }; 7 | 8 | template <> 9 | struct fibonacci<1> { 10 | static constexpr unsigned value = 1; 11 | }; 12 | 13 | template <> 14 | struct fibonacci<0> { 15 | static constexpr unsigned value = 0; 16 | }; 17 | 18 | int main() { 19 | std::cout << fibonacci<6>::value << "\n"; // movl $8, %esi 20 | } 21 | -------------------------------------------------------------------------------- /Code/TypeDeduction/ADL2.cpp: -------------------------------------------------------------------------------- 1 | template 2 | void foo(T,U) {}; 3 | 4 | namespace N0 { 5 | struct X{}; 6 | template 7 | void foo(X,T) {} 8 | } 9 | namespace N1 { 10 | struct Y {}; 11 | template 12 | void foo(T,Y) {} 13 | } 14 | 15 | int main() { 16 | // The following is ambiguous for all the candidates 17 | //foo(N0::X{}, N1::Y{}); 18 | 19 | ::foo(N0::X{}, N1::Y{}); 20 | N0::foo(N0::X{}, N1::Y{}); 21 | N1::foo(N0::X{}, N1::Y{}); 22 | } 23 | -------------------------------------------------------------------------------- /Code/StaticVariables/initialization/const_init.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | struct S { 3 | static constexpr int s_c = 5; 4 | }; 5 | struct D{ 6 | static constexpr int s_d = 10 * S::s_c ; 7 | }; 8 | struct F{ 9 | static constexpr int s_f = 10 * D::s_d ; 10 | }; 11 | constexpr int F::s_f; 12 | constexpr int D::s_d; 13 | constexpr int S::s_c; 14 | int main(){ 15 | std::cout << "s_f = " << F::s_f << '\n'; // 500 16 | std::cout << "s_d = " << D::s_d << '\n'; // 50 17 | std::cout << "s_c = " << S::s_c << '\n';}// 5 18 | -------------------------------------------------------------------------------- /Code/Constexpr/Storage/solution/storage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "storage_info.hpp" 3 | 4 | // storage allocated on the heap 5 | struct storage{ 6 | template 7 | storage(storage_info const& info_) : 8 | m_data(new double[info_.size()]) 9 | {} 10 | ~storage(){ delete[] m_data; } 11 | 12 | template 13 | double operator()(StorageInfo info_, Ints ... ids){ 14 | return m_data[info_.index(ids ...)]; 15 | } 16 | private: 17 | double* m_data; 18 | }; 19 | -------------------------------------------------------------------------------- /Code/Constexpr/check_if_constexpr.cpp: -------------------------------------------------------------------------------- 1 | struct test{ 2 | constexpr test(int arg_) : m_val{arg_}{} 3 | constexpr int get() const {return m_val;} 4 | int m_val; 5 | }; 6 | 7 | int main(){ 8 | constexpr test t1_(5); 9 | test t2_(10); 10 | constexpr bool check_t1_ = (noexcept(t1_.get())); 11 | constexpr bool check_t2_ = (noexcept(t2_.get())); 12 | 13 | #ifndef __clang__ 14 | #if __GNUG__ < 6 15 | static_assert(check_t1_==true, "error"); 16 | static_assert(check_t2_==false, "error"); 17 | #endif 18 | #endif 19 | } 20 | -------------------------------------------------------------------------------- /Code/StaticVariables/initialization/first_touch_init.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | static int D(); 3 | static int S(); 4 | 5 | static int F(){ 6 | static int m_f=10 * D() ; 7 | return m_f; 8 | } 9 | 10 | static int D(){ 11 | static int m_d = 10 * S() ; 12 | return m_d; 13 | } 14 | 15 | static int S() { 16 | static int m_c=5; 17 | return m_c; 18 | } 19 | 20 | int main() 21 | { 22 | std::cout << "m_f = " << F() << '\n'; 23 | std::cout << "m_d = " << D() << '\n'; 24 | std::cout << "m_c = " << S() << '\n'; 25 | } 26 | -------------------------------------------------------------------------------- /Code/TypeDeduction/usefulADL.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | namespace X { 6 | 7 | struct A {}; 8 | 9 | void foo(A) { 10 | std::cout << "I'm X\n"; 11 | } 12 | } 13 | 14 | namespace Y { 15 | 16 | struct A {}; 17 | 18 | void foo(A) { 19 | std::cout << "I'm Y\n"; 20 | } 21 | } 22 | 23 | 24 | template 25 | void bar(T const& x) { 26 | foo(x); 27 | } 28 | 29 | int main() { 30 | X::A xa; 31 | Y::A ya; 32 | 33 | bar(xa); 34 | bar(ya); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Exercises/SmartPtrs/dynamic_polymorph_3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct Base{ 7 | 8 | virtual std::string f(void) const { return "Base"; } 9 | }; 10 | 11 | 12 | struct Derived : public Base { 13 | 14 | std::string f(void) const { return "Derived"; } 15 | }; 16 | 17 | 18 | int main(){ 19 | 20 | // 0 - Update using only std::shared_ptr 21 | Base* p_base = new Derived(); 22 | 23 | // 1 - What is the called f() method? 24 | assert(sp_base->f() == ???); 25 | } 26 | -------------------------------------------------------------------------------- /Code/move_examples/call_copy_contructor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct A { 4 | int generation = 0; 5 | A() { std::cout << "D " << generation << "\n"; } 6 | //A(A const& a) : generation{a.generation+1} { std::cout << "C " << generation << "\n"; } 7 | A& operator=(A const& a) { generation = a.generation+1; std::cout << "A " << generation << "\n"; return *this; }; 8 | ~A() { std::cout << "X " << generation << "\n"; }; 9 | }; 10 | 11 | int main() { 12 | A a; 13 | A b{a}; 14 | A c = b; 15 | A d; 16 | d = c; 17 | } 18 | -------------------------------------------------------------------------------- /Code/SmartPtrs/dynamic_polymorph_3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct Base{ 7 | 8 | virtual std::string f(void) const { return "Base"; } 9 | }; 10 | 11 | 12 | struct Derived : public Base { 13 | 14 | std::string f(void) const { return "Derived"; } 15 | }; 16 | 17 | 18 | int main(){ 19 | 20 | // 0 - Update using only std::shared_ptr 21 | std::shared_ptr sp_base(new Derived); 22 | 23 | // 1 - What is the called f() method? 24 | assert(sp_base->f() == "Derived"); 25 | } 26 | -------------------------------------------------------------------------------- /Code/move_examples/rvalues.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../show.h" 3 | 4 | int f(int &x) { 5 | std::cout << "int&\n"; 6 | return x; 7 | } 8 | 9 | int f(int&& x) { 10 | std::cout << "int&&\n"; 11 | return x; 12 | } 13 | 14 | struct A { 15 | void operator()() & { 16 | std::cout << "A&\n"; 17 | } 18 | 19 | void operator()() && { 20 | std::cout << "A&&\n"; 21 | } 22 | }; 23 | 24 | int main() { 25 | int x = 10; 26 | f(x); 27 | f(10); 28 | 29 | A a; 30 | a(); 31 | A()(); 32 | } 33 | -------------------------------------------------------------------------------- /Code/move_examples/copy_only.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../show.h" 5 | 6 | struct movable { 7 | std::vector v; 8 | 9 | movable(int s) : v(s) {std::cout << "Default\n";} 10 | //movable(movable&& other) = delete; 11 | movable(movable const & other) : v(other.v) {std::cout << "Copy\n";} 12 | }; 13 | 14 | int main() { 15 | movable z(movable(200)); 16 | SHOW(z.v.size()); 17 | //movable w(z); 18 | movable u(std::move(z)); 19 | SHOW(z.v.size()); 20 | SHOW(u.v.size()); 21 | } 22 | -------------------------------------------------------------------------------- /Code/Templates/structured_bindings.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "../show.h" 6 | 7 | template 8 | std::tuple values(Ts&&... as) { 9 | return std::make_tuple(std::forward(as)...); 10 | } 11 | 12 | int main() { 13 | 14 | int a[2] = { 3,4 }; 15 | 16 | auto [x, y] = a; 17 | std::cout << x << ", " << y << "\n"; 18 | 19 | auto [u, v, w] = values(3.4, std::string{"hello"}, 8); 20 | std::cout << u << ", " 21 | << v << ", " 22 | << w << "\n"; 23 | } 24 | -------------------------------------------------------------------------------- /Exercises/Templates/exercise01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct record_t { 5 | std::string firstname, lastname; 6 | int age; 7 | }; 8 | 9 | std::ostream& operator<<(std::ostream &s, record_t const& x) { 10 | return s << "{ first: " << x.firstname << ", last: " << x.lastname << ", age: " << x.age << " }"; 11 | } 12 | 13 | int main() { 14 | /* Implement afacility to make this code to work as expected */ 15 | auto record = record_t( lastname = "Bianco", age = 21, firstname = "Mauro" ); 16 | std::cout << record << "\n"; 17 | } 18 | -------------------------------------------------------------------------------- /Code/Threads/Intro/exception_7.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void f() { 6 | 7 | std::cout<<"Start work in f()"< 2 | 3 | /* 1 */ int foo(int, int) {std::cout << __PRETTY_FUNCTION__ << "\n"; return 0;} 4 | 5 | /* 2 */ double foo(int, float) {std::cout << __PRETTY_FUNCTION__ << "\n"; return 0.;} 6 | 7 | template 8 | /* 3 */ char foo(T, int) {std::cout << __PRETTY_FUNCTION__ << "\n"; return '\n';} 9 | 10 | int main() { 11 | /* A */ foo(3,4); 12 | 13 | /* B */ //foo(3,4.3); 14 | 15 | /* C */ foo(3.4,4); 16 | 17 | /* D */ foo(3.4f,4); 18 | 19 | /* E */ foo(3.4,4.5); 20 | 21 | /* F */ //foo(3.4f,4.5f); 22 | } 23 | -------------------------------------------------------------------------------- /Code/Threads/Synchronization/future_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | std::thread::id f(double i_d, double& io_d) { 6 | io_d = i_d; 7 | std::this_thread::sleep_for(std::chrono::seconds(5)); 8 | return std::this_thread::get_id(); 9 | } 10 | 11 | int main() { 12 | 13 | double d=0.; 14 | std::future get_id = std::async(std::launch::async,f,23.0,std::ref(d)); 15 | std::cout<<"std::this_thread::get_id() "< v; 8 | 9 | movable(int s) : v(s) {std::cout << "Default\n";} 10 | //movable(movable&& other) : v(std::move(other.v)) {std::cout << "Move\n";} 11 | //movable(movable const & other) : v(other.v) {std::cout << "Copy\n";} 12 | }; 13 | 14 | int main() { 15 | movable z(movable(200)); 16 | SHOW(z.v.size()); 17 | movable w(z); 18 | movable u(std::move(z)); 19 | SHOW(z.v.size()); 20 | SHOW(u.v.size()); 21 | } 22 | -------------------------------------------------------------------------------- /Code/SmartPtrs/object_cycle_2_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct B; 5 | 6 | struct A { 7 | 8 | ~A(){ 9 | std::cout<<"A dtor"< m_ptr; 13 | }; 14 | 15 | struct B { 16 | 17 | ~B(){ 18 | std::cout<<"B dtor"< m_ptr; 23 | std::shared_ptr m_ptr; 24 | }; 25 | 26 | int main() { 27 | 28 | 29 | std::shared_ptr a(new A); 30 | std::shared_ptr b(new B); 31 | 32 | a->m_ptr = b; 33 | b->m_ptr = a; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Code/Exceptions/math_12.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | 7 | std::feclearexcept(math_errhandling); 8 | double logval = std::log(-1.); 9 | if(std::fetestexcept(math_errhandling)) { 10 | 11 | if(std::fetestexcept(FE_DIVBYZERO)){ 12 | std::cout<<"Error: division by zero"< 11 | using void_t = void; 12 | 13 | template 14 | struct has_foo { 15 | static constexpr bool value = false; 16 | }; 17 | 18 | template 19 | struct has_foo(), std::declval()))> > { 20 | static constexpr bool value = true; 21 | }; 22 | 23 | int main() { 24 | SHOW_BOOL((has_foo::value)); 25 | SHOW_BOOL((has_foo::value)); 26 | } 27 | -------------------------------------------------------------------------------- /Code/move_examples/move_only_fail.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../show.h" 5 | 6 | struct movable { 7 | std::vector v; 8 | 9 | movable(int s) : v(s) {std::cout << "Default\n";} 10 | //movable(movable&& other) = delete; //: v(std::move(other.v)) {std::cout << "Move\n";} 11 | //movable(movable const & other) : v(other.v) {std::cout << "Copy\n";} 12 | //~movable() {} 13 | }; 14 | 15 | int main() { 16 | movable z(movable(200)); 17 | SHOW(z.v.size()); 18 | movable u(std::move(z)); 19 | SHOW(z.v.size()); 20 | SHOW(u.v.size()); 21 | } 22 | -------------------------------------------------------------------------------- /Code/Concepts/pipes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace pipes { 7 | 8 | template , int> = 0> 10 | auto operator|(Arg &&arg, F f) { 11 | return f(std::forward(arg)); 12 | }; 13 | 14 | template , int> = 0> 16 | auto operator|(F f, G g) { 17 | return [f = std::move(f), g = std::move(g)](auto &&... args) { 18 | return g(f(std::forward(args)...)); 19 | }; 20 | } 21 | 22 | } // namespace pipes 23 | -------------------------------------------------------------------------------- /Code/Lambdas/generic.cpp: -------------------------------------------------------------------------------- 1 | #include "../show.h" 2 | 3 | template 4 | void foo(Func func, T a, T b) { 5 | SHOW(func(a,b)); 6 | }; 7 | 8 | 9 | int main() { 10 | { 11 | auto f = [](auto a, auto b) {return a+b;}; 12 | SHOW(f(42, 3.1415926)); 13 | } 14 | { 15 | auto f = [](auto &a, auto &b) { return a++ + b; }; 16 | int x = 42; 17 | double y = 3.1415926; 18 | SHOW(f(x,y)); 19 | SHOW(x); 20 | } 21 | { 22 | auto f = [](auto a, auto b) {return a+b;}; 23 | foo(f, 3.14, 3.52); 24 | foo(f, 42, 32); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Code/tinysimd/README.md: -------------------------------------------------------------------------------- 1 | # Demo code for Advanced C++ for HPC course. 2 | 3 | ## Building 4 | 5 | Make sure git submodules are initialized for google test and google bench. Then: 6 | 7 | 8 | ``` 9 | mkdir build 10 | cd build 11 | ln -s ../Makefile 12 | 13 | # Make unit test executable ./unit 14 | make unit 15 | 16 | # Make ex_xxx.asm assembly code from example source. 17 | make examples 18 | 19 | # Make benchmarks ./bench_xxx from sources in bench/ 20 | make benchmarks 21 | 22 | # Remove object files. 23 | make clean 24 | 25 | # Remove object files, executables, libraries. and generated dependencies. 26 | make realclean 27 | ``` 28 | -------------------------------------------------------------------------------- /Code/Constexpr/ET/expressions.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | template struct expr_derivative; 8 | template struct expr_plus; 9 | template struct expr_times; 10 | 11 | #include "constant.hpp" 12 | #include "p.hpp" 13 | 14 | #if __cplusplus >= 201402L 15 | #include "expr_plus.hpp" 16 | #include "expr_times.hpp" 17 | #include "expr_derivative.hpp" 18 | #else 19 | #pragma message("Compiling with C++11") 20 | #include "expr_plus_cxx11.hpp" 21 | #include "expr_times_cxx11.hpp" 22 | #include "expr_derivative_cxx11.hpp" 23 | #endif 24 | -------------------------------------------------------------------------------- /Code/STL/containers/emplace.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct my_class{ 6 | my_class(my_class const&){std::cout<<"Copy\n";}; 7 | my_class(int, double){std::cout<<"Construct\n";}; 8 | // my_class(my_class &&){std::cout<<"Move\n";}; 9 | // void operator = (my_class &&){std::cout<<"Move Assignment\n";}; 10 | }; 11 | 12 | int main(){ 13 | 14 | std::vector m; 15 | m.reserve(2); 16 | m.push_back( my_class(1,2.) ); 17 | m.push_back( my_class(1,2.) ); 18 | //m.emplace_back( 1,2. ); 19 | //m.emplace_back( 1,2. ); 20 | //m.emplace(m.begin(), 1, 2. ); 21 | } 22 | -------------------------------------------------------------------------------- /Code/Templates/patternT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | struct X { 5 | X() {std::cout << "primary\n";} 6 | }; 7 | 8 | 9 | template 10 | struct X> { 11 | X() {std::cout << "specialization\n";} 12 | }; 13 | 14 | template 15 | void foo(X) { 16 | std::cout << "foo\n"; 17 | } 18 | 19 | template 20 | void foo(X) { 21 | std::cout << "foo\n"; 22 | } 23 | 24 | int main() { 25 | X x1; 26 | X> x2; 27 | X>> x3; 28 | 29 | foo(x1); 30 | foo(x3); 31 | } 32 | -------------------------------------------------------------------------------- /Code/move_examples/real_world.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void read(std::string & in) { 5 | std::cout << "Write something\n"; 6 | std::cin >> in; 7 | } 8 | 9 | int main() { 10 | std::string input; 11 | read(input); 12 | std::vector vector; 13 | 14 | while (input != "end") { 15 | std::cout << "inserting \"" << input << "\"\n"; 16 | vector.push_back(std::move(input)); 17 | std::cout << "What's left :\"" << input << "\"\n"; 18 | read(input); 19 | } 20 | 21 | std::cout << "\n************\n\n"; 22 | for (auto const& s: vector) { 23 | std::cout << s << "\n"; 24 | } 25 | } -------------------------------------------------------------------------------- /Code/Concepts/cursor/range_loop.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "concept.hpp" 4 | 5 | namespace range_loop_impl_ { 6 | struct stop {}; 7 | 8 | template struct cur_iter { 9 | Cur cur_; 10 | 11 | decltype(auto) operator*() const { return cursor::concept ::get(cur_); } 12 | void operator++() { cursor::concept ::next(cur_); } 13 | bool operator!=(stop) const { return !cursor::concept ::done(cur_); } 14 | }; 15 | 16 | template cur_iter begin(Cur &&cur) { 17 | return {std::forward(cur)}; 18 | } 19 | template stop end(Cur &&) { return {}; } 20 | } // namespace range_loop_impl_ 21 | 22 | using range_loop_impl_::begin; 23 | using range_loop_impl_::end; 24 | -------------------------------------------------------------------------------- /Code/StaticVariables/linking/test_static.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Test to be compiled either 3 | in a single translation unit 4 | g++ init_static.cpp test_static.cpp 5 | or with dynamic linking: 6 | g++ -c init_static.cpp -fPIC -o libs.o; g++ -shared -o libs.so libs.o; g++ test_static.cpp -O3 -L. libs.so 7 | or with static linking: 8 | g++ -c init_static.cpp -o libs.o; ar rvs libs.a libs.o; g++ test_static.cpp -O3 -L. libs.a 9 | */ 10 | 11 | #include 12 | #include "init_static.hpp" 13 | 14 | int main() 15 | { 16 | std::cout<::reg<::reg<<"\n"; 17 | // register_product::reg; 18 | // register_product::reg; 19 | } 20 | -------------------------------------------------------------------------------- /Code/TypesAndValues/array_vector_example.cpp: -------------------------------------------------------------------------------- 1 | #include "../show.h" 2 | 3 | #include 4 | #include 5 | 6 | template 7 | auto generate() { 8 | return V{1,2,3,4,5}; 9 | } 10 | 11 | 12 | template 13 | void test() { 14 | // Here generate calls initializer_list constructor of the vector 15 | auto x = generate(); 16 | 17 | for (auto i: x) { 18 | std::cout << i << ","; 19 | } 20 | std::cout << "\n"; 21 | } 22 | 23 | int main() { 24 | test>(); // Initializes the vector calling the initializer_list constructor 25 | test>(); // Initializes the array by aggregate initialization 26 | } -------------------------------------------------------------------------------- /Exercises/Constexpr/Storage/layout_map.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | struct layout_map{ 6 | static constexpr int length=sizeof...(Args); 7 | static const constexpr int layout_vector[sizeof...(Args)]={Args...}; 8 | 9 | template 10 | static constexpr int at() { 11 | return layout_vector[ I ]; 12 | } 13 | 14 | template 15 | static auto constexpr select(int const* dims) { 16 | return dims[layout_vector[I]]; 17 | } 18 | 19 | template 20 | static auto constexpr select(T & ... args) { 21 | return std::get( std::make_tuple(args ...) ); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /Code/Constexpr/Storage/solution/layout_map.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | struct layout_map{ 6 | static constexpr int length=sizeof...(Args); 7 | static const constexpr int layout_vector[sizeof...(Args)]={Args...}; 8 | 9 | template 10 | static constexpr int at() { 11 | return layout_vector[ I ]; 12 | } 13 | 14 | template 15 | static auto constexpr select(int const* dims) { 16 | return dims[layout_vector[I]]; 17 | } 18 | 19 | template 20 | static auto constexpr select(T & ... args) { 21 | return std::get( std::make_tuple(args ...) ); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /Code/Threads/Synchronization/packaged_task_3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | std::thread::id f(double i_d, double& io_d) { 6 | io_d = i_d; 7 | std::this_thread::sleep_for(std::chrono::seconds(5)); 8 | return std::this_thread::get_id(); 9 | } 10 | 11 | int main() { 12 | 13 | double d=0.; 14 | auto task = std::packaged_task(f); 15 | auto get_id = task.get_future(); 16 | std::thread t1(std::move(task),23.0,std::ref(d)); 17 | std::cout<<"std::this_thread::get_id() "< 10 | template 11 | struct Order {}; 12 | 13 | struct B { 14 | using type = B; 15 | static const int value = 100; 16 | }; 17 | 18 | int main() { 19 | foo("hello", 4.5); // Ok! 20 | foo("hello", 4.5); // Ok! 21 | //foo("hello", 4.5); // Error! 22 | 23 | Order x; 24 | } 25 | -------------------------------------------------------------------------------- /Code/Exceptions/exception_specification_old_5.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct ExceptionTypeA {}; 5 | struct ExceptionTypeB {}; 6 | struct ExceptionTypeC : public ExceptionTypeB {}; 7 | 8 | void f1(void) //throw (ExceptionTypeA,ExceptionTypeB) 9 | { 10 | throw ExceptionTypeC(); 11 | } 12 | 13 | void f2(void) //throw () 14 | { 15 | throw std::exception(); 16 | } 17 | 18 | int main() { 19 | 20 | try{ 21 | 22 | f1(); 23 | 24 | } 25 | catch(...){ 26 | 27 | std::cout<<"Caught exception from f1()"< 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | std::tuple t(10,"A",3.14); 8 | 9 | auto tuple = std::make_tuple("Hello", 42, std::string("World")); 10 | static_assert(std::is_same::type, const char*>::value, ""); 11 | static_assert(std::is_same::type, int>::value, ""); 12 | static_assert(std::is_same::type, std::string>::value, ""); 13 | 14 | const char* ptr; 15 | int x; 16 | std::string str; 17 | std::tie(ptr, x, str) = tuple; 18 | std::cout << ptr << x << str <<"\n"; 19 | } 20 | -------------------------------------------------------------------------------- /Code/move_examples/move_and_copy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../show.h" 5 | 6 | struct movable { 7 | std::vector v; 8 | 9 | movable(int s) : v(s) {std::cout << "Default\n";} 10 | movable(movable&& other) : v(std::move(other.v)) {std::cout << "Move\n";} 11 | movable(movable const & other) : v(other.v) {std::cout << "Copy\n";} 12 | }; 13 | 14 | int main() { 15 | movable x(100); 16 | movable y(x); // copy constructor: x is lvalue 17 | 18 | movable z(movable(200)); // move constructor 19 | SHOW(z.v.size()); // prints 200 20 | movable u(std::move(z)); // move constructor 21 | SHOW(z.v.size()); // prints 0 22 | SHOW(u.v.size()); // prints 200 23 | } 24 | -------------------------------------------------------------------------------- /Code/Constexpr/more_complex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // constexpr int f1(std::vector const& v_){ return v_.size();} 6 | 7 | template 8 | constexpr auto f2(std::tuple const& t_){ return std::get<2>(t_);} 9 | 10 | template 11 | constexpr auto f3(std::tuple const& t_){ 12 | bool cond=std::get<2>(t_)(t_); 13 | if(cond) 14 | return std::get<2>(t_); 15 | else 16 | return std::get<1>(t_); 17 | } 18 | 19 | int main(){ 20 | 21 | std::vector v{0,1,2,3,4}; 22 | // std::cout< 2 | 3 | // The mental model of templates that substitute text is ok in almost all cases. 4 | // But in this example we can see that ADL does not apply in template instantiation! 5 | 6 | namespace name { 7 | struct X {}; 8 | void foo(X) { std::cout << "name::foo: ";} 9 | } 10 | 11 | void foo(name::X) { std::cout << "::foo: ";} 12 | 13 | 14 | template 15 | void bar(T x) { 16 | F(x); 17 | //foo(x); // This goes in ADL 18 | std::cout << "ADL does not apply\n"; 19 | }; 20 | 21 | int main() { 22 | //foo(name::X{}); // Regular ADL 23 | 24 | bar(name::X{}); // bar calls foo(name::X) but it works! No ADL is used 25 | //bar(name::X{}); 26 | } -------------------------------------------------------------------------------- /Code/tinysimd/example/ex_mul_indexed.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // scalar multiply vector add 4 | 5 | #define N 32768 6 | 7 | void mul_indexed(double* __restrict c, const int* index, const double* a, const double* b) { 8 | for (unsigned i = 0; i; 17 | using vint = simd; 18 | 19 | for (unsigned i = 0; i 7 | void foo(T&& x) { 8 | //bar(std::move(x)); 9 | bar(std::forward(x)); 10 | } 11 | 12 | template 13 | void foo1(T x) { 14 | //bar(std::move(x)); 15 | bar(std::forward(x)); 16 | } 17 | 18 | // void foo(int&); 19 | // void foo(int&); 20 | 21 | void test() { 22 | int i = 19; 23 | foo(i); 24 | SHOW(i); 25 | foo(i); 26 | SHOW(i); 27 | foo(42); 28 | } 29 | 30 | void test1() { 31 | int i = 19; 32 | foo1(i); 33 | SHOW(i); 34 | foo1(i); 35 | SHOW(i); 36 | foo1(42); 37 | } 38 | 39 | int main() { 40 | test(); 41 | test1(); 42 | } 43 | -------------------------------------------------------------------------------- /Code/Threads/Synchronization/promises_4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void f(std::promise i_promise, double i_d, double& io_d) { 6 | io_d = i_d; 7 | std::this_thread::sleep_for(std::chrono::seconds(5)); 8 | i_promise.set_value(std::this_thread::get_id()); 9 | } 10 | 11 | int main() { 12 | 13 | double d=0.; 14 | std::promise id_promise; 15 | auto get_id = id_promise.get_future(); 16 | std::thread t1(f,std::move(id_promise),23.0,std::ref(d)); 17 | std::cout<<"Valid future "<(65); // Template argument is specified... 14 | foo(65); // ... so this call passes a char ('A') 15 | 16 | // Template arguments types are deduced! 17 | foo(3.14159); 18 | 19 | foo(std::string("string")); // This goes to the free-standing function that takes a string which is more specialized 20 | 21 | foo(std::string("another string")); // This goes to the template implementation of foo, since this syntax explicitly says that a template instantiation is required 22 | } 23 | -------------------------------------------------------------------------------- /Code/move_examples/move_constructor_automatic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../show.h" 6 | 7 | struct movable { 8 | int * pv = nullptr; 9 | int s = 0; 10 | 11 | movable() {} 12 | 13 | movable(int s) : pv{new int[s]}, s{s} {std::cout << "Default\n";} 14 | 15 | 16 | // The exixtence of a copy constructor prevent the automatic generation of the move constructor. Even if it's deleted. 17 | // movable(movable const & other) = delete; 18 | 19 | int size() const {return s;} 20 | }; 21 | 22 | int main() { 23 | movable z(200); 24 | SHOW(z.size()); // prints 200 25 | movable u(std::move(z)); // move constructor 26 | SHOW(z.size()); // prints 0 27 | SHOW(u.size()); // prints 200 28 | } 29 | -------------------------------------------------------------------------------- /Code/Constexpr/Storage/storage_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | struct storage_info{ 6 | 7 | template 8 | constexpr storage_info(Dims ... dims_) : m_dims{dims_ ...}{} 9 | 10 | static constexpr int size(){return Size;} 11 | 12 | template 13 | constexpr int dim() const {return m_dims[Coord];} 14 | 15 | private: 16 | int m_dims[Size]; 17 | }; 18 | 19 | int main(){ 20 | constexpr storage_info<5> c_{2,3,4,5,6}; 21 | static_assert(c_.index(1,0,0,0,0)==1, "error"); 22 | static_assert(c_.index(0,1,0,0,0)==2, "error"); 23 | static_assert(c_.index(0,0,1,0,0)==3*2, "error"); 24 | static_assert(c_.index(0,0,0,1,0)==4*3*2, "error"); 25 | static_assert(c_.index(0,0,0,0,1)==5*4*3*2, "error"); 26 | } 27 | -------------------------------------------------------------------------------- /Code/TypesAndValues/BrokenABI/broken.cpp: -------------------------------------------------------------------------------- 1 | #include "library.hpp" 2 | 3 | void foo(int a, int b, int c, pair p) { 4 | f(p); 5 | } 6 | 7 | 8 | int main() { 9 | int a, b, c; 10 | 11 | pair p{42, 42}; 12 | 13 | int d, e, g; 14 | 15 | foo(a,b,g,p); 16 | } 17 | 18 | /* 19 | COMPILER EXPLORER 20 | EXPLICIT CONSTRUCTOR 21 | mov rax, QWORD PTR [rbp-32] 22 | mov QWORD PTR [rbp-24], rax 23 | lea rax, [rbp-24] 24 | mov rdi, rax 25 | call f(pair) 26 | lea rax, [rbp-24] 27 | mov rdi, rax 28 | call pair::~pair() [complete object destructor] 29 | DEFAULT CONSTRUCTOR 30 | mov rax, QWORD PTR [rbp-8] 31 | mov rdi, rax 32 | call f(pair) 33 | */ 34 | -------------------------------------------------------------------------------- /Code/Templates/specialization_partial_order.cpp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Primary template 4 | template 5 | struct X { 6 | X() { std::cout << "Primary\n";} 7 | }; 8 | 9 | // Specialization 1 10 | template 11 | struct X { 12 | X() { std::cout << "Specialization 1\n";} 13 | }; 14 | 15 | // Specialization 2 16 | template 17 | struct X { 18 | X() { std::cout << "Specialization 2\n";} 19 | }; 20 | 21 | template <> 22 | struct X { 23 | X() { std::cout << "Full specialization\n";} 24 | }; 25 | int main() { 26 | X a; // primary template 27 | X b; // Specialization 1 28 | X c; // specialization 2 29 | X d; // error: ambiguous partial specializations of 'X' 30 | } 31 | -------------------------------------------------------------------------------- /Code/Threads/Intro/thread_guard_8.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void f() { 5 | 6 | std::cout<<"Start work in f()"<joinable()){ 28 | t->join(); 29 | } 30 | } 31 | 32 | thread_guard(thread_guard const &) = delete; 33 | thread_guard& operator=(thread_guard const &) = delete; 34 | 35 | }; 36 | 37 | 38 | int main(){ 39 | 40 | std::thread t(f); 41 | thread_guard tg(t); 42 | // Do we need to join t? 43 | } 44 | -------------------------------------------------------------------------------- /Code/Proxy/stream_proxy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct stream_proxy { 4 | 5 | std::ostream* sptr = nullptr; 6 | 7 | stream_proxy(std::ostream & s) 8 | : sptr(&s) 9 | {} 10 | 11 | stream_proxy& operator=(std::ostream& s) { 12 | sptr = &s; 13 | return *this; 14 | } 15 | 16 | template 17 | stream_proxy& operator<<(T const& x) { 18 | *sptr << "*" << x; 19 | return *this; 20 | } 21 | }; 22 | 23 | 24 | int main () { 25 | stream_proxy s(std::cout); 26 | 27 | s << "Hello " << "world" << "\n"; 28 | 29 | s = std::cerr; 30 | 31 | s << "Hello " << "world on std::err" << "\n"; 32 | 33 | s = std::cout; 34 | 35 | s << "Hello " << "world" << "\n"; 36 | 37 | s = std::cerr; 38 | 39 | s << "Hello " << "world on std::err" << "\n"; 40 | } 41 | -------------------------------------------------------------------------------- /Code/Templates/SFINAE.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | struct X { 5 | X() { std::cout << "value type\n";} 6 | }; 7 | 8 | template 9 | struct X { 10 | X() { std::cout << "extra type\n";} 11 | }; 12 | 13 | struct A { 14 | using value_type = int; 15 | }; 16 | 17 | struct B { 18 | using extra_type = int; 19 | }; 20 | 21 | struct C { 22 | using extra_type = float; 23 | }; 24 | 25 | struct D { 26 | using extra_type = char; 27 | }; 28 | 29 | int main() { 30 | X a; // Specialization is discarded due to SFINAE 31 | X b; // Specialization is taken 32 | X c; // C::extra_type is not int 33 | X b1; // B::extra_type is int, but char is the second argument 34 | X d; // is more specialized! 35 | } 36 | -------------------------------------------------------------------------------- /Code/TypeDeduction/ADL1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../show.h" 4 | 5 | template 6 | void for_each(IT begin, IT end, F f) { 7 | std::cout << "My for each\n"; 8 | std::for_each(begin, end, f); 9 | }; 10 | 11 | int main() { 12 | std::vector v(10); 13 | // The following call is ambiguous!! 14 | //for_each(v.begin(), v.end(), [](int &i){ ++i; std::cout << i << " ";}); 15 | // Either do for a std:: implementation: 16 | std::for_each(v.begin(), v.end(), [](int &i) { 17 | ++i; 18 | std::cout << i << " "; 19 | }); 20 | std::cout << "\n"; 21 | // Or do :: for the global namespace implementation: 22 | ::for_each(v.begin(), v.end(), [](int &i) { 23 | ++i; 24 | std::cout << i << " "; 25 | }); 26 | std::cout << "\n"; 27 | } 28 | -------------------------------------------------------------------------------- /Code/Generic/graphtest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "graph.hpp" 4 | #include "bfs.hpp" 5 | 6 | template 7 | void test_from(Graph & G, Src s) { 8 | auto&& r1 = bfs(G, s); 9 | std::cout << "Starting at " << s << ": {"; 10 | for (auto i: r1) {std::cout << i << ", ";} 11 | std::cout << "}\n"; 12 | } 13 | 14 | template 15 | void run() { 16 | GType G{3,7,4,6,8}; 17 | G[3].neighbors({4,7}); 18 | G[7].neighbors({6,8}); 19 | G[4].neighbors({7,8}); 20 | G[6].neighbors({7,8}); 21 | G[8].neighbors({6}); 22 | 23 | test_from(G, 7); 24 | test_from(G, 3); 25 | test_from(G, 4); 26 | test_from(G, 6); 27 | test_from(G, 8); 28 | } 29 | 30 | int main() { 31 | using namespace graphlib; 32 | 33 | run(); 34 | run(); 35 | } 36 | -------------------------------------------------------------------------------- /Code/Constexpr/constexpr_object.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #if __GNUG__ && __GNUC__ < 5 5 | #pragma message("This example require GCC > 5.4, sorry\n") 6 | int main() {} 7 | #else 8 | struct my_const_struct{ 9 | template 10 | constexpr my_const_struct(T t_) : m_i{} { 11 | bool cond=std::get<2>(t_)(t_); 12 | if(cond) 13 | m_i = std::get<2>(t_); 14 | else 15 | m_i = std::get<1>(t_); 16 | } 17 | constexpr int get() const {return m_i;} 18 | int m_i; 19 | // std::string m_s; //This does not have a constexpr constructor 20 | }; 21 | 22 | int main(){ 23 | constexpr auto t_=std::make_tuple(1,2,3,4); 24 | constexpr my_const_struct my_struct(t_); 25 | std::cout< 2 | #include 3 | 4 | struct MyException { 5 | 6 | MyException(const std::string& i_message) 7 | :m_message(i_message) 8 | {} 9 | 10 | std::string m_message; 11 | }; 12 | 13 | 14 | class MyType { 15 | 16 | public: 17 | 18 | ~MyType() noexcept(false) 19 | { 20 | freeResources(); 21 | } 22 | 23 | private: 24 | 25 | void freeResources() { 26 | throw MyException("Exception from dctor"); 27 | } 28 | 29 | }; 30 | 31 | void f() { 32 | 33 | try { 34 | 35 | MyType myType; 36 | throw MyException("Exception from f"); 37 | 38 | } 39 | catch(MyException e) { 40 | 41 | std::cout<<"Exception caught in f()"< 2 | #include 3 | 4 | 5 | void hello_fun() { 6 | 7 | std::cout<<"Hello world from fun!"< 2 | #include 3 | #include 4 | 5 | template 6 | void print(Only const& o) { 7 | std::cout << o; 8 | } 9 | 10 | template 11 | void print(First const& f, Ts const &...v) { 12 | std::cout << f << ", "; 13 | print(v...); 14 | } 15 | 16 | template 17 | void 18 | unpack(Tuple& tuple_, 19 | std::integer_sequence){ 20 | print(std::get(tuple_)...); 21 | 22 | } 23 | 24 | template 25 | auto print_tuple(std::tuple const & x) { 26 | std::cout << "Tuple ("; 27 | unpack(x, std::make_integer_sequence{}); 28 | std::cout << ")\n"; 29 | } 30 | 31 | int main(){ 32 | auto tuple_ = std::make_tuple(1., 'b', 2u, "ciao"); 33 | print_tuple(tuple_); 34 | } 35 | -------------------------------------------------------------------------------- /Code/Exceptions/exception_specification_new_6.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void f1(void) noexcept(false) 5 | { 6 | throw std::exception(); 7 | } 8 | 9 | void f2(void) noexcept(true) 10 | { 11 | throw std::exception(); 12 | } 13 | 14 | void f3(void) noexcept(noexcept(f1())) { 15 | 16 | try{ 17 | f1(); 18 | } 19 | catch(...){ 20 | throw; 21 | } 22 | 23 | } 24 | 25 | 26 | int main() { 27 | 28 | try{ 29 | 30 | f1(); 31 | 32 | } 33 | catch(...){ 34 | 35 | std::cout<<"Caught exception from f1()"< 2 | #include 3 | 4 | struct MyException { 5 | 6 | MyException(std::string i_error_message) 7 | :m_error_message(i_error_message) 8 | {} 9 | 10 | std::string m_error_message; 11 | 12 | }; 13 | 14 | void f3() { 15 | 16 | throw MyException("Throwing from f3()."); 17 | 18 | } 19 | 20 | void f2() { 21 | 22 | try { 23 | f3(); 24 | } 25 | catch(MyException& e) { 26 | e.m_error_message.append(" Rethrowing from f2()."); 27 | throw; 28 | } 29 | 30 | } 31 | 32 | void f1() { 33 | 34 | try { 35 | f2(); 36 | } 37 | catch(MyException& e) { 38 | e.m_error_message.append(" Rethrowing from f1()."); 39 | throw; 40 | } 41 | 42 | } 43 | 44 | 45 | int main() { 46 | 47 | try { 48 | f1(); 49 | } 50 | catch(MyException e) { 51 | std::cout< 2 | #include 3 | #include 4 | #include 5 | #include "../show.h" 6 | 7 | struct movable { 8 | int * pv = nullptr; 9 | int s = 0; 10 | 11 | movable() {} 12 | 13 | movable(int s) : pv{new int[s]}, s{s} {std::cout << "Default\n";} 14 | //movable(movable&& other) = delete; 15 | movable(movable const & other) { 16 | s=other.s; 17 | if (pv) { 18 | delete[] pv; 19 | } 20 | pv = new int[s]; 21 | std::copy(other.pv, other.pv+other.s, pv); 22 | std::cout << "Copy\n"; 23 | } 24 | 25 | int size() const {return s;} 26 | }; 27 | 28 | int main() { 29 | movable z(200); 30 | SHOW(z.size()); // prints 200 31 | movable u(std::move(z)); // move constructor 32 | SHOW(z.size()); // prints 0 33 | SHOW(u.size()); // prints 200 34 | } 35 | -------------------------------------------------------------------------------- /Code/Lambdas/function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../show.h" 3 | 4 | float foo(int a, int b) { 5 | std::cout << "stand alone "; 6 | return static_cast(a+b); 7 | } 8 | 9 | struct A { 10 | float operator()(int a, int b) { 11 | std::cout << "functor "; 12 | return static_cast(a+b); 13 | } 14 | }; 15 | 16 | int main() { 17 | std::function f = [](int a,int b) { 18 | std::cout << "lambda "; 19 | return static_cast(a+b);}; 20 | 21 | SHOW(f(3,4)); 22 | 23 | // Re-targeting to standalone 24 | f = foo; 25 | SHOW(f(3,4)); 26 | 27 | // Re-targeting to functor 28 | f = A(); 29 | SHOW(f(3,4)); 30 | 31 | using namespace std::placeholders; 32 | 33 | f = std::bind([](int a, int b, int c) { std::cout << "binded "; return a+b-c;}, 34 | _1, _2, 0); 35 | SHOW(f(3,4)); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Code/Threads/Intro/identification_6.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void fun(){ 6 | std::this_thread::sleep_for(std::chrono::seconds(10)); 7 | return; 8 | } 9 | 10 | int main() 11 | { 12 | 13 | std::thread::id t0_id = std::this_thread::get_id(); 14 | std::thread t1(fun); 15 | std::thread::id t1_id(t1.get_id()); 16 | std::thread t2(fun); 17 | std::thread::id t2_id(t2.get_id()); 18 | std::cout<<"t0_id == t1_id "<<(t0_id==t1_id)< 2 | #include 3 | 4 | struct MyException { 5 | 6 | std::string getExceptionType() const { return "MyException"; } 7 | 8 | }; 9 | 10 | void handle_exception_pointer(std::exception_ptr exc_ptr) { 11 | 12 | try { 13 | if(exc_ptr) { 14 | std::rethrow_exception(exc_ptr); 15 | } 16 | } 17 | catch(std::exception e) { 18 | std::cout< 2 | #include 3 | #include "../../show.h" 4 | class A { 5 | int a; 6 | 7 | public: 8 | A(int a) : a{a} {} 9 | 10 | A(A const& x) : a(x.a) {std::cout << "copy\n";} 11 | 12 | A inc() const { return A{a+1}; } 13 | 14 | int value() const { return a; } 15 | }; 16 | 17 | std::ostream& operator<<(std::ostream& s, A const& a) { 18 | return s << a.value(); 19 | } 20 | 21 | 22 | std::tuple get(int a, int b) { 23 | return std::make_tuple(A{a}, A{b}); 24 | } 25 | 26 | std::tuple inc_get(A const& a, A const& b) { 27 | return std::make_tuple(a.inc(), b.inc()); 28 | } 29 | 30 | int main() { 31 | 32 | std::cout << " > tie example <\n"; 33 | 34 | A a{10}; 35 | A b{100}; 36 | 37 | SHOW(a); 38 | SHOW(b); 39 | 40 | std::tie(a,b) = get(11,111); 41 | 42 | SHOW(a); 43 | SHOW(b); 44 | 45 | std::tie(a,b) = inc_get(a,b); 46 | 47 | SHOW(a); 48 | SHOW(b); 49 | } 50 | -------------------------------------------------------------------------------- /Code/Concepts/cursor/any.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "concept.hpp" 6 | 7 | namespace cursor { 8 | template class any_cursor { 9 | struct iface { 10 | virtual ~iface() {} 11 | virtual T const &get() const = 0; 12 | virtual void next() = 0; 13 | virtual bool done() const = 0; 14 | }; 15 | template struct impl : iface { 16 | Cur cur_; 17 | impl(Cur cur) : cur_(std::move(cur)) {} 18 | T const &get() const override { return concept ::get(cur_); } 19 | void next() override { concept ::next(cur_); } 20 | bool done() const override { return concept ::done(cur_); } 21 | }; 22 | std::unique_ptr impl_; 23 | 24 | public: 25 | template 26 | any_cursor(Cur cur) : impl_(new impl{std::move(cur)}) {} 27 | 28 | T const &get() const { return impl_->get(); } 29 | void next() { impl_->next(); } 30 | bool done() const { return impl_->done(); } 31 | }; 32 | } // namespace cursor 33 | -------------------------------------------------------------------------------- /Code/TypesAndValues/value_initialization.cpp: -------------------------------------------------------------------------------- 1 | #include "../show.h" 2 | 3 | struct A { 4 | A(int =10) { std::cout << "Default constuctor of A\n";} 5 | }; 6 | 7 | struct B { 8 | int a, b, c; 9 | B() = delete; 10 | }; 11 | 12 | OUT(B) { 13 | return s << a.a << " " << a.b << " " << a.c; 14 | } 15 | 16 | 17 | struct C { 18 | C(int x=10) { std::cout << "Not(!) default constructor of C\n";} 19 | }; 20 | 21 | void test() { 22 | int i; // default initialized to indeterminate 23 | int j{}; // zero initialized 24 | 25 | A a; // default constructed by calling default constructor 26 | A b{}; // default constructed though overload resolution 27 | // B c; // default constructor cannot be called! Error 28 | B d{}; // B is an aggregate (even with deleted constructors) 29 | SHOW(d); 30 | 31 | C e; // Overload resolution of C() // N4537 8.5.17.6 32 | C f{}; // default constructed though overload resolution 33 | } 34 | 35 | int main() { 36 | test(); 37 | } 38 | -------------------------------------------------------------------------------- /Code/Templates/defaults.cpp: -------------------------------------------------------------------------------- 1 | #include "../show.h" 2 | 3 | template 4 | Return foo(T x) { 5 | return static_cast(x); 6 | } 7 | 8 | template 9 | struct my_container { 10 | my_container() {std::cout << "Primary " << size << "\n";} 11 | }; 12 | 13 | template 14 | struct my_container { 15 | my_container() {std::cout << "THIS IS JUST 10\n";} 16 | }; 17 | 18 | template 19 | struct my_container { 20 | my_container() {std::cout << "THIS IS JUST 15\n";} 21 | }; 22 | 23 | int main() { 24 | 25 | // For functions: 26 | SHOW(foo(65)); 27 | SHOW((foo(65.3))) 28 | 29 | // For classes 30 | my_container<> x; // a my_container of doubles 31 | // <> are needed since my_container is a template! 32 | my_container y; 33 | my_container z; 34 | my_container u; 35 | my_container v; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /Code/Templates/min.cpp: -------------------------------------------------------------------------------- 1 | #include "../show.h" 2 | 3 | template 4 | T const& min(T const& a, T const& b) { 5 | return (a 11 | T const* min(T const* const a, T const* const b) { 12 | std::cout << " *ptr spcialization* "; 13 | return (*a<*b)?a:b; 14 | } 15 | 16 | char const* min(const char * const a, const char * const b) { 17 | std::cout << " *char specialization* "; 18 | return (std::string(a) < std::string(b)?a:b); 19 | } 20 | 21 | int main() { 22 | SHOW((min(3,4))); 23 | 24 | // SHOW((min("Allucination", "Dream"))) 25 | SHOW((min("Alluc", "Dream"))) 26 | 27 | // char const* const c0 = "423"; 28 | // char const* const c1 = "234"; 29 | char const c0[4] = "423"; 30 | char const c1[4] = "234"; 31 | SHOW((min(c0, c1))); // ??? Exercise 1: find a way of comparing pointers, find a way of comparing char const* // the commented code above 32 | 33 | // SHOW((min(c0,c1))); 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Code/Constexpr/tmp_vs_constexpr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | //run: 3 | //time g++ -O3 example_00.cpp -ftemplate-depth=100000 -fconstexpr-depth=100000 4 | template 5 | struct sum{ // template recursion 6 | static const long int value=I+sum::value; 7 | }; 8 | 9 | template <> 10 | struct sum<1>{ 11 | static const long int value=1; 12 | }; 13 | 14 | constexpr int sum2(int id){ // regular recursion 15 | return id>1 ? id+sum2(id-1) : id; 16 | }; 17 | 18 | int main(){ 19 | static_assert(sum<100>::value > 0, "error"); 20 | static_assert(sum2(100) > 0, "error"); 21 | std::cout< 6 | #include 7 | 8 | template 9 | class my_class { 10 | std::string m_name = "my_class"; 11 | public: 12 | std::string const& name() const {return m_name;} 13 | }; 14 | 15 | template 16 | class my_class { 17 | std::string m_name = "my_class"; 18 | public: 19 | std::string const& name() const {return m_name;} 20 | }; 21 | 22 | template <> 23 | class my_class { 24 | std::string m_name = "my_class"; 25 | public: 26 | std::string const& name() const {return m_name;} 27 | }; 28 | 29 | 30 | int main() { 31 | 32 | std::cout << " > templates_02 <\n"; 33 | 34 | my_class a; 35 | 36 | assert(a.name() == "my_class"); 37 | 38 | my_class b; 39 | 40 | assert(b.name() == "my_class"); 41 | 42 | my_class c; 43 | 44 | assert(c.name() == "my_class"); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Exercises/Templates/templates_02.cpp: -------------------------------------------------------------------------------- 1 | #ifdef NDEBUG 2 | #undef NDEBUG 3 | #endif 4 | 5 | #include 6 | #include 7 | 8 | template 9 | class my_class { 10 | std::string m_name = "my_class"; 11 | public: 12 | std::string const& name() const {return m_name;} 13 | }; 14 | 15 | template 16 | class my_class { 17 | std::string m_name = "my_class"; 18 | public: 19 | std::string const& name() const {return m_name;} 20 | }; 21 | 22 | template 23 | class my_class { 24 | std::string m_name = "my_class"; 25 | public: 26 | std::string const& name() const {return m_name;} 27 | }; 28 | 29 | 30 | int main() { 31 | 32 | std::cout << " > templates_02 <\n"; 33 | 34 | my_class a; 35 | 36 | assert(a.name() == "my_class"); 37 | 38 | my_class b; 39 | 40 | assert(b.name() == "my_class"); 41 | 42 | my_class c; 43 | 44 | assert(c.name() == "my_class"); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Code/Exceptions/exception_constructor_8.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Size{ 6 | 7 | Size(int i_size) 8 | :m_size(i_size) 9 | {} 10 | 11 | void print() { 12 | std::cout<<"Illegal size error. Size value: "<(new int[3]); 28 | 29 | // Check size request 30 | if(i_data_size > 1000 || i_data_size < 0) 31 | throw Size(i_data_size); 32 | } 33 | 34 | ~Vector() { 35 | } 36 | 37 | Vector(const Vector&) = delete; 38 | Vector(Vector&&) = delete; 39 | 40 | private: 41 | std::unique_ptr m_meta_data; 42 | int m_data_size; 43 | 44 | }; 45 | 46 | int main() { 47 | 48 | try { 49 | Vector vec(-3); 50 | } 51 | catch(Size e) { 52 | e.print(); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /Code/Lambdas/return.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../show.h" 4 | 5 | struct complex { 6 | double re, im; 7 | 8 | complex & operator+=(complex d) { 9 | im += d.im; 10 | re += d.re; 11 | return *this; 12 | } 13 | }; 14 | 15 | std::ostream& operator<<(std::ostream& s, complex c) { 16 | return s << c.re << " + i" << c.im; 17 | } 18 | 19 | 20 | int main() { 21 | auto make_complex = [](double a, double b) -> complex {return {a,b};}; 22 | SHOW((make_complex(1.4, 3.2))); 23 | 24 | auto copy_complex = [](complex c) -> complex {return c;}; 25 | complex copy = copy_complex(complex{4.,2.}); 26 | SHOW(copy); 27 | 28 | #if __cplusplus>=201402L 29 | auto sum_inplace = [](complex &c, complex d) -> auto& {c += d; return c;}; 30 | #else 31 | auto sum_inplace = [](complex &c, complex d) -> complex& {c += d; return c;}; 32 | #endif 33 | complex x{0.,0.}; 34 | auto& xr = sum_inplace(x, complex{4.,2.}); 35 | SHOW(xr); 36 | x.im = 42; 37 | SHOW(xr); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /Exercises/Lambdas/lambdas_2.cpp: -------------------------------------------------------------------------------- 1 | #ifdef NDEBUG 2 | #undef NDEBUG 3 | #endif 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main() { 11 | 12 | std::size_t s; 13 | std::cout << "This program will take a sequence of integer values and \nprint the prefix sum of those values starting from a given value\n:"; 14 | 15 | std::cout << "Number of elements\n:"; 16 | std::cin >> s; 17 | 18 | std::vector data(s); 19 | 20 | std::for_each(data.begin(), data.end(), 21 | [????](????) ???? { std::cout << ":"; std::cin >> x;}); 22 | 23 | std::cout << "Enter the starting value\n:"; 24 | int m{}; 25 | std::cin >> m; 26 | int old_m = m; 27 | 28 | std::for_each(data.begin(), data.end(), 29 | [????](????) ???? { x += m; m=x; }); 30 | 31 | assert(m==old_m); /* !!! */ 32 | 33 | std::for_each(data.begin(), data.end(), 34 | [????](????) ???? { std::cout << x << " ";}); 35 | std::cout << "\n"; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /Code/TypesAndValues/initializer_list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | template 6 | void f(T const& chars) { 7 | std::for_each(chars.begin(), chars.end(), 8 | [](char c) {std::cout << c;}); 9 | std::cout << std::endl; 10 | } 11 | 12 | void f(std::initializer_list const& chars) { 13 | std::for_each(chars.begin(), chars.end(), 14 | [](char c) {std::cout << c;}); 15 | std::cout << std::endl; 16 | } 17 | 18 | class X { 19 | std::vector v; 20 | public: 21 | X(std::initializer_list const& chars) 22 | : v{chars} 23 | { 24 | f(chars); 25 | } 26 | }; 27 | 28 | int main() { 29 | X x{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!'}; 30 | X y = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!'}; 31 | 32 | f({'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!'}); 33 | f(std::initializer_list{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!'}); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Code/Lambdas/lambdas_2.cpp: -------------------------------------------------------------------------------- 1 | #ifdef NDEBUG 2 | #undef NDEBUG 3 | #endif 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main() { 11 | 12 | std::size_t s; 13 | std::cout << "This program will take a sequence of integer values and \nprint the prefix sum of those values starting from a given value\n:"; 14 | 15 | std::cout << "Number of elements\n:"; 16 | std::cin >> s; 17 | 18 | std::vector data(s); 19 | 20 | std::for_each(data.begin(), data.end(), 21 | [](int& x) { std::cout << ":"; std::cin >> x;}); 22 | 23 | std::cout << "Enter the starting value\n:"; 24 | int m{}; 25 | std::cin >> m; 26 | int old_m = m; 27 | 28 | std::for_each(data.begin(), data.end(), 29 | [m](int &x) mutable { x += m; m=x; }); 30 | std::cout << "\nhelloooo" << m << "\n"; 31 | 32 | assert(m==old_m); 33 | 34 | std::for_each(data.begin(), data.end(), 35 | [](int x) { std::cout << x << " ";}); 36 | std::cout << "\n"; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /Code/Templates/void_t.cpp: -------------------------------------------------------------------------------- 1 | #include "../show.h" 2 | 3 | template 4 | using void_t = void; 5 | 6 | template 7 | using can_add = decltype(std::declval()+std::declval()); 8 | 9 | 10 | template // this "void" is idiomatic 11 | struct sum { 12 | static T add(T const&,T const&) { std::cout << "No operator found "; return T{};} 13 | }; 14 | 15 | template 16 | struct sum>> { 17 | static T add(T const& a, T const& b) { 18 | return a+b; 19 | } 20 | }; 21 | 22 | 23 | struct A {}; 24 | 25 | std::ostream& operator<<(std::ostream& s, A) { 26 | return s << "A"; 27 | } 28 | 29 | struct B { 30 | std::string s; 31 | B(std::string s) : s{s} {} 32 | }; 33 | 34 | B operator+(B const& x, B const& y) {return B{x.s + " " + y.s};} 35 | 36 | std::ostream& operator<<(std::ostream& s, B const& x) { 37 | return s << x.s; 38 | } 39 | 40 | int main() { 41 | SHOW(sum::add(3,4)) 42 | SHOW(sum::add(A{}, A{})) 43 | SHOW(sum::add(B{"Hello"}, B{"World"})) 44 | } -------------------------------------------------------------------------------- /Exercises/Templates/templates_03.cpp: -------------------------------------------------------------------------------- 1 | #ifdef NDEBUG 2 | #undef NDEBUG 3 | #endif 4 | 5 | #include 6 | #include 7 | 8 | template 9 | struct X { 10 | std::string m_name = "X"; 11 | public: 12 | std::string const& name() const {return m_name;} 13 | }; 14 | 15 | 16 | template 17 | struct X> { 18 | std::string m_name = "X>"; 19 | public: 20 | std::string const& name() const {return m_name;} 21 | }; 22 | 23 | template 24 | std::string foo(X) { 25 | return "X"; 26 | } 27 | 28 | template 29 | std::string foo(X) { 30 | return "X"; 31 | } 32 | 33 | int main() { 34 | std::cout << " > templates_03 <\n"; 35 | 36 | X x1; 37 | assert(x1.name() == "????"); 38 | 39 | X> x2; 40 | assert(x2.name() == "????"); 41 | 42 | X>> x3; 43 | assert(x3.name() == "????"); 44 | 45 | assert(foo(x1) == "????"); 46 | 47 | assert(foo(x3) == "????"); 48 | } 49 | -------------------------------------------------------------------------------- /Exercises/Lambdas/function_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | float foo(int a, int b) { 6 | std::cout << "stand alone "; 7 | return static_cast(a+b); 8 | } 9 | 10 | struct A { 11 | float operator()(int a, int b) { 12 | std::cout << "functor "; 13 | return static_cast(a+b); 14 | } 15 | }; 16 | 17 | float bar(int a, int b, int c) { 18 | return static_cast(a-b+c); 19 | } 20 | 21 | int main() { 22 | std::function< ???? > f = [](int a,int b) { 23 | std::cout << "lambda "; 24 | return static_cast(a+b);}; 25 | 26 | assert(f(3,4) == (float)(3+4)); 27 | 28 | // Re-targeting to standalone foo 29 | f = ????; 30 | 31 | assert(f(3,4) == (float)(3+4)); 32 | 33 | // Re-targeting to functor A 34 | f = ????; 35 | 36 | assert(f(3,4) == (float)(3+4)); 37 | 38 | using namespace std::placeholders; 39 | 40 | // Re-targeting to bar using bind (look at assert) 41 | f = std::bind(bar, ???? ); 42 | 43 | assert(f(3,4) == (float)(3+4)); 44 | } 45 | -------------------------------------------------------------------------------- /Code/Templates/templates_03.cpp: -------------------------------------------------------------------------------- 1 | #ifdef NDEBUG 2 | #undef NDEBUG 3 | #endif 4 | 5 | #include 6 | #include 7 | 8 | template 9 | struct X { 10 | std::string m_name = "X"; 11 | public: 12 | std::string const& name() const {return m_name;} 13 | }; 14 | 15 | 16 | template 17 | struct X> { 18 | std::string m_name = "X>"; 19 | public: 20 | std::string const& name() const {return m_name;} 21 | }; 22 | 23 | template 24 | std::string foo(X) { 25 | return "X"; 26 | } 27 | 28 | template 29 | std::string foo(X) { 30 | return "X"; 31 | } 32 | 33 | int main() { 34 | std::cout << " > templates_03 <\n"; 35 | 36 | X x1; 37 | assert(x1.name() == "X"); 38 | 39 | X> x2; 40 | assert(x2.name() == "X>"); 41 | 42 | X>> x3; 43 | assert(x3.name() == "X"); 44 | 45 | assert(foo(x1) == "X"); 46 | 47 | assert(foo(x3) == "X"); 48 | } 49 | -------------------------------------------------------------------------------- /Code/TypeDeduction/conversion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void f(int8_t a) { 5 | std::cout << (int)a << std::endl; 6 | } 7 | 8 | struct A {}; 9 | 10 | #define SHOW(x) std::cout << #x << ": " << x << "\n"; 11 | 12 | struct B { 13 | B(char c) {} 14 | 15 | operator A() {return A{};} 16 | 17 | template 18 | operator X() = delete; 19 | }; 20 | 21 | struct C { 22 | operator B() {return B{'a'};} 23 | }; 24 | 25 | int main() { 26 | int16_t a = 16383; 27 | SHOW(sizeof(int16_t)); 28 | SHOW(sizeof(int8_t)); 29 | SHOW(sizeof(int)); 30 | 31 | { 32 | unsigned char ch = 2345; 33 | } 34 | 35 | { 36 | unsigned char ch = 234; 37 | } 38 | f(a); // no warning 39 | 40 | f((short)16383); 41 | f((1 << 16)-1); // warning 42 | 43 | int i = (1<<16)-1; 44 | f(i); // warning 45 | 46 | char c1 = 32, c2 = 33; 47 | B x(c1+c2); // {} would not work! 48 | { 49 | A y = static_cast(C{}); 50 | } 51 | { 52 | // A y = C{}; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /Code/TypesAndValues/zero_initialization.cpp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../show.h" 3 | 4 | double f[35]; // zero-initialized to three 0.0's 5 | int* p; // zero-initialized to null pointer value 6 | std::string s; // zero-initialized to indeterminate value 7 | // then default-initialized to "" 8 | 9 | void test() 10 | { 11 | double f_[15]; // non static, so not initialized 12 | static int n; // zero-initialized to 0 (static) 13 | int m; // default initialize to indeterminate 14 | 15 | char hello[17] = "hello"; // values after "hello" are zero initialized 16 | 17 | SHOW(f[0]); 18 | SHOW(f[1]); 19 | SHOW(f[2]); 20 | 21 | SHOW(f_[0]); 22 | SHOW(f_[1]); 23 | SHOW(f_[2]); 24 | 25 | SHOW(n); 26 | SHOW(m); 27 | 28 | SHOW(p); 29 | 30 | SHOW(hello); 31 | 32 | for (int i; i<17; ++i) { 33 | std::cout << static_cast(hello[i]) << " "; 34 | } 35 | std::cout << "\n"; 36 | 37 | // then copy-initialized to argc 38 | delete [] p; // safe to delete a null pointer 39 | } 40 | 41 | int main() { 42 | test(); 43 | } 44 | -------------------------------------------------------------------------------- /Code/STL/tuple/tuple_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template struct my_tuple; 4 | 5 | template 6 | struct my_tuple { 7 | static constexpr int size=1; 8 | constexpr my_tuple(First first_) : m_value(first_){} 9 | template constexpr First get() const {return m_value;} 10 | First m_value; 11 | }; 12 | 13 | template 14 | struct my_tuple : public my_tuple { 15 | using super=my_tuple; 16 | static constexpr int size = sizeof...(T); 17 | 18 | constexpr my_tuple(First first_, T ... rest_) : super(rest_ ...), m_value(first_){} 19 | 20 | First m_value; 21 | 22 | template 23 | constexpr auto get() const {return Id==size ? m_value : super::template get();} 24 | 25 | }; 26 | 27 | template 28 | constexpr auto get(Tuple t_){ return t_.template get();} 29 | 30 | 31 | int main(){ 32 | constexpr my_tuple t_(1,3.4); 33 | std::cout<(t_)<<"\n"; 34 | static_assert(get<1>(t_)==3.4, ""); 35 | } 36 | -------------------------------------------------------------------------------- /Exercises/SmartPtrs/deleters_7.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int* makeArray(const int i_size) { 6 | 7 | return new int[i_size]; 8 | } 9 | 10 | struct Object { 11 | 12 | void dumpToFile(const std::string& i_fileName) { 13 | 14 | std::cout<<"Dumping status in file "< sp(?); 24 | 25 | // 1 - Fix the above bug with a custom deleter. WARNING, THIS IS BAD CODE! USE STL CONTAINERS!!! 26 | std::shared_ptr sp_new(); 27 | 28 | // 2 - Create unique_ptr from Factory function makeArray. This is the only case you would need 29 | // a unique_ptr of T[] type: an external function returning a raw pointer to heap array you take ownerhip of 30 | std::unique_ptr up(?); 31 | 32 | // 3 - Create unique_ptr of Object that dumps the status at destruction time 33 | const std::string fileName = "dump_file.dat"; 34 | std::unique_ptr up_obj(?); 35 | } 36 | -------------------------------------------------------------------------------- /Code/Lambdas/lambdas_1.cpp: -------------------------------------------------------------------------------- 1 | #ifdef NDEBUG 2 | #undef NDEBUG 3 | #endif 4 | 5 | #include 6 | #include 7 | 8 | int main() { 9 | 10 | auto sum = [](int i, int j) { return i+j;}; 11 | 12 | assert(sum(3,5) == 8); 13 | 14 | int i; 15 | 16 | auto initialize = [&i](int j) {i=j;}; 17 | 18 | initialize(42); 19 | assert(i==42); 20 | 21 | std::string prefix("hello"); 22 | auto concat = [prefix](std::string s) {return prefix + " " + s;}; 23 | 24 | std::cout << concat("world") << " OH!\n"; 25 | assert( ("hello world") == concat("world") ); 26 | 27 | auto concat2 = [prefix](std::string s) mutable {prefix[0] = std::toupper(prefix[0]); return prefix + " " + s;}; 28 | 29 | std::cout << concat2("world") << " OH!\n"; 30 | assert( ("Hello world") == concat2("world") ); 31 | 32 | auto concat3 = [prefix](std::string s, int index) mutable {prefix[0] = std::toupper(prefix[0]); return prefix + " " + s + " " + std::to_string(index);}; 33 | 34 | assert( ("Hello world 42") == concat3("world", 42) ); 35 | 36 | std::cout << concat3("world", 42) << " OH!\n"; 37 | } 38 | -------------------------------------------------------------------------------- /Code/STL/allocator/allocators.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "stack.hpp" 8 | #include "heap.hpp" 9 | 10 | void heap() { 11 | std::cout << " >> heap allocator <<\n"; 12 | 13 | std::vector > q_({0,1,2,3,4,5,6,7}); 14 | assert(q_[2]==2); 15 | 16 | try { 17 | std::vector > q_(101); //throws bad_alloc 18 | } catch (std::bad_alloc const&) { 19 | std::cout << "Only 100 elements are allowed\n"; 20 | } 21 | } 22 | 23 | void stack() { 24 | std::cout << " >> stack allocator <<\n"; 25 | 26 | std::vector > q_({0,1,2,3,4,5,6,7}); 27 | assert(q_[2]==2); 28 | 29 | try { 30 | std::vector > q_(101); //throws bad_alloc 31 | } catch (std::bad_alloc const&) { 32 | std::cout << "Only 100 elements are allowed\n"; 33 | } 34 | } 35 | 36 | 37 | int main() { 38 | 39 | std::cout << " > allocators <\n"; 40 | 41 | heap(); 42 | 43 | stack(); 44 | } 45 | -------------------------------------------------------------------------------- /Code/TypeDeduction/ADL.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../show.h" 3 | 4 | void f(int) { std::cout << "Never run!\n";} 5 | 6 | namespace A { 7 | struct X {}; 8 | struct Y { 9 | int i = 4; 10 | Y() {} 11 | Y(int v) : i(v) {} 12 | Y operator-(Y const& v) const { 13 | return Y(i-v.i); 14 | } 15 | }; 16 | void f(int) {} 17 | void g(X) {} 18 | } 19 | 20 | std::ostream& operator<<(std::ostream& s, A::Y const& y) { 21 | return s << " Y(" << y.i << ")"; 22 | } 23 | 24 | namespace B { 25 | void f(int i) { 26 | SHOW(i); 27 | if (i>0) f(i-1); // calls B::f 28 | } 29 | void g(A::X x) { 30 | //g(x); // Error: ambiguous between B::g (ordinary lookup) 31 | // and A::g (argument-dependent lookup) 32 | } 33 | void h(A::Y y) { 34 | SHOW(y); 35 | if (y.i>0) h(y-1); // calls B::h : ADL examines the A namespace 36 | // but finds no A::h, so only B::h from ordinary lookup is used 37 | } 38 | } 39 | 40 | 41 | int main() { 42 | B::f(3); 43 | B::g(A::X{}); 44 | B::h(A::Y{}); 45 | } -------------------------------------------------------------------------------- /Code/TypesAndValues/bitfield.cpp: -------------------------------------------------------------------------------- 1 | #include "../show.h" 2 | 3 | struct instr_t { 4 | using basic_type = unsigned; 5 | basic_type oper : 3; 6 | basic_type cond1 : 2; 7 | basic_type val1 : 3; 8 | basic_type cond2 : 2; 9 | basic_type val2 : 3; 10 | basic_type act : 3; 11 | basic_type cell : 4; 12 | basic_type : sizeof(basic_type)*8-21; // unused (not necessary at the pad) 13 | basic_type :0; // Force starting a new unsigned: not really necessary here 14 | basic_type other; // regular data member 15 | }; 16 | 17 | std::ostream& operator<<(std::ostream& s, instr_t a) { 18 | return s << "inst " << a.oper 19 | << ", " << a.cond1 20 | << ", " << a.val1 21 | << ", " << a.cond2 22 | << ", " << a.val2 23 | << ", " << a.act 24 | << ", " << a.cell << "\n"; 25 | } 26 | 27 | int main() { 28 | SHOW(sizeof(instr_t)); 29 | instr_t x = instr_t{33,34,5,3,3,4,12}; 30 | for (int i=0; i<10; ++i) { 31 | SHOW(x); 32 | x.cond1 += 1; 33 | } 34 | 35 | // static_assert(instr_t{10}.oper == 2, ""); 36 | } 37 | -------------------------------------------------------------------------------- /Exercises/SmartPtrs/mix_smart_raw_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class Object{ 5 | 6 | public: 7 | 8 | Object() = default; 9 | 10 | Object(const int i_value): 11 | m_value(i_value) 12 | {} 13 | 14 | int getValue() const { return m_value; } 15 | 16 | void setValue(const int i_value) { m_value = i_value; } 17 | 18 | private: 19 | 20 | int m_value; 21 | 22 | }; 23 | 24 | int main(){ 25 | 26 | // 0 - Create managed resource, manager object and first shared pointer 27 | std::shared_ptr sp1(new Object(23)); 28 | 29 | // 1 - Create a new Object on the stack 30 | Object stack_ob(3); 31 | 32 | // 2 - Create a shared_ptr from the stack object 33 | std::shared_ptr sp2(&stack_ob); 34 | 35 | // 3 - Create a new shared_ptr from sp1 36 | std::shared_ptr sp3(sp1.get()); 37 | 38 | // 4 - How many pointers are pointing the same resource? 39 | assert(sp1.use_count() == ?); 40 | assert(sp2.use_count() == ?); 41 | assert(sp3.use_count() == ?); 42 | 43 | // 5 - Create a shared_ptr to array 44 | std::shared_ptr sp4(new Object[10]); 45 | 46 | // Find the bugs! 47 | } 48 | -------------------------------------------------------------------------------- /Code/Templates/functionsastemplates.cpp: -------------------------------------------------------------------------------- 1 | #include "../show.h" 2 | 3 | template 4 | using void_ = void; 5 | 6 | void foo(int &x) { std::cout << "Function foo& " << (x++) << "\n"; } 7 | void foo_(int x) { std::cout << "Function foo&& " << (x++) << "\n"; } 8 | 9 | struct bar { 10 | bar() {std::cout << "bar constructor\n";} 11 | void operator()(int &x) {std::cout << "Execute bar " << (x++) << "\n";} 12 | void operator()(int&& x) {std::cout << "Execute bar " << (x++) << "\n";} 13 | }; 14 | 15 | 16 | 17 | 18 | template 19 | void deduce_run(Ret(*F)(Args...), Args&&... args) { 20 | std::cout << "deduce_run void(*)()\n"; 21 | F(std::forward(args)...); 22 | } 23 | 24 | 25 | template 26 | void deduce_run(F, Ts&& ...vs) { 27 | std::cout << "deduce_run functor\n"; 28 | F{}(std::forward(vs)...); 29 | } 30 | 31 | int main() { 32 | deduce_run(foo_, 4); 33 | deduce_run(bar(), 5); 34 | 35 | int i = 4; 36 | SHOW(i); 37 | deduce_run(foo, i); 38 | SHOW(i); 39 | deduce_run(bar(), i); 40 | SHOW(i); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Code/Exceptions/stack_unwinding_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct MyException{}; 5 | struct MyOtherException{}; 6 | 7 | struct MyType { 8 | 9 | MyType(const std::string& i_scope) 10 | :m_scope(i_scope) 11 | {} 12 | 13 | ~MyType() 14 | { 15 | std::cout<<"MyType dctor in: "< 2 | #include 3 | 4 | class Object{ 5 | 6 | public: 7 | 8 | Object() = default; 9 | 10 | Object(const int i_value): 11 | m_value(i_value) 12 | {} 13 | 14 | int getValue() const { return m_value; } 15 | 16 | void setValue(const int i_value) { m_value = i_value; } 17 | 18 | private: 19 | 20 | int m_value; 21 | 22 | }; 23 | 24 | int main(){ 25 | 26 | // 0 - Create managed resource, manager object and first shared pointer 27 | std::shared_ptr sp1(new Object(23)); 28 | 29 | // 1 - Create a new Object on the stack 30 | Object stack_ob(3); 31 | 32 | // 2 - Create a shared_ptr from the stack object 33 | std::shared_ptr sp2(&stack_ob); 34 | 35 | // 3 - Create a new shared_ptr from sp1 36 | std::shared_ptr sp3(sp1.get()); 37 | 38 | // 4 - How many pointers are pointing the same resource? 39 | assert(sp1.use_count() == 1); 40 | assert(sp2.use_count() == 1); 41 | assert(sp3.use_count() == 1); 42 | 43 | // 5 - Create a shared_ptr to array 44 | std::shared_ptr sp4(new Object[10]); 45 | 46 | // Find the bugs! 47 | } 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Exercises/Proxy/proxy_exercise.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | template 7 | struct zip_proxy { 8 | 9 | /* Add any other stuff that you might need */ 10 | 11 | }; 12 | 13 | 14 | template 15 | bool operator!=(zip_proxy const& i0, zip_proxy const& i1) { 16 | return /*???*/ ; 17 | } 18 | 19 | 20 | // A simple maker to avoid cumbersome syntax in constructors 21 | template 22 | zip_proxy make_zip_proxy(T t, U u) { 23 | return zip_proxy(t,u); 24 | } 25 | 26 | int main() { 27 | std::vector iv = {1, 2, 3, 4, 5, 6}; 28 | std::list fv = {7, 6, 5, 4, 3, 2, 1}; 29 | 30 | auto zip0 = make_zip_proxy(iv.begin(), fv.begin()); 31 | auto zip1 = make_zip_proxy(iv.end(), fv.end()); 32 | 33 | /* The exercise is to make the following code to work. */ 34 | std::for_each(zip0, zip1, [](auto x) {*(x.first) += *(x.second); *(x.second) *= 2;}); 35 | std::for_each(zip0, zip1, [](auto x) {std::cout << *(x.first) << ", " << *(x.second) << "\n";}); 36 | } 37 | -------------------------------------------------------------------------------- /Code/Threads/Intro/passing_args_4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | class X{ 7 | 8 | public: 9 | void set(int i_int) { m_int=i_int; } 10 | int get(void) const { return m_int; } 11 | 12 | private: 13 | int m_int; 14 | 15 | }; 16 | 17 | void setX(int i_int, X& io_x) 18 | { 19 | io_x.set(i_int); 20 | } 21 | 22 | void setX_ptr(int i_int, X* io_x) 23 | { 24 | io_x->set(i_int); 25 | } 26 | 27 | void setX_move(int i_int,std::unique_ptr i_ptr) 28 | { 29 | i_ptr->set(i_int); 30 | } 31 | 32 | int main() 33 | { 34 | X x; 35 | 36 | // 1- Check pass by reference mechanism 37 | std::thread t(setX, 1, std::ref(x)); 38 | t.join(); 39 | std::cout<<"x int value: "< ux(new X); 51 | ux->set(-3); 52 | t = std::thread(setX_move,23,std::move(ux)); 53 | assert(!ux); 54 | t.join(); 55 | } 56 | -------------------------------------------------------------------------------- /Code/TypeDeduction/decltype.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int* foo(float, double) {return nullptr;} 4 | 5 | 6 | int main() { 7 | int x = 10; 8 | int const& y = x; 9 | 10 | static_assert(std::is_same::value, ""); 11 | 12 | static_assert(std::is_same::value, ""); 13 | 14 | static_assert(std::is_same::value, ""); 15 | 16 | static_assert(std::is_same::value, ""); 17 | 18 | static_assert(std::is_same::value, ""); 19 | 20 | int* (*f)(float, double) = nullptr; 21 | static_assert(std::is_same::value, ""); 22 | 23 | static_assert(std::is_same::value, ""); 24 | 25 | static_assert(std::is_same::value, ""); 26 | static_assert(std::is_same::value, ""); 27 | 28 | int const* (*g)(float, double) = nullptr; 29 | static_assert(std::is_same::value, ""); 30 | static_assert(std::is_same::value, ""); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Exercises/Exceptions/exception_constructor_8.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Size{ 6 | 7 | Size(int i_size) 8 | :m_size(i_size) 9 | {} 10 | 11 | void print() { 12 | std::cout<<"Illegal size error. Size value: "< 1000 || i_data_size < 0) 32 | throw Size(i_data_size); 33 | } 34 | 35 | ~Vector() { 36 | 37 | if(m_meta_data) { 38 | delete [] m_meta_data; 39 | m_meta_data = nullptr; 40 | } 41 | 42 | } 43 | 44 | Vector(const Vector&) = delete; 45 | Vector(Vector&&) = delete; 46 | 47 | private: 48 | int* m_meta_data; 49 | int m_data_size; 50 | 51 | }; 52 | 53 | int main() { 54 | 55 | try { 56 | Vector vec(-3); 57 | } 58 | catch(Size e) { 59 | e.print(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /Code/Threads/Intro/join_vs_detach_3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct func 7 | { 8 | 9 | int m_id; 10 | 11 | func(int id) 12 | :m_id(id) 13 | {} 14 | 15 | void operator()() const { 16 | 17 | std::cout<<"Thread with f "< 2 | #include 3 | #include "../show.h" 4 | 5 | 6 | namespace V1 { 7 | template 8 | struct A; 9 | 10 | template 11 | struct A::value, void>::type> { 12 | A() { std::cout << "int!\n"; } 13 | }; 14 | 15 | 16 | template 17 | struct A::value, void>::type> { 18 | A() { std::cout << "not int\n"; } 19 | }; 20 | } // namespace V1 21 | 22 | namespace V2 { 23 | template 24 | struct A; 25 | 26 | template 27 | struct A, void>> { 28 | A() { std::cout << "int!\n"; } 29 | }; 30 | 31 | 32 | template 33 | struct A, void>> { 34 | A() { std::cout << "not int\n"; } 35 | }; 36 | } // namespace V2 37 | 38 | int main() { 39 | { 40 | V1::A x; 41 | V1::A y; 42 | } 43 | { 44 | V2::A x; 45 | V2::A y; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Code/TypesAndValues/copy_initialization.cpp: -------------------------------------------------------------------------------- 1 | #include "../show.h" 2 | 3 | struct A { 4 | int a; 5 | int b = 10; 6 | explicit A(int x) :a(x) {} 7 | explicit A(int x, int y) :a(x), b(y) {} 8 | explicit operator int() {return a;} 9 | }; 10 | 11 | struct B { 12 | int a; 13 | int b = 10; 14 | B(int x) : a(x) {} 15 | B(int x, int y) : a(x), b(y) {} 16 | operator int() {return a;} 17 | }; 18 | 19 | B make_B(int a, int b) { 20 | return {a,b}; 21 | } 22 | 23 | A make_A(int a, int b) { 24 | return A{a,b}; 25 | } 26 | 27 | void take_B(B x) { 28 | SHOW_PREFIX("In take_B I receive: ", x.a); 29 | } 30 | 31 | struct C { 32 | int a; 33 | explicit C(int x): a{x} {std::cout << "hello C\n";} 34 | }; 35 | 36 | void testB() { 37 | B x = 10.; 38 | SHOW(x.a); 39 | 40 | take_B(42); 41 | 42 | B y = {34,45}; // calling B(int, int) 43 | SHOW(make_B(45,67).a); 44 | 45 | int i = y; 46 | } 47 | 48 | void testA() { 49 | A x(10.); 50 | SHOW(x.a); 51 | 52 | A y{34,45}; 53 | SHOW(make_A(45,67).a); 54 | 55 | int i = static_cast(y); 56 | } 57 | 58 | int main() { 59 | testB(); 60 | testA(); 61 | C a = static_cast(10); 62 | } 63 | -------------------------------------------------------------------------------- /Code/tinysimd/include/tinysimd/generic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace tinysimd { 9 | 10 | template 11 | struct generic; 12 | 13 | namespace abi { 14 | 15 | template 16 | struct generic { using type = ::tinysimd::generic; }; 17 | 18 | } // namespace abi 19 | 20 | template 21 | struct simd_traits> { 22 | static constexpr unsigned width = N; 23 | using scalar_type = T; 24 | using vector_type = std::array; 25 | }; 26 | 27 | template 28 | struct generic: fallback> { 29 | using array = std::array; 30 | 31 | static void copy_to(array v, T* p) { 32 | std::copy(std::begin(v), std::end(v), p); 33 | } 34 | static array copy_from(const T* p) { 35 | array v; 36 | std::copy(p, p+N, v.data()); 37 | return v; 38 | } 39 | static T element(array v, unsigned i) { 40 | return v[i]; 41 | } 42 | static void set_element(array& v, unsigned i, const T& x) { 43 | v[i] = x; 44 | } 45 | }; 46 | 47 | } // namespace tinysimd 48 | -------------------------------------------------------------------------------- /Code/TemplateMetaProgramming/factorial_protected.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | template 5 | struct factorial; 6 | 7 | template 8 | struct factorial::type> { 9 | 10 | static constexpr unsigned value = N * factorial::value; 11 | }; 12 | 13 | /* alternative solution with just a statis assert 14 | * in this case the second template argument is not needed 15 | template 16 | struct factorial { 17 | static_assert(N<=12, "The argument to factorial is too big"); 18 | static constexpr unsigned value = N * factorial::value; 19 | }; 20 | */ 21 | 22 | template <> 23 | struct factorial<1, void> { 24 | static constexpr unsigned value=1; 25 | }; 26 | 27 | template 28 | struct factorial12), void>::type> { 29 | // commenting out for sake of compilation static_assert(false, "The argument to factorial is too big"); 30 | static constexpr unsigned value = 0; 31 | }; 32 | 33 | int main() { 34 | std::cout << factorial<5>::value << "\n"; 35 | std::cout << factorial<12>::value << "\n"; 36 | std::cout << factorial<13>::value << "\n"; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Exercises/SmartPtrs/caching_factory_6.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | //#include 4 | #include 5 | 6 | struct Object { 7 | 8 | Object(const unsigned int i): 9 | m_value(i) 10 | { 11 | // std::cout<<"Ctor called with "< > cache; 25 | 26 | std::shared_ptr cachedFactory(const unsigned int i){ 27 | 28 | auto objPtr = cache[i].lock(); 29 | 30 | if(!objPtr){ 31 | objPtr = factory(i); 32 | cache[i] = objPtr; 33 | } 34 | 35 | return objPtr; 36 | } 37 | 38 | int main(){ 39 | 40 | // 1 - Build obj shared_ptr with slow factory method 41 | std::shared_ptr sp1(factory(3)); 42 | 43 | // 2 - Build obj shared ptr with fast factory method 44 | auto sp2(cachedFactory(3)); 45 | 46 | // 3 - Build obj shared ptr with fast factory method 47 | auto sp3(cachedFactory(3)); 48 | 49 | // 4 - Find reference count of sp3 50 | assert(sp1.use_count()==?); 51 | assert(sp2.use_count()==?); 52 | 53 | // 5 - How many calls to Object ctor? 54 | } 55 | -------------------------------------------------------------------------------- /Code/Lambdas/capture.cpp: -------------------------------------------------------------------------------- 1 | #include "../show.h" 2 | 3 | struct A { 4 | 5 | int a; 6 | int *p; 7 | 8 | A(int _a) :a(_a), p(&a) {} 9 | 10 | void operator()() { 11 | DO((auto f = [=]() {int a=0; a++; std::cout << a << std::endl;})); 12 | DO((f())); 13 | } 14 | 15 | void alternate() { // !! WARNING: only this is copied by value 16 | DO((auto f = [=]() {a++; std::cout << a << std::endl;})); 17 | DO((f())); 18 | } 19 | 20 | void alternate2() { // This is the same as alternate 21 | DO((auto f = [=]() {this->a++; std::cout << this->a << std::endl;})); 22 | DO((f())); 23 | } 24 | 25 | void safe_version() { 26 | DO((int a = 5)); 27 | DO((auto x = [=] () { std::cout << this->a << std::endl; std::cout << a << std::endl; })); 28 | DO((a = 3)); 29 | DO((x())); 30 | } 31 | 32 | void out() const { 33 | std::cout << a << "\n"; 34 | } 35 | }; 36 | 37 | 38 | int main() { 39 | 40 | A a(10); 41 | 42 | DO((a())); 43 | 44 | DO((a.out())); 45 | 46 | DO((a.alternate())); 47 | DO((a.alternate2())); 48 | 49 | DO((a.out())); 50 | 51 | DO((a.safe_version())); 52 | DO((a.out())); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Code/Constexpr/ET/automatic_differentiation.cpp: -------------------------------------------------------------------------------- 1 | #include "expressions.hpp" 2 | 3 | using namespace expressions; 4 | int main() { 5 | constexpr auto expr = x * x + x * x * x * c{3}; 6 | std::cout << expr.to_string() << "\n"; 7 | std::cout << "sums of E: " << expr.sum_ops() << "\n"; 8 | std::cout << "multiplications of E: " << expr.mult_ops() << "\n"; 9 | std::cout << "value of E in 4: " << expr(4) << "\n"; 10 | 11 | std::cout << "derivative: " << D(expr).to_string() << "\n"; 12 | std::cout << "sums of D: " << D(expr).sum_ops() << "\n"; 13 | std::cout << "multiplications of D: " << D(expr).mult_ops() << "\n"; 14 | std::cout << "value of D in 4: " << D(expr)(4) << "\n"; 15 | 16 | std::cout << "derivative of derivative: " << D(D(expr)).to_string() << "\n"; 17 | std::cout << "sums of D: " << D(D(expr)).sum_ops() << "\n"; 18 | std::cout << "multiplications of D: " << D(D(expr)).mult_ops() << "\n"; 19 | std::cout << "value of D in 4: " << D(D(expr))(4) << "\n"; 20 | 21 | static_assert(expr(4) == 208, "error"); 22 | static_assert(D(expr)(4) == 152, "error"); 23 | static_assert(D(D(expr))(4) == 74, "error"); 24 | 25 | static_assert(expr.sum_ops() == 1, "error"); 26 | static_assert(D(D(expr)).sum_ops() == 7, "error"); 27 | } 28 | -------------------------------------------------------------------------------- /Code/EnumClasses/enum_classes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../show.h" 4 | 5 | enum class Color : char {Red = 'r', Green = 'g', Blue = 'b'}; 6 | 7 | enum Size {Small=-1, Medium, Large}; 8 | enum Car {Sedan, Coupe, Compact}; 9 | 10 | std::ostream& operator<<(std::ostream& s, Color c) { 11 | return s << static_cast(c); 12 | } 13 | 14 | 15 | template 16 | void foo() { 17 | std::cout << "Color " << C << "\n"; 18 | } 19 | 20 | 21 | int main() { 22 | foo(); 23 | foo(); 24 | foo(); 25 | //foo<1>(); // Error: no conversion from int to Color 26 | foo(65)>(); // ?? UB? 27 | 28 | SHOW_BOOL((std::is_same::type, char>::value)); 29 | SHOW_BOOL((std::is_same::type, int>::value)); 30 | 31 | SHOW_BOOL((std::is_same::type, unsigned int>::value)); 32 | SHOW_BOOL((std::is_same::type, int>::value)); 33 | 34 | SHOW_BOOL((std::is_same::type, unsigned int>::value)); 35 | SHOW_BOOL((std::is_same::type, int>::value)); 36 | 37 | // Color x{1}; Since C++17 38 | } 39 | -------------------------------------------------------------------------------- /Exercises/Lambdas/lambdas_1.cpp: -------------------------------------------------------------------------------- 1 | #ifdef NDEBUG 2 | #undef NDEBUG 3 | #endif 4 | 5 | #include 6 | #include 7 | 8 | int main() { 9 | 10 | { 11 | auto sum = []( ???? ) { return i+j;}; 12 | 13 | assert(sum(3,5) == 8); 14 | } 15 | 16 | { 17 | int i; 18 | 19 | auto initialize = [????](int j) {i=j;}; 20 | 21 | initialize(42); 22 | assert(i==42); 23 | } 24 | 25 | std::string prefix("hello"); 26 | 27 | { 28 | auto concat = [????](std::string s) ???? {return prefix + " " + s;}; 29 | 30 | std::cout << concat("world") << " \n"; 31 | assert( ("hello world") == concat("world") ); 32 | } 33 | 34 | { 35 | auto concat2 = [????](std::string s) ???? {prefix[0] = std::toupper(prefix[0]); return prefix + " " + s;}; 36 | 37 | std::cout << concat2("world") << " \n"; 38 | assert( ("Hello world") == concat2("world") ); 39 | } 40 | 41 | { 42 | auto concat3 = [????](????) ???? {prefix[0] = std::toupper(prefix[0]); return prefix + " " + s + " " + std::to_string(index);}; 43 | 44 | assert( ("Hello world 42") == concat3("world", 42) ); 45 | 46 | std::cout << concat3("world", 42) << " \n"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Exercises/SmartPtrs/unique_ptr_5.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class Object{ 6 | 7 | public: 8 | 9 | Object(void) = default; 10 | 11 | Object(const int i_value): 12 | m_value(i_value) 13 | {} 14 | 15 | int getValue() const { return m_value; } 16 | 17 | void setValue(const int i_value) { m_value = i_value; } 18 | 19 | private: 20 | 21 | int m_value; 22 | 23 | }; 24 | 25 | Object* makeObject(const int i_value) { 26 | 27 | return new Object(i_value); 28 | 29 | } 30 | 31 | int main() { 32 | 33 | // 0 - Create unique_ptr 34 | std::unique_ptr up1(new Object(23)); 35 | 36 | // 1 - Transfer ownership 37 | std::unique_ptr up2(?(up1)); 38 | 39 | // 2 - Transfer again 40 | std::unique_ptr up3 = ?(up2); 41 | 42 | // 3 - Check ownership 43 | assert(up1.?==nullptr); 44 | 45 | // 4 - Fix my Factory function using unique_ptr 46 | const int value(23); 47 | Object* up4 = makeObject(value); 48 | 49 | // 5 - Create a shared_ptr using same resource (owned by up4) 50 | std::shared_ptr sp1?; 51 | 52 | // 6 - Check ownership 53 | assert(?up4); 54 | assert(?sp1); 55 | 56 | // 7 - Create a shared_ptr using makeObject 57 | std::shared_ptr sp2(?); 58 | 59 | } 60 | -------------------------------------------------------------------------------- /Code/SmartPtrs/caching_factory_6.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct Object { 7 | 8 | Object(const unsigned int i): 9 | m_value(i) 10 | { 11 | std::cout<<"Ctor called with "< factory(const unsigned int i){ 20 | 21 | return std::unique_ptr(new Object(i)); 22 | } 23 | 24 | std::shared_ptr cachedFactory(const unsigned int i){ 25 | 26 | static std::unordered_map > cache; 27 | 28 | auto objPtr = cache[i].lock(); 29 | 30 | if(!objPtr){ 31 | objPtr = factory(i); 32 | cache[i] = objPtr; 33 | } 34 | 35 | return objPtr; 36 | } 37 | 38 | int main(){ 39 | 40 | // 1 - Build obj shared_ptr with slow factory method 41 | std::shared_ptr sp1(factory(3)); 42 | 43 | // 2 - Build obj shared ptr with fast factory method 44 | auto sp2(cachedFactory(3)); 45 | 46 | // 3 - Build obj shared ptr with fast factory method 47 | auto sp3(cachedFactory(3)); 48 | 49 | // 4 - Find reference count of sp3 50 | assert(sp1.use_count()==1); 51 | assert(sp2.use_count()==2); 52 | 53 | // 5 - How many calls to Object ctor? 54 | } 55 | -------------------------------------------------------------------------------- /Code/SmartPtrs/deleters_7.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int* makeArray(const int i_size) { 6 | 7 | return new int[i_size]; 8 | } 9 | 10 | struct Object { 11 | 12 | void dumpToFile(const std::string& i_fileName) { 13 | 14 | std::cout<<"Dumping status in file "< sp(new int[10]); 24 | 25 | // 1 - Fix the above bug with a custom deleter. WARNING, THIS IS BAD CODE! USE STL CONTAINERS!!! 26 | std::shared_ptr sp_new(new int[10],[](int* p_int){ delete [] p_int; }); 27 | 28 | // 2 - Create unique_ptr from Factory function makeArray. This is the only case you would need 29 | // a unique_ptr of T[] type: an external function returning a raw pointer to heap array you take ownerhip of 30 | std::unique_ptr up(makeArray(10)); 31 | 32 | // 3 - Create unique_ptr of Object that dumps the status at destruction time 33 | const std::string fileName = "dump_file.dat"; 34 | auto up_deleter = [fileName](Object* i_obj){ i_obj->dumpToFile(fileName); }; 35 | std::unique_ptr up_obj(new Object,up_deleter); 36 | } 37 | -------------------------------------------------------------------------------- /Code/tinysimd/example/ex_scatter_add.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define N 8192 4 | 5 | constexpr unsigned width = 4; 6 | 7 | template 8 | V kernel(V x) { 9 | return 5+x*(1+x*(2+x*3)); 10 | } 11 | 12 | void scatter_add(double* __restrict out, const double* a, const int* index) { 13 | for (unsigned i = 0; i; 22 | using vint = simd; 23 | 24 | for (unsigned i = 0; i; 36 | using vint = simd; 37 | 38 | for (unsigned i = 0; i 2 | 3 | // scalar multiply vector add 4 | 5 | #define N 32768 6 | 7 | void sma(double* __restrict c, double k, const double* a, const double* b) { 8 | for (unsigned i = 0; i; 17 | 18 | for (unsigned i = 0; i; 28 | 29 | for (unsigned i = 0; i; 38 | 39 | for (unsigned i = 0; i 3 | 4 | class POD { 5 | //private: // also good 6 | public: 7 | int a; /* = 12; // non pod: this is a member initializer */ 8 | int b; 9 | char c; 10 | }; 11 | 12 | class DPOD : public POD { 13 | public: 14 | int d; 15 | }; 16 | 17 | class non_POD0 { 18 | int a; 19 | float b; 20 | public: // Not the same access control 21 | char c; 22 | }; 23 | 24 | class non_POD1 { 25 | public: 26 | int a; 27 | float b; 28 | char c; 29 | non_POD1(int& a, float b, char c) // user defined constructor 30 | : a(a), b(b), c(c) 31 | {} 32 | }; 33 | 34 | class non_POD2 { 35 | public: 36 | int &a; // reference 37 | float b; 38 | char c; 39 | non_POD2(int& a, float b, char c) 40 | : a(a), b(b), c(c) 41 | {} 42 | }; 43 | 44 | class non_POD3 { 45 | public: 46 | int a; 47 | float b; 48 | char c; 49 | non_POD3(POD const& ) = delete; // copy constructor even though deleted 50 | }; 51 | 52 | int main () { 53 | SHOW_BOOL(std::is_pod::value) 54 | SHOW_BOOL(std::is_pod::value) 55 | SHOW_BOOL(std::is_pod::value) 56 | SHOW_BOOL(std::is_pod::value) 57 | SHOW_BOOL(std::is_pod::value) 58 | SHOW_BOOL(std::is_pod::value) 59 | } 60 | -------------------------------------------------------------------------------- /Code/SmartPtrs/unique_ptr_5.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class Object{ 6 | 7 | public: 8 | 9 | Object(void) = default; 10 | 11 | Object(const int i_value): 12 | m_value(i_value) 13 | {} 14 | 15 | int getValue() const { return m_value; } 16 | 17 | void setValue(const int i_value) { m_value = i_value; } 18 | 19 | private: 20 | 21 | int m_value; 22 | 23 | }; 24 | 25 | std::unique_ptr makeObject(const int i_value) { 26 | 27 | return std::unique_ptr(new Object(i_value)); 28 | 29 | } 30 | 31 | int main() { 32 | 33 | // 0 - Create unique_ptr 34 | std::unique_ptr up1(new Object(23)); 35 | 36 | // 1 - Transfer ownership 37 | std::unique_ptr up2(std::move(up1)); 38 | 39 | // 2 - Transfer again 40 | std::unique_ptr up3 = std::move(up2); 41 | 42 | // 3 - Check ownership 43 | assert(up1.get()==nullptr); 44 | 45 | // 4 - Fix my Factory function using unique_ptr 46 | const int value(23); 47 | std::unique_ptr up4(makeObject(value)); 48 | 49 | // 5 - Create a shared_ptr using same resource (owned by up4) 50 | std::shared_ptr sp1(std::move(up4)); 51 | 52 | // 6 - Check ownership 53 | assert(!up4); 54 | assert(sp1); 55 | 56 | // 7 - Create a shared_ptr using makeObject 57 | std::shared_ptr sp2(makeObject(3)); 58 | } 59 | -------------------------------------------------------------------------------- /Code/Exceptions/performance_13.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "performance_fun.hpp" 6 | 7 | 8 | int main(){ 9 | 10 | int N_IT; 11 | std::cout<<"Enter number of loop iterations (I would suggest 10000000...): "; 12 | std::cin>>N_IT; 13 | if(N_IT<0){ 14 | std::cout<<"Number of iteration must be non negative"< 2 | #include 3 | 4 | class Object : public std::enable_shared_from_this{ 5 | 6 | public: 7 | 8 | Object(const int i_value): 9 | m_value(i_value) 10 | {} 11 | 12 | ~Object() { 13 | 14 | std::cout<<"dctor"< i_object) { 35 | 36 | // 0 - Add missing code 37 | i_object->setValue(i_value); 38 | 39 | } 40 | 41 | 42 | void Object::modify(const int i_value) { 43 | 44 | // 1 - Add missing code 45 | std::shared_ptr sp = shared_from_this(); 46 | workOnObject(i_value,sp); 47 | } 48 | 49 | #else 50 | 51 | void workOnObject(const int i_value, Object* const i_object) { 52 | 53 | i_object->setValue(i_value); 54 | 55 | } 56 | 57 | void Object::modify(const int i_value) { 58 | 59 | workOnObject(i_value,this); 60 | 61 | } 62 | 63 | #endif 64 | 65 | 66 | int main(){ 67 | 68 | std::shared_ptr object(new Object(23)); 69 | 70 | object->modify(32); 71 | 72 | std::cout<<"object->getValue() "<getValue()< 2 | #include 3 | #include 4 | 5 | int main() { 6 | 7 | // Create default random engine 8 | std::default_random_engine e; 9 | 10 | // Create uniform_int_distribution d1 with generation in [1,6) 11 | std::uniform_int_distribution<> d1{1,6}; 12 | std::cout<<"d1 range: ["<::param_type{0,2}); 16 | std::cout<<"d1 range: ["<::param_type{1,6}); 20 | std::cout<<"d1 range: ["< d2{1,6}; 24 | 25 | // Compare the distribution status 26 | std::cout<<"(d1==d2)? "<<(d1==d2)<::param_type{0,2}); 30 | std::cout<<"(d1==d2)? "<<(d1==d2)< 6 | #include 7 | 8 | template 9 | T add1(T x) { return x + 1; } 10 | 11 | std::string add1(std::string x) { return x + "1"; } 12 | 13 | 14 | int execute(int(*fp)(int), int a) { 15 | return fp(a); 16 | } 17 | 18 | template 19 | T execute(T(*fp)(T), T a) { 20 | return fp(a); 21 | } 22 | 23 | 24 | int main() { 25 | 26 | int x = 64; 27 | 28 | auto a = add1(x); 29 | static_assert(std::is_same::value, ""); 30 | assert(a == 65); 31 | 32 | std::cout << "As int " << a << "\n"; // Should print 65 33 | 34 | auto b = add1(x); 35 | static_assert(std::is_same::value, ""); 36 | assert(b == 'A'); 37 | 38 | std::cout << "As char " << b << "\n"; // Should print 'A' 39 | 40 | std::string s("64 + "); 41 | auto c = add1(s); 42 | static_assert(std::is_same::value, ""); 43 | assert(c == "64 + 1"); 44 | 45 | std::cout << "As string " << c << "\n"; 46 | 47 | 48 | int (*fp)(int) = add1; 49 | 50 | auto d = execute(fp, 41); 51 | assert(d == 42); 52 | 53 | std::cout << d << "\n"; 54 | 55 | 56 | float (*flp)(float) = add1; 57 | 58 | auto e = execute(flp, 40.9999f); 59 | assert(e == 41.9999f); 60 | 61 | std::cout << e << "\n"; 62 | } 63 | -------------------------------------------------------------------------------- /Code/Templates/Deduction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | class A { 5 | T x; 6 | public: 7 | A(T x) : x{x} {} 8 | }; 9 | 10 | template 11 | class A2 { 12 | T x; 13 | public: 14 | template 15 | A2(T x, U, int) : x{x} {} 16 | }; 17 | 18 | template 19 | struct B { 20 | F f; 21 | B(F&& f) : f{std::move(f)} {} 22 | 23 | template 24 | void call(Args&&... args) { 25 | f(std::forward(args)...); 26 | } 27 | }; 28 | 29 | 30 | template 31 | A make_A(T a) { 32 | return A{a}; 33 | } 34 | 35 | template 36 | A2 make_copy_A2(A2 a) { 37 | return A2{a}; 38 | } 39 | 40 | template 41 | A2 make_A2(T a, U x, int y) { 42 | return A2{a, x, y}; 43 | } 44 | 45 | int main() { 46 | { 47 | A x(3); 48 | A y(3); 49 | 50 | auto z = make_A(3); 51 | } 52 | { 53 | A2 x(3, 4.5, 8); 54 | 55 | auto z = make_A2(3, 4.5, 8); 56 | 57 | A2 y{x}; 58 | 59 | auto y2 = make_copy_A2(y); 60 | } 61 | auto f = [](int i, int j) { std::cout << i+j << "\n"; }; 62 | B a{std::move(f)}; 63 | 64 | B b{[](int i, int j) { std::cout << i+j << "\n"; }}; 65 | 66 | B c{[](int i, int j) { std::cout << i-j << "\n"; }}; 67 | 68 | a.call(3,4); 69 | b.call(3,4); 70 | c.call(3,4); 71 | } 72 | -------------------------------------------------------------------------------- /Code/Templates/alias.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | struct my_allocator { 6 | using value_type = T; 7 | T* allocate(std::size_t s) const {return new T[s];} 8 | void deallocate(T* p, std::size_t) const {delete [] p;} 9 | }; 10 | 11 | template 12 | using my_vec = std::vector>; 13 | 14 | template 15 | std::size_t size_of(my_vec const& v) { 16 | return v.size(); 17 | } 18 | 19 | // The following code redefined the previous size_of. my_vec is not a new type! 20 | // template 21 | // std::size_t size_of(std::vector> const& v) { 22 | // return v.size(); 23 | // } 24 | 25 | template