O'Reilly logo

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Expert C++ Programming

Book Description

Developing expert level application development skills with C++

About This Book
  • ​Take ​ ​advantage ​ ​of ​ ​the ​ ​myriad ​ ​of ​ ​features ​ ​and ​ ​possibilities ​ ​that ​ ​C++ offers ​ ​to ​ ​build ​ real-world ​ ​applications
  • Delve into the fundamentals of multithreading and concurrency and find out how to implement them
  • Learn the latest features of C++ and how to write better code by using the Standard Library
Who This Book Is For

This ​course ​is​ ​for​ ​intermediate to advanced level​ ​C++ ​developers who want to get the most out of C++ to build concurrent and scalable application.

What You Will Learn
  • Write ​ ​modular ​ ​C++ ​ ​applications ​ ​in ​ ​terms ​ ​of ​ ​the ​ ​existing ​ ​and newly ​ ​introduced ​ ​features
  • Identify ​ ​code-smells, ​ ​clean ​ ​up, ​ ​and ​ ​refactor ​ ​legacy ​ ​C++ applications
  • ​Leverage ​ ​the ​ ​possibilities ​ ​provided ​ ​by ​ ​Cucumber ​ ​and ​ ​Google Test/Mock ​ ​to automate ​ ​test ​ ​cases
  • Deep dive into the details of the how various operating systems currently implement multithreading
  • Choose the best multithreading APIs when designing a new application
  • Explore the use of mutexes, spin-locks, and other synchronization concepts and see how to safely pass data between threads
  • Work with strings the STL way instead of handcrafting C-style code
  • Understand standard support classes for concurrency and synchronization, and how to put them to work
  • Use the filesystem library addition available with the C++17 STL
In Detail

C++ has ​ ​come ​ ​a ​ ​long ​ ​way ​ ​and ​ ​has ​ ​now ​ ​been ​ ​adopted ​ ​in ​ ​several ​ ​contexts. Its ​ ​key ​strengths ​ ​are ​ ​its ​ ​software ​ ​infrastructure ​ ​and ​ ​resource-constrained applications. ​ ​The ​C++ ​ ​17 ​ ​release ​ ​will ​ ​change ​ ​the ​ ​way ​ ​developers ​ ​write code, ​ ​and ​ ​this ​ ​course ​ ​will ​ ​help ​you ​ ​master ​ ​your ​ ​developing ​ ​skills ​ ​with ​ ​C++. With ​ ​real-world, ​ ​practical ​ ​examples ​ ​explaining ​ ​each ​ ​concept, ​ ​the ​ ​course is divided into three modules where ​ ​will begin ​ ​by ​ ​introducing ​ ​you ​ ​to ​ ​the ​ ​latest ​ ​features ​ ​in ​ ​C++ ​ ​17. ​ ​It ​ ​encourages clean ​code ​ ​practices ​ ​in ​ ​C++ ​ ​in ​ ​general ​ ​and ​ ​demonstrates ​ ​the ​ ​GUI app-development ​ ​options ​ ​in ​ ​C++. ​ ​You’ll ​ ​get ​ ​tips ​ ​on ​ ​avoiding ​ ​memory ​ ​leaks using ​ ​smart-pointers. ​

In the next module, ​ ​you’ll ​ ​see ​ ​how ​ ​multi-threaded ​programming can ​ ​help ​ ​you ​ ​achieve ​ ​concurrency ​ ​in ​ ​your ​ ​applications. We start with a brief introduction to the fundamentals of multithreading and concurrency concepts. We then take an in-depth look at how these concepts work at the hardware-level as well as how both operating systems and frameworks use these low-level functions.

You will learn about the native multithreading and concurrency support available in C++ since the 2011 revision, synchronization and communication between threads, debugging concurrent C++ applications, and the best programming practices in C++.

Moving ​ ​on, ​ ​you’ll ​ ​get ​ ​an ​ ​in-depth ​ ​understanding ​ ​of ​ ​the ​ ​C++ ​ ​Standard Template ​ ​Library. ​Where we show implementation-specific, problem-solution approach that will help you quickly overcome hurdles. You will learn the core STL concepts, such as containers, algorithms, utility classes, lambda expressions, iterators, and more while working on practical real-world recipes. These recipes will help you get the most from the STL and show you how to program in a better way.

Jeganathan Swaminathan : Mastering C++ Programming

Maya Posch : Mastering C++ Multithreading

Jacek Galowicz : C++17 STL Cookbook

Style and approach

This is a developer's guide to mastering multithreadded application development in C++

