├── 9781484218754.jpg ├── Chapter 1 ├── 01 - complex.cpp ├── 02 - ratio.cpp ├── 03 - random - Dice Roll.cpp ├── 04 - random - Dice Roll - bind.cpp ├── 05 - random - Seeding.cpp ├── 06 - random - Piecewise Constant Distribution.cpp ├── 07 - random - Piecewise Linear Distribution.cpp ├── 08 - valarray.cpp ├── 09 - valarray - slice.cpp ├── 10 - valarray - gslice.cpp ├── 11 - valarray - mask_array.cpp └── 12 - valarray - indirect_array.cpp ├── Chapter 2 ├── 01 - Moving.cpp ├── 02 - Move Assignment.cpp ├── 03 - Forwarding.cpp ├── 04 - pair.cpp ├── 05 - tuple.cpp ├── 06 - rel_ops.cpp ├── 07 - unique_ptr.cpp ├── 08 - unique_ptr - Array.cpp ├── 09 - unique_ptr - Take Ownership.cpp ├── 10 - unique_ptr - fopen.cpp ├── 11 - shared_ptr.cpp ├── 12 - shared_ptr - fopen.cpp ├── 13 - shared_ptr - Casts.cpp ├── 14 - shared_ptr - Aliasing.cpp ├── 15 - weak_ptr.cpp ├── 16 - my_plus.cpp ├── 17 - reference_wrapper.cpp ├── 18 - sort.cpp ├── 19 - plus.cpp ├── 20 - function.cpp ├── 21 - bind.cpp ├── 22 - Functors for Class Members.cpp ├── 23 - mem_fn.cpp ├── 24 - initializer_list.cpp ├── 25 - initializer_list - ExampleClass.cpp ├── 26 - duration.cpp ├── 27 - time_point.cpp ├── 28 - clock.cpp ├── 29 - strftime.cpp ├── 30 - typeid.cpp ├── 31 - Type Traits.cpp ├── 32 - copy.cpp └── 33 - my_decay.cpp ├── Chapter 3 ├── 01 - non-member begin and end.cpp ├── 02 - range-based for loop.cpp ├── 03 - vector.cpp ├── 04 - deque.cpp ├── 05 - array.cpp ├── 06 - list.cpp ├── 07 - bitset.cpp ├── 08 - Container Adapters.cpp ├── 09 - map.cpp ├── 10 - set.cpp └── 11 - hash - Person.cpp ├── Chapter 4 ├── 01 - transform.cpp ├── 02 - all_of.cpp ├── 03 - find_if.cpp ├── 04 - lower_bound.cpp ├── 05 - equal_range.cpp ├── 06 - generate and iota.cpp ├── 07 - unique.cpp ├── 08 - rotate.cpp ├── 09 - partial_sort_copy.cpp ├── 10 - nth_element.cpp ├── 11 - shuffle.cpp ├── 12 - accumulate.cpp ├── 13 - inner_product.cpp └── 14 - Iterator Adaptors.cpp ├── Chapter 5 ├── 01 - Manipulators.cpp ├── 02 - Error Handling.cpp ├── 03 - ostream.cpp ├── 04 - istream.cpp ├── 05 - sstream.cpp ├── 06 - fstream - input and output.cpp ├── 07 - fstream.cpp ├── 08 - Custom Output and Extraction Operator.cpp ├── 09 - ostream_iterator.cpp ├── 10 - istream_iterator.cpp ├── 11 - Stream Iterators.cpp ├── 12 - Stream Buffers - Redirect.cpp ├── 13 - Stream Buffers - Read File.cpp ├── 14 - printf.cpp ├── 15 - printf - Formatting.cpp └── 16 - scanf.cpp ├── Chapter 6 ├── 01 - string.cpp ├── 02 - codecvt.cpp ├── 03 - Global Locale.cpp ├── 04 - use_facet.cpp ├── 05 - Monetary Formatting.cpp ├── 06 - String Ordering.cpp ├── 07 - Combining Facets.cpp ├── 08 - Custom Facets - yes_no.cpp ├── 09 - Custom Facets - Accounting.cpp ├── 10 - C Locales.cpp ├── 11 - regex.cpp └── 12 - regex_replace.cpp ├── Chapter 7 ├── 01 - Threads.cpp ├── 02 - Futures.cpp ├── 03 - Mutual Exclusion.cpp ├── 04 - call_once.cpp ├── 05 - Condition Variables.cpp └── 06 - Atomic Operations.cpp ├── Chapter 8 ├── 01 - assert.cpp ├── 02 - Exception Pointers.cpp ├── 03 - Nested Exceptions.cpp ├── 04 - system_error.cpp └── 05 - cerrno.cpp ├── Common.zip ├── LICENSE.txt ├── README.md └── contributing.md /9781484218754.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/cpp-standard-library-quick-reference/2532dfcf52d18dfd6ddf00fdde83bbe74cf2f655/9781484218754.jpg -------------------------------------------------------------------------------- /Chapter 1/01 - complex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::complex c(1, 2); // Both arguments are optional (default: 0) 7 | std::cout << "c=" << c.real() << '+' << c.imag() << 'i' << '\n'; // c=1+2i 8 | c.real(3); c.imag(3); c += 1; 9 | std::cout << "norm(" << c << ") = " << std::norm(c); // norm((4,3)) = 25 10 | 11 | std::cout << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter 1/02 - ratio.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | typedef std::ratio<1, 3> a_third; 7 | typedef std::ratio<1, 2> a_half; 8 | typedef std::ratio<2, 4> two_quart; 9 | typedef std::ratio_add sum; 10 | 11 | std::cout << two_quart::num << '/' << two_quart::den << '\n'; // 1/2 12 | std::cout << sum::num << '/' << sum::den << '\n'; // 5/6 13 | std::cout << std::boolalpha; /* print true/false instead of 1/0 */ 14 | std::cout << (typeid(two_quart) == typeid(a_half)) << '\n'; // false 15 | std::cout << (typeid(two_quart::type) == typeid(a_half)) << '\n'; // true 16 | std::cout << std::ratio_equal::value << '\n'; // true 17 | 18 | std::cout << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter 1/03 - random - Dice Roll.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::default_random_engine generator; 7 | std::uniform_int_distribution distribution(1, 6); 8 | int dice_roll = distribution(generator); // 1 <= dice_roll <= 6 9 | std::cout << dice_roll << std::endl; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter 1/04 - random - Dice Roll - bind.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::default_random_engine generator; 8 | std::uniform_int_distribution distribution(1, 6); 9 | std::function roller = std::bind(distribution, generator); 10 | for (int i = 0; i < 100; ++i) 11 | { 12 | std::cout << roller() << '\n'; 13 | } 14 | 15 | std::cout << std::endl; 16 | } 17 | -------------------------------------------------------------------------------- /Chapter 1/05 - random - Seeding.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::random_device seeder; 8 | const auto seed = seeder.entropy() ? seeder() : std::time(nullptr); 9 | std::default_random_engine generator( 10 | static_cast(seed)); 11 | 12 | std::uniform_int_distribution distribution(1, 6); 13 | int dice_roll = distribution(generator); // 1 <= dice_roll <= 6 14 | std::cout << dice_roll << std::endl; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter 1/06 - random - Piecewise Constant Distribution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::mt19937 generator; // Default-seeded for this example 8 | std::vector intervals = { 1,20,40,60,80 }; 9 | std::vector weights = { 1,3,1,3 }; 10 | std::piecewise_constant_distribution distribution( 11 | begin(intervals), end(intervals), begin(weights)); 12 | int value = static_cast(distribution(generator)); 13 | std::cout << value << std::endl; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter 1/07 - random - Piecewise Linear Distribution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::mt19937 generator; // Default-seeded for this example 8 | std::vector intervals = { 1,20,40,60,80 }; 9 | std::vector weights = { 1,3,1,3,1 }; 10 | std::piecewise_linear_distribution distribution( 11 | begin(intervals), end(intervals), begin(weights)); 12 | int value = static_cast(distribution(generator)); 13 | std::cout << value << std::endl; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter 1/08 - valarray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::valarray ints1(7); // 7 zero-initialized integers 7 | std::valarray doubles = { 1.1, 2.2, 3.3 }; 8 | int carray[] = { 6,5,4,3,2,1 }; 9 | std::valarray ints2(carray, 3); // Contains 6,5,4 10 | 11 | std::cout << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter 1/09 - valarray - slice.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::valarray ints = { 0,1,2,3,4,5,6,7 }; 7 | std::slice mySlicer(2, 3, 2); 8 | const std::valarray& constInts = ints; 9 | auto copies = constInts[mySlicer]; // valarray with copies of 2,4,6 10 | auto refs = ints[mySlicer]; // slice_array with references to 2,4,6 11 | std::valarray factors{ 6,3,2 }; 12 | refs *= factors; // ints will be 0,1,12,3,12,5,12,7 13 | 14 | std::cout << std::endl; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter 1/10 - valarray - gslice.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::valarray a = { 0,11,22,33,44,55,66,77,88,99,111 }; 7 | std::valarray sizes{ 2, 3 }; 8 | std::valarray strides{ 5, 2 }; 9 | std::valarray r = a[std::gslice(1, sizes, strides)]; //11,33,55,66,88,111 10 | 11 | std::cout << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter 1/11 - valarray - mask_array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::valarray ints = { 0,1,2,3,4,5,6,7,8,9,10 }; 7 | // Construct a valarray with true for all even elements in ints. 8 | std::valarray even = ((ints % 2) == 0); 9 | // Count the number of true values in even. 10 | int count = std::count(begin(even), end(even), true); 11 | // Construct a valarray with count elements of value 4. 12 | std::valarray factors(4, count); 13 | // Multiply the even elements in ints with a factor of 4. 14 | ints[even] *= factors; // 0,1,8,3,16,5,24,7,32,9,40 15 | 16 | std::cout << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter 1/12 - valarray - indirect_array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::valarray ints = { 0,1,2,3,4 }; 7 | std::valarray indices = { 1,3,4 }; 8 | ints[indices] = -1; // 0,-1,2,-1,-1 9 | 10 | std::cout << std::endl; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter 2/01 - Moving.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void f(std::string s) 5 | { 6 | std::cout << "Moved or copied: " << s << '\n'; 7 | } 8 | 9 | void g(std::string&& s) 10 | { 11 | std::cout << "Moved " << s << '\n'; 12 | } 13 | 14 | std::string h() 15 | { 16 | std::string s("test"); 17 | return s; // moved implicitly, same as std::move(s) 18 | } 19 | 20 | int main() 21 | { 22 | std::string test("123"); 23 | f(test); // test is copied to a new string 24 | f(std::move(test)); // test is moved to a new string (move constructor) 25 | // std::cout << test; --> Undefined: may give "" or "123", or simply crash 26 | test = "456"; // test is reinitialized, and may be used again 27 | // g(test); --> Does not compile 28 | g(std::move(test)); 29 | g(std::string("789")); // Unnamed objects are moved implicitly 30 | g(h()); 31 | 32 | std::cout << std::endl; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter 2/02 - Move Assignment.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::string one("Test 123"); 7 | std::string other; 8 | other = std::move(one); 9 | // std::cout << one; --> Undefined behavior: one was moved to other 10 | 11 | std::cout << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter 2/03 - Forwarding.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct A 4 | { 5 | A() {} 6 | A(const A&) = delete; // A objects cannot be copied 7 | }; 8 | 9 | void f(const A&) 10 | { 11 | std::cout << "lval, "; // forwarded as lvalue reference 12 | } 13 | 14 | void f(A&&) 15 | { 16 | std::cout << "rval, "; // forwarded as rvalue reference 17 | } 18 | 19 | // Three different forwarding (fwd) schemes: 20 | template void good_fwd(T&& t) { f(std::forward(t)); } 21 | template void bad_fwd(T&& t) { f(t); } 22 | template void ugly_fwd(T t) { f(t); } 23 | 24 | int main() 25 | { 26 | A a; 27 | good_fwd(a); good_fwd(std::move(a)); good_fwd(A()); // lval, rval, rval, 28 | bad_fwd(a); bad_fwd(std::move(a)); bad_fwd(A()); // lval, lval, lval, 29 | // ugly_fwd(a); ugly_fwd(std::move(a)); ugly_fwd(A()); --> error: 3x copy 30 | 31 | std::cout << std::endl; 32 | } 33 | -------------------------------------------------------------------------------- /Chapter 2/04 - pair.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../Common/Person.h" 5 | 6 | int main() 7 | { 8 | std::pair p1(42u, Person("Douglas", "Adams")); 9 | 10 | 11 | auto p2 = std::make_pair(42u, Person("Douglas", "Adams")); 12 | 13 | 14 | std::pair p3(std::piecewise_construct, 15 | std::make_tuple(42u), std::forward_as_tuple("Douglas", "Adams")); 16 | 17 | 18 | std::cout << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter 2/05 - tuple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | auto t = std::make_tuple(1, 2, 0.3, std::string("4")); 8 | std::cout << std::get<0>(t) << '\n'; // get using 0-based index 9 | std::get<2>(t) = 3.0; // no set required: get returns a reference 10 | std::cout << std::get(t) << '\n'; // get using unique type 11 | // std::cout << std::get(t) << '\n'; --> ambiguous: compiler error! 12 | std::string s = std::get<3>(std::move(t)); // move a value out of a tuple 13 | 14 | 15 | int one, two; 16 | double three; 17 | std::tie(one, two, three, std::ignore) = t; 18 | 19 | 20 | std::cout << std::tuple_size::value << '\n'; // 4 21 | std::tuple_element<0, decltype(t)>::type elementOne = std::get<0>(t); // int 22 | std::cout << elementOne << std::endl; 23 | 24 | 25 | std::cout << std::endl; 26 | } 27 | -------------------------------------------------------------------------------- /Chapter 2/06 - rel_ops.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../Common/Person.h" 4 | 5 | int main() 6 | { 7 | // Works even though only operator< is defined for our Person class: 8 | using namespace std::rel_ops; 9 | const bool comparison = (Person("Alexander") > Person("Bob")); 10 | std::cout << comparison; // 0 (Alexander is not greater) 11 | 12 | std::cout << std::endl; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter 2/07 - unique_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../Common/Person.h" 4 | 5 | void DoSomethingWith(Person& person) 6 | { 7 | /* ... */ 8 | } 9 | 10 | int main() 11 | { 12 | { 13 | std::unique_ptr jeff(new Person("Jeffrey")); 14 | if (jeff != nullptr) 15 | jeff->SetLastName("Griffin"); 16 | if (jeff) 17 | DoSomethingWith(*jeff); // Dereference as Person& 18 | } // jeff is deleted, even if DoSomethingWith() throws 19 | 20 | 21 | { 22 | auto jeff = std::make_unique("Jeffrey"); 23 | if (jeff != nullptr) 24 | jeff->SetLastName("Griffin"); 25 | if (jeff) 26 | DoSomethingWith(*jeff); // Dereference as Person& 27 | } // jeff is deleted, even if DoSomethingWith() throws 28 | 29 | 30 | std::cout << std::endl; 31 | } 32 | -------------------------------------------------------------------------------- /Chapter 2/08 - unique_ptr - Array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void DoSomethingWith(int* data) 5 | { 6 | /* ... */ 7 | } 8 | 9 | int main() 10 | { 11 | { 12 | std::unique_ptr array(new int[123]); // or make_unique(123) 13 | for (int i = 0; i < 123; ++i) 14 | array[i] = i; 15 | DoSomethingWith(array.get()); // Pass raw int* pointer 16 | } // array is delete[]'d, even if DoSomethingWith() throws 17 | 18 | std::cout << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter 2/09 - unique_ptr - Take Ownership.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../Common/Person.h" 4 | 5 | void TakeOwnership(Person* person) 6 | { 7 | /* Do something with person and delete it! */ 8 | } 9 | 10 | int main() 11 | { 12 | auto niles = std::make_unique("Niles", "Crane"); 13 | niles.reset(new Person("Niles", "Butler")); // Niles Crane is deleted 14 | TakeOwnership(niles.release()); // TakeOwnership() must delete Niles Butler 15 | 16 | std::cout << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter 2/10 - unique_ptr - fopen.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void DoSomethingWith(FILE* file) 7 | { 8 | /* ... */ 9 | } 10 | 11 | int main() 12 | { 13 | { 14 | std::unique_ptr> smartFilePtr(fopen("test.txt", "r"), fclose); 15 | DoSomethingWith(smartFilePtr.get()); 16 | } // The FILE* is closed, even if DoSomethingWith() throws 17 | 18 | std::cout << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter 2/11 - shared_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | { 7 | auto bond = std::make_shared(007); // bond.use_count() == 1 8 | auto james = bond; // james.use_count() == 2 && bond.use_count() == 2 9 | bond.reset(); // james.use_count() == 1 && bond.use_count() == 0 10 | } // 007 is deleted 11 | 12 | std::cout << std::endl; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter 2/12 - shared_ptr - fopen.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void DoSomethingWith(FILE* file) 6 | { 7 | /* ... */ 8 | } 9 | 10 | int main() 11 | { 12 | { 13 | std::shared_ptr smartFilePtr(fopen("test.txt", "r"), fclose); 14 | DoSomethingWith(smartFilePtr.get()); 15 | } // The FILE* is closed, even if DoSomethingWith() throws 16 | 17 | std::cout << std::endl; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter 2/13 - shared_ptr - Casts.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class A { public: virtual ~A() {}; }; 5 | class B : public A {}; 6 | class C {}; 7 | 8 | int main() 9 | { 10 | std::shared_ptr a = std::make_shared(); // a points to a new B() 11 | std::shared_ptr b = std::dynamic_pointer_cast(a); 12 | std::shared_ptr c = std::dynamic_pointer_cast(a); 13 | // (c == nullptr) && (a.use_count() == b.use_count() == 2) 14 | 15 | std::cout << std::endl; 16 | } 17 | -------------------------------------------------------------------------------- /Chapter 2/14 - shared_ptr - Aliasing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct A 5 | { 6 | int* member; 7 | /* ... */ 8 | }; 9 | 10 | int main() 11 | { 12 | auto a = std::make_shared(); 13 | auto m = std::shared_ptr(a, a->member); // aliasing constructor 14 | // a.use_count() == m.use_count() == 2 15 | 16 | 17 | std::cout << std::endl; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter 2/15 - weak_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void DoSomethingWith(std::string& s) 5 | { 6 | /* ... */ 7 | } 8 | 9 | int main() 10 | { 11 | auto s = std::make_shared("SharedString"); 12 | auto w = std::weak_ptr(s); //w.use_count() == s.use_count() == 1 13 | { 14 | std::shared_ptr s2 = w.lock(); 15 | DoSomethingWith(*s2); // w.use_count() == s.use_count() == 2 16 | } // w.use_count() == s.use_count() == 1 17 | s.reset(); // w.expired() == true 18 | 19 | 20 | std::cout << std::endl; 21 | } 22 | -------------------------------------------------------------------------------- /Chapter 2/16 - my_plus.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | struct my_plus 5 | { 6 | T operator() (const T& x, const T& y) const { return x + y; } 7 | }; 8 | 9 | int main() 10 | { 11 | my_plus functor; 12 | std::cout << functor(11, 22) << std::endl; // 33 13 | 14 | std::cout << std::endl; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter 2/17 - reference_wrapper.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | int i = 234; 8 | std::vector> v{ std::ref(i) }; // cf. Chapter 3 9 | v[0].get() = 432; // Occasionally, like here, an explicit get() is needed 10 | // (v[0] returns reference_wrapper&, not int&). 11 | std::cout << v[0] << "==" << i << std::endl; // 432==432 12 | 13 | std::cout << std::endl; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter 2/18 - sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | int array[] = { 7, 9, 7, 2, 0, 4 }; 8 | std::sort(std::begin(array), std::end(array), std::greater()); 9 | 10 | std::cout << std::endl; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter 2/19 - plus.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::plus<> functor; // defaults to std::plus 7 | std::cout << functor(234, 432) << ' ' << functor(1.101, 2.0405) << std::endl; 8 | 9 | std::cout << std::endl; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter 2/20 - function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | bool my_less(int x, int y) { return x < y; } 5 | 6 | int main() 7 | { 8 | std::function test = my_less; // function 9 | test = &my_less; // function pointer 10 | test = std::less<>{}; // function object 11 | test = [](int x, int y) { return x < y; }; // lambda closure 12 | if (test) std::cout << test(234, 432) << std::endl; // 1 (true) 13 | 14 | std::cout << std::endl; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter 2/21 - bind.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | bool my_less(int x, int y) { return x < y; } 8 | void f(std::string& x, char y) { x += y; } 9 | 10 | int main() 11 | { 12 | using namespace std::placeholders; // contains _1, _2, _3, ... 13 | auto my_greater = std::bind(my_less, _2, _1); // function + swap _1 _2 14 | auto twice = std::bind(std::plus{}, _1, _1); // functor + twice _1 15 | auto plus5 = std::bind(std::plus{}, _1, 5); // functor + fixed 5 16 | std::cout << my_greater(twice(13), plus5(20)) << '\n'; // 1 (true) 17 | 18 | // bind() expressions may be nested whilst sharing placeholders: 19 | auto g = std::bind(my_greater, std::bind(twice, _1), std::bind(plus5, _1)); 20 | std::cout << g(10) << ' ' << g(4) << '\n'; // 1 0 (true false) 21 | 22 | // Use std::ref()/cref() to pass references 23 | // (For containers, algorithms, and strings see chapters 3, 4, and 6) 24 | std::vector v{ 'c', 'o', 'n', 'c', 'a', 't' }; 25 | std::string concat; 26 | std::for_each(begin(v), end(v), std::bind(f, std::ref(concat), _1)); 27 | std::cout << concat << std::endl; 28 | 29 | std::cout << std::endl; 30 | } 31 | -------------------------------------------------------------------------------- /Chapter 2/22 - Functors for Class Members.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct my_struct { int val; bool fun(int i) { return val == i; } }; 5 | 6 | int main() 7 | { 8 | my_struct s{ 234 }; 9 | 10 | std::function f_get_val = &my_struct::val; 11 | std::function f_call_fun = &my_struct::fun; 12 | std::cout << f_get_val(s) << ' ' << f_call_fun(s, 123) << std::endl; 13 | 14 | using std::placeholders::_1; 15 | auto b_get_val = std::bind(&my_struct::val, _1); 16 | auto b_call_fun_on_s = std::bind(&my_struct::fun, std::ref(s), _1); 17 | std::cout << b_get_val(s) << ' ' << b_call_fun_on_s(234) << std::endl; 18 | 19 | auto m_get_val = std::mem_fn(&my_struct::val); 20 | auto m_call_fun = std::mem_fn(&my_struct::fun); 21 | std::cout << m_get_val(s) << ' ' << m_call_fun(s, 456) << std::endl; 22 | 23 | 24 | std::cout << std::endl; 25 | } 26 | -------------------------------------------------------------------------------- /Chapter 2/23 - mem_fn.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | std::vector v{ "Test", "", "123", "", "" }; 10 | std::cout << std::count_if(begin(v), end(v), std::mem_fn(&std::string::empty)); // 3 11 | 12 | std::cout << std::endl; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter 2/24 - initializer_list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | auto list = { 1, 2, 3 }; // list has type std::initializer_list 7 | 8 | std::cout << std::endl; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter 2/25 - initializer_list - ExampleClass.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class ExampleClass { 5 | public: 6 | ExampleClass(int, int) { std::cout << "(int, int) ctor" << '\n'; } 7 | ExampleClass(std::initializer_list) { std::cout << "initializer_list ctor" << '\n'; } 8 | }; 9 | 10 | int main() 11 | { 12 | ExampleClass a(1, 2); // (int, int) constructor is used 13 | ExampleClass b{ 1, 2 }; // initializer_list constructor is used 14 | 15 | 16 | std::cout << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter 2/26 - duration.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | using namespace std::chrono; 7 | typedef duration> hours_t; 8 | typedef duration millisecs_t; // milli == ratio<1,1000> 9 | const hours_t one_hour(1); 10 | const millisecs_t ms(one_hour); 11 | std::cout << "1h = " << ms.count() << "ms" << '\n'; // 1h = 3600000ms 12 | 13 | 14 | // const hours_t back_to_hours(ms); <-- error (int64_t would be truncated) 15 | const auto back_to_hours = duration_cast(ms); 16 | 17 | 18 | const auto secs = duration_cast(0.5h); 19 | std::cout << "0.5h = " << secs.count() << "s" << '\n'; // 0.5h = 1800s 20 | 21 | 22 | const auto result = duration_cast((12min + .5h) / 2 + (100ns >= 1ms ? -3h : ++59s)); 23 | std::cout << result.count(); 24 | 25 | 26 | std::cout << std::endl; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter 2/27 - time_point.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | using namespace std::chrono; 7 | 8 | time_point one_hour(1h); // 1h since epoch 9 | time_point sixty_minutes = one_hour; 10 | std::cout << (one_hour - sixty_minutes).count() << std::endl; // 0 11 | 12 | 13 | auto one_hour2 = time_point_cast(sixty_minutes); 14 | 15 | 16 | std::cout << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter 2/28 - clock.cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS // To make sure ctime() works with Visual C++. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | using std::chrono::steady_clock; 10 | const steady_clock::time_point before = steady_clock::now(); 11 | std::cout << steady_clock::period::num << '/' /* Possible output: */ 12 | << steady_clock::period::den << '\n'; // 1/1000000000 13 | std::cout << (steady_clock::now() - before).count() << '\n'; // 34721 14 | 15 | 16 | using std::chrono::system_clock; 17 | const auto now = system_clock::now(); /* Possible output: */ 18 | const time_t now_time_t = system_clock::to_time_t(now); 19 | std::cout << now.time_since_epoch().count() << '\n'; // 1445470140000 20 | std::cout << ctime(&now_time_t) << '\n'; // Wed Oct 21 16:29:00 2015 21 | 22 | 23 | std::cout << std::endl; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter 2/29 - strftime.cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS // To make sure localtime() works with Visual C++. 2 | 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | time_t time = std::time(nullptr); 9 | tm time_tm = *std::localtime(&time); 10 | char buffer[256]; 11 | strftime(buffer, sizeof(buffer), "Today is %a %e/%m%n", &time_tm); 12 | std::cout << buffer; // Today is Sat 30/01 13 | strftime(buffer, sizeof(buffer), "%c--%x %X", &time_tm); 14 | std::cout << buffer << '\n'; // Sat Jan 30 17:58:23 2016--01/30/16 17:58:23 15 | 16 | std::cout << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter 2/30 - typeid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::string s; 7 | std::cout << typeid(s).name() << '\n'; 8 | std::cout << (typeid(typeid(s).name()) == typeid(s.data())); // 1 (true) 9 | 10 | std::cout << std::endl; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter 2/31 - Type Traits.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::cout << std::boolalpha; // Print true/false instead of 1/0 7 | std::cout << std::is_integral::value << '\n'; // true 8 | std::cout << std::is_class>::value << '\n'; // true 9 | std::cout << std::is_function::value << '\n'; // true 10 | std::cout << std::is_function::value << '\n'; // true 11 | std::cout << std::is_pointer::value << '\n'; // true 12 | struct A { void f() {}; }; 13 | void(A::* p)() = &A::f; 14 | std::cout << std::is_member_function_pointer() << '\n';// true 15 | 16 | std::cout << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter 2/32 - copy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // use the efficient memcpy() if allowed (i.e., if T is trivially copyable): 6 | template 7 | typename std::enable_if::value>::type 8 | copy(T(&from)[N], T(&to)[N]) 9 | { 10 | std::memcpy(to, from, N * sizeof(T)); 11 | } 12 | 13 | // otherwise, copy elements one by one using copy assignment: 14 | template 15 | std::enable_if_t::value> 16 | copy(T(&from)[N], T(&to)[N]) 17 | { 18 | for (size_t i = 0; i < N; ++i) 19 | to[i] = from[i]; 20 | } 21 | 22 | int main() 23 | { 24 | int arrayFrom[12] = { 0 }; 25 | int arrayTo[12] = { 0 }; 26 | copy(arrayFrom, arrayTo); // Calls the first copy() implementation. 27 | 28 | std::string vecFrom[2] = { "A", "B" }; 29 | std::string vecTo[2]; 30 | copy(vecFrom, vecTo); // Calls the second copy() implementation. 31 | 32 | 33 | std::cout << std::endl; 34 | } 35 | -------------------------------------------------------------------------------- /Chapter 2/33 - my_decay.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | template 7 | struct my_decay 8 | { 9 | private: 10 | typedef remove_reference_t U; 11 | 12 | public: 13 | typedef conditional_t::value, remove_extent_t*, 14 | conditional_t::value, add_pointer_t, 15 | remove_cv_t> > type; 16 | }; 17 | 18 | 19 | int main() 20 | { 21 | std::cout << typeid(my_decay::type).name() << '\n'; // int 22 | std::cout << typeid(my_decay::type).name() << '\n'; // const int * 23 | 24 | 25 | std::cout << std::endl; 26 | } 27 | -------------------------------------------------------------------------------- /Chapter 3/01 - non-member begin and end.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | int myArray[] = { 1,2,3,4 }; 7 | auto beginIter = std::cbegin(myArray); 8 | auto endIter = std::cend(myArray); 9 | for (auto iter = beginIter; iter != endIter; ++iter) { 10 | std::cout << *iter << std::endl; 11 | } 12 | 13 | std::cout << std::endl; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter 3/02 - range-based for loop.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | int myArray[] = { 1,2,3,4 }; 6 | for (const auto& element : myArray) { 7 | std::cout << element << std::endl; 8 | } 9 | 10 | 11 | std::cout << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter 3/03 - vector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../Common/Person.h" 5 | 6 | int main() 7 | { 8 | { 9 | std::vector myVector1 = { 1,2,3,4 }; 10 | std::vector myVector2{ 1,2,3,4 }; 11 | } 12 | 13 | 14 | { 15 | std::vector myVector(100, 12); 16 | 17 | 18 | myVector[1] = 22; 19 | std::cout << myVector[1] << '\n'; // 22 20 | } 21 | 22 | 23 | { 24 | std::vector myVector; 25 | myVector.push_back(11); 26 | myVector.push_back(2); 27 | } 28 | 29 | 30 | { 31 | std::vector myVector = { 1,2,3,4 }; 32 | myVector.insert(myVector.begin() + 2, 22); // 1,2,22,3,4 33 | } 34 | 35 | 36 | { 37 | std::vector myVector = { 1,2,3,4 }; 38 | for (auto iter = myVector.begin(); iter != myVector.end(); ++iter) 39 | { 40 | if (*iter % 2 == 0) // Duplicate all even values... 41 | iter = myVector.insert(iter + 1, *iter); 42 | } 43 | } 44 | 45 | 46 | { 47 | std::vector v1{ 1,2,3 }; 48 | std::vector v2{ 4,5 }; 49 | v1.insert(cbegin(v1) + 1, cbegin(v2), cend(v2)); // 1,4,5,2,3 50 | v1.insert(cend(v1), cbegin(v2), cend(v2)); // 1,4,5,2,3,4,5 (append!) 51 | 52 | 53 | v1.insert(cbegin(v1) + 1, { 4,5 }); // 1,4,5,2,3 54 | v1.insert(cend(v1), 2, 6); // 1,4,5,2,3,6,6 55 | } 56 | 57 | 58 | { 59 | std::vector persons; 60 | persons.push_back(Person("Sheldon", "Cooper", true)); 61 | persons.emplace_back("Leonard", "Hofstadter", false); 62 | 63 | 64 | Person person("Howard", "Wolowitz"); 65 | persons.push_back(std::move(person)); 66 | } 67 | 68 | 69 | { 70 | std::vector myVector; 71 | myVector.resize(100, 12); 72 | 73 | 74 | myVector.reserve(100); 75 | 76 | 77 | myVector.reserve(myVector.size() + 100); 78 | } 79 | 80 | 81 | { 82 | std::vector unlucky(100000, 13); // Now reclaim unlucky's memory... 83 | { std::vector empty; empty.swap(unlucky); } 84 | 85 | 86 | std::vector().swap(unlucky); // (temporary is destroyed after ';') 87 | } 88 | 89 | 90 | { 91 | std::vector myVector{ 1,2,3,2,2,6 }; 92 | for (auto it = cbegin(myVector); it != cend(myVector);) { 93 | if (*it == 2) 94 | it = myVector.erase(it); // Returns iterator one past the removed item 95 | else 96 | ++it; 97 | } 98 | } 99 | 100 | 101 | { 102 | std::vector vec{ 1,2,3,2,2,6 }; // 1,2,3,2,2,6 103 | auto iter = std::remove(begin(vec), end(vec), 2); // 1,3,6,2,2,6 104 | vec.erase(iter, end(vec)); // 1,3,6 105 | 106 | 107 | vec.erase(std::remove(begin(vec), end(vec), 2), end(vec)); 108 | } 109 | 110 | 111 | std::cout << std::endl; 112 | } 113 | -------------------------------------------------------------------------------- /Chapter 3/04 - deque.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::deque myDeque = { 1,2,3,4 }; 7 | myDeque.insert(myDeque.begin() + 2, 22); // 1,2,22,3,4 8 | myDeque.pop_front(); // 2,22,3,4 9 | myDeque.erase(myDeque.begin() + 1); // 2,3,4 10 | myDeque.push_front(11); // 11,2,3,4 11 | 12 | 13 | std::cout << std::endl; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter 3/05 - array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | { 7 | std::array myArray; 8 | } 9 | 10 | 11 | { 12 | std::array myArray{ 1,2 }; // 1,2,0 13 | } 14 | 15 | 16 | { 17 | std::array myArray{}; // 0,0,0 18 | 19 | 20 | myArray.fill(5); // 5,5,5 21 | } 22 | 23 | 24 | std::cout << std::endl; 25 | } 26 | -------------------------------------------------------------------------------- /Chapter 3/06 - list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::list list1{ 1,7,5 }, list2{ 5,6,2 }, list3{ 3,4 }; 7 | list1.sort(); // 1,5,7 8 | list2.sort(); // 2,5,6 9 | list1.merge(list2); // list1 = 1,2,5,5,6,7 10 | // list2 = empty 11 | list1.unique(); // 1,2,5,6,7 12 | 13 | auto splicePosition = std::next(begin(list1), 2); 14 | list1.splice(splicePosition, list3); // list1 = 1,2,3,4,5,6,7 15 | // list3 = empty 16 | 17 | 18 | std::cout << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter 3/07 - bitset.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | { 7 | std::bitset<10> myBitset; 8 | } 9 | 10 | 11 | { 12 | std::bitset<4> myBitset("1001"); 13 | } 14 | 15 | std::cout << std::endl; 16 | } 17 | -------------------------------------------------------------------------------- /Chapter 3/08 - Container Adapters.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../Common/Person.h" 5 | 6 | int main() 7 | { 8 | std::queue cont; 9 | cont.emplace("Doug", "B", true); 10 | cont.emplace("Phil", "W", false); 11 | cont.emplace("Stu", "P", true); 12 | cont.emplace("Alan", "G", false); 13 | while (!cont.empty()) 14 | { 15 | std::cout << cont.front() << std::endl; // queue 16 | // std::cout << cont.top() << std::endl; // priority_queue and stack 17 | cont.pop(); 18 | } 19 | 20 | 21 | std::cout << std::endl; 22 | } 23 | -------------------------------------------------------------------------------- /Chapter 3/09 - map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../Common/Person.h" 4 | 5 | int main() 6 | { 7 | std::map myMap{ { Person("Jenne"), 1 },{ Person("Bart"), 2 } }; 8 | 9 | 10 | auto iter = begin(myMap); // type of iter is pair 11 | std::cout << "Key=" << iter->first.GetFirstName(); // Key=Bart (not Jenne) 12 | std::cout << ", Value=" << iter->second; // , Value=2 13 | 14 | 15 | myMap[Person("Peter")] = 3; 16 | 17 | 18 | myMap.insert(std::make_pair(Person("Marc"), 4)); 19 | 20 | 21 | myMap.emplace(Person("Anna"), 4); 22 | 23 | 24 | myMap.emplace(std::piecewise_construct, 25 | std::forward_as_tuple("Anna"), std::forward_as_tuple(4)); 26 | 27 | 28 | std::cout << std::endl; 29 | } 30 | -------------------------------------------------------------------------------- /Chapter 3/10 - set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::set mySet{ 3,2,1 }; 7 | mySet.insert(2); 8 | mySet.insert(6); 9 | std::cout << mySet.size() << ' ' << *mySet.begin(); // 4 1 10 | 11 | 12 | std::cout << std::endl; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter 3/11 - hash - Person.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../Common/Person.h" 4 | 5 | namespace std { 6 | template<> struct hash { 7 | // Two nested types required by the Standard for specializations, but 8 | // not specified to be part of the (unspecified) hash template: 9 | typedef Person argument_type; 10 | typedef std::size_t result_type; 11 | 12 | result_type operator()(const argument_type& p) const { 13 | auto firstNameHash(std::hash()(p.GetFirstName())); 14 | auto lastNameHash(std::hash()(p.GetLastName())); 15 | return firstNameHash ^ lastNameHash; 16 | } 17 | }; 18 | } 19 | 20 | int main() 21 | { 22 | std::unordered_set persons; 23 | persons.insert(Person("John", "Doe")); 24 | 25 | std::cout << std::endl; 26 | } 27 | -------------------------------------------------------------------------------- /Chapter 4/01 - transform.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | std::vector vec{ 1,2,3,4,5,6 }; 9 | 10 | std::transform(cbegin(vec), cend(vec), begin(vec), 11 | [](auto& element) { return element * 2; }); 12 | 13 | std::transform(cbegin(vec), cend(vec), begin(vec), std::negate<>()); 14 | 15 | std::for_each(cbegin(vec), cend(vec), 16 | [](auto& element) { std::cout << element << " "; }); 17 | 18 | 19 | std::cout << std::endl; 20 | } 21 | -------------------------------------------------------------------------------- /Chapter 4/02 - all_of.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::vector vec{ 1,2,3,4,5,6 }; 8 | bool allOf = std::all_of(cbegin(vec), cend(vec), 9 | [](auto& element) { return element % 2 == 0; }); // false 10 | std::cout << allOf << std::endl; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter 4/03 - find_if.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../Common/Person.h" 5 | 6 | int main() 7 | { 8 | auto people = { Person("Wally"), Person("Wilma"), Person("Wenda"), 9 | Person("Odlaw"), Person("Waldo"), Person("Woof") }; 10 | auto iter = std::find_if(begin(people), end(people), 11 | [](const Person& p) { return p.GetFirstName() == "Waldo"; }); 12 | std::cout << iter->GetFirstName() << std::endl; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter 4/04 - lower_bound.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::vector vec{ 11,22,33 }; 8 | const int valueToAdd = 18; 9 | auto lower = std::lower_bound(cbegin(vec), cend(vec), valueToAdd); 10 | vec.insert(lower, valueToAdd); // 11,18,22,33 11 | 12 | std::cout << std::endl; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter 4/05 - equal_range.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::vector vec{ 1,2,2,3,4 }; 8 | auto result = std::equal_range(cbegin(vec), cend(vec), 2); 9 | vec.erase(result.first, result.second); // 1,3,4 10 | 11 | std::cout << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter 4/06 - generate and iota.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | std::vector vec(6); // 0,0,0,0,0,0 9 | int value = 11; 10 | std::generate(begin(vec), begin(vec) + 3, 11 | [&value] { value *= 2; return value; }); // 22,44,88,0,0,0 12 | std::iota(begin(vec) + 3, end(vec), 2); // 22,44,88,2,3,4 13 | 14 | std::cout << std::endl; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter 4/07 - unique.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::vector v{ 3,4,4,4,5,6,4,5,5,7 }; 8 | auto result = std::unique(begin(v), end(v)); // possible outcome: 3,4,5,6,4,5,7,5,5,7 9 | v.erase(result, end(v)); // final outcome: 3,4,5,6,4,5,7 10 | 11 | std::cout << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter 4/08 - rotate.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::vector vec{ 1,2,3,4,5,6 }; 8 | std::rotate(begin(vec), begin(vec) + 4, end(vec)); 9 | 10 | std::cout << std::endl; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter 4/09 - partial_sort_copy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::vector vec{ 9,2,4,7,3,6,1 }; 8 | std::vector threeSmallestElements(3); 9 | std::partial_sort_copy(begin(vec), end(vec), 10 | begin(threeSmallestElements), end(threeSmallestElements)); 11 | 12 | std::cout << std::endl; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter 4/10 - nth_element.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::vector vec{ 9,2,4,7,3,6,1 }; 8 | auto middle = begin(vec) + vec.size() / 2; 9 | std::nth_element(begin(vec), middle, end(vec)); 10 | int median = *middle; // 4 11 | std::cout << median << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter 4/11 - shuffle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | std::random_device seeder; 10 | const auto seed = seeder.entropy() ? seeder() : std::time(nullptr); 11 | std::default_random_engine gen( 12 | static_cast(seed)); 13 | std::vector vec{ 1,2,3,4,5,6 }; 14 | std::shuffle(begin(vec), end(vec), gen); // Possible result: 5 1 4 2 6 3 15 | 16 | std::cout << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter 4/12 - accumulate.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::vector vec{ 4,2,5,1,3,6 }; 8 | int sum = std::accumulate(begin(vec), end(vec), 0); // 21 9 | std::cout << sum << std::endl; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter 4/13 - inner_product.cpp: -------------------------------------------------------------------------------- 1 | #define _SCL_SECURE_NO_WARNINGS // To make the example work in Visual C++. 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | double v1[] = { 0,1,2 }; 9 | double v2[] = { 1,0,2 }; 10 | double dot = std::inner_product(std::begin(v1), std::end(v1), 11 | std::begin(v2), 0.0); // 0*1 + 1*0 + 2*2 = 4.0 12 | 13 | std::cout << dot << std::endl; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter 4/14 - Iterator Adaptors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::vector v{ "1","2","3" }; 12 | 13 | std::deque reversed; 14 | std::copy(cbegin(v), cend(v), std::front_inserter(reversed)); 15 | 16 | std::string s123 = std::accumulate(std::make_move_iterator(begin(v)), 17 | std::make_move_iterator(end(v)), 18 | std::string()); 19 | std::cout << s123 << '\n'; // 123 20 | 21 | 22 | std::cout << std::endl; 23 | } 24 | -------------------------------------------------------------------------------- /Chapter 5/01 - Manipulators.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | using namespace std; 8 | cout.imbue(locale("")); // Use the user's preferred locale, see Chapter 6 9 | cout << setfill('_') << hex << showbase; 10 | cout << "Left: " << left << setw(7) << put_money(123) << '\n'; 11 | cout << "Right: " << right << setw(7) << put_money(123) << '\n'; 12 | cout << "Internal: " << internal; 13 | cout.width(7); 14 | cout << 123 << '\n'; 15 | 16 | 17 | std::cout << std::endl; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter 5/02 - Error Handling.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | { 7 | std::ifstream ofs("non_existing_file.ext"); 8 | std::cout << ofs.fail() << std::endl; // 1 9 | } 10 | 11 | 12 | { 13 | std::ifstream ofs("non_existing_file.ext"); 14 | try { 15 | ofs.exceptions(ofs.failbit); // Enable exceptions for failures. 16 | } 17 | catch (const std::ios_base::failure& exception) { 18 | std::cout << exception.what() << std::endl; 19 | } 20 | } 21 | 22 | 23 | std::cout << std::endl; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter 5/03 - ostream.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | std::cout << "PI = " << 3.1415 << std::endl; 6 | std::cout.put('\t'); 7 | std::cout.write("C++", 3); 8 | 9 | 10 | std::cout << std::endl; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter 5/04 - istream.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | int anInt; 7 | double aDouble; 8 | std::cout << "Enter an integer followed by some whitespace " 9 | << "and a double, and press enter: "; 10 | std::cin >> anInt >> aDouble; 11 | std::cout << "You entered: "; 12 | std::cout << "Integer = " << anInt << ", Double = " << aDouble << std::endl; 13 | 14 | std::string message; 15 | std::cout << "Enter a string. End input with a * and enter: "; 16 | std::getline(std::cin >> std::ws, message, '*'); 17 | std::cout << "You entered: '" << message << "'" << std::endl; 18 | 19 | 20 | std::cout << std::endl; 21 | } 22 | -------------------------------------------------------------------------------- /Chapter 5/05 - sstream.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::ostringstream oss; 8 | oss << 123 << " " << 3.1415; 9 | std::string myString = oss.str(); 10 | std::cout << "ostringstream contains: '" << myString << "'" << std::endl; 11 | 12 | std::istringstream iss(myString); 13 | int myInt; double myDouble; 14 | iss >> myInt >> myDouble; 15 | std::cout << "int = " << myInt << ", double = " << myDouble << std::endl; 16 | 17 | 18 | std::cout << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter 5/06 - fstream - input and output.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::string filename = "data.txt"; 7 | std::fstream fs(filename); // default openmode=ios_base::in|ios_base::out 8 | if (!fs) { 9 | fs.clear(); // First clear any error states. 10 | fs.open(filename, std::ios_base::out); // Create the file. 11 | fs.close(); // Close and reopen the file for input and output 12 | fs.open(filename, std::ios_base::in | std::ios_base::out); 13 | } 14 | 15 | 16 | std::cout << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter 5/07 - fstream.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | const std::string filename = "output.txt"; 8 | std::ofstream ofs(filename); 9 | ofs << 123 << " " << 3.1415; 10 | ofs.close(); 11 | 12 | std::ifstream ifs(filename); 13 | int myInt; double myDouble; 14 | ifs >> myInt >> myDouble; 15 | std::cout << "int = " << myInt << ", double = " << myDouble << std::endl; 16 | 17 | 18 | std::cout << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter 5/08 - Custom Output and Extraction Operator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | class Person { 7 | public: 8 | Person() = default; 9 | explicit Person(const std::string& first, 10 | const std::string& last = "", bool isVIP = false) 11 | : m_first(first), m_last(last), m_isVIP(isVIP) {} 12 | 13 | const std::string& GetFirstName() const { return m_first; } 14 | void SetFirstName(const std::string& first) { m_first = first; } 15 | 16 | const std::string& GetLastName() const { return m_last; } 17 | void SetLastName(const std::string& last) { m_last = last; } 18 | 19 | bool IsVIP() const { return m_isVIP; } 20 | 21 | private: 22 | friend bool operator<(const Person&, const Person&); 23 | std::string m_first; 24 | std::string m_last; 25 | bool m_isVIP = false; 26 | }; 27 | 28 | // Comparison operator. 29 | bool operator<(const Person& lhs, const Person& rhs) { 30 | if (lhs.IsVIP() != rhs.IsVIP()) return rhs.IsVIP(); 31 | if (lhs.GetLastName() != rhs.GetLastName()) 32 | return lhs.GetLastName() < rhs.GetLastName(); 33 | return lhs.GetFirstName() < rhs.GetFirstName(); 34 | } 35 | 36 | // Equality operator. 37 | bool operator==(const Person& lhs, const Person& rhs) { 38 | return lhs.IsVIP() == rhs.IsVIP() && 39 | lhs.GetFirstName() == rhs.GetFirstName() && 40 | lhs.GetLastName() == rhs.GetLastName(); 41 | } 42 | 43 | std::ostream& operator<<(std::ostream& os, const Person& person) { 44 | os << std::quoted(person.GetFirstName()) << ' ' 45 | << std::quoted(person.GetLastName()); 46 | return os; 47 | } 48 | 49 | std::istream& operator>>(std::istream& is, Person& person) { 50 | std::string firstName, lastName; 51 | is >> std::quoted(firstName) >> std::quoted(lastName); 52 | person.SetFirstName(firstName); person.SetLastName(lastName); 53 | return is; 54 | } 55 | 56 | int main() 57 | { 58 | Person kurt("Kurt", "von Strohm"); 59 | std::stringstream ss; 60 | ss << kurt; 61 | std::cout << ss.str() << '\n'; // "Kurt" "von Strohm" 62 | ss.seekg(0); // Seek back to beginning of stream 63 | Person readBack; 64 | ss >> readBack; 65 | std::cout << readBack << '\n'; // "Kurt" "von Strohm" 66 | 67 | 68 | std::cout << std::endl; 69 | } 70 | -------------------------------------------------------------------------------- /Chapter 5/09 - ostream_iterator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::vector vec{ 1.11, 2.22, 3.33, 4.44 }; 8 | std::copy(cbegin(vec), cend(vec), 9 | std::ostream_iterator(std::cout, "\t")); 10 | 11 | std::cout << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter 5/10 - istream_iterator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::istream_iterator begin(std::cin), end; 8 | double sum = 0.0; int count = 0; 9 | std::for_each(begin, end, [&](double value) { sum += value; ++count;}); 10 | std::cout << sum / count << std::endl; 11 | 12 | 13 | std::cout << std::endl; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter 5/11 - Stream Iterators.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::ostringstream oss; 8 | std::istream_iterator begin(std::cin), end; 9 | std::copy(begin, end, std::ostream_iterator(oss, "\t")); 10 | std::cout << oss.str() << std::endl; 11 | 12 | 13 | std::cout << std::endl; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter 5/12 - Stream Buffers - Redirect.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::ofstream file("output.txt"); 7 | auto oldCoutBuf = std::cout.rdbuf(file.rdbuf()); // Redirect cout to file 8 | std::cout << "Some output" << '\n'; // Write to file 9 | std::cout.rdbuf(oldCoutBuf); // Restore the old cout buffer! 10 | 11 | 12 | std::cout << std::endl; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter 5/13 - Stream Buffers - Read File.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::ifstream ifs("test.txt"); 8 | std::stringstream buffer; 9 | buffer << ifs.rdbuf(); 10 | 11 | 12 | std::cout << std::endl; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter 5/14 - printf.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | string bottles = "bottles of beer"; 9 | char on_wall[99]; 10 | for (int i = 99; i > 0; --i) { 11 | snprintf(on_wall, sizeof(on_wall), "%s on the wall", bottles.c_str()); 12 | printf("%d %s, %d %s.\n", i, on_wall, i, bottles.c_str()); 13 | printf("Take one down, pass it around, %d %s.\n", i - 1, on_wall); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chapter 5/15 - printf - Formatting.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | int i = 123; 9 | std::printf("i: '%+10d'\n", i); // i: ' +123' 10 | 11 | long double d = 31.415; 12 | int prcsion = 4; /* precision */ 13 | std::printf("d: %.4Lf = %.*Le\n", d, prcsion, d); // d: 31.4150 = 3.1415e+01 14 | } 15 | -------------------------------------------------------------------------------- /Chapter 5/16 - scanf.cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS // To make the example work with Visual C++. 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::string s = "int: +123; double: -2.34E-3; chars: abcdef"; 8 | int i = 0; double d = 0.0; char chars[4] = { 0 }; 9 | std::sscanf(s.data(), "int: %i; double: %lE; chars: %[abc]", &i, &d, chars); 10 | std::printf("int: %+i; double: %.2lE; chars: %s", i, d, chars); 11 | 12 | std::printf("\n"); 13 | } 14 | -------------------------------------------------------------------------------- /Chapter 6/01 - string.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | { 8 | std::string s = "Strings be fun"; 9 | s.reserve(20); 10 | s.push_back('!'); // "Strings be fun!" 11 | const auto found = std::find(cbegin(s), cend(s), 'b'); 12 | s[found - s.cbegin()] = 'r'; // "Strings re fun!" 13 | s.insert(found, 'a'); // "Strings are fun!" 14 | } 15 | 16 | 17 | { 18 | std::string s = "Strings be fun"; 19 | s.reserve(20); 20 | s.push_back('!'); // "Strings be fun!" 21 | const size_t found = s.find('b'); 22 | s[found] = 'r'; 23 | s.insert(found, "a"); // (no index-based single-character insert exists) 24 | } 25 | 26 | 27 | { 28 | std::string s = "Strings be fun"; 29 | s.reserve(20); 30 | s.push_back('!'); // "Strings be fun!" 31 | const size_t found = s.find("be"); 32 | s.replace(found, 2, "are"); // 2 = number of characters to replace 33 | } 34 | 35 | 36 | { 37 | using namespace std::literals::string_literals; 38 | auto a = "a is a const char*"; 39 | auto b = "b is a std::string"s; 40 | auto c = std::make_pair(3u, L"c is a pair"s); // 41 | } 42 | 43 | 44 | { 45 | std::string s(u8"字符串"); // UTF-8 encoding of Chinese word for "string" 46 | std::cout << s.length(); // Length: 9 code units! 47 | } 48 | 49 | 50 | std::cout << std::endl; 51 | } 52 | -------------------------------------------------------------------------------- /Chapter 6/02 - codecvt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // Forward all constructors and make protected destructor public: 7 | template class deletable : public Base { 8 | public: 9 | template 10 | deletable(Params&&... params) : Base(std::forward(params)...) {} 11 | ~deletable() {} 12 | }; 13 | 14 | int main() 15 | { 16 | std::string s(u8"字符串"); // UTF-8 encoding of Chinese word for "string" 17 | std::cout << s.length(); // Length: 9 code units! 18 | 19 | /* Does not compile. See text for the explanation. 20 | { 21 | typedef std::codecvt cvt; 22 | std::wstring_convert convertor; 23 | std::u32string s_u32 = convertor.from_bytes(s); 24 | std::cout << s_u32.length(); // Length: 3 code units 25 | } 26 | */ 27 | 28 | 29 | { // Does not work in Visual C++ 2015. See text. 30 | typedef deletable> cvt; 31 | std::wstring_convert convertor; 32 | std::u32string s_u32 = convertor.from_bytes(s); 33 | std::cout << s_u32.length(); // Length: 3 code units 34 | } 35 | 36 | 37 | { // Does not work in Visual C++ 2015. See text. 38 | typedef deletable> cvt; 39 | std::wstring_convert convertor(new cvt("")); 40 | std::u32string s_u32 = convertor.from_bytes(s); 41 | std::cout << s_u32.length(); // Length: 3 code units 42 | } 43 | 44 | 45 | { // Works fine with Visual C++ 2015. 46 | std::ofstream out("test.txt"); // char-based file output stream 47 | std::wbuffer_convert> cvt(out.rdbuf()); 48 | std::wostream wout(&cvt); // wchar_t output stream 49 | wout << L"I am written as UTF-8, irrespective of the native wide format!"; 50 | } 51 | 52 | std::cout << std::endl; 53 | } 54 | -------------------------------------------------------------------------------- /Chapter 6/03 - Global Locale.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::locale current_locale; 7 | std::cout << '"' << current_locale.name() << '"' << '\n'; // "C" 8 | std::cout << 100000 << '\n'; // 100000 9 | std::locale::global(std::locale("")); // Global locale --> user preferences 10 | std::cout << 100000 << '\n'; // 100000 11 | std::cout.imbue(std::locale()); // Imbue the current global locale 12 | std::cout << 100000 << '\n'; // Some possible outputs (locale dependent): 13 | // 100,000; 100 000; 100.000; 1,00,000; ... 14 | 15 | 16 | std::cout << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter 6/04 - use_facet.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | const auto& f = std::use_facet>(std::locale::classic()); 7 | std::cout << f.decimal_point() << std::endl; // Prints a dot character '.' 8 | 9 | 10 | std::cout << std::endl; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter 6/05 - Monetary Formatting.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/cpp-standard-library-quick-reference/2532dfcf52d18dfd6ddf00fdde83bbe74cf2f655/Chapter 6/05 - Monetary Formatting.cpp -------------------------------------------------------------------------------- /Chapter 6/06 - String Ordering.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/cpp-standard-library-quick-reference/2532dfcf52d18dfd6ddf00fdde83bbe74cf2f655/Chapter 6/06 - String Ordering.cpp -------------------------------------------------------------------------------- /Chapter 6/07 - Combining Facets.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() 8 | { 9 | int bigValue = 10000; 10 | long double money = 123456; 11 | cout << bigValue << " " << put_money(money) << '\n'; // 10000 123456 12 | 13 | locale chinese("zh_CN"); // For Windows use "zh-CN" 14 | cout.imbue(chinese); 15 | cout << bigValue << ' ' << put_money(money) << '\n'; // 10,000 1,234.56 16 | 17 | // Use the neutral "C" locale, but with Chinese monetary punctuation: 18 | locale combined = locale::classic().combine>(chinese); 19 | // Or: 20 | // locale combined(locale::classic(), &use_facet>(chinese)); 21 | // Or: 22 | // locale combined(locale::classic(), chinese, locale::monetary); 23 | cout.imbue(combined); 24 | cout << bigValue << ' ' << put_money(money) << '\n'; // 10000 1,234.56 25 | 26 | 27 | std::cout << std::endl; 28 | } 29 | -------------------------------------------------------------------------------- /Chapter 6/08 - Custom Facets - yes_no.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class yes_no_numpunct : public std::numpunct { 5 | protected: 6 | virtual string_type do_truename() const override { return "yes"; } 7 | virtual string_type do_falsename() const override { return "no"; } 8 | }; 9 | 10 | int main() 11 | { 12 | std::cout.imbue(std::locale(std::cout.getloc(), new yes_no_numpunct)); 13 | std::cout << std::boolalpha << true << " / " << false << std::endl; 14 | 15 | 16 | std::cout << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter 6/09 - Custom Facets - Accounting.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class accounting_moneypunct : public std::moneypunct_byname { 6 | public: 7 | accounting_moneypunct(const std::string& name) 8 | : moneypunct_byname(name) { } 9 | protected: 10 | // Put negative numbers between parentheses: 11 | virtual string_type do_negative_sign() const override { return "()"; } 12 | // Override formats to facilitate accounting-style padding: 13 | static pattern acc_format() { return{ symbol, space, sign, value }; } 14 | virtual pattern do_neg_format() const override { return acc_format(); } 15 | virtual pattern do_pos_format() const override { return acc_format(); } 16 | }; 17 | 18 | int main() 19 | { 20 | const auto name = "en_US"; // en-US on Windows. 21 | std::locale my_locale(std::locale(name), new accounting_moneypunct(name)); 22 | std::cout.imbue(my_locale); 23 | std::cout << std::showbase << std::internal; //show $ sign + tweak padding 24 | for (auto val : { 100000, -500 }) 25 | std::cout << std::setw(12) << std::put_money(val) << '\n'; 26 | 27 | 28 | std::cout << std::endl; 29 | } 30 | -------------------------------------------------------------------------------- /Chapter 6/10 - C Locales.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | // Use the user's preferred locale settings, 8 | // but with neutral numeric and monetary formatting 9 | std::locale::global(std::locale(std::locale(""), "C", 10 | std::locale::numeric | std::locale::monetary)); 11 | std::setlocale(LC_ALL, ""); 12 | std::setlocale(LC_NUMERIC, "C"); 13 | std::setlocale(LC_MONETARY, "C"); 14 | 15 | 16 | std::cout << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter 6/11 - regex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::regex pattern(R"(<(.+)>(.*?))"); 8 | std::string target = "Bold, not bold, bold again."; 9 | 10 | std::cout << std::boolalpha; // print true/false instead of 1/0 11 | std::cout << std::regex_match(target, pattern) << "\n\n"; // false 12 | 13 | { 14 | std::smatch results; 15 | auto begin = target.cbegin(), end = target.cend(); 16 | while (std::regex_search(begin, end, results, pattern)) { 17 | std::cout << results.str(2) << '\n'; // "Bold", then "bold again" 18 | begin += results.length(); 19 | } 20 | } 21 | 22 | 23 | { 24 | std::sregex_iterator begin(target.cbegin(), target.cend(), pattern), 25 | end; // default constructor creates end-iterator 26 | std::for_each(begin, end, [](auto& results) { /* const std::smatch& */ 27 | std::cout << results.str(2) << '\n'; 28 | }); 29 | } 30 | 31 | 32 | { 33 | std::sregex_token_iterator beg(target.cbegin(), target.cend(), pattern, 2), 34 | end; // default constructor creates end-iterator 35 | std::for_each(beg, end, [](auto& subMatch) { /* const std::ssub_match& */ 36 | std::cout << subMatch << '\n'; 37 | }); 38 | } 39 | 40 | 41 | std::cout << std::endl; 42 | } 43 | -------------------------------------------------------------------------------- /Chapter 6/12 - regex_replace.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::regex vowels("[aeiou]"); 8 | std::cout << std::regex_replace("devoweled", vowels, "*") << '\n'; 9 | 10 | std::regex bolds("(.*?)"); 11 | std::string target = "debolded"; 12 | std::ostream_iterator out(std::cout); 13 | std::regex_replace(out, target.cbegin(), target.cend(), bolds, "$1"); 14 | 15 | 16 | std::cout << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter 7/01 - Threads.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void function(const std::string& str, int i) 6 | { 7 | /* ... */ 8 | } 9 | 10 | int main() 11 | { 12 | int anotherArg = 42; 13 | std::thread worker1(function, "arg", anotherArg); 14 | std::thread worker2([=] { function("arg", anotherArg); }); 15 | 16 | worker1.join(); // See text. 17 | worker2.join(); // See text. 18 | 19 | std::cout << std::endl; 20 | } 21 | -------------------------------------------------------------------------------- /Chapter 7/02 - Futures.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int gcd(int x, int y) { return y ? gcd(y, x % y) : x; } // Euclid's algorithm 5 | 6 | int main() 7 | { 8 | { 9 | // std::async 10 | std::future answer = std::async(gcd, 123, 6); 11 | // ... 12 | std::cout << answer.get() << '\n'; // 3 (greatest common divisor of 123 and 6) 13 | } 14 | 15 | 16 | { 17 | // std::packaged_task 18 | std::packaged_task gcd_task(gcd); 19 | std::future gcd_future = gcd_task.get_future(); 20 | std::thread worker(std::move(gcd_task), 8, 12); 21 | worker.detach(); 22 | // ... 23 | const int four = gcd_future.get(); 24 | std::cout << four << '\n'; 25 | } 26 | 27 | 28 | { 29 | // make_ready_at_thread_exit 30 | std::packaged_task gcd_task(gcd); 31 | std::thread worker([&] { gcd_task.make_ready_at_thread_exit(8, 12); }); 32 | worker.detach(); 33 | // ... 34 | const int four = gcd_task.get_future().get(); 35 | std::cout << four << '\n'; 36 | } 37 | 38 | 39 | { 40 | // std::promise 41 | std::promise gcd_promise; 42 | std::thread worker([&] { gcd_promise.set_value(gcd(121, 22)); }); 43 | worker.detach(); 44 | // ... 45 | const int eleven = gcd_promise.get_future().get(); 46 | std::cout << eleven << '\n'; 47 | } 48 | 49 | 50 | std::cout << std::endl; 51 | } 52 | -------------------------------------------------------------------------------- /Chapter 7/03 - Mutual Exclusion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | int counter = 0; 10 | std::mutex m; 11 | std::vector threads; // Needs and . 12 | for (int t = 0; t < 4; ++t) // Launch 4 counting threads. 13 | threads.emplace_back([&] { 14 | for (int i = 0; i < 500; ++i) { // Count to 500 in each thread. 15 | using namespace std::literals::chrono_literals; 16 | std::this_thread::sleep_for(1ms); 17 | std::lock_guard lock(m); 18 | ++counter; 19 | } 20 | }); 21 | for (auto& t : threads) { t.join(); } // Wait for all threads to finish. 22 | std::cout << counter << std::endl; // 2000 23 | 24 | 25 | std::cout << std::endl; 26 | } 27 | -------------------------------------------------------------------------------- /Chapter 7/04 - call_once.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void initialise(const std::string& str) 6 | { 7 | /* ... */ 8 | } 9 | 10 | int main() 11 | { 12 | std::once_flag flag; 13 | // ... 14 | std::call_once(flag, initialise, "a string argument"); 15 | 16 | 17 | std::cout << std::endl; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter 7/05 - Condition Variables.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Shared between threads: 6 | std::mutex m; 7 | std::condition_variable cv; 8 | bool ready = false; 9 | 10 | int main() 11 | { 12 | std::thread t([] { 13 | std::unique_lock lock(m); 14 | while (!ready) cv.wait(lock); 15 | // Or: 16 | // cv.wait(lock, [&]{ return ready; }); 17 | 18 | std::cout << "Finished waiting in a thread.\n"; 19 | 20 | //... access to other resources guarded by m, if any 21 | }); 22 | 23 | { // Set ready = true in the main thread: 24 | std::lock_guard lock(m); 25 | ready = true; 26 | } 27 | cv.notify_all(); 28 | 29 | 30 | t.join(); 31 | 32 | 33 | std::cout << std::endl; 34 | } 35 | -------------------------------------------------------------------------------- /Chapter 7/06 - Atomic Operations.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../Common/Person.h" 4 | 5 | int main() 6 | { 7 | { 8 | std::atomic_int atom; // Uninitialized! 9 | atom = 123; 10 | std::cout << atom << std::endl; // 123 11 | 12 | 13 | atom.store(123); 14 | std::cout << atom.load() << std::endl; // 123 15 | } 16 | 17 | 18 | { 19 | std::atomic atomic_person(nullptr); 20 | // ... (share references to atomic_person with other threads) 21 | auto person = new Person(); 22 | person->SetFirstName("Jay"); 23 | person->SetLastName("Pritchett"); 24 | atomic_person = person; // atomic store + release fence! 25 | 26 | // ... 27 | 28 | auto p = atomic_person.exchange(nullptr); 29 | delete p; 30 | } 31 | 32 | 33 | std::cout << std::endl; 34 | } 35 | -------------------------------------------------------------------------------- /Chapter 8/01 - assert.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void foo(const char* msg) 5 | { 6 | assert(msg != nullptr); // or: assert(msg); 7 | } 8 | 9 | int main() 10 | { 11 | foo("Test"); // OK 12 | foo(nullptr); // Triggers the assertion. 13 | 14 | 15 | std::cout << std::endl; 16 | } 17 | -------------------------------------------------------------------------------- /Chapter 8/02 - Exception Pointers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::exception_ptr threadException; 8 | std::thread t([&threadException] { // Needs 9 | try { 10 | throw std::invalid_argument("Test"); // In worker thread 11 | } 12 | catch (...) { 13 | threadException = std::current_exception(); // Store exception 14 | } 15 | }); 16 | 17 | t.join(); // Wait for thread to finish. 18 | 19 | if (threadException) { // In main thread: handle exception if there is one. 20 | try { 21 | std::rethrow_exception(threadException); 22 | } 23 | catch (const std::exception& caughtException) { 24 | std::cout << "Caught from thread: " << caughtException.what() << '\n'; 25 | } 26 | } 27 | 28 | 29 | std::cout << std::endl; 30 | } 31 | -------------------------------------------------------------------------------- /Chapter 8/03 - Nested Exceptions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void execute_helper() { 5 | throw std::range_error("Out-of-range error in execute_helper()"); 6 | } 7 | 8 | void execute() { 9 | try { execute_helper(); } 10 | catch (...) { 11 | std::throw_with_nested(std::runtime_error("Caught in execute()")); 12 | } 13 | } 14 | 15 | void print(const std::exception& exc) { 16 | std::cout << "Exception: " << exc.what() << std::endl; 17 | try { std::rethrow_if_nested(exc); } 18 | catch (const std::exception& e) { 19 | std::cout << " Nested "; 20 | print(e); 21 | } 22 | } 23 | 24 | int main() 25 | { 26 | try { execute(); } 27 | catch (const std::exception& e) { print(e); } 28 | 29 | 30 | std::cout << std::endl; 31 | } 32 | -------------------------------------------------------------------------------- /Chapter 8/04 - system_error.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | try { 7 | throw std::system_error(std::make_error_code(std::errc::invalid_argument), 8 | "Now what am I to do with that argument?"); // optional what() message 9 | } catch (const std::exception& caughtException) { 10 | std::cout << caughtException.what(); 11 | } 12 | 13 | 14 | std::cout << std::endl; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter 8/05 - cerrno.cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS // To make this example work in Visual C++. 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | errno = 0; // Reset errno to 0! 10 | std::exp(100000); // Causes an overflow error. 11 | // Convert the errno error code to an error_code instance. 12 | std::error_code errorCode(errno, std::generic_category()); 13 | std::error_condition okCondition; // Default constructor creates 14 | // a no-error condition. 15 | if (errorCode != okCondition) // Check for an error. 16 | std::cerr << "Error: " << errorCode.message() << std::endl; 17 | 18 | 19 | std::cerr << "Error: " << std::strerror(errno) << std::endl; 20 | std::perror("Error"); // Prefix string is non-optional 21 | 22 | 23 | std::cout << std::endl; 24 | } 25 | -------------------------------------------------------------------------------- /Common.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/cpp-standard-library-quick-reference/2532dfcf52d18dfd6ddf00fdde83bbe74cf2f655/Common.zip -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/cpp-standard-library-quick-reference/2532dfcf52d18dfd6ddf00fdde83bbe74cf2f655/LICENSE.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apress Source Code 2 | 3 | This repository accompanies [*C++ Standard Library Quick Reference*](http://www.apress.com/9781484218754) by Peter Van Weert and Marc Gregoire (Apress, 2016). 4 | 5 | ![Cover image](9781484218754.jpg) 6 | 7 | Download the files as a zip using the green button, or clone the repository to your machine using Git. 8 | 9 | ## Releases 10 | 11 | Release v1.0 corresponds to the code in the published book, without corrections or updates. 12 | 13 | ## Contributions 14 | 15 | See the file Contributing.md for more information on how you can contribute to this repository. 16 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Apress Source Code 2 | 3 | Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. 4 | 5 | ## How to Contribute 6 | 7 | 1. Make sure you have a GitHub account. 8 | 2. Fork the repository for the relevant book. 9 | 3. Create a new branch on which to make your change, e.g. 10 | `git checkout -b my_code_contribution` 11 | 4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. 12 | 5. Submit a pull request. 13 | 14 | Thank you for your contribution! --------------------------------------------------------------------------------