Downloading the example code for this book You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.

Table of Contents

  1. Title Page - Courses
  2. Copyright and Credits - Courses
    1. Expert C++ Programming
  3. Packt Upsell - Courses
    1. Why subscribe?
    2. PacktPub.com
  4. Preface
    1. Who this learning path is for
    2. What this learning path covers
    3. To get the most out of this learning path
      1. Download the example code files
      2. Conventions used
    4. Get in touch
      1. Reviews
  5. Mastering C++ Programming
  6. Introduction to C++17 Standard Template Library
    1. The Standard Template Library architecture
      1. Algorithms
      2. Iterators
      3. Containers
      4. Functors
    2. Sequence containers
      1. Array
        1. Code walkthrough
        2. Commonly used APIs in an array
      2. Vector 
        1. Code walkthrough
        2. Commonly used vector APIs
        3. Code walkthrough
        4. Pitfalls of a vector
      3. List 
        1. Commonly used APIs in a list
      4. Forward list
        1. Code walkthrough
        2. Commonly used APIs in a forward_list container
      5. Deque
        1. Commonly used APIs in a deque
    3. Associative containers
      1. Set
        1. Code walkthrough
        2. Commonly used APIs in a set
      2. Map
        1. Code walkthrough
        2. Commonly used APIs in a map
      3. Multiset
      4. Multimap
      5. Unordered sets
      6. Unordered maps
      7. Unordered multisets
      8. Unordered multimaps
    4. Container adapters
      1. Stack
        1. Commonly used APIs in a stack
      2. Queue
        1. Commonly used APIs in a queue
      3. Priority queue
        1. Commonly used APIs in a priority queue
    5. Summary
  7. Template Programming
    1. Generic programming
      1. Function templates
        1. Code walkthrough
      2. Overloading function templates
        1. Code walkthrough
      3. Class template
        1. Code walkthrough
      4. Explicit class specializations
        1. Code walkthrough
      5. Partial template specialization
    2. Summary
  8. Smart Pointers
    1. Memory management
    2. Issues with raw pointers
    3. Smart pointers
      1. auto_ptr
        1. Code walkthrough - Part 1
        2. Code walkthrough - Part 2
      2. unique_ptr
        1. Code walkthrough
      3. shared_ptr
        1. Code walkthrough
      4. weak_ptr
        1. Circular dependency
    4. Summary
  9. Developing GUI Applications in C++
    1. Qt 
      1. Installing Qt 5.7.0 in Ubuntu 16.04
    2. Qt Core
      1. Writing our first Qt console application
    3. Qt Widgets
      1. Writing our first Qt GUI application
    4. Layouts
      1. Writing a GUI application with a horizontal layout
      2. Writing a GUI application with a vertical layout
      3. Writing a GUI application with a box layout
      4. Writing a GUI application with a grid layout
    5. Signals and slots
    6. Using stacked layout in Qt applications
      1. Writing a simple math application combining multiple layouts
    7. Summary
  10. Test-Driven Development
    1. TDD
    2. Common myths and questions around TDD
      1. Does it take more efforts for a developer to write a unit test? 
      2. Is code coverage metrics good or bad?
      3. Does TDD work for complex legacy projects? 
      4. Is TDD even applicable for embedded or products that involve hardware?
    3. Unit testing frameworks for C++
    4. Google test framework
      1. Installing Google test framework on Ubuntu
      2. How to build google test and mock together as one single static library without installing?
      3. Writing our first test case using the Google test framework
      4. Using Google test framework in Visual Studio IDE
    5. TDD in action
      1. Testing a piece of legacy code that has dependency
    6. Summary
  11. Behavior-Driven Development
    1. Behavior-driven development
    2. TDD versus BDD
    3. C++ BDD frameworks
    4. The Gherkin language
    5. Installing cucumber-cpp in Ubuntu
      1. Installing the cucumber-cpp framework prerequisite software
      2. Building and executing the test cases
    6. Feature file
    7. Spoken languages supported by Gherkin
    8. The recommended cucumber-cpp project folder structure
    9. Writing our first Cucumber test case
      1. Integrating our project in cucumber-cpp CMakeLists.txt
      2. Executing our test case
    10. Dry running your cucumber test cases
    11. BDD - a test-first development approach
      1. Let's build and run our BDD test case
      2. It's testing time!
    12. Summary
  12. Code Smells and Clean Code Practices
    1. Code refactoring
    2. Code smell
    3. What is agile?
    4. SOLID design principle
      1. Single responsibility principle
      2. Open closed principle
      3. Liskov substitution principle
      4. Interface segregation
      5. Dependency inversion
    5. Code smell
      1. Comment smell
      2. Long method
      3. Long parameter list
      4. Duplicate code
      5. Conditional complexity
      6. Large class
      7. Dead code
      8. Primitive obsession
      9. Data class
      10. Feature envy
    6. Summary
  13. Mastering C++ Multithreading
  14. Revisiting Multithreading
    1. Getting started
    2. The multithreaded application
      1. Makefile
    3. Other applications
    4. Summary
  15. Multithreading Implementation on the Processor and OS
    1. Introduction to POSIX pthreads
    2. Creating threads with the pthreads library
      1. How to compile and run
    3. Does C++ support threads natively?
    4. Defining processes and threads
      1. Tasks in x86 (32-bit and 64-bit)
      2. Process state in ARM
    5. The stack
    6. Defining multithreading
      1. Flynn's taxonomy
      2. Symmetric versus asymmetric multiprocessing
      3. Loosely and tightly coupled multiprocessing
      4. Combining multiprocessing with multithreading
      5. Multithreading types
        1. Temporal multithreading
        2. Simultaneous multithreading (SMT)
    7. Schedulers
    8. Tracing the demo application
    9. Mutual exclusion implementations
      1. Hardware
      2. Software
    10. Concurrency
      1. How to compile and run
      2. Asynchronous message passing using the concurrency support library
        1. How to compile and run
      3. Concurrency tasks
        1. How to compile and run
      4. Using tasks with a thread support library
        1. How to compile and run
      5. Binding the thread procedure and its input to packaged_task 
        1. How to compile and run
      6. Exception handling with the concurrency library
        1. How to compile and run
        2. What did you learn?
    11. Summary
  16. C++ Multithreading APIs
    1. API overview
    2. POSIX threads
      1. Windows support
      2. PThreads thread management
      3. Mutexes
      4. Condition variables
      5. Synchronization
      6. Semaphores
      7. Thread local storage (TLC)
    3. Windows threads
      1. Thread management
      2. Advanced management
      3. Synchronization
      4. Condition variables
      5. Thread local storage
    4. Boost
      1. Thread class
      2. Thread pool
      3. Thread local storage (TLS)
      4. Synchronization
    5. C++ threads
    6. Putting it together
    7. Summary
  17. Thread Synchronization and Communication
    1. Safety first
    2. The scheduler
      1. High-level view
      2. Implementation
        1. Request class
        2. Worker class
      3. Dispatcher
      4. Makefile
      5. Output
    3. Sharing data
      1. Using r/w-locks
      2. Using shared pointers
    4. Summary
  18. Native C++ Threads and Primitives
    1. The STL threading API
      1. Boost.Thread API
    2. The 2011 standard
    3. C++14
    4. Thread class
      1. Basic use
      2. Passing parameters
      3. Return value
      4. Moving threads
      5. Thread ID
      6. Sleeping
      7. Yield
      8. Detach
      9. Swap
    5. Mutex
      1. Basic use
        1. Non-blocking locking
      2. Timed mutex
      3. Lock guard
      4. Unique lock
      5. Scoped lock
      6. Recursive mutex
      7. Recursive timed mutex
    6. Shared mutex
      1. Shared timed mutex
    7. Condition variable
      1. Condition_variable_any
      2. Notify all at thread exit
    8. Future
      1. Promise
        1. Shared future
      2. Packaged_task
      3. Async
        1. Launch policy
    9. Atomics
    10. Summary
  19. Debugging Multithreaded Code
    1. When to start debugging
    2. The humble debugger
      1. GDB
      2. Debugging multithreaded code
      3. Breakpoints
      4. Back traces
    3. Dynamic analysis tools
      1. Limitations
      2. Alternatives
      3. Memcheck
        1. Basic use
        2. Error types
          1. Illegal read / illegal write errors
          2. Use of uninitialized values
          3. Uninitialized or unaddressable system call values
          4. Illegal frees
          5. Mismatched deallocation
          6. Overlapping source and destination
          7. Fishy argument values
          8. Memory leak detection
      4. Helgrind
        1. Basic use
      5. Misuse of the pthreads API
      6. Lock order problems
      7. Data races
      8. DRD
      9. Basic use
      10. Features
      11. C++11 threads support
    4. Summary
  20. Best Practices
    1. Proper multithreading
    2. Wrongful expectations - deadlocks
    3. Being careless - data races
    4. Mutexes aren't magic
    5. Locks are fancy mutexes
    6. Threads versus the future
    7. Static order of initialization
    8. Summary
  21. Atomic Operations - Working with the Hardware
    1. Atomic operations
      1. Visual C++
      2. GCC
        1. Memory order
      3. Other compilers
      4. C++11 atomics
      5. Example
      6. Non-class functions
      7. Example
      8. Atomic flag
      9. Memory order
        1. Relaxed ordering
        2. Release-acquire ordering
        3. Release-consume ordering
        4. Sequentially-consistent ordering
        5. Volatile keyword
    2. Summary
  22. Multithreading with Distributed Computing
    1. Distributed computing, in a nutshell
      1. MPI
        1. Implementations
        2. Using MPI
      2. Compiling MPI applications
      3. The cluster hardware
    2. Installing Open MPI
      1. Linux and BSDs
      2. Windows
    3. Distributing jobs across nodes
      1. Setting up an MPI node
      2. Creating the MPI host file
      3. Running the job
      4. Using a cluster scheduler
    4. MPI communication
      1. MPI data types
        1. Custom types
      2. Basic communication
      3. Advanced communication
      4. Broadcasting
      5. Scattering and gathering
    5. MPI versus threads
    6. Potential issues
    7. Summary
  23. Multithreading with GPGPU
    1. The GPGPU processing model
      1. Implementations
      2. OpenCL
      3. Common OpenCL applications
      4. OpenCL versions
        1. OpenCL 1.0
        2. OpenCL 1.1
        3. OpenCL 1.2
        4. OpenCL 2.0
        5. OpenCL 2.1
        6. OpenCL 2.2
    2. Setting up a development environment
      1. Linux
      2. Windows
      3. OS X/MacOS
    3. A basic OpenCL application
    4. GPU memory management
    5. GPGPU and multithreading
      1. Latency
    6. Potential issues
    7. Debugging GPGPU applications
    8. Summary
  24. C++17 STL Cookbook
  25. The New C++17 Features
    1. Introduction
    2. Using structured bindings to unpack bundled return values
      1. How to do it...
      2. How it works...
      3. There's more...
    3. Limiting variable scopes to if and switch statements
      1. How to do it...
      2. How it works...
      3. There's more...
    4. Profiting from the new bracket initializer rules
      1. How to do it...
      2. How it works...
    5. Letting the constructor automatically deduce the resulting template class type
      1. How to do it...
      2. How it works...
      3. There's more...
    6. Simplifying compile time decisions with constexpr-if
      1. How to do it...
      2. How it works...
      3. There's more...
    7. Enabling header-only libraries with inline variables
      1. How it's done...
      2. How it works...
      3. There's more...
    8. Implementing handy helper functions with fold expressions
      1. How to do it...
      2. How it works...
      3. There's more...
        1. Match ranges against individual items
        2. Check if multiple insertions into a set are successful
        3. Check if all the parameters are within a certain range
        4. Pushing multiple items into a vector
  26. STL Containers
    1. Using the erase-remove idiom on std::vector
      1. How to do it...
      2. How it works...
      3. There's more...
    2. Deleting items from an unsorted std::vector in O(1) time
      1. How to do it...
      2. How it works...
    3. Accessing std::vector instances the fast or the safe way
      1. How to do it...
      2. How it works...
      3. There's more...
    4. Keeping std::vector instances sorted
      1. How to do it...
      2. How it works...
      3. There's more...
    5. Inserting items efficiently and conditionally into std::map
      1. How to do it...
      2. How it works...
      3. There's more...
    6. Knowing the new insertion hint semantics of std::map::insert
      1. How to do it...
      2. How it works...
      3. There's more...
    7. Efficiently modifying the keys of std::map items
      1. How to do it...
      2. How it works...
      3. There's more...
    8. Using std::unordered_map with custom types
      1. How to do it...
      2. How it works...
    9. Filtering duplicates from user input and printing them in alphabetical order with std::set
      1. How to do it...
      2. How it works...
        1. std::istream_iterator
        2. std::inserter
        3. Putting it together
    10. Implementing a simple RPN calculator with std::stack
      1. How to do it...
      2. How it works...
        1. Stack handling
        2. Distinguishing operands from operations from user input
        3. Selecting and applying the right mathematical operation
      3. There's more...
    11. Implementing a word frequency counter with std::map
      1. How to do it...
      2. How it works...
    12. Implement a writing style helper tool for finding very long sentences in text with std::multimap
      1. How to do it...
      2. How it works...
      3.  There's more...
    13. Implementing a personal to-do list using std::priority_queue
      1. How to do it...
      2. How it works...
  27. Iterators
    1. Introduction
      1. Iterator categories
        1. Input iterator
        2. Forward iterator
        3. Bidirectional iterator
        4. Random access iterator
        5. Contiguous iterator
        6. Output iterator
        7. Mutable iterator
    2. Building your own iterable range
      1. How to do it...
      2. How it works...
    3. Making your own iterators compatible with STL iterator categories
      1. How to do it...
      2. How it works...
      3. There's more...
    4. Using iterator adapters to fill generic data structures
      1. How to do it...
      2. How it works...
        1. std::back_insert_iterator
        2. std::front_insert_iterator
        3. std::insert_iterator
        4. std::istream_iterator
        5. std::ostream_iterator
    5. Implementing algorithms in terms of iterators
      1. How to do it...
      2. There's more...
    6. Iterating the other way around using reverse iterator adapters
      1. How to do it...
      2. How it works...
    7. Terminating iterations over ranges with iterator sentinels
      1. How to do it...
    8. Automatically checking iterator code with checked iterators
      1. How to do it...
      2. How it works...
      3. There's more...
    9. Building your own zip iterator adapter
      1. How to do it...
      2. There's more...
        1. Ranges library
  28. Lambda Expressions
    1. Introduction
    2. Defining functions on the run using lambda expressions
      1. How to do it...
      2. How it works...
        1. Capture list
        2. mutable (optional)
        3. constexpr (optional)
        4. exception attr (optional)
        5. return type (optional)
    3. Adding polymorphy by wrapping lambdas into std::function
      1. How to do it...
      2. How it works...
    4. Composing functions by concatenation
      1. How to do it...
      2. How it works...
    5. Creating complex predicates with logical conjunction
      1. How to do it...
      2. There's more...
    6. Calling multiple functions with the same input
      1. How to do it...
      2. How it works...
    7. Implementing transform_if using std::accumulate and lambdas
      1. How to do it...
      2. How it works...
    8. Generating cartesian product pairs of any input at compile time
      1. How to do it...
      2. How it works...
  29. STL Algorithm Basics
    1. Introduction
    2. Copying items from containers to other containers
      1. How to do it...
      2. How it works...
    3. Sorting containers
      1. How to do it...
      2. How it works...
    4. Removing specific items from containers
      1. How to do it...
      2. How it works...
    5. Transforming the contents of containers
      1. How to do it...
      2. How it works...
    6. Finding items in ordered and unordered vectors
      1. How to do it...
      2. How it works...
    7. Limiting the values of a vector to a specific numeric range with std::clamp
      1. How to do it...
      2. How it works...
    8. Locating patterns in strings with std::search and choosing the optimal implementation
      1. How to do it...
      2. How it works...
    9. Sampling large vectors
      1. How to do it...
      2. How it works...
    10. Generating permutations of input sequences
      1. How to do it...
      2. How it works...
    11. Implementing a dictionary merging tool
      1. How to do it...
      2. How it works...
  30. Advanced Use of STL Algorithms
    1. Introduction
    2. Implementing a trie class using STL algorithms
      1. How to do it...
      2. How it works...
    3. Implementing a search input suggestion generator with tries
      1. How to do it...
      2. How it works...
      3. There's more...
    4. Implementing the Fourier transform formula with STL numeric algorithms
      1. How to do it...
      2. How it works...
    5. Calculating the error sum of two vectors
      1. How to do it...
      2. How it works...
    6. Implementing an ASCII Mandelbrot renderer
      1. How to do it...
      2. How it works...
    7. Building our own algorithm - split
      1. How to do it...
      2. How it works...
      3. There's more...
    8. Composing useful algorithms from standard algorithms - gather
      1. How to do it...
      2. How it works...
    9. Removing consecutive whitespace between words
      1. How to do it...
      2. How it works...
    10. Compressing and decompressing strings
      1. How to do it...
      2. How it works...
      3. There's more...
  31. Strings, Stream Classes, and Regular Expressions
    1. Introduction
    2. Creating, concatenating, and transforming strings
      1. How to do it...
      2. How it works...
    3. Trimming whitespace from the beginning and end of strings
      1. How to do it...
      2. How it works...
    4. Getting the comfort of std::string without the cost of constructing std::string objects
      1. How to do it...
      2. How it works...
    5. Reading values from user input
      1. How to do it...
      2. How it works...
    6. Counting all words in a file
      1. How to do it...
      2. How it works...
    7. Formatting your output with I/O stream manipulators
      1. How to do it...
      2. How it works...
    8. Initializing complex objects from file input
      1. How to do it...
      2. How it works...
    9. Filling containers from std::istream iterators
      1. How to do it...
      2. How it works...
    10. Generic printing with std::ostream iterators
      1. How to do it...
      2. How it works...
    11. Redirecting output to files for specific code sections
      1. How to do it...
      2. How it works...
    12. Creating custom string classes by inheriting from std::char_traits
      1. How to do it...
      2. How it works...
    13. Tokenizing input with the regular expression library
      1. How to do it...
      2. How it works...
    14. Comfortably pretty printing numbers differently per context on the fly
      1. How to do it...
    15. Catching readable exceptions from std::iostream errors
      1. How to do it...
      2. How it works...
  32. Utility Classes
    1. Introduction
    2. Converting between different time units using std::ratio
      1. How to do it...
      2. How it works...
      3. There's more...
    3. Converting between absolute and relative times with std::chrono
      1. How to do it...
      2. How it works...
    4. Safely signalizing failure with std::optional
      1. How to do it...
      2. How it works...
    5. Applying functions on tuples
      1. How to do it...
      2. How it works...
    6. Quickly composing data structures with std::tuple
      1. How to do it...
      2. How it works...
        1. operator<< for tuples
        2. The zip function for tuples
    7. Replacing void* with std::any for more type safety
      1. How to do it...
      2. How it works...
    8. Storing different types with std::variant
      1. How to do it...
      2. How it works...
    9. Automatically handling resources with std::unique_ptr
      1. How to do it...
      2. How it works...
    10. Automatically handling shared heap memory with std::shared_ptr
      1. How to do it...
      2. How it works...
      3. There's more...
    11. Dealing with weak pointers to shared objects
      1. How to do it...
      2. How it works...
    12. Simplifying resource handling of legacy APIs with smart pointers
      1. How to do it...
      2. How it works...
    13. Sharing different member values of the same object
      1. How to do it...
      2. How it works...
    14. Generating random numbers and choosing the right random number engine
      1. How to do it...
      2. How it works...
    15. Generating random numbers and letting the STL shape specific distributions
      1. How to do it...
      2. How it works...
  33. Parallelism and Concurrency
    1. Introduction
    2. Automatically parallelizing code that uses standard algorithms
      1. How to do it...
      2. How it works...
        1. Which STL algorithms can we parallelize this way?
        2. How do those execution policies work?
        3. What does vectorization mean?
    3. Putting a program to sleep for specific amounts of time
      1. How to do it...
      2. How it works...
    4. Starting and stopping threads
      1. How to do it...
      2. How it works...
    5. Performing exception safe shared locking with std::unique_lock and std::shared_lock
      1. How to do it...
      2. How it works...
        1. Mutex classes
        2. Lock classes
    6. Avoiding deadlocks with std::scoped_lock
      1. How to do it...
      2. How it works...
    7. Synchronizing concurrent std::cout use
      1. How to do it...
      2. How it works...
    8. Safely postponing initialization with std::call_once
      1. How to do it...
      2. How it works...
    9. Pushing the execution of tasks into the background using std::async
      1. How to do it...
      2. How it works...
      3. There's more...
    10. Implementing the producer/consumer idiom with std::condition_variable
      1. How to do it...
      2. How it works...
    11. Implementing the multiple producers/consumers idiom with std::condition_variable
      1. How to do it...
      2. How it works...
    12. Parallelizing the ASCII Mandelbrot renderer using std::async
      1. How to do it...
      2. How it works...
    13. Implementing a tiny automatic parallelization library with std::future
      1. How to do it...
      2. How it works...
  34. Filesystem
    1. Introduction
    2. Implementing a path normalizer
      1. How to do it...
      2. How it works...
      3. There's more...
    3. Getting canonical file paths from relative paths
      1. How to do it...
      2. How it works...
    4. Listing all files in directories
      1. How to do it...
      2. How it works...
    5. Implementing a grep-like text search tool
      1. How to do it...
      2. How it works...
      3. There's more...
    6. Implementing an automatic file renamer
      1. How to do it...
    7. Implementing a disk usage counter
      1. How to do it...
      2. How it works...
    8. Calculating statistics about file types
      1. How to do it...
    9. Implementing a tool that reduces folder size by substituting duplicates with symlinks
      1. How to do it...
      2. How it works...
      3. There's more...
  35. Bibliography