[
  {
    "path": ".gitmodules",
    "content": "[submodule \"Workarounds/fmt\"]\n\tpath = Workarounds/fmt\n\turl = https://github.com/fmtlib/fmt.git\n[submodule \"Workarounds/range-v3\"]\n\tpath = Workarounds/range-v3\n\turl = https://github.com/ericniebler/range-v3\n"
  },
  {
    "path": "Contributing.md",
    "content": "# Contributing to Apress Source Code\r\n\r\nCopyright 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.\r\n\r\n## How to Contribute\r\n\r\n1. Make sure you have a GitHub account.\r\n2. Fork the repository for the relevant book.\r\n3. Create a new branch on which to make your change, e.g. \r\n`git checkout -b my_code_contribution`\r\n4. 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.\r\n5. Submit a pull request.\r\n\r\nThank you for your contribution!"
  },
  {
    "path": "Examples/Modules/Chapter 01/Ex1_01.cpp",
    "content": "// A complete C++ program\nimport <iostream>;\n\nint main()\n{\n  int answer {42};              // Defines answer with value 42\n\n  std::cout << \"The answer to life, the universe, and everything is \"\n            << answer\n            << std::endl;\n\n  return 0;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 01/Ex1_02.cpp",
    "content": "// Using escape sequences\nimport <iostream>;\n\nint main()\n{\n  std::cout << \"\\\"Least \\'said\\' \\\\\\n\\t\\tsoonest \\'mended\\'.\\\"\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 02/Ex2_01.cpp",
    "content": "// Writing values of variables to cout\nimport <iostream>;    // For user input and output through std::cin / cout\n\nint main()\n{\n  int apple_count {15};                            // Number of apples\n  int orange_count {5};                            // Number of oranges\n  int total_fruit {apple_count + orange_count};    // Total number of fruit\n\n  std::cout << \"The value of apple_count is \"  << apple_count  << std::endl;\n  std::cout << \"The value of orange_count is \" << orange_count << std::endl;\n  std::cout << \"The value of total_fruit is \"  << total_fruit  << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 02/Ex2_02.cpp",
    "content": "// Converting distances\nimport <iostream>;    // For user input and output through std::cin / cout\n\nint main() \n{\n  unsigned int yards {}, feet {}, inches {};\n \n  // Convert a distance in yards, feet, and inches to inches\n  std::cout << \"Enter a distance as yards, feet, and inches \"\n            << \"with the three values separated by spaces: \"; \n  std::cin >> yards >> feet >> inches;\n\n  const unsigned feet_per_yard {3};\n  const unsigned inches_per_foot {12};\n  \n  unsigned total_inches {};\n  total_inches = inches + inches_per_foot * (yards*feet_per_yard + feet);\n  std::cout << \"The distances corresponds to \" << total_inches << \" inches.\\n\";\n\n  // Convert a distance in inches to yards feet and inches\n  std::cout << \"Enter a distance in inches: \";\n  std::cin >> total_inches;\n  feet   = total_inches / inches_per_foot;\n  inches = total_inches % inches_per_foot;\n  yards  = feet / feet_per_yard;\n  feet   = feet % feet_per_yard;\n  std::cout << \"The distances corresponds to \"\n            << yards  << \" yards \" \n            << feet   << \" feet \"\n            << inches << \" inches.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 02/Ex2_03.cpp",
    "content": "// Sizing a pond for happy fish\nimport <iostream>;\nimport <numbers>;   // For the pi constant\n\n#include <cmath>    // For the square root function\n\nint main()\n{\n  // 2 square feet pond surface for every 6 inches of fish\n  const double fish_factor { 2.0/0.5 };  // Area per unit length of fish\n  const double inches_per_foot { 12.0 };\n\n  double fish_count {};            // Number of fish\n  double fish_length {};           // Average length of fish\n\n  std::cout << \"Enter the number of fish you want to keep: \";\n  std::cin >> fish_count;\n  std::cout << \"Enter the average fish length in inches: \";\n  std::cin >> fish_length;\n  fish_length /= inches_per_foot;  // Convert to feet\n  std::cout << '\\n';\n\n  // Calculate the required surface area\n  const double pond_area {fish_count * fish_length * fish_factor};\n\n  // Calculate the pond diameter from the area\n  const double pond_diameter {2.0 * std::sqrt(pond_area / std::numbers::pi)};\n\n  std::cout << \"Pond diameter required for \" << fish_count << \" fish is \"\n            << pond_diameter << \" feet.\\n\";\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 02/Ex2_03A.cpp",
    "content": "// Expressions with mixed variables types\n// (The difference with the original example \n//  is the type of fish_count and inches_per_foot)\nimport <iostream>;\nimport <numbers>;   // For the pi constant\n\n#include <cmath>    // For the square root function\n\nint main()\n{\n  // 2 square feet pond surface for every 6 inches of fish\n  const double fish_factor { 2.0/0.5 };       // Area per unit length of fish\n  const unsigned int inches_per_foot { 12 };  // <-- Used to be of type double\n\n  unsigned int fish_count {};  // Number of fish (used to be of type double as well)\n  double fish_length {};       // Average length of fish\n\n  std::cout << \"Enter the number of fish you want to keep: \";\n  std::cin >> fish_count;\n  std::cout << \"Enter the average fish length in inches: \";\n  std::cin >> fish_length;\n  fish_length /= inches_per_foot;  // Convert to feet\n  std::cout << '\\n';\n\n  // Calculate the required surface area\n  const double pond_area {fish_count * fish_length * fish_factor};\n\n  // Calculate the pond diameter from the area\n  const double pond_diameter {2.0 * std::sqrt(pond_area / std::numbers::pi)};\n\n  std::cout << \"Pond diameter required for \" << fish_count << \" fish is \"\n            << pond_diameter << \" feet.\\n\";\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 02/Ex2_03B.cpp",
    "content": "// Formatting text using std::format()\nimport <iostream>;\nimport <format>;\nimport <numbers>;   // For the pi constant\n\n#include <cmath>    // For the square root function\n\nint main()\n{\n  // 2 square feet pond surface for every 6 inches of fish\n  const double fish_factor{ 2.0 / 0.5 };       // Area per unit length of fish\n  const unsigned int inches_per_foot{ 12 };\n\n  unsigned int fish_count{};  // Number of fish\n  double fish_length{};       // Average length of fish\n\n  std::cout << \"Enter the number of fish you want to keep: \";\n  std::cin >> fish_count;\n  std::cout << \"Enter the average fish length in inches: \";\n  std::cin >> fish_length;\n  fish_length /= inches_per_foot;  // Convert to feet\n  std::cout << '\\n';\n\n  // Calculate the required surface area\n  const double pond_area{ fish_count * fish_length * fish_factor };\n\n  // Calculate the pond diameter from the area\n  const double pond_diameter{ 2.0 * std::sqrt(pond_area / std::numbers::pi) };\n\n  std::cout << std::format(\"Pond diameter required for {} fish is {} feet.\\n\",\n                           fish_count, pond_diameter);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 02/Ex2_03C.cpp",
    "content": "// Format specifiers for std::format()\nimport <iostream>;\nimport <format>;\nimport <numbers>;   // For the pi constant\n\n#include <cmath>    // For the square root function\n\nint main()\n{\n  // 2 square feet pond surface for every 6 inches of fish\n  const double fish_factor{ 2.0 / 0.5 };       // Area per unit length of fish\n  const unsigned int inches_per_foot{ 12 };\n\n  unsigned int fish_count{};  // Number of fish\n  double fish_length{};       // Average length of fish\n\n  std::cout << \"Enter the number of fish you want to keep: \";\n  std::cin >> fish_count;\n  std::cout << \"Enter the average fish length in inches: \";\n  std::cin >> fish_length;\n  fish_length /= inches_per_foot;  // Convert to feet\n  std::cout << '\\n';\n\n  // Calculate the required surface area\n  const double pond_area{ fish_count * fish_length * fish_factor };\n\n  // Calculate the pond diameter from the area\n  const double pond_diameter{ 2.0 * std::sqrt(pond_area / std::numbers::pi) };\n\n  std::cout << std::format(\"Pond diameter required for {} fish is {:.2} feet.\\n\",\n                           fish_count, pond_diameter);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 02/Ex2_03D.cpp",
    "content": "// Debugging format specifiers for std::format() using try/catch\nimport <iostream>;\nimport <format>;\nimport <numbers>;   // For the pi constant\n\n#include <cmath>    // For the square root function\n\nint main()\n{\n  // 2 square feet pond surface for every 6 inches of fish\n  const double fish_factor{ 2.0 / 0.5 };       // Area per unit length of fish\n  const unsigned int inches_per_foot{ 12 };\n\n  unsigned int fish_count{};  // Number of fish\n  double fish_length{};       // Average length of fish\n\n  std::cout << \"Enter the number of fish you want to keep: \";\n  std::cin >> fish_count;\n  std::cout << \"Enter the average fish length in inches: \";\n  std::cin >> fish_length;\n  fish_length /= inches_per_foot;  // Convert to feet\n  std::cout << '\\n';\n\n  // Calculate the required surface area\n  const double pond_area{ fish_count * fish_length * fish_factor };\n\n  // Calculate the pond diameter from the area\n  const double pond_diameter{ 2.0 * std::sqrt(pond_area / std::numbers::pi) };\n\n  try\n  {\n    std::cout << std::format(\"Pond diameter required for {:.2} fish is {:.2} feet.\\n\",\n                             fish_count, pond_diameter);\n  }\n  catch (const std::format_error& error)\n  {\n    std::cout << error.what();  // Outputs \"precision not allowed for this argument type\"\n  }\n}"
  },
  {
    "path": "Examples/Modules/Chapter 02/Ex2_04.cpp",
    "content": "// Using explicit type conversions\nimport <iostream>;\n\nint main()\n{\n  const unsigned feet_per_yard{ 3 };\n  const unsigned inches_per_foot{ 12 };\n  const unsigned inches_per_yard{ feet_per_yard * inches_per_foot };\n\n  double length{};        // Length as decimal yards\n  unsigned int yards{};   // Whole yards\n  unsigned int feet{};    // Whole feet\n  unsigned int inches{};  // Whole inches\n\n  std::cout << \"Enter a length in yards as a decimal: \";\n  std::cin >> length;\n\n  // Get the length as yards, feet, and inches\n  yards = static_cast<unsigned int>(length);\n  feet = static_cast<unsigned int>((length - yards) * feet_per_yard);\n  inches = static_cast<unsigned int>(length * inches_per_yard) % inches_per_foot;\n\n  std::cout << length << \" yards converts to \"\n    << yards << \" yards \"\n    << feet << \" feet \"\n    << inches << \" inches.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 02/Ex2_05.cpp",
    "content": "// The width, alignment, fill, and 0 formatting options of std::format() \nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  // Default alignment: right for numbers, left otherwise\n  std::cout << std::format(\"{:7}|{:7}|{:7}|{:7}|{:7}\\n\", 1, -.2, \"str\", 'c', true);\n  // Left and right alignment + custom fill character\n  std::cout << std::format(\"{:*<7}|{:*<7}|{:*>7}|{:*>7}|{:*>7}\\n\", 1, -.2, \"str\", 'c', true);\n  // Centered alignment + 0 formatting option for numbers\n  std::cout << std::format(\"{:^07}|{:^07}|{:^7}|{:^7}|{:^7}\\n\", 1, -.2, \"str\", 'c', true);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 02/Ex2_06.cpp",
    "content": "// Formatting numeric values with std::format() \nimport <iostream>;\nimport <format>;\nimport <numbers>;\n\nint main()\n{\n  const double pi{ std::numbers::pi };\n  std::cout << std::format(\"Default: {:.2}, fixed: {:.2f}, scientific: {:.2e}, \"\n    \"general: {:.2g}\\n\", pi, pi, pi, pi);\n  std::cout << std::format(\"Default: {}, binary: {:b}, hex.: {:x}\\n\", 314, 314, 314);\n  std::cout << std::format(\"Default: {}, decimal: {:d}, hex.: {:x}\\n\", 'c', 'c', 'c');\n  std::cout << std::format(\"Alternative hex.: {:#x}, binary: {:#b}, HEX.: {:#X}\\n\",\n    314, 314, 314);\n  std::cout << std::format(\"Forced sign: {:+}, space sign: {: }\\n\", 314, 314);\n  std::cout << std::format(\"All together: {:*<+10.4f}, {:+#09x}\\n\", pi, 314);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 02/Ex2_06B.cpp",
    "content": "// Argument indices for std::format()\nimport <iostream>;\nimport <format>;\nimport <numbers>;\n\nint main()\n{\n  const double pi{ std::numbers::pi };\n  std::cout << std::format(\"Default: {:.2}, fixed: {:.2f}, scientific: {:.2e}, \"\n    \"general: {:.2g}\\n\", pi, pi, pi, pi);\n  std::cout << std::format(\"Default: {0}, binary: {0:b}, hex.: {0:x}\\n\", 314);\n  std::cout << std::format(\"Default: {0}, decimal: {0:d}, hex.: {0:x}\\n\", 'c');\n  std::cout << std::format(\"Alternative hex.: {0:#x}, binary: {0:#b}, HEX.: {0:#X}\\n\", 314);\n  std::cout << std::format(\"Forced sign: {0:+}, space sign: {0: }\\n\", 314);\n  std::cout << std::format(\"All together: {:*<+10.4f}, {:+#09x}\\n\", pi, 314);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 02/Ex2_07.cpp",
    "content": "// Finding maximum and minimum values for data types\nimport <iostream>;\nimport <limits>;\nimport <format>;\n\nint main()\n{\n  std::cout\n    << std::format(\"The range for type short is from {} to {}\\n\",\n      std::numeric_limits<short>::min(), std::numeric_limits<short>::max())\n    << std::format(\"The range for type unsigned int is from {} to {}\\n\",\n      std::numeric_limits<unsigned int>::min(),\n      std::numeric_limits<unsigned int>::max())\n    << std::format(\"The range for type long is from {} to {}\\n\",\n      std::numeric_limits<long>::min(), std::numeric_limits<long>::max())\n    << std::format(\"The positive range for type float is from {} to {}\\n\",\n      std::numeric_limits<float>::min(), std::numeric_limits<float>::max())\n    << std::format(\"The full range for type float is from {} to {}\\n\",\n      std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max())\n    << std::format(\"The positive range for type double is from {} to {}\\n\",\n      std::numeric_limits<double>::min(),\n      std::numeric_limits<double>::max())\n    << std::format(\"The positive range for type long double is from {} to {}\\n\",\n      std::numeric_limits<long double>::min(),\n      std::numeric_limits<long double>::max());\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 03/Ex3_01.cpp",
    "content": "// Using the bitwise operators\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  const unsigned int red{ 0xFF0000u };   // Color red\n  const unsigned int white{ 0xFFFFFFu }; // Color white - RGB all maximum\n\n  std::cout << \"Try out bitwise complement, AND and OR operators:\\n\";\n  std::cout << std::format(\"Initial value:       red = {:08X}\\n\", red);\n  std::cout << std::format(\"Complement:         ~red = {:08X}\\n\", ~red);\n\n  std::cout << std::format(\"Initial value:     white = {:08X}\\n\", white);\n  std::cout << std::format(\"Complement:       ~white = {:08X}\\n\", ~white);\n\n  std::cout << std::format(\"Bitwise AND: red & white = {:08X}\\n\", red & white);\n  std::cout << std::format(\"Bitwise  OR: red | white = {:08X}\\n\", red | white);\n\n  std::cout << \"\\nNow try successive exclusive OR operations:\\n\";\n  unsigned int mask{ red ^ white };\n  std::cout << std::format(\"mask = red ^ white = {:08X}\\n\", mask);\n  std::cout << std::format(\"        mask ^ red = {:08X}\\n\", mask ^ red);\n  std::cout << std::format(\"      mask ^ white = {:08X}\\n\", mask ^ white);\n\n  unsigned int flags{ 0xFF };            // Flags variable\n  unsigned int bit1mask{ 0x1 };          // Selects bit 1\n  unsigned int bit6mask{ 0b100000 };     // Selects bit 6\n  unsigned int bit20mask{ 1u << 19 };    // Selects bit 20\n\n  std::cout << \"Use masks to select or set a particular flag bit:\\n\";\n  std::cout << std::format(\"Select bit 1 from flags  : {:08X}\\n\", flags & bit1mask);\n  std::cout << std::format(\"Select bit 6 from flags  : {:08X}\\n\", flags & bit6mask);\n  std::cout << std::format(\"Switch off bit 6 in flags: {:08X}\\n\", flags &= ~bit6mask);\n  std::cout << std::format(\"Switch on bit 20 in flags: {:08X}\\n\", flags |= bit20mask);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 03/Ex3_02.cpp",
    "content": "// Demonstrating scope, lifetime, and global variables\nimport <iostream>;\n\nlong count1{999L};         // Global count1\ndouble count2{3.14};       // Global count2\nint count3;                // Global count3 - default initialization\n\nint main()\n{ /* Function scope starts here */\n  int count1{10};          // Hides global count1\n  int count3{50};          // Hides global count3\n  std::cout << \"Value of outer count1 = \"  << count1 << std::endl;\n  std::cout << \"Value of global count1 = \" << ::count1 << std::endl;\n  std::cout << \"Value of global count2 = \" << count2 << std::endl;\n\n  { /* New block scope starts here... */\n    int count1{20};        // This is a new variable that hides the outer count1\n    int count2{30};        // This hides global count2\n    std::cout << \"\\nValue of inner count1 = \"<< count1 << std::endl;\n    std::cout << \"Value of global count1 = \" << ::count1 << std::endl;\n    std::cout << \"Value of inner count2 = \"  << count2 << std::endl;\n    std::cout << \"Value of global count2 = \" << ::count2 << std::endl;\n\n    count1 = ::count1 + 3;   // This sets inner count1 to global count1+3\n    ++::count1;              // This changes global count1\n    std::cout << \"\\nValue of inner count1 = \" << count1 << std::endl;\n    std::cout << \"Value of global count1 = \"  << ::count1 << std::endl;\n    count3 += count2;        // Increments outer count3 by inner count2;\n\n    int count4 {};\n  } /* ...and ends here. */\n\n// std::cout << count4 << std::endl;    // count4 does not exist in this scope!\n\n  std::cout << \"\\nValue of outer count1 = \"<< count1 << std::endl\n            << \"Value of outer count3 = \"  << count3 << std::endl;\n  std::cout << \"Value of global count3 = \" << ::count3 << std::endl;\n\n  std::cout << \"Value of global count2 = \" << count2 << std::endl;\n} /* Function scope ends here */\n"
  },
  {
    "path": "Examples/Modules/Chapter 03/Ex3_03.cpp",
    "content": "// Operations with enumerations\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  enum class Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };\n  Day yesterday{ Day::Monday }, today{ Day::Tuesday }, tomorrow{ Day::Wednesday };\n  const Day poets_day{ Day::Friday };\n\n  enum class Punctuation : char { Comma = ',', Exclamation = '!', Question = '?' };\n  Punctuation ch{ Punctuation::Comma };\n\n  std::cout << std::format(\"yesterday's value is {}{} but poets_day's is {}{}\\n\",\n    static_cast<int>(yesterday), static_cast<char>(ch),\n    static_cast<int>(poets_day), static_cast<char>(Punctuation::Exclamation));\n\n  today = Day::Thursday;        // Assign new ...\n  ch = Punctuation::Question;   // ... enumerator values\n  tomorrow = poets_day;         // Copy enumerator value\n\n  std::cout << std::format(\"Is today's value({}) the same as poets_day({}){}\\n\",\n    static_cast<int>(today), static_cast<int>(poets_day), static_cast<char>(ch));\n\n  //   ch = tomorrow;             /* Uncomment any of these for an error */\n  //   tomorrow = Friday;\n  //   today = 6;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_01.cpp",
    "content": "// Comparing data values\nimport <iostream>;\n\nint main()\n{\n  char first {};      // Stores the first character\n  char second {};     // Stores the second character\n\n  std::cout << \"Enter a character: \";\n  std::cin >> first;\n\n  std::cout << \"Enter a second character: \";\n  std::cin >> second;\n\n  // std::cout << std::boolalpha;   /* Output true/false instead of 1/0 */\n\n  std::cout << \"The value of the expression \" << first << '<' << second\n            << \" is \" << (first < second) << std::endl;\n  std::cout << \"The value of the expression \" << first << \"==\" << second\n            << \" is \" << (first == second) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_01A.cpp",
    "content": "// Comparing data values (output using std::format())\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  char first {};      // Stores the first character\n  char second {};     // Stores the second character\n\n  std::cout << \"Enter a character: \";\n  std::cin >> first;\n\n  std::cout << \"Enter a second character: \";\n  std::cin >> second;\n\n  std::cout << std::format(\"The value of the expression {} < {} is {}\\n\",\n                           first, second, first < second);\n  std::cout << std::format(\"The value of the expression {} == {} is {}\\n\",\n                           first, second, first == second);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_02.cpp",
    "content": "// Three-way comparison of integers\nimport <compare>;  // Required when using operator <=> (even for fundamental types)\nimport <format>;\nimport <iostream>;\n\nint main()\n{\n  std::cout << \"Please enter a number: \";\n\n  int value;\n  std::cin >> value;\n\n  std::strong_ordering ordering{ value <=> 0 };\n\n  std::cout << std::format(\"value < 0: {}\\n\", ordering == std::strong_ordering::less);\n  std::cout << std::format(\"value > 0: {}\\n\", ordering == std::strong_ordering::greater);\n  std::cout << std::format(\"value == 0: {}\\n\", ordering == std::strong_ordering::equal);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_02A.cpp",
    "content": "// Using the named comparison functions\nimport <compare>;  // Required when using operator <=> (even for fundamental types)\nimport <format>;\nimport <iostream>;\n\nint main()\n{\n  std::cout << \"Please enter a number: \";\n\n  int value;\n  std::cin >> value;\n\n  std::strong_ordering ordering{ value <=> 0 };\n\n  std::cout << std::format(\"value < 0: {}\\n\", std::is_lt(ordering));  // is less than\n  std::cout << std::format(\"value > 0: {}\\n\", std::is_gt(ordering));  // is greater than\n  std::cout << std::format(\"value == 0: {}\\n\", std::is_eq(ordering)); // is equivalent\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_03.cpp",
    "content": "// Using an if statement\nimport <iostream>;\n\nint main()\n{\n  std::cout << \"Enter an integer between 50 and 100: \";\n\n  int value {};\n  std::cin >> value;\n\n  if (value)\n    std::cout << \"You have entered a value that is different from zero.\" << std::endl;\n\n  if (value < 50)\n    std::cout << \"The value is invalid - it is less than 50.\" << std::endl;\n\n  if (value > 100)\n    std::cout << \"The value is invalid - it is greater than 100.\" << std::endl;\n\n  std::cout << \"You entered \" << value << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_04.cpp",
    "content": "// Using a nested if\nimport <iostream>;\n\nint main()\n{\n  char letter {};                      // Store input here\n  std::cout << \"Enter a letter: \";     // Prompt for the input\n  std::cin >> letter;\n\n  if (letter >= 'A')\n  {                                    // letter is 'A' or larger\n    if (letter <= 'Z')\n    {                                  // letter is 'Z' or smaller\n      std::cout << \"You entered an uppercase letter.\" << std::endl;\n      return 0;\n    }\n  }\n\n  if (letter >= 'a')                   // Test for 'a' or larger\n    if (letter <= 'z')\n    {                                  // letter is >= 'a' and <= 'z'\n      std::cout << \"You entered a lowercase letter.\" << std::endl;\n      return 0;\n    }\n  std::cout << \"You did not enter a letter.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_04A.cpp",
    "content": "// Using the std::isupper() / islower() character classification functions\nimport <iostream>;\n\n#include <cctype>\n\nint main()\n{\n  char letter {};                      // Store input here\n  std::cout << \"Enter a letter: \";     // Prompt for the input\n  std::cin >> letter;\n\n  if (std::isupper(letter))\n  {\n    std::cout << \"You entered an uppercase letter.\" << std::endl;\n    return 0;\n  }\n\n  if (std::islower(letter))\n  {\n    std::cout << \"You entered a lowercase letter.\" << std::endl;\n    return 0;\n  }\n\n  std::cout << \"You did not enter a letter.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_05.cpp",
    "content": "// Using the if-else statement\nimport <iostream>;\n\nint main()\n{\n  long number {};      // Stores input\n  std::cout << \"Enter an integer less than 2 billion: \";\n  std::cin >> number;\n\n  if (number % 2) // Test remainder after division by 2\n  { // Here if remainder is 1\n    std::cout << \"Your number is odd.\" << std::endl;\n  }\n  else\n  { // Here if remainder is 0\n    std::cout << \"Your number is even.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_06.cpp",
    "content": "// Combining logical operators for loan approval\nimport <iostream>;\n\nint main()\n{\n  int age {};                  // Age of the prospective borrower\n  int income {};               // Income of the prospective borrower\n  int balance {};              // Current bank balance\n\n  // Get the basic data for assessing the loan\n  std::cout << \"Please enter your age in years: \";\n  std::cin  >> age;\n  std::cout << \"Please enter your annual income in dollars: \";\n  std::cin  >> income;\n  std::cout << \"What is your current account balance in dollars: \";\n  std::cin  >> balance;\n\n  // We only lend to people who are at least 21 years of age,\n  // who make over $25,000 per year,\n  // or have over $100,000 in their account, or both.\n  if (age >= 21 && (income > 25'000 || balance > 100'000))\n  {\n    // OK, you are good for the loan - but how much?\n    // This will be the lesser of twice income and half balance\n    int loan {};               // Stores maximum loan amount\n    if (2*income < balance/2)\n    {\n      loan = 2*income;\n    }\n    else\n    {\n      loan = balance/2;\n    }\n    std::cout << \"\\nYou can borrow up to $\" << loan << std::endl;\n  }\n  else     // No loan for you...\n  {\n    std::cout << \"\\nUnfortunately, you don't qualify for a loan.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_07.cpp",
    "content": "// Using the conditional operator to select output.\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  int mice {};               // Count of all mice\n  int brown {};              // Count of brown mice\n  int white {};              // Count of white mice\n\n  std::cout << \"How many brown mice do you have? \";\n  std::cin >> brown;\n  std::cout << \"How many white mice do you have? \";\n  std::cin >> white;\n\n  mice = brown + white;\n\n  std::cout << \n    std::format(\"You have {} {} in total.\\n\", mice, mice == 1 ? \"mouse\" : \"mice\");\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_08.cpp",
    "content": "// Using the switch statement\nimport <iostream>;\n\nint main()\n{\n  std::cout << \"Your electronic recipe book is at your service.\\n\"\n            << \"You can choose from the following delicious dishes:\\n\"\n            << \"1. Boiled eggs\\n\"\n            << \"2. Fried eggs\\n\"\n            << \"3. Scrambled eggs\\n\"\n            << \"4. Coddled eggs\\n\\n\"\n            << \"Enter your selection number: \";\n\n  int choice {};  // Stores selection value\n  std::cin >> choice;\n\n  switch (choice)\n  {\n  case 1:\n    std::cout << \"Boil some eggs.\" << std::endl;\n    break;\n  case 2:\n    std::cout << \"Fry some eggs.\" << std::endl;\n    break;\n  case 3:\n    std::cout << \"Scramble some eggs.\" << std::endl;\n    break;\n  case 4:\n    std::cout << \"Coddle some eggs.\"  << std::endl;\n    break;\n  default:\n    std::cout << \"You entered a wrong number - try raw eggs.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_09.cpp",
    "content": "// Multiple case actions\nimport <iostream>;\n\n#include <cctype>\n\nint main()\n{\n  char letter {};\n  std::cout << \"Enter a letter: \";\n  std::cin >> letter;\n\n  if (std::isalpha(letter))\n  {\n    switch (std::tolower(letter))\n    {\n    case 'a': case 'e': case 'i': case 'o': case 'u':\n      std::cout << \"You entered a vowel.\" << std::endl;\n      break;\n    default:\n      std::cout << \"You entered a consonant.\" << std::endl;\n      break;\n    }\n  }\n  else\n  {\n    std::cout << \"You did not enter a letter.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 04/Ex4_09A.cpp",
    "content": "// Using a return statement to exit a switch statement\nimport <iostream>;\n\n#include <cctype>\n\nint main()\n{\n  char letter {};\n  std::cout << \"Enter a letter: \";\n  std::cin >> letter;\n\n  if (std::isalpha(letter))\n  {\n    switch (std::tolower(letter))\n    {\n    case 'a': case 'e': case 'i': case 'o': case 'u':\n      std::cout << \"You entered a vowel.\" << std::endl;\n      return 0;                               // Ends the program\n    }\n\n    // We did not exit main() in the above switch, so letter is not a vowel:\n    std::cout << \"You entered a consonant.\" << std::endl;\n  }\n  else\n  {\n    std::cout << \"You did not enter a letter.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_01.cpp",
    "content": "// Using a for loop with an array\nimport <iostream>;\n\nint main()\n{\n  const unsigned size {6};                        // Array size\n  unsigned height[size] {26, 37, 47, 55, 62, 75}; // An array of heights\n\n  unsigned total {};                              // Sum of heights\n  for (size_t i {}; i < size; ++i)\n  {\n    total += height[i];\n  }\n\n  const unsigned average {total/size};            // Calculate average height\n  std::cout << \"The average height is \" << average << std::endl;\n\n  unsigned count {};\n  for (size_t i {}; i < size; ++i)\n  {\n    if (height[i] < average) ++count;\n  }\n  std::cout << count << \" people are below average height.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_02.cpp",
    "content": "// Obtaining the number of array elements\nimport <iostream>;\nimport <array>;       // for std::size()\n\nint main()\n{\n  int values[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};\n\n  std::cout << \"There are \" << std::size(values) << \" elements in the array.\\n\";\n\n  int sum {};\n  const size_t old_school_size{ sizeof(values) / sizeof(values[0]) };\n  for (size_t i {}; i < old_school_size; ++i)\n  {\n    sum += values[i];\n  }\n  std::cout << \"The sum of the array elements is \" << sum << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_03.cpp",
    "content": "// Floating-point control in a for loop\nimport <format>;\nimport <iostream>;\nimport <numbers>;\n\nint main()\n{\n  const size_t values_per_line {3}; // Outputs per line\n  size_t values_current_line {};    // Number of outputs on current line\n  for (double radius {0.2}; radius <= 3.0; radius += 0.2)\n  {\n    const auto area{ std::numbers::pi * radius * radius };\n    std::cout << std::format(\"radius = {:4.2f}, area = {:5.2f}; \", radius, area);\n    if (++values_current_line == values_per_line)  // When enough values written...\n    {\n      std::cout << std::endl;    // ...start a new line...\n      values_current_line = 0;   // ...and reset the line counter\n    }\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_03A.cpp",
    "content": "// Floating-point control in a for loop\nimport <format>;\nimport <iostream>;\nimport <numbers>;\n\nint main()\n{\n  const size_t values_per_line {3}; // Outputs per line\n  size_t values_current_line {};    // Number of outputs on current line\n  for (double radius {0.2}; radius < 3.0 + 0.001; radius += 0.2)\n  {\n    const auto area{ std::numbers::pi * radius * radius };\n    std::cout << std::format(\"radius = {:4.2f}, area = {:5.2f}; \", radius, area);\n    if (++values_current_line == values_per_line)  // When enough values written...\n    {\n      std::cout << std::endl;    // ...start a new line...\n      values_current_line = 0;   // ...and reset the line counter\n    }\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_04.cpp",
    "content": "// Multiple initializations in a loop expression\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  unsigned int limit {};\n  std::cout << \"This program calculates n! and the sum of the integers \"\n            << \"up to n for values 1 to limit.\\n\";\n  std::cout << \"What upper limit for n would you like? \";\n  std::cin >> limit;\n\n  // The format string for all rows of the table\n  const auto table_format{ \"{:>8} {:>8} {:>20}\\n\" };\n  \n  // Output column headings\n  std::cout << std::format(table_format, \"integer\", \"sum\", \"factorial\"); \n\n  for (unsigned long long n {1}, sum {}, factorial {1}; n <= limit; ++n)\n  {\n    sum += n;           // Accumulate sum to current n\n    factorial *= n;     // Calculate n! for current n\n    std::cout << std::format(table_format, n, sum, factorial);\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_04A.cpp",
    "content": "// Multiple calculations in a loop expression's third control expression\n// by using the comma operator\nimport <iostream>;\nimport <format>;\n\nint main() \n{\n  unsigned int limit {};\n  std::cout << \"This program calculates n! and the sum of the integers \"\n            << \"up to n for values 1 to limit.\\n\";\n  std::cout << \"What upper limit for n would you like? \";\n  std::cin >> limit;\n\n  // The format string for all rows of the table\n  const auto table_format{ \"{:>8} {:>8} {:>20}\\n\" };\n  \n  // Output column headings\n  std::cout << std::format(table_format, \"integer\", \"sum\", \"factorial\"); \n\n  for (unsigned long long n {1}, sum {1}, factorial {1}; n <= limit; \n                                  ++n, sum += n, factorial *= n)\n  {\n    std::cout << std::format(table_format, n, sum, factorial);\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_05.cpp",
    "content": "// Using a while loop to calculate the sum of integers from 1 to n and n!\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  unsigned int limit {};\n  std::cout << \"This program calculates n! and the sum of the integers \"\n            << \"up to n for values 1 to limit.\\n\";\n  std::cout << \"What upper limit for n would you like? \";\n  std::cin >> limit;\n\n  // The format string for all rows of the table\n  const auto table_format{ \"{:>8} {:>8} {:>20}\\n\" };\n  \n  // Output column headings\n  std::cout << std::format(table_format, \"integer\", \"sum\", \"factorial\"); \n\n  unsigned int n {};\n  unsigned int sum {};\n  unsigned long long factorial {1ULL};\n\n  while (++n <= limit)\n  {\n    sum += n;                    // Accumulate sum to current n\n    factorial *= n;              // Calculate n! for current n\n    std::cout << std::format(table_format, n, sum, factorial);\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_06.cpp",
    "content": "// Using a do-while loop to manage input\nimport <iostream>;\n\n#include <cctype>                                  // For tolower() function\n\nint main()\n{\n  char reply {};                                   // Stores response to prompt for input\n  int count {};                                    // Counts the number of input values\n  double temperature {};                           // Stores an input value\n  double total {};                                 // Stores the sum of all input values\n  do\n  {\n    std::cout << \"Enter a temperature reading: \";  // Prompt for input\n    std::cin >> temperature;                       // Read input value\n\n    total += temperature;                          // Accumulate total of values\n    ++count;                                       // Increment count\n\n    std::cout << \"Do you want to enter another? (y/n): \";\n    std::cin >> reply;                             // Get response\n  } while (std::tolower(reply) == 'y');\n\n  std::cout << \"The average temperature is \" << total/count << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_07.cpp",
    "content": "// Generating multiplication tables using nested loops\nimport <iostream>;\nimport <format>;\n\n#include <cctype>\n\nint main()\n{\n  size_t table {};              // Table size\n  const size_t table_min {2};   // Minimum table size - at least up to the 2-times\n  const size_t table_max {12};  // Maximum table size\n  char reply {};                // Response to prompt\n\n  do\n  {\n    std::cout << \n      std::format(\"What size table would you like ({} to {})? \", table_min, table_max);\n    std::cin >> table;          // Get the table size\n    std::cout << std::endl;\n\n    // Make sure table size is within the limits\n    if (table < table_min || table > table_max)\n    {\n      std::cout << \"Invalid table size entered. Program terminated.\" << std::endl;\n      return 1;\n    }\n\n    // Create the top line of the table\n    std::cout << std::format(\"{:>6}\", '|');\n    for (size_t i {1}; i <= table; ++i)\n    {\n      std::cout << std::format(\" {:3} |\", i);\n    }\n    std::cout << std::endl;\n\n    // Create the separator row\n    for (size_t i {}; i <= table; ++i)\n    {\n      std::cout << \"------\";\n    }\n    std::cout << std::endl;\n\n    for (size_t i {1}; i <= table; ++i)\n    {    // Iterate over rows\n      std::cout << std::format(\" {:3} |\", i);      // Start the row\n\n      // Output the values in a row\n      for (size_t j {1}; j <= table; ++j)\n      {\n        std::cout << std::format(\" {:3} |\", i*j);  // For each column\n      }\n      std::cout << std::endl;                      // End the row\n    }\n\n    // Check if another table is required\n    std::cout << \"\\nDo you want another table (y or n)? \";\n    std::cin >> reply;\n\n  } while (std::tolower(reply) == 'y');\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_07A.cpp",
    "content": "// Generating multiplication tables using nested loops\n// In this version an indefinite for loop is used, in combination with break statements.\nimport <iostream>;\nimport <format>;\n\n#include <cctype>\t\t// for std::tolower()\n\nint main()\n{\n  size_t table {};              // Table size\n  const size_t table_min {2};   // Minimum table size - at least up to the 2-times\n  const size_t table_max {12};  // Maximum table size\n  char reply {};                // Response to prompt\n\n  const size_t max_tries{ 3 };   // Max. number of times a user can try entering a table size\n  do\n  {\n    for (size_t count{ 1 }; ; ++count)  // Indefinite loop\n    {\n      std::cout <<\n        std::format(\"What size table would you like ({} to {})? \", table_min, table_max);\n      std::cin >> table; // Get the table size\n\n      // Make sure table size is within the limits\n      if (table >= table_min && table <= table_max)\n      {\n        break;      // Exit the input loop\n      }\n      else if (count < max_tries)\n      {\n        std::cout << \"Invalid input - try again.\\n\";\n      }\n      else\n      {\n        std::cout << \"Invalid table size entered - yet again!\\nSorry, only \"\n          << max_tries << \" allowed - program terminated.\" << std::endl;\n        return 1;\n      }\n    }\n\n\n    // Create the top line of the table\n    std::cout << std::format(\"{:>6}\", '|');\n    for (size_t i {1}; i <= table; ++i)\n    {\n      std::cout << std::format(\" {:3} |\", i);\n    }\n    std::cout << std::endl;\n\n    // Create the separator row\n    for (size_t i {}; i <= table; ++i)\n    {\n      std::cout << \"------\";\n    }\n    std::cout << std::endl;\n\n    for (size_t i {1}; i <= table; ++i)\n    {    // Iterate over rows\n      std::cout << std::format(\" {:3} |\", i);      // Start the row\n\n      // Output the values in a row\n      for (size_t j {1}; j <= table; ++j)\n      {\n        std::cout << std::format(\" {:3} |\", i*j);  // For each column\n      }\n      std::cout << std::endl;                      // End the row\n    }\n\n    // Check if another table is required\n    std::cout << \"\\nDo you want another table (y or n)? \";\n    std::cin >> reply;\n\n  } while (std::tolower(reply) == 'y');\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_08.cpp",
    "content": "// Using the continue statement to display ASCII character codes\nimport <iostream>;\nimport <format>;\n\n#include <cctype>\n\nint main()\n{\n  const auto header_format{ \"{:^11}{:^11}{:^11}\\n\" };    // 3 cols., 11 wide, centered (^)\n  const auto body_format{ \"{0:^11}{0:^11X}{0:^11d}\\n\" }; // Print same argument three times\n\n  std::cout << std::format(header_format, \"Character\", \"Hexadecimal\", \"Decimal\");\n\n  // Output 7-bit ASCII characters and corresponding codes\n  char ch{};\n  do\n  {\n    if (!std::isprint(ch))  // If it's not printable...\n      continue;             // ...skip this iteration\n    std::cout << std::format(body_format, ch);\n  } while (ch++ < 127);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_09.cpp",
    "content": "// Sorting an array in ascending sequence - using an indefinite while loop\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  const size_t size {1000};     // Array size\n  double x[size] {};            // Stores data to be sorted\n  size_t count {};              // Number of values in array\n\n  while (true)\n  {\n    double input {};            // Temporary store for a value\n    std::cout << \"Enter a non-zero value, or 0 to end: \";\n    std::cin >> input;\n    if (input == 0)\n      break;\n\n    x[count] = input;\n\n    if (++count == size)\n    {\n      std::cout << \"Sorry, I can only store \" << size << \" values.\\n\";\n      break;\n    }\n  }\n\n  if (count == 0)\n  {\n    std::cout << \"Nothing to sort...\" << std::endl;\n    return 0;\n  }\n\n  std::cout << \"Starting sort...\" << std::endl;\n\n  while (true)\n  {\n    bool swapped{ false };    // Becomes true when not all values are in order\n    for (size_t i {}; i < count - 1; ++i)\n    {\n      if (x[i] > x[i + 1])    // Out of order so swap them\n      {\n        const auto temp{ x[i] };\n        x[i] = x[i+1];\n        x[i + 1] = temp;\n        swapped = true;\n      }\n    }\n\n    if (!swapped)    // If there were no swaps\n      break;         // ...all values are in order...\n  }                  // ...otherwise, go round again.\n\n  std::cout << \"Your data in ascending sequence:\\n\";\n  const size_t perline {10};         // Number output per line\n  size_t n {};                       // Number on current line\n  for (size_t i {}; i < count; ++i)\n  {\n    std::cout << std::format(\"{:8.1f}\", x[i]);\n    if (++n == perline)              // When perline have been written...\n    {\n      std::cout << std::endl;        // Start a new line and...\n      n = 0;                         // ...reset count on this line\n    }\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_10.cpp",
    "content": "// Classifying the letters in a C-style string\nimport <iostream>;\n\n#include <cctype>\n\nint main()\n{\n  const int max_length {100};   // Array size\n  char text[max_length] {};     // Array to hold input string\n\n  std::cout << \"Enter a line of text:\" << std::endl;\n\n  // Read a line of characters including spaces\n  std::cin.getline(text, max_length);\n  std::cout << \"You entered:\\n\" << text << std::endl;\n\n  size_t vowels {};            // Count of vowels\n  size_t consonants {};        // Count of consonants\n  for (int i {}; text[i] != '\\0'; i++)\n  {\n    if (std::isalpha(text[i]))         // If it is a letter...\n    {\n      switch (std::tolower(text[i]))\n      {                                // ...check lowercase...\n        case 'a': case 'e': case 'i': case 'o': case 'u':\n          ++vowels;                    // ...it is a vowel\n          break;\n\n        default:\n          ++consonants;                    // ...it is a consonant\n      }\n    }\n  }\n  std::cout << \"Your input contained \" << vowels << \" vowels and \"\n            << consonants << \" consonants.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_11.cpp",
    "content": "// Working with strings in an array\nimport <iostream>;\nimport <array>; // for std::size()\n\nint main()\n{\n  const size_t max_length{ 80 };      // Maximum string length (including \\0)\n  char stars[][max_length]{\n                          \"Fatty Arbuckle\",  \"Clara Bow\",\n                          \"Lassie\",          \"Slim Pickens\",\n                          \"Boris Karloff\",   \"Mae West\",\n                          \"Oliver Hardy\",    \"Greta Garbo\"\n  };\n  size_t choice{};\n\n  std::cout << \"Pick a lucky star! Enter a number between 1 and \"\n    << std::size(stars) << \": \";\n  std::cin >> choice;\n\n  if (choice >= 1 && choice <= std::size(stars))\n  {\n    std::cout << \"Your lucky star is \" << stars[choice - 1] << std::endl;\n  }\n  else\n  {\n    std::cout << \"Sorry, you haven't got a lucky star.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_12.cpp",
    "content": "// Allocating an array at runtime\n// This example does not work with some compilers (such as Visual C++)\n// because dynamic arrays is not standard C++ (it is valid C though).\nimport <iostream>;\nimport <format>;\n\n#ifdef _MSC_VER   // See Appendix A for an explanation of preprocessing macros\n  #error Visual Studio does not support variable length arrays (not standard C++)\n#endif\n\nint main()\n{\n  size_t count {};\n  std::cout << \"How many heights will you enter? \";\n  std::cin >> count;\n  int height[count];            // Create the array of count elements\n\n  // Read the heights\n  size_t entered {};\n  while (entered < count)\n  {\n    std::cout <<\"Enter a height (in inches): \";\n    std::cin >> height[entered];\n    if (height[entered] > 0)    // Make sure value is positive\n    {\n      ++entered;\n    }\n    else\n    {\n      std::cout << \"A height must be positive - try again.\\n\";\n    }\n  }\n\n  // Calculate the sum of the heights\n  unsigned int total {};\n  for (size_t i {}; i < count; ++i)\n  {\n    total += height[i];\n  }\n  std::cout << std::format(\"The average height is {:.1f}\\n\",\n                              static_cast<float>(total) / count);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_12A.cpp",
    "content": "// Allocating an array at runtime (for loop merged into preceding while loop)\n// This example does not work with some compilers (such as Visual C++)\n// because dynamic arrays is not standard C++ (it is valid C though).\nimport <iostream>;\nimport <format>;\n\n#ifdef _MSC_VER   // See Appendix A for an explanation of preprocessing macros\n  #error Visual Studio does not support variable length arrays (not standard C++)\n#endif\n\nint main()\n{\n  size_t count {};\n  std::cout << \"How many heights will you enter? \";\n  std::cin >> count;\n  int height[count];            // Create the array of count elements\n\n  // Read the heights\n  unsigned int total {};\n  size_t entered {};\n  while (entered < count)\n  {\n    std::cout << \"Enter a height (in inches): \";\n    std::cin >> height[entered];\n    if (height[entered] > 0)          // Make sure value is positive\n    {\n      total += height[entered++];\n    }\n    else\n    {\n      std::cout << \"A height must be positive - try again.\\n\";\n    }\n  }\n\n  std::cout << std::format(\"The average height is {:.1f}\\n\",\n                              static_cast<float>(total) / count);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_13.cpp",
    "content": "// Comparing array<> objects and plain arrays\nimport <iostream>;\nimport <array>;\n\nint main()\n{\n  {\n    std::cout << \"First we try out the comparison operators for std::array<> objects:\" << std::endl;\n\t\n    std::array<double,4> these {1.0, 2.0, 3.0, 4.0};\n    std::array<double,4> those {1.0, 2.0, 3.0, 4.0};\n    std::array<double,4> them  {1.0, 1.0, 5.0, 5.0};\n\n    if (these == those) std::cout << \"these and those are equal.\"    << std::endl;\n    if (those != them)  std::cout << \"those and them are not equal.\" << std::endl;\n    if (those > them)   std::cout << \"those are greater than them.\"  << std::endl;\n    if (them < those)   std::cout << \"them are less than those.\"     << std::endl;\n  }\n  \n  std::cout << std::endl;\n  \n  {\n\t  std::cout << \"Next we repeat exactly the same comparisons with plain C++ arrays:\" << std::endl;\n    double these[4] {1.0, 2.0, 3.0, 4.0};\n    double those[4] {1.0, 2.0, 3.0, 4.0};\n    double them[4]  {1.0, 1.0, 5.0, 5.0};\n\n    if (these == those) std::cout << \"these and those are equal.\"    << std::endl;\n    if (those != them)  std::cout << \"those and them are not equal.\" << std::endl;\n    if (those > them)   std::cout << \"those are greater than them.\"  << std::endl;\n    if (them < those)   std::cout << \"them are less than those.\"     << std::endl;\n  }\n  \n  /* The explanation of why this does not work as expected with plain arrays follows in Chapter 6 */\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_14.cpp",
    "content": "// Using array<T,N> to create Body Mass Index (BMI) table\n// BMI = weight/(height*height)\n// weight in kilograms, height in meters\n\nimport <iostream>;\nimport <format>;\nimport <array>;        // For array<T,N>\n\nint main()\n{\n  const unsigned min_wt {100};     // Minimum weight in table (in pounds)\n  const unsigned max_wt {250};     // Maximum weight in table\n  const unsigned wt_step {10};\n  const size_t wt_count {1 + (max_wt - min_wt) / wt_step};\n\n  const unsigned min_ht {48};      // Minimum height in table (inches)\n  const unsigned max_ht {84};      // Maximum height in table\n  const unsigned ht_step {2};\n  const size_t ht_count { 1 + (max_ht - min_ht) / ht_step };\n\n  const double lbs_per_kg {2.2};   // Pounds per kilogram\n  const double ins_per_m {39.37};  // Inches per meter\n  std::array<unsigned, wt_count> weight_lbs {};\n  std::array<unsigned, ht_count> height_ins {};\n\n  // Create weights from 100lbs in steps of 10lbs\n  for (unsigned i{}, w{ min_wt }; i < wt_count; w += wt_step, ++i)\n  {\n    weight_lbs[i] = w;\n  }\n  // Create heights from 48 inches in steps of 2 inches\n  for (unsigned i{}, h{ min_ht }; h <= max_ht; h += ht_step)\n  {\n    height_ins.at(i++) = h;\n  }\n  // Output table headings\n  std::cout << std::format(\"{:>8}\", '|');\n  for (auto w : weight_lbs)\n    std::cout << std::format(\"{:^6}|\", w);\n  std::cout << std::endl;\n  \n  // Output line below headings\n  for (unsigned i{1}; i < wt_count; ++i)\n    std::cout << \"--------\";\n  std::cout << std::endl;\n\n  const unsigned int inches_per_foot {12U};\n  for (auto h : height_ins)\n  {\n    const unsigned feet{ h / inches_per_foot };\n    const unsigned inches{ h % inches_per_foot };\n    std::cout << std::format(\"{:2}'{:2}\\\" |\", feet, inches);\n\n    const double h_m{ h / ins_per_m };     // Height in meter\n    for (auto w : weight_lbs)\n    {\n      const double w_kg = w / lbs_per_kg; // Weight in kilogram\n      const double bmi = w_kg / (h_m * h_m);\n      std::cout << std::format(\" {:2.1f} |\", bmi);\n    }\n    std::cout << std::endl;\n  }\n  // Output line below table\n  for (size_t i {1}; i < wt_count; ++i)\n    std::cout << \"--------\";\n  std::cout << \"\\nBMI from 18.5 to 24.9 is normal\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 05/Ex5_15.cpp",
    "content": "// Sorting an array in ascending sequence - using a vector<T> container\nimport <iostream>;\nimport <format>;\nimport <vector>;\n\nint main()\n{\n  std::vector<double> x;    // Stores data to be sorted\n\n  while (true)\n  {\n    double input {};        // Temporary store for a value\n    std::cout << \"Enter a non-zero value, or 0 to end: \";\n    std::cin >> input;\n    if (input == 0)\n      break;\n\n    x.push_back(input);\n  }\n\n  if (x.empty())\n  {\n    std::cout << \"Nothing to sort...\" << std::endl;\n    return 0;\n  }\n\n  std::cout << \"Starting sort.\" << std::endl;\n\n  while (true)\n  {\n    bool swapped{ false };   // Becomes true when not all values are in order\n    for (size_t i {}; i < x.size() - 1; ++i)\n    {\n      if (x[i] > x[i + 1])   // Out of order so swap them\n      {\n        const auto temp{ x[i] };\n        x[i] = x[i+1];\n        x[i + 1] = temp;\n        swapped = true;\n      }\n    }\n\n    if (!swapped)   // If there were no swaps\n      break;        // ...all values are in order...\n  }                 // ...otherwise, go round again.\n\n  std::cout << \"Your data in ascending sequence:\\n\";\n  const size_t perline {10};   // Number output per line\n  size_t n {};                 // Number on current line\n  for (size_t i {}; i < x.size(); ++i)\n  {\n    std::cout << std::format(\"{:8.1f}\", x[i]);\n    if (++n == perline)        // When perline have been written...\n    {\n      std::cout << std::endl;  // Start a new line and...\n      n = 0;                   // ...reset count on this line\n    }\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 06/Ex6_01.cpp",
    "content": "// The size of pointers\nimport <iostream>;\n\nint main()\n{\n  // Print out the size (in number of bytes) of some data types\n  // and the corresponding pointer types:\n  std::cout << sizeof(double)  << \" > \"  << sizeof(char16_t)  << std::endl;\n  std::cout << sizeof(double*) << \" == \" << sizeof(char16_t*) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 06/Ex6_02.cpp",
    "content": "// Dereferencing pointers\n// Calculates the purchase price for a given quantity of items\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  int unit_price {295};                // Item unit price in cents\n  int count {};                        // Number of items ordered\n  int discount_threshold {25};         // Quantity threshold for discount\n  double discount {0.07};              // Discount for quantities over discount_threshold\n\n  int* pcount {&count};                // Pointer to count\n  std::cout << \"Enter the number of items you want: \";\n  std::cin >> *pcount;\n  std::cout << std::format(\"The unit price is ${:.2f}\\n\", unit_price / 100.0);\n\n  // Calculate gross price\n  int* punit_price{ &unit_price };      // Pointer to unit_price\n  int price{ *pcount * *punit_price };  // Gross price via pointers\n  auto* pprice {&price};                // Pointer to gross price\n\n  // Calculate net price in US$\n  double net_price{};\n  double* pnet_price {nullptr};\n  pnet_price = &net_price;\n  if (*pcount > discount_threshold)\n  {\n    std::cout << \n      std::format(\"You qualify for a discount of {:.0f} percent.\\n\", discount * 100);\n    *pnet_price = price*(1 - discount) / 100;\n  }\n  else\n  {\n    net_price = *pprice / 100;\n  }\n  std::cout << std::format(\"The net price for {} items is ${:.2f}\\n\", *pcount, net_price);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 06/Ex6_03.cpp",
    "content": "// Initializing pointers with strings\nimport <iostream>;\n\nint main()\n{\n  const char* pstar1 {\"Fatty Arbuckle\"};\n  const char* pstar2 {\"Clara Bow\"};\n  const char* pstar3 {\"Lassie\"};\n  const char* pstar4 {\"Slim Pickens\"};\n  const char* pstar5 {\"Boris Karloff\"};\n  const char* pstar6 {\"Mae West\"};\n  const char* pstar7 {\"Oliver Hardy\"};\n  const char* pstar8 {\"Greta Garbo\"};\n  const char* pstr {\"Your lucky star is \"};\n\n  std::cout << \"Pick a lucky star! Enter a number between 1 and 8: \";\n  size_t choice {};\n  std::cin >> choice;\n\n  switch (choice)\n  {\n  case 1: std::cout << pstr << pstar1 << std::endl; break;\n  case 2: std::cout << pstr << pstar2 << std::endl; break;\n  case 3: std::cout << pstr << pstar3 << std::endl; break;\n  case 4: std::cout << pstr << pstar4 << std::endl; break;\n  case 5: std::cout << pstr << pstar5 << std::endl; break;\n  case 6: std::cout << pstr << pstar6 << std::endl; break;\n  case 7: std::cout << pstr << pstar7 << std::endl; break;\n  case 8: std::cout << pstr << pstar8 << std::endl; break;\n  default: std::cout << \"Sorry, you haven't got a lucky star.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 06/Ex6_04.cpp",
    "content": "// Using an array of pointers\nimport <iostream>;\nimport <array>;      // for std::size()\n\nint main()\n{\n  const char* pstars[] {\n                         \"Fatty Arbuckle\", \"Clara Bow\", \"Lassie\", \n                         \"Slim Pickens\", \"Boris Karloff\", \"Mae West\",\n                         \"Oliver Hardy\", \"Greta Garbo\"\n                       };\n\n  std::cout << \"Pick a lucky star! Enter a number between 1 and \"\n            << std::size(pstars) << \": \";\n  size_t choice {};\n  std::cin >> choice;\n\n  if (choice >= 1 && choice <= std::size(pstars))\n  {\n    std::cout << \"Your lucky star is \" << pstars[choice - 1] << std::endl;\n  }\n  else\n  {\n    std::cout << \"Sorry, you haven't got a lucky star.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 06/Ex6_05.cpp",
    "content": "// Calculating primes using pointer notation\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  const size_t max {100};    // Number of primes required\n  long primes[max] {2L};     // First prime defined\n  size_t count {1};          // Count of primes found so far\n  long trial {3L};           // Candidate prime\n\n  while (count < max)\n  {\n    bool isprime {true}; // Indicates when a prime is found\n\n    // Try dividing the candidate by all the primes we have\n    for (size_t i {}; i < count && isprime; ++i)\n    {\n      isprime = trial % *(primes + i) > 0;   // False for exact division\n    }\n\n    if (isprime)\n    {                              // We got one...\n      *(primes + count++) = trial; // ...so save it in primes array\n    }\n\n    trial += 2;                    // Next value for checking\n  }\n\n  // Output primes 10 to a line\n  std::cout << \"The first \" << max << \" primes are:\" << std::endl;\n  for (size_t i{}; i < max; ++i)\n  {\n    std::cout << std::format(\"{:7}\", *(primes + i));\n    if ((i+1) % 10 == 0)           // Newline after every 10th prime\n      std::cout << std::endl;\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 06/Ex6_06.cpp",
    "content": "// Calculating primes using dynamic memory allocation\nimport <iostream>;\nimport <format>;\n\n#include <cmath>       // For square root function (std::sqrt())\n\nint main()\n{\n  size_t max {};       // Number of primes required\n\n  std::cout << \"How many primes would you like? \";\n  std::cin >> max;          // Read number required\n\n  if (max == 0) return 0;   // Zero primes: do nothing\n\n  auto* primes {new unsigned[max]};  // Allocate memory for max primes\n\n  size_t count {1};         // Count of primes found\n  primes[0] = 2;            // Insert first seed prime\n\n  unsigned trial {3};       // Initial candidate prime\n\n  while (count < max)\n  {\n    bool isprime {true};    // Indicates when a prime is found\n\n    const auto limit = static_cast<unsigned>(std::sqrt(trial));\n    for (size_t i {}; primes[i] <= limit && isprime; ++i)\n    {\n      isprime = trial % primes[i] > 0;  // False for exact division\n    }\n\n    if (isprime)                // We got one...\n      primes[count++] = trial;  // ...so save it in primes array\n\n    trial += 2;                 // Next value for checking\n  }\n\n  // Output primes 10 to a line\n  for (size_t i{}; i < max; ++i)\n  {\n    std::cout << std::format(\"{:10}\", primes[i]);\n    if ((i + 1) % 10 == 0)      // After every 10th prime...\n      std::cout << std::endl;   // ...start a new line\n  }\n  std::cout << std::endl;\n\n  delete[] primes;              // Free up memory...\n  primes = nullptr;             // ... and reset the pointer\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 06/Ex6_07.cpp",
    "content": "// Using smart pointers\nimport <iostream>;\nimport <format>;\nimport <memory>;   // For smart pointers\nimport <vector>;   // For std::vector<> container\n\n#include <cctype>  // For std::toupper()\n\nint main()\n{\n  std::vector<std::shared_ptr<std::vector<double>>> records; // Temperature records by days\n  size_t day{ 1 };       // Day number\n\n  while (true)           // Collect temperatures by day\n  {\n    // Vector to store current day's temperatures created in the free store\n    auto day_records{ std::make_shared<std::vector<double>>() };\n    records.push_back(day_records);   // Save pointer in records vector\n\n    std::cout << \"Enter the temperatures for day \" << day++\n              << \" separated by spaces. Enter 1000 to end:\\n\";\n\n    while (true)\n    { // Get temperatures for current day\n      double t{};        // A temperature\n      std::cin >> t;\n      if (t == 1000.0) break;\n\n      day_records->push_back(t);\n    }\n\n    std::cout << \"Enter another day's temperatures (Y or N)? \";\n    char answer{};\n    std::cin >> answer;\n    if (std::toupper(answer) != 'Y') break;\n  }\n\n  day = 1;\n\n  for (auto record : records)\n  {\n    double total{};\n    size_t count{};\n\n    std::cout << std::format(\"\\nTemperatures for day {}:\\n\", day++);\n    for (auto temp : *record)\n    {\n      total += temp;\n      std::cout << std::format(\"{:6.2f}\", temp);\n      if (++count % 5 == 0) std::cout << std::endl;\n    }\n\n    std::cout << std::format(\"\\nAverage temperature: {:.2f}\", total / count) << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_01.cpp",
    "content": "// Calculating powers\nimport <iostream>;\nimport <format>;\n\n// Function to calculate x to the power n\ndouble power(double x, int n)\n{\n  double result{ 1.0 };\n  if (n >= 0)\n  {\n    for (int i{ 1 }; i <= n; ++i)\n      result *= x;\n  }\n  else // n < 0\n  {\n    for (int i{ 1 }; i <= -n; ++i)\n      result /= x;\n  }\n  return result;\n}\n\nint main()\n{\n  // Calculate powers of 8 from -3 to +3\n  for (int i{ -3 }; i <= 3; ++i)\n    std::cout << std::format(\"{:10g}\", power(8.0, i));\n\n  std::cout << std::endl;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_02.cpp",
    "content": "// Calculating powers - rearranged\nimport <iostream>;\nimport <format>;\n\n//double power(double x, int n);               // Function prototype - uncomment for successful compilation\n\nint main()\n{\n  // Calculate powers of 8 from -3 to +3\n  for (int i{ -3 }; i <= 3; ++i)\n    std::cout << std::format(\"{:10}\", power(8.0, i));\n\n  std::cout << std::endl;\n}\n\n// Function to calculate x to the power n\ndouble power(double x, int n)\n{\n  double result{ 1.0 };\n  if (n >= 0)\n  {\n    for (int i{ 1 }; i <= n; ++i)\n      result *= x;\n  }\n  else // n < 0\n  {\n    for (int i{ 1 }; i <= -n; ++i)\n      result /= x;\n  }\n  return result;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_03.cpp",
    "content": "// Failing to modify the original value of a function argument\nimport <iostream>;\n\ndouble changeIt(double value_to_be_changed);    // Function prototype\n\nint main()  \n{\n  double it {5.0};\n  double result {changeIt(it)};\n\n  std::cout << \"After function execution, it = \" << it\n            << \"\\nResult returned is \" << result << std::endl;\n}\n\n// Function that attempts to modify an argument and return it\ndouble changeIt(double it)\n{\n  it += 10.0;                       // This modifies the copy\n  std::cout << \"Within function, it = \" << it << std::endl;\n  return it;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_04.cpp",
    "content": "// Modifying the value of a caller variable\nimport <iostream>;\n\ndouble changeIt(double* pointer_to_it);    // Function prototype\n\nint main()\n{\n  double it {5.0};\n  double result {changeIt(&it)};      // Now we pass the address\n\n  std::cout << \"After function execution, it = \" << it\n            << \"\\nResult returned is \" << result << std::endl;\n}\n\n// Function to modify an argument and return it\ndouble changeIt(double* pit)\n{\n  *pit += 10.0;             // This modifies the original double\n  std::cout << \"Within function, *pit = \" << *pit << std::endl;\n  return *pit;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_05.cpp",
    "content": "// Passing an array to a function\nimport <iostream>;\nimport <array>;          // For std::size()\n\ndouble average(double array[], size_t count);   // Function prototype\n\nint main()\n{\n  double values[] {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};\n  std::cout << \"Average = \" << average(values, std::size(values)) << std::endl;\n}\n\n// Function to compute an average\ndouble average(double array[], size_t count)\n{\n  double sum {};                       // Accumulate total in here\n  for (size_t i {}; i < count; ++i)\n    sum += array[i];                   // Sum array elements\n  return sum / count;                  // Return average\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_05A.cpp",
    "content": "// Passing an array to a function - false expectations\n// Note: with main() as defined in this file, \n// this program will likely either crash or produce garbage output!\nimport <iostream>;\n\ndouble average10(double array[10]);        // Function prototype\n\nint main()\n{\n // double values[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\n  double values[] { 1.0, 2.0, 3.0 };           // Only three values!!!\n  std::cout << \"Average = \" << average10(values) << std::endl;\n}\n\n// Function to compute an average\ndouble average10(double array[10])         /* The [10] does not mean what you might expect! */\n{\n  double sum{};                            // Accumulate total in here\n  for (size_t i{} ; i < 10; ++i)\n    sum += array[i];                       // Sum array elements\n  return sum / 10;                         // Return average\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_06.cpp",
    "content": "// Passing a two-dimensional array to a function\nimport <iostream>;\nimport <array>;\t          // For std::size()\n\ndouble yield(const double values[][4], size_t n);\n\nint main()\n{\n  double beans[3][4] {  { 1.0,   2.0,   3.0,   4.0},\n                        { 5.0,   6.0,   7.0,   8.0},\n                        { 9.0,  10.0,  11.0,  12.0}  };\n\n  std::cout << \"Yield = \" << yield(beans, std::size(beans))\n            << std::endl;\n}\n\n// Function to compute total yield\ndouble yield(const double array[][4], size_t size)\n{\n  double sum  {};\n  for (size_t i {}; i < size; ++i)   // Loop through rows\n  {\n    for (size_t j {}; j < std::size(array[i]); ++j) // Loop through elements in a row\n    {\n      sum += array[i][j];\n    }\n  }\n  return sum;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_06A.cpp",
    "content": "// Passing a two-dimensional array to a function (range-based for loop)\nimport <iostream>;\nimport <array>;\t          // For std::size()\n\ndouble yield(const double values[][4], size_t n);\n\nint main()\n{\n  double beans[3][4]{ { 1.0,   2.0,   3.0,   4.0},\n                        { 5.0,   6.0,   7.0,   8.0},\n                        { 9.0,  10.0,  11.0,  12.0} };\n\n  std::cout << \"Yield = \" << yield(beans, std::size(beans))\n    << std::endl;\n}\n\n// Function to compute total yield\ndouble yield(const double array[][4], size_t size)\n{\n  double sum{};\n  for (size_t i{}; i < size; ++i)  // Loop through rows\n  {\n    for (double val : array[i])    // Loop through elements in a row\n    {\n      sum += val;\n    }\n  }\n  return sum;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_07.cpp",
    "content": "// Modifying the value of a caller variable  references vs pointers\nimport <iostream>;\n\nvoid change_it_by_pointer(double* reference_to_it);    // Pass pointer (by value)\nvoid change_it_by_reference(double& reference_to_it);  // Pass by reference\n\nint main()\n{\n  double it {5.0};\n\n  change_it_by_pointer(&it);         // Now we pass the address\n  std::cout << \"After first function execution, it = \" << it << std::endl;\n\n  change_it_by_reference(it);        // Now we pass a reference, not the value!\n  std::cout << \"After second function execution, it = \" << it << std::endl;\n}\n\nvoid change_it_by_pointer(double* pit)\n{\n  *pit += 10.0;       // This modifies the original double\n}\nvoid change_it_by_reference(double& pit)\n{\n  pit += 10.0;        // This modifies the original double as well!\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_08.cpp",
    "content": "// Using a reference parameter\nimport <iostream>;\nimport <format>;\nimport <string>;\nimport <vector>;\n\nusing std::string;\nusing std::vector;\n\nvoid find_words(vector<string>& words, const string& str, const string& separators);\nvoid list_words(const vector<string>& words);\n\nint main()\n{\n  std::string text;         // The string to be searched\n  std::cout << \"Enter some text terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n\n  const std::string separators {\" ,;:.\\\"!?'\\n\"};  // Word delimiters\n  std::vector<std::string> words;                 // Words found\n\n  find_words(words, text, separators);\n  list_words(words);\n}\n\nvoid find_words(vector<string>& words, const string& text, const string& separators)\n{\n  size_t start {text.find_first_not_of(separators)};     // First word start index\n\n  while (start != string::npos)                          // Find the words\n  {\n    size_t end{ text.find_first_of(separators, start + 1) }; // Find end of word\n    if (end == string::npos)                             // Found a separator?\n      end = text.length();                               // No, so set to end of text\n\n    words.push_back(text.substr(start, end - start));    // Store the word\n    start = text.find_first_not_of(separators, end + 1); // Find 1st character of next word\n  }\n}\n\nvoid list_words(const vector<string>& words)\n{\n  std::cout << \"Your string contains the following \" << words.size() << \" words:\\n\";\n  size_t count {};                 // Number of outputted words\n  for (const auto& word : words)\n  {\n    std::cout << std::format(\"{:>15}\", word);\n    if (!(++count % 5))\n      std::cout << std::endl;\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_09A.cpp",
    "content": "// Passing an array to a function - pass by reference\n// Note: with main() as defined in this file, this program will not compile...\nimport <iostream>;\n\ndouble average10(const double (&)[10]);        // Function prototype\n\nint main()\n{\n  // Use 10 values to make example compile...\n // double values[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\n  double values[] { 1.0, 2.0, 3.0 };           // Only three values!!!\n  std::cout << \"Average = \" << average10(values) << std::endl;\n}\n\n// Function to compute an average\ndouble average10(const double (&array)[10])   /* Only arrays of length 10 can be passed! */\n{\n  double sum {};                       // Accumulate total in here\n  for (size_t i {}; i < 10; ++i)\n    sum += array[i];                   // Sum array elements\n  return sum / 10;                     // Return average\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_09B.cpp",
    "content": "// Passing an array to a function - pass by reference improved\nimport <iostream>;\nimport <array>;          // for std::size()\n\ndouble average10(const double (&)[10]);        // Function prototype\n\nint main()\n{\n  double values[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\n // double values[] { 1.0, 2.0, 3.0 };           // Only three values!!!\n  std::cout << \"Average = \" << average10(values) << std::endl;\n}\n\n// Function to compute an average\ndouble average10(const double (&array)[10])\n{\n  double sum {};                       // Accumulate total in here\n  for (double val : array)\n    sum += val;                        // Sum array elements\n  return sum / std::size(array);       // Return average\n}"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_09C.cpp",
    "content": "// Passing an array to a function - use std::array<>\nimport <iostream>;\nimport <array>;\n\ndouble average10(const std::array<double,10>& array);        // Function prototype\n\nint main()\n{\n  std::array<double,10> values{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\n // std::array<double,3> values{ 1.0, 2.0, 3.0 };           // Only three values!!!\n  std::cout << \"Average = \" << average10(values) << std::endl;\n}\n\n// Function to compute an average\ndouble average10(const std::array<double,10>& array)\n{\n  double sum {};                       // Accumulate total in here\n  for (double val : array)\n    sum += val;                        // Sum array elements\n  return sum / array.size();           // Return average\n}"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_10.cpp",
    "content": "// Implicit conversions of reference parameters\nimport <iostream>;\n\nvoid double_it(double& it)      { it *= 2; }\nvoid print_it(const double& it) { std::cout << it << std::endl; }\n\nint main()\n{\n  double d{123};\n  double_it(d);\n  print_it(d);\n\n  int i{456};\n  // double_it(i);        /* error, does not compile! */\n  print_it(i);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_11.cpp",
    "content": "// Using multiple default parameter values\nimport <iostream>;\nimport <format>;\nimport <string>;\n\n// The function prototype including defaults for parameters\nvoid show_data(const int data[], size_t count = 1,  \n               const std::string& title = \"Data Values\",\n               size_t width = 10, size_t perLine = 5);\nint main()\n{\n  int samples[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};\n\n  int dataItem {-99};\n  show_data(&dataItem);\n\n  dataItem = 13;\n  show_data(&dataItem, 1, \"Unlucky for some!\");\n\n  show_data(samples, std::size(samples));\n  show_data(samples, std::size(samples), \"Samples\");\n  show_data(samples, std::size(samples), \"Samples\", 6);\n  show_data(samples, std::size(samples), \"Samples\", 8, 4);\n}\n\nvoid show_data(const int data[], size_t count, const std::string& title, \n               size_t width, size_t perLine)\n{\n  std::cout << title << std::endl;    // Display the title\n\n  // Output the data values\n  for (size_t i {}; i < count; ++i)\n  {\n    std::cout << std::format(\"{:{}}\", data[i], width); // Display a data item\n    if ((i+1) % perLine == 0)                          // Newline after perLine values\n      std::cout << '\\n';\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_12.cpp",
    "content": "// Program that lists its command line arguments\nimport <iostream>;\n\nint  main(int argc, char* argv[])\n{\n  for (int i{}; i < argc; ++i)\n    std::cout << argv[i] << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_13.cpp",
    "content": "// Returning a pointer\nimport <iostream>;\nimport <format>;\nimport <string>;\nimport <array>;                  // for std::size()\n\nvoid show_data(const double data[], size_t count = 1, \n               const std::string& title = \"Data Values\",\n               size_t width = 10, size_t perLine = 5);\nconst double* largest(const double data[], size_t count);\nconst double* smallest(const double data[], size_t count);\ndouble* shift_range(double data[], size_t count, double delta);\ndouble* scale_range(double data[], size_t count, double divisor);\ndouble* normalize_range(double data[], size_t count);\n\nint main()\n{\n  double samples[] {\n                     11.0,  23.0,  13.0,  4.0,\n                     57.0,  36.0, 317.0, 88.0,\n                      9.0, 100.0, 121.0, 12.0\n                   };\n\n  const size_t count{std::size(samples)};              // Number of samples\n  show_data(samples, count, \"Original Values\");        // Output original values\n  normalize_range(samples, count);                     // Normalize the values\n  show_data(samples, count, \"Normalized Values\", 12);  // Output normalized values\n}\n\n// Outputs an array of double values\nvoid show_data(const double data[], size_t count, \n               const std::string& title, size_t width, size_t perLine)\n{\n  std::cout << title << std::endl;  // Display the title\n\n  // Output the data values\n  for (size_t i {}; i < count; ++i)\n  {\n    // Display a data item (uses a dynamic field width: see Chapter 7)\n    std::cout << std::format(\"{:{}.6g}\", data[i], width); \n    if ((i + 1) % perLine == 0)     // Newline after perLine values\n      std::cout << '\\n';\n  }\n  std::cout << std::endl;\n}\n\nconst double* smallest(const double data[], size_t count)\n{\n  if (!count) return nullptr;     // There is no smallest in an empty array\n\n  size_t index_min {};\n  for (size_t i {1}; i < count; ++i)\n    if (data[index_min] > data[i])\n      index_min = i;\n\n  return &data[index_min];\n}\n\ndouble* shift_range(double data[], size_t count, double delta)\n{\n  for (size_t i {}; i < count; ++i)\n    data[i] += delta;\n  return data;\n}\n\nconst double* largest(const double data[], size_t count)\n{\n  if (!count) return nullptr;    // There is no largest in an empty array\n\n  size_t index_max {};\n  for (size_t i {1}; i < count; ++i)\n    if (data[index_max] < data[i])\n      index_max = i;\n\n  return &data[index_max];\n}\n\ndouble* scale_range(double data[], size_t count, double divisor)\n{\n  if (!divisor) return data;     // Do nothing for a zero divisor\n\n  for (size_t i{}; i < count; ++i)\n    data[i] /= divisor;\n  return data;\n}\n\ndouble* normalize_range(double data[], size_t count)\n{\n  shift_range(data, count, -(*smallest(data, count)));\n  return scale_range(data, count, *largest(data, count));\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_14.cpp",
    "content": "// Overloading a function\nimport <iostream>;\nimport <string>;\nimport <vector>;\n\n// Function prototypes\ndouble largest(const double data[], size_t count);\ndouble largest(const std::vector<double>& data);\nint largest(const std::vector<int>& data);\nstd::string largest(const std::vector<std::string>& words);\n// int largest(const std::vector<std::string>& words); \n            /* Above function overload would not compile: overloaded functions\n               must differ in more than just their return type! */\nint main()\n{\n  double array[] {1.5, 44.6, 13.7, 21.2, 6.7};\n  std::vector<int> numbers {15, 44, 13, 21, 6, 8, 5, 2};\n  std::vector<double> data{3.5, 5, 6, -1.2, 8.7, 6.4};\n  std::vector<std::string> names {\"Charles Dickens\", \"Emily Bronte\", \n                                  \"Jane Austen\", \"Henry James\", \"Arthur Miller\"};\n  std::cout << \"The largest of array is \" << largest(array, std::size(array)) \n                        << std::endl;\n  std::cout << \"The largest of numbers is \" << largest(numbers) << std::endl;\n  std::cout << \"The largest of data is \" << largest(data) << std::endl;\n  std::cout << \"The largest of names is \" << largest(names) << std::endl;\n}\n\n// Finds the largest of an array of double values\ndouble largest(const double data[], size_t count)\n{\n  double max{ data[0] };\n  for (size_t i{ 1 }; i < count; ++i)\n    if (max < data[i]) max = data[i];\n  return max;\n}\n\n// Finds the largest of a vector of double values\ndouble largest(const std::vector<double>& data)\n{\n  double max {data[0]};\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of int values\nint largest(const std::vector<int>& data)\n{\n  int max {data[0]};\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of string objects\nstd::string largest(const std::vector<std::string>& words)\n{\n  std::string max_word {words[0]};\n  for (const auto& word : words)\n    if (max_word < word) max_word = word;\n  return max_word;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_15.cpp",
    "content": "// Overloading a function with reference parameters\nimport <iostream>;\nimport <format>;\n\ndouble larger(double a, double b); // Non-reference parameters\nlong& larger(long& a, long& b);    // Reference parameters\n\nint main()\n{\n  double a_double {1.5}, b_double {2.5};\n  std::cout << std::format(\"The larger of double values {} and {} is {}\\n\",\n                           a_double, b_double, larger(a_double, b_double));\n\n  int a_int {15}, b_int {25};\n  std::cout << std::format(\"The larger of int values {} and {} is {}\\n\",\n                  a_int, b_int, \n                  larger(static_cast<long>(a_int), static_cast<long>(b_int)));\n}\n\n// Returns the larger of two floating point values\ndouble larger(double a, double b)\n{\n  std::cout << \"double larger() called.\" << std::endl;\n  return a > b ? a : b;\n}\n\n// Returns the larger of two long references\nlong& larger(long& a, long& b)\n{\n  std::cout << \"long ref larger() called\" << std::endl;\n  return a > b ? a : b;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_16.cpp",
    "content": "// Recursive version of function for x to the power n, n positive or negative\nimport <iostream>;\nimport <format>;\n\ndouble power(double x, int n);\n\nint main()\n{\n  for (int i{ -3 }; i <= 3; ++i)      // Calculate powers of 8 from -3 to +3\n    std::cout << std::format(\"{:10g}\", power(8.0, i));\n\n  std::cout << std::endl;\n}\n\n// Recursive function to calculate x to the power n\ndouble power(double x, int n)\n{\n  if (n == 0)      return 1.0;\n  else if (n > 0)  return x * power(x, n - 1);\n  else /* n < 0 */ return 1.0 / power(x, -n);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 08/Ex8_17.cpp",
    "content": "// Sorting words recursively\nimport <iostream>;\nimport <format>;\nimport <memory>;\nimport <string>;\nimport <vector>;\nusing Words = std::vector<std::shared_ptr<std::string>>;\n\nvoid swap(Words& words, size_t first, size_t second);\nvoid sort(Words& words);\nvoid sort(Words& words, size_t start, size_t end);\nvoid extract_words(Words& words, const std::string& text, const std::string& separators);\nvoid show_words(const Words& words);\nsize_t max_word_length(const Words& words);\n\nint main()\n{\n  Words words;\n  std::string text;                    // The string to be sorted\n  const auto separators{\" ,.!?\\\"\\n\"};  // Word delimiters\n\n  // Read the string to be processed from the keyboard\n  std::cout << \"Enter a string terminated by *:\" << std::endl;\n  getline(std::cin, text, '*');\n\n  extract_words(words, text, separators);\n  if (words.empty())\n  {\n    std::cout << \"No words in text.\" << std::endl;\n    return 0;\n  }\n\n  sort(words);         // Sort the words\n  show_words(words);   // Output the words\n}\n\nvoid extract_words(Words& words, const std::string& text, const std::string& separators)\n{\n  size_t start {text.find_first_not_of(separators)}; // Start index of first word\n\n  while (start != std::string::npos)\n  {\n    size_t end{ text.find_first_of(separators, start + 1) }; // Find end of a word\n    if (end == std::string::npos)                    // Found a separator?\n      end = text.length();                           // Yes, so set to end of text\n    words.push_back(std::make_shared<std::string>(text.substr(start, end - start)));\n    start = text.find_first_not_of(separators, end + 1); // Find start next word\n  }\n}\n\nvoid swap(Words& words, size_t first, size_t second)\n{\n  auto temp{words[first]};\n  words[first] = words[second];\n  words[second] = temp;\n}\n\n// Sort strings in ascending sequence\nvoid sort(Words& words)\n{\n  if (!words.empty())\n    sort(words, 0, words.size() - 1);\n}\n\nvoid sort(Words& words, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle address to partition set\n  swap(words, start, (start + end) / 2);     // Swap middle address with start\n\n  // Check words against chosen word\n  size_t current {start};\n  for (size_t i {start + 1}; i <= end; i++)\n  {\n    if (*words[i] < *words[start])           // Is word less than chosen word?\n      swap(words, ++current, i);             // Yes, so swap to the left\n  }\n\n  swap(words, start, current);               // Swap chosen and last swapped words\n\n  if (current > start) sort(words, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) sort(words, current + 1, end); // Sort right subset if exists\n}\n\nsize_t max_word_length(const Words& words)\n{\n  size_t max {};\n  for (auto& pword : words)\n    if (max < pword->length()) max = pword->length();\n  return max;\n}\n\nvoid show_words(const Words& words)\n{\n  const size_t field_width {max_word_length(words) + 1};\n  const size_t words_per_line {8};\n  std::cout << std::format(\"{:{}}\", *words[0], field_width); // Output first word\n\n  size_t words_in_line {};         // Number of words in current line\n  for (size_t i {1}; i < words.size(); ++i)\n  { // Output newline when initial letter changes or after 8 per line\n    if ((*words[i])[0] != (*words[i - 1])[0] || ++words_in_line == words_per_line)\n    {\n      words_in_line = 0;\n      std::cout << std::endl;\n    }\n    std::cout << std::format(\"{:{}}\", *words[i], field_width); // Output a word\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 09/Ex9_01.cpp",
    "content": "// Working with std::optional<>\nimport <optional>;     // std::optional<> is defined in the <optional> module\nimport <iostream>;\nimport <string>;\n\nstd::optional<size_t> find_last(\n   const std::string& string, char to_find,\n   std::optional<size_t> start_index = std::nullopt); // or: ... start_index = {});\n\nint main()\n{\n  const auto string{ \"Growing old is mandatory; growing up is optional.\" };\n\n  const std::optional<size_t> found_a{ find_last(string, 'a') };\n  if (found_a)\n    std::cout << \"Found the last a at index \" << *found_a << std::endl;\n\n  const auto found_b{ find_last(string, 'b') };\n  if (found_b.has_value())\n    std::cout << \"Found the last b at index \" << found_b.value() << std::endl;\n\n// following line gives an error (cannot convert std::optional<size_t> to size_t)\n// const size_t found_c{ find_last(string, 'c') }; \n                                                   \n  const auto found_early_i{ find_last(string, 'i', 10) };\n  if (found_early_i != std::nullopt)\n    std::cout << \"Found an early i at index \" << *found_early_i << std::endl;\n}\n\nstd::optional<size_t> find_last(const std::string& string, char to_find, \n                                std::optional<size_t> start_index)\n{\n  // code below will not work for empty strings  \n  if (string.empty())            \n    return std::nullopt;         // or: 'return std::optional<size_t>{};'\n                                 // or: 'return {};'\n  // determine the starting index for the loop that follows:\n  size_t index{ start_index.value_or(string.size() - 1) };\n\n  while (true)  // never use while (index >= 0) here, as size_t is always >= 0!\n  {\n    if (string[index] == to_find) return index;\n    if (index == 0) return std::nullopt;\n    --index;\n  }\n}"
  },
  {
    "path": "Examples/Modules/Chapter 09/Ex9_02.cpp",
    "content": "// Using std::string_view parameters\nimport <iostream>;\nimport <format>;\nimport <string>;\nimport <string_view>;\nimport <vector>;\n\nusing std::string;\nusing std::string_view;\nusing std::vector;\n\nvoid find_words(vector<string>& words, string_view str, string_view separators);\nvoid list_words(const vector<string>& words);\n\nint main()\n{\n  std::string text;         // The string to be searched\n  std::cout << \"Enter some text terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n\n  const std::string separators{ \" ,;:.\\\"!?'\\n\" };  // Word delimiters\n  std::vector<std::string> words;                 // Words found\n\n  find_words(words, text, separators);\n  list_words(words);\n}\n\nvoid find_words(vector<string>& words, string_view text, string_view separators)\n{\n  size_t start{ text.find_first_not_of(separators) }; // First word start index\n\n  while (start != string_view::npos)                          // Find the words\n  {\n    size_t end{ text.find_first_of(separators, start + 1) };  // Find end of word\n    if (end == string_view::npos)                             // Found a separator?\n      end = text.length();                              // No, so set to end of text\n\n    words.push_back(std::string{ text.substr(start, end - start) }); // Store the word\n// Or: words.emplace_back(text.substr(start, end - start));    // (in-place construction)\n    start = text.find_first_not_of(separators, end + 1); // Find 1st character of next word\n  }\n}\n\nvoid list_words(const vector<string>& words)\n{\n  std::cout << \"Your string contains the following \" << words.size() << \" words:\\n\";\n  size_t count{};                 // Number of outputted words\n  for (const auto& word : words)\n  {\n    std::cout << std::format(\"{:>15}\", word);\n    if (!(++count % 5))\n      std::cout << std::endl;\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 09/Ex9_03.cpp",
    "content": "// Using std::span<> to reduce the number of overloads of largest()\n// Clearly the three resulting functions are still similar. \n// See Chapter 10 on how you can eliminate this duplication using function templates.\nimport <iostream>;\nimport <string>;\nimport <vector>;\nimport <array>;\nimport <span>;\n\n// Old function prototypes\n//double largest(const double data[], size_t count);\n//double largest(const std::vector<double>& data);\n//int largest(const std::vector<int>& data);\n//std::string largest(const std::vector<std::string>& words);\n\n// New function prototypes\n// (these functions work for any sequential input, not just arrays or vectors)\n/* Caution: these signatures are not ideal yet: see Ex9_03A */\ndouble largest(std::span<double> data);\nint largest(std::span<int> data);\nstd::string largest(std::span<std::string> words);\n\nint main()\n{\n  double array[] {1.5, 44.6, 13.7, 21.2, 6.7};\n  std::vector numbers {15, 44, 13, 21, 6, 8, 5, 2};\n  std::vector data{3.5, 5.0, 6.0, -1.2, 8.7, 6.4};\n  std::array array_data{ 3.5, 5.0, 6.0, -1.2, 8.7, 6.4 }; // Throwing in an std::array for good measure\n  std::vector<std::string> names {\"Charles Dickens\", \"Emily Bronte\", \n                                  \"Jane Austen\", \"Henry James\", \"Arthur Miller\"};\n  std::cout << \"The largest of array is \" << largest(array) << std::endl;\n  std::cout << \"The largest of numbers is \" << largest(numbers) << std::endl;\n  std::cout << \"The largest of data is \" << largest(data) << std::endl;\n  std::cout << \"The largest of array_data is (also) \" << largest(array_data) << std::endl;\n  std::cout << \"The largest of names is \" << largest(names) << std::endl;\n}\n\n// Finds the largest of a span of values\ndouble largest(std::span<double> data)\n{\n  double max {data[0]};\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of int values\nint largest(std::span<int> data)\n{\n  int max {data[0]};\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of string objects\nstd::string largest(std::span<std::string> words)\n{\n  std::string max_word {words[0]};\n  for (const auto& word : words)\n    if (max_word < word) max_word = word;\n  return max_word;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 09/Ex9_03A.cpp",
    "content": "// Using std::span<const T> to ensure largest() works for const inputs\nimport <iostream>;\nimport <string>;\nimport <vector>;\nimport <array>;\nimport <span>;\n\n// Old function prototypes\n//double largest(const double data[], size_t count);\n//double largest(const std::vector<double>& data);\n//int largest(const std::vector<int>& data);\n//std::string largest(const std::vector<std::string>& words);\n\n// New function prototypes\n// (these functions work for any sequential input, not just arrays or vectors)\ndouble largest(std::span<const double> data);\nint largest(std::span<const int> data);\nstd::string largest(std::span<const std::string> words);\n\nint main()\n{\n  const double array[] {1.5, 44.6, 13.7, 21.2, 6.7};\n  const std::vector numbers {15, 44, 13, 21, 6, 8, 5, 2};\n  const std::vector data{3.5, 5.0, 6.0, -1.2, 8.7, 6.4};\n  const std::array array_data{ 3.5, 5.0, 6.0, -1.2, 8.7, 6.4 }; // Throwing in an std::array for good measure\n  const std::vector<std::string> names {\"Charles Dickens\", \"Emily Bronte\", \n                                  \"Jane Austen\", \"Henry James\", \"Arthur Miller\"};\n  std::cout << \"The largest of array is \" << largest(array) << std::endl;\n  std::cout << \"The largest of numbers is \" << largest(numbers) << std::endl;\n  std::cout << \"The largest of data is \" << largest(data) << std::endl;\n  std::cout << \"The largest of array_data is (also) \" << largest(array_data) << std::endl;\n  std::cout << \"The largest of names is \" << largest(names) << std::endl;\n}\n\n// Finds the largest of a span of values\ndouble largest(std::span<const double> data)\n{\n  double max {data[0]};\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of int values\nint largest(std::span<const int> data)\n{\n  int max {data[0]};\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of string objects\nstd::string largest(std::span<const std::string> words)\n{\n  std::string max_word {words[0]};\n  for (const auto& word : words)\n    if (max_word < word) max_word = word;\n  return max_word;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 10/Ex10_01.cpp",
    "content": "// Using a function template\nimport <iostream>;\nimport <format>;\nimport <string>;\n\ntemplate<typename T> T larger(T a, T b);    // Function template prototype\n\nint main()\n{\n  std::cout << \"Larger of 1.5 and 2.5 is \" << larger(1.5, 2.5) << std::endl;\n  std::cout << \"Larger of 3.5 and 4.5 is \" << larger(3.5, 4.5) << std::endl;\n\n  int big_int {17011983}, small_int {10};\n  std::cout << std::format(\"Larger of {} and {} is {}\\n\", \n                            big_int, small_int, larger(big_int, small_int));\n\n  std::string a_string {\"A\"}, z_string {\"Z\"};\n  std::cout << std::format(R\"(Larger of \"{}\" and \"{}\" is \"{}\")\", \n                           a_string, z_string, larger(a_string, z_string)) << std::endl;\n}\n\n// Template for functions to return the larger of two values\ntemplate <typename T>\nT larger(T a, T b)\n{\n    return a > b ? a : b;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 10/Ex10_02.cpp",
    "content": "// Overloading function templates\nimport <iostream>;\nimport <format>;\nimport <string>;\nimport <vector>;\n\ntemplate<typename T> T larger(T a, T b);    // Function template prototype\ntemplate <typename T> T* larger(T*, T*);\ntemplate <typename T> const T* larger(const std::vector<T>& data);\n\nint main()\n{\n  int big_int {17011983}, small_int {10};\n  std::cout << std::format(\"Larger of {} and {} is {}\", \n                 big_int, small_int, larger(big_int, small_int)) << std::endl;\n  std::cout << std::format(\"Larger of {} and {} is {}\",\n                 big_int, small_int, *larger(&big_int, &small_int)) << std::endl;\n\n  std::vector<double> data {-1.4, 7.3, -100.0, 54.1, 16.3};\n  std::cout << \"The largest value in data is \" << *larger(data) << std::endl;\n\n  std::vector<std::string> words {\"The\", \"higher\", \"the\", \"fewer\"};\n  std::cout << std::format(R\"(The largest word in words is \"{}\")\", *larger(words)) \n            << std::endl;\n}\n\n// Template for functions to return the larger of two values\ntemplate <typename T>\nT larger(T a, T b)\n{\n    return a > b ? a : b;\n}\n\ntemplate<typename T>\nT* larger(T* a, T* b)\n{\n  return *a > * b ? a : b;\n}\n\ntemplate <typename T>\nconst T* larger(const std::vector<T>& data)\n{\n  const T* result {};       // The largest of an empty vector is nullptr\n  for (auto& value : data)\n    if (!result || value > *result) result = &value;\n  return result;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 10/Ex10_03.cpp",
    "content": "// Using return type deduction with templates\nimport <iostream>;\nimport <string>;\n\n// Template for functions to return the larger of two values\n// Supports implicit converion of differently-typed arguments\ntemplate <typename T1, typename T2>\nauto larger(const T1& a, const T2& b)\n{\n  return a > b ? a : b;\n}\n\nint main()\n{\n  int small_int {10};\n  std::cout << \"Larger of \" << small_int << \" and 9.6 is \"\n            << larger(small_int, 9.6) << std::endl;       // deduced return type: double\n  \n  std::string a_string {\"A\"};\n  std::cout << \"Larger of \\\"\" << a_string << \"\\\" and \\\"Z\\\" is \\\"\"\n            << larger(a_string, \"Z\") << '\"' << std::endl; // deduced return type: std::string\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 10/Ex10_03A.cpp",
    "content": "// Using return type deduction with templates (decltype(auto) instead of auto)\nimport <iostream>;\nimport <string>;\nimport <vector>;\n\n// Template for functions to return the larger of two values\n// Supports implicit converion of differently-typed arguments\ntemplate <typename T1, typename T2>\ndecltype(auto) larger(const T1& a, const T2& b)\n{\n  return a > b ? a : b;\n}\n\nint main()\n{\n  const int small_int {10};\n  std::cout << \"Larger of \" << small_int << \" and 9.6 is \"\n            << larger(small_int, 9.6) << std::endl;       // deduced return type: double\n  \n  const std::string a_string {\"A\"};\n  std::cout << \"Larger of \\\"\" << a_string << \"\\\" and \\\"Z\\\" is \\\"\"\n            << larger(a_string, \"Z\") << '\"' << std::endl; // deduced return type: std::string\n\n  const std::vector v1{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n  const std::vector v2{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 11 };\n  std::cout << \"The larger of our two vectors ends with \" << larger(v1, v2).back();\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 10/Ex10_04.cpp",
    "content": "// Defining templates for functions that accept fixed-size arrays\nimport <iostream>;\n\ntemplate <typename T, size_t N>\nT average(const T(&array)[N]);\n\nint main()\n{\n  double doubles[2]{ 1.0, 2.0 };\n  std::cout << average(doubles) << std::endl;\n\n  double moreDoubles[]{ 1.0, 2.0, 3.0, 4.0 };\n  std::cout << average(moreDoubles) << std::endl;\n\n  // double* pointer = doubles;\n  // std::cout << average(pointer) << std::endl;      /* will not compile */\n\n  std::cout << average({ 1.0, 2.0, 3.0, 4.0 }) << std::endl;\n\n  int ints[] = { 1, 2, 3, 4 };\n  std::cout << average(ints) << std::endl;\n}\n\ntemplate <typename T, size_t N>\nT average(const T(&array)[N])\n{\n  T sum{};                            // Accumulate total in here\n  for (size_t i{}; i < N; ++i)\n    sum += array[i];                   // Sum array elements\n  return sum / N;                      // Return average\n}"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_01/Ex11_01.cpp",
    "content": "// Consuming your own module\nimport <iostream>;\nimport <format>;\nimport math;\n\nint main()\n{\n  std::cout << \"Lambda squared: \" << square(lambda) << std::endl;\n\n  int number;\n  std::cout << \"\\nPlease enter an odd number: \";\n  std::cin >> number;\n  std::cout << std::endl;\n\n  // if (isOdd(number))            /* Error: identifier not found: 'isOdd' */\n  //   std::cout << \"Well done!\" << std::endl;\n\n  switch (getOddity(number))\n  {\n    using enum Oddity;\n  case Odd:\n    std::cout << \"Well done! And remember: you have to be odd to be number one!\";\n    break;\n  case Even:\n    std::cout << std::format(\"Odd, {} seems to be even?\", number);\n    break;\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_01/math.cppm",
    "content": "export module math;\n\nexport auto square(const auto& x) { return x * x; }  // An abbreviated function template\n\nexport const double lambda = 1.303577269034296391257;        // Conway's constant\n\nexport enum class Oddity { Even, Odd };\nbool isOdd(int x) { return x % 2 != 0; }  // Module-local function (not exported)\nexport auto getOddity(int x) { return isOdd(x) ? Oddity::Odd : Oddity::Even; }\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_01A/Ex11_01A.cpp",
    "content": "// Exporting multiple entities at once\nimport <iostream>;\nimport <format>;\nimport math;\n\nint main()\n{\n  std::cout << \"Lambda squared: \" << square(lambda) << std::endl;\n\n  int number;\n  std::cout << \"\\nPlease enter an odd number: \";\n  std::cin >> number;\n  std::cout << std::endl;\n\n  // if (isOdd(number))            /* Error: identifier not found: 'isOdd' */\n  //   std::cout << \"Well done!\" << std::endl;\n\n  switch (getOddity(number))\n  {\n    using enum Oddity;\n  case Odd:\n    std::cout << \"Well done! And remember: you have to be odd to be number one!\";\n    break;\n  case Even:\n    std::cout << std::format(\"Odd, {} seems to be even?\", number);\n    break;\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_01A/math.cppm",
    "content": "export module math;\n\nbool isOdd(int x) { return x % 2 != 0; }   // Module-local function (not exported)\n\nexport\n{\n  auto square(const auto& x) { return x * x; }\n\n  const double lambda = 1.303577269034296391257;  // Conway's constant\n\n  enum class Oddity { Even, Odd };\n  auto getOddity(int x) { return isOdd(x) ? Oddity::Odd : Oddity::Even; }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_01B/Ex11_01B.cpp",
    "content": "// Separating implementation from interface within the module interface file\nimport <iostream>;\nimport <format>;\nimport math;\n\nint main()\n{\n  std::cout << \"Lambda squared: \" << square(lambda) << std::endl;\n\n  int number;\n  std::cout << \"\\nPlease enter an odd number: \";\n  std::cin >> number;\n  std::cout << std::endl;\n\n  // if (isOdd(number))            /* Error: identifier not found: 'isOdd' */\n  //   std::cout << \"Well done!\" << std::endl;\n\n  switch (getOddity(number))\n  {\n    using enum Oddity;\n  case Odd:\n    std::cout << \"Well done! And remember: you have to be odd to be number one!\";\n    break;\n  case Even:\n    std::cout << std::format(\"Odd, {} seems to be even?\", number);\n    break;\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_01B/math.cppm",
    "content": "export module math;\n\nexport\n{\n  auto square(const auto& x);\n\n  const double lambda = 1.303577269034296391257;  // Conway's constant\n\n  enum class Oddity { Even, Odd };\n  auto getOddity(int x);\n}\n\n// The implementation of the module's functions (+ local helpers)\nauto square(const auto& x) { return x * x; }\n\nbool isOdd(int x) { return x % 2 != 0; }\nauto getOddity(int x) { return isOdd(x) ? Oddity::Odd : Oddity::Even; }\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_02/Ex11_02.cpp",
    "content": "// Defining functions in module implementation files\nimport <iostream>;\nimport <string>;\nimport roman;\n\nint main()\n{\n  std::cout << \"1234 in Roman numerals is \" << to_roman(1234) << std::endl;\n  std::cout << \"MMXX in Arabic numerals is \" << from_roman(\"MMXX\") << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_02/from_roman.cpp",
    "content": "// Implementation of the from_roman() function\nmodule roman;\n\nunsigned int from_roman(char c)\n{\n  switch (c)\n  {\n  case 'I': return 1;    case 'V': return 5;   case 'X': return 10;\n  case 'L': return 50;   case 'C': return 100; case 'D': return 500;\n  case 'M': return 1000; default:  return 0;\n  }\n}\n\nunsigned int from_roman(std::string_view roman)\n{\n  unsigned int result{};\n  for (size_t i{}, n{ roman.length() }; i < n; ++i)\n  {\n    const auto j{ from_roman(roman[i]) };   // Integer value of the i'th roman digit\n    // Look at the next digit (if there is one) to know whether to add or subtract j\n    if (i + 1 == n || j >= from_roman(roman[i + 1])) result += j; else result -= j;\n  }\n  return result;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_02/roman.cppm",
    "content": "// Interface file for a Roman numerals module\nexport module roman;\nimport <string>;\nimport <string_view>;\n\nexport std::string to_roman(unsigned int i);\nexport unsigned int from_roman(std::string_view roman);"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_02/to_roman.cpp",
    "content": "// Implementation of the to_roman() function\nmodule roman;\n\nstd::string to_roman(unsigned int i)\n{\n  if (i > 3999) return {}; // 3999, or MMMCMXCIX, is the largest standard Roman numeral\n  static const std::string ms[]{ \"\",\"M\",\"MM\",\"MMM\" };\n  static const std::string cds[]{ \"\",\"C\",\"CC\",\"CCC\",\"CD\",\"D\",\"DC\",\"DCC\",\"DCCC\",\"CM\" };\n  static const std::string xls[]{ \"\",\"X\",\"XX\",\"XXX\",\"XL\",\"L\",\"LX\",\"LXX\",\"LXXX\",\"XC\" };\n  static const std::string ivs[]{ \"\",\"I\",\"II\",\"III\",\"IV\",\"V\",\"VI\",\"VII\",\"VIII\",\"IX\" };\n  return ms[i / 1000] + cds[(i % 1000) / 100] + xls[(i % 100) / 10] + ivs[i % 10];\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_03/Ex11_03.cpp",
    "content": "// Using types with reachable definitions but whose names are not visible\nimport <iostream>;\nimport roman;\n\nint main()\n{\n  // std::string_view is reachable, so its constructor can be invoked \n  // (this constructor, unlike the std::string_view name itself, is visible)\n  std::cout << \"MMXX in Arabic numerals is \" << from_roman(\"MMXX\") << std::endl;\n\n  // The names of the c_str() and size() members are visible as well\n  // (because the definition of std::string is reachable), \n  // and can thus be invoked.\n  std::cout << \"1234 in Roman numerals is \" << to_roman(1234).c_str() << std::endl;\n  std::cout << \"This consists of \" << to_roman(1234).size() << \" numerals\" << std::endl;\n\n  // std::string_view s{ \"MMXX\" };   /* Error: the name std::string_view is not visible */\n  // std::string roman{ to_roman(567) };  /* Error: the name std::string is not visible */\n\n  auto roman{ to_roman(567) };\n  std::cout << \"567 in Roman numerals is \" << roman.c_str() << std::endl;\n\n  // std::cout << \"std::stoi() is not visible: \" << std::stoi(\"1234\") << std::endl;\n\n  // The << operator (which is implemented as a non-member function) is not visible either\n  // std::cout << \"1234 in Roman numerals is \" << to_roman(1234) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_03/from_roman.cpp",
    "content": "// Implementation of the from_roman() function\nmodule roman;\n\nunsigned int from_roman(char c)\n{\n  switch (c)\n  {\n  case 'I': return 1;    case 'V': return 5;   case 'X': return 10;\n  case 'L': return 50;   case 'C': return 100; case 'D': return 500;\n  case 'M': return 1000; default:  return 0;\n  }\n}\n\nunsigned int from_roman(std::string_view roman)\n{\n  unsigned int result{};\n  for (size_t i{}, n{ roman.length() }; i < n; ++i)\n  {\n    const auto j{ from_roman(roman[i]) };   // Integer value of the i'th roman digit\n    // Look at the next digit (if there is one) to know whether to add or subtract j\n    if (i + 1 == n || j >= from_roman(roman[i + 1])) result += j; else result -= j;\n  }\n  return result;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_03/roman.cppm",
    "content": "// Interface file for a Roman numerals module\nexport module roman;\nimport <string>;\nimport <string_view>;\n\nexport std::string to_roman(unsigned int i);\nexport unsigned int from_roman(std::string_view roman);"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_03/to_roman.cpp",
    "content": "// Implementation of the to_roman() function\nmodule roman;\n\nstd::string to_roman(unsigned int i)\n{\n  if (i > 3999) return {}; // 3999, or MMMCMXCIX, is the largest standard Roman numeral\n  static const std::string ms[]{ \"\",\"M\",\"MM\",\"MMM\" };\n  static const std::string cds[]{ \"\",\"C\",\"CC\",\"CCC\",\"CD\",\"D\",\"DC\",\"DCC\",\"DCCC\",\"CM\" };\n  static const std::string xls[]{ \"\",\"X\",\"XX\",\"XXX\",\"XL\",\"L\",\"LX\",\"LXX\",\"LXXX\",\"XC\" };\n  static const std::string ivs[]{ \"\",\"I\",\"II\",\"III\",\"IV\",\"V\",\"VI\",\"VII\",\"VIII\",\"IX\" };\n  return ms[i / 1000] + cds[(i % 1000) / 100] + xls[(i % 100) / 10] + ivs[i % 10];\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_04/Ex11_04.cpp",
    "content": "// Module implementation partitions\nimport <iostream>;\nimport <string>;\nimport roman;\n\nint main()\n{\n  std::cout << \"1234 in Roman numerals is \" << to_roman(1234) << std::endl;\n  std::cout << \"MMXX in Arabic numerals is \" << from_roman(\"MMXX\") << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_04/from_roman.cpp",
    "content": "// Implementation of the from_roman() function\nmodule roman;\nimport :internals;\n\nunsigned int from_roman(std::string_view roman)\n{\n  unsigned int result{};\n  for (size_t i{}, n{ roman.length() }; i < n; ++i)\n  {\n    const auto j{ from_roman(roman[i]) };   // Integer value of the i'th roman digit\n    // Look at the next digit (if there is one) to know whether to add or subtract j\n    if (i + 1 == n || j >= from_roman(roman[i + 1])) result += j; else result -= j;\n  }\n  return result;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_04/roman-internals.cpp",
    "content": "// Implementation of the internal from_roman() function\nmodule roman:internals;\n\nunsigned int from_roman(char c)\n{\n  switch (c)\n  {\n  case 'I': return 1;    case 'V': return 5;   case 'X': return 10;\n  case 'L': return 50;   case 'C': return 100; case 'D': return 500;\n  case 'M': return 1000; default:  return 0;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_04/roman.cppm",
    "content": "// Interface file for a Roman numerals module\nexport module roman;\nimport <string>;\nimport <string_view>;\n\nexport std::string to_roman(unsigned int i);\nexport unsigned int from_roman(std::string_view roman);"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_04/to_roman.cpp",
    "content": "// Implementation of the to_roman() function\nmodule roman;\n\nstd::string to_roman(unsigned int i)\n{\n  if (i > 3999) return {}; // 3999, or MMMCMXCIX, is the largest standard Roman numeral\n  static const std::string ms[]{ \"\",\"M\",\"MM\",\"MMM\" };\n  static const std::string cds[]{ \"\",\"C\",\"CC\",\"CCC\",\"CD\",\"D\",\"DC\",\"DCC\",\"DCCC\",\"CM\" };\n  static const std::string xls[]{ \"\",\"X\",\"XX\",\"XXX\",\"XL\",\"L\",\"LX\",\"LXX\",\"LXXX\",\"XC\" };\n  static const std::string ivs[]{ \"\",\"I\",\"II\",\"III\",\"IV\",\"V\",\"VI\",\"VII\",\"VIII\",\"IX\" };\n  return ms[i / 1000] + cds[(i % 1000) / 100] + xls[(i % 100) / 10] + ivs[i % 10];\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_05/Ex11_05.cpp",
    "content": "// Creating module interface partitions\nimport <iostream>;\nimport <string>;\nimport roman;\n\nint main()\n{\n  std::cout << \"1234 in Roman numerals is \" << to_roman(1234) << std::endl;\n  std::cout << \"MMXX in Arabic numerals is \" << from_roman(\"MMXX\") << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_05/from_roman.cpp",
    "content": "// Implementation of the from_roman() function\nmodule roman;\nimport :internals;\n\nunsigned int from_roman(std::string_view roman)\n{\n  unsigned int result{};\n  for (size_t i{}, n{ roman.length() }; i < n; ++i)\n  {\n    const auto j{ from_roman(roman[i]) };   // Integer value of the i'th roman digit\n    // Look at the next digit (if there is one) to know whether to add or subtract j\n    if (i + 1 == n || j >= from_roman(roman[i + 1])) result += j; else result -= j;\n  }\n  return result;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_05/roman-from.cppm",
    "content": "// Module interface file for the from partition of the roman module\nexport module roman:from;\nimport <string_view>;\n\nexport unsigned int from_roman(std::string_view roman);"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_05/roman-internals.cpp",
    "content": "// Implementation of the internal from_roman() function\nmodule roman:internals;\n\nunsigned int from_roman(char c)\n{\n  switch (c)\n  {\n  case 'I': return 1;    case 'V': return 5;   case 'X': return 10;\n  case 'L': return 50;   case 'C': return 100; case 'D': return 500;\n  case 'M': return 1000; default:  return 0;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_05/roman-to.cppm",
    "content": "// Module interface file for the to partition of the roman module\nexport module roman:to;\nimport <string>;\n\nexport std::string to_roman(unsigned int i)\n{\n  if (i > 3999) return {}; // 3999, or MMMCMXCIX, is the largest standard Roman numeral\n  static const std::string ms[]{ \"\",\"M\",\"MM\",\"MMM\" };\n  static const std::string cds[]{ \"\",\"C\",\"CC\",\"CCC\",\"CD\",\"D\",\"DC\",\"DCC\",\"DCCC\",\"CM\" };\n  static const std::string xls[]{ \"\",\"X\",\"XX\",\"XXX\",\"XL\",\"L\",\"LX\",\"LXX\",\"LXXX\",\"XC\" };\n  static const std::string ivs[]{ \"\",\"I\",\"II\",\"III\",\"IV\",\"V\",\"VI\",\"VII\",\"VIII\",\"IX\" };\n  return ms[i / 1000] + cds[(i % 1000) / 100] + xls[(i % 100) / 10] + ivs[i % 10];\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_05/roman.cppm",
    "content": "// Primary module interface file for the roman module\nexport module roman;\n\nexport import :to;     // Not: 'export import roman:to;'\nexport import :from;   // Not: 'export import roman:from;'\n// export import :internals;  /* Error: only interface partitions can be exported */\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_06/Ex11_06.cpp",
    "content": "// Defining and using a namespace\n\nimport <iostream>;\nimport <numbers>;\n\nnamespace math\n{\n  const double sqrt2{ 1.414213562373095 };      // the square root of 2\n  auto square(const auto& x) { return x * x; }\n  auto pow4(const auto& x) { return square(square(x)); }\n}\n\nint main()\n{\n  std::cout << \"math::sqrt2 has the value \" << math::sqrt2 << std::endl;\n  std::cout << \"This should be 0: \" << (math::sqrt2 - std::numbers::sqrt2) << std::endl;\n  std::cout << \"This should be 2: \" << math::square(math::sqrt2) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_06A/Ex11_06A.cpp",
    "content": "// Defining and using a namespace\nimport <iostream>;\nimport <numbers>;\nimport squaring;\n\nint main()\n{\n  std::cout << \"math::sqrt2 has the value \" << math::sqrt2 << std::endl;\n  std::cout << \"This should be 0: \" << (math::sqrt2 - std::numbers::sqrt2) << std::endl;\n  std::cout << \"This should be 2: \" << math::square(math::sqrt2) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_06A/squaring.cppm",
    "content": "export module squaring;\n\nnamespace math\n{\n  export const double sqrt2{ 1.414213562373095 };      // the square root of 2\n  export auto square(const auto& x) { return x * x; }\n  export auto pow4(const auto& x) { return square(square(x)); }\n}"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_06B/Ex11_06B.cpp",
    "content": "// Defining and using a namespace\nimport <iostream>;\nimport <numbers>;\nimport squaring;\n\nint main()\n{\n  std::cout << \"math::sqrt2 has the value \" << math::sqrt2 << std::endl;\n  std::cout << \"This should be 0: \" << (math::sqrt2 - std::numbers::sqrt2) << std::endl;\n  std::cout << \"This should be 2: \" << math::square(math::sqrt2) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_06B/squaring.cppm",
    "content": "export module squaring;\n\nexport namespace math         // Exports all nested declarations at once\n{\n  const double sqrt2{ 1.414213562373095 };       // the square root of 2\n  auto square(const auto& x) { return x * x; }\n  auto pow4(const auto& x) { return square(square(x)); }\n}"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_07/Ex11_07.cpp",
    "content": "// Separating declarations and definitions of functions\n// declared in a namespace.\nimport <iostream>;\nimport math;\n\nint main()\n{\n  const double values[]{ 10, 2, 1, 8, 3, 7, 4, 5, 6, 9 };\n  std::cout << \"Arithmetic mean: \" << math::averages::arithmetic_mean(values) << std::endl;\n  std::cout << \"Geometric mean: \" << math::averages::geometric_mean(values) << std::endl;\n  std::cout << \"Root mean square: \" << math::averages::rms(values) << std::endl;\n  std::cout << \"Median: \" << math::averages::median(values) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_07/math.cpp",
    "content": "module;\n#include <cmath>    // For std::pow(), std::sqrt(), ...\nmodule math;\n\nimport <limits>;   // For std::numeric_limits<double>::quiet_NaN()\nimport <vector>;   // For std::numeric_limits<double>::quiet_NaN()\n\nvoid quicksort(std::vector<double>& data); // See Chapter 8\n\n// Option 1: define in nested namespace block (compact syntax)\nnamespace math::averages\n{\n  double arithmetic_mean(std::span<const double> data)\n  {\n    // The arithmetic mean, the most commonly used average, \n    // is defined as the sum of all elements divided by the number of elements.\n    double sum {};\n    for (auto value : data)\n      sum += value;\n    \n    return data.empty() \n      ? std::numeric_limits<double>::quiet_NaN() // Or std::nan(\"\")\n      : sum / data.size();\n  }\n}\n\n// Option 2: define in nested namespace blocks\nnamespace math\n{\n  namespace averages\n  {\n    double geometric_mean(std::span<const double> data)\n    {\n      // The geometric mean of n elements\n      // is defined as the n-th root of the product of all n elements\n      double product{ 1 };\n      for (auto value : data)\n        product *= value;\n\n      return data.empty()\n        ? std::numeric_limits<double>::quiet_NaN() \n        : std::pow(product, 1.0 / data.size());\n    }\n  }\n}\n\n// Option 3: define using fully qualified function name\ndouble math::averages::rms(std::span<const double> data)\n{ \n  // The RMS or root mean square is defined as \n  // square root of the arithmetic mean of the squares of the elements.\n  double sum_squares{};\n  for (auto value : data)\n    sum_squares += square(value);\n\n  return data.empty()\n    ? std::numeric_limits<double>::quiet_NaN() // Or std::nan(\"\")\n    : std::sqrt(sum_squares / data.size());\n}\n\n// Option 4: define using qualified name in outer namespace block\nnamespace math\n{\n  double averages::median(std::span<const double> data)\n  {\n    // The median of an odd number of elements is the value \n    // that appears in the middle position of these elements when they are sorted.\n    // The median of an even number of elements is typically\n    // defined as the mean of the two middle elements in a sorted range.\n\n    // We cannot sort the data span itself, because it's elements are const.\n    // Therefore, we first copy the const input data to be able to sort it\n    std::vector<double> sorted;\n\n    // Use range-based for loop to copy the input data.\n    // See Chapter 20 for built-in means of copying a data range.\n    for (auto value : data)\n      sorted.push_back(value);\n\n    // See Chapter 20 for built-in means of (partially) sorting data\n    quicksort(sorted);\n\n    const size_t mid = data.size() / 2;\n    return data.empty() ? std::numeric_limits<double>::quiet_NaN() // Or std::nan\n         : data.size() % 2 == 1 ? sorted[mid]\n         : (sorted[mid - 1] + sorted[mid]) / 2;\n  }\n}\n\nvoid quicksort(std::vector<double>& data, size_t start, size_t end);\nvoid quicksort(std::vector<double>& data)\n{\n  if (!data.empty())\n    quicksort(data, 0, data.size() - 1);\n}\n\nvoid quicksort(std::vector<double>& data, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle value to partition set, \n  // and move it to the front of the current range\n  std::swap(data[start], data[(start + end) / 2]);\n  \n  // Compare all other values against chosen value at index start\n  size_t current{ start };\n  for (size_t i{ start + 1 }; i <= end; i++)\n  {\n    if (data[i] < data[start]) // Is the value less than chosen value?\n      std::swap(data[++current], data[i]); // Yes, so swap to the left\n  }\n\n  std::swap(data[start], data[current]); // Swap chosen and last swapped words\n\n  if (current > start) quicksort(data, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) quicksort(data, current + 1, end); // Sort right subset if exists\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_07/math.cppm",
    "content": "export module math;\n\nimport <span>;\n\nexport namespace math\n{\n  auto square(const auto& x) { return x * x; };\n\n  namespace averages\n  {\n    double arithmetic_mean(std::span<const double> data);\n    double geometric_mean(std::span<const double> data);\n    double rms(std::span<const double> data);\n    double median(std::span<const double> data);\n  }\n}"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_08/Ex11_08.cpp",
    "content": "// Using using declarations and using directives\n// (Note: example was not named in the text)\nimport <iostream>;\nimport squaring;\n\n/* Make names from the math namespace available locally */\n// Note: text uses hypot(), but this causes ambiguities with hypot() \n// function of <cmath> with Visual Studio\nauto hypotenuse(const auto& x, const auto& y)\n{\n  using namespace math;\n  // Or:\n  //   using math::square;\n  //   using math::sqrt;    /* Same as, of course: using std::sqrt; */\n  return sqrt(square(x) + square(y));\n}\n\nint main()\n{\n  std::cout << \"math::sqrt2 has the value \" << math::sqrt2 << std::endl;\n  std::cout << \"This should be 0: \" << (math::sqrt2 - std::numbers::sqrt2) << std::endl;\n  std::cout << \"This should be 2: \" << math::square(math::sqrt2) << std::endl;\n  std::cout << \"This should be 5: \" << hypotenuse(3, 4) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 11/Ex11_08/squaring.cppm",
    "content": "module;               // Start of the global module fragment (for #include directives)\n#include <cmath>      // For std::sqrt()\nexport module squaring;\nimport <numbers>;     // For std::numbers::sqrt2 \n\n/* Re-export two existing entities from the math namespace using using declarations */\nexport namespace math         // Exports all nested declarations at once\n{\n  \n  using std::numbers::sqrt2;\n  using std::sqrt;    // Never 'using std::sqrt();' or 'using std::sqrt(double);'!\n  auto square(const auto& x) { return x * x; }\n  auto pow4(const auto& x) { return square(square(x)); }\n}\n\n/* Export all names from a namespace from the math namespace using a using directive */\n//namespace math\n//{\n//  export using namespace std::numbers;\n//}"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_01/Ex12_01.cpp",
    "content": "// Defining a class constructor\nimport <iostream>;\n\n// Class to represent a box\nclass Box\n{\npublic:\n  // Constructor\n  Box(double length, double width, double height)\n  {\n    std::cout << \"Box constructor called.\"  << std::endl;\n    m_length = length;\n    m_width = width;\n    m_height = height;\n  }\n\n  // Function to calculate the volume of a box\n  double volume()\n  {\n    return m_length * m_width * m_height;\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\nint main()\n{\n  Box firstBox {80.0, 50.0, 40.0};            // Create a box\n  double firstBoxVolume {firstBox.volume()};  // Calculate the box volume\n  std::cout << \"Volume of Box object is \" << firstBoxVolume << std::endl;\n\n  // Box secondBox;        // Causes a compiler error message\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_01A/Ex12_01A.cpp",
    "content": "// Defining a default constructor\nimport <iostream>;\n\n// Class to represent a box\nclass Box\n{\npublic:\n// Box() {}           // Explicitly defined default constructor\n  Box() = default;    // Defaulted default constructor\n\n  // Constructor\n  Box(double length, double width, double height)\n  {\n    std::cout << \"Box constructor called.\"  << std::endl;\n    m_length = length;\n    m_width = width;\n    m_height = height;\n  }\n\n  // Function to calculate the volume of a box\n  double volume()\n  {\n    return m_length * m_width * m_height;\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\nint main()\n{\n  Box firstBox {80.0, 50.0, 40.0};            // Create a box\n  double firstBoxVolume {firstBox.volume()};  // Calculate the box volume\n  std::cout << \"Volume of Box object is \" << firstBoxVolume << std::endl;\n\n  Box secondBox;        // No longer causes a compiler error message\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_02/Ex12_02.cpp",
    "content": "// Defining member functions outside a class\n// Note that, unlike what we said in the text, \n// in this example we put the function definitions after the main() function.\n// This illustrates that to invoke a member function,\n// the compiler again only needs access to the signature of the member function.\nimport <iostream>;\n\n// Class to represent a box\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume();   // Function to calculate the volume of a box\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\nint main()\n{\n  Box firstBox {80.0, 50.0, 40.0};            // Create a box\n  double firstBoxVolume {firstBox.volume()};  // Calculate the box volume\n  std::cout << \"Volume of Box object is \" << firstBoxVolume << std::endl;\n\n  Box secondBox;        // No longer causes a compiler error message\n}\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n  m_length = length;\n  m_width = width;\n  m_height = height;\n}\n\n// Member function definition\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_03/Ex12_03.cpp",
    "content": "// Using a member initializer list\nimport <iostream>;\n\n// Class to represent a box\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume();   // Function to calculate the volume of a box\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\nint main()\n{\n  Box firstBox {80.0, 50.0, 40.0};            // Create a box\n  double firstBoxVolume {firstBox.volume()};  // Calculate the box volume\n  std::cout << \"Volume of Box object is \" << firstBoxVolume << std::endl;\n\n  Box secondBox;        // No longer causes a compiler error message\n}\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{length}, m_width{width}, m_height{height}\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Member function definition\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_04/Ex12_04.cpp",
    "content": "// Using the explicit keyword\n// Uncomment \"explicit\" to make the compilation of \n// the expression \"box1.hasLargerVolumeThan(50.0)\" fail\nimport <iostream>;\n\nclass Cube\n{\npublic:\n  /*explicit*/ Cube(double side);       // Constructor\n  double volume();                      // Calculate volume of a cube\n  bool hasLargerVolumeThan(Cube cube);  // Compare volume of a cube with another\nprivate:\n  double m_side;\n};\n\nCube::Cube(double side) : m_side{ side }\n{\n  std::cout << \"Cube constructor called.\" << std::endl;\n}\n\ndouble Cube::volume() { return m_side * m_side * m_side; }\nbool Cube::hasLargerVolumeThan(Cube cube) { return volume() > cube.volume(); }\n\nint main()\n{\n  Cube box1{ 7.0 };\n  Cube box2{ 3.0 };\n  if (box1.hasLargerVolumeThan(box2))\n    std::cout << \"box1 is larger than box2.\" << std::endl;\n  else\n    std::cout << \"Volume of box1 is less than or equal to that of box2.\" << std::endl;\n\n  std::cout << \"Volume of box1 is \" << box1.volume() << std::endl;\n  if (box1.hasLargerVolumeThan(50.0))\n    std::cout << \"Volume of box1 is greater than 50\" << std::endl;\n  else\n    std::cout << \"Volume of box1 is less than or equal to 50\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_05/Ex12_05.cpp",
    "content": "// Delegating constructors\nimport <iostream>;\n\nclass Box\n{\npublic:\n  Box(double length, double width, double height);\n  explicit Box(double side);   // Constructor for a cube (explicit!)\n  Box() = default;             // Defaulted default constructor\n\n  double volume();             // Function to calculate the volume of a box\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n};\n\n// A constructor that initializes all three member variables\nBox::Box(double length, double width, double height) \n  : m_length{length}, m_width{width}, m_height{height}\n{\n  std::cout << \"Box constructor 1 called.\" << std::endl;\n}\n\n// This second constructor forwards to the first one to initialize all members.\n// Note that you do not repeat the explicit keyword here!\nBox::Box(double side) : Box{ side, side, side }\n{\n  std::cout << \"Box constructor 2 called.\" << std::endl;\n}\n\nint main()\n{\n  Box box1{ 2.0, 3.0, 4.0 };     // An arbitrary box\n  Box box2{ 5.0 };               // A box that is a cube\n  std::cout << \"box1 volume = \" << box1.volume() << std::endl;\n  std::cout << \"box2 volume = \" << box2.volume() << std::endl;\n}\n\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_05A/Ex12_05A.cpp",
    "content": "// Implementing the copy constructor\n// Note: this example is explained but not named in the text\nimport <iostream>;\n\nclass Box\n{\npublic:\n  Box(double length, double width, double height);\n  explicit Box(double side);   // Constructor for a cube (explicit!)\n  Box() = default;             // Defaulted default constructor\n  Box(const Box& box);         // Copy constructor\n\n  double volume();             // Function to calculate the volume of a box\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n};\n\n// A basic copy constructor\nBox::Box(const Box& box)\n  : m_length{ box.m_length }, m_width{ box.m_width }, m_height{ box.m_height }\n{\n  std::cout << \"Copy constructor called.\" << std::endl;\n}\n\n// A delegating copy constructor\n//Box::Box(const Box& box) : Box{ box.m_length, box.m_width, box.m_height }\n//{\n//  std::cout << \"Copy constructor called.\" << std::endl;\n//}\n\n\nint main()\n{\n  Box box1{ 2.0, 3.0, 4.0 };     // An arbitrary box\n  Box box2{ 5.0 };               // A box that is a cube\n  std::cout << \"box1 volume = \" << box1.volume() << std::endl;\n  std::cout << \"box2 volume = \" << box2.volume() << std::endl;\n\n  Box box3{ box2 };\n  std::cout << \"box3 volume = \" << box3.volume() << std::endl;   // Volume = 125\t\n}\n\n// A constructor that initializes all three member variables\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor 1 called.\" << std::endl;\n}\n\n// This second constructor forwards to the first one to initialize all members.\n// Note that you do not repeat the explicit keyword here!\nBox::Box(double side) : Box{ side, side, side }\n{\n  std::cout << \"Box constructor 2 called.\" << std::endl;\n}\n\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_06/Box.cppm",
    "content": "// Module interface file for a module exporting the Box class\nexport module box;\nimport <iostream>;\n\n// Class to represent a box\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume();   // Function to calculate the volume of a box\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Member function definition\ndouble Box::volume() { return m_length * m_width * m_height; }\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_06/Ex12_06.cpp",
    "content": "// Exporting a class from a module\nimport <iostream>;   // For use of std::cout, std::endl, etc.\nimport box;          // For use of the Box class\n\nint main()\n{\n  Box myBox{ 6.0, 6.0, 18.5 }; // Create a box\n  std::cout << \"Volume of the first Box object is \" << myBox.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_06A/Box.cpp",
    "content": "module box;\nimport <iostream>;\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Member function definition\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_06A/Box.cppm",
    "content": "export module box;\n\n// Class to represent a box\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume();   // Function to calculate the volume of a box\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_06A/Ex12_06A.cpp",
    "content": "// Defining class members in a module implementation file\n\nimport <iostream>;  // For use of std::cout, std::endl, etc.\nimport box;         // For use of the Box class\n\nint main()\n{\n  Box myBox{ 6.0, 6.0, 18.5 }; // Create a box\n  std::cout << \"Volume of the first Box object is \" << myBox.volume() << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_06B/Box.cppm",
    "content": "export module box;\nimport <iostream>;\n\n// Class to represent a box\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height)\n    : m_length{ length }, m_width{ width }, m_height{ height }\n  {\n    std::cout << \"Box constructor called.\" << std::endl;\n  }\n\n  // Function to calculate the volume of a box\n  double volume() { return m_length * m_width * m_height; }\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_06B/Ex12_06B.cpp",
    "content": "// Defining classes with in-class member definitions.\n\nimport <iostream>; // For use of std::cout, std::endl, etc.\nimport box;        // For use of the Box class\n\nint main()\n{\n  Box myBox{ 6.0, 6.0, 18.5 }; // Create a box\n  std::cout << \"Volume of the first Box object is \" << myBox.volume() << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_07/Box.cpp",
    "content": "module box;\n\nimport <iostream>;\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Member function definition\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_07/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume();    // Function to calculate the volume of a box\n\n  // Functions to provide access to the values of member variables\n  double getLength() { return m_length; }\n  double getWidth()  { return m_width; }\n  double getHeight() { return m_height; }\n\n  // Functions to set member variable values\n  void setLength(double length) { if (length > 0) m_length = length; }\n  void setWidth(double width)   { if (width > 0)  m_width  = width;  }\n  void setHeight(double height) { if (height > 0) m_height = height; }\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_07/Ex12_07.cpp",
    "content": "// Accessing private members through getters and setters\nimport <iostream>;\nimport box;\n\nint main()\n{\n  Box myBox {3.0, 4.0, 5.0};\n  std::cout << \"myBox dimensions are \" << myBox.getLength()\n            << \" by \" << myBox.getWidth()\n            << \" by \" << myBox.getHeight() << std::endl;\n\n  myBox.setLength(-20.0);       // ignored!\n  myBox.setWidth(40.0);\n  myBox.setHeight(10.0);\n  std::cout << \"myBox dimensions are now \" << myBox.getLength()  // 3 (unchanged)\n    << \" by \" << myBox.getWidth()                        // by 40\n    << \" by \" << myBox.getHeight() << std::endl;         // by 10\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_08/Box.cpp",
    "content": "module box;\nimport <iostream>;\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Member function definition\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}\n\n// Mutator function definitions\nBox& Box::setLength(double length)\n{\n  if (length > 0) m_length = length;\n  return *this;\n}\nBox& Box::setWidth(double width)\n{\n  if (width > 0) m_width = width;\n  return *this;\n}\nBox& Box::setHeight(double height)\n{\n  if (height > 0) m_height = height;\n  return *this;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_08/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume();    // Function to calculate the volume of a box\n\n  // Inspector functions\n  double getLength() { return m_length; }\n  double getWidth()  { return m_width; }\n  double getHeight() { return m_height; }\n\n  // Mutator functions\n  Box& setLength(double length);\n  Box& setWidth(double width);\n  Box& setHeight(double height);\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_08/Ex12_08.cpp",
    "content": "// Accessing private members through getters and setters (method chaining variant)\nimport <iostream>;\nimport box;\n\nint main()\n{\n  Box myBox {3.0, 4.0, 5.0};\n  std::cout << \"myBox dimensions are \" << myBox.getLength()\n            << \" by \" << myBox.getWidth()\n            << \" by \" << myBox.getHeight() << std::endl;\n\n  myBox.setLength(-20.0).setWidth(40.0).setHeight(10.0); // Set all dimensions of myBox\n\n  std::cout << \"myBox dimensions are now \" << myBox.getLength()  // 3 (unchanged)\n    << \" by \" << myBox.getWidth()                        // by 40\n    << \" by \" << myBox.getHeight() << std::endl;         // by 10\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_09/Box.cpp",
    "content": "module box;\n\nimport <iostream>;\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Const member function definition\ndouble Box::volume() const\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_09/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume() const;    // Const function to calculate the volume of a box\n\n  // Functions to provide access to the values of member variables (all const!)\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions to set member variable values (not const!)\n  void setLength(double length) { if (length > 0) m_length = length; }\n  void setWidth(double width)   { if (width > 0)  m_width  = width;  }\n  void setHeight(double height) { if (height > 0) m_height = height; }\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_09/Ex12_09.cpp",
    "content": "// Const objects and const member functions\nimport <iostream>;\nimport box;\n\nint main()\n{\n  // v-- this const was added...\n  const Box myBox {3.0, 4.0, 5.0};\n  std::cout << \"myBox dimensions are \" << myBox.getLength()\n            << \" by \" << myBox.getWidth()\n            << \" by \" << myBox.getHeight() << std::endl;\n\n  // Invoking mutators / setters is not possible on a const object:\n  //myBox.setLength(-20.0);       // ignored!\n  //myBox.setWidth(40.0);\n  //myBox.setHeight(10.0);\n  //std::cout << \"myBox dimensions are now \" << myBox.getLength()  // 3 (unchanged)\n  //  << \" by \" << myBox.getWidth()                        // by 40\n  //  << \" by \" << myBox.getHeight() << std::endl;         // by 10\n\n  std::cout << \"myBox's volume is \" << myBox.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_10/Box.cpp",
    "content": "module box;\nimport <iostream>;\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Const member function definition\ndouble Box::volume() const\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_10/Box.cppm",
    "content": "export module box;\nimport <iostream>;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume() const;    // Const function to calculate the volume of a box\n\n  // Non-const overloads (return references to dimension variable)\n  double& length() { std::cout << \"non-const overload called\\n\"; return m_length; };\n  double& width()  { std::cout << \"non-const overload called\\n\"; return m_width; };\n  double& height() { std::cout << \"non-const overload called\\n\"; return m_height; };\n\n  // Const overloads (return references to const variables)\n  const double& length() const { std::cout << \"const overload called\\n\"; return m_length; };\n  const double& width()  const { std::cout << \"const overload called\\n\"; return m_width; };\n  const double& height() const { std::cout << \"const overload called\\n\"; return m_height; };\n\n  // Attempt to return non-const references to member variables from const functions\n// double& length() const { return m_length; };   // This must not be allowed to compile!\n// double& width()  const { return m_width; };\n// double& height() const { return m_height; };\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_10/Ex12_10.cpp",
    "content": "// Overloading on const\nimport <iostream>;\nimport box;\n\nint main()\n{\n  const Box constBox{ 1, 2, 3 };\n  // constBox.length() = 2;                          // Does not compile: good!\n  std::cout << constBox.length() << std::endl;\n\n  Box nonConstBox{ 3, 2, 1 };\n  nonConstBox.length() *= 2;\n  std::cout << nonConstBox.length() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_11/Box.cpp",
    "content": "module box;\n\nimport <iostream>;\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Const member function definition\ndouble Box::volume() const\n{\n  return m_length * m_width * m_height;\n}\n\n// Modify mutable member variable from a const member function \nvoid Box::printVolume() const\n{\n  // Count how many times printVolume() is called using a mutable member in a const function\n  std::cout << \"The volume of this box is \" << volume() << std::endl;\n  std::cout << \"printVolume() has been called \" << ++m_count << \" time(s)\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_11/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume() const;      // Function to calculate the volume of a box\n  void printVolume() const;   // Function to print out the volume of a box (const!)\n\n  // Functions to provide access to the values of member variables (all const!)\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions to set member variable values (not const!)\n  void setLength(double length) { if (length > 0) m_length = length; }\n  void setWidth(double width)   { if (width > 0)  m_width  = width;  }\n  void setHeight(double height) { if (height > 0) m_height = height; }\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n  mutable unsigned m_count{};   // Counts the amount of time printVolume() is called\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_11/Ex12_11.cpp",
    "content": "// Const objects and const member functions\nimport <iostream>;\nimport box;\n\nint main()\n{\n  const Box myBox {3.0, 4.0, 5.0};\n  std::cout << \"myBox dimensions are \" << myBox.getLength()\n            << \" by \" << myBox.getWidth()\n            << \" by \" << myBox.getHeight() << std::endl;\n\n  myBox.printVolume();\n  myBox.printVolume();\n  myBox.printVolume();\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_12/Box.cpp",
    "content": "module box;\n\nimport <iostream>;\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Const member function definition\ndouble Box::volume() const\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_12/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0} {}        // A delegating default constructor\n  Box(double length, double width, double height);\n\n  double volume() const;                // Function to calculate the volume of a box\n\n  friend double surfaceArea(const Box& box); // Friend function for the surface area\n\nprivate:\n  double m_length, m_width, m_height;\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_12/Ex12_12.cpp",
    "content": "// Using a friend function of a class\nimport <iostream>;\nimport <memory>;\nimport box;\n\nint main()\n{\n  Box box1 {2.2, 1.1, 0.5};    // An arbitrary box\n  Box box2;                    // A default box\n  auto box3{ std::make_unique<Box>(15.0, 20.0, 8.0) }; // Dynamically allocated Box\n\n  std::cout << \"Volume of box1 = \" << box1.volume() << std::endl;\n  std::cout << \"Surface area of box1 = \" << surfaceArea(box1) << std::endl;\n\n  std::cout << \"Volume of box2 = \"<< box2.volume() << std::endl;\n  std::cout << \"Surface area of box2 = \" << surfaceArea(box2) << std::endl;\n\n  std::cout << \"Volume of box3 = \" << box3->volume() << std::endl;\n  std::cout << \"Surface area of box3 = \" << surfaceArea(*box3) << std::endl;\n}\n\n// friend function to calculate the surface area of a Box object\ndouble surfaceArea(const Box& box)\n{\n  return 2.0 * (box.m_length * box.m_width\n    + box.m_length * box.m_height + box.m_height * box.m_width);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_13/Box.cpp",
    "content": "module box;\n\nimport <iostream>;\n\nBox::Box(double length, double width, double height)  // Constructor definition\n  : m_length{length}, m_width{width}, m_height{height}\n{\n  std::cout << \"Box constructor 1 called.\" << std::endl;\n}\n\nBox::Box(double side) : Box{side, side, side}  // Constructor for a cube\n{\n  std::cout << \"Box constructor 2 called.\" << std::endl;\n}\n\nBox::Box()                                      // Default constructor\n{\n  std::cout << \"Default Box constructor called.\" << std::endl;\n}\n\nBox::Box(const Box& box)                        // Copy constructor\n  : m_length{box.m_length}, m_width{box.m_width}, m_height{box.m_height}\n{\n  std::cout << \"Box copy constructor called.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_13/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  /* Constructors */\n  Box(double length, double width, double height);\n  Box(double side);       // Constructor for a cube\n  Box();                  // Default constructor\n  Box(const Box& box);    // Copy constructor\n\n  double volume() const { return m_length * m_width * m_height; };\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_13/Ex12_13.cpp",
    "content": "// Creating an array of objects\nimport <iostream>;\nimport box;\n\nint main()\n{\n  const Box box1 {2.0, 3.0, 4.0};  // An arbitrary box\n  Box box2 {5.0};                  // A box that is a cube\n  std::cout << \"box1 volume = \" << box1.volume() << std::endl;\n  std::cout << \"box2 volume = \" << box2.volume() << std::endl;\n  Box box3 {box2};\n  std::cout << \"box3 volume = \" << box3.volume() << std::endl;   // Volume = 125\n\n  std::cout << std::endl;\n\n  Box boxes[6] {box1, box2, box3, Box {2.0}};\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_14/Box.cpp",
    "content": "module box;\nimport <iostream>;\n\nBox::Box(double length, double width, double height)  // Constructor definition\n  : m_length{length}, m_width{width}, m_height{height}\n{\n  ++s_object_count;\n  std::cout << \"Box constructor 1 called.\" << std::endl;\n}\n\nBox::Box(double side) : Box{side, side, side}  // Constructor for a cube\n{\n  // Do not increment s_object_count in forwarding constructor: \n  // already incremented in the constructor this constructor forwards to!\n  std::cout << \"Box constructor 2 called.\" << std::endl;\n}\n\nBox::Box()                                      // Default constructor\n{\n  ++s_object_count;\n  std::cout << \"Default Box constructor called.\" << std::endl;\n}\n\nBox::Box(const Box& box)                        // Copy constructor\n  : m_length{box.m_length}, m_width{box.m_width}, m_height{box.m_height}\n{\n  ++s_object_count;\n  std::cout << \"Box copy constructor called.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_14/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  Box();                     // Default constructor  \n  Box(double side);          // Constructor for a cube\n  Box(const Box& box);       // Copy constructor\n  Box(double length, double width, double height);\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  size_t getObjectCount() const { return s_object_count; }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n  static inline size_t s_object_count {};   // Count of objects ever created\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_14/Ex12_14.cpp",
    "content": "// Using a static member variable\nimport <iostream>;\nimport box;\n\nint main()\n{\n  const Box box1 {2.0, 3.0, 4.0};                              // An arbitrary box\n  Box box2 {5.0};                                              // A box that is a cube\n  std::cout << \"box1 volume = \" << box1.volume() << std::endl;\n  std::cout << \"box2 volume = \" << box2.volume() << std::endl;\n  Box box3 {box2};\n  std::cout << \"box3 volume = \" << box3.volume() << std::endl; // Volume = 125\n\n  std::cout << std::endl;\n\n  Box boxes[6] {box1, box2, box3, Box {2.0}};\n\n  std::cout << \"\\nThere are now \" << box1.getObjectCount() << \" Box objects.\\n\";\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_15/CylindricalBox.cpp",
    "content": "module cylindrical;\n\nimport <iostream>;\n\nCylindricalBox::CylindricalBox(float radius, float height, std::string_view material)\n  : m_radius{ radius }\n  , m_height{ height }\n  , m_material{ material }\n{\n  std::cout << \"Box constructed consisting of \" << material;\n  if (material == s_default_material)\n  {\n    std::cout << \" (the default material!)\";\n  }\n  std::cout << std::endl;\n}\n\nfloat CylindricalBox::volume() const\n{\n  return PI * m_radius * m_radius * m_height;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_15/CylindricalBox.cppm",
    "content": "export module cylindrical;\n\nimport <string>;\nimport <string_view>;\n\nexport class CylindricalBox\n{\npublic:\n  static inline const float s_max_radius { 35.0f };\n  static inline const float s_max_height { 60.0f };\n  static inline const std::string_view s_default_material { \"paperboard\" };\n\n  CylindricalBox(float radius, float height,\n                 std::string_view material = s_default_material);\n  float volume() const;\n\nprivate:\n  // The value of PI used by CylindricalBox's volume() function\n  static inline const float PI { 3.141592f };  \n\n  float m_radius;\n  float m_height;\n  std::string m_material;\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_15/Ex12_15.cpp",
    "content": "// Defining and using static constants\nimport <iostream>;\nimport cylindrical;\n\nint main()\n{\n  CylindricalBox bigBox{ 1.23f,\n            CylindricalBox::s_max_height, CylindricalBox::s_default_material };\n  std::cout << \"The volume of bigBox is \" <<  bigBox.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_16/Box.cpp",
    "content": "module box;\nimport <iostream>;\n\nBox::Box(double length, double width, double height)  // Constructor definition\n  : m_length{length}, m_width{width}, m_height{height}\n{\n  ++s_object_count;\n  std::cout << \"Box constructor 1 called.\" << std::endl;\n}\n\nBox::Box(double side) : Box{side, side, side}  // Constructor for a cube\n{\n  // Do not increment s_object_count in forwarding constructor: \n  // already incremented in the constructor this constructor forwards to!\n  std::cout << \"Box constructor 2 called.\" << std::endl;\n}\n\nBox::Box()                                      // Default constructor\n{\n  ++s_object_count;\n  std::cout << \"Default Box constructor called.\" << std::endl;\n}\n\nBox::Box(const Box& box)                        // Copy constructor\n  : m_length{box.m_length}, m_width{box.m_width}, m_height{box.m_height}\n{\n  ++s_object_count;\n  std::cout << \"Box copy constructor called.\" << std::endl;\n}\n\nBox::~Box()                              // Destructor\n{\n  std::cout << \"Box destructor called.\" << std::endl;\n  --s_object_count;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_16/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  Box();                     // Default constructor  \n  Box(double side);          // Constructor for a cube\n  Box(const Box& box);       // Copy constructor\n  Box(double length, double width, double height);\n  ~Box();   // Destructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  static size_t getObjectCount() { return s_object_count; }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n  static inline size_t s_object_count {};   // Count of objects ever created\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_16/Ex12_16.cpp",
    "content": "// Implementing a destructor\nimport <iostream>;\nimport box;\n\nint main()\n{\n  std::cout << \"There are now \" << Box::getObjectCount() << \" Box objects.\" << std::endl;\n\n  const Box box1 {2.0, 3.0, 4.0};     // An arbitrary box\n  Box box2 {5.0};                     // A box that is a cube\n\n  std::cout << \"There are now \" << Box::getObjectCount() << \" Box objects.\" << std::endl;\n\n  for (double d {} ; d < 3.0 ; ++d)\n  {\n    Box box {d, d + 1.0, d + 2.0};\n    std::cout << \"Box volume is \" << box.volume() << std::endl;\n  }\n\n  std::cout << \"There are now \" << Box::getObjectCount() << \" Box objects.\" << std::endl;\n\n  auto pBox{ std::make_unique<Box>(1.5, 2.5, 3.5) };\n  std::cout << \"Box volume is \" << pBox->volume() << std::endl;\n  std::cout << \"There are now \" << pBox->getObjectCount() << \" Box objects.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_17/Box.cppm",
    "content": "export module box;\n\nimport <iostream>;\nimport <format>;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  void listBox() const\n  {\n    std::cout << std::format(\"Box({:.1f},{:.1f},{:.1f})\", m_length, m_width, m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_17/Ex12_17.cpp",
    "content": "// Using a linked list\nimport box.random;\nimport truckload;\nimport <iostream>;\n\nint main()  \n{\n  Truckload load1;  // Create an empty list\n\n  // Add 12 random Box objects to the list\n  const size_t boxCount {12};\n  for (size_t i {} ; i < boxCount ; ++i)\n    load1.addBox(randomSharedBox());\n\n  std::cout << \"The first list:\\n\";\n  load1.listBoxes();\n\n  // Copy the truckload\n  Truckload copy{load1};\n  std::cout << \"The copied truckload:\\n\";\n  copy.listBoxes();\n\n  // Find the largest Box in the list\n  SharedBox largestBox{load1.getFirstBox()};\n\n  SharedBox nextBox{load1.getNextBox()};\n  while (nextBox)\n  {\n    if (nextBox->compare(*largestBox) > 0)\n      largestBox = nextBox;\n    nextBox = load1.getNextBox();\n  }\n\n  std::cout << \"\\nThe largest box in the first list is \";\n  largestBox->listBox();\n  std::cout << std::endl;\n  load1.removeBox(largestBox);\n  std::cout << \"\\nAfter deleting the largest box, the list contains:\\n\";\n  load1.listBoxes();\n\n  const size_t nBoxes {20};            // Number of vector elements\n  std::vector<SharedBox> boxes;        // Array of Box objects\n\n  for (size_t i {} ; i < nBoxes ; ++i)\n    boxes.push_back(randomSharedBox());\n\n  Truckload load2{boxes};\n  std::cout << \"\\nThe second list:\\n\";\n  load2.listBoxes();\n\n  auto smallestBox{ load2.getFirstBox() };\n  for (auto box{ load2.getNextBox() }; box; box = load2.getNextBox())\n    if (box->compare(*smallestBox) < 0)\n      smallestBox = box;\n\n  std::cout << \"\\nThe smallest box in the second list is \";\n  smallestBox->listBox();\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_17/Package.cpp",
    "content": "module truckload:package;\n\nimport :shared_box;\n\nclass Package\n{\npublic:\n  Package(SharedBox box) : m_box{box}, m_next{nullptr} {}  // Constructor\n  ~Package() { delete m_next; }                            // Destructor\n\n  // Retrieve the Box pointer\n  SharedBox getBox() const { return m_box; }\n\n  // Retrieve or update the pointer to the next Package\n  Package* getNext() { return m_next; }\n  void setNext(Package* package) { m_next = package; }\n\nprivate:\n  SharedBox m_box;    // Pointer to the Box object contained in this Package\n  Package* m_next;    // Pointer to the next Package in the list\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_17/RandomBoxes.cppm",
    "content": "export module box.random;\nimport box;\nimport <random>;        // For random number generation\nimport <functional>;    // For std::bind()\nimport <memory>;        // For std::make_shared<>() and std::shared_ptr<>;\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\nexport Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return { random(), random(), random() };\n}\n\nexport auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_17/SharedBox.cppm",
    "content": "export module truckload:shared_box;\n\nimport <memory>;\nimport box;\n\nexport using SharedBox = std::shared_ptr<Box>;\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_17/Truckload.cpp",
    "content": "module truckload;\n\nimport <iostream>;\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->getNext())\n  {\n    addBox(package->getBox());\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nvoid Truckload::listBoxes() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count {};  \n  for (Package* package{m_head}; package; package = package->getNext())\n  {\n    std::cout << ' ';\n    package->getBox()->listBox();\n    if (! (++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\n\nSharedBox Truckload::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->getBox() : nullptr;\n}\n\nSharedBox Truckload::getNextBox()\n{\n  if (!m_current)                                    // If there's no current...\n    return getFirstBox();                            // ...return the 1st Box\n\n  m_current = m_current->getNext();                  // Move to the next package\n\n  return m_current? m_current->getBox() : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->setNext(package);      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};      // no previous yet\n  Package* current {m_head};        // initialize current to the head of the list\n  while (current)\n  {\n    if (current->getBox() == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->setNext(current->getNext());\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->getNext();\n      if (current == m_tail) m_tail = previous;\n      if (current == m_current) m_current = current->getNext();\n\n      current->setNext(nullptr);        // Disconnect the current Package from the list\n      delete current;                   // and delete it\n\n      return true;                      // Return true: we found and removed the box\n    }\n                                        // Move both pointers along (mind the order!)\n    previous = current;                 //  - first current becomes the new previous\n    current = current->getNext();       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_17/Truckload.cppm",
    "content": "export module truckload;\n\nexport import :shared_box;\nimport :package;\nimport <vector>;\n\nexport class Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  SharedBox getFirstBox();          // Get the first Box\n  SharedBox getNextBox();           // Get the next Box\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n  void listBoxes() const;           // Output the Boxes\n\nprivate:\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n  Package* m_current {};            // Last retrieved from the list\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_18/Box.cppm",
    "content": "export module box;\n\nimport <iostream>;\nimport <format>;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  void listBox() const\n  {\n    std::cout << std::format(\"Box({:.1f},{:.1f},{:.1f})\", m_length, m_width, m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_18/Ex12_18.cpp",
    "content": "// Using nested classes\nimport box.random;\nimport truckload;\nimport <iostream>;\n\nint main()  \n{\n  Truckload load1;  // Create an empty list\n\n  // Add 12 random Box objects to the list\n  const size_t boxCount {12};\n  for (size_t i {} ; i < boxCount ; ++i)\n    load1.addBox(randomSharedBox());\n\n  std::cout << \"The first list:\\n\";\n  load1.listBoxes();\n\n  // Copy the truckload\n  Truckload copy{load1};\n  std::cout << \"The copied truckload:\\n\";\n  copy.listBoxes();\n\n  // Find the largest Box in the list\n  SharedBox largestBox{load1.getFirstBox()};\n\n  SharedBox nextBox{load1.getNextBox()};\n  while (nextBox)\n  {\n    if (nextBox->compare(*largestBox) > 0)\n      largestBox = nextBox;\n    nextBox = load1.getNextBox();\n  }\n\n  std::cout << \"\\nThe largest box in the first list is \";\n  largestBox->listBox();\n  std::cout << std::endl;\n  load1.removeBox(largestBox);\n  std::cout << \"\\nAfter deleting the largest box, the list contains:\\n\";\n  load1.listBoxes();\n\n  const size_t nBoxes {20};            // Number of vector elements\n  std::vector<SharedBox> boxes;        // Array of Box objects\n\n  for (size_t i {} ; i < nBoxes ; ++i)\n    boxes.push_back(randomSharedBox());\n\n  Truckload load2{boxes};\n  std::cout << \"\\nThe second list:\\n\";\n  load2.listBoxes();\n\n  auto smallestBox{ load2.getFirstBox() };\n  for (auto box{ load2.getNextBox() }; box; box = load2.getNextBox())\n    if (box->compare(*smallestBox) < 0)\n      smallestBox = box;\n\n  std::cout << \"\\nThe smallest box in the second list is \";\n  smallestBox->listBox();\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_18/RandomBoxes.cppm",
    "content": "export module box.random;\n\nimport box;\nimport <random>;        // For random number generation\nimport <functional>;    // For std::bind()\nimport <memory>;        // For std::make_shared<>() and std::shared_ptr<>;\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\nexport Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\nexport auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_18/Truckload.cpp",
    "content": "module truckload;\nimport <iostream>;\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nvoid Truckload::listBoxes() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count {};  \n  for (Package* package{m_head}; package; package = package->m_next)\n  {\n    std::cout << ' ';\n    package->m_box->listBox();\n    if (! (++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\n\nSharedBox Truckload::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\nSharedBox Truckload::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n      if (current == m_current) m_current = current->m_next;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 12/Ex12_18/Truckload.cppm",
    "content": "export module truckload;\nimport box;\n\nimport <memory>;\nimport <vector>;\n\nexport using SharedBox = std::shared_ptr<Box>;\n\nexport class Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  SharedBox getFirstBox();          // Get the first Box\n  SharedBox getNextBox();           // Get the next Box\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n  void listBoxes() const;           // Output the Boxes\n\nprivate:\n  class Package\n  {\n  public:\n    SharedBox m_box;      // Pointer to the Box object contained in this Package\n    Package* m_next;      // Pointer to the next Package in the list\n\n    Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n    ~Package() { delete m_next; }                           // Destructor\n  };\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n  Package* m_current {};            // Last retrieved from the list\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_01/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h} {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  bool operator<(const Box& aBox) const     // Less-than operator\n  { return volume() < aBox.volume(); }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_01/Ex13_01.cpp",
    "content": "// Implementing a less-than operator\nimport <iostream>;\nimport <vector>;\nimport box;\n\nint main()\n{\n  std::vector boxes {Box {2.0, 2.0, 3.0}, Box {1.0, 3.0, 2.0},\n                     Box {1.0, 2.0, 1.0}, Box {2.0, 3.0, 3.0}};\n  Box smallBox {boxes[0]};\n  for (const auto& box : boxes)\n  {\n    if (box < smallBox) smallBox = box;\n  }\n\n  std::cout << \"The smallest box has dimensions \"\n    << smallBox.getLength() << 'x'\n    << smallBox.getWidth()  << 'x'\n    << smallBox.getHeight() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_02/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  bool operator<(const Box& aBox) const    // Less-than operator\n  {\n    return volume() < aBox.volume();\n  }\n\n  bool operator<(double value) const;      // Compare Box volume < double value\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n// Compare the volume of a Box object with a constant\nbool Box::operator<(double value) const\n{\n  return volume() < value;\n}\n\n// Function comparing a constant with volume of a Box object\nexport bool operator<(double value, const Box& aBox)\n{\n  return value < aBox.volume();\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_02/Ex13_02.cpp",
    "content": "// Using the overloaded 'less-than' operators for Box ojects\nimport <iostream>;\nimport <vector>;\nimport <format>;\nimport box;\n\n// Display box dimensions\nvoid show(const Box& box)\n{\n  std::cout << std::format(\"Box {:g}x{:g}x{:g}\", \n                 box.getLength(), box.getWidth(), box.getHeight()) << std::endl;\n}\n\nint main()\n{\n  std::vector boxes {Box {2.0, 2.0, 3.0}, Box {1.0, 3.0, 2.0},\n                     Box {1.0, 2.0, 1.0}, Box {2.0, 3.0, 3.0}};\n  const double minVolume{6.0};\n  std::cout << \"Objects with volumes less than \" << minVolume << \" are:\\n\";\n  for (const auto& box : boxes)\n    if (box < minVolume) show(box);\n\n  std::cout << \"Objects with volumes greater than \" << minVolume << \" are:\\n\";\n  for (const auto& box : boxes)\n    if (minVolume < box) show(box);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_03/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const\n  {\n    return m_length == otherBox.m_length\n        && m_width  == otherBox.m_width\n        && m_height == otherBox.m_height; \n  }\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_03/Ex13_03.cpp",
    "content": "// Overloading <=> and == to fully support all comparison operators\nimport <iostream>;\nimport <format>;\nimport <string_view>;\nimport <vector>;\nimport box;\n\nvoid show(const Box& box)\n{\n  std::cout << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\", \n                  box.getLength(), box.getWidth(), box.getHeight());\n}\nvoid show(const Box& box1, std::string_view relationship, const Box& box2)\n{\n  show(box1); std::cout << relationship; show(box2); std::cout << std::endl;\n}\n\nint main()\n{\n  const std::vector boxes {Box {2.0, 1.5, 3.0}, Box {1.0, 3.0, 5.0},\n                           Box {1.0, 2.0, 1.0}, Box {2.0, 3.0, 2.0}};\n  const Box theBox {3.0, 1.0, 4.0};\n\n  for (const auto& box : boxes)\n    if (theBox > box) show(theBox, \" is greater than \", box);  // > works\n\n  std::cout << std::endl;\n\n  for (const auto& box : boxes)\n    if (theBox != box) show(theBox, \" is not equal to \", box); // != works\n\n  std::cout << std::endl;  \n\n  for (const auto& box : boxes)\n    if (6.0 <= box)                     // Yes, even double <= Box works!!\n      { std::cout << \"6 is less than or equal to \"; show(box); std::cout << std::endl; }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_03A/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_03A/Ex13_03A.cpp",
    "content": "// Defaulting the == operator\n\nimport <iostream>;\nimport <format>;\nimport <string_view>;\nimport <vector>;\nimport box;\n\nvoid show(const Box& box)\n{\n  std::cout << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\", \n                  box.getLength(), box.getWidth(), box.getHeight());\n}\nvoid show(const Box& box1, std::string_view relationship, const Box& box2)\n{\n  show(box1); std::cout << relationship; show(box2); std::cout << std::endl;\n}\n\nint main()\n{\n  const std::vector boxes {Box {2.0, 1.5, 3.0}, Box {1.0, 3.0, 5.0},\n                           Box {1.0, 2.0, 1.0}, Box {2.0, 3.0, 2.0}};\n  const Box theBox {3.0, 1.0, 4.0};\n\n  for (const auto& box : boxes)\n    if (theBox > box) show(theBox, \" is greater than \", box);  // > works\n\n  std::cout << std::endl;\n\n  for (const auto& box : boxes)\n    if (theBox != box) show(theBox, \" is not equal to \", box); // != works\n\n  std::cout << std::endl;  \n\n  for (const auto& box : boxes)\n    if (6.0 <= box)                     // Yes, even double <= Box works!!\n      { std::cout << \"6 is less than or equal to \"; show(box); std::cout << std::endl; }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_04/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\nimport <ostream>;  // For std::ostream\nimport <format>;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                             box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_04/Ex13_04.cpp",
    "content": "// Overloading the << operator\nimport <iostream>;\nimport <format>;\nimport <string_view>;\nimport <vector>;\nimport box;\n\nint main()\n{\n  const std::vector boxes {Box {2.0, 1.5, 3.0}, Box {1.0, 3.0, 5.0},\n                           Box {1.0, 2.0, 1.0}, Box {2.0, 3.0, 2.0}};\n  const Box theBox {3.0, 1.0, 4.0};\n\n  for (const auto& box : boxes)\n    if (theBox > box) \n      std::cout << theBox << \" is greater than \" << box << std::endl;  // > works\n\n  std::cout << std::endl;\n\n  for (const auto& box : boxes)\n    if (theBox != box) \n      std::cout << theBox << \" is not equal to \" << box << std::endl; // != works\n\n  std::cout << std::endl;  \n\n  for (const auto& box : boxes)\n    if (6.0 <= box)                     // Yes, even double <= Box works!!\n      std::cout << \"6 is less than or equal to \" << box << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_05/Box.cpp",
    "content": "module box;\n\nimport <format>;\nimport <algorithm>;    // For the min() and max() function templates\n\ndouble Box::volume() const\n{\n    return m_length * m_width * m_height;\n}\n\nBox Box::operator+(const Box& aBox) const\n{\n  // New object has larger length and width, and sum of heights\n  return Box{ std::max(m_length, aBox.m_length),\n              std::max(m_width, aBox.m_width),\n              m_height + aBox.m_height };\n}\n\nstd::partial_ordering Box::operator<=>(const Box& aBox) const\n{\n  return volume() <=> aBox.volume();\n}\n\nstd::partial_ordering Box::operator<=>(double value) const\n{\n  return volume() <=> value;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                          box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_05/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\nimport <ostream>;  // For std::ostream\n\nexport class Box\n{\npublic:\n  Box() = default;       // Default constructor\n  Box(double length, double width, double height)\n    : m_length{ std::max(length,width) }\n    , m_width { std::min(length,width) }\n    , m_height{ height } \n  {}\n\n  double volume() const; // Function to calculate the volume\n  \n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions that add full support for comparison operators\n  std::partial_ordering operator<=>(const Box& aBox) const;\n  std::partial_ordering operator<=>(double value) const;\n  bool operator==(const Box& aBox) const = default;\n\n  Box operator+(const Box& aBox) const;   // Function to add two Box objects\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Box& box);\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_05/Ex13_05.cpp",
    "content": "// Using the addition operator for Box objects\nimport <iostream>;\nimport <format>;\nimport <vector>;\nimport <random>;       // For random number generation\nimport <functional>;   // For std::bind()\nimport box;\n\n// See Chapter 12 for an explanation of this function\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 1.0, max }; // Generate in [1, max) interval\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\nint main()\n{\n  const double limit {99};       // Upper limit on Box dimensions\n  auto random { createUniformPseudoRandomNumberGenerator(limit) };\n\n  const size_t boxCount {20}; // Number of Box object to be created\n  std::vector<Box> boxes;     // Vector of Box objects\n\n  // Create 20 Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    boxes.push_back(Box{ random(), random(), random() });\n\n  size_t first {};            // Index of first Box object of pair\n  size_t second {1};          // Index of second Box object of pair\n  double minVolume {(boxes[first] + boxes[second]).volume()};\n\n  for (size_t i {}; i < boxCount - 1; ++i)\n  {  \n    for (size_t j {i + 1}; j < boxCount; j++)\n    {\n      if (boxes[i] + boxes[j] < minVolume)\n      {\n        first = i;\n        second = j;\n        minVolume = (boxes[i] + boxes[j]).volume();\n      }\n    }\n  }\n\n  std::cout << \"The two boxes that sum to the smallest volume are \"\n            << boxes[first] << \" and \" << boxes[second] << '\\n';\n  std::cout << std::format(\"The volume of the first box is {:.1f}\\n\",\n                            boxes[first].volume());\n  std::cout << std::format(\"The volume of the second box is {:.1f}\\n\",\n                            boxes[second].volume());\n  std::cout << \"The sum of these boxes is \" << (boxes[first] + boxes[second]) << '\\n';\n  std::cout << std::format(\"The volume of the sum is {:.1f}\", minVolume) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_06/Box.cpp",
    "content": "module;\n#include <cmath>    // For the min() and max() function templates\nmodule box;\n\nimport <format>;\n\ndouble Box::volume() const\n{\n    return m_length * m_width * m_height;\n}\n\n// Overloaded += operator\nBox& Box::operator+=(const Box& aBox)\n{\n  // New object has larger length and width, and sum of heights\n  m_length = std::max(m_length, aBox.m_length);\n  m_width = std::max(m_width, aBox.m_width);\n  m_height += aBox.m_height;\n  return *this;\n}\n\n// Function to add two Box objects\nBox Box::operator+(const Box& aBox) const\n{\n  Box copy{ *this };\n  copy += aBox;\n  return copy;\n}\n\nstd::partial_ordering Box::operator<=>(const Box& aBox) const\n{\n  return volume() <=> aBox.volume();\n}\n\nstd::partial_ordering Box::operator<=>(double value) const\n{\n  return volume() <=> value;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                          box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_06/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\nimport <ostream>;  // For std::ostream\n\nexport class Box\n{\npublic:\n  Box() = default;       // Default constructor\n  Box(double length, double width, double height)\n    : m_length{ std::max(length,width) }\n    , m_width { std::min(length,width) }\n    , m_height{ height } \n  {}\n\n  double volume() const; // Function to calculate the volume\n  \n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions that add full support for comparison operators\n  std::partial_ordering operator<=>(const Box& aBox) const;\n  std::partial_ordering operator<=>(double value) const;\n  bool operator==(const Box& aBox) const = default;\n\n  Box& operator+=(const Box& aBox);      // Function to add a Box objects\n  Box operator+(const Box& aBox) const; // Function to add two Box objects\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Box& box);\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_06/Ex13_06.cpp",
    "content": "// Using the addition operator for Box objects\nimport <iostream>;\nimport <format>;\nimport <vector>;\nimport <random>;       // For random number generation\nimport <functional>;   // For std::bind()\nimport box;\n\n// See Chapter 12 for an explanation of this function\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 1.0, max }; // Generate in [1, max) interval\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\nint main()\n{\n  const double limit {99};       // Upper limit on Box dimensions\n  auto random { createUniformPseudoRandomNumberGenerator(limit) };\n\n  const size_t boxCount {20}; // Number of Box object to be created\n  std::vector<Box> boxes;     // Vector of Box objects\n\n  // Create 20 Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    boxes.push_back(Box{ random(), random(), random() });\n\n  size_t first {};            // Index of first Box object of pair\n  size_t second {1};          // Index of second Box object of pair\n  double minVolume {(boxes[first] + boxes[second]).volume()};\n\n  for (size_t i {}; i < boxCount - 1; ++i)\n  {  \n    for (size_t j {i + 1}; j < boxCount; j++)\n    {\n      if (boxes[i] + boxes[j] < minVolume)\n      {\n        first = i;\n        second = j;\n        minVolume = (boxes[i] + boxes[j]).volume();\n      }\n    }\n  }\n\n  std::cout << \"The two boxes that sum to the smallest volume are \"\n            << boxes[first] << \" and \" << boxes[second] << '\\n';\n  std::cout << std::format(\"The volume of the first box is {:.1f}\\n\",\n                            boxes[first].volume());\n  std::cout << std::format(\"The volume of the second box is {:.1f}\\n\",\n                            boxes[second].volume());\n  std::cout << \"The sum of these boxes is \" << (boxes[first] + boxes[second]) << '\\n';\n  std::cout << std::format(\"The volume of the sum is {:.1f}\", minVolume) << std::endl;\n\n  Box sum{ 0, 0, 0 };            // Start from an empty Box\n  for (const auto& box : boxes)  // And then add all randomly generated Box objects\n    sum += box;\n\n  std::cout << \"The sum of \" << boxCount << \" random boxes is \" << sum << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_07/Ex13_07.cpp",
    "content": "// Implicit conversions reduce the number of operator functions\nimport <iostream>;\nimport integer;\n\nint main() \n{\n  const Integer i{1};\n  const Integer j{2};\n  const auto result = (i * 2 + 4 / j - 1) % j;\n  std::cout << result.getValue() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_07/Integer.cppm",
    "content": "export module integer;\n\nexport class Integer\n{\npublic:\n  Integer(int value = 0) : m_value{value} {}\n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\nprivate:\n  int m_value;\n};\n\nexport Integer operator+(const Integer& one, const Integer& other)\n{\n  return one.getValue() + other.getValue();\n}\nexport Integer operator-(const Integer& one, const Integer& other)\n{\n  return one.getValue() - other.getValue();\n}\nexport Integer operator*(const Integer& one, const Integer& other)\n{\n  return one.getValue() * other.getValue();\n}\nexport Integer operator/(const Integer& one, const Integer& other)\n{\n  return one.getValue() / other.getValue();\n}\nexport Integer operator%(const Integer& one, const Integer& other)\n{\n  return one.getValue() % other.getValue();\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_08/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\nimport <ostream>;  // For std::ostream\nimport <format>;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  Box operator~() const\n  {\n    return Box{m_width, m_length, m_height}; // Width and length are swapped\n  }\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                             box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_08/Ex13_08.cpp",
    "content": "// Overloading a unary \"rotate\" operator\nimport <iostream>;\nimport box;\n\nint main()\n{\n  Box someBox{ 1, 2, 3 };\n  std::cout << ~someBox << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_09/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\nimport <ostream>;  // For std::ostream\nimport <format>;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  Box& operator++();         // Prefix ++operator\n  const Box operator++(int); // Postfix operator++\n  Box& operator--();         // Prefix --operator\n  const Box operator--(int); // Postfix operator--\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\nBox& Box::operator++()   // Prefix ++operator\n{\n  ++m_length;\n  ++m_width;\n  ++m_height;\n  return *this;\n}\n\nconst Box Box::operator++(int)  // Postfix operator++\n{\n  auto copy{ *this };  // Create a copy of the current object\n  ++(*this);           // Increment the current object using the prefix operator...\n  return copy;         // Return the unincremented copy\n}\n\nBox& Box::operator--()   // Prefix --operator\n{\n  --m_length;\n  --m_width;\n  --m_height;\n  return *this;\n}\n\nconst Box Box::operator--(int)  // Postfix operator--\n{\n  auto copy{ *this };  // Create a copy of the current object\n  --(*this);           // Decrement the current object using the prefix operator...\n  return copy;         // Return copy of the original value\n}\n\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                             box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_09/Ex13_09.cpp",
    "content": "// Overloading pre- and postfix inrement and decrement operators\nimport <iostream>;\nimport box;\n\nint main()\n{\n  Box theBox{ 3.0, 1.0, 3.0 };\n\n  std::cout << \"Our test Box is \" << theBox << std::endl;\n\n  std::cout << \"Postfix increment evaluates to the original object: \"\n    << theBox++ << std::endl;\n\n  std::cout << \"After postfix increment: \" << theBox << std::endl;\n\n  std::cout << \"Prefix decrement evaluates to the decremented object: \"\n    << --theBox << std::endl;\n  std::cout << \"After prefix decrement: \" << theBox << std::endl;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_10/Box.cppm",
    "content": "export module box;\n\nimport <ostream>;\nimport <format>;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f},{:.1f},{:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_10/Ex13_10.cpp",
    "content": "// Using the subscript operator\nimport <iostream>;\nimport <memory>;\nimport <random>;       // For random number generation\nimport <functional>;   // For std::bind()\nimport truckload;\n\n// See Chapter 12 for an explanation of this function\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 1.0, max }; // Generate in [1, max) interval\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\nint main()\n{\n  const double limit {99.0};    // Upper limit on Box dimensions\n  auto random = createUniformPseudoRandomNumberGenerator(limit);\n\n  Truckload load;\n  const size_t boxCount {16};   // Number of Box object to be created\n\n  // Create boxCount Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    load.addBox(std::make_shared<Box>(random(), random(), random()));\n\n  std::cout << \"The boxes in the Truckload are:\\n\";\n  std::cout << load;\n\n  // Find the largest Box in the Truckload\n  double maxVolume {};\n  size_t maxIndex {};\n  size_t i {};\n  while (load[i])\n  {\n    if (load[i]->volume() > maxVolume)\n    {\n      maxIndex = i;\n      maxVolume = load[i]->volume();\n    }\n    ++i;\n  }\n\n  std::cout << \"\\nThe largest box is: \";\n  std::cout << *load[maxIndex] << std::endl;\n\n  load.removeBox(load[maxIndex]);\n  std::cout << \"\\nAfter deleting the largest box, the Truckload contains:\\n\";\n  std::cout << load;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_10/Truckload.cpp",
    "content": "module truckload;\n\nimport <iostream>;\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nSharedBox Truckload::operator[](size_t index) const\n{\n  size_t count{};             // Package count\n  for (Package* package{ m_head }; package; package = package->m_next)\n  {\n    if (count++ == index)      // Up to index yet?\n      return package->m_box;   // If so return the pointer to Box\n  }\n  return nullptr;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_10/Truckload.cppm",
    "content": "export module truckload;\n\nimport box;\n\nimport <memory>;\nimport <vector>;\nimport <ostream>;\n\nexport using SharedBox = std::shared_ptr<Box>;\n\nexport class Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox operator[](size_t index) const;   // Overloaded subscript operator\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Truckload& load);\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_11/Box.cppm",
    "content": "export module box;\n\nimport <ostream>;\nimport <format>;\nimport <algorithm>;    // For the std::min()/max() function templates\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f},{:.1f},{:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\n  Box operator+(const Box& aBox) const   // Function to add two Box objects\n  {\n    return Box{ std::max(m_length, aBox.m_length),\n                std::max(m_width, aBox.m_width),\n                m_height + aBox.m_height }; \n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_11/Ex13_11.cpp",
    "content": "// Modifying the result of an overloaded subscript operator\nimport <iostream>;\nimport <memory>;\nimport <random>;       // For random number generation\nimport <functional>;   // For std::bind()\nimport truckload;\n\n/*\n  Caution: in the text, we suggest to add \n    \n    static SharedBox nullBox{};\n  \n  to the Truckload class definition. This will not compile.\n  In-class definitions of non-const static members are only allowed\n  if you add the inline keyword, as we did in this solution.\n  See Chapter 12 for more explanation,\n  and for the alternative of defining the member out-of-class.\n*/\n\n// See Chapter 12 for an explanation of this function\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 1.0, max }; // Generate in [1, max) interval\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\nint main()\n{\n  const double limit {99.0};    // Upper limit on Box dimensions\n  auto random = createUniformPseudoRandomNumberGenerator(limit);\n\n  Truckload load;\n  const size_t boxCount {16};   // Number of Box object to be created\n\n  // Create boxCount Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    load.addBox(std::make_shared<Box>(random(), random(), random()));\n\n  std::cout << \"The boxes in the Truckload are:\\n\";\n  std::cout << load;\n\n  // Find the largest Box in the Truckload\n  double maxVolume {};\n  size_t maxIndex {};\n  size_t i {};\n  while (load[i])\n  {\n    if (load[i]->volume() > maxVolume)\n    {\n      maxIndex = i;\n      maxVolume = load[i]->volume();\n    }\n    ++i;\n  }\n\n  std::cout << \"\\nThe largest box is: \";\n  std::cout << *load[maxIndex] << std::endl;\n\n  load.removeBox(load[maxIndex]);\n  std::cout << \"\\nAfter deleting the largest box, the Truckload contains:\\n\";\n  std::cout << load;\n\n  load[0] = load[1];        // Copy 2nd element to the 1st\n  std::cout << \"\\nAfter copying the 2nd element to the 1st, the list contains:\\n\";\n  std::cout << load;\n\n  load[1] = std::make_shared<Box>(*load[2] + *load[3]);\n  std::cout << \"\\nAfter making the 2nd element a pointer to the 3rd plus 4th,\"\n                                                          \" the list contains:\\n\";\n  std::cout << load;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_11/Truckload.cpp",
    "content": "module truckload;\n\nimport <iostream>;\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nSharedBox& Truckload::operator[](size_t index) const\n{\n  size_t count{};             // Package count\n  for (Package* package{ m_head }; package; package = package->m_next)\n  {\n    if (count++ == index)      // Up to index yet?\n      return package->m_box;   // If so return the pointer to Box\n  }\n  return nullBox;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_11/Truckload.cppm",
    "content": "export module truckload;\n\nimport box;\n\nimport <memory>;\nimport <vector>;\nimport <ostream>;\n\nexport using SharedBox = std::shared_ptr<Box>;\n\nexport class Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox& operator[](size_t index) const;   // Overloaded subscript operator\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n\n  // Caution: inline is required to allow for this definition to appear in-class.\n  // In the text we forgot to add this. See Chapter 12 for more explanation,\n  // and for the alternative of defining the member out-of-class.\n  static inline SharedBox nullBox{}; // Pointer to nullptr\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Truckload& load);\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_12/Ex13_12.cpp",
    "content": "// Defining a copy assignment operator\nimport message;\nimport <iostream>;\n\nint main()\n{\n  Message beware{ \"Careful\" };\n  Message warning;\n  \n  warning = beware;    // Call assignment operator\n\n  std::cout << \"After assignment beware is: \" << beware.getText() << std::endl;\n  std::cout << \"After assignment warning is: \" << warning.getText() << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_12/Message.cpp",
    "content": "module;\n#include <cstring>  // For std::strlen() and std::strcpy()\nmodule message;\n\nMessage& Message::operator=(const Message& message)\n{\n  if (&message != this)\n  {\n    delete[] m_text;                                    // Delete the previous char array\n    m_text = new char[std::strlen(message.m_text) + 1]; // Replace it with a new array\n    std::strcpy(m_text, message.m_text);                // Copy the text (mind the order!)\n  }\n  return *this;      // Return the left operand\n}"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_12/Message.cppm",
    "content": "module;\n#include <cstring>  // For std::strlen() and std::strcpy()\nexport module message;\n\nexport class Message\n{\npublic:\n  explicit Message(const char* text = \"\")\n    : m_text(new char[std::strlen(text) + 1]) // Caution: include the null character!\n  {\n    std::strcpy(m_text, text);        // Mind the order: strcpy(destination, source)!\n  }\n  ~Message() { delete[] m_text; }\n\n  Message& operator=(const Message& message); // Assignment operator\n\n  const char* getText() const { return m_text; }\n\nprivate:\n  char* m_text;\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_12A/Ex13_12A.cpp",
    "content": "// Always define both copy members together\n// (see also 'Rule of Five' in Chapter 18!)\nimport message;\nimport <iostream>;\n\nint main()\n{\n  Message beware{ \"Careful\" };\n  Message warning;\n  \n  warning = beware;    // Call assignment operator\n\n  Message caution{ warning };\n\n  std::cout << \"After assignment beware is: \" << beware.getText() << std::endl;\n  std::cout << \"After assignment warning is: \" << warning.getText() << std::endl;\n  std::cout << \"As a copy of warning, caution is: \" << caution.getText() << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_12A/Message.cpp",
    "content": "module;\n#include <cstring>  // For std::strlen() and std::strcpy()\nmodule message;\n\nMessage::Message(const Message& message)\n  : Message{ message.m_text }  // By far easiest and preferred option: forward to existing constructor!\n{\n}\n\nMessage& Message::operator=(const Message& message)\n{\n  if (&message != this)\n  {\n    delete[] m_text;                                    // Delete the previous char array\n    m_text = new char[std::strlen(message.m_text) + 1]; // Replace it with a new array\n    std::strcpy(m_text, message.m_text);                // Copy the text (mind the order!)\n  }\n  return *this;      // Return the left operand\n}"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_12A/Message.cppm",
    "content": "module;\n#include <cstring>  // For std::strlen() and std::strcpy()\nexport module message;\n\nexport class Message\n{\npublic:\n  explicit Message(const char* text = \"\")\n    : m_text(new char[std::strlen(text) + 1]) // Caution: include the null character!\n  {\n    std::strcpy(m_text, text);        // Mind the order: strcpy(destination, source)!\n  }\n  ~Message() { delete[] m_text; }\n\n  Message(const Message& message);            // Copy constructor\n  Message& operator=(const Message& message); // Copy assignment operator\n\n  const char* getText() const { return m_text; }\n\nprivate:\n  char* m_text;\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_12B/Ex13_12B.cpp",
    "content": "// Sneak preview: use copy-and-swap for copy assignment operator\n// (see Chapter 17 for details, including the noexcept keyword...)\n// In short, you eliminate duplicating the logic of copying an object\n// by expressing the copy assignment operator in terms of the copy constructor.\n// Less duplication means less room for error, less maintenance overhead, etc.\n// Note: this solution is hinted at in a Note in the text, but not explicitly named.\nimport message;\nimport <iostream>;\n\nint main()\n{\n  Message beware{ \"Careful\" };\n  Message warning;\n  \n  warning = beware;    // Call assignment operator\n\n  Message caution{ warning };\n\n  std::cout << \"After assignment beware is: \" << beware.getText() << std::endl;\n  std::cout << \"After assignment warning is: \" << warning.getText() << std::endl;\n  std::cout << \"As a copy of warning, caution is: \" << caution.getText() << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_12B/Message.cpp",
    "content": "module message;\n\nimport <utility>;    // For std::swap()\n\nMessage::Message(const Message& message)\n  : Message{ message.m_text }  // By far easiest and preferred option: forward to existing constructor!\n{\n}\n\nMessage& Message::operator=(const Message& message)\n{\n  // Note: self-assignment test no longer required (or even recommended)\n  auto copy{ message }; // Copy-...\n  swap(copy);           // ...and-swap!\n  return *this;         // Always return reference to left operand\n}\n\nvoid Message::swap(Message& other) noexcept\n{\n  std::swap(m_text, other.m_text);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 13/Ex13_12B/Message.cppm",
    "content": "module;\n#include <cstring>  // For std::strlen() and std::strcpy()\nexport module message;\n\nexport class Message\n{\npublic:\n  explicit Message(const char* text = \"\")\n    : m_text(new char[std::strlen(text) + 1]) // Caution: include the null character!\n  {\n    std::strcpy(m_text, text);        // Mind the order: strcpy(destination, source)!\n  }\n  ~Message() { delete[] m_text; }\n\n  Message(const Message& message);            // Copy constructor \n  Message& operator=(const Message& message); // Copy assignment operator\n\n  void swap(Message& other) noexcept;\n\n  const char* getText() const { return m_text; }\n\nprivate:\n  char* m_text;\n};\n\nexport void swap(Message& one, Message& other) noexcept\n{\n  return one.swap(other);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_01/Box.cppm",
    "content": "// Box.cppm - defines Box class\nexport module box;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height)\n    : m_length{ length }, m_width{ width }, m_height{ height }\n  {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprivate:\n  double m_length {1.0};\n  double m_width  {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_01/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class with the Box class as base\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport box;\n\nexport class Carton : public Box\n{\npublic:\n  explicit Carton(std::string_view material = \"Cardboard\")  // Constructor\n    : m_material{material} {}\n\nprivate:\n  std::string m_material;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_01/Ex14_01.cpp",
    "content": "// Defining and using a derived class\nimport <iostream>;\nimport box;                 // For the Box class\nimport carton;              // For the Carton class\n\nint main()\n{\n  // Create a Box object and two Carton objects\n  Box box {40.0, 30.0, 20.0};\n  Carton carton;\n  Carton chocolateCarton {\"Solid bleached board\"};  // Good old SBB\n  // Check them out - sizes first of all\n  std::cout << \"box occupies \" << sizeof box << \" bytes\" << std::endl;\n  std::cout << \"carton occupies \" << sizeof carton << \" bytes\" << std::endl;\n  std::cout << \"candyCarton occupies \" << sizeof chocolateCarton << \" bytes\" << std::endl;\n\n  // Now volumes...\n  std::cout << \"box volume is \" << box.volume() << std::endl;\n  std::cout << \"carton volume is \" << carton.volume() << std::endl;\n  std::cout << \"chocolateCarton volume is \" << chocolateCarton.volume() << std::endl;\n\n  std::cout << \"chocolateCarton length is \" << chocolateCarton.getLength() << std::endl;\n\n  // Uncomment any of the following for an error...\n  // box.m_length = 10.0;\n  // chocolateCarton.m_length = 10.0;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_01A/Box.cppm",
    "content": "// Box.cppm - defines Box class\nexport module box;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height)\n      : m_length{ length }, m_width{ width }, m_height{ height }\n  {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprivate:\n  double m_length {1.0};\n  double m_width  {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_01A/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class with the Box class as private base\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport box;\n\nexport class Carton : private Box\n{\npublic:\n  explicit Carton(std::string_view mat = \"Cardboard\") : m_material {mat} {}\n  using Box::volume; // Inherit as public\n\nprivate:\n  std::string m_material;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_01A/Ex14_01A.cpp",
    "content": "// Changing the access specification of inherited members using using\nimport <iostream>;\nimport box;                 // For the Box class\nimport carton;              // For the Carton class\n\nint main()\n{\n  // Create a Box object and two Carton objects\n  Box box {40.0, 30.0, 20.0};\n  Carton carton;\n  Carton chocolateCarton {\"Solid bleached board\"};  // Good old SBB\n  // Check them out - sizes first of all\n  std::cout << \"box occupies \" << sizeof box << \" bytes\" << std::endl;\n  std::cout << \"carton occupies \" << sizeof carton << \" bytes\" << std::endl;\n  std::cout << \"candyCarton occupies \" << sizeof chocolateCarton << \" bytes\" << std::endl;\n\n  // Now volumes...\n  std::cout << \"box volume is \" << box.volume() << std::endl;\n  std::cout << \"carton volume is \" << carton.volume() << std::endl;\n  std::cout << \"chocolateCarton volume is \" << chocolateCarton.volume() << std::endl;\n\n  // Uncomment any of the following for an error...\n  // std::cout << \"chocolateCarton length is \" << chocolateCarton.getLength() << std::endl;\n  //\n  // box.m_length = 10.0;\n  // chocolateCarton.m_length = 10.0;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_02/Box.cppm",
    "content": "// Box.cppm - defines Box class\nexport module box;\n\nimport <iostream>;     // For standard streams\nimport <format>;       // For string formatting\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_02/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class with the Box class as base\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport box;\n\nexport class Carton : public Box\n{\npublic:\n  Carton() { std::cout << \"Carton() called.\\n\"; }\n\n  explicit Carton(std::string_view material) : m_material{material}\n  { std::cout << \"Carton(string_view) called.\\n\"; }\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n/*\n  // This constructor won't compile!\n  Carton::Carton(double l, double w, double h, std::string_view material)\n    : m_length{ l }, m_width{ w }, m_height{ h }, m_material{ material }\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }\n*/\n/*\n  // Constructor that will compile!\n  Carton::Carton(double l, double w, double h, std::string_view material)\n    : m_material{material}\n  {\n    m_length = l;  // These should normally be initialized in a base class constructor...\n    m_width = w;\n    m_height = h;\n    std::cout << \"Carton(double,double,double,string_view) called.\\n\";\n  }\n*/\n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_02/Ex14_02.cpp",
    "content": "// Calling base class constructors in a derived class constructor\nimport <iostream>;\nimport carton;       // For the Carton class\n\nint main()\n{\n  // Create four Carton objects\n  Carton carton1;                             std::cout << std::endl;\n  Carton carton2 {\"White-lined chipboard\"};   std::cout << std::endl;\n  Carton carton3 {4.0, 5.0, 6.0, \"PET\"};      std::cout << std::endl;\n  Carton carton4 {2.0, \"Folding boxboard\"};   std::cout << std::endl;\n\n  std::cout << \"carton1 volume is \" << carton1.volume() << std::endl;\n  std::cout << \"carton2 volume is \" << carton2.volume() << std::endl;\n  std::cout << \"carton3 volume is \" << carton3.volume() << std::endl;\n  std::cout << \"carton4 volume is \" << carton4.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_03/Box.cppm",
    "content": "// Box.cppm - defines Box class (with additional copy constuctor)\nexport module box;\n\nimport <iostream>;     // For standard streams\nimport <format>;       // For string formatting\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  // Copy constructor\n  Box(const Box& b) : m_length{ b.m_length }, m_width{ b.m_width }, m_height{ b.m_height }\n  { std::cout << \"Box copy constructor\" << std::endl; }\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_03/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class (with additional copy constuctor)\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport box;\n\nexport class Carton : public Box\n{\npublic:\n  Carton() { std::cout << \"Carton() called.\\n\"; }\n\n  explicit Carton(std::string_view material) : m_material{material}\n  { std::cout << \"Carton(string_view) called.\\n\"; }\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n\n  // Copy constructor (wrong)\n  Carton(const Carton& carton) : m_material {carton.m_material}\n  { std::cout << \"Carton copy constructor\" << std::endl; }\n/*\n  // Copy constructor (correct)\n  Carton(const Carton& carton) : Box{ carton }, m_material{ carton.m_material }\n  { std::cout << \"Carton copy constructor\" << std::endl; }\n*/\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_03/Ex14_03.cpp",
    "content": "// Using a derived class copy constructor\nimport <iostream>;\nimport carton;\n\nint main()\n{\n  // Declare and initialize a Carton object\n  Carton carton{ 20.0, 30.0, 40.0, \"Expanded polystyrene\" };\n  std::cout << std::endl;\n\n  Carton cartonCopy{ carton };  // Use copy constructor\n  std::cout << std::endl;\n\n  std::cout << \"Volume of carton is \" << carton.volume() << std::endl\n            << \"Volume of cartonCopy is \" << cartonCopy.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_04/Box.cppm",
    "content": "// Box.cppm - defines Box class\nexport module box;\n\nimport <iostream>;     // For standard streams\nimport <format>;       // For string formatting\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_04/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class with the Box class as base\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport box;\n\nexport class Carton : public Box\n{\npublic:\n  Carton() = default;\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_04/Ex14_04.cpp",
    "content": "// Defaulting the default constructor in a derived class (working version)\nimport <iostream>;\nimport box;                 // For the Box class\nimport carton;              // For the Carton class\n\nint main()\n{\n  // Create three Carton objects\n  Carton carton1;                             std::cout << std::endl;\n  Carton carton2 {4.0, 5.0, 6.0, \"PET\"};      std::cout << std::endl;\n  Carton carton3 {2.0, \"Folding boxboard\"};   std::cout << std::endl;\n\n  std::cout << \"carton1 volume is \" << carton1.volume() << std::endl;\n  std::cout << \"carton2 volume is \" << carton2.volume() << std::endl;\n  std::cout << \"carton3 volume is \" << carton3.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_04A/Box.cppm",
    "content": "// Box.cppm - defines Box class\nexport module box;\n\nimport <iostream>;     // For standard streams\nimport <format>;       // For string formatting\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n//  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor removed!\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_04A/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class with the Box class as base\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport box;\n\nexport class Carton : public Box\n{\npublic:\n  Carton() = default;\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_04A/Ex14_04A.cpp",
    "content": "// Defaulting the default constructor in a derived class\n// without a default constructor in the base class\n// is equivalent to deleting the default constructor.\nimport <iostream>;\nimport box;                 // For the Box class\nimport carton;              // For the Carton class\n\n/* Note: this example will fail to compile! */\n\nint main()\n{\n  // Create three Carton objects\n  Carton carton1;                             std::cout << std::endl;\n  Carton carton2 {4.0, 5.0, 6.0, \"PET\"};      std::cout << std::endl;\n  Carton carton3 {2.0, \"Folding boxboard\"};   std::cout << std::endl;\n\n  std::cout << \"carton1 volume is \" << carton1.volume() << std::endl;\n  std::cout << \"carton2 volume is \" << carton2.volume() << std::endl;\n  std::cout << \"carton3 volume is \" << carton3.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_04B/Box.cppm",
    "content": "// Box.cppm - defines Box class\nexport module box;\n\nimport <iostream>;     // For standard streams\nimport <format>;       // For string formatting\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() = delete;   // Default constructor explicitly deleted\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_04B/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class with the Box class as base\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport box;\n\nexport class Carton : public Box\n{\npublic:\n  Carton() = default;\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_04B/Ex14_04B.cpp",
    "content": "// Defaulting the default constructor in a derived class\n// with a deleted default constructor in the base class\n// is equivalent to deleting the default constructor.\nimport <iostream>;\nimport box;                 // For the Box class\nimport carton;              // For the Carton class\n\n/* Note: this example will fail to compile! */\n\nint main()\n{\n  // Create three Carton objects\n  Carton carton1;                             std::cout << std::endl;\n  Carton carton2 {4.0, 5.0, 6.0, \"PET\"};      std::cout << std::endl;\n  Carton carton3 {2.0, \"Folding boxboard\"};   std::cout << std::endl;\n\n  std::cout << \"carton1 volume is \" << carton1.volume() << std::endl;\n  std::cout << \"carton2 volume is \" << carton2.volume() << std::endl;\n  std::cout << \"carton3 volume is \" << carton3.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_04C/Box.cppm",
    "content": "// Box.cppm - defines Box class\nexport module box;\n\nimport <iostream>;     // For standard streams\nimport <format>;       // For string formatting\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprivate:\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor (made private)\n\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_04C/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class with the Box class as base\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport box;\n\nexport class Carton : public Box\n{\npublic:\n  Carton() = default;\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_04C/Ex14_04C.cpp",
    "content": "// Defaulting the default constructor in a derived class\n// with a private constructor in the base class\n// is equivalent to deleting the default constructor.\nimport <iostream>;\nimport box;                 // For the Box class\nimport carton;              // For the Carton class\n\n/* Note: this example will fail to compile! */\n\nint main()\n{\n  // Create three Carton objects\n  Carton carton1;                             std::cout << std::endl;\n  Carton carton2 {4.0, 5.0, 6.0, \"PET\"};      std::cout << std::endl;\n  Carton carton3 {2.0, \"Folding boxboard\"};   std::cout << std::endl;\n\n  std::cout << \"carton1 volume is \" << carton1.volume() << std::endl;\n  std::cout << \"carton2 volume is \" << carton2.volume() << std::endl;\n  std::cout << \"carton3 volume is \" << carton3.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_05/Box.cppm",
    "content": "// Box.cppm - defines Box class\nexport module box;\n\nimport <iostream>;     // For standard streams\nimport <format>;       // For string formatting\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_05/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class with the Box class as base\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport box;\n\nexport class Carton : public Box\n{\n  using Box::Box;  // Inherit Box class constructors \n\npublic:\n  Carton() = default;   // Required by Visual C++\n  Carton(double length, double width, double height, std::string_view mat)\n     : Box{length, width, height}, m_material{mat}\n     { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }\n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_05/Ex14_05.cpp",
    "content": "// Inheriting constructors\nimport <iostream>;\nimport carton;       // For the Carton class\n\nint main()\n{\n  Carton cart;                                    // Calls inherited default constructor\n  Carton cube { 4.0 };                                 // Calls inherited constructor\n  Carton copy { cube };                                // Calls default copy constructor\n  Carton carton {1.0, 2.0, 3.0};                       // Calls inherited constructor\n  Carton cerealCarton (50.0, 30.0, 20.0, \"Chipboard\"); // Calls Carton class constructor\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_06/Box.cppm",
    "content": "// Box.cppm - defines Box class\nexport module box;\n\nimport <iostream>;     // For standard streams\nimport <format>;       // For string formatting\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  // Copy constructor\n  Box(const Box& b) : m_length{ b.m_length }, m_width{ b.m_width }, m_height{ b.m_height }\n  { std::cout << \"Box copy constructor\" << std::endl; }\n\n  // Destructor\n  ~Box() { std::cout << \"Box destructor\" << std::endl; }\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_06/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport box;\n\nexport class Carton : public Box\n{\npublic:\n  Carton() { std::cout << \"Carton() called.\\n\"; }\n\n  explicit Carton(std::string_view material) : m_material{material}\n  { std::cout << \"Carton(string_view) called.\\n\"; }\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n\n  // Copy constructor (correct)\n  Carton(const Carton& carton) : Box{ carton }, m_material{ carton.m_material }\n  { std::cout << \"Carton copy constructor\" << std::endl; }\n\n  // Destructor\n  ~Carton() { std::cout << \"Carton destructor. Material = \" << m_material << std::endl; }\n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_06/Ex14_06.cpp",
    "content": "// Destructors in a class hierarchy\nimport <iostream>;\nimport carton;   // For the Carton class\n\nint main()\n{\n  Carton carton;\n  Carton candyCarton{50.0, 30.0, 20.0, \"SBB\"};\t// Solid bleached board\n\n  std::cout << \"carton volume is \" << carton.volume() << std::endl;\n  std::cout << \"candyCarton volume is \" << candyCarton.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07/Box.cppm",
    "content": "// Box.cppm - defines Box class\nexport module box;\n\nimport <iostream>;     // For standard streams\nimport <format>;       // For string formatting\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class with the Box class as base\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport box;\n\nexport class Carton : public Box\n{\npublic:\n  Carton() { std::cout << \"Carton() called.\\n\"; }\n\n  explicit Carton(std::string_view material) : m_material{material}\n  { std::cout << \"Carton(string_view) called.\\n\"; }\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; } \n\n  // One new constructor\n  Carton(double l, double w, double h, std::string_view m, double density, double thickness)\n    : Carton{l, w, h, m} \n  {\n    m_thickness = thickness; m_density = density;\n    std::cout << \"Carton(double,double,double,string_view,double,double) called.\\n\";\n  }\n\n  // Copy constructor\n  Carton(const Carton& carton) : Box{carton}, m_material{carton.m_material},\n     m_thickness{carton.m_thickness}, m_density{carton.m_density}\n  {\n    std::cout << \"Carton copy constructor\" << std::endl;\n  }\n\n  // Destructor\n  ~Carton()\n  {\n    std::cout << \"Carton destructor. Material = \" << m_material << std::endl;\n  }\n\n  double getWeight() const\n  {\n    return 2.0 * (m_length * m_width + m_width * m_height + m_height * m_length) \n               * m_thickness * m_density;\n  }\n\nprivate:\n  std::string m_material {\"Cardboard\"};\n  double m_thickness {0.125};   // Material thickness in inch\n  double m_density {0.2};       // Material density in pounds/cubic inch\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07/CerealPack.cppm",
    "content": "// Cerealpack.cppm - Class defining a carton of cereal\nexport module cereal;\nimport <iostream>;\nimport carton;\nimport food;\n\nexport class CerealPack : public Carton, public FoodContainer\n{\npublic:\n  CerealPack(double length, double width, double height, std::string_view cerealType)\n    : Carton {length, width, height, \"Chipboard\"}, FoodContainer {cerealType}\n  {\n    std::cout << \"CerealPack constructor\" << std::endl;\n    FoodContainer::volume = 0.9 * Carton::volume();   // Set food container's volume\n  }\n\n  ~CerealPack()\n  {\n    std::cout << \"CerealPack destructor\" << std::endl;\n  }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07/Ex14_07.cpp",
    "content": "// Ex14_07 - doesn't compile!\n// Using multiple inheritance can lead to ambiguity if members with \n// the same name are inherited from different base classes.\nimport <iostream>;\nimport cereal;             // For the CerealPack class\n\nint main()\n{\n  CerealPack cornflakes{ 8.0, 3.0, 10.0, \"Cornflakes\" };\n\n  std::cout << \"cornflakes volume is \" << cornflakes.volume() << std::endl\n            << \"cornflakes weight is \" << cornflakes.getWeight() << std::endl;\n/*\n  // Here is one way to make this work (see Ex14_07A and B for alternatives)\n  std::cout << \"cornflakes volume is \" << cornflakes.Carton::volume() << std::endl\n          << \"cornflakes weight is \" << cornflakes.FoodContainer::getWeight() \n          << std::endl;\n*/\n}"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07/FoodContainer.cppm",
    "content": "export module food;\n\nimport <iostream>;\nimport <string>;\nimport <string_view>;\n\nexport class FoodContainer\n{\npublic:\n  FoodContainer() { std::cout << \"FoodContainer() called.\\n\"; }\n\n  FoodContainer(std::string_view name) : name {name}\n  { std::cout << \"FoodContainer(string_view) called.\\n\"; }\n\n  FoodContainer(std::string_view name, double density, double volume)\n    : name {name}, density {density}, volume {volume}\n  { std::cout << \"FoodContainer(string_view,double,double) called.\\n\"; }\n\n  ~FoodContainer() { std::cout << \"FoodContainer destructor\" << std::endl; }\n\n  double getWeight() const { return volume * density; }\n\nprotected:  // Protected to make initialization in CerealPack constructor work (book says private)\n  std::string name {\"cereal\"};  // Food type\n  double volume {};             // Cubic inches\n  double density {0.03};        // Pounds per cubic inch\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07A/Box.cppm",
    "content": "// Box.cppm - defines Box class\nexport module box;\n\nimport <iostream>;     // For standard streams\nimport <format>;       // For string formatting\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07A/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class with the Box class as base\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport box;\n\nexport class Carton : public Box\n{\npublic:\n  Carton() { std::cout << \"Carton() called.\\n\"; }\n\n  explicit Carton(std::string_view material) : m_material{material}\n  { std::cout << \"Carton(string_view) called.\\n\"; }\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; } \n\n  // One new constructor\n  Carton(double l, double w, double h, std::string_view m, double density, double thickness)\n    : Carton{l, w, h, m} \n  {\n    m_thickness = thickness; m_density = density;\n    std::cout << \"Carton(double,double,double,string_view,double,double) called.\\n\";\n  }\n\n  // Copy constructor\n  Carton(const Carton& carton) : Box{carton}, m_material{carton.m_material},\n     m_thickness{carton.m_thickness}, m_density{carton.m_density}\n  {\n    std::cout << \"Carton copy constructor\" << std::endl;\n  }\n\n  // Destructor\n  ~Carton()\n  {\n    std::cout << \"Carton destructor. Material = \" << m_material << std::endl;\n  }\n\n  double getWeight() const\n  {\n    return 2.0 * (m_length * m_width + m_width * m_height + m_height * m_length) \n               * m_thickness * m_density;\n  }\n\nprivate:\n  std::string m_material {\"Cardboard\"};\n  double m_thickness {0.125};   // Material thickness in inch\n  double m_density {0.2};       // Material density in pounds/cubic inch\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07A/CerealPack.cppm",
    "content": "// Cerealpack.cppm - Class defining a carton of cereal\nexport module cereal;\nimport <iostream>;\nimport carton;\nimport food;\n\nexport class CerealPack : public Carton, public FoodContainer\n{\npublic:\n  CerealPack(double length, double width, double height, std::string_view cerealType)\n    : Carton {length, width, height, \"Chipboard\"}, FoodContainer {cerealType}\n  {\n    std::cout << \"CerealPack constructor\" << std::endl;\n    FoodContainer::volume = 0.9 * Carton::volume();   // Set food container's volume\n  }\n\n  ~CerealPack()\n  {\n    std::cout << \"CerealPack destructor\" << std::endl;\n  }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07A/Ex14_07A.cpp",
    "content": "// Ex14_07A - Disambiguating ambiguous member inheritance through casting\nimport <iostream>;\nimport cereal;             // For the CerealPack class\n\nint main()\n{\n  CerealPack cornflakes{ 8.0, 3.0, 10.0, \"Cornflakes\" };\n\n std::cout << \"cornflakes volume is \" << static_cast<Carton&>(cornflakes).volume()\n    << std::endl         \n    << \"cornflakes weight is \" << static_cast<FoodContainer&>(cornflakes).getWeight()\n    << std::endl;\n /*\n  // Alternate solution by explicitly qualifying the base class name (see also Ex14_07)\n  std::cout << \"cornflakes volume is \" << cornflakes.Carton::volume() << std::endl\n          << \"cornflakes weight is \" << cornflakes.FoodContainer::getWeight() \n          << std::endl;\n*/\n}"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07A/FoodContainer.cppm",
    "content": "export module food;\n\nimport <iostream>;\nimport <string>;\nimport <string_view>;\n\nexport class FoodContainer\n{\npublic:\n  FoodContainer() { std::cout << \"FoodContainer() called.\\n\"; }\n\n  FoodContainer(std::string_view name) : name {name}\n  { std::cout << \"FoodContainer(string_view) called.\\n\"; }\n\n  FoodContainer(std::string_view name, double density, double volume)\n    : name {name}, density {density}, volume {volume}\n  { std::cout << \"FoodContainer(string_view,double,double) called.\\n\"; }\n\n  ~FoodContainer() { std::cout << \"FoodContainer destructor\" << std::endl; }\n\n  double getWeight() const { return volume * density; }\n\nprotected:  // Protected to make initialization in CerealPack constructor work (book says private)\n  std::string name {\"cereal\"};  // Food type\n  double volume {};             // Cubic inches\n  double density {0.03};        // Pounds per cubic inch\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07B/Box.cppm",
    "content": "// Box.cppm - defines Box class\nexport module box;\n\nimport <iostream>;     // For standard streams\nimport <format>;       // For string formatting\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07B/Carton.cppm",
    "content": "// Carton.cppm - defines the Carton class with the Box class as base\nexport module carton;\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport box;\n\nexport class Carton : public Box\n{\npublic:\n  Carton() { std::cout << \"Carton() called.\\n\"; }\n\n  explicit Carton(std::string_view material) : m_material{material}\n  { std::cout << \"Carton(string_view) called.\\n\"; }\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; } \n\n  // One new constructor\n  Carton(double l, double w, double h, std::string_view m, double density, double thickness)\n    : Carton{l, w, h, m} \n  {\n    m_thickness = thickness; m_density = density;\n    std::cout << \"Carton(double,double,double,string_view,double,double) called.\\n\";\n  }\n\n  // Copy constructor\n  Carton(const Carton& carton) : Box{carton}, m_material{carton.m_material},\n     m_thickness{carton.m_thickness}, m_density{carton.m_density}\n  {\n    std::cout << \"Carton copy constructor\" << std::endl;\n  }\n\n  // Destructor\n  ~Carton()\n  {\n    std::cout << \"Carton destructor. Material = \" << m_material << std::endl;\n  }\n\n  double getWeight() const\n  {\n    return 2.0 * (m_length * m_width + m_width * m_height + m_height * m_length) \n               * m_thickness * m_density;\n  }\n\nprivate:\n  std::string m_material {\"Cardboard\"};\n  double m_thickness {0.125};   // Material thickness in inch\n  double m_density {0.2};       // Material density in pounds/cubic inch\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07B/CerealPack.cppm",
    "content": "// Cerealpack.cppm - Class defining a carton of cereal\nexport module cereal;\nimport <iostream>;\nimport carton;\nimport food;\n\nexport class CerealPack : public Carton, public FoodContainer\n{\npublic:\n  CerealPack(double length, double width, double height, std::string_view cerealType)\n    : Carton {length, width, height, \"Chipboard\"}, FoodContainer {cerealType}\n  {\n    std::cout << \"CerealPack constructor\" << std::endl;\n    FoodContainer::volume = 0.9 * Carton::volume();   // Set food container's volume\n  }\n\n  ~CerealPack()\n  {\n    std::cout << \"CerealPack destructor\" << std::endl;\n  }\n\n  using Carton::volume;\n  using FoodContainer::getWeight;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07B/Ex14_07B.cpp",
    "content": "// Ex14_07B - Disambiguating ambiguous member through \n// using declarations in the derived class (CerealPack)\nimport <iostream>;\nimport cereal;          // For the CerealPack class\n\nint main()\n{\n  CerealPack cornflakes{ 8.0, 3.0, 10.0, \"Cornflakes\" };\n\n  std::cout << \"cornflakes volume is \" << cornflakes.volume() << std::endl\n            << \"cornflakes weight is \" << cornflakes.getWeight() << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 14/Ex14_07B/FoodContainer.cppm",
    "content": "export module food;\n\nimport <iostream>;\nimport <string>;\nimport <string_view>;\n\nexport class FoodContainer\n{\npublic:\n  FoodContainer() { std::cout << \"FoodContainer() called.\\n\"; }\n\n  FoodContainer(std::string_view name) : name {name}\n  { std::cout << \"FoodContainer(string_view) called.\\n\"; }\n\n  FoodContainer(std::string_view name, double density, double volume)\n    : name {name}, density {density}, volume {volume}\n  { std::cout << \"FoodContainer(string_view,double,double) called.\\n\"; }\n\n  ~FoodContainer() { std::cout << \"FoodContainer destructor\" << std::endl; }\n\n  double getWeight() const { return volume * density; }\n\nprotected:  // Protected to make initialization in CerealPack constructor work (book says private)\n  std::string name {\"cereal\"};  // Food type\n  double volume {};             // Cubic inches\n  double density {0.03};        // Pounds per cubic inch\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_01/Box.cppm",
    "content": "export module boxes:box;\n\nimport <iostream>;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_01/Boxes.cppm",
    "content": "// Boxes.cppm: primary module interface file\nexport module boxes;\n\nexport import :box;           // Export all partitions\nexport import :tough_pack;\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_01/Ex15_01.cpp",
    "content": "// Behavior of inherited functions in a derived class\nimport boxes;\n\nint main()\n{\n  Box box {20.0, 30.0, 40.0};            // Create a box\n  ToughPack hardcase {20.0, 30.0, 40.0}; // Create a tough pack - same size\n\n  box.showVolume();      // Display volume of base box (calls volume() for box)\n  hardcase.showVolume(); // Display volume of derived box (call volume() for hardcase)\n\n  //std::cout << \"hardcase volume is \" << hardcase.volume() << std::endl;\n  //Box* box_pointer{ &hardcase };\n  //std::cout << \"hardcase volume through a Box* pointer is \"\n  //          << box_pointer->volume() << std::endl;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_01/ToughPack.cppm",
    "content": "export module boxes:tough_pack;\n\nimport :box;\n\nexport class ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const { return 0.85 * m_length * m_width * m_height; }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_02/Box.cppm",
    "content": "export module boxes:box;\n\nimport <iostream>;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_02/Boxes.cppm",
    "content": "// Boxes.cppm: primary module interface file\nexport module boxes;\n\nexport import :box;           // Export all partitions\nexport import :tough_pack;\nexport import :carton;\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_02/Carton.cppm",
    "content": "export module boxes:carton;\nimport <algorithm>;    // For std::max()\nimport <string>;\nimport <string_view>;\nimport :box;\n\nexport class Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_02/Ex15_02.cpp",
    "content": "// Using virtual functions\nimport <iostream>;\nimport boxes;\n\nint main()\n{\n  Box box {20.0, 30.0, 40.0};\n  ToughPack hardcase {20.0, 30.0, 40.0};        // A derived box - same size\n  Carton carton {20.0, 30.0, 40.0, \"Plastic\"};  // A different derived box\n\n  box.showVolume();        // Volume of Box\n  hardcase.showVolume();   // Volume of ToughPack\n  carton.showVolume();     // Volume of Carton\n\n  // Now using a base pointer...\n  Box* base {&box};        // Points to type Box\n  std::cout << \"\\nbox volume through base pointer is \" << base->volume() << std::endl;\n  base ->showVolume();\n\n  base = &hardcase;        // Points to type ToughPack\n  std::cout << \"hardcase volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n\n  base = &carton;          // Points to type Carton\n  std::cout << \"carton volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_02/ToughPack.cppm",
    "content": "export module boxes:tough_pack;\n\nimport :box;\n\nexport class ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const { return 0.85 * m_length * m_width * m_height; }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_03/Box.cppm",
    "content": "export module boxes:box;\n\nimport <iostream>;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_03/Boxes.cppm",
    "content": "// Boxes.cppm: primary module interface file\nexport module boxes;\n\nexport import :box;           // Export all partitions\nexport import :tough_pack;\nexport import :carton;"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_03/Carton.cppm",
    "content": "export module boxes:carton;\nimport <algorithm>;    // For std::max()\nimport <string>;\nimport <string_view>;\nimport :box;\n\nexport class Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_03/Ex15_03.cpp",
    "content": "// Access specifiers and virtual functions\nimport <iostream>;\nimport boxes;\n\nint main()\n{\n  Box box {20.0, 30.0, 40.0};\n  ToughPack hardcase {20.0, 30.0, 40.0};         // A derived box - same size\n  Carton carton {20.0, 30.0, 40.0, \"Plastic\"};   // A different derived box\n\n  box.showVolume();          // Volume of Box\n  hardcase.showVolume();     // Volume of ToughPack\n  carton.showVolume();       // Volume of Carton\n\n// Uncomment the following statement for an error\n// std::cout << \"\\nhardcase volume is \" << hardcase.volume() << std::endl;\n\n  // Now using a base pointer...\n  Box* base {&box};          // Points to type Box\n  std::cout << \"\\nbox volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n\n  base = &hardcase;          // Points to type ToughPack\n  std::cout << \"hardcase volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n\n  base = &carton;                // Points to type Carton\n  std::cout << \"carton volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_03/ToughPack.cppm",
    "content": "export module boxes:tough_pack;\n\nimport :box;\n\nexport class ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\nprotected:\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * m_length * m_width * m_height; }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_04/Box.cppm",
    "content": "export module boxes:box;\n\nimport <iostream>;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume(int i = 5) const\n  { \n    std::cout << \"(Box argument = \" << i << \") \";\n    return m_length * m_width * m_height;\n  }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_04/Boxes.cppm",
    "content": "// Boxes.cppm: primary module interface file\nexport module boxes;\n\nexport import :box;           // Export all partitions\nexport import :tough_pack;\nexport import :carton;"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_04/Carton.cppm",
    "content": "export module boxes:carton;\nimport <algorithm>;    // For std::max()\nimport <string>;\nimport <string_view>;\nimport :box;\n\nexport class Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume(int i = 50) const override\n  {\n    std::cout << \"(Carton argument = \" << i << \") \";\n    return std::max((m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5), 0.0);\n  }\n\nprivate:\n  std::string m_material;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_04/Ex15_04.cpp",
    "content": "// Default parameter values in virtual functions\nimport <iostream>;\nimport boxes;\n\nint main()\n{\n  Box box{ 20.0, 30.0, 40.0 };\n  ToughPack hardcase{ 20.0, 30.0, 40.0 };        // A derived box - same size\n  Carton carton{ 20.0, 30.0, 40.0, \"Plastic\" };  // A different derived box\n\n  box.showVolume();        // Volume of Box\n  hardcase.showVolume();   // Volume of ToughPack\n  carton.showVolume();     // Volume of Carton\n\n  std::cout << \"\\nhardcase volume is \" << hardcase.volume() << std::endl;\n\n  // Now using a base pointer...\n  Box* base{ &box };        // Points to type Box\n  std::cout << \"\\nbox volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n\n  base = &hardcase;        // Points to type ToughPack\n  std::cout << \"hardcase volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n\n  base = &carton;          // Points to type Carton\n  std::cout << \"carton volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_04/ToughPack.cppm",
    "content": "export module boxes:tough_pack;\n\nimport :box;\n\nexport class ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume(int i = 500) const override\n  {\n    std::cout << \"(ToughPack argument = \" << i << \") \";\n    return 0.85 * m_length * m_width * m_height;\n  }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_05/Box.cppm",
    "content": "export module boxes:box;\n\nimport <iostream>;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_05/Boxes.cppm",
    "content": "// Boxes.cppm: primary module interface file\nexport module boxes;\n\nexport import :box;           // Export all partitions\nexport import :tough_pack;\nexport import :carton;"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_05/Carton.cppm",
    "content": "export module boxes:carton;\nimport <algorithm>;    // For std::max()\nimport <string>;\nimport <string_view>;\nimport :box;\n\nexport class Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_05/Ex15_05.cpp",
    "content": "// Using a reference parameter to call virtual function\nimport <iostream>;\nimport boxes;\n\n// Global function to display the volume of a box\nvoid showVolume(const Box& box)\n{\n  std::cout << \"Box usable volume is \" << box.volume() << std::endl;\n}\n\nint main()\n{\n  Box box {20.0, 30.0, 40.0};                  // A base box\n  ToughPack hardcase {20.0, 30.0, 40.0};       // A derived box - same size\n  Carton carton {20.0, 30.0, 40.0, \"Plastic\"}; // A different derived box\n\n  showVolume(box);       // Display volume of base box\n  showVolume(hardcase);  // Display volume of derived box\n  showVolume(carton);    // Display volume of derived box\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_05/ToughPack.cppm",
    "content": "export module boxes:tough_pack;\n\nimport :box;\n\nexport class ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * m_length * m_width * m_height; }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_06/Box.cppm",
    "content": "export module boxes:box;\n\nimport <iostream>;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_06/Boxes.cppm",
    "content": "// Boxes.cppm: primary module interface file\nexport module boxes;\n\nexport import :box;           // Export all partitions\nexport import :tough_pack;\nexport import :carton;"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_06/Carton.cppm",
    "content": "export module boxes:carton;\nimport <algorithm>;    // For std::max()\nimport <string>;\nimport <string_view>;\nimport :box;\n\nexport class Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_06/Ex15_06.cpp",
    "content": "// Polymorphic vectors of smart pointers\nimport <iostream>;\nimport <memory>;                                // For smart pointers\nimport <vector>;                                // For vector\nimport boxes;\n\nint main()\n{\n  // Careful: this first attempt at a mixed collection is a bad idea (object slicing!)\n  std::vector<Box> boxes;\n  boxes.push_back(Box{20.0, 30.0, 40.0});\n  boxes.push_back(ToughPack{20.0, 30.0, 40.0});\n  boxes.push_back(Carton{20.0, 30.0, 40.0, \"plastic\"});\n\n  for (const auto& box : boxes)\n    box.showVolume();\n\n  std::cout << std::endl;\n\n  // Next, we create a proper polymorphic vector<>:\n  std::vector<std::unique_ptr<Box>> polymorphicBoxes;\n  polymorphicBoxes.push_back(std::make_unique<Box>(20.0, 30.0, 40.0));\n  polymorphicBoxes.push_back(std::make_unique<ToughPack>(20.0, 30.0, 40.0));\n  polymorphicBoxes.push_back(std::make_unique<Carton>(20.0, 30.0, 40.0, \"plastic\"));\n\n  for (const auto& box : polymorphicBoxes)\n    box->showVolume();\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_06/ToughPack.cppm",
    "content": "export module boxes:tough_pack;\n\nimport :box;\n\nexport class ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\nprotected:\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * m_length * m_width * m_height; }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_07/Box.cppm",
    "content": "export module boxes:box;\n\nimport <iostream>;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n  \n  // Uncomment virtual to ensure destructors of derived classes are called correctly\n  /*virtual*/ ~Box() { std::cout << \"Box destructor called\" << std::endl; }\n  \n  // More typical declaration of the destructor of a base class\n  // virtual ~Box() = default;\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_07/Boxes.cppm",
    "content": "// Boxes.cppm: primary module interface file\nexport module boxes;\n\nexport import :box;           // Export all partitions\nexport import :tough_pack;\nexport import :carton;"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_07/Carton.cppm",
    "content": "export module boxes:carton;\nimport <algorithm>;    // For std::max()\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport :box;\n\nexport class Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n  ~Carton() { std::cout << \"Carton destructor called\" << std::endl; }\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_07/Ex15_07.cpp",
    "content": "// Polymorphic vectors of smart pointers\nimport <iostream>;\nimport <memory>;                                // For smart pointers\nimport <vector>;                                // For vector\nimport boxes;\n\nint main()\n{\n  // Careful: this first attempt at a mixed collection is a bad idea (object slicing!)\n  std::vector<Box> boxes;\n  boxes.push_back(Box{20.0, 30.0, 40.0});\n  boxes.push_back(ToughPack{20.0, 30.0, 40.0});\n  boxes.push_back(Carton{20.0, 30.0, 40.0, \"plastic\"});\n\n  for (const auto& p : boxes)\n    p.showVolume();\n\n  std::cout << std::endl;\n  \n  // Next, we create a proper polymorphic vector<>:\n  std::vector<std::unique_ptr<Box>> polymorphicBoxes;\n  polymorphicBoxes.push_back(std::make_unique<Box>(20.0, 30.0, 40.0));\n  polymorphicBoxes.push_back(std::make_unique<ToughPack>(20.0, 30.0, 40.0));\n  polymorphicBoxes.push_back(std::make_unique<Carton>(20.0, 30.0, 40.0, \"plastic\"));\n\n  for (const auto& p : polymorphicBoxes)\n    p->showVolume();\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_07/ToughPack.cppm",
    "content": "export module boxes:tough_pack;\n\nimport :box;\nimport <iostream>;\n\nexport class ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n  ~ToughPack() { std::cout << \"ToughPack destructor called\" << std::endl; }\n\nprotected:\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * m_length * m_width * m_height; }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_07A/Box.cppm",
    "content": "export module boxes:box;\n\nimport <iostream>;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n  \n  virtual ~Box() = default;\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_07A/Boxes.cppm",
    "content": "// Boxes.cppm: primary module interface file\nexport module boxes;\n\nexport import :box;           // Export all partitions\nexport import :tough_pack;\nexport import :carton;"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_07A/Carton.cppm",
    "content": "export module boxes:carton;\nimport <algorithm>;    // For std::max()\nimport <string>;\nimport <string_view>;\nimport :box;\n\nexport class Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n  ~Carton() override = default;\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_07A/Ex15_07A.cpp",
    "content": "// Calling the base class version of a virtual function (see ToughPack::volume())\nimport <iostream>;\nimport <memory>;                                // For smart pointers\nimport <vector>;                                // For vector\nimport boxes;\n\nint main()\n{\n  // Careful: this first attempt at a mixed collection is a bad idea (object slicing!)\n  std::vector<Box> boxes;\n  boxes.push_back(Box{20.0, 30.0, 40.0});\n  boxes.push_back(ToughPack{20.0, 30.0, 40.0});\n  boxes.push_back(Carton{20.0, 30.0, 40.0, \"plastic\"});\n\n  for (const auto& p : boxes)\n    p.showVolume();\n\n  std::cout << std::endl;\n  \n  // Next, we create a proper polymorphic vector<>:\n  std::vector<std::unique_ptr<Box>> polymorphicBoxes;\n  polymorphicBoxes.push_back(std::make_unique<Box>(20.0, 30.0, 40.0));\n  polymorphicBoxes.push_back(std::make_unique<ToughPack>(20.0, 30.0, 40.0));\n  polymorphicBoxes.push_back(std::make_unique<Carton>(20.0, 30.0, 40.0, \"plastic\"));\n\n  for (const auto& p : polymorphicBoxes)\n    p->showVolume();\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_07A/ToughPack.cppm",
    "content": "export module boxes:tough_pack;\n\nimport :box;\n\nexport class ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\nprotected:\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * Box::volume(); }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_08/Box.cppm",
    "content": "export module boxes:box;\n\nimport <iostream>;\n\nexport class Box\n{\npublic:\n  Box(double length, double width, double height)\n    : m_length {length}, m_width {width}, m_height {height}\n  {\n    std::cout << \"Box constructor called for a Box of volume \" << volume() << std::endl;\n  }\n  virtual ~Box()\n  {\n    std::cout << \"Box destructor called for a Box of volume \" << volume() << std::endl;\n  }\n\n  // Function to calculate volume of a Box\n  virtual double volume() const { return m_length * m_width * m_height; }\n\n  void showVolume() const\n  {\n    std::cout << \"The volume from inside Box::showVolume() is \"\n              << volume() << std::endl;\n  }\n\nprivate:\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_08/Boxes.cppm",
    "content": "// Boxes.cppm: primary module interface file\nexport module boxes;\n\nexport import :box;           // Export all partitions\nexport import :tough_pack;\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_08/Ex14_08.cpp",
    "content": "// Calling virtual functions from constructors and destructors\nimport boxes;\n\nint main()\n{\n  ToughPack toughPack{ 1.0, 2.0, 3.0 };\n  toughPack.showVolume();     // Should show a volume equal to 85% of 1x2x3, or 5.1\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_08/ToughPack.cppm",
    "content": "export module boxes:tough_pack;\nimport :box;\nimport <iostream>;\n\nexport class ToughPack : public Box\n{\npublic:\n  ToughPack(double length, double width, double height)\n    : Box{length, width, height}\n  {\n    std::cout << \"ToughPack constructor called for a Box of volume \"\n              << volume() << std::endl;\n  }\n  virtual ~ToughPack()\n  {\n    std::cout << \"ToughPack destructor called for a Box of volume \"\n              << volume() << std::endl;\n  }\n\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * Box::volume(); }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_09/Box.cppm",
    "content": "export module boxes:box;\n\nimport <iostream>;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n  virtual ~Box() = default;\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_09/Boxes.cppm",
    "content": "// Boxes.cppm: primary module interface file\nexport module boxes;\n\nexport import :box;           // Export all partitions\nexport import :carton;"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_09/Carton.cppm",
    "content": "export module boxes:carton;\nimport <algorithm>;    // For std::max()\nimport <string>;\nimport <string_view>;\nimport :box;\n\nexport class Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_09/Ex15_09.cpp",
    "content": "// Using the typeid() operator\nimport <iostream>;\nimport <typeinfo>;         // For the std::type_info class\nimport boxes;\n\n// Define trivial non-polymorphic base and derived classes:\nclass NonPolyBase {};\nclass NonPolyDerived : public NonPolyBase {};\n\nBox& getSomeBox();              // Function returning a reference to a polymorphic type\nNonPolyBase& getSomeNonPoly();  // Function returning a reference to a non-polymorphic type\n\nint main()\n{\n  // Part 1: typeid() on types and == operator\n  std::cout << \"Type double has name \" << typeid(double).name() << std::endl;\n  std::cout << \"1 is \" << (typeid(1) == typeid(int)? \"an int\" : \"no int\") << std::endl;\n\n  // Part 2: typeid() on polymorphic references\n  Carton carton{ 1, 2, 3, \"paperboard\" };\n  Box& boxReference{ carton };\n\n  std::cout << \"Type of carton is \"       << typeid(carton).name()       << std::endl;\n  std::cout << \"Type of boxReference is \" << typeid(boxReference).name() << std::endl;\n  std::cout << \"These are \" << (typeid(carton) == typeid(boxReference)? \"\" : \"not \")\n            << \"equal\" << std::endl;\n\n  // Part 3: typeid() on polymorphic pointers\n  Box* boxPointer{ &carton };\n  std::cout << \"Type of &carton is \"     << typeid(&carton).name()     << std::endl;\n  std::cout << \"Type of boxPointer is \"  << typeid(boxPointer).name()  << std::endl;\n  std::cout << \"Type of *boxPointer is \" << typeid(*boxPointer).name() << std::endl;\n\n  // Part 4: typeid() with non-polymorphic classes\n  NonPolyDerived derived;\n  NonPolyBase& baseRef{ derived };\n\n  std::cout << \"Type of baseRef is \" << typeid(baseRef).name() << std::endl;\n\n  // Part 5: typeid() on expressions\n  const auto& type_info1{ typeid(getSomeBox()) };       // function call evaluated\n  const auto& type_info2{ typeid(getSomeNonPoly()) };   // function call not evaluated\n  std::cout << \"Type of getSomeBox() is \" << type_info1.name() << std::endl;\n  std::cout << \"Type of getSomeNonPoly() is \"    << type_info2.name() << std::endl;\n}\n\nBox& getSomeBox()\n{\n  std::cout << \"getSomeBox() called...\" << std::endl;\n  static Carton carton{ 2, 3, 5, \"duplex\" };\n  return carton;\n}\nNonPolyBase& getSomeNonPoly()\n{\n  std::cout << \"getSomeNonPoly() called...\" << std::endl;\n  static NonPolyDerived derived;\n  return derived;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_10/Box.cppm",
    "content": "export module boxes:box;\n\nimport <iostream>;\n\nexport class Box\n{\npublic:\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n  virtual ~Box() = default;            // Virtual destructor\n  virtual double volume() const = 0;   // Function to calculate the volume\n\nprotected:  // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_10/Boxes.cppm",
    "content": "// Boxes.cppm: primary module interface file\nexport module boxes;\n\nexport import :box;           // Export all partitions\nexport import :tough_pack;\nexport import :carton;"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_10/Carton.cppm",
    "content": "export module boxes:carton;\nimport <algorithm>;    // For std::max()\nimport <string>;\nimport <string_view>;\nimport :box;\n\nexport class Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_10/Ex15_10.cpp",
    "content": "// Using an abstract class\nimport <iostream>;\nimport boxes;\n\nint main()\n{\n  // Box box{20.0, 30.0, 40.0};                  // Uncomment for compiler error\n\n  ToughPack hardcase {20.0, 30.0, 40.0};         // A derived box - same size\n  Carton carton {20.0, 30.0, 40.0, \"plastic\"};   // A different derived box\n\n  Box*pBox {&hardcase};                          // Base pointer - derived address\n  std::cout << \"hardcase volume is \" << pBox->volume() << std::endl;\n\n  pBox = &carton;                                // New derived address\n  std::cout << \"carton volume is \" << pBox->volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_10/ToughPack.cppm",
    "content": "export module boxes:tough_pack;\n\nimport :box;\n\nexport class ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\nprotected:\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * m_length * m_width * m_height; }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_11/Box.cppm",
    "content": "export module boxes:box;\n\nimport vessel;\n\nexport class Box : public Vessel\n{\npublic:\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  double volume() const override { return m_length * m_width * m_height; }\n\nprotected:   // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_11/Boxes.cppm",
    "content": "// Boxes.cppm: primary module interface file\nexport module boxes;\n\nexport import :box;           // Export all partitions\nexport import :tough_pack;\nexport import :carton;"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_11/Can.cppm",
    "content": "// Can.cppm Class defining a cylindrical can of a given height and diameter\nexport module can;\n\nimport vessel;\nimport <numbers>;\n\nexport class Can : public Vessel\n{\npublic:\n  Can(double diameter, double height) \n    : m_diameter {diameter}, m_height {height} {}    \n\n  double volume() const override\n  { \n    return std::numbers::pi * m_diameter * m_diameter * m_height / 4;\n  }\n\nprivate:\n  double m_diameter, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_11/Carton.cppm",
    "content": "export module boxes:carton;\nimport <algorithm>;    // For std::max()\nimport <string>;\nimport <string_view>;\nimport :box;\n\nexport class Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_11/Ex15_11.cpp",
    "content": "// Using an interface class and indirect base classes\nimport <iostream>;\nimport <vector>;                     // For the vector container\nimport boxes;\nimport vessel;\nimport can;\n\nint main()\n{\n  Box box {40, 30, 20};\n  Can can {10, 3};\n  Carton carton {40, 30, 20, \"Plastic\"};\n  ToughPack hardcase {40, 30, 20};\n\n  std::vector<const Vessel*> vessels {&box, &can, &carton, &hardcase};\n\n  for (const auto* vessel : vessels)\n    std::cout << \"Volume is \" << vessel->volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_11/ToughPack.cppm",
    "content": "export module boxes:tough_pack;\n\nimport :box;\n\nexport class ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\nprotected:\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * m_length * m_width * m_height; }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 15/Ex15_11/Vessel.cppm",
    "content": "// Vessel.cppm  Abstract class defining a vessel\nexport module vessel;\n\nexport class Vessel\n{\npublic:\n  virtual ~Vessel() = default;         // As always: a virtual destructor!\n  virtual double volume() const = 0;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_01/Ex16_01.cpp",
    "content": "// Throwing and catching exceptions\nimport <iostream>;\n\nint main()\n{\n  for (size_t i {}; i < 5; ++i)\n  {\n    try\n    {\n      if (i < 2)\n        throw i;\n\n      std::cout << \"i not thrown - value is \" << i << std::endl;\n\n      if (i > 3)\n        throw \"Here is another!\";\n\n      std::cout << \"End of the try block.\" << std::endl;\n    }\n    catch (size_t i)     // Catch exceptions of type size_t\n    {\n      std::cout << \"i caught - value is \" << i << std::endl;\n    }\n    catch (const char* message)    // Catch exceptions of type char*\n    {\n      std::cout << \"message caught - value is \\\"\" << message << '\"' << std::endl;\n    }\n\n    std::cout << \"End of the for loop body (after the catch blocks)\"\n              << \" - i is \" << i << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_02/Ex16_02.cpp",
    "content": "// Throw an exception object\nimport <iostream>;\nimport <string_view>;    // for operator<<\nimport troubles;\n\nvoid trySomething(int i);\n\nint main()\n{\n  for (int i {}; i < 2; ++i)\n  {\n    try\n    {\n      trySomething(i);\n    }\n    catch (const Trouble& t)\n    {\n      // What seems to be the trouble?\n      std::cout << \"Exception: \" << t.what() << std::endl;\n    }\n  }\n}\n\nvoid trySomething(int i)\n{\n  // There's always trouble when trying something...\n  if (i == 0)\n    throw Trouble {};\n  else\n    throw Trouble {\"Nobody knows the trouble I've seen...\"};\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_02/Troubles.cppm",
    "content": "// Exception class definition\nexport module troubles;\nimport <string>;\nimport <string_view>;\n\nexport class Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\") \n    : m_message {message} \n  {}\n  std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_03/Ex16_03.cpp",
    "content": "// Throwing and catching objects in a hierarchy\nimport <iostream>;\nimport <string_view>;    // for operator<<\nimport troubles;\n\nint main()\n{\n  for (int i {}; i < 7; ++i)\n  {\n    try\n    {\n      if (i == 3)\n        throw Trouble{};\n      else if (i == 5)\n        throw MoreTrouble{};\n      else if (i == 6)\n        throw BigTrouble{};\n    }\n    catch (const BigTrouble& t)\n    {\n      std::cout << \"BigTrouble object caught: \" << t.what() << std::endl;\n    }\n    catch (const MoreTrouble& t)\n    {\n      std::cout << \"MoreTrouble object caught: \" << t.what() << std::endl;\n    }\n    catch (const Trouble& t)\n    {\n      std::cout << \"Trouble object caught: \" << t.what() << std::endl;\n    }\n\n    std::cout << \"End of the for loop (after the catch blocks) - i is \" << i << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_03/Troubles.cppm",
    "content": "// Troubles.cppm Exception classes\nexport module troubles;\nimport <string>;\nimport <string_view>;\n\nexport class Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\") \n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nexport class MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nexport class BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_04/Ex16_04.cpp",
    "content": "// Catching exceptions with a base class handler\nimport <iostream>;\nimport <typeinfo>;\t\t\t// for the type_info type returned by the typeid operator\nimport <string_view>;       // for operator<<\nimport troubles;\n\nint main()\n{\n  for (int i {}; i < 7; ++i)\n  {\n    try\n    {\n      if (i == 3)\n        throw Trouble{};\n      else if (i == 5)\n        throw MoreTrouble{};\n      else if (i == 6)\n        throw BigTrouble{};\n    }\n    catch (const Trouble& t)\n    {\n      //std::cout << \"Trouble object caught: \" << t.what() << std::endl;\n      std::cout << typeid(t).name() << \" object caught: \" << t.what() << std::endl;\n    }\n    std::cout << \"End of the for loop (after the catch blocks) - i is \" << i << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_04/Troubles.cppm",
    "content": "// Troubles.cppm Exception classes\nexport module troubles;\nimport <string>;\nimport <string_view>;\n\nexport class Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nexport class MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nexport class BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_05/Ex16_05.cpp",
    "content": "// Rethrowing exceptions\nimport <iostream>;\nimport <typeinfo>;\nimport <string_view>;   // for operator<<\nimport troubles;\n\nint main()\n{\n  for (int i {}; i < 7; ++i)\n  {\n    try\n    {\n      try\n      {\n        if (i == 3)\n          throw Trouble{};\n        else if (i == 5)\n          throw MoreTrouble{};\n        else if (i == 6)\n          throw BigTrouble{};\n      }\n      catch (const Trouble& t)\n      {\n        if (typeid(t) == typeid(Trouble))\n          std::cout << \"Trouble object caught in inner block: \" << t.what() << std::endl;\n        else\n          throw;     // Rethrow current exception\n      }\n    }\n    catch (const Trouble& t)\n    {\n      std::cout << typeid(t).name() << \" object caught in outer block: \"\n                << t.what() << std::endl;\n    }\n    std::cout << \"End of the for loop (after the catch blocks) - i is \" << i << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_05/Troubles.cppm",
    "content": "// Troubles.cppm Exception classes\nexport module troubles;\nimport <string>;\nimport <string_view>;\n\nexport class Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\") \n    : m_message {message}\n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nexport class MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nexport class BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_06/Ex16_06.cpp",
    "content": "// Catching any exception\nimport <iostream>;\nimport <typeinfo>;         // For use of typeid()\nimport <string_view>;      // for operator<<\nimport troubles;\n\nint main()\n{\n  for (int i {}; i < 7; ++i)\n  {\n    try\n    {\n      try\n      {\n        if (i == 3)\n          throw Trouble{};\n        else if (i == 5)\n          throw MoreTrouble{};\n        else if (i == 6)\n          throw BigTrouble{};\n      }\n      catch (const BigTrouble& bt)\n      {\n        std::cout << \"Oh dear, big trouble. Let's handle it here and now.\" << std::endl;\n        // Do not rethrow...\n      }\n      catch (...)   // Catch any other exception\n      {\n        std::cout << \"We caught something else! Let's rethrow it. \" << std::endl;\n        throw;      // Rethrow current exception\n      }\n    }\n    catch (const Trouble& t)\n    {\n      std::cout << typeid(t).name() << \" object caught in outer block: \"\n                << t.what() << std::endl;\n    }\n    std::cout << \"End of the for loop (after the catch blocks) - i is \" << i << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_06/Troubles.cppm",
    "content": "// Troubles.cppm Exception classes\nexport module troubles;\nimport <string>;\nimport <string_view>;\n\nexport class Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nexport class MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nexport class BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_07/Ex16_07.cpp",
    "content": "// Exceptions may result in resource leaks!\nimport <iostream>;\nimport troubles;\n\n#include <cmath>                    // For std::sqrt()\n\ndouble computeValue(size_t x);         // A function to compute a single value\ndouble* computeValues(size_t howMany); // A function to compute an array of values\n\nint main()\n{\n  try\n  {\n    double* values{ computeValues(10'000) };\n    // Unfortunately we won't be making it this far...\n    delete[] values;\n  }\n  catch (const Trouble&)\n  {\n    std::cout << \"No worries: I've caught it!\" << std::endl;\n  }\n}\n\ndouble* computeValues(size_t howMany)\n{\n  double* values{ new double[howMany] };\n  for (size_t i{}; i < howMany; ++i)\n    values[i] = computeValue(i);\n  return values;\n}\n\ndouble computeValue(size_t x)\n{\n  if (x < 100)\n    return std::sqrt(x);   // Return the square root of the input argument\n  else\n    throw Trouble{ \"The trouble with trouble is, it starts out as fun!\" };\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_07/Troubles.cppm",
    "content": "// Troubles.cppm Exception classes\nexport module troubles;\nimport <string>;\nimport <string_view>;\n\nexport class Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nexport class MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nexport class BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_07A/Ex16_07A.cpp",
    "content": "// Use of a try-catch block to fix the memory leak!\nimport <iostream>;\nimport troubles;\n\n#include <cmath>      // For std::sqrt()\n\ndouble computeValue(size_t x);         // A function to compute a single value\ndouble* computeValues(size_t howMany); // A function to compute an array of values\n\nint main()\n{\n  try\n  {\n    double* values{ computeValues(10'000) };\n    // Unfortunately we won't be making it this far...\n    delete[] values;\n  }\n  catch (const Trouble&)\n  {\n    std::cout << \"No worries: I've caught it!\" << std::endl;\n  }\n}\n\ndouble* computeValues(size_t howMany)\n{\n  double* values{ new double[howMany] };\n  try\n  {\n    for (size_t i {}; i < howMany; ++i)\n      values[i] = computeValue(i);\n    return values;\n  }\n  catch (const Trouble&)\n  {\n    std::cout << \"I sense trouble... Freeing memory...\" << std::endl;\n    delete[] values;\n    throw;\n  }\n}\n\ndouble computeValue(size_t x)\n{\n  if (x < 100)\n    return std::sqrt(x);   // Return the square root of the input argument\n  else\n    throw Trouble{ \"The trouble with trouble is, it starts out as fun!\" };\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_07A/Troubles.cppm",
    "content": "// Troubles.cppm Exception classes\nexport module troubles;\nimport <string>;\nimport <string_view>;\n\nexport class Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message}\n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nexport class MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nexport class BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_07B/DoubleArrayRAII.cppm",
    "content": "// A custom RAII class to manage a dynamic double[] array resource\nexport module raii;\nimport <iostream>;\n\nexport class DoubleArrayRAII final\n{\npublic:\n  explicit DoubleArrayRAII(size_t size) : m_resource{ new double[size] } {}\n  ~DoubleArrayRAII()\n  {\n    std::cout << \"Freeing memory...\" << std::endl;\n    delete[] m_resource;\n  }\n\n  // Delete copy constructor and assignment operator\n  DoubleArrayRAII(const DoubleArrayRAII&) = delete;\n  DoubleArrayRAII& operator=(const DoubleArrayRAII&) = delete;\n\n  // Array subscript operator\n  double& operator[](size_t index) noexcept { return m_resource[index]; }\n  const double& operator[](size_t index) const noexcept { return m_resource[index]; }\n\n  // Function to access the encapsulated resource\n  double* get() const noexcept { return m_resource; }\n\n  // Function to instruct the RAII object to hand over the resource.\n  // Once called, the RAII object shall no longer release the resource\n  // upon destruction anymore. Returns the resource in the process.\n  double* release() noexcept\n  {\n    double* result = m_resource;\n    m_resource = nullptr;\n    return result;\n  }\n\nprivate:\n  double* m_resource;\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_07B/Ex16_07B.cpp",
    "content": "// Exceptions may result in resource leaks!\nimport <iostream>;\nimport troubles;\nimport raii;\n\n#include <cmath>                    // For std::sqrt()\n\ndouble computeValue(size_t x);         // A function to compute a single value\ndouble* computeValues(size_t howMany); // A function to compute an array of values\n\nint main()\n{\n  try\n  {\n    double* values{ computeValues(10'000) };\n    // Unfortunately we won't be making it this far...\n    delete[] values;\n  }\n  catch (const Trouble&)\n  {\n    std::cout << \"No worries: I've caught it!\" << std::endl;\n  }\n}\n\ndouble* computeValues(size_t howMany)\n{\n  DoubleArrayRAII values{ howMany };\n  for (size_t i{}; i < howMany; ++i)\n    values[i] = computeValue(i);\n  return values.release();\n}\n\ndouble computeValue(size_t x)\n{\n  if (x < 100)\n    return std::sqrt(x);   // Return the square root of the input argument\n  else\n    throw Trouble{ \"The trouble with trouble is, it starts out as fun!\" };\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_07B/Troubles.cppm",
    "content": "// Troubles.cppm Exception classes\nexport module troubles;\nimport <string>;\nimport <string_view>;\n\nexport class Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nexport class MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nexport class BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_07C/Ex16_07C.cpp",
    "content": "// Avoid resource leaks due to exceptions using std::unique_ptr<>\n// Note: this example is given but not named in the text.\n// Instead of a custom RAII class DoubleArrayRAII, it uses std::unique_ptr<>.\n// Unlike the former, the latter can be returned from computeValues() as well.\nimport <iostream>;\nimport <memory>;\nimport troubles;\n\n#include <cmath>            // For std::sqrt()\n\ndouble computeValue(size_t x);      // A function to compute a single value\nstd::unique_ptr<double[]> computeValues(size_t howMany); // A function to compute an array of values\n\nint main()\n{\n  try\n  {\n    auto values{ computeValues(10'000) }; // Cannot leak either: resource is managed by RAII object!\n  }\n  catch (const Trouble&)\n  {\n    std::cout << \"No worries: I've caught it!\" << std::endl;\n  }\n}\n\nstd::unique_ptr<double[]> computeValues(size_t howMany)\n{\n  auto values{ std::make_unique<double[]>(howMany) };\n  for (size_t i{}; i < howMany; ++i)\n    values[i] = computeValue(i);\n  return values;\n}\n\ndouble computeValue(size_t x)\n{\n  if (x < 100)\n    return std::sqrt(x);   // Return the square root of the input argument\n  else\n    throw Trouble{ \"The trouble with trouble is, it starts out as fun!\" };\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_07C/Troubles.cppm",
    "content": "// Troubles.cppm Exception classes\nexport module troubles;\nimport <string>;\nimport <string_view>;\n\nexport class Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nexport class MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nexport class BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_07D/Ex16_07D.cpp",
    "content": "// Avoid resource leaks due to exceptions using std::unique_ptr<>\n// Note: this example is given but not named in the text.\n// Instead of a custom RAII class DoubleArrayRAII, it uses std::vector<>.\n// Unlike the former, the latter can of course be returned from computeValues() as well.\nimport <iostream>;\nimport <vector>;\nimport troubles;\n\n#include <cmath>            // For std::sqrt()\n\ndouble computeValue(size_t x);      // A function to compute a single value\nstd::vector<double> computeValues(size_t howMany); // A function to compute an array of values\n\nint main()\n{\n  try\n  {\n    auto values{ computeValues(10'000) }; // Cannot leak either: resource is managed by RAII object!\n  }\n  catch (const Trouble&)\n  {\n    std::cout << \"No worries: I've caught it!\" << std::endl;\n  }\n}\n\nstd::vector<double> computeValues(size_t howMany)\n{\n  std::vector<double> values;\n  for (size_t i{}; i < howMany; ++i)\n    values.push_back(computeValue(i));\n  return values;\n}\n\ndouble computeValue(size_t x)\n{\n  if (x < 100)\n    return std::sqrt(x);   // Return the square root of the input argument\n  else\n    throw Trouble{ \"The trouble with trouble is, it starts out as fun!\" };\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_07D/Troubles.cppm",
    "content": "// Troubles.cppm Exception classes\nexport module troubles;\nimport <string>;\nimport <string_view>;\n\nexport class Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nexport class MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nexport class BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_09/Box.cppm",
    "content": "export module box;\nimport <algorithm>;                        // For std::min() function template\nimport dimension_error;\n\nexport class Box\n{\npublic:\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h }\n  {\n    if (l <= 0.0 || w <= 0.0 || h <= 0.0)\n      throw DimensionError{ std::min({l, w, h}) };\n  }\n\n  double volume() const { return m_length * m_width * m_height; }\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_09/DimensionError.cppm",
    "content": "export module dimension_error;\n\nimport <stdexcept>;        // For derived exception classes such as std::out_of_range\nimport <string>;           // For std::to_string() and the std::string type\n\nexport class DimensionError : public std::out_of_range\n{\npublic:\n  explicit DimensionError(double value)\n    : std::out_of_range{ \"Zero or negative dimension: \" + std::to_string(value) }\n    , m_value{ value } {}\n\n  // Function to obtain the invalid dimension value\n  double getValue() const noexcept { return m_value; }\nprivate:\n  double m_value;\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 16/Ex16_09/Ex16_09.cpp",
    "content": "// Using an exception class\nimport <iostream>;\nimport box;               // For the Box class\nimport dimension_error;   // For the dimension_error class\n\nint main()\n{\n  try\n  {\n    Box box1 {1.0, 2.0, 3.0};\n    std::cout << \"box1 volume is \" << box1.volume() << std::endl;\n    Box box2 {1.0, -2.0, 3.0};\n    std::cout << \"box2 volume is \" << box2.volume() << std::endl;\n  }\n  catch (const std::exception& ex)\n  {\n    std::cout << \"Exception caught in main(): \" << ex.what() << std::endl;\n  }\n}"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_01/Array.cppm",
    "content": "// This solution uses the const-and-back-again idiom to avoid code duplication\n// between the non-const and const overloads of the array subscript operators.\n// It does not yet use the copy-and-swap idiom for the copy assignment operator \n// template, though: see Ex17_01A.\nexport module array;\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\n\nexport template <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Copy assignment operator template (not exception safe)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  if (&rhs != this)               // If lhs != rhs...\n  {                               // ...do the assignment...\n    delete[] m_elements;          // Release any free store memory\n\n    m_size = rhs.m_size;          // Copy the members of rhs into lhs\n    m_elements = new T[m_size];\n    for (size_t i {}; i < m_size; ++i)\n      m_elements[i] = rhs.m_elements[i];\n  }\n  return *this;                   // ... return lhs\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_01/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {};\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\nprivate:\n  double m_length, m_width, m_height;\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_01/Ex17_01.cpp",
    "content": "// Using a class template\nimport box;\nimport array;\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  try\n  {\n    const size_t numValues {20};\n    Array<double> values {numValues};\n\n    for (unsigned i {}; i < numValues; ++i)\n      values[i] = i + 1;\n\n    std::cout << \"Sums of pairs of elements:\";\n    size_t lines {};\n    for (size_t i {numValues - 1}; i >= 0; --i)\n    {\n      std::cout << (lines++ % 5 == 0 ? \"\\n\" : \"\")\n                << std::format(\"{:5g}\", values[i] + values[i-1]);\n    }\n  }\n  catch (const std::out_of_range& ex)\n  {\n    std::cerr << \"\\nout_of_range exception object caught! \" << ex.what() << std::endl;\n  }\n\n  try\n  {\n    const size_t numBoxes {5};\n    Array<Box> boxes {numBoxes};\n    for (size_t i {} ; i <= numBoxes ; ++i)\n      std::cout << \"Box volume is \" << boxes[i].volume() << std::endl;\n  }\n  catch (const std::out_of_range& ex)\n  {\n    std::cerr << \"\\nout_of_range exception object caught! \" << ex.what() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_01A/Array.cppm",
    "content": "// This solution uses \n//  1) the const-and-back-again idiom to avoid code duplication\n//     between the non-const and const overloads of the array subscript operators.\n//  2) the copy-and-swap idiom for a thread-safe copy assignment operator \nexport module array;\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\n\nexport template <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_01A/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {};\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\nprivate:\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_01A/Ex17_01A.cpp",
    "content": "// Using a class template\nimport box;\nimport array;\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  try\n  {\n    const size_t numValues {20};\n    Array<double> values {numValues};\n\n    for (unsigned i {}; i < numValues; ++i)\n      values[i] = i + 1;\n\n    std::cout << \"Sums of pairs of elements:\";\n    size_t lines {};\n    for (size_t i {numValues - 1}; i >= 0; --i)\n    {\n      std::cout << (lines++ % 5 == 0 ? \"\\n\" : \"\")\n                << std::format(\"{:5g}\", values[i] + values[i-1]);\n    }\n  }\n  catch (const std::out_of_range& ex)\n  {\n    std::cerr << \"\\nout_of_range exception object caught! \" << ex.what() << std::endl;\n  }\n\n  try\n  {\n    const size_t numBoxes {5};\n    Array<Box> boxes {numBoxes};\n    for (size_t i {} ; i <= numBoxes ; ++i)\n      std::cout << \"Box volume is \" << boxes[i].volume() << std::endl;\n  }\n  catch (const std::out_of_range& ex)\n  {\n    std::cerr << \"\\nout_of_range exception object caught! \" << ex.what() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_02/Array.cppm",
    "content": "export module array;\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For to_string()\nimport <utility>;                          // For std::as_const()\n\nexport template <typename T, int startIndex>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor  \n  Array& operator=(const Array& rhs);       // Assignment operator\n  void swap(Array& other) noexcept;         // noexcept swap() function\n  T& operator[](int index);                 // Subscript operator\n  const T& operator[](int index) const;     // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for size\n\nprivate:\n  T* m_elements;   // Array of type T\n  size_t m_size;   // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T, int startIndex>\nArray<T, startIndex>::Array(size_t size) : m_elements{ new T[size] {} }, m_size{ size }\n{}\n\n// Copy constructor template\ntemplate <typename T, int startIndex>\nArray<T, startIndex>::Array(const Array& array) : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T, int startIndex>\nArray<T, startIndex>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T, int startIndex>\nconst T& Array<T, startIndex>::operator[](int index) const\n{\n  if (index < startIndex)\n    throw std::out_of_range{ \"Index too small: \" + std::to_string(index) };\n\n  if (index > startIndex + static_cast<int>(m_size) - 1)\n    throw std::out_of_range{ \"Index too large: \" + std::to_string(index) };\n\n  return m_elements[index - startIndex];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T, int startIndex>\nT& Array<T, startIndex>::operator[](int index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T, int startIndex>\nArray<T, startIndex>& Array<T, startIndex>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Swap member function template\ntemplate <typename T, int startIndex>\nvoid Array<T, startIndex>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (can only swap arrays with identical startIndex)\nexport template <typename T, int startIndex>\nvoid swap(Array<T, startIndex>& one, Array<T, startIndex>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_02/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {};\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\nprivate:\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_02/Ex17_02.cpp",
    "content": "// Using a class template with a non-type parameter\nimport box;\nimport array;\nimport <iostream>;\nimport <format>;\nimport <typeinfo>;         // For use of typeid()\n\nint main()\n{\n  try\n  {\n    try\n    {\n      const size_t size {21};                              // Number of array elements\n      const int start {-10};                               // Index for first element\n      const int end {start + static_cast<int>(size) - 1};  // Index for last element\n\n      Array<double, start> values {size};                  // Define array of double values\n\n      for (int i {start}; i <= end; ++i)                   // Initialize the elements\n        values[i] = i - start + 1;\n\n      std::cout << \"Sums of pairs of elements: \";\n      size_t lines {};\n      for (int i {end}; i >= start; --i)\n      {\n        std::cout << (lines++ % 5 == 0 ? \"\\n\" : \"\")\n                  << std::format(\"{:5g}\", values[i] + values[i-1]);\n      }\n    }\n    catch (const std::out_of_range& ex)\n    {\n      std::cerr << \"\\nout_of_range exception object caught! \" << ex.what() << std::endl;\n    }\n\n    // Create array of Box objects\n    const int numBoxes {9};\n    Array<Box, -numBoxes / 2> boxes { static_cast<size_t>(numBoxes) };    \n\n    for (int i { -numBoxes / 2 }; i <= numBoxes/2 + numBoxes%2; ++i)\n      std::cout << std::format(\"Volume of Box[{}] is {}\\n\", i, boxes[i].volume());\n  }\n  catch (const std::exception& ex)\n  {\n    std::cerr << typeid(ex).name() << \" exception caught in main()! \"\n      << ex.what() << std::endl;\n  }\n}"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_02A/Array.cppm",
    "content": "export module array;\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For to_string()\nimport <utility>;                          // For std::as_const()\n\nexport template <typename T, int startIndex>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor  \n  Array& operator=(const Array& rhs);       // Assignment operator\n  void swap(Array& other) noexcept;         // noexcept swap() function\n  T& operator[](int index);                 // Subscript operator\n  const T& operator[](int index) const;     // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for size\n\nprivate:\n  T* m_elements;   // Array of type T\n  size_t m_size;   // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T, int startIndex>\nArray<T, startIndex>::Array(size_t size) : m_elements{ new T[size] {} }, m_size{ size }\n{}\n\n// Copy constructor template\ntemplate <typename T, int startIndex>\nArray<T, startIndex>::Array(const Array& array) : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T, int startIndex>\nArray<T, startIndex>::~Array() { delete[] m_elements; }\n\n// const subscript operator template (improved readability!)\ntemplate <typename T, int startIndex>\nconst T& Array<T, startIndex>::operator[](int index) const\n{\n  // Subtract startIndex to obtain the actual index into the m_elements array.\n  // If startIndex is 0, conventional 0-based array indexing is used.\n  const int actualIndex{ index - startIndex };\n\n  if (actualIndex < 0)\n    throw std::out_of_range {\"Index too small: \" + std::to_string(index)};\n\n  if (actualIndex >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n\n  return m_elements[actualIndex];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T, int startIndex>\nT& Array<T, startIndex>::operator[](int index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T, int startIndex>\nArray<T, startIndex>& Array<T, startIndex>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Swap member function template\ntemplate <typename T, int startIndex>\nvoid Array<T, startIndex>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (can only swap arrays with identical startIndex)\nexport template <typename T, int startIndex>\nvoid swap(Array<T, startIndex>& one, Array<T, startIndex>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_02A/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {};\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\nprivate:\n  double m_length, m_width, m_height;\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_02A/Ex17_02A.cpp",
    "content": "// Using a class template with a non-type parameter\n// In this variant the code readability of the array subscript operator template\n// was improved (see Array<> source code).\nimport box;\nimport array;\nimport <iostream>;\nimport <format>;\nimport <typeinfo>;         // For use of typeid()\n\nint main()\n{\n  try\n  {\n    try\n    {\n      const size_t size {21};                              // Number of array elements\n      const int start {-10};                               // Index for first element\n      const int end {start + static_cast<int>(size) - 1};  // Index for last element\n\n      Array<double, start> values {size};                  // Define array of double values\n\n      for (int i {start}; i <= end; ++i)                   // Initialize the elements\n        values[i] = i - start + 1;\n\n      std::cout << \"Sums of pairs of elements: \";\n      size_t lines {};\n      for (int i {end}; i >= start; --i)\n      {\n        std::cout << (lines++ % 5 == 0 ? \"\\n\" : \"\")\n                  << std::format(\"{:5g}\", values[i] + values[i-1]);\n      }\n    }\n    catch (const std::out_of_range& ex)\n    {\n      std::cerr << \"\\nout_of_range exception object caught! \" << ex.what() << std::endl;\n    }\n\n    // Create array of Box objects\n    const int numBoxes {9};\n    Array<Box, -numBoxes / 2> boxes { static_cast<size_t>(numBoxes) };    \n\n    for (int i { -numBoxes / 2 }; i <= numBoxes/2 + numBoxes%2; ++i)\n      std::cout << std::format(\"Volume of Box[{}] is {}\\n\", i, boxes[i].volume());\n  }\n  catch (const std::exception& ex)\n  {\n    std::cerr << typeid(ex).name() << \" exception caught in main()! \"\n      << ex.what() << std::endl;\n  }\n}"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_03/Array.cppm",
    "content": "export module array;\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\nimport <initializer_list>;                 // For the std::initializer_list<> template\n\nexport template <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(std::initializer_list<T> elements); // Initializer list constructor\n  Array(const Array& array);                // Copy constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Initializer list constructor template\ntemplate <typename T>\nArray<T>::Array(std::initializer_list<T> elements)\n  : m_elements{ new T[elements.size()] }, m_size{ elements.size() }\n{\n  // std::initializer_list<> has no operator[], but can be used in range-based for loop.\n  // The possibility to add variable initializations such as \"size_t i {};\" \n  // to a range-based for loop is new in C++20.\n  for (size_t i{}; const T & element : elements)\n    m_elements[i++] = element;\n}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_03/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {};\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\nprivate:\n  double m_length, m_width, m_height;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_03/Ex17_03.cpp",
    "content": "// Illustrating Class Template Argument Deduction (CTAD) \n// by adding an initializer list constructor to our Array<> template.\nimport box;\nimport array;\nimport <iostream>;\n\nint main()\n{\n  // Class Template Argument Deduction (CTAD) in action:\n  Array integers{ 1, 2, 3, 4, 5 };           // Deduced type: Array<int>\n  Array doubles{ 1.0, 2.0, 3.0, 4.0, 5.0 };  // Deduced type: Array<double\n\n  // But... caution!\n  {\n    const size_t numValues{ 50 };\n    Array<double> values{ numValues };  // Now uses the initializer list constructor!\n\n    std::cout << \"Wrong constructor used, so \" << values.getSize() << \" != \" << numValues << std::endl;\n    std::cout << \"Single value contained in Array<> is \" << values[0] << std::endl;\n  }\n\n  // Workaround: do not use uniform initialization (or \"near uniform\", as is thus more appropriate...)\n  { \n    const size_t numValues{ 50 };\n    Array<double> values(numValues);    // Uses Array(size_t) constructor as before\n\n    std::cout << \"Intended constructor used, so \" << values.getSize() << \" == \" << numValues << std::endl;\n    std::cout << \"All values are equal to \" << values[numValues / 2] << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_04/Ex17_04.cpp",
    "content": "// Using a stack defined by nested class templates\nimport stack;\nimport <iostream>;\nimport <string>;\n\nint main()\n{\n  std::string words[]{ \"The\", \"quick\", \"brown\", \"fox\", \"jumps\" };\n  Stack<std::string> wordStack;              // A stack of strings\n\n  for (const auto& word : words)\n    wordStack.push(word);\n\n  Stack<std::string> newStack{ wordStack };  // Create a copy of the stack\n\n  // Display the words in reverse order\n  while (!newStack.isEmpty())\n    std::cout << newStack.pop() << ' ';\n  std::cout << std::endl;\n\n  // Reverse wordStack onto newStack\n  while (!wordStack.isEmpty())\n    newStack.push(wordStack.pop());\n\n  // Display the words in original order\n  while (!newStack.isEmpty())\n    std::cout << newStack.pop() << ' ';\n  std::cout << std::endl;\n\n  std::cout << std::endl << \"Enter a line of text:\" << std::endl;\n  std::string text;\n  std::getline(std::cin, text);    // Read a line into the string object\n\n  Stack<const char> characters;    // A stack for characters\n\n  for (size_t i{}; i < text.length(); ++i)\n    characters.push(text[i]);      // Push the string characters onto the stack\n\n  std::cout << std::endl;\n  while (!characters.isEmpty())\n    std::cout << characters.pop(); // Pop the characters off the stack\n\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_04/Stack.cppm",
    "content": "// Stack.cppm Templates to define stacks\nexport module stack;\nimport <stdexcept>;\n\nexport template <typename T>\nclass Stack\n{\npublic:\n  Stack() = default;                  // Default constructor\n  ~Stack();                           // Destructor\n\n  Stack(const Stack & stack);          // Copy constructor\n  Stack& operator=(const Stack & rhs); // Copy assignment operator\n  void swap(Stack & other) noexcept;   // noexcept swap() function\n\n  void push(const T & item);           // Push an object onto the stack\n  T pop();                            // Pop an object off the stack\n  bool isEmpty() const;               // Empty test\n\nprivate:\n  // Nested class\n  class Node\n  {\n  public:\n    Node(const T& item) : m_item{ item } {} // Create a node from an object\n\n    T m_item;          // The object stored in this node\n    Node* m_next{};   // Pointer to next node\n  };\n\n  Node* m_head{};     // Points to the top of the stack\n};\n\n// Copy constructor\ntemplate <typename T>\nStack<T>::Stack(const Stack& stack)\n{\n  if (stack.m_head)\n  {\n    m_head = new Node {*stack.m_head}; // Copy the top node of the original\n    Node* oldNode {stack.m_head};      // Points to the top node of the original\n    Node* newNode {m_head};            // Points to the node in the new stack\n\n    while (oldNode = oldNode->m_next)  // If m_next was nullptr, the last node was copied\n    {     \n      newNode->m_next = new Node{*oldNode}; // Duplicate it\n      newNode = newNode->m_next;            // Move to the node just created\n    }\n  }\n}\n\n// Destructor\ntemplate <typename T>\nStack<T>::~Stack()\n{\n  while (m_head)\n  {                               // While current pointer is not null\n    auto* next{ m_head->m_next }; // Get the pointer to the next node\n    delete m_head;                // Delete the current head\n    m_head = next;                // Make m_head point to the next node\n  }\n}\n\n// Copy assignment operator\ntemplate <typename T>\nStack<T>& Stack<T>::operator=(const Stack& rhs)\n{\n  auto copy{ rhs }; // Copy...        (could go wrong and throw an exception)\n  swap(copy);       // ... and swap!  (noexcept)\n  return *this;\n}\n\n// Push an object onto the stack\ntemplate <typename T>\nvoid Stack<T>::push(const T& item)\n{\n  Node* node{ new Node{item} }; // Create the new node\n  node->m_next = m_head;  // Point to the old top node\n  m_head = node;          // Make the new node the top\n}\n\n// Pop an object off the stack\ntemplate <typename T>\nT Stack<T>::pop()\n{\n  if (isEmpty())     // If it's empty pop() is not valid so throw exception\n    throw std::logic_error {\"Stack empty\"}; \n\n  auto* next {m_head->m_next}; // Save pointer to the next node\n  T item {m_head->m_item};     // Save the T value to return later\n  delete m_head;               // Delete the current head\n  m_head = next;               // Make head point to the next node\n  return item;                 // Return the top object\n}\n\ntemplate <typename T>\nbool Stack<T>::isEmpty() const { return m_head == nullptr; }\n\n// noexcept swap member function\ntemplate <typename T>\nvoid Stack<T>::swap(Stack& other) noexcept\n{\n  std::swap(m_head, other.m_head);\n}\n\n// Conventional noexcept swap non-member function\nexport template <typename T>\nvoid swap(Stack<T>& one, Stack<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_04A/Ex17_04A.cpp",
    "content": "// Using a stack defined by nested class templates\n// (with improvement suggested in the \"A Better Stack\" section: see Stack<> source)\nimport stack;\nimport <iostream>;\nimport <string>;\n\nint main()\n{\n  std::string words[]{ \"The\", \"quick\", \"brown\", \"fox\", \"jumps\" };\n  Stack<std::string> wordStack;              // A stack of strings\n\n  for (const auto& word : words)\n    wordStack.push(word);\n\n  Stack<std::string> newStack{ wordStack };  // Create a copy of the stack\n\n  // Display the words in reverse order\n  while (!newStack.isEmpty())\n    std::cout << newStack.pop() << ' ';\n  std::cout << std::endl;\n\n  // Reverse wordStack onto newStack\n  while (!wordStack.isEmpty())\n    newStack.push(wordStack.pop());\n\n  // Display the words in original order\n  while (!newStack.isEmpty())\n    std::cout << newStack.pop() << ' ';\n  std::cout << std::endl;\n\n  std::cout << std::endl << \"Enter a line of text:\" << std::endl;\n  std::string text;\n  std::getline(std::cin, text);    // Read a line into the string object\n\n  Stack<const char> characters;    // A stack for characters\n\n  for (size_t i{}; i < text.length(); ++i)\n    characters.push(text[i]);      // Push the string characters onto the stack\n\n  std::cout << std::endl;\n  while (!characters.isEmpty())\n    std::cout << characters.pop(); // Pop the characters off the stack\n\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_04A/Stack.cppm",
    "content": "// Stack.cppm Templates to define stacks \n// (with improvement suggested in the \"A Better Stack\" section)\nexport module stack;\nimport <stdexcept>;\n\nexport template <typename T>\nclass Stack\n{\npublic:\n  Stack() = default;                  // Default constructor\n  ~Stack();                           // Destructor\n\n  Stack(const Stack & stack);          // Copy constructor\n  Stack& operator=(const Stack & rhs); // Copy assignment operator\n  void swap(Stack & other) noexcept;   // noexcept swap() function\n\n  void push(const T & item);           // Push an object onto the stack\n  T pop();                            // Pop an object off the stack\n  bool isEmpty() const;               // Empty test\n\nprivate:\n  // Nested class\n  class Node\n  {\n  public:\n    Node(const T& item) : m_item{ item } {} // Create a node from an object\n\n    T m_item;          // The object stored in this node\n    Node* m_next{};   // Pointer to next node\n  };\n\n  Node* m_head{};     // Points to the top of the stack\n};\n\n// Copy constructor\ntemplate <typename T>\nStack<T>::Stack(const Stack& stack)\n{\n  if (stack.m_head)\n  {\n    m_head = new Node {*stack.m_head}; // Copy the top node of the original\n    Node* oldNode {stack.m_head};      // Points to the top node of the original\n    Node* newNode {m_head};            // Points to the node in the new stack\n\n    while (oldNode = oldNode->m_next)  // If m_next was nullptr, the last node was copied\n    {     \n      newNode->m_next = new Node{*oldNode}; // Duplicate it\n      newNode = newNode->m_next;            // Move to the node just created\n    }\n  }\n}\n\n// Destructor\ntemplate <typename T>\nStack<T>::~Stack()\n{\n  while (!isEmpty()) pop();\n}\n\n// Copy assignment operator\ntemplate <typename T>\nStack<T>& Stack<T>::operator=(const Stack& rhs)\n{\n  auto copy{ rhs }; // Copy...        (could go wrong and throw an exception)\n  swap(copy);       // ... and swap!  (noexcept)\n  return *this;\n}\n\n// Push an object onto the stack\ntemplate <typename T>\nvoid Stack<T>::push(const T& item)\n{\n  Node* node{ new Node{item} }; // Create the new node\n  node->m_next = m_head;  // Point to the old top node\n  m_head = node;          // Make the new node the top\n}\n\n// Pop an object off the stack\ntemplate <typename T>\nT Stack<T>::pop()\n{\n  if (isEmpty())     // If it's empty pop() is not valid so throw exception\n    throw std::logic_error {\"Stack empty\"}; \n\n  auto* next {m_head->m_next}; // Save pointer to the next node\n  T item {m_head->m_item};     // Save the T value to return later\n  delete m_head;               // Delete the current head\n  m_head = next;               // Make head point to the next node\n  return item;                 // Return the top object\n}\n\ntemplate <typename T>\nbool Stack<T>::isEmpty() const { return m_head == nullptr; }\n\n// noexcept swap member function\ntemplate <typename T>\nvoid Stack<T>::swap(Stack& other) noexcept\n{\n  std::swap(m_head, other.m_head);\n}\n\n// Conventional noexcept swap non-member function\nexport template <typename T>\nvoid swap(Stack<T>& one, Stack<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_04B/Ex17_04B.cpp",
    "content": "// Using a stack defined by nested class templates\n// (using std::unique_ptr<>: see Stack<> source)\n// Note: this is a bonus example that is only hinted at in the text (and not explicitly named). \n// It requires the use of std::move(), seen only in Chapter 18.\nimport stack;\nimport <iostream>;\nimport <string>;\n\nint main()\n{\n  std::string words[]{ \"The\", \"quick\", \"brown\", \"fox\", \"jumps\" };\n  Stack<std::string> wordStack;              // A stack of strings\n\n  for (const auto& word : words)\n    wordStack.push(word);\n\n  Stack<std::string> newStack{ wordStack };  // Create a copy of the stack\n\n  // Display the words in reverse order\n  while (!newStack.isEmpty())\n    std::cout << newStack.pop() << ' ';\n  std::cout << std::endl;\n\n  // Reverse wordStack onto newStack\n  while (!wordStack.isEmpty())\n    newStack.push(wordStack.pop());\n\n  // Display the words in original order\n  while (!newStack.isEmpty())\n    std::cout << newStack.pop() << ' ';\n  std::cout << std::endl;\n\n  std::cout << std::endl << \"Enter a line of text:\" << std::endl;\n  std::string text;\n  std::getline(std::cin, text);    // Read a line into the string object\n\n  Stack<const char> characters;    // A stack for characters\n\n  for (size_t i{}; i < text.length(); ++i)\n    characters.push(text[i]);      // Push the string characters onto the stack\n\n  std::cout << std::endl;\n  while (!characters.isEmpty())\n    std::cout << characters.pop(); // Pop the characters off the stack\n\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_04B/Stack.cppm",
    "content": "// Stack.cppm Templates to define stacks \n// (using std::unique_ptr<> instead of raw pointer)\nexport module stack;\nimport <stdexcept>;\nimport <memory>;       // For std::unique_ptr<>\n\n/*\n    The required changes are minimal, \n    but they do require std::move() which we only cover in Chapter 18.\n\n    Other changes include:\n      - no need for the destructor anymore (all memory is managed by smart pointers)\n      - Nodes can no longer be copied, \n        so you need to construct all Nodes with the Node(const T&) constructor\n */\n\nexport template <typename T>\nclass Stack\n{\npublic:\n  Stack() = default;                  // Default constructor\n\n  Stack(const Stack & stack);          // Copy constructor\n  Stack& operator=(const Stack & rhs); // Copy assignment operator\n  void swap(Stack & other) noexcept;   // noexcept swap() function\n\n  void push(const T & item);           // Push an object onto the stack\n  T pop();                            // Pop an object off the stack\n  bool isEmpty() const;               // Empty test\n\nprivate:\n  // Nested class\n  class Node\n  {\n  public:\n    Node(const T& item) : m_item{ item } {} // Create a node from an object\n\n    T m_item;          // The object stored in this node\n    std::unique_ptr<Node> m_next{};   // Pointer to next node\n  };\n\n  std::unique_ptr<Node> m_head;     // Points to the top of the stack\n};\n\n// Copy constructor\ntemplate <typename T>\nStack<T>::Stack(const Stack& stack)\n{\n  if (stack.m_head)\n  {\n    m_head = std::make_unique<Node>(stack.m_head->m_item); // Copy the top node of the original\n    Node* oldNode {stack.m_head.get()}; // Points to the top node of the original\n    Node* newNode {m_head.get()};       // Points to the node in the new stack\n\n    while (oldNode = oldNode->m_next.get()) // If m_next was nullptr, the last node was copied\n    {     \n      newNode->m_next = std::make_unique<Node>(oldNode->m_item); // Duplicate it\n      newNode = newNode->m_next.get();      // Move to the node just created\n    }\n  }\n}\n\n// Copy assignment operator\ntemplate <typename T>\nStack<T>& Stack<T>::operator=(const Stack& rhs)\n{\n  auto copy{ rhs }; // Copy...        (could go wrong and throw an exception)\n  swap(copy);       // ... and swap!  (noexcept)\n  return *this;\n}\n\n// Push an object onto the stack\ntemplate <typename T>\nvoid Stack<T>::push(const T& item)\n{\n  // See Chapter 18 for std::move()\n  auto node{ std::make_unique<Node>(item) }; // Create the new node\n  node->m_next = std::move(m_head);   // Point to the old top node\n  m_head = std::move(node);           // Make the new node the top\n}\n\n// Pop an object off the stack\ntemplate <typename T>\nT Stack<T>::pop()\n{\n  if (isEmpty())     // If it's empty pop() is not valid so throw exception\n    throw std::logic_error {\"Stack empty\"}; \n\n  // See Chapter 18 for std::move()\n  auto next {std::move(m_head->m_next)}; // Save pointer to the next node\n  T item {m_head->m_item};     // Save the T value to return later\n  m_head.reset();              // Delete the current head\n  m_head = std::move(next);    // Make head point to the next node\n  return item;                 // Return the top object\n}\n\ntemplate <typename T>\nbool Stack<T>::isEmpty() const { return m_head == nullptr; }\n\n// noexcept swap member function\ntemplate <typename T>\nvoid Stack<T>::swap(Stack& other) noexcept\n{\n  std::swap(m_head, other.m_head);\n}\n\n// Conventional noexcept swap non-member function\nexport template <typename T>\nvoid swap(Stack<T>& one, Stack<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_05/Ex17_05A.cpp",
    "content": "// Disambiguating dependant names: this code will not compile. \n\ntemplate <typename T>\nclass Outer\n{\npublic:\n  class Nested { /* ... */ };  // Or a type alias of form 'using Nested = ...;'\n  // ...\n};\n\n// Uncomment the typename keyword to turn Outer<T>::Nested into \n// a dependent type name and fix the compilation\ntemplate <typename T>\nvoid someFunction() { /*typename*/ Outer<T>::Nested* nested; /* ... */ }\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_05/Ex17_05B.cpp",
    "content": "// Disambiguating dependant names\n// Note: not all compilers may implement the C++20 rules already,\n// any may still require additional typename keywords in front of T::Derived\n\ntemplate <typename T>\nclass Outer\n{\npublic:\n  class Nested { /* ... */ };  // Or a type alias of form 'using Nested = ...;'\n  // ...\n};\n\ntemplate <typename T>   // T assumed to define nested Base and Derived types / aliases\nvoid someOtherFunction()\n{\n  typename T::Base* b{ new T::Derived{} };                      // Or: auto* b{ ... }\n  const typename T::Derived& d{ static_cast<T::Derived&>(*b) }; // Or: const auto& d{ ... }\n  /* ... */\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_05/Ex17_05C.cpp",
    "content": "// Disambiguating dependant names\n\n// Note: not all compilers may implement the C++20 rules already,\n// any may still require additional typename keywords in front of Outer<T>::Nested\n\ntemplate <typename T>\nclass Outer\n{\npublic:\n  class Nested { /* ... */ };  // Or a type alias of form 'using Nested = ...;'\n  // ...\n};\n\ntemplate <typename T>\nclass MyClass\n{\npublic:\n  Outer<T>::Nested memberFunction(const Outer<T>::Nested& nested);\nprivate:\n  T::Nested m_member_variable;\n};\n\ntemplate<class T>\nT::Nested nonMemberFunction(const typename T::Nested* nested);\n\ntemplate<typename T>\nOuter<T>::Nested MyClass<T>::memberFunction(const typename Outer<T>::Nested& nested)\n{\n  return nested;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 17/Ex17_06/Ex17_06.cpp",
    "content": "// Disambiguating dependant base class names\n// (this code does not compile without changes)\n\nimport <iostream>;\n\ntemplate <typename T>\nclass Base\n{\npublic:\n  void baseFun() { /* ... */ }\nprotected:\n  int m_base_var {};\n};\n\ntemplate <typename T>\nclass Derived : public Base<T>\n{\npublic:\n  void derivedFun();\n\n  // Option 3: using declarations (remove to see error messages)\n// using Base<T>::baseFun;\n// using Base<T>::m_base_var;\n};\n\ntemplate <typename T>\nvoid Derived<T>::derivedFun()\n{\n  // These two lines should give compiler errors.\n  // Uncomment the using declarations in the Derived<> template \n  // to make them work. Alternative solutions are illustrated below.\n  baseFun();\n  std::cout << m_base_var << std::endl;\n\n  // Option 1: add this->\n  this->baseFun();\n  std::cout << this->m_base_var << std::endl;\n\n  // Option 2: add Base<T>::\n  Base<T>::baseFun();\n  std::cout << Base<T>::m_base_var << std::endl;\n}\n\nint main()\n{\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_01/Array.cppm",
    "content": "export module array;\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\nimport <iostream>;\n\nexport template <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_01/Ex18_01.cpp",
    "content": "// Copying objects into a vector\nimport array;\nimport <string>;\nimport <vector>;\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  const size_t numArrays{ 10 };       // Fill 10 Arrays with 1,000 strings each\n  const size_t numStringsPerArray{ 1000 };\n\n  std::vector<Array<std::string>> vectorOfArrays;\n  vectorOfArrays.reserve(numArrays);  // Inform the vector<> how many Arrays we'll be adding\n\n  for (size_t i {}; i < numArrays; ++i)\n  {\n     vectorOfArrays.push_back(buildStringArray(numStringsPerArray));\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_02/Array.cppm",
    "content": "export module array;\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\nimport <iostream>;\n\nexport template <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array);                     // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved)\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_02/Ex18_02.cpp",
    "content": "// Moving objects into a vector\nimport array;\nimport <string>;\nimport <vector>;\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  const size_t numArrays{ 10 };       // Fill 10 Arrays with 1,000 strings each\n  const size_t numStringsPerArray{ 1000 };\n\n  std::vector<Array<std::string>> vectorOfArrays;\n  vectorOfArrays.reserve(numArrays);  // Inform the vector<> how many Arrays we'll be adding\n\n  for (size_t i {}; i < numArrays; ++i)\n  {\n     vectorOfArrays.push_back(buildStringArray(numStringsPerArray));\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_03/Array.cppm",
    "content": "export module array;\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\nimport <iostream>;\n\nexport template <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array);                     // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs);            // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved)\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs)\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_03/Ex18_03.cpp",
    "content": "// Defining and using a move assignment operator\nimport array;\nimport <string>;\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  Array<std::string> strings { 123 };\n  strings = buildStringArray(1'000);           // Assign an rvalue to strings\n\n  Array<std::string> more_strings{ 2'000 };\n  strings = more_strings;                      // Assign an lvalue to strings\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_04/Array.cppm",
    "content": "export module array;\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\nimport <iostream>;\n\nexport template <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array);                     // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs);            // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved)\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs)\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_04/Ex18_04.cpp",
    "content": "// Using std::move() to force the move assignment of a named variable\nimport array;\nimport <string>;\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  Array<std::string> strings { 123 };\n  strings = buildStringArray(1'000);           // Assign an rvalue to strings\n\n  Array<std::string> more_strings{ 2'000 };\n  strings = std::move(more_strings);           // Move more_strings into strings\n\n  /* Caution: once moved, an object should not be used anymore! */\n// std::cout << more_strings[101] << std::endl; // ???\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_05A/Array.cppm",
    "content": "export module array;\n\n// Compared to Ex18_04, this variant adds two overloads of push_back().\n// The Array<>() default constructor is new as well.\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\nimport <iostream>;\n\nexport template <typename T>\nclass Array\n{\npublic:\n  Array();                                  // Default constructor\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array);                     // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs);            // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n  void push_back(const T& element);         // Add copy of given element to the back of the array\n  void push_back(T&& element);              // Move element to the back of the array\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T>\nArray<T>::Array() : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved)\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs)\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n// push_back() overload for lvalue references\ntemplate <typename T>\nvoid Array<T>::push_back(const T& element)\n{\n  Array<T> newArray{m_size + 1};      // Allocate a larger Array<>\n  for (size_t i{}; i < m_size; ++i)   // Move all existing elements...\n    newArray[i] = std::move(m_elements[i]);\n\n  newArray[m_size] = element;         // Copy the new one...\n\n  swap(newArray);                     // ... and swap!\n}\n\n// push_back() overload for rvalue references\ntemplate <typename T>\nvoid Array<T>::push_back(T&& element)\n{\n  Array<T> newArray{m_size + 1};      // Allocate a larger Array<>\n  for (size_t i{}; i < m_size; ++i)   // Move all existing elements...\n    newArray[i] = std::move(m_elements[i]);\n\n  newArray[m_size] = std::move(element); // Move the new one...\n\n  swap(newArray);                        // ... and swap!\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_05A/Ex18_05A.cpp",
    "content": "// Exercising two overloads of push_back(): one for lvalue arguments, and one for rvalue arguments\nimport array;\nimport <string>;\nimport <iostream>;\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  Array<Array<std::string>> array_of_arrays;\n\n  Array<std::string> array{ buildStringArray(1'000) };  \n  array_of_arrays.push_back(array);              // Push an lvalue\n\n  array.push_back(\"One more for good measure\");\n  std::cout << std::endl;\n\n  array_of_arrays.push_back(std::move(array));   // Push an rvalue\n}"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_05B/Array.cppm",
    "content": "export module array;\n\n// This variant merges the two overloads of push_back() of Ex18_05 into one single member.\n// The push_back() function accepts a new element by value.\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\nimport <iostream>;\n\nexport template <typename T>\nclass Array\n{\npublic:\n  Array();                                  // Default constructor\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array);                     // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs);            // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n  void push_back(T element);                // Copy or move element to the back of the array\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T>\nArray<T>::Array() : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved)\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs)\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n// push_back() overload for lvalue references\ntemplate <typename T>\nvoid Array<T>::push_back(T element)   // Pass by value (copy of lvalue, or moved rvalue!)\n{\n  Array<T> newArray{m_size + 1};      // Allocate a larger Array<>\n  for (size_t i{}; i < m_size; ++i)   // Move all existing elements...\n    newArray[i] = std::move(m_elements[i]);\n\n  newArray[m_size] = std::move(element); // Move the new one (could itself be a copy already)...\n\n  swap(newArray);                     // ... and swap!\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_05B/Ex18_05B.cpp",
    "content": "// Exercising a single overload of push_back() \n// that can be used to either to add a copy of, or move, a new value into an Array<>.\n// The caller decides whether the element is copied or moved.\nimport array;\nimport <string>;\nimport <iostream>;\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  Array<Array<std::string>> array_of_arrays;\n\n  Array<std::string> array{ buildStringArray(1'000) };\n  array_of_arrays.push_back(array);              // Push an lvalue\n\n  array.push_back(\"One more for good measure\");\n  std::cout << std::endl;\n\n  array_of_arrays.push_back(std::move(array));   // Push an rvalue\n}"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_06/Array.cppm",
    "content": "export module array;\n\n// Compared to Ex18_05B, this variant adds noexcept specifiers to all move members \n// and implements a strongly exception safe push_back().\n// It uses some mild template meta programming in move_assign_if_noexcept() to accomplish the latter.\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\nimport <iostream>;\nimport <type_traits>;\n\ntemplate<class T>\nstd::conditional_t<std::is_nothrow_move_assignable_v<T>, T&&, const T&>\nmove_assign_if_noexcept(T& x) noexcept\n{\n  return std::move(x);\n}\n\nexport template <typename T>\nclass Array\n{\npublic:\n  Array();                                  // Default constructor\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array) noexcept;                     // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs) noexcept;   // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n  void push_back(T element);                // Copy or move element to the back of the array\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T>\nArray<T>::Array() : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved) noexcept\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs) noexcept\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n// push_back() overload for lvalue references\ntemplate <typename T>\nvoid Array<T>::push_back(T element)  // Pass by value (copy of lvalue, or moved rvalue!)\n{\n  Array<T> newArray{m_size + 1};     // Allocate a larger Array<>\n  for (size_t i {}; i < m_size; ++i) // Move existing elements (copy if not noexcept)...\n    newArray[i] = move_assign_if_noexcept(m_elements[i]);\n\n  newArray[m_size] = move_assign_if_noexcept(element);  // Move (or copy) the new one...\n\n  swap(newArray);                   // ... and swap!\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_06/Ex18_06.cpp",
    "content": "// Exercising a single, exception safe overload of push_back() \n// Remove the noexcept specifiers from Array<> to observe\n// that copying is then used instead of moving\n// (moving would be unsafe if an exception occurs).\nimport array;\nimport <string>;\nimport <iostream>;\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  Array<Array<std::string>> array_of_arrays;\n\n  Array<std::string> array{ buildStringArray(1'000) };\n  array_of_arrays.push_back(array);              // Push an lvalue\n\n  array.push_back(\"One more for good measure\");\n  std::cout << std::endl;\n\n  array_of_arrays.push_back(std::move(array));   // Push an rvalue\n}"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_07/Array.cppm",
    "content": "export module array;\n\n// Exact same as template as Ex18_05B (that is: without noexcept specifiers!)\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\nimport <iostream>;\n\nexport template <typename T>\nclass Array\n{\npublic:\n  Array();                                  // Default constructor\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array) /*noexcept*/;        // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs) /*noexcept*/; // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n  void push_back(T element);                // Copy or move element to the back of the array\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T>\nArray<T>::Array() : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved) /*noexcept*/\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs) /*noexcept*/\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n// push_back() overload for lvalue references\ntemplate <typename T>\nvoid Array<T>::push_back(T element)   // Pass by value (copy of lvalue, or moved rvalue!)\n{\n  Array<T> newArray{m_size + 1};      // Allocate a larger Array<>\n  for (size_t i{}; i < m_size; ++i)   // Move all existing elements...\n    newArray[i] = std::move(m_elements[i]);\n\n  newArray[m_size] = std::move(element); // Move the new one (could itself be a copy already)...\n\n  swap(newArray);                     // ... and swap!\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 18/Ex18_07/Ex18_07.cpp",
    "content": "// The effect of not adding noexcept to move members\n// Uncomment the noexcept specifiers in the Array<> template source \n// to avoid copying when a std::vector<> grows its dynamic array.\nimport array;\nimport <string>;\nimport <vector>;\nimport <iostream>;\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  std::vector<Array<std::string>> v;\n\n  v.push_back(buildStringArray(1'000));\n\n  std::cout << std::endl;\n\n  v.push_back(buildStringArray(2'000));\n}"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_01/Ex19_01.cpp",
    "content": "// Exercising pointers to functions\nimport <iostream>;\n\nlong sum(long a, long b);           // Function prototype\nlong product(long a, long b);       // Function prototype\n\nint main()\n{\n  long(*fun_ptr)(long, long) {};    // Pointer to function\n\n  fun_ptr = product;\n  std::cout << \"3 * 5 = \" << fun_ptr(3, 5) << std::endl; // Call product() thru fun_ptr\n\n  fun_ptr = sum;                    // Reassign pointer to sum()\n  std::cout << \"3 * (4+5) + 6 = \"   // Call sum() thru fun_ptr twice\n    << fun_ptr(product(3, fun_ptr(4, 5)), 6) << std::endl; \n}\n\n// Function to multiply two values\nlong product(long a, long b) { return a * b; }\n\n// Function to add two values\nlong sum(long a, long b) { return a + b; }\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_02/Ex19_02.cpp",
    "content": "// Exercising the use of function pointers as callback functions\nimport <iostream>;\nimport <string>;\nimport <vector>;\nimport optimum;\n\n// Comparison function prototypes:\nbool less(const int&, const int&);\ntemplate <typename T> bool greater(const T&, const T&);\nbool longer(const std::string&, const std::string&);\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \" << *findOptimum(numbers, less) << std::endl;\n  std::cout << \"Maximum element: \" << *findOptimum(numbers, greater<int>) << std::endl;\n\n  std::vector<std::string> names{ \"Moe\", \"Larry\", \"Shemp\", \"Curly\", \"Joe\", \"Curly Joe\" };\n  std::cout << \"Alphabetically last name: \"\n            << *findOptimum(names, greater<std::string>) << std::endl;\n  std::cout << \"Longest name: \" << *findOptimum(names, longer) << std::endl;\n}\n\nbool less(const int& one, const int& other) { return one < other; }\n\ntemplate <typename T>\nbool greater(const T& one, const T& other) { return one > other; }\n\nbool longer(const std::string& one, const std::string& other)\n{\n  return one.length() > other.length();\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_02/Optimum.cppm",
    "content": "// Optimum.cppm - a function template to determine the optimum element in a given vector\nexport module optimum;\n\nimport <vector>;\n\nexport template <typename T>\nconst T* findOptimum(const std::vector<T>& values, bool (*compare)(const T&, const T&))\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_03/Ex19_03.cpp",
    "content": "// Exercising the use of a functor as callback functions\nimport <iostream>;\nimport <vector>;\nimport optimum;\nimport less;\n\ntemplate <typename T>\nbool greater(const T& one, const T& other) { return one > other; }\n\nint main()\n{\n  Less less;     // Create a 'less than' functor\n\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \" << *findOptimum(numbers, less) << std::endl;\n  std::cout << \"Maximum element: \" << *findOptimum(numbers, greater<int>) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_03/Less.cppm",
    "content": "// Less.cppm - A basic class of functor objects\nexport module less;\n\nexport class Less\n{\npublic:\n  bool operator()(int a, int b) const { return a < b; }\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_03/Optimum.cppm",
    "content": "// Optimum.cppm - a function template to determine the optimum element in a given vector\nexport module optimum;\n\nimport <vector>;\n\nexport template <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_03A/Ex19_03A.cpp",
    "content": "// Exercising the use of standard functors\nimport <iostream>;\nimport <functional>;\nimport <vector>;\nimport optimum;\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \" << *findOptimum(numbers, std::less<>{}) << std::endl;\n  std::cout << \"Maximum element: \" << *findOptimum(numbers, std::greater<>{}) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_03A/Optimum.cppm",
    "content": "// Optimum.cppm - a function template to determine the optimum element in a given vector\nexport module optimum;\n\nimport <vector>;\n\nexport template <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_04/Ex19_04.cpp",
    "content": "// Exercising a function object with a member variable\nimport <iostream>;\nimport <format>;\nimport <vector>;\nimport optimum;\nimport nearer;\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n\n  int number_to_search_for {};\n  std::cout << \"Please enter a number: \";\n  std::cin >> number_to_search_for;\n\n  std::cout << std::format(\"The number nearest to {} is {}\", \n                  number_to_search_for, \n                  *findOptimum(numbers, Nearer{ number_to_search_for })) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_04/Nearer.cppm",
    "content": "// A class of function objects that compare two values based on how close they are \n// to some third value that was provided to the functor at construction time.\nmodule;\n#include <cmath>   // For std::abs()\nexport module nearer;\n\nexport class Nearer\n{\npublic:\n  explicit Nearer(int value) : m_value{ value } {}\n  bool operator()(int x, int y) const\n  { \n    return std::abs(x - m_value) < std::abs(y - m_value); \n  }\nprivate:\n  int m_value;\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_04/Optimum.cppm",
    "content": "// Optimum.cppm - a function template to determine the optimum element in a given vector\nexport module optimum;\n\nimport <vector>;\n\nexport template <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_05/Ex19_05.cpp",
    "content": "// Exercising the use of stateless lambda expressions as callback functions\nimport <iostream>;\nimport <string>;\nimport <string_view>;\nimport <vector>;\nimport optimum;\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \"\n            << *findOptimum(numbers, [](int x, int y) { return x < y; }) << std::endl;\n  std::cout << \"Maximum element: \"\n            << *findOptimum(numbers, [](int x, int y) { return x > y; }) << std::endl;\n\n  // Define two anonymous comparison functions for strings:\n  auto alpha{ [](std::string_view x, std::string_view y) { return x > y; } };\n  auto longer{ [](std::string_view x, std::string_view y) { return x.length() > y.length(); } };\n\n  std::vector<std::string> names{ \"Moe\", \"Larry\", \"Shemp\", \"Curly\", \"Joe\", \"Curly Joe\" };\n  std::cout << \"Alphabetically last name: \" << *findOptimum(names, alpha) << std::endl;\n  std::cout << \"Longest name: \" << *findOptimum(names, longer) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_05/Optimum.cppm",
    "content": "// Optimum.cppm - a function template to determine the optimum element in a given vector\nexport module optimum;\n\nimport <vector>;\n\nexport template <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_05A/Ex19_05A.cpp",
    "content": "// If possible, using the standard functors instead of lambda expressions \n// often leads to more compact and elegant code.\nimport <iostream>;\nimport <string>;\nimport <string_view>;\nimport <functional>;\nimport <vector>;\nimport optimum;\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \"\n            << *findOptimum(numbers, std::less<>{}) << std::endl;\n  std::cout << \"Maximum element: \"\n            << *findOptimum(numbers, std::greater<>{}) << std::endl;\n\n  // Define two anonymous comparison functions for strings:\n  auto alpha{ std::greater<>{} };\n  auto longer{ [](std::string_view x, std::string_view y) { return x.length() > y.length(); } };\n\n  std::vector<std::string> names{ \"Moe\", \"Larry\", \"Shemp\", \"Curly\", \"Joe\", \"Curly Joe\" };\n  std::cout << \"Alphabetically last name: \" << *findOptimum(names, alpha) << std::endl;\n  std::cout << \"Longest name: \" << *findOptimum(names, longer) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_05A/Optimum.cppm",
    "content": "// Optimum.cppm - a function template to determine the optimum element in a given vector\nexport module optimum;\n\nimport <vector>;\n\nexport template <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_06/Ex19_06.cpp",
    "content": "// Using a default capture-by-value clause to access a local variable \n// from within the body of a lambda expression.\nimport <iostream>;\nimport <vector>;\nimport optimum;\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n\n  int number_to_search_for {};\n  std::cout << \"Please enter a number: \";\n  std::cin >> number_to_search_for;\n\n  auto nearer { [=](int x, int y) {\n    return std::abs(x - number_to_search_for) < std::abs(y - number_to_search_for);\n  }};\n  std::cout << \"The number nearest to \" << number_to_search_for << \" is \"\n            << *findOptimum(numbers, nearer) << std::endl;\n\n  //unsigned count{};\n  //auto counter{ [&](int x, int y) { ++count; return x < y; } };\n  //findOptimum(numbers, counter);\n  //std::cout << \"Number of comparisons: \" << count;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_06/Optimum.cppm",
    "content": "// Optimum.cppm - a function template to determine the optimum element in a given vector\nexport module optimum;\n\nimport <vector>;\n\nexport template <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_07/Ex19_07.cpp",
    "content": "// Using a lambda expression from inside a member function (see Finder.cpp)\nimport <iostream>;\nimport <vector>;\nimport optimum;\nimport finder;\n\nint main()\n{\n  std::vector<double> numbers{ 91, 18, 92, 22, 13, 43 };\n\n  int number_to_search_for {};\n  std::cout << \"Please enter a number: \";\n  std::cin >> number_to_search_for;\n\n  Finder finder;\n  finder.setNumberToSearchFor(number_to_search_for);\n  std::cout << \"The number nearest to \" << finder.getNumberToSearchFor() << \" is \"\n            << *finder.findNearest(numbers) << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_07/Finder.cpp",
    "content": "// Exercising capturing the this pointer\nmodule;\n#include <cmath>       // For std::abs()\nmodule finder;\n\nimport optimum;\n\nstd::optional<double> Finder::findNearest(const std::vector<double>& values) const\n{\n  if (values.empty())\n    return std::nullopt;\n  else  \n    return *findOptimum(values, [this](double x, double y) {\n      return std::abs(x - m_number_to_search_for) < std::abs(y - m_number_to_search_for);\n    });\n}\n\ndouble Finder::getNumberToSearchFor() const\n{\n  return m_number_to_search_for;\n}\n\nvoid Finder::setNumberToSearchFor(double value)\n{\n  m_number_to_search_for = value;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_07/Finder.cppm",
    "content": "// Finder.cppm - A small class to illustrate the use of lambda expression in member functions\nexport module finder;\n\nimport <vector>;\nimport <optional>;\n\nexport class Finder\n{\npublic:\n  double getNumberToSearchFor() const;\n  void setNumberToSearchFor(double n);\n\n  std::optional<double> findNearest(const std::vector<double>& values) const;\nprivate:\n  double m_number_to_search_for {};\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_07/Optimum.cppm",
    "content": "// Optimum.cppm - a function template to determine the optimum element in a given vector\nexport module optimum;\n\nimport <vector>;\n\nexport template <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 19/Ex19_08/Ex19_08.cpp",
    "content": "// Using the std::function<> template\nimport <iostream>;\nimport <functional>;\n#include <cmath>            // for std::abs()\n\n// A global less() function\nbool less(int x, int y) { return x < y; }\n\nint main()\n{\n  int a{ 18 }, b{ 8 };  \n  std::cout << std::boolalpha; // Print true/false rather than 1/0\n\n  std::function<bool(int,int)> compare;\n\n  compare = less;              // Store a function pointer into compare\n  std::cout << a << \" < \" << b << \": \" << compare(a, b) << std::endl;\n\n  compare = std::greater<>{};  // Store a function object into compare\n  std::cout << a << \" > \" << b << \": \" << compare(a, b) << std::endl;\n\n  int n{ 10 };                 // Store a lambda closure into compare\n  compare = [n](int x, int y) { return std::abs(x - n) < std::abs(y - n); };\n  std::cout << a << \" nearer to \" << n << \" than \" << b << \": \" << compare(a, b);\n\n  // Check whether a function<> object is tied to an actual function\n  std::function<void(const int&)> empty;\n  if (empty)             // Or, equivalently: 'if (empty != nullptr)'\n  {\n    std::cout << \"Calling a default-constructed std::function<>?\" << std::endl;\n    empty(a);\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_01/Ex20_01.cpp",
    "content": "// Working with std::deque<>\nimport <iostream>;\nimport <deque>;\n\nint main()\n{\n  std::deque<int> my_deque;  // A deque<> allows efficient insertions \n  my_deque.push_back(2);     // to both ends of the sequence\n  my_deque.push_back(4);\n  my_deque.push_front(1);\n\n  my_deque[2] = 3;           // A deque<> is a random-access sequence container\n\n  std::cout << \"There are \" << my_deque.size() << \" elements in my_deque: \";\n\n  for (int element : my_deque) // A deque<>, like all containers, is a range\n    std::cout << element << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_02/Ex20_02.cpp",
    "content": "// Working with stacks and queues\nimport <iostream>;\nimport <stack>;\nimport <queue>;\n\nint main()\n{\n  std::stack<int> stack;\n  for (int i {}; i < 10; ++i)\n    stack.push(i);\n\n  std::cout << \"The elements coming off the top of the stack:    \";\n  while (!stack.empty())\n  {\n    std::cout << stack.top() << ' ';\n    stack.pop();    // pop() is a void function!\n  }\n  std::cout << std::endl;\n\n  std::queue<int> queue;\n  for (int i {}; i < 10; ++i)\n    queue.push(i);\n\n  std::cout << \"The elements coming from the front of the queue: \";\n  while (!queue.empty())\n  {\n    std::cout << queue.front() << ' ';\n    queue.pop();    // pop() is a void function!\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_03/Ex20_03.cpp",
    "content": "// Working with sets\nimport <iostream>;\nimport <set>;         // For the std::set<> container template\n\nvoid printSet(const std::set<int>& my_set);  // Print the contents of a set to std::cout\n\nint main()\n{\n  std::set<int> my_set;\n\n  // Insert elements 1 through 4 in arbitrary order:\n  my_set.insert(1);\n  my_set.insert(4);\n  my_set.insert(3);\n  my_set.insert(3);  // Elements 3 and 1 are added twice\n  my_set.insert(1);\n  my_set.insert(2);\n\n  printSet(my_set);\n\n  std::cout << \"The element 1 occurs \" << my_set.count(1) << \" time(s)\" << std::endl;\n\n  my_set.erase(1);   // Remove the element 1 once\n  printSet(my_set);\n\n  my_set.clear();    // Remove all elements\n  printSet(my_set);\n}\n\nvoid printSet(const std::set<int>& my_set)\n{\n  std::cout << \"There are \" << my_set.size() << \" elements in my_set: \";\n  for (int element : my_set)       // A set, like all containers, is a range\n    std::cout << element << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_04/Ex20_04.cpp",
    "content": "// Basic use of std::map<>\nimport <map>;\nimport <iostream>;\nimport <string>;\n\nint main()\n{\n  std::map<std::string, unsigned long long> phone_book;\n  phone_book[\"Donald\"] = 202'456'1111;\n  phone_book[\"Melania\"] = 202'456'1111;\n  phone_book[\"Francis\"] = 39'06'6982;\n  phone_book[\"Elizabeth\"] = 44'020'7930'4832;\n\n  std::cout << \"The pope's number is \" << phone_book[\"Francis\"] << std::endl;\n\n  for (const auto& [name, number] : phone_book)\n    std::cout << name << \" can be reached at \" << number << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_05/Ex20_05.cpp",
    "content": "// Working with maps\nimport <iostream>;\nimport <format>;\nimport <map>;\nimport <string>;\nimport <string_view>;\nimport <vector>;\n\n// Type aliases\nusing Words = std::vector<std::string_view>;\nusing WordCounts = std::map<std::string_view, size_t>;\n\n// Function prototypes\nWords extractWords(std::string_view text, std::string_view separators = \" ,.!?\\\"\\n\");\nWordCounts countWords(const Words& words);\nvoid showWordCounts(const WordCounts& wordCounts);\nsize_t maxWordLength(const WordCounts& wordCounts);\n\nint main()\n{\n  std::string text;    // The string to count words in\n\n  // Read a string from the keyboard\n  std::cout << \"Enter a string terminated by *:\" << std::endl;\n  getline(std::cin, text, '*');\n\n  const Words words{ extractWords(text) };\n  if (words.empty())\n  {\n    std::cout << \"No words in text.\" << std::endl;\n    return 0;\n  }\n\n  WordCounts wordCounts = countWords(words);\n  showWordCounts(wordCounts);\n}\n\nWords extractWords(std::string_view text, std::string_view separators)\n{\n  Words words;\n  size_t start{ text.find_first_not_of(separators) };    // Start 1st word\n  size_t end{};                                          // Index for the end of a word\n                                                         \n  while (start != std::string_view::npos)                \n  {                                                      \n    end = text.find_first_of(separators, start + 1);     // Find end separator\n    if (end == std::string_view::npos)                   // End of text?\n      end = text.length();                               // Yes, so set to last+1\n    words.push_back(text.substr(start, end - start));    \n    start = text.find_first_not_of(separators, end + 1); // Find next word\n  }\n\n  return words;\n}\n\nWordCounts countWords(const Words& words)\n{\n  WordCounts result;\n  for (auto& word : words)\n    ++result[word];\n  return result;\n}\n\nsize_t maxWordLength(const WordCounts& wordCounts)\n{\n  size_t max{};\n  for (const auto& [word, count] : wordCounts)\n    if (count >= 2 && max < word.length()) max = word.length();\n  return max;\n}\n\nvoid showWordCounts(const WordCounts& wordCounts)\n{\n  const size_t field_width{maxWordLength(wordCounts) + 1};\n  const size_t words_per_line{5};\n\n  size_t words_in_line{};      // Number of words in the current line\n  char previous_initial{};\n  for (const auto& [word, count] : wordCounts)\n  {\n    if (count < 2) continue;   // Skip words that appear only once\n\n    // Output newline when initial letter changes or after 5 per line\n    if ( (previous_initial && word[0] != previous_initial)\n          || words_in_line++ == words_per_line)\n    {\n      words_in_line = 0;\n      std::cout << std::endl;\n    }\n    // Output \"word (count)\", where word has a dynamic field width\n    std::cout << std::format(\"{:>{}} ({:2})\", word, field_width, count); \n    previous_initial = word[0];\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_06/Ex20_06.cpp",
    "content": "// Creating and working with Standard iterators\nimport <vector>;\nimport <iostream>;\n\nint main()\n{\n  std::vector<char> letters{ 'a', 'b', 'c', 'd', 'e' };\n  auto my_iter{ letters.begin() };\n\n  std::cout << *my_iter << std::endl;       // a\n\n  *my_iter = 'x';\n  std::cout << letters[0] << std::endl;     // x\n\n  ++my_iter;                                // Move my_iter to the next element\n  std::cout << *my_iter << std::endl;       // b\n\n  my_iter += 2;                             // Move my_iter two elements further\n  std::cout << *my_iter-- << std::endl;     // d\n  std::cout << *my_iter << std::endl;       // c (iterator altered using the post-decrement\n                                            //    operator in the previous statement)\n  auto copy{ my_iter };                     // Create a copy of my_iter (pointing at c)\n  my_iter += 2;                             // Move my_iter two elements further\n  std::cout << *copy << std::endl;          // c (copy not affected by moving my_iter)\n  std::cout << *my_iter << std::endl;       // e\n  std::cout << my_iter - copy << std::endl; // 2\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_07/Ex20_07.cpp",
    "content": "// Iterating over the elements of a list<>\nimport <iostream>;\nimport <list>;\n\nint main()\n{\n  std::cout << \"Enter a sequence of positive numbers, terminated by -1: \";\n\n  std::list<unsigned> numbers;\n\n  while (true)\n  {\n    signed number{ -1 };\n    std::cin >> number;\n    if (number == -1) break;\n    numbers.push_back(static_cast<unsigned>(number));\n  }\n\n  std::cout << \"You entered the following numbers: \";\n  for (auto iter{ numbers.begin() }; iter != numbers.end(); ++iter)\n  {\n    std::cout << *iter << ' ';\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_08/Box.cppm",
    "content": "export module box;\n\n// Class to represent a box\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height)\n    : m_length{ length }, m_width{ width }, m_height{ height }\n  {}\n\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  void setLength(double length) { if (length > 0) m_length = length; }\n  void setWidth(double width)   { if (width > 0) m_width = width; }\n  void setHeight(double height) { if (height > 0) m_height = height; }\n\n  // Function to calculate the volume of a box\n  double volume() const { return m_length * m_width * m_height; }\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_08/Ex20_08.cpp",
    "content": "// Altering elements through a mutable iterator\nimport <iostream>;\nimport <vector>;\nimport box;      // From Ex11_04\n\nint main()\n{\n  std::vector boxes{ Box{ 1.0, 2.0, 3.0 } };  // A vector containing 1 Box\n\n  auto iter{ boxes.begin() };\n  std::cout << iter->volume() << std::endl;        // 6 == 1.0 * 2.0 * 3.0\n  \n  *iter = Box{ 2.0, 3.0, 4.0 };\n  std::cout << iter->volume() << std::endl;        // 24 == 2.0 * 3.0 * 4.0\n\n  iter->setHeight(7.0);\n  std::cout << iter->volume() << std::endl;        // 42 == 2.0 * 3.0 * 7.0\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_09/Ex20_09.cpp",
    "content": "// Inserting in and erasing from sequence containers\nimport <iostream>;\nimport <vector>;\n\nvoid printVector(const std::vector<int>& v);\n\nint main()\n{\n  std::vector numbers{ 2, 4, 5 };     // Deduced type: std::vector<int>\n  numbers.insert(numbers.begin(), 1); // Add single element to the beginning of the sequence\n  printVector(numbers);   // 1 2 4 5\n\n  numbers.insert(numbers.begin() + numbers.size() / 2, 3); // Add in the middle\n  printVector(numbers);   // 1 2 3 4 5\n\n  std::vector more_numbers{ 6, 7, 8 };\n  numbers.insert(numbers.end(), more_numbers.begin(), more_numbers.end());\n  printVector(numbers);   // 1 2 3 4 5 6 7 8\n\n  numbers.erase(numbers.end() - 3, numbers.end());      // Erase last 3 elements\n  numbers.erase(numbers.begin() + numbers.size() / 2);  // Erase the middle element\n  numbers.erase(numbers.begin());                       // Erase the first element\n  printVector(numbers);   // 2 4 5\n}\n\nvoid printVector(const std::vector<int>& v)\n{\n  for (auto i : v) std::cout << i << ' ';\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_10/Ex20_10.cpp",
    "content": "// Removing all elements that satisfy a certain condition \n// while iterating over a container\nimport <vector>;\nimport <string_view>;\nimport <iostream>;\n\nstd::vector<int> fillVector_1toN(size_t N);  // Fill a vector with 1, 2, ..., N\nvoid printVector(std::string_view message, const std::vector<int>& numbers);\n\nvoid removeEvenNumbers(auto& numbers)    /* Correct! */\n{\n  for (auto iter{ numbers.begin() }; iter != numbers.end(); )\n  {\n    if (*iter % 2 == 0)\n      iter = numbers.erase(iter);\n    else\n      ++iter;\n  }\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ fillVector_1toN(num_numbers) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  removeEvenNumbers(numbers);\n\n  printVector(\"The numbers that were kept\", numbers);\n}\n\nstd::vector<int> fillVector_1toN(size_t N)\n{\n  std::vector<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.push_back(i);\n  return numbers;\n}\n\nvoid printVector(std::string_view message, const std::vector<int>& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_11/Ex20_11.cpp",
    "content": "// Your first algorithms: std::min_element() and max_element()\nimport <iostream>;\nimport <algorithm>;\nimport <vector>;\n#include <cmath>    // For std::abs()\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \"\n            << *std::min_element(begin(numbers), end(numbers)) << std::endl;\n  std::cout << \"Maximum element: \"\n            << *std::max_element(begin(numbers), end(numbers)) << std::endl;\n\n  int number_to_search_for {};\n  std::cout << \"Please enter a number: \";\n  std::cin >> number_to_search_for;\n\n  auto nearer { [=](int x, int y) {\n    return std::abs(x - number_to_search_for) < std::abs(y - number_to_search_for);\n  }};\n\n  std::cout << \"The number nearest to \" << number_to_search_for << \" is \"\n            << *std::min_element(begin(numbers), end(numbers), nearer) << std::endl;\n  std::cout << \"The number furthest from \" << number_to_search_for << \" is \"\n            << *std::max_element(begin(numbers), end(numbers), nearer) << std::endl;\n\n/*\n  const auto [nearest, furthest]\n    { std::minmax_element(begin(numbers), end(numbers), nearer) };\n\n  std::cout << \"The number nearest to \" << number_to_search_for << \" is \"\n            << *nearest << std::endl;\n  std::cout << \"The number furthest from \" << number_to_search_for << \" is \"\n            << *furthest << std::endl;\n*/\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_11A/Ex20_11A.cpp",
    "content": "// Your first algorithms: std::min_element() and max_element(),\n// this time using the range-based versions.\nimport <iostream>;\nimport <algorithm>;\nimport <vector>;\n#include <cmath>    // For std::abs()\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \"\n            << *std::ranges::min_element(numbers) << std::endl;\n  std::cout << \"Maximum element: \"\n            << *std::ranges::max_element(numbers) << std::endl;\n\n  int number_to_search_for {};\n  std::cout << \"Please enter a number: \";\n  std::cin >> number_to_search_for;\n\n  auto nearer { [=](int x, int y) {\n    return std::abs(x - number_to_search_for) < std::abs(y - number_to_search_for);\n  }};\n\n  std::cout << \"The number nearest to \" << number_to_search_for << \" is \"\n            << *std::ranges::min_element(numbers, nearer) << std::endl;\n  std::cout << \"The number furthest from \" << number_to_search_for << \" is \"\n            << *std::ranges::max_element(numbers, nearer) << std::endl;\n\n/*\n  const auto [nearest, furthest]\n    { std::ranges::minmax_element(numbers, nearer) };\n\n  std::cout << \"The number nearest to \" << number_to_search_for << \" is \"\n            << *nearest << std::endl;\n  std::cout << \"The number furthest from \" << number_to_search_for << \" is \"\n            << *furthest << std::endl;\n*/\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_12/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_12/Ex20_12.cpp",
    "content": "// Finding boxes.\nimport <iostream>;\nimport <vector>;\nimport <algorithm>;\nimport box;      // From Ex13_03A\n\nint main()\n{\n  std::vector boxes{ Box{1,2,3}, Box{5,2,3}, Box{9,2,1}, Box{3,2,1} };\n\n  // Define a lambda functor to print the result of find() or find_if():\n  auto print_result{ [&boxes] (auto result)\n  {\n    if (result == end(boxes))\n      std::cout << \"No box found.\" << std::endl;\n    else\n      std::cout << \"Found matching box at position \"\n                << (result - begin(boxes)) << std::endl;\n  }};\n\n  // Find an exact box\n  Box box_to_find{ 3,2,1 };\n  auto result{ std::find(begin(boxes), end(boxes), box_to_find) };\n  print_result(result);\n\n  // Find a box with a volume larger than that of box_to_find\n  const auto required_volume{ box_to_find.volume() };\n  result = std::find_if(begin(boxes), end(boxes),\n              [required_volume](const Box& box) { return box > required_volume; });\n  print_result(result);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_12A/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_12A/Ex20_12A.cpp",
    "content": "// Finding boxes, this time using range-based algorithms.\nimport <iostream>;\nimport <vector>;\nimport <algorithm>;\nimport box;      // From Ex13_03A\n\nint main()\n{\n  std::vector boxes{ Box{1,2,3}, Box{5,2,3}, Box{9,2,1}, Box{3,2,1} };\n\n  // Define a lambda functor to print the result of find() or find_if():\n  auto print_result{ [&boxes](auto result)\n  {\n    if (result == end(boxes))\n      std::cout << \"No box found.\" << std::endl;\n    else\n      std::cout << \"Found matching box at position \"\n                << (result - begin(boxes)) << std::endl;\n  }};\n\n  // Find an exact box\n  Box box_to_find{ 3,2,1 };\n  auto result{ std::ranges::find(boxes, box_to_find) };\n  print_result(result);\n\n  // Find a box with a volume larger than that of box_to_find\n  const auto required_volume{ box_to_find.volume() };\n  result = std::ranges::find_if(boxes,\n              [required_volume](const Box& box) { return box > required_volume; });\n  print_result(result);\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_13/Ex20_13.cpp",
    "content": "// Extracting all odd numbers.\nimport <iostream>;\nimport <set>;\nimport <vector>;\nimport <algorithm>;\n\nstd::set<int> fillSet_1toN(size_t N);        // Fill a set with 1, 2, ..., N\nvoid printVector(const std::vector<int>& v); // Print the contents of a vector to std::cout\n\nint main()\n{\n  const size_t num_numbers{20};\n\n  const auto numbers{ fillSet_1toN(num_numbers) };\n\n  std::vector<int> odd_numbers( numbers.size() ); // Caution: not { numbers.size() } here!\n  auto end_odd_numbers{ std::copy_if(begin(numbers), end(numbers), begin(odd_numbers),\n                                      [](int n) { return n % 2 == 1; }) };\n  odd_numbers.erase(end_odd_numbers, end(odd_numbers));\n\n  printVector(odd_numbers);\n}\n\nstd::set<int> fillSet_1toN(size_t N)   // Fill a set with 1, 2, ..., N\n{\n  std::set<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.insert(i);\n  return numbers;\n}\n\nvoid printVector(const std::vector<int>& v)\n{\n  for (auto i : v) std::cout << i << ' ';\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_13A/Ex20_13A.cpp",
    "content": "// Extracting all odd numbers using std::back_inserter().\nimport <iostream>;\nimport <set>;\nimport <vector>;\nimport <algorithm>;\nimport <iterator>;\t           // For std::back_inserter()\n\nstd::set<int> fillSet_1toN(size_t N);        // Fill a set with 1, 2, ..., N\nvoid printVector(const std::vector<int>& v); // Print the contents of a vector to std::cout\n\nint main()\n{\n  const size_t num_numbers{20};\n\n  const auto numbers{ fillSet_1toN(num_numbers) };\n\n  std::vector<int> odd_numbers;\n  std::copy_if(begin(numbers), end(numbers), back_inserter(odd_numbers),\n               [](int n) { return n % 2 == 1; });\n\n  printVector(odd_numbers);\n}\n\nstd::set<int> fillSet_1toN(size_t N)   // Fill a set with 1, 2, ..., N\n{\n  std::set<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.insert(i);\n  return numbers;\n}\n\nvoid printVector(const std::vector<int>& v)\n{\n  for (auto i : v) std::cout << i << ' ';\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_13B/Ex20_13B.cpp",
    "content": "// Extracting all odd numbers using std::back_inserter().\n// This time using the range-based version of std::copy_if().\nimport <iostream>;\nimport <set>;\nimport <vector>;\nimport <algorithm>;\nimport <iterator>;             // For std::back_inserter()\n\nstd::set<int> fillSet_1toN(size_t N);        // Fill a set with 1, 2, ..., N\nvoid printVector(const std::vector<int>& v); // Print the contents of a vector to std::cout\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  const auto numbers{ fillSet_1toN(num_numbers) };\n\n  std::vector<int> odd_numbers;\n  std::ranges::copy_if(numbers, back_inserter(odd_numbers),\n    [](int n) { return n % 2 == 1; });\n\n  printVector(odd_numbers);\n}\n\nstd::set<int> fillSet_1toN(size_t N)   // Fill a set with 1, 2, ..., N\n{\n  std::set<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.insert(i);\n  return numbers;\n}\n\nvoid printVector(const std::vector<int>& v)\n{\n  for (auto i : v) std::cout << i << ' ';\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_14/Ex20_14.cpp",
    "content": "// Removing all elements that satisfy a certain condition \n// usign the remove-erase idiom\nimport <vector>;\nimport <string_view>;\nimport <iostream>;\nimport <algorithm>;\n\nstd::vector<int> fillVector_1toN(size_t N);  // Fill a vector with 1, 2, ..., N\nvoid printVector(std::string_view message, const std::vector<int>& numbers);\n\nvoid removeEvenNumbers(std::vector<int>& numbers)\n{\n  // Use the remove_if() algorithm to remove all even numbers\n  auto first_to_erase{ std::remove_if(begin(numbers), end(numbers),\n                                      [](int number) { return number % 2 == 0; }) };\n  // Erase all elements including and beyond first_to_erase  \n  numbers.erase(first_to_erase, end(numbers));\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ fillVector_1toN(num_numbers) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  removeEvenNumbers(numbers);\n\n  printVector(\"The numbers that were kept\", numbers);\n}\n\nstd::vector<int> fillVector_1toN(size_t N)\n{\n  std::vector<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.push_back(i);\n  return numbers;\n}\n\nvoid printVector(std::string_view message, const std::vector<int>& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_14A/Ex20_14A.cpp",
    "content": "// Removing all elements that satisfy a certain condition usign std::erase_if()\nimport <vector>;\nimport <string_view>;\nimport <iostream>;\n\nstd::vector<int> fillVector_1toN(size_t N);  // Fill a vector with 1, 2, ..., N\nvoid printVector(std::string_view message, const std::vector<int>& numbers);\n\nvoid removeEvenNumbers(std::vector<int>& numbers)\n{\n  std::erase_if(numbers, [](int number) { return number % 2 == 0; });\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ fillVector_1toN(num_numbers) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  removeEvenNumbers(numbers);\n\n  printVector(\"The numbers that were kept\", numbers);\n}\n\nstd::vector<int> fillVector_1toN(size_t N)\n{\n  std::vector<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.push_back(i);\n  return numbers;\n}\n\nvoid printVector(std::string_view message, const std::vector<int>& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_14B/Ex20_14B.cpp",
    "content": "// Removing all elements that satisfy a certain condition \n// usign the remove-erase idiom and the range-based version of std::remove_if.\n// Unlike the iterator-based version, std::ranges::erase_if() returns a subrange, \n// and not an iterator. \n// Note also that in this case std::erase_if() is even more compact (see Ex20_14A).\nimport <vector>;\nimport <string_view>;\nimport <iostream>;\nimport <algorithm>;\n\nstd::vector<int> fillVector_1toN(size_t N);  // Fill a vector with 1, 2, ..., N\nvoid printVector(std::string_view message, const std::vector<int>& numbers);\n\nvoid removeEvenNumbers(std::vector<int>& numbers)\n{\n  // Use the remove_if() algorithm to remove all even numbers\n  auto [first_to_erase, last_to_erase] \n    { std::ranges::remove_if(numbers, [](int number) { return number % 2 == 0; }) };\n  // Erase all elements including and beyond first_to_erase  \n  numbers.erase(first_to_erase, last_to_erase);\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ fillVector_1toN(num_numbers) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  removeEvenNumbers(numbers);\n\n  printVector(\"The numbers that were kept\", numbers);\n}\n\nstd::vector<int> fillVector_1toN(size_t N)\n{\n  std::vector<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.push_back(i);\n  return numbers;\n}\n\nvoid printVector(std::string_view message, const std::vector<int>& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_15/Ex20_15.cpp",
    "content": "// Sorting strings\nimport <iostream>;\nimport <string>;\nimport <vector>;\nimport <algorithm>;\n\nint main()\n{\n  std::vector<std::string> names{\"Frodo Baggins\", \"Gandalf the Gray\", \n    \"Aragon\", \"Samwise Gamgee\", \"Peregrin Took\", \"Meriadoc Brandybuck\", \n    \"Gimli\", \"Legolas Greenleaf\", \"Boromir\"};\n\n  // Sort the names lexicographically\n  std::sort(begin(names), end(names));\n  std::cout << \"Names sorted lexicographically:\" << std::endl;\n  for (const auto& name : names) std::cout << name << \", \";\n  std::cout << std::endl << std::endl;  \n\n  // Sort the names by length\n  std::sort(begin(names), end(names),\n    [](const auto& left, const auto& right) {return left.length() < right.length(); });\n  std::cout << \"Names sorted by length:\" << std::endl;\n  for (const auto& name : names) std::cout << name << \", \";\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_15A/Ex20_15A.cpp",
    "content": "// Sorting strings using range-based sort()\nimport <iostream>;\nimport <string>;\nimport <vector>;\nimport <algorithm>;\n\nint main()\n{\n  std::vector<std::string> names{\"Frodo Baggins\", \"Gandalf the Gray\", \n    \"Aragon\", \"Samwise Gamgee\", \"Peregrin Took\", \"Meriadoc Brandybuck\", \n    \"Gimli\", \"Legolas Greenleaf\", \"Boromir\"};\n\n  // Sort the names lexicographically\n  std::ranges::sort(names);\n  std::cout << \"Names sorted lexicographically:\" << std::endl;\n  for (const auto& name : names) std::cout << name << \", \";\n  std::cout << std::endl << std::endl;  \n\n  // Sort the names by length\n  std::ranges::sort(names,\n    [](const auto& left, const auto& right) {return left.length() < right.length(); });\n  std::cout << \"Names sorted by length:\" << std::endl;\n  for (const auto& name : names) std::cout << name << \", \";\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_16/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_16/Ex20_16.cpp",
    "content": "// Using range adaptors\nimport <iostream>;\nimport <vector>;\nimport <algorithm>;\nimport <iterator>;   // For std::back_inserter()\nimport <ranges>;\nimport box;\n\nusing namespace std::ranges::views;\n\nint main()\n{\n  // Our challenge: given a sequence of boxes, \n  // gather pointers to all boxes larger than required_volume\n  std::vector<Box> boxes{ { 1, 2, 3 }, { 4, 5, 6}, { 7, 8, 9 }, { 10, 11, 12 } };\n  const double required_volume{ 200 };\n\n  // Without range-based algorithms and range adaptors (in two steps):\n  std::vector<Box*> box_pointers;\n  std::transform(begin(boxes), end(boxes), back_inserter(box_pointers),\n    [](Box& box) { return &box; });\n  std::vector<Box*> large_boxes;\n  std::copy_if(begin(box_pointers), end(box_pointers), back_inserter(large_boxes),\n    [=](const Box* box) { return *box >= required_volume; });\n\n  std::cout << \"There are \" << large_boxes.size() << \" large boxes.\" << std::endl;\n\n  // With range-based algorithm copy() and a filter-transform pipeline\n  std::vector<Box*> large_boxes_ranges_copy;\n  std::ranges::copy(\n    boxes | filter([=](const Box& box) { return box >= required_volume; })\n          | transform([](Box& box) { return &box; }),\n    back_inserter(large_boxes_ranges_copy)\n  );\n\n  // With range-based algorithm copy_if() and transform adaptor\n  std::vector<Box*> large_boxes_ranges_copy_if;\n  std::ranges::copy_if(    /* Transform using adaptor before filtering in copy_if() */\n     boxes | transform([](Box& box) { return &box; }),       // Input view of boxes\n     back_inserter(large_boxes_ranges_copy_if),              // Output iterator\n     [=](const Box* box) { return *box >= required_volume; } // Condition for copy_if()\n  );\n\n  // With range-based algorithm transform() and a filter adaptor\n  std::vector<Box*> large_boxes_ranges_transform;\n  std::ranges::transform(  /* Filter using adaptor before transforming using algorithm */\n     boxes | filter([=](const Box& box) { return box >= required_volume; }),\n     back_inserter(large_boxes_ranges_transform),          // Output iterator\n     [](Box& box) { return &box; }        // Transform functor of transform()\n  );\n\n  if (large_boxes_ranges_copy != large_boxes\n    || large_boxes_ranges_copy_if != large_boxes\n    || large_boxes_ranges_transform != large_boxes)\n  {\n    std::cerr << \"Oh dear... One of the range-based algorithms gave a different result!\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_17/Ex20_17.cpp",
    "content": "// Range factories and range adaptors\nimport <iostream>;\nimport <ranges>;   // For views, range factories, and range adaptors\n\nusing namespace std::ranges::views;\n\nbool isEven(int i) { return i % 2 == 0; }\nint squared(int i) { return i * i; }\n\nint main()\n{\n  for (int i : iota(1, 10))       // Lazily generate range [1,10)\n    std::cout << i << ' ';\n  std::cout << std::endl;\n\n  for (int i : iota(1, 1000) | filter(isEven) | transform(squared)\n    | drop(2) | take(5) | reverse)\n    std::cout << i << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 20/Ex20_18/Ex20_18.cpp",
    "content": "// Writing through a view\nimport <iostream>;\nimport <vector>;\nimport <ranges>;   // For views, range factories, and range adaptors\n\nbool isEven(int i) { return i % 2 == 0; }\n\nint main()\n{\n  std::vector numbers{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n\n  for (int& i : numbers | std::ranges::views::filter(isEven))\n    i *= i;\n\n  for (int i : numbers) std::cout << i << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 21/Ex21_01/Ex21_01.cpp",
    "content": "// Class template instantiation errors\nimport <set>;\nimport <list>;\nimport <vector>;\nimport <algorithm>;\n\nclass MyClass { /* just a dummy class */ };\n\nint main()\n{\n  std::vector<int&> v;\n\n  MyClass one, other;\n  auto biggest{ std::max(one, other) };\n\n  std::set<MyClass> objects;\n  objects.insert(MyClass{});\n\n  std::list numbers{ 4, 1, 3, 2 };\n  std::sort(begin(numbers), end(numbers));\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 21/Ex21_02/Ex21_02.cpp",
    "content": "// Asserting that a type models a concept\nimport <concepts>;    // For the std::same_as<> and std::convertible_to<> concepts\nimport <ranges>;      // For std::ranges::range<> concept\nimport <type_traits>; // For the std::remove_cv<> type trait\nimport <list>;\nimport <vector>;\nimport <string>;\n\ntemplate <typename Iter>\nconcept BidirectionalIterator = true; // Feel free to further work out all requirements...\n\ntemplate<class Iter>\nconcept RandomAccessIterator = BidirectionalIterator<Iter>\n  && requires(const Iter i, const Iter j, Iter k, const int n)\n     {\n       { i - n } -> std::same_as<Iter>;\n       { i + n } -> std::same_as<Iter>; { n + i } -> std::same_as<Iter>;\n       { k += n }-> std::same_as<Iter&>; { k -= n }-> std::same_as<Iter&>;\n       { i[n] }  -> std::same_as<decltype(*i)>;\n       { i < j } -> std::convertible_to<bool>;\n       { i > j } -> std::convertible_to<bool>;\n       { i <= j } -> std::convertible_to<bool>;\n       { i >= j } -> std::convertible_to<bool>;\n     };\n\ntemplate <typename T>\nconcept NoExceptDestructible = requires (T & value) { { value.~T() } noexcept; };\n\ntemplate <typename C>\nconcept Character = std::same_as<std::remove_cv_t<C>, char>\n                  || std::same_as<std::remove_cv_t<C>, char8_t>\n                  || std::same_as<std::remove_cv_t<C>, char16_t>\n                  || std::same_as<std::remove_cv_t<C>, char32_t>\n                  || std::same_as<std::remove_cv_t<C>, wchar_t>;\n\ntemplate <typename S>\nconcept String = std::ranges::range<S> && requires(S & s, const S & cs)\n{\n  typename S::value_type;\n  requires Character<typename S::value_type>;\n  { cs.length() } -> std::integral;\n  { s[0] } -> std::same_as<typename S::value_type&>;\n  { cs[0] } -> std::convertible_to<typename S::value_type>;\n  { s.data() } -> std::same_as<typename S::value_type*>;\n  { cs.data() } -> std::same_as<const typename S::value_type*>;\n  // ...\n};\n\nstatic_assert(NoExceptDestructible<std::string>);\nstatic_assert(NoExceptDestructible<int>);\nstatic_assert(String<std::string>);\nstatic_assert(!String<std::vector<char>>);\nstatic_assert(Character<char>);\nstatic_assert(Character<const char>);\nstatic_assert(RandomAccessIterator<std::vector<int>::iterator>);\nstatic_assert(!RandomAccessIterator<std::list<int>::iterator>);\nstatic_assert(RandomAccessIterator<int*>);\n\nint main()\n{\n}"
  },
  {
    "path": "Examples/Modules/Chapter 21/Ex21_03/Array.cppm",
    "content": "export module array;\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\nimport <concepts>;\n\nexport template <typename T> requires std::default_initializable<T> && std::destructible<T>\nclass Array\n{\npublic:\n  Array();                                  \n  explicit Array(size_t size);              \n  ~Array();                                 \n  Array(const Array& array) requires std::copyable<T>;\n  Array& operator=(const Array& rhs) requires std::copyable<T>;\n  Array(Array&& array) noexcept requires std::movable<T>;\n  Array& operator=(Array&& rhs) noexcept requires std::movable<T>;\n  void swap(Array& other) noexcept;        \n  T& operator[](size_t index);             \n  const T& operator[](size_t index) const; \n  size_t getSize() const { return m_size; }\n  void push_back(T element) requires std::movable<T>;\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>::Array() \n  : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>::Array(size_t size) \n  : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>::Array(const Array& array) requires std::copyable<T> \n  : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>::Array(Array&& moved) noexcept requires std::movable<T>\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>& Array<T>::operator=(const Array& rhs) requires std::copyable<T>\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>& Array<T>::operator=(Array&& rhs) noexcept requires std::movable<T>\n{\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T> requires std::default_initializable<T> && std::destructible<T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n// push_back() overload for lvalue references\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nvoid Array<T>::push_back(T element) requires std::movable<T>\n{\n  Array<T> newArray{m_size + 1};      // Allocate a larger Array<>\n  for (size_t i{}; i < m_size; ++i)   // Move all existing elements...\n    newArray[i] = std::move(m_elements[i]);\n\n  newArray[m_size] = std::move(element); // Move the new one (could itself be a copy already)...\n\n  swap(newArray);                     // ... and swap!\n}\n\n"
  },
  {
    "path": "Examples/Modules/Chapter 21/Ex21_03/Ex21_03.cpp",
    "content": "// Violating constraints of uninstantiated class members\nimport array;\nimport <memory>;  // For std::unique_ptr<>\n\n// Assert that Array<std::unique_ptr<int>> is a valid type\nstatic_assert(requires { typename Array<std::unique_ptr<int>>; });\n\nint main()\n{\n  Array<std::unique_ptr<int>> tenSmartPointers(10);\n  Array<std::unique_ptr<int>> target;\n  // target = tenSmartPointers;   /* Constraint not satisfied: copyable<unique_ptr> */\n  target = std::move(tenSmartPointers);\n  target.push_back(std::make_unique<int>(123));\n}\n"
  },
  {
    "path": "Examples/Modules/Chapter 21/Ex21_04/Ex21_04.cpp",
    "content": "// Constraint based specialization\nimport <concepts>;  // For the std::equality_comparable<> concept\nimport <iterator>;  // The iterator concepts and the iter_difference_t<>() trait\nimport <vector>;\nimport <list>;\nimport <iostream>;\n\n// Precondition: incrementing first eventually leads to last\ntemplate <std::input_or_output_iterator Iter> requires std::equality_comparable<Iter>\nauto distanceBetween(Iter first, Iter last)\n{\n  std::cout << \"Distance determined by linear traversal: \";\n  std::iter_difference_t<Iter> result{};\n  while (first != last) { ++first; ++result; }\n  return result;\n}\n\ntemplate <std::random_access_iterator Iter>\nauto distanceBetween(Iter first, Iter last)\n{\n  std::cout << \"Distance determined in constant time: \";\n  return last - first;\n}\n\nint main()\n{\n  std::list l{ 'a', 'b', 'c' };\n  std::vector v{ 1, 2, 3, 4, 5 };\n  float a[] { 1.2f, 3.4f, 4.5f };\n\n  std::cout << distanceBetween(cbegin(l), cend(l)) << std::endl;\n  std::cout << distanceBetween(begin(v), end(v)) << std::endl;\n  std::cout << distanceBetween(a, a + std::size(a)) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_01/ExA_01.cpp",
    "content": "// Defining object-like macros\n#include <iostream>\n\n#define POINTER_SIZE sizeof(int*) * BITS_PER_BYTE\n#define BITS_PER_BYTE 8\n\nint main()\n{\n  std::cout << POINTER_SIZE << std::endl;   // 32 or 64, normally\n}\n\n// The next macro (while providing a perfectly valid definition for \"main\") \n// is never applied, because it is not defined yet when the preprocessor \n// processes the line \"int main()\".\n#define main Of chief or leading importance; prime, principal.\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_02/ExA_02.cpp",
    "content": "// Working with preprocessor operators\n#include <iostream>\n\n#define DEFINE_PRINT_FUNCTION(NAME, COUNT, VALUE) \\\n  void NAME##COUNT() { std::cout << #VALUE << std::endl; }\n\nDEFINE_PRINT_FUNCTION(fun, 123, Test 1 \"2\" 3)\n\nint main()\n{\n  fun123();\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_02A/ExA_02A.cpp",
    "content": "// Fun with line continuations\n#include <iostream>\n\n#define DEFINE_PRINT_FUNCT\\\nION(NAME, COUNT, VALUE) vo\\\nid NAME##COUNT() { std::co\\\nut << #VALUE << std::endl; }\n\nDEFINE_PRINT_FUNCTION(fun, 123, Test 1 \"2\" 3)\n\n\\\ni\\\nnt\\\n ma\\\nin()\\\n{fun1\\\n23();}\\\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_03/ExA_03.cpp",
    "content": "// Using std::source_location, C++'s answer to __LINE__ and __FILE__\n#include <iostream>\n#include <source_location>\n#include <string_view>\n#include <format>\n\nvoid logError(std::string_view message,\n              std::source_location location = std::source_location::current())\n{\n  std::cerr << std::format(\"{}:{}:{} - An unexpected error occurred in {}: {}\",\n    location.file_name(), location.line(), location.column(),\n    location.function_name(), message) << std::endl;\n}\n\nint main() \n{ \n  logError(\"OOPS!\");  // The line number in the log message will refer to \n                      // this line in main(), not to the where logError() is defined.\n}"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_04/ExA_04.cpp",
    "content": "// Demonstrating assertions\n#include <iostream>\n#include <format>\n\n// Uncomment to disable the assertion in main() (needs to be defined before including <cassert>)\n//#define NDEBUG\n#include <cassert> \n\nint main()\n{\n  int y{ 5 };\n\n  for (int x{}; x < 20; ++x)\n  {\n    std::cout << std::format(\"x = {}\\ty = {}\", x, y) << std::endl;\n    assert(x < y);\n  }\n}\n\n// A static assertion (comment out to build as a 32-bit program)\nstatic_assert(sizeof(int*) > 4, \"32-bit compilation is not supported.\");"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_05/ExA_05.cpp",
    "content": "// ExA_05.cpp\n// Introducing the #include directive\n#include <iostream>\n\nint main()\n{\n#include \"inclusivity.quote\"\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_05/inclusivity.quote",
    "content": "std::cout << \"We are trying to construct a more inclusive society.\\n\";\nstd::cout << \"We are going to make a country in which no one is left out.\\n\"\n          << \"\\t\\t\\t\\t- Franklin D. Roosevelt\" << std::endl;"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_06/ExA_06.cpp",
    "content": "// Defining the same function twice (won't compile!)\n#include <iostream>\n#include <format>\n\ndouble power(double x, int n);\ndouble power(double x, int n);  // Redundant declaration (harmless)\n\nint main()\n{\n  for (int i{ -3 }; i <= 3; ++i)    // Calculate powers of 8 from -3 to +3\n    std::cout << std::format(\"{:10}\\n\", power(8.0, i));\n  std::cout << std::endl;\n}\n\ndouble power(double x, int n)   // A first definition\n{\n  if (n == 0)      return 1.0;\n  else if (n > 0)  return x * power(x, n - 1);\n  else /* n < 0 */ return 1.0 / power(x, -n);\n}\n\ndouble power(double x, int n);  // Another redundant declaration (harmless)\n\ndouble power(double x, int n)   // A second, more efficient definition (error!)\n{\n  if (n < 0)  return 1.0 / power(x, -n); // Deal with negative exponents\n  if (n == 0) return 1.0;                // Base case of the recursion\n  const double y{ power(x, n / 2) };     // See Exercise 8-8 for an explanation\n  return y * y * (n % 2 == 1 ? x : 1.0);\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_07/ExA_07.cpp",
    "content": "// Calling external functions\n#include <iostream>\n#include <format>\n\ndouble power(double x, int n);   // Declaration of an external power() function\n\nint main()\n{\n  for (int i{ -3 }; i <= 3; ++i)  // Calculate powers of 8 from -3 to +3\n    std::cout << std::format(\"{:10}\\n\", power(8.0, i));\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_07/Power.cpp",
    "content": "// The power function called from ExA_07.cpp is defined in a different translation unit\ndouble power(double x, int n)\n{\n  if (n < 0) return 1.0 / power(x, -n); // Deal with negative exponents\n  if (n == 0) return 1.0;               // Recursion base case\n  const double y{ power(x, n / 2) };    // See Exercise 8-8 for an explanation\n  return y * y * (n % 2 == 1 ? x : 1.0);\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_07A/ExA_07A.cpp",
    "content": "// Calling external functions that are declared in a header file\n#include <iostream>\n#include <format>\n\n#include \"Power.h\"\n\nint main()\n{\n  for (int i{ -3 }; i <= 3; ++i)  // Calculate powers of 8 from -3 to +3\n    std::cout << std::format(\"{:10}\\n\", power(8.0, i));\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_07A/Power.cpp",
    "content": "// The power function called from ExA_07.cpp is defined in a different translation unit\ndouble power(double x, int n)\n{\n  if (n < 0) return 1.0 / power(x, -n); // Deal with negative exponents\n  if (n == 0) return 1.0;               // Recursion base case\n  const double y{ power(x, n / 2) };    // See Exercise 8-8 for an explanation\n  return y * y * (n % 2 == 1 ? x : 1.0);\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_07A/Power.h",
    "content": "// Your first header file containing a declaration of an external power() function\ndouble power(double x, int n);\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_08/ExA_08.cpp",
    "content": "// Using an externally defined variable\n#include <iostream>\n#include <format>\n\n/*extern*/ double power(double x, int n);  // Declaration of an external power() function\n/*extern*/ int power_range;                // Not an unreasonable first attempt, right?\n\nint main()\n{\n  for (int i{ -power_range }; i <= power_range; ++i)  // Calculate powers of 8\n    std::cout << std::format(\"{:10}\\n\", power(8.0, i));\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_08/Power.cpp",
    "content": "// The power function called from ExA_07.cpp is defined in a different translation unit\ndouble power(double x, int n)\n{\n  if (n < 0) return 1.0 / power(x, -n); // Deal with negative exponents\n  if (n == 0) return 1.0;               // Recursion base case\n  const double y{ power(x, n / 2) };    // See Exercise 8-8 for an explanation\n  return y * y * (n % 2 == 1 ? x : 1.0);\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_08/Range.cpp",
    "content": "int power_range{ 3 };            // A global variable with external linkage"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_08A/ExA_08A.cpp",
    "content": "// Using an externally defined constant\n#include <iostream>\n#include <format>\n\nextern double power(double x, int n);  // Declaration of an external power() function\nextern const int power_range;          // Declaration of an external global constant\n\nint main()\n{\n  for (int i{ -power_range }; i <= power_range; ++i)  // Calculate powers of 8\n    std::cout << std::format(\"{:10}\\n\", power(8.0, i));\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_08A/Power.cpp",
    "content": "// The power function called from ExA_07.cpp is defined in a different translation unit\ndouble power(double x, int n)\n{\n  if (n < 0) return 1.0 / power(x, -n); // Deal with negative exponents\n  if (n == 0) return 1.0;               // Recursion base case\n  const double y{ power(x, n / 2) };    // See Exercise 8-8 for an explanation\n  return y * y * (n % 2 == 1 ? x : 1.0);\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_08A/Range.cpp",
    "content": "extern const int power_range{ 3 }; // Definition of a global constant with external linkage"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_09/ExA_09.cpp",
    "content": "// Using a local helper function with internal linkage (see Power.cpp)\n#include <iostream>\n#include <format>\n\nextern double power(double x, int n);  // Declaration of an external power() function\n\nint main()\n{\n  for (int i{ -3 }; i <= 3; ++i)  // Calculate powers of 8\n    std::cout << std::format(\"{:10}\\n\", power(8.0, i));\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_09/Power.cpp",
    "content": "// A local helper function with internal linkage \nnamespace\n{\n  double localHelper(double x, unsigned n)   // localHelper() has internal linkage \n  {\n    if (n == 0) return 1.0;                  // Recursion base case\n    const double y{ localHelper(x, n / 2) }; // See Exercise 8-8 for an explanation\n    return y * y * (n % 2 == 1 ? x : 1.0); \n  }\n}\n\ndouble power(double x, int n)               // power() has external linkage\n{\n  return n >= 0 ? localHelper(x, static_cast<unsigned>(n))\n                : 1.0 / localHelper(x, static_cast<unsigned>(-n));\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_09A/ExA_09A.cpp",
    "content": "// Attempting to call a function with internal linkage from a different translation unit\n#include <iostream>\n#include <format>\n\ndouble localHelper(double x, unsigned n); // Declares an external localHelper() function\n\nint main()\n{\n  for (unsigned i{ 0 }; i <= 5; ++i)  // Calculate positive powers of 8\n    std::cout << std::format(\"{:10}\\n\", localHelper(8.0, i));\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_09A/Power.cpp",
    "content": "// A local helper function with internal linkage \nnamespace\n{\n  double localHelper(double x, unsigned n)   // localHelper() has internal linkage \n  {\n    if (n == 0) return 1.0;                  // Recursion base case\n    const double y{ localHelper(x, n / 2) }; // See Exercise 8-8 for an explanation\n    return y * y * (n % 2 == 1 ? x : 1.0); \n  }\n}\n\ndouble power(double x, int n)               // power() has external linkage\n{\n  return n >= 0 ? localHelper(x, static_cast<unsigned>(n))\n                : 1.0 / localHelper(x, static_cast<unsigned>(-n));\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_10/BadMath.h",
    "content": "auto square(const auto& x) { return x * x; }    // An abbreviated function template\n\nconst double lambda{ 1.303577269034296391257 }; // Conway's constant\n\nenum class Oddity { Even, Odd };\nbool isOdd(int x) { return x % 2 != 0; }\nauto getOddity(int x) { return isOdd(x) ? Oddity::Odd : Oddity::Even; }\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_10/ExA_10.cpp",
    "content": "#include <iostream>\n#include \"BadMath.h\"\n#include \"BadMath.h\"\n\nint main()\n{\n  std::cout << square(1.234) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_10A/BetterMath.h",
    "content": "// A second, better attempt at creating a header file\n#ifndef BETTER_MATH_H\n#define BETTER_MATH_H\n\nauto square(const auto& x) { return x * x; }    // An abbreviated function template\n\nconst double lambda{ 1.303577269034296391257 }; // Conway's constant\n\nenum class Oddity { Even, Odd };\nbool isOdd(int x) { return x % 2 != 0; }\nauto getOddity(int x) { return isOdd(x) ? Oddity::Odd : Oddity::Even; }\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_10A/ExA_10A.cpp",
    "content": "#include <iostream>\n#include \"BetterMath.h\"\n#include \"BetterMath.h\"\n\nint main()\n{\n  std::cout << square(1.234) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_11/BetterMath.h",
    "content": "// A second, better attempt at creating a header file\n#ifndef BETTER_MATH_H\n#define BETTER_MATH_H\n\nauto square(const auto& x) { return x * x; }    // An abbreviated function template\n\nconst double lambda{ 1.303577269034296391257 }; // Conway's constant\n\nenum class Oddity { Even, Odd };\nbool isOdd(int x) { return x % 2 != 0; }\nauto getOddity(int x) { return isOdd(x) ? Oddity::Odd : Oddity::Even; }\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_11/ExA_11.cpp",
    "content": "// Creating multiple definitions of the same functions in a program,\n// even though #include guards are present.\n// (The guards only prevent multiple definitions within one translation unit!)\n#include <iostream>\n#include \"Hypot.h\"\n#include \"Pow4.h\"\n\nint main()\n{\n  std::cout << math::hypot(3, 4) << '\\t' << math::pow4(5) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_11/Hypot.cpp",
    "content": "// Hypot.cpp - Definition of the math::hypot() function\n#include \"BetterMath.h\"  // For the square() function template definition\n#include \"Hypot.h\"       // Missing from the code listing in the book!\n#include <cmath>         // For std::sqrt()\n\n// Caution: See Chapter 11 for why you should always use std::hypot() \n// over this nave definition (based on the Pythagorean Theorem)!\ndouble math::hypot(double x, double y) { return std::sqrt(square(x) + square(y)); }\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_11/Hypot.h",
    "content": "// Declaration of an external math::hypot() function\n#ifndef HYPOT_H\n#define HYPOT_H\n\nnamespace math\n{\n  // Computes the length of the hypotenuse of a right-angle triangle\n  double hypot(double x, double y);\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_11/Pow4.cpp",
    "content": "// Definition of the math::pow4() function\n#include \"BetterMath.h\"  // For the square() function template definition\n\nnamespace math\n{\n  double pow4(double x) { return square(square(x)); }\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_11/Pow4.h",
    "content": "// Declaration of a math::pow4() function\n#ifndef POW4_H\n#define POW4_H\n\nnamespace math\n{\n  // Same as std::pow(x, 4)\n  double pow4(double x);\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_12/ExA_12.cpp",
    "content": "// Using inline definitions to prevent ODR violations when\n// including a header in multiple translation units of the same program.\n#include <iostream>\n#include \"Hypot.h\"\n#include \"Pow4.h\"\n\nint main()\n{\n  std::cout << math::hypot(3, 4) << '\\t' << math::pow4(5) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_12/Hypot.cpp",
    "content": "// Hypot.cpp - Definition of the math::hypot() function\n#include \"ProperMath.h\"  // For the square() function template definition\n#include \"Hypot.h\"       // Missing from the code listing in the book!\n#include <cmath>         // For std::sqrt()\n\n// Caution: See Chapter 11 for why you should always use std::hypot() \n// over this nave definition (based on the Pythagorean Theorem)!\ndouble math::hypot(double x, double y) { return std::sqrt(square(x) + square(y)); }\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_12/Hypot.h",
    "content": "// Declaration of an external math::hypot() function\n#ifndef HYPOT_H\n#define HYPOT_H\n\nnamespace math\n{\n  // Computes the length of the hypotenuse of a right-angle triangle\n  double hypot(double x, double y);\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_12/Pow4.cpp",
    "content": "// Definition of the math::pow4() function\n#include \"ProperMath.h\"  // For the square() function template definition\n\nnamespace math\n{\n  double pow4(double x) { return square(square(x)); }\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_12/Pow4.h",
    "content": "// Declaration of a math::pow4() function\n#ifndef POW4_H\n#define POW4_H\n\nnamespace math\n{\n  // Same as std::pow(x, 4)\n  double pow4(double x);\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_12/ProperMath.h",
    "content": "// Your first, proper header file\n#ifndef PROPER_MATH_H\n#define PROPER_MATH_H\n\nauto square(const auto& x) { return x * x; }  // An abbreviated function template\n\nconst inline double lambda{ 1.303577269034296391257 };       // Conway's constant\n\nenum class Oddity { Even, Odd };\ninline bool isOdd(int x) { return x % 2 != 0; }\ninline auto getOddity(int x) { return isOdd(x) ? Oddity::Odd : Oddity::Even; }\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_13/Box.cpp",
    "content": "#include \"Box.h\"\n\nBox::Box() : Box{ 1.0, 1.0, 1.0 } {}\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{}\n\ndouble Box::getLength() const { return m_length; }\ndouble Box::getWidth() const { return m_width; }\ndouble Box::getHeight() const { return m_height; }\n\ndouble Box::volume() const\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_13/Box.h",
    "content": "// Your first header file with a class definition\n#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box();\n  Box(double length, double width, double height);\n\n  double getLength() const;\n  double getWidth() const;\n  double getHeight() const;\n\n  double volume() const;\n\nprivate:\n  double m_length;\n  double m_width;\n  double m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_13/ExA_13.cpp",
    "content": "// Including a class definition from a header\n#include <iostream>\n#include \"Box.h\"\n\nint main()\n{\n  Box boxy{ 1, 2, 3 };\n  std::cout << boxy.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_13A/Box.h",
    "content": "// Inline class member definitions\n#ifndef BOX_H\n#define BOX_H\n\n#include <ostream>   // Caution: do not use import <ostream>; here!\n\nclass Box\n{\npublic:\n  Box() = default;   // In-class definition, and thus implicitly inline\n  Box(double length, double width, double height);\n  \n  // In-class member definitions are implicitly inline\n  double getLength() const { return m_length; };\n  double getWidth() const  { return m_width; };\n  double getHeight() const { return m_height; };\n  \n  double volume() const;\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Out-of-class member definitions must be explicitly marked as inline \ninline Box::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{}\n\ninline double Box::volume() const\n{\n  return m_length * m_width * m_height;\n}\n\n// Definitions of non-member functions of course must be inline as well\ninline std::ostream& operator<<(std::ostream& out, const Box& box)\n{\n  return out << \"Box(\" << box.getLength() << \", \" \n             << box.getWidth() << \", \" << box.getHeight() << ')';\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Appendix A/ExA_13A/ExA_13A.cpp",
    "content": "// Inline class member definitions (see Box.h)\n#include <iostream>\n#include \"Box.h\"\n\nint main()\n{\n  Box boxy{ 1, 2, 3 };\n  std::cout << boxy.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 01/Ex1_01.cpp",
    "content": "// A complete C++ program\n#include <iostream>\n\nint main()\n{\n  int answer {42};              // Defines answer with value 42\n\n  std::cout << \"The answer to life, the universe, and everything is \"\n            << answer\n            << std::endl;\n\n  return 0;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 01/Ex1_02.cpp",
    "content": "// Using escape sequences\n#include <iostream>\n\nint main()\n{\n  std::cout << \"\\\"Least \\'said\\' \\\\\\n\\t\\tsoonest \\'mended\\'.\\\"\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 02/Ex2_01.cpp",
    "content": "// Writing values of variables to cout\n#include <iostream>    // For user input and output through std::cin / cout\n\nint main()\n{\n  int apple_count {15};                            // Number of apples\n  int orange_count {5};                            // Number of oranges\n  int total_fruit {apple_count + orange_count};    // Total number of fruit\n\n  std::cout << \"The value of apple_count is \"  << apple_count  << std::endl;\n  std::cout << \"The value of orange_count is \" << orange_count << std::endl;\n  std::cout << \"The value of total_fruit is \"  << total_fruit  << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 02/Ex2_02.cpp",
    "content": "// Converting distances\n#include <iostream>    // For user input and output through std::cin / cout\n\nint main() \n{\n  unsigned int yards {}, feet {}, inches {};\n \n  // Convert a distance in yards, feet, and inches to inches\n  std::cout << \"Enter a distance as yards, feet, and inches \"\n            << \"with the three values separated by spaces: \"; \n  std::cin >> yards >> feet >> inches;\n\n  const unsigned feet_per_yard {3};\n  const unsigned inches_per_foot {12};\n  \n  unsigned total_inches {};\n  total_inches = inches + inches_per_foot * (yards*feet_per_yard + feet);\n  std::cout << \"The distances corresponds to \" << total_inches << \" inches.\\n\";\n\n  // Convert a distance in inches to yards feet and inches\n  std::cout << \"Enter a distance in inches: \";\n  std::cin >> total_inches;\n  feet   = total_inches / inches_per_foot;\n  inches = total_inches % inches_per_foot;\n  yards  = feet / feet_per_yard;\n  feet   = feet % feet_per_yard;\n  std::cout << \"The distances corresponds to \"\n            << yards  << \" yards \" \n            << feet   << \" feet \"\n            << inches << \" inches.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 02/Ex2_03.cpp",
    "content": "// Sizing a pond for happy fish\n#include <iostream>\n#include <numbers>   // For the pi constant\n#include <cmath>     // For the square root function\n\nint main()\n{\n  // 2 square feet pond surface for every 6 inches of fish\n  const double fish_factor { 2.0/0.5 };  // Area per unit length of fish\n  const double inches_per_foot { 12.0 };\n\n  double fish_count {};            // Number of fish\n  double fish_length {};           // Average length of fish\n\n  std::cout << \"Enter the number of fish you want to keep: \";\n  std::cin >> fish_count;\n  std::cout << \"Enter the average fish length in inches: \";\n  std::cin >> fish_length;\n  fish_length /= inches_per_foot;  // Convert to feet\n  std::cout << '\\n';\n\n  // Calculate the required surface area\n  const double pond_area {fish_count * fish_length * fish_factor};\n\n  // Calculate the pond diameter from the area\n  const double pond_diameter {2.0 * std::sqrt(pond_area / std::numbers::pi)};\n\n  std::cout << \"Pond diameter required for \" << fish_count << \" fish is \"\n            << pond_diameter << \" feet.\\n\";\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 02/Ex2_03A.cpp",
    "content": "// Expressions with mixed variables types\n// (The difference with the original example \n//  is the type of fish_count and inches_per_foot)\n#include <iostream>\n#include <numbers>   // For the pi constant\n#include <cmath>     // For the square root function\n\nint main()\n{\n  // 2 square feet pond surface for every 6 inches of fish\n  const double fish_factor { 2.0/0.5 };       // Area per unit length of fish\n  const unsigned int inches_per_foot { 12 };  // <-- Used to be of type double\n\n  unsigned int fish_count {};  // Number of fish (used to be of type double as well)\n  double fish_length {};       // Average length of fish\n\n  std::cout << \"Enter the number of fish you want to keep: \";\n  std::cin >> fish_count;\n  std::cout << \"Enter the average fish length in inches: \";\n  std::cin >> fish_length;\n  fish_length /= inches_per_foot;  // Convert to feet\n  std::cout << '\\n';\n\n  // Calculate the required surface area\n  const double pond_area {fish_count * fish_length * fish_factor};\n\n  // Calculate the pond diameter from the area\n  const double pond_diameter {2.0 * std::sqrt(pond_area / std::numbers::pi)};\n\n  std::cout << \"Pond diameter required for \" << fish_count << \" fish is \"\n            << pond_diameter << \" feet.\\n\";\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 02/Ex2_03B.cpp",
    "content": "// Formatting text using std::format()\n#include <iostream>\n#include <format>\n#include <numbers>   // For the pi constant\n#include <cmath>     // For the square root function\n\nint main()\n{\n  // 2 square feet pond surface for every 6 inches of fish\n  const double fish_factor{ 2.0 / 0.5 };       // Area per unit length of fish\n  const unsigned int inches_per_foot{ 12 };\n\n  unsigned int fish_count{};  // Number of fish\n  double fish_length{};       // Average length of fish\n\n  std::cout << \"Enter the number of fish you want to keep: \";\n  std::cin >> fish_count;\n  std::cout << \"Enter the average fish length in inches: \";\n  std::cin >> fish_length;\n  fish_length /= inches_per_foot;  // Convert to feet\n  std::cout << '\\n';\n\n  // Calculate the required surface area\n  const double pond_area{ fish_count * fish_length * fish_factor };\n\n  // Calculate the pond diameter from the area\n  const double pond_diameter{ 2.0 * std::sqrt(pond_area / std::numbers::pi) };\n\n  std::cout << std::format(\"Pond diameter required for {} fish is {} feet.\\n\",\n                           fish_count, pond_diameter);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 02/Ex2_03C.cpp",
    "content": "// Format specifiers for std::format()\n#include <iostream>\n#include <format>\n#include <numbers>   // For the pi constant\n#include <cmath>     // For the square root function\n\nint main()\n{\n  // 2 square feet pond surface for every 6 inches of fish\n  const double fish_factor{ 2.0 / 0.5 };       // Area per unit length of fish\n  const unsigned int inches_per_foot{ 12 };\n\n  unsigned int fish_count{};  // Number of fish\n  double fish_length{};       // Average length of fish\n\n  std::cout << \"Enter the number of fish you want to keep: \";\n  std::cin >> fish_count;\n  std::cout << \"Enter the average fish length in inches: \";\n  std::cin >> fish_length;\n  fish_length /= inches_per_foot;  // Convert to feet\n  std::cout << '\\n';\n\n  // Calculate the required surface area\n  const double pond_area{ fish_count * fish_length * fish_factor };\n\n  // Calculate the pond diameter from the area\n  const double pond_diameter{ 2.0 * std::sqrt(pond_area / std::numbers::pi) };\n\n  std::cout << std::format(\"Pond diameter required for {} fish is {:.2} feet.\\n\",\n                           fish_count, pond_diameter);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 02/Ex2_03D.cpp",
    "content": "// Debugging format specifiers for std::format() using try/catch\n#include <iostream>\n#include <format>\n#include <numbers>   // For the pi constant\n#include <cmath>     // For the square root function\n\nint main()\n{\n  // 2 square feet pond surface for every 6 inches of fish\n  const double fish_factor{ 2.0 / 0.5 };       // Area per unit length of fish\n  const unsigned int inches_per_foot{ 12 };\n\n  unsigned int fish_count{};  // Number of fish\n  double fish_length{};       // Average length of fish\n\n  std::cout << \"Enter the number of fish you want to keep: \";\n  std::cin >> fish_count;\n  std::cout << \"Enter the average fish length in inches: \";\n  std::cin >> fish_length;\n  fish_length /= inches_per_foot;  // Convert to feet\n  std::cout << '\\n';\n\n  // Calculate the required surface area\n  const double pond_area{ fish_count * fish_length * fish_factor };\n\n  // Calculate the pond diameter from the area\n  const double pond_diameter{ 2.0 * std::sqrt(pond_area / std::numbers::pi) };\n\n  try\n  {\n    std::cout << std::format(\"Pond diameter required for {:.2} fish is {:.2} feet.\\n\",\n                             fish_count, pond_diameter);\n  }\n  catch (const std::format_error& error)\n  {\n    std::cout << error.what();  // Outputs \"precision not allowed for this argument type\"\n  }\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 02/Ex2_04.cpp",
    "content": "// Using explicit type conversions\n#include <iostream>\n\nint main()\n{\n  const unsigned feet_per_yard{ 3 };\n  const unsigned inches_per_foot{ 12 };\n  const unsigned inches_per_yard{ feet_per_yard * inches_per_foot };\n\n  double length{};        // Length as decimal yards\n  unsigned int yards{};   // Whole yards\n  unsigned int feet{};    // Whole feet\n  unsigned int inches{};  // Whole inches\n\n  std::cout << \"Enter a length in yards as a decimal: \";\n  std::cin >> length;\n\n  // Get the length as yards, feet, and inches\n  yards = static_cast<unsigned int>(length);\n  feet = static_cast<unsigned int>((length - yards) * feet_per_yard);\n  inches = static_cast<unsigned int>(length * inches_per_yard) % inches_per_foot;\n\n  std::cout << length << \" yards converts to \"\n    << yards << \" yards \"\n    << feet << \" feet \"\n    << inches << \" inches.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 02/Ex2_05.cpp",
    "content": "// The width, alignment, fill, and 0 formatting options of std::format() \n#include <iostream>\n#include <format>\n\nint main()\n{\n  // Default alignment: right for numbers, left otherwise\n  std::cout << std::format(\"{:7}|{:7}|{:7}|{:7}|{:7}\\n\", 1, -.2, \"str\", 'c', true);\n  // Left and right alignment + custom fill character\n  std::cout << std::format(\"{:*<7}|{:*<7}|{:*>7}|{:*>7}|{:*>7}\\n\", 1, -.2, \"str\", 'c', true);\n  // Centered alignment + 0 formatting option for numbers\n  std::cout << std::format(\"{:^07}|{:^07}|{:^7}|{:^7}|{:^7}\\n\", 1, -.2, \"str\", 'c', true);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 02/Ex2_06.cpp",
    "content": "// Formatting numeric values with std::format() \n#include <iostream>\n#include <format>\n#include <numbers>\n\nint main()\n{\n  const double pi{ std::numbers::pi };\n  std::cout << std::format(\"Default: {:.2}, fixed: {:.2f}, scientific: {:.2e}, \"\n    \"general: {:.2g}\\n\", pi, pi, pi, pi);\n  std::cout << std::format(\"Default: {}, binary: {:b}, hex.: {:x}\\n\", 314, 314, 314);\n  std::cout << std::format(\"Default: {}, decimal: {:d}, hex.: {:x}\\n\", 'c', 'c', 'c');\n  std::cout << std::format(\"Alternative hex.: {:#x}, binary: {:#b}, HEX.: {:#X}\\n\",\n    314, 314, 314);\n  std::cout << std::format(\"Forced sign: {:+}, space sign: {: }\\n\", 314, 314);\n  std::cout << std::format(\"All together: {:*<+10.4f}, {:+#09x}\\n\", pi, 314);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 02/Ex2_06B.cpp",
    "content": "// Argument indices for std::format()\n#include <iostream>\n#include <format>\n#include <numbers>\n\nint main()\n{\n  const double pi{ std::numbers::pi };\n  std::cout << std::format(\"Default: {:.2}, fixed: {:.2f}, scientific: {:.2e}, \"\n    \"general: {:.2g}\\n\", pi, pi, pi, pi);\n  std::cout << std::format(\"Default: {0}, binary: {0:b}, hex.: {0:x}\\n\", 314);\n  std::cout << std::format(\"Default: {0}, decimal: {0:d}, hex.: {0:x}\\n\", 'c');\n  std::cout << std::format(\"Alternative hex.: {0:#x}, binary: {0:#b}, HEX.: {0:#X}\\n\", 314);\n  std::cout << std::format(\"Forced sign: {0:+}, space sign: {0: }\\n\", 314);\n  std::cout << std::format(\"All together: {:*<+10.4f}, {:+#09x}\\n\", pi, 314);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 02/Ex2_07.cpp",
    "content": "// Finding maximum and minimum values for data types\n#include <iostream>\n#include <limits>\n#include <format>\n\nint main()\n{\n  std::cout\n    << std::format(\"The range for type short is from {} to {}\\n\",\n      std::numeric_limits<short>::min(), std::numeric_limits<short>::max())\n    << std::format(\"The range for type unsigned int is from {} to {}\\n\",\n      std::numeric_limits<unsigned int>::min(),\n      std::numeric_limits<unsigned int>::max())\n    << std::format(\"The range for type long is from {} to {}\\n\",\n      std::numeric_limits<long>::min(), std::numeric_limits<long>::max())\n    << std::format(\"The positive range for type float is from {} to {}\\n\",\n      std::numeric_limits<float>::min(), std::numeric_limits<float>::max())\n    << std::format(\"The full range for type float is from {} to {}\\n\",\n      std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max())\n    << std::format(\"The positive range for type double is from {} to {}\\n\",\n      std::numeric_limits<double>::min(),\n      std::numeric_limits<double>::max())\n    << std::format(\"The positive range for type long double is from {} to {}\\n\",\n      std::numeric_limits<long double>::min(),\n      std::numeric_limits<long double>::max());\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 03/Ex3_01.cpp",
    "content": "// Using the bitwise operators\n#include <iostream>\n#include <format>\n\nint main()\n{\n  const unsigned int red{ 0xFF0000u };   // Color red\n  const unsigned int white{ 0xFFFFFFu }; // Color white - RGB all maximum\n\n  std::cout << \"Try out bitwise complement, AND and OR operators:\\n\";\n  std::cout << std::format(\"Initial value:       red = {:08X}\\n\", red);\n  std::cout << std::format(\"Complement:         ~red = {:08X}\\n\", ~red);\n\n  std::cout << std::format(\"Initial value:     white = {:08X}\\n\", white);\n  std::cout << std::format(\"Complement:       ~white = {:08X}\\n\", ~white);\n\n  std::cout << std::format(\"Bitwise AND: red & white = {:08X}\\n\", red & white);\n  std::cout << std::format(\"Bitwise  OR: red | white = {:08X}\\n\", red | white);\n\n  std::cout << \"\\nNow try successive exclusive OR operations:\\n\";\n  unsigned int mask{ red ^ white };\n  std::cout << std::format(\"mask = red ^ white = {:08X}\\n\", mask);\n  std::cout << std::format(\"        mask ^ red = {:08X}\\n\", mask ^ red);\n  std::cout << std::format(\"      mask ^ white = {:08X}\\n\", mask ^ white);\n\n  unsigned int flags{ 0xFF };            // Flags variable\n  unsigned int bit1mask{ 0x1 };          // Selects bit 1\n  unsigned int bit6mask{ 0b100000 };     // Selects bit 6\n  unsigned int bit20mask{ 1u << 19 };    // Selects bit 20\n\n  std::cout << \"Use masks to select or set a particular flag bit:\\n\";\n  std::cout << std::format(\"Select bit 1 from flags  : {:08X}\\n\", flags & bit1mask);\n  std::cout << std::format(\"Select bit 6 from flags  : {:08X}\\n\", flags & bit6mask);\n  std::cout << std::format(\"Switch off bit 6 in flags: {:08X}\\n\", flags &= ~bit6mask);\n  std::cout << std::format(\"Switch on bit 20 in flags: {:08X}\\n\", flags |= bit20mask);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 03/Ex3_02.cpp",
    "content": "// Demonstrating scope, lifetime, and global variables\n#include <iostream>\n\nlong count1{999L};         // Global count1\ndouble count2{3.14};       // Global count2\nint count3;                // Global count3 - default initialization\n\nint main()\n{ /* Function scope starts here */\n  int count1{10};          // Hides global count1\n  int count3{50};          // Hides global count3\n  std::cout << \"Value of outer count1 = \"  << count1 << std::endl;\n  std::cout << \"Value of global count1 = \" << ::count1 << std::endl;\n  std::cout << \"Value of global count2 = \" << count2 << std::endl;\n\n  { /* New block scope starts here... */\n    int count1{20};        // This is a new variable that hides the outer count1\n    int count2{30};        // This hides global count2\n    std::cout << \"\\nValue of inner count1 = \"<< count1 << std::endl;\n    std::cout << \"Value of global count1 = \" << ::count1 << std::endl;\n    std::cout << \"Value of inner count2 = \"  << count2 << std::endl;\n    std::cout << \"Value of global count2 = \" << ::count2 << std::endl;\n\n    count1 = ::count1 + 3;   // This sets inner count1 to global count1+3\n    ++::count1;              // This changes global count1\n    std::cout << \"\\nValue of inner count1 = \" << count1 << std::endl;\n    std::cout << \"Value of global count1 = \"  << ::count1 << std::endl;\n    count3 += count2;        // Increments outer count3 by inner count2;\n\n    int count4 {};\n  } /* ...and ends here. */\n\n// std::cout << count4 << std::endl;    // count4 does not exist in this scope!\n\n  std::cout << \"\\nValue of outer count1 = \"<< count1 << std::endl\n            << \"Value of outer count3 = \"  << count3 << std::endl;\n  std::cout << \"Value of global count3 = \" << ::count3 << std::endl;\n\n  std::cout << \"Value of global count2 = \" << count2 << std::endl;\n} /* Function scope ends here */\n"
  },
  {
    "path": "Examples/NoModules/Chapter 03/Ex3_03.cpp",
    "content": "// Operations with enumerations\n#include <iostream>\n#include <format>\n\nint main()\n{\n  enum class Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };\n  Day yesterday{ Day::Monday }, today{ Day::Tuesday }, tomorrow{ Day::Wednesday };\n  const Day poets_day{ Day::Friday };\n\n  enum class Punctuation : char { Comma = ',', Exclamation = '!', Question = '?' };\n  Punctuation ch{ Punctuation::Comma };\n\n  std::cout << std::format(\"yesterday's value is {}{} but poets_day's is {}{}\\n\",\n    static_cast<int>(yesterday), static_cast<char>(ch),\n    static_cast<int>(poets_day), static_cast<char>(Punctuation::Exclamation));\n\n  today = Day::Thursday;        // Assign new ...\n  ch = Punctuation::Question;   // ... enumerator values\n  tomorrow = poets_day;         // Copy enumerator value\n\n  std::cout << std::format(\"Is today's value({}) the same as poets_day({}){}\\n\",\n    static_cast<int>(today), static_cast<int>(poets_day), static_cast<char>(ch));\n\n  //   ch = tomorrow;             /* Uncomment any of these for an error */\n  //   tomorrow = Friday;\n  //   today = 6;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_01.cpp",
    "content": "// Comparing data values\n#include <iostream>\n\nint main()\n{\n  char first {};      // Stores the first character\n  char second {};     // Stores the second character\n\n  std::cout << \"Enter a character: \";\n  std::cin >> first;\n\n  std::cout << \"Enter a second character: \";\n  std::cin >> second;\n\n  // std::cout << std::boolalpha;   /* Output true/false instead of 1/0 */\n\n  std::cout << \"The value of the expression \" << first << '<' << second\n            << \" is \" << (first < second) << std::endl;\n  std::cout << \"The value of the expression \" << first << \"==\" << second\n            << \" is \" << (first == second) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_01A.cpp",
    "content": "// Comparing data values (output using std::format())\n#include <iostream>\n#include <format>\n\nint main()\n{\n  char first {};      // Stores the first character\n  char second {};     // Stores the second character\n\n  std::cout << \"Enter a character: \";\n  std::cin >> first;\n\n  std::cout << \"Enter a second character: \";\n  std::cin >> second;\n\n  std::cout << std::format(\"The value of the expression {} < {} is {}\\n\",\n                           first, second, first < second);\n  std::cout << std::format(\"The value of the expression {} == {} is {}\\n\",\n                           first, second, first == second);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_02.cpp",
    "content": "// Three-way comparison of integers\n#include <compare>  // Required when using operator <=> (even for fundamental types)\n#include <format>\n#include <iostream>\n\nint main()\n{\n  std::cout << \"Please enter a number: \";\n\n  int value;\n  std::cin >> value;\n\n  std::strong_ordering ordering{ value <=> 0 };\n\n  std::cout << std::format(\"value < 0: {}\\n\", ordering == std::strong_ordering::less);\n  std::cout << std::format(\"value > 0: {}\\n\", ordering == std::strong_ordering::greater);\n  std::cout << std::format(\"value == 0: {}\\n\", ordering == std::strong_ordering::equal);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_02A.cpp",
    "content": "// Using the named comparison functions\n#include <compare>  // Required when using operator <=> (even for fundamental types)\n#include <format>\n#include <iostream>\n\nint main()\n{\n  std::cout << \"Please enter a number: \";\n\n  int value;\n  std::cin >> value;\n\n  std::strong_ordering ordering{ value <=> 0 };\n\n  std::cout << std::format(\"value < 0: {}\\n\", std::is_lt(ordering));  // is less than\n  std::cout << std::format(\"value > 0: {}\\n\", std::is_gt(ordering));  // is greater than\n  std::cout << std::format(\"value == 0: {}\\n\", std::is_eq(ordering)); // is equivalent\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_03.cpp",
    "content": "// Using an if statement\n#include <iostream>\n\nint main()\n{\n  std::cout << \"Enter an integer between 50 and 100: \";\n\n  int value {};\n  std::cin >> value;\n\n  if (value)\n    std::cout << \"You have entered a value that is different from zero.\" << std::endl;\n\n  if (value < 50)\n    std::cout << \"The value is invalid - it is less than 50.\" << std::endl;\n\n  if (value > 100)\n    std::cout << \"The value is invalid - it is greater than 100.\" << std::endl;\n\n  std::cout << \"You entered \" << value << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_04.cpp",
    "content": "// Using a nested if\n#include <iostream>\n\nint main()\n{\n  char letter {};                      // Store input here\n  std::cout << \"Enter a letter: \";     // Prompt for the input\n  std::cin >> letter;\n\n  if (letter >= 'A')\n  {                                    // letter is 'A' or larger\n    if (letter <= 'Z')\n    {                                  // letter is 'Z' or smaller\n      std::cout << \"You entered an uppercase letter.\" << std::endl;\n      return 0;\n    }\n  }\n\n  if (letter >= 'a')                   // Test for 'a' or larger\n    if (letter <= 'z')\n    {                                  // letter is >= 'a' and <= 'z'\n      std::cout << \"You entered a lowercase letter.\" << std::endl;\n      return 0;\n    }\n  std::cout << \"You did not enter a letter.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_04A.cpp",
    "content": "// Using the std::isupper() / islower() character classification functions\n#include <iostream>\n#include <cctype>\n\nint main()\n{\n  char letter {};                      // Store input here\n  std::cout << \"Enter a letter: \";     // Prompt for the input\n  std::cin >> letter;\n\n  if (std::isupper(letter))\n  {\n    std::cout << \"You entered an uppercase letter.\" << std::endl;\n    return 0;\n  }\n\n  if (std::islower(letter))\n  {\n    std::cout << \"You entered a lowercase letter.\" << std::endl;\n    return 0;\n  }\n\n  std::cout << \"You did not enter a letter.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_05.cpp",
    "content": "// Using the if-else statement\n#include <iostream>\n\nint main()\n{\n  long number {};      // Stores input\n  std::cout << \"Enter an integer less than 2 billion: \";\n  std::cin >> number;\n\n  if (number % 2) // Test remainder after division by 2\n  { // Here if remainder is 1\n    std::cout << \"Your number is odd.\" << std::endl;\n  }\n  else\n  { // Here if remainder is 0\n    std::cout << \"Your number is even.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_06.cpp",
    "content": "// Combining logical operators for loan approval\n#include <iostream>\n\nint main()\n{\n  int age {};                  // Age of the prospective borrower\n  int income {};               // Income of the prospective borrower\n  int balance {};              // Current bank balance\n\n  // Get the basic data for assessing the loan\n  std::cout << \"Please enter your age in years: \";\n  std::cin  >> age;\n  std::cout << \"Please enter your annual income in dollars: \";\n  std::cin  >> income;\n  std::cout << \"What is your current account balance in dollars: \";\n  std::cin  >> balance;\n\n  // We only lend to people who are at least 21 years of age,\n  // who make over $25,000 per year,\n  // or have over $100,000 in their account, or both.\n  if (age >= 21 && (income > 25'000 || balance > 100'000))\n  {\n    // OK, you are good for the loan - but how much?\n    // This will be the lesser of twice income and half balance\n    int loan {};               // Stores maximum loan amount\n    if (2*income < balance/2)\n    {\n      loan = 2*income;\n    }\n    else\n    {\n      loan = balance/2;\n    }\n    std::cout << \"\\nYou can borrow up to $\" << loan << std::endl;\n  }\n  else     // No loan for you...\n  {\n    std::cout << \"\\nUnfortunately, you don't qualify for a loan.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_07.cpp",
    "content": "// Using the conditional operator to select output.\n#include <iostream>\n#include <format>\n\nint main()\n{\n  int mice {};               // Count of all mice\n  int brown {};              // Count of brown mice\n  int white {};              // Count of white mice\n\n  std::cout << \"How many brown mice do you have? \";\n  std::cin >> brown;\n  std::cout << \"How many white mice do you have? \";\n  std::cin >> white;\n\n  mice = brown + white;\n\n  std::cout << \n    std::format(\"You have {} {} in total.\\n\", mice, mice == 1 ? \"mouse\" : \"mice\");\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_08.cpp",
    "content": "// Using the switch statement\n#include <iostream>\n\nint main()\n{\n  std::cout << \"Your electronic recipe book is at your service.\\n\"\n            << \"You can choose from the following delicious dishes:\\n\"\n            << \"1. Boiled eggs\\n\"\n            << \"2. Fried eggs\\n\"\n            << \"3. Scrambled eggs\\n\"\n            << \"4. Coddled eggs\\n\\n\"\n            << \"Enter your selection number: \";\n\n  int choice {};  // Stores selection value\n  std::cin >> choice;\n\n  switch (choice)\n  {\n  case 1:\n    std::cout << \"Boil some eggs.\" << std::endl;\n    break;\n  case 2:\n    std::cout << \"Fry some eggs.\" << std::endl;\n    break;\n  case 3:\n    std::cout << \"Scramble some eggs.\" << std::endl;\n    break;\n  case 4:\n    std::cout << \"Coddle some eggs.\"  << std::endl;\n    break;\n  default:\n    std::cout << \"You entered a wrong number - try raw eggs.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_09.cpp",
    "content": "// Multiple case actions\n#include <iostream>\n#include <cctype>\n\nint main()\n{\n  char letter {};\n  std::cout << \"Enter a letter: \";\n  std::cin >> letter;\n\n  if (std::isalpha(letter))\n  {\n    switch (std::tolower(letter))\n    {\n    case 'a': case 'e': case 'i': case 'o': case 'u':\n      std::cout << \"You entered a vowel.\" << std::endl;\n      break;\n    default:\n      std::cout << \"You entered a consonant.\" << std::endl;\n      break;\n    }\n  }\n  else\n  {\n    std::cout << \"You did not enter a letter.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 04/Ex4_09A.cpp",
    "content": "// Using a return statement to exit a switch statement\n#include <iostream>\n#include <cctype>\n\nint main()\n{\n  char letter {};\n  std::cout << \"Enter a letter: \";\n  std::cin >> letter;\n\n  if (std::isalpha(letter))\n  {\n    switch (std::tolower(letter))\n    {\n    case 'a': case 'e': case 'i': case 'o': case 'u':\n      std::cout << \"You entered a vowel.\" << std::endl;\n      return 0;                               // Ends the program\n    }\n\n    // We did not exit main() in the above switch, so letter is not a vowel:\n    std::cout << \"You entered a consonant.\" << std::endl;\n  }\n  else\n  {\n    std::cout << \"You did not enter a letter.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_01.cpp",
    "content": "// Using a for loop with an array\n#include <iostream>\n\nint main()\n{\n  const unsigned size {6};                        // Array size\n  unsigned height[size] {26, 37, 47, 55, 62, 75}; // An array of heights\n\n  unsigned total {};                              // Sum of heights\n  for (size_t i {}; i < size; ++i)\n  {\n    total += height[i];\n  }\n\n  const unsigned average {total/size};            // Calculate average height\n  std::cout << \"The average height is \" << average << std::endl;\n\n  unsigned count {};\n  for (size_t i {}; i < size; ++i)\n  {\n    if (height[i] < average) ++count;\n  }\n  std::cout << count << \" people are below average height.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_02.cpp",
    "content": "// Obtaining the number of array elements\n#include <iostream>\n#include <array>       // for std::size()\n\nint main()\n{\n  int values[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};\n\n  std::cout << \"There are \" << std::size(values) << \" elements in the array.\\n\";\n\n  int sum {};\n  const size_t old_school_size{ sizeof(values) / sizeof(values[0]) };\n  for (size_t i {}; i < old_school_size; ++i)\n  {\n    sum += values[i];\n  }\n  std::cout << \"The sum of the array elements is \" << sum << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_03.cpp",
    "content": "// Floating-point control in a for loop\n#include <format>\n#include <iostream>\n#include <numbers>\n\nint main()\n{\n  const size_t values_per_line {3}; // Outputs per line\n  size_t values_current_line {};    // Number of outputs on current line\n  for (double radius {0.2}; radius <= 3.0; radius += 0.2)\n  {\n    const auto area{ std::numbers::pi * radius * radius };\n    std::cout << std::format(\"radius = {:4.2f}, area = {:5.2f}; \", radius, area);\n    if (++values_current_line == values_per_line)  // When enough values written...\n    {\n      std::cout << std::endl;    // ...start a new line...\n      values_current_line = 0;   // ...and reset the line counter\n    }\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_03A.cpp",
    "content": "// Floating-point control in a for loop\n#include <format>\n#include <iostream>\n#include <numbers>\n\nint main()\n{\n  const size_t values_per_line {3}; // Outputs per line\n  size_t values_current_line {};    // Number of outputs on current line\n  for (double radius {0.2}; radius < 3.0 + 0.001; radius += 0.2)\n  {\n    const auto area{ std::numbers::pi * radius * radius };\n    std::cout << std::format(\"radius = {:4.2f}, area = {:5.2f}; \", radius, area);\n    if (++values_current_line == values_per_line)  // When enough values written...\n    {\n      std::cout << std::endl;    // ...start a new line...\n      values_current_line = 0;   // ...and reset the line counter\n    }\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_04.cpp",
    "content": "// Multiple initializations in a loop expression\n#include <iostream>\n#include <format>\n\nint main()\n{\n  unsigned int limit {};\n  std::cout << \"This program calculates n! and the sum of the integers \"\n            << \"up to n for values 1 to limit.\\n\";\n  std::cout << \"What upper limit for n would you like? \";\n  std::cin >> limit;\n\n  // The format string for all rows of the table\n  const auto table_format{ \"{:>8} {:>8} {:>20}\\n\" };\n  \n  // Output column headings\n  std::cout << std::format(table_format, \"integer\", \"sum\", \"factorial\"); \n\n  for (unsigned long long n {1}, sum {}, factorial {1}; n <= limit; ++n)\n  {\n    sum += n;           // Accumulate sum to current n\n    factorial *= n;     // Calculate n! for current n\n    std::cout << std::format(table_format, n, sum, factorial);\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_04A.cpp",
    "content": "// Multiple calculations in a loop expression's third control expression\n// by using the comma operator\n#include <iostream>\n#include <format>\n\nint main() \n{\n  unsigned int limit {};\n  std::cout << \"This program calculates n! and the sum of the integers \"\n            << \"up to n for values 1 to limit.\\n\";\n  std::cout << \"What upper limit for n would you like? \";\n  std::cin >> limit;\n\n  // The format string for all rows of the table\n  const auto table_format{ \"{:>8} {:>8} {:>20}\\n\" };\n  \n  // Output column headings\n  std::cout << std::format(table_format, \"integer\", \"sum\", \"factorial\"); \n\n  for (unsigned long long n {1}, sum {1}, factorial {1}; n <= limit; \n                                  ++n, sum += n, factorial *= n)\n  {\n    std::cout << std::format(table_format, n, sum, factorial);\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_05.cpp",
    "content": "// Using a while loop to calculate the sum of integers from 1 to n and n!\n#include <iostream>\n#include <format>\n\nint main()\n{\n  unsigned int limit {};\n  std::cout << \"This program calculates n! and the sum of the integers \"\n            << \"up to n for values 1 to limit.\\n\";\n  std::cout << \"What upper limit for n would you like? \";\n  std::cin >> limit;\n\n  // The format string for all rows of the table\n  const auto table_format{ \"{:>8} {:>8} {:>20}\\n\" };\n  \n  // Output column headings\n  std::cout << std::format(table_format, \"integer\", \"sum\", \"factorial\"); \n\n  unsigned int n {};\n  unsigned int sum {};\n  unsigned long long factorial {1ULL};\n\n  while (++n <= limit)\n  {\n    sum += n;                    // Accumulate sum to current n\n    factorial *= n;              // Calculate n! for current n\n    std::cout << std::format(table_format, n, sum, factorial);\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_06.cpp",
    "content": "// Using a do-while loop to manage input\n#include <iostream>\n#include <cctype>                                  // For tolower() function\n\nint main()\n{\n  char reply {};                                   // Stores response to prompt for input\n  int count {};                                    // Counts the number of input values\n  double temperature {};                           // Stores an input value\n  double total {};                                 // Stores the sum of all input values\n  do\n  {\n    std::cout << \"Enter a temperature reading: \";  // Prompt for input\n    std::cin >> temperature;                       // Read input value\n\n    total += temperature;                          // Accumulate total of values\n    ++count;                                       // Increment count\n\n    std::cout << \"Do you want to enter another? (y/n): \";\n    std::cin >> reply;                             // Get response\n  } while (std::tolower(reply) == 'y');\n\n  std::cout << \"The average temperature is \" << total/count << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_07.cpp",
    "content": "// Generating multiplication tables using nested loops\n#include <iostream>\n#include <format>\n#include <cctype>\n\nint main()\n{\n  size_t table {};              // Table size\n  const size_t table_min {2};   // Minimum table size - at least up to the 2-times\n  const size_t table_max {12};  // Maximum table size\n  char reply {};                // Response to prompt\n\n  do\n  {\n    std::cout << \n      std::format(\"What size table would you like ({} to {})? \", table_min, table_max);\n    std::cin >> table;          // Get the table size\n    std::cout << std::endl;\n\n    // Make sure table size is within the limits\n    if (table < table_min || table > table_max)\n    {\n      std::cout << \"Invalid table size entered. Program terminated.\" << std::endl;\n      return 1;\n    }\n\n    // Create the top line of the table\n    std::cout << std::format(\"{:>6}\", '|');\n    for (size_t i {1}; i <= table; ++i)\n    {\n      std::cout << std::format(\" {:3} |\", i);\n    }\n    std::cout << std::endl;\n\n    // Create the separator row\n    for (size_t i {}; i <= table; ++i)\n    {\n      std::cout << \"------\";\n    }\n    std::cout << std::endl;\n\n    for (size_t i {1}; i <= table; ++i)\n    {    // Iterate over rows\n      std::cout << std::format(\" {:3} |\", i);      // Start the row\n\n      // Output the values in a row\n      for (size_t j {1}; j <= table; ++j)\n      {\n        std::cout << std::format(\" {:3} |\", i*j);  // For each column\n      }\n      std::cout << std::endl;                      // End the row\n    }\n\n    // Check if another table is required\n    std::cout << \"\\nDo you want another table (y or n)? \";\n    std::cin >> reply;\n\n  } while (std::tolower(reply) == 'y');\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_07A.cpp",
    "content": "// Generating multiplication tables using nested loops\n// In this version an indefinite for loop is used, in combination with break statements.\n#include <iostream>\n#include <format>\n#include <cctype>\t\t// for std::tolower()\n\nint main()\n{\n  size_t table {};              // Table size\n  const size_t table_min {2};   // Minimum table size - at least up to the 2-times\n  const size_t table_max {12};  // Maximum table size\n  char reply {};                // Response to prompt\n\n  const size_t max_tries{ 3 };   // Max. number of times a user can try entering a table size\n  do\n  {\n    for (size_t count{ 1 }; ; ++count)  // Indefinite loop\n    {\n      std::cout <<\n        std::format(\"What size table would you like ({} to {})? \", table_min, table_max);\n      std::cin >> table; // Get the table size\n\n      // Make sure table size is within the limits\n      if (table >= table_min && table <= table_max)\n      {\n        break;      // Exit the input loop\n      }\n      else if (count < max_tries)\n      {\n        std::cout << \"Invalid input - try again.\\n\";\n      }\n      else\n      {\n        std::cout << \"Invalid table size entered - yet again!\\nSorry, only \"\n          << max_tries << \" allowed - program terminated.\" << std::endl;\n        return 1;\n      }\n    }\n\n\n    // Create the top line of the table\n    std::cout << std::format(\"{:>6}\", '|');\n    for (size_t i {1}; i <= table; ++i)\n    {\n      std::cout << std::format(\" {:3} |\", i);\n    }\n    std::cout << std::endl;\n\n    // Create the separator row\n    for (size_t i {}; i <= table; ++i)\n    {\n      std::cout << \"------\";\n    }\n    std::cout << std::endl;\n\n    for (size_t i {1}; i <= table; ++i)\n    {    // Iterate over rows\n      std::cout << std::format(\" {:3} |\", i);      // Start the row\n\n      // Output the values in a row\n      for (size_t j {1}; j <= table; ++j)\n      {\n        std::cout << std::format(\" {:3} |\", i*j);  // For each column\n      }\n      std::cout << std::endl;                      // End the row\n    }\n\n    // Check if another table is required\n    std::cout << \"\\nDo you want another table (y or n)? \";\n    std::cin >> reply;\n\n  } while (std::tolower(reply) == 'y');\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_08.cpp",
    "content": "// Using the continue statement to display ASCII character codes\n#include <iostream>\n#include <format>\n#include <cctype>\n\nint main()\n{\n  const auto header_format{ \"{:^11}{:^11}{:^11}\\n\" };    // 3 cols., 11 wide, centered (^)\n  const auto body_format{ \"{0:^11}{0:^11X}{0:^11d}\\n\" }; // Print same argument three times\n\n  std::cout << std::format(header_format, \"Character\", \"Hexadecimal\", \"Decimal\");\n\n  // Output 7-bit ASCII characters and corresponding codes\n  char ch{};\n  do\n  {\n    if (!std::isprint(ch))  // If it's not printable...\n      continue;             // ...skip this iteration\n    std::cout << std::format(body_format, ch);\n  } while (ch++ < 127);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_09.cpp",
    "content": "// Sorting an array in ascending sequence - using an indefinite while loop\n#include <iostream>\n#include <format>\n\nint main()\n{\n  const size_t size {1000};     // Array size\n  double x[size] {};            // Stores data to be sorted\n  size_t count {};              // Number of values in array\n\n  while (true)\n  {\n    double input {};            // Temporary store for a value\n    std::cout << \"Enter a non-zero value, or 0 to end: \";\n    std::cin >> input;\n    if (input == 0)\n      break;\n\n    x[count] = input;\n\n    if (++count == size)\n    {\n      std::cout << \"Sorry, I can only store \" << size << \" values.\\n\";\n      break;\n    }\n  }\n\n  if (count == 0)\n  {\n    std::cout << \"Nothing to sort...\" << std::endl;\n    return 0;\n  }\n\n  std::cout << \"Starting sort...\" << std::endl;\n\n  while (true)\n  {\n    bool swapped{ false };    // Becomes true when not all values are in order\n    for (size_t i {}; i < count - 1; ++i)\n    {\n      if (x[i] > x[i + 1])    // Out of order so swap them\n      {\n        const auto temp{ x[i] };\n        x[i] = x[i+1];\n        x[i + 1] = temp;\n        swapped = true;\n      }\n    }\n\n    if (!swapped)    // If there were no swaps\n      break;         // ...all values are in order...\n  }                  // ...otherwise, go round again.\n\n  std::cout << \"Your data in ascending sequence:\\n\";\n  const size_t perline {10};         // Number output per line\n  size_t n {};                       // Number on current line\n  for (size_t i {}; i < count; ++i)\n  {\n    std::cout << std::format(\"{:8.1f}\", x[i]);\n    if (++n == perline)              // When perline have been written...\n    {\n      std::cout << std::endl;        // Start a new line and...\n      n = 0;                         // ...reset count on this line\n    }\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_10.cpp",
    "content": "// Classifying the letters in a C-style string\n#include <iostream>\n#include <cctype>\n\nint main()\n{\n  const int max_length {100};   // Array size\n  char text[max_length] {};     // Array to hold input string\n\n  std::cout << \"Enter a line of text:\" << std::endl;\n\n  // Read a line of characters including spaces\n  std::cin.getline(text, max_length);\n  std::cout << \"You entered:\\n\" << text << std::endl;\n\n  size_t vowels {};            // Count of vowels\n  size_t consonants {};        // Count of consonants\n  for (int i {}; text[i] != '\\0'; i++)\n  {\n    if (std::isalpha(text[i]))         // If it is a letter...\n    {\n      switch (std::tolower(text[i]))\n      {                                // ...check lowercase...\n        case 'a': case 'e': case 'i': case 'o': case 'u':\n          ++vowels;                    // ...it is a vowel\n          break;\n\n        default:\n          ++consonants;                    // ...it is a consonant\n      }\n    }\n  }\n  std::cout << \"Your input contained \" << vowels << \" vowels and \"\n            << consonants << \" consonants.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_11.cpp",
    "content": "// Working with strings in an array\n#include <iostream>\n#include <array> // for std::size()\n\nint main()\n{\n  const size_t max_length{ 80 };      // Maximum string length (including \\0)\n  char stars[][max_length]{\n                          \"Fatty Arbuckle\",  \"Clara Bow\",\n                          \"Lassie\",          \"Slim Pickens\",\n                          \"Boris Karloff\",   \"Mae West\",\n                          \"Oliver Hardy\",    \"Greta Garbo\"\n  };\n  size_t choice{};\n\n  std::cout << \"Pick a lucky star! Enter a number between 1 and \"\n    << std::size(stars) << \": \";\n  std::cin >> choice;\n\n  if (choice >= 1 && choice <= std::size(stars))\n  {\n    std::cout << \"Your lucky star is \" << stars[choice - 1] << std::endl;\n  }\n  else\n  {\n    std::cout << \"Sorry, you haven't got a lucky star.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_12.cpp",
    "content": "// Allocating an array at runtime\n// This example does not work with some compilers (such as Visual C++)\n// because dynamic arrays is not standard C++ (it is valid C though).\n#include <iostream>\n#include <format>\n\n#ifdef _MSC_VER   // See Appendix A for an explanation of preprocessing macros\n  #error Visual Studio does not support variable length arrays (not standard C++)\n#endif\n\nint main()\n{\n  size_t count {};\n  std::cout << \"How many heights will you enter? \";\n  std::cin >> count;\n  int height[count];            // Create the array of count elements\n\n  // Read the heights\n  size_t entered {};\n  while (entered < count)\n  {\n    std::cout <<\"Enter a height (in inches): \";\n    std::cin >> height[entered];\n    if (height[entered] > 0)    // Make sure value is positive\n    {\n      ++entered;\n    }\n    else\n    {\n      std::cout << \"A height must be positive - try again.\\n\";\n    }\n  }\n\n  // Calculate the sum of the heights\n  unsigned int total {};\n  for (size_t i {}; i < count; ++i)\n  {\n    total += height[i];\n  }\n  std::cout << std::format(\"The average height is {:.1f}\\n\",\n                              static_cast<float>(total) / count);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_12A.cpp",
    "content": "// Allocating an array at runtime (for loop merged into preceding while loop)\n// This example does not work with some compilers (such as Visual C++)\n// because dynamic arrays is not standard C++ (it is valid C though).\n#include <iostream>\n#include <format>\n\n#ifdef _MSC_VER   // See Appendix A for an explanation of preprocessing macros\n  #error Visual Studio does not support variable length arrays (not standard C++)\n#endif\n\nint main()\n{\n  size_t count {};\n  std::cout << \"How many heights will you enter? \";\n  std::cin >> count;\n  int height[count];            // Create the array of count elements\n\n  // Read the heights\n  unsigned int total {};\n  size_t entered {};\n  while (entered < count)\n  {\n    std::cout << \"Enter a height (in inches): \";\n    std::cin >> height[entered];\n    if (height[entered] > 0)          // Make sure value is positive\n    {\n      total += height[entered++];\n    }\n    else\n    {\n      std::cout << \"A height must be positive - try again.\\n\";\n    }\n  }\n\n  std::cout << std::format(\"The average height is {:.1f}\\n\",\n                              static_cast<float>(total) / count);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_13.cpp",
    "content": "// Comparing array<> objects and plain arrays\n#include <iostream>\n#include <array>\n\nint main()\n{\n  {\n    std::cout << \"First we try out the comparison operators for std::array<> objects:\" << std::endl;\n\t\n    std::array<double,4> these {1.0, 2.0, 3.0, 4.0};\n    std::array<double,4> those {1.0, 2.0, 3.0, 4.0};\n    std::array<double,4> them  {1.0, 1.0, 5.0, 5.0};\n\n    if (these == those) std::cout << \"these and those are equal.\"    << std::endl;\n    if (those != them)  std::cout << \"those and them are not equal.\" << std::endl;\n    if (those > them)   std::cout << \"those are greater than them.\"  << std::endl;\n    if (them < those)   std::cout << \"them are less than those.\"     << std::endl;\n  }\n  \n  std::cout << std::endl;\n  \n  {\n\t  std::cout << \"Next we repeat exactly the same comparisons with plain C++ arrays:\" << std::endl;\n    double these[4] {1.0, 2.0, 3.0, 4.0};\n    double those[4] {1.0, 2.0, 3.0, 4.0};\n    double them[4]  {1.0, 1.0, 5.0, 5.0};\n\n    if (these == those) std::cout << \"these and those are equal.\"    << std::endl;\n    if (those != them)  std::cout << \"those and them are not equal.\" << std::endl;\n    if (those > them)   std::cout << \"those are greater than them.\"  << std::endl;\n    if (them < those)   std::cout << \"them are less than those.\"     << std::endl;\n  }\n  \n  /* The explanation of why this does not work as expected with plain arrays follows in Chapter 6 */\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_14.cpp",
    "content": "// Using array<T,N> to create Body Mass Index (BMI) table\n// BMI = weight/(height*height)\n// weight in kilograms, height in meters\n\n#include <iostream>\n#include <format>\n#include <array>        // For array<T,N>\n\nint main()\n{\n  const unsigned min_wt {100};     // Minimum weight in table (in pounds)\n  const unsigned max_wt {250};     // Maximum weight in table\n  const unsigned wt_step {10};\n  const size_t wt_count {1 + (max_wt - min_wt) / wt_step};\n\n  const unsigned min_ht {48};      // Minimum height in table (inches)\n  const unsigned max_ht {84};      // Maximum height in table\n  const unsigned ht_step {2};\n  const size_t ht_count { 1 + (max_ht - min_ht) / ht_step };\n\n  const double lbs_per_kg {2.2};   // Pounds per kilogram\n  const double ins_per_m {39.37};  // Inches per meter\n  std::array<unsigned, wt_count> weight_lbs {};\n  std::array<unsigned, ht_count> height_ins {};\n\n  // Create weights from 100lbs in steps of 10lbs\n  for (unsigned i{}, w{ min_wt }; i < wt_count; w += wt_step, ++i)\n  {\n    weight_lbs[i] = w;\n  }\n  // Create heights from 48 inches in steps of 2 inches\n  for (unsigned i{}, h{ min_ht }; h <= max_ht; h += ht_step)\n  {\n    height_ins.at(i++) = h;\n  }\n  // Output table headings\n  std::cout << std::format(\"{:>8}\", '|');\n  for (auto w : weight_lbs)\n    std::cout << std::format(\"{:^6}|\", w);\n  std::cout << std::endl;\n  \n  // Output line below headings\n  for (unsigned i{1}; i < wt_count; ++i)\n    std::cout << \"--------\";\n  std::cout << std::endl;\n\n  const unsigned int inches_per_foot {12U};\n  for (auto h : height_ins)\n  {\n    const unsigned feet{ h / inches_per_foot };\n    const unsigned inches{ h % inches_per_foot };\n    std::cout << std::format(\"{:2}'{:2}\\\" |\", feet, inches);\n\n    const double h_m{ h / ins_per_m };     // Height in meter\n    for (auto w : weight_lbs)\n    {\n      const double w_kg = w / lbs_per_kg; // Weight in kilogram\n      const double bmi = w_kg / (h_m * h_m);\n      std::cout << std::format(\" {:2.1f} |\", bmi);\n    }\n    std::cout << std::endl;\n  }\n  // Output line below table\n  for (size_t i {1}; i < wt_count; ++i)\n    std::cout << \"--------\";\n  std::cout << \"\\nBMI from 18.5 to 24.9 is normal\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 05/Ex5_15.cpp",
    "content": "// Sorting an array in ascending sequence - using a vector<T> container\n#include <iostream>\n#include <format>\n#include <vector>\n\nint main()\n{\n  std::vector<double> x;    // Stores data to be sorted\n\n  while (true)\n  {\n    double input {};        // Temporary store for a value\n    std::cout << \"Enter a non-zero value, or 0 to end: \";\n    std::cin >> input;\n    if (input == 0)\n      break;\n\n    x.push_back(input);\n  }\n\n  if (x.empty())\n  {\n    std::cout << \"Nothing to sort...\" << std::endl;\n    return 0;\n  }\n\n  std::cout << \"Starting sort.\" << std::endl;\n\n  while (true)\n  {\n    bool swapped{ false };   // Becomes true when not all values are in order\n    for (size_t i {}; i < x.size() - 1; ++i)\n    {\n      if (x[i] > x[i + 1])   // Out of order so swap them\n      {\n        const auto temp{ x[i] };\n        x[i] = x[i+1];\n        x[i + 1] = temp;\n        swapped = true;\n      }\n    }\n\n    if (!swapped)   // If there were no swaps\n      break;        // ...all values are in order...\n  }                 // ...otherwise, go round again.\n\n  std::cout << \"Your data in ascending sequence:\\n\";\n  const size_t perline {10};   // Number output per line\n  size_t n {};                 // Number on current line\n  for (size_t i {}; i < x.size(); ++i)\n  {\n    std::cout << std::format(\"{:8.1f}\", x[i]);\n    if (++n == perline)        // When perline have been written...\n    {\n      std::cout << std::endl;  // Start a new line and...\n      n = 0;                   // ...reset count on this line\n    }\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 06/Ex6_01.cpp",
    "content": "// The size of pointers\n#include <iostream>\n\nint main()\n{\n  // Print out the size (in number of bytes) of some data types\n  // and the corresponding pointer types:\n  std::cout << sizeof(double)  << \" > \"  << sizeof(char16_t)  << std::endl;\n  std::cout << sizeof(double*) << \" == \" << sizeof(char16_t*) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 06/Ex6_02.cpp",
    "content": "// Dereferencing pointers\n// Calculates the purchase price for a given quantity of items\n#include <iostream>\n#include <format>\n\nint main()\n{\n  int unit_price {295};                // Item unit price in cents\n  int count {};                        // Number of items ordered\n  int discount_threshold {25};         // Quantity threshold for discount\n  double discount {0.07};              // Discount for quantities over discount_threshold\n\n  int* pcount {&count};                // Pointer to count\n  std::cout << \"Enter the number of items you want: \";\n  std::cin >> *pcount;\n  std::cout << std::format(\"The unit price is ${:.2f}\\n\", unit_price / 100.0);\n\n  // Calculate gross price\n  int* punit_price{ &unit_price };      // Pointer to unit_price\n  int price{ *pcount * *punit_price };  // Gross price via pointers\n  auto* pprice {&price};                // Pointer to gross price\n\n  // Calculate net price in US$\n  double net_price{};\n  double* pnet_price {nullptr};\n  pnet_price = &net_price;\n  if (*pcount > discount_threshold)\n  {\n    std::cout << \n      std::format(\"You qualify for a discount of {:.0f} percent.\\n\", discount * 100);\n    *pnet_price = price*(1 - discount) / 100;\n  }\n  else\n  {\n    net_price = *pprice / 100;\n  }\n  std::cout << std::format(\"The net price for {} items is ${:.2f}\\n\", *pcount, net_price);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 06/Ex6_03.cpp",
    "content": "// Initializing pointers with strings\n#include <iostream>\n\nint main()\n{\n  const char* pstar1 {\"Fatty Arbuckle\"};\n  const char* pstar2 {\"Clara Bow\"};\n  const char* pstar3 {\"Lassie\"};\n  const char* pstar4 {\"Slim Pickens\"};\n  const char* pstar5 {\"Boris Karloff\"};\n  const char* pstar6 {\"Mae West\"};\n  const char* pstar7 {\"Oliver Hardy\"};\n  const char* pstar8 {\"Greta Garbo\"};\n  const char* pstr {\"Your lucky star is \"};\n\n  std::cout << \"Pick a lucky star! Enter a number between 1 and 8: \";\n  size_t choice {};\n  std::cin >> choice;\n\n  switch (choice)\n  {\n  case 1: std::cout << pstr << pstar1 << std::endl; break;\n  case 2: std::cout << pstr << pstar2 << std::endl; break;\n  case 3: std::cout << pstr << pstar3 << std::endl; break;\n  case 4: std::cout << pstr << pstar4 << std::endl; break;\n  case 5: std::cout << pstr << pstar5 << std::endl; break;\n  case 6: std::cout << pstr << pstar6 << std::endl; break;\n  case 7: std::cout << pstr << pstar7 << std::endl; break;\n  case 8: std::cout << pstr << pstar8 << std::endl; break;\n  default: std::cout << \"Sorry, you haven't got a lucky star.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 06/Ex6_04.cpp",
    "content": "// Using an array of pointers\n#include <iostream>\n#include <array>      // for std::size()\n\nint main()\n{\n  const char* pstars[] {\n                         \"Fatty Arbuckle\", \"Clara Bow\", \"Lassie\", \n                         \"Slim Pickens\", \"Boris Karloff\", \"Mae West\",\n                         \"Oliver Hardy\", \"Greta Garbo\"\n                       };\n\n  std::cout << \"Pick a lucky star! Enter a number between 1 and \"\n            << std::size(pstars) << \": \";\n  size_t choice {};\n  std::cin >> choice;\n\n  if (choice >= 1 && choice <= std::size(pstars))\n  {\n    std::cout << \"Your lucky star is \" << pstars[choice - 1] << std::endl;\n  }\n  else\n  {\n    std::cout << \"Sorry, you haven't got a lucky star.\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 06/Ex6_05.cpp",
    "content": "// Calculating primes using pointer notation\n#include <iostream>\n#include <format>\n\nint main()\n{\n  const size_t max {100};    // Number of primes required\n  long primes[max] {2L};     // First prime defined\n  size_t count {1};          // Count of primes found so far\n  long trial {3L};           // Candidate prime\n\n  while (count < max)\n  {\n    bool isprime {true}; // Indicates when a prime is found\n\n    // Try dividing the candidate by all the primes we have\n    for (size_t i {}; i < count && isprime; ++i)\n    {\n      isprime = trial % *(primes + i) > 0;   // False for exact division\n    }\n\n    if (isprime)\n    {                              // We got one...\n      *(primes + count++) = trial; // ...so save it in primes array\n    }\n\n    trial += 2;                    // Next value for checking\n  }\n\n  // Output primes 10 to a line\n  std::cout << \"The first \" << max << \" primes are:\" << std::endl;\n  for (size_t i{}; i < max; ++i)\n  {\n    std::cout << std::format(\"{:7}\", *(primes + i));\n    if ((i+1) % 10 == 0)           // Newline after every 10th prime\n      std::cout << std::endl;\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 06/Ex6_06.cpp",
    "content": "// Calculating primes using dynamic memory allocation\n#include <iostream>\n#include <format>\n#include <cmath>       // For square root function (std::sqrt())\n\nint main()\n{\n  size_t max {};       // Number of primes required\n\n  std::cout << \"How many primes would you like? \";\n  std::cin >> max;          // Read number required\n\n  if (max == 0) return 0;   // Zero primes: do nothing\n\n  auto* primes {new unsigned[max]};  // Allocate memory for max primes\n\n  size_t count {1};         // Count of primes found\n  primes[0] = 2;            // Insert first seed prime\n\n  unsigned trial {3};       // Initial candidate prime\n\n  while (count < max)\n  {\n    bool isprime {true};    // Indicates when a prime is found\n\n    const auto limit = static_cast<unsigned>(std::sqrt(trial));\n    for (size_t i {}; primes[i] <= limit && isprime; ++i)\n    {\n      isprime = trial % primes[i] > 0;  // False for exact division\n    }\n\n    if (isprime)                // We got one...\n      primes[count++] = trial;  // ...so save it in primes array\n\n    trial += 2;                 // Next value for checking\n  }\n\n  // Output primes 10 to a line\n  for (size_t i{}; i < max; ++i)\n  {\n    std::cout << std::format(\"{:10}\", primes[i]);\n    if ((i + 1) % 10 == 0)      // After every 10th prime...\n      std::cout << std::endl;   // ...start a new line\n  }\n  std::cout << std::endl;\n\n  delete[] primes;              // Free up memory...\n  primes = nullptr;             // ... and reset the pointer\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 06/Ex6_07.cpp",
    "content": "// Using smart pointers\n#include <iostream>\n#include <format>\n#include <memory>   // For smart pointers\n#include <vector>   // For std::vector<> container\n#include <cctype>   // For std::toupper()\n\nint main()\n{\n  std::vector<std::shared_ptr<std::vector<double>>> records; // Temperature records by days\n  size_t day{ 1 };       // Day number\n\n  while (true)           // Collect temperatures by day\n  {\n    // Vector to store current day's temperatures created in the free store\n    auto day_records{ std::make_shared<std::vector<double>>() };\n    records.push_back(day_records);   // Save pointer in records vector\n\n    std::cout << \"Enter the temperatures for day \" << day++\n              << \" separated by spaces. Enter 1000 to end:\\n\";\n\n    while (true)\n    { // Get temperatures for current day\n      double t{};        // A temperature\n      std::cin >> t;\n      if (t == 1000.0) break;\n\n      day_records->push_back(t);\n    }\n\n    std::cout << \"Enter another day's temperatures (Y or N)? \";\n    char answer{};\n    std::cin >> answer;\n    if (std::toupper(answer) != 'Y') break;\n  }\n\n  day = 1;\n\n  for (auto record : records)\n  {\n    double total{};\n    size_t count{};\n\n    std::cout << std::format(\"\\nTemperatures for day {}:\\n\", day++);\n    for (auto temp : *record)\n    {\n      total += temp;\n      std::cout << std::format(\"{:6.2f}\", temp);\n      if (++count % 5 == 0) std::cout << std::endl;\n    }\n\n    std::cout << std::format(\"\\nAverage temperature: {:.2f}\", total / count) << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 07/Ex7_01.cpp",
    "content": "// Concatenating strings\n#include <iostream>\n#include <string>\n\nint main()\n{\n  std::string first;                             // Stores the first name\n  std::string second;                            // Stores the second name\n\n  std::cout << \"Enter your first name: \";\n  std::cin >> first;                             // Read first name\n\n  std::cout << \"Enter your second name: \";\n  std::cin >> second;                            // Read second name\n\n  std::string sentence {\"Your full name is \"};   // Create basic sentence\n  sentence += first + \" \" + second + \".\";        // Augment with names\n\n  std::cout << sentence << std::endl;            // Output the sentence\n  std::cout << \"The string contains \"            // Output its length\n            << sentence.length() << \" characters.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 07/Ex7_01A.cpp",
    "content": "// Concatenating characters and strings\n// (exactly the same as Ex07_01, except that we use ' ' and '.' instead of \" \" and \".\") \n#include <iostream>\n#include <string>\n\nint main()\n{\n  std::string first;                             // Stores the first name\n  std::string second;                            // Stores the second name\n\n  std::cout << \"Enter your first name: \";\n  std::cin >> first;                             // Read first name\n\n  std::cout << \"Enter your second name: \";\n  std::cin >> second;                            // Read second name\n\n  std::string sentence {\"Your full name is \"};   // Create basic sentence\n  sentence += first + ' ' + second + '.';        // Augment with names\n\n  std::cout << sentence << std::endl;            // Output the sentence\n  std::cout << \"The string contains \"            // Output its length\n            << sentence.length() << \" characters.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 07/Ex7_02.cpp",
    "content": "// Accessing characters in a string\n#include <iostream>\n#include <string>\n#include <cctype>\n\nint main()\n{\n  std::string text;                          // Stores the input\n  std::cout << \"Enter a line of text:\\n\";\n  std::getline(std::cin, text);              // Read a line including spaces\n\n  unsigned vowels {};                        // Count of vowels\n  unsigned consonants {};                    // Count of consonants\n  for (size_t i {}; i < text.length(); ++i)\n  {\n    if (std::isalpha(text[i]))               // Check for a letter\n    {\n      switch (std::tolower(text[i]))         // Convert to lowercase\n      {        \n        case 'a': case 'e': case 'i': case 'o': case 'u':\n          ++vowels;\n          break;\n\n        default:\n          ++consonants;\n          break;\n      }\n    }\n  }\n\n  std::cout << \"Your input contained \" << vowels << \" vowels and \"\n            << consonants << \" consonants.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 07/Ex7_02A.cpp",
    "content": "// Accessing characters in a string\n// (same as Ex7_02, except that this version uses the more convenient range-based for loop)\n#include <iostream>\n#include <string>\n#include <cctype>\t\t// for std::isalpha() and tolower()\n\nint main()\n{\n  std::string text;                              // Stores the input\n  std::cout << \"Enter a line of text:\\n\";\n  std::getline(std::cin, text);                  // Read a line including spaces\n\n  unsigned vowels {};                            // Count of vowels\n  unsigned consonants {};                        // Count of consonants\n  for (const char ch : text)\n  {\n    if (std::isalpha(ch))                        // Check for a letter\n\t{\n      switch (std::tolower(ch))                  // Convert to lowercase\n      {\n        case 'a': case 'e': case 'i': case 'o': case 'u':\n          ++vowels;\n          break;\n\n        default:\n          ++consonants;\n          break;\n      }\n\t}\n  }\n\n  std::cout << \"Your input contained \" \n            << vowels << \" vowels and \"\n            << consonants << \" consonants.\"\n\t\t\t<< std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 07/Ex7_03.cpp",
    "content": "// Comparing strings\n#include <iostream>    // For stream I/O\n#include <format>      // For string formatting\n#include <string>      // For the string type\n#include <vector>      // For the vector container\n\nint main()\n{\n  std::vector<std::string> names;     // Vector of names\n  std::string input_name;             // Stores a name\n\n  for (;;)                            // Indefinite loop (stopped using break)\n  {\n    std::cout << \"Enter a name followed by Enter (leave blank to stop): \";\n    std::getline(std::cin, input_name);  // Read a name and...\n    if (input_name.empty()) break;       // ...if it's not empty...\n    names.push_back(input_name);         // ...add it to the vector\n  }\n\n  // Sort the names in ascending sequence\n  bool sorted {};                      \n  do\n  {\n    sorted = true;                // remains true when names are sorted\n    for (size_t i {1}; i < names.size(); ++i)\n    {\n      if (names[i-1] > names[i])\n      { // Out of order - so swap names\n        names[i].swap(names[i-1]);\n        sorted = false;\n      }\n    }\n  } while (!sorted);\n\n  // Find the length of the longest name\n  size_t max_length{};\n  for (const auto& name : names)\n    if (max_length < name.length())\n      max_length = name.length();\n\n  // Output the sorted names 5 to a line\n  const size_t field_width{ max_length + 2 };\n  size_t count {};\n\n  std::cout << \"In ascending sequence the names you entered are:\\n\";\n  for (const auto& name : names)\n  {\n    std::cout << std::format(\"{:>{}}\", name, field_width); // Right-align + dynamic width\n    if (!(++count % 5)) std::cout << std::endl;\n  }\n\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 07/Ex7_04.cpp",
    "content": "// Searching within strings\n#include <iostream>\n#include <string>\n\nint main()\n{\n  std::string sentence {\"Manners maketh man\"};\n  std::string word {\"man\"};\n  std::cout << sentence.find(word) << std::endl;  // Outputs 15\n  std::cout << sentence.find(\"Ma\") << std::endl;  // Outputs 0\n  std::cout << sentence.find('k') << std::endl;   // Outputs 10\n  std::cout << sentence.find('x') << std::endl;   // Outputs std::string::npos\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 07/Ex7_05.cpp",
    "content": "// Searching within substrings\n#include <iostream>\n#include <string>\n\nint main()\n{\n  std::string text;          // The string to be searched\n  std::string word;          // Substring to be found\n  std::cout << \"Enter the string to be searched and press Enter:\\n\";\n  std::getline(std::cin, text);\n\n  std::cout << \"Enter the string to be found and press Enter:\\n\";\n  std::getline(std::cin, word);\n\n  size_t count{};            // Count of substring occurrences\n  size_t index{};            // String index\n  while ((index = text.find(word, index)) != std::string::npos)\n  {\n    ++count;\n    index += word.length();  // Advance by full word (discards overlapping occurrences)\n  }\n\n  std::cout << \"Your text contained \" << count << \" occurrences of \\\"\"\n            << word << \"\\\".\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 07/Ex7_06.cpp",
    "content": "#include <iostream>\n#include <format>\n#include <string> \n#include <vector>\n\nint main()\n{\n  std::string text;                                     // The string to be searched\n  std::cout << \"Enter some text terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n\n  const std::string separators{ \" ,;:.\\\"!?'\\n\" };       // Word delimiters\n  std::vector<std::string> words;                       // Words found\n  size_t start { text.find_first_not_of(separators) };  // First word start index\n\n  while (start != std::string::npos)                    // Find the words\n  {\n    size_t end{ text.find_first_of(separators, start + 1) }; // Find end of word\n    if (end == std::string::npos)                        // Found a separator?\n      end = text.length();                               // No, so set to end of text\n    words.push_back(text.substr(start, end - start));    // Store the word\n    start = text.find_first_not_of(separators, end + 1); // Find first character of next word\n  }\n\n  std::cout << \"Your string contains the following \" << words.size() << \" words:\\n\";\n  size_t count{};                                       // Number output\n  for (const auto& word : words)\n  {\n    std::cout << std::format(\"{:15}\", word);\n    if (!(++count % 5))\n      std::cout << std::endl;\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 07/Ex7_07.cpp",
    "content": "// Replacing words in a string\n#include <iostream>\n#include <string>\n\nint main()\n{\n  std::string text;                                   // The string to be modified\n  std::cout << \"Enter a string terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n\n  std::string word;                                   // The word to be replaced\n  std::cout << \"Enter the word to be replaced: \";\n  std::cin >> word;\n\n  std::string replacement;                            // The word to be substituted\n  std::cout << \"Enter the string to be substituted for \" << word << \": \";\n  std::cin >> replacement;\n\n  if (word == replacement)                            // Verify there's something to do\n  {\n    std::cout << \"The word and its replacement are the same.\\n\"\n              << \"Operation aborted.\" << std::endl;\n    return 1;\n  }\n\n  size_t start {text.find(word)};                      // Index of 1st occurrence of word\n  while (start != std::string::npos)                   // Find and replace all occurrences\n  {\n    text.replace(start, word.length(), replacement);   // Replace word\n    start = text.find(word, start + replacement.length());\n  }\n\n  std::cout << \"\\nThe string you entered is now:\\n\" << text << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_01.cpp",
    "content": "// Calculating powers\n#include <iostream>\n#include <format>\n\n// Function to calculate x to the power n\ndouble power(double x, int n)\n{\n  double result{ 1.0 };\n  if (n >= 0)\n  {\n    for (int i{ 1 }; i <= n; ++i)\n      result *= x;\n  }\n  else // n < 0\n  {\n    for (int i{ 1 }; i <= -n; ++i)\n      result /= x;\n  }\n  return result;\n}\n\nint main()\n{\n  // Calculate powers of 8 from -3 to +3\n  for (int i{ -3 }; i <= 3; ++i)\n    std::cout << std::format(\"{:10g}\", power(8.0, i));\n\n  std::cout << std::endl;\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_02.cpp",
    "content": "// Calculating powers - rearranged\n#include <iostream>\n#include <format>\n\n//double power(double x, int n);               // Function prototype - uncomment for successful compilation\n\nint main()\n{\n  // Calculate powers of 8 from -3 to +3\n  for (int i{ -3 }; i <= 3; ++i)\n    std::cout << std::format(\"{:10}\", power(8.0, i));\n\n  std::cout << std::endl;\n}\n\n// Function to calculate x to the power n\ndouble power(double x, int n)\n{\n  double result{ 1.0 };\n  if (n >= 0)\n  {\n    for (int i{ 1 }; i <= n; ++i)\n      result *= x;\n  }\n  else // n < 0\n  {\n    for (int i{ 1 }; i <= -n; ++i)\n      result /= x;\n  }\n  return result;\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_03.cpp",
    "content": "// Failing to modify the original value of a function argument\n#include <iostream>\n\ndouble changeIt(double value_to_be_changed);    // Function prototype\n\nint main()  \n{\n  double it {5.0};\n  double result {changeIt(it)};\n\n  std::cout << \"After function execution, it = \" << it\n            << \"\\nResult returned is \" << result << std::endl;\n}\n\n// Function that attempts to modify an argument and return it\ndouble changeIt(double it)\n{\n  it += 10.0;                       // This modifies the copy\n  std::cout << \"Within function, it = \" << it << std::endl;\n  return it;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_04.cpp",
    "content": "// Modifying the value of a caller variable\n#include <iostream>\n\ndouble changeIt(double* pointer_to_it);    // Function prototype\n\nint main()\n{\n  double it {5.0};\n  double result {changeIt(&it)};      // Now we pass the address\n\n  std::cout << \"After function execution, it = \" << it\n            << \"\\nResult returned is \" << result << std::endl;\n}\n\n// Function to modify an argument and return it\ndouble changeIt(double* pit)\n{\n  *pit += 10.0;             // This modifies the original double\n  std::cout << \"Within function, *pit = \" << *pit << std::endl;\n  return *pit;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_05.cpp",
    "content": "// Passing an array to a function\n#include <iostream>\n#include <array>          // For std::size()\n\ndouble average(double array[], size_t count);   // Function prototype\n\nint main()\n{\n  double values[] {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};\n  std::cout << \"Average = \" << average(values, std::size(values)) << std::endl;\n}\n\n// Function to compute an average\ndouble average(double array[], size_t count)\n{\n  double sum {};                       // Accumulate total in here\n  for (size_t i {}; i < count; ++i)\n    sum += array[i];                   // Sum array elements\n  return sum / count;                  // Return average\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_05A.cpp",
    "content": "// Passing an array to a function - false expectations\n// Note: with main() as defined in this file, \n// this program will likely either crash or produce garbage output!\n#include <iostream>\n\ndouble average10(double array[10]);        // Function prototype\n\nint main()\n{\n // double values[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\n  double values[] { 1.0, 2.0, 3.0 };           // Only three values!!!\n  std::cout << \"Average = \" << average10(values) << std::endl;\n}\n\n// Function to compute an average\ndouble average10(double array[10])         /* The [10] does not mean what you might expect! */\n{\n  double sum{};                            // Accumulate total in here\n  for (size_t i{} ; i < 10; ++i)\n    sum += array[i];                       // Sum array elements\n  return sum / 10;                         // Return average\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_06.cpp",
    "content": "// Passing a two-dimensional array to a function\n#include <iostream>\n#include <array>\t          // For std::size()\n\ndouble yield(const double values[][4], size_t n);\n\nint main()\n{\n  double beans[3][4] {  { 1.0,   2.0,   3.0,   4.0},\n                        { 5.0,   6.0,   7.0,   8.0},\n                        { 9.0,  10.0,  11.0,  12.0}  };\n\n  std::cout << \"Yield = \" << yield(beans, std::size(beans))\n            << std::endl;\n}\n\n// Function to compute total yield\ndouble yield(const double array[][4], size_t size)\n{\n  double sum  {};\n  for (size_t i {}; i < size; ++i)   // Loop through rows\n  {\n    for (size_t j {}; j < std::size(array[i]); ++j) // Loop through elements in a row\n    {\n      sum += array[i][j];\n    }\n  }\n  return sum;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_06A.cpp",
    "content": "// Passing a two-dimensional array to a function (range-based for loop)\n#include <iostream>\n#include <array>\t          // For std::size()\n\ndouble yield(const double values[][4], size_t n);\n\nint main()\n{\n  double beans[3][4]{ { 1.0,   2.0,   3.0,   4.0},\n                        { 5.0,   6.0,   7.0,   8.0},\n                        { 9.0,  10.0,  11.0,  12.0} };\n\n  std::cout << \"Yield = \" << yield(beans, std::size(beans))\n    << std::endl;\n}\n\n// Function to compute total yield\ndouble yield(const double array[][4], size_t size)\n{\n  double sum{};\n  for (size_t i{}; i < size; ++i)  // Loop through rows\n  {\n    for (double val : array[i])    // Loop through elements in a row\n    {\n      sum += val;\n    }\n  }\n  return sum;\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_07.cpp",
    "content": "// Modifying the value of a caller variable  references vs pointers\n#include <iostream>\n\nvoid change_it_by_pointer(double* reference_to_it);    // Pass pointer (by value)\nvoid change_it_by_reference(double& reference_to_it);  // Pass by reference\n\nint main()\n{\n  double it {5.0};\n\n  change_it_by_pointer(&it);         // Now we pass the address\n  std::cout << \"After first function execution, it = \" << it << std::endl;\n\n  change_it_by_reference(it);        // Now we pass a reference, not the value!\n  std::cout << \"After second function execution, it = \" << it << std::endl;\n}\n\nvoid change_it_by_pointer(double* pit)\n{\n  *pit += 10.0;       // This modifies the original double\n}\nvoid change_it_by_reference(double& pit)\n{\n  pit += 10.0;        // This modifies the original double as well!\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_08.cpp",
    "content": "// Using a reference parameter\n#include <iostream>\n#include <format>\n#include <string>\n#include <vector>\n\nusing std::string;\nusing std::vector;\n\nvoid find_words(vector<string>& words, const string& str, const string& separators);\nvoid list_words(const vector<string>& words);\n\nint main()\n{\n  std::string text;         // The string to be searched\n  std::cout << \"Enter some text terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n\n  const std::string separators {\" ,;:.\\\"!?'\\n\"};  // Word delimiters\n  std::vector<std::string> words;                 // Words found\n\n  find_words(words, text, separators);\n  list_words(words);\n}\n\nvoid find_words(vector<string>& words, const string& text, const string& separators)\n{\n  size_t start {text.find_first_not_of(separators)};     // First word start index\n\n  while (start != string::npos)                          // Find the words\n  {\n    size_t end{ text.find_first_of(separators, start + 1); } // Find end of word\n    if (end == string::npos)                             // Found a separator?\n      end = text.length();                               // No, so set to end of text\n\n    words.push_back(text.substr(start, end - start));    // Store the word\n    start = text.find_first_not_of(separators, end + 1); // Find 1st character of next word\n  }\n}\n\nvoid list_words(const vector<string>& words)\n{\n  std::cout << \"Your string contains the following \" << words.size() << \" words:\\n\";\n  size_t count {};                 // Number of outputted words\n  for (const auto& word : words)\n  {\n    std::cout << std::format(\"{:>15}\", word);\n    if (!(++count % 5))\n      std::cout << std::endl;\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_09A.cpp",
    "content": "// Passing an array to a function - pass by reference\n// Note: with main() as defined in this file, this program will not compile...\n#include <iostream>\n\ndouble average10(const double (&)[10]);        // Function prototype\n\nint main()\n{\n  // Use 10 values to make example compile...\n // double values[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\n  double values[] { 1.0, 2.0, 3.0 };           // Only three values!!!\n  std::cout << \"Average = \" << average10(values) << std::endl;\n}\n\n// Function to compute an average\ndouble average10(const double (&array)[10])   /* Only arrays of length 10 can be passed! */\n{\n  double sum {};                       // Accumulate total in here\n  for (size_t i {}; i < 10; ++i)\n    sum += array[i];                   // Sum array elements\n  return sum / 10;                     // Return average\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_09B.cpp",
    "content": "// Passing an array to a function - pass by reference improved\n#include <iostream>\n#include <array>          // for std::size()\n\ndouble average10(const double (&)[10]);        // Function prototype\n\nint main()\n{\n  double values[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\n // double values[] { 1.0, 2.0, 3.0 };           // Only three values!!!\n  std::cout << \"Average = \" << average10(values) << std::endl;\n}\n\n// Function to compute an average\ndouble average10(const double (&array)[10])\n{\n  double sum {};                       // Accumulate total in here\n  for (double val : array)\n    sum += val;                        // Sum array elements\n  return sum / std::size(array);       // Return average\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_09C.cpp",
    "content": "// Passing an array to a function - use std::array<>\n#include <iostream>\n#include <array>\n\ndouble average10(const std::array<double,10>& array);        // Function prototype\n\nint main()\n{\n  std::array<double,10> values{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\n // std::array<double,3> values{ 1.0, 2.0, 3.0 };           // Only three values!!!\n  std::cout << \"Average = \" << average10(values) << std::endl;\n}\n\n// Function to compute an average\ndouble average10(const std::array<double,10>& array)\n{\n  double sum {};                       // Accumulate total in here\n  for (double val : array)\n    sum += val;                        // Sum array elements\n  return sum / array.size();           // Return average\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_10.cpp",
    "content": "// Implicit conversions of reference parameters\n#include <iostream>\n\nvoid double_it(double& it)      { it *= 2; }\nvoid print_it(const double& it) { std::cout << it << std::endl; }\n\nint main()\n{\n  double d{123};\n  double_it(d);\n  print_it(d);\n\n  int i{456};\n  // double_it(i);        /* error, does not compile! */\n  print_it(i);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_11.cpp",
    "content": "// Using multiple default parameter values\n#include <iostream>\n#include <format>\n#include <string>\n\n// The function prototype including defaults for parameters\nvoid show_data(const int data[], size_t count = 1,  \n               const std::string& title = \"Data Values\",\n               size_t width = 10, size_t perLine = 5);\nint main()\n{\n  int samples[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};\n\n  int dataItem {-99};\n  show_data(&dataItem);\n\n  dataItem = 13;\n  show_data(&dataItem, 1, \"Unlucky for some!\");\n\n  show_data(samples, std::size(samples));\n  show_data(samples, std::size(samples), \"Samples\");\n  show_data(samples, std::size(samples), \"Samples\", 6);\n  show_data(samples, std::size(samples), \"Samples\", 8, 4);\n}\n\nvoid show_data(const int data[], size_t count, const std::string& title, \n               size_t width, size_t perLine)\n{\n  std::cout << title << std::endl;    // Display the title\n\n  // Output the data values\n  for (size_t i {}; i < count; ++i)\n  {\n    std::cout << std::format(\"{:{}}\", data[i], width); // Display a data item\n    if ((i+1) % perLine == 0)                          // Newline after perLine values\n      std::cout << '\\n';\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_12.cpp",
    "content": "// Program that lists its command line arguments\n#include <iostream>\n\nint  main(int argc, char* argv[])\n{\n  for (int i{}; i < argc; ++i)\n    std::cout << argv[i] << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_13.cpp",
    "content": "// Returning a pointer\n#include <iostream>\n#include <format>\n#include <string>\n#include <array>                  // for std::size()\n\nvoid show_data(const double data[], size_t count = 1, \n               const std::string& title = \"Data Values\",\n               size_t width = 10, size_t perLine = 5);\nconst double* largest(const double data[], size_t count);\nconst double* smallest(const double data[], size_t count);\ndouble* shift_range(double data[], size_t count, double delta);\ndouble* scale_range(double data[], size_t count, double divisor);\ndouble* normalize_range(double data[], size_t count);\n\nint main()\n{\n  double samples[] {\n                     11.0,  23.0,  13.0,  4.0,\n                     57.0,  36.0, 317.0, 88.0,\n                      9.0, 100.0, 121.0, 12.0\n                   };\n\n  const size_t count{std::size(samples)};              // Number of samples\n  show_data(samples, count, \"Original Values\");        // Output original values\n  normalize_range(samples, count);                     // Normalize the values\n  show_data(samples, count, \"Normalized Values\", 12);  // Output normalized values\n}\n\n// Outputs an array of double values\nvoid show_data(const double data[], size_t count, \n               const std::string& title, size_t width, size_t perLine)\n{\n  std::cout << title << std::endl;  // Display the title\n\n  // Output the data values\n  for (size_t i {}; i < count; ++i)\n  {\n    // Display a data item (uses a dynamic field width: see Chapter 7)\n    std::cout << std::format(\"{:{}.6g}\", data[i], width); \n    if ((i + 1) % perLine == 0)     // Newline after perLine values\n      std::cout << '\\n';\n  }\n  std::cout << std::endl;\n}\n\nconst double* smallest(const double data[], size_t count)\n{\n  if (!count) return nullptr;     // There is no smallest in an empty array\n\n  size_t index_min {};\n  for (size_t i {1}; i < count; ++i)\n    if (data[index_min] > data[i])\n      index_min = i;\n\n  return &data[index_min];\n}\n\ndouble* shift_range(double data[], size_t count, double delta)\n{\n  for (size_t i {}; i < count; ++i)\n    data[i] += delta;\n  return data;\n}\n\nconst double* largest(const double data[], size_t count)\n{\n  if (!count) return nullptr;    // There is no largest in an empty array\n\n  size_t index_max {};\n  for (size_t i {1}; i < count; ++i)\n    if (data[index_max] < data[i])\n      index_max = i;\n\n  return &data[index_max];\n}\n\ndouble* scale_range(double data[], size_t count, double divisor)\n{\n  if (!divisor) return data;     // Do nothing for a zero divisor\n\n  for (size_t i{}; i < count; ++i)\n    data[i] /= divisor;\n  return data;\n}\n\ndouble* normalize_range(double data[], size_t count)\n{\n  shift_range(data, count, -(*smallest(data, count)));\n  return scale_range(data, count, *largest(data, count));\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_14.cpp",
    "content": "// Overloading a function\n#include <iostream>\n#include <string>\n#include <vector>\n\n// Function prototypes\ndouble largest(const double data[], size_t count);\ndouble largest(const std::vector<double>& data);\nint largest(const std::vector<int>& data);\nstd::string largest(const std::vector<std::string>& words);\n// int largest(const std::vector<std::string>& words); \n            /* Above function overload would not compile: overloaded functions\n               must differ in more than just their return type! */\nint main()\n{\n  double array[] {1.5, 44.6, 13.7, 21.2, 6.7};\n  std::vector<int> numbers {15, 44, 13, 21, 6, 8, 5, 2};\n  std::vector<double> data{3.5, 5, 6, -1.2, 8.7, 6.4};\n  std::vector<std::string> names {\"Charles Dickens\", \"Emily Bronte\", \n                                  \"Jane Austen\", \"Henry James\", \"Arthur Miller\"};\n  std::cout << \"The largest of array is \" << largest(array, std::size(array)) \n                        << std::endl;\n  std::cout << \"The largest of numbers is \" << largest(numbers) << std::endl;\n  std::cout << \"The largest of data is \" << largest(data) << std::endl;\n  std::cout << \"The largest of names is \" << largest(names) << std::endl;\n}\n\n// Finds the largest of an array of double values\ndouble largest(const double data[], size_t count)\n{\n  double max{ data[0] };\n  for (size_t i{ 1 }; i < count; ++i)\n    if (max < data[i]) max = data[i];\n  return max;\n}\n\n// Finds the largest of a vector of double values\ndouble largest(const std::vector<double>& data)\n{\n  double max {data[0]};\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of int values\nint largest(const std::vector<int>& data)\n{\n  int max {data[0]};\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of string objects\nstd::string largest(const std::vector<std::string>& words)\n{\n  std::string max_word {words[0]};\n  for (const auto& word : words)\n    if (max_word < word) max_word = word;\n  return max_word;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_15.cpp",
    "content": "// Overloading a function with reference parameters\n#include <iostream>\n#include <format>\n\ndouble larger(double a, double b); // Non-reference parameters\nlong& larger(long& a, long& b);    // Reference parameters\n\nint main()\n{\n  double a_double {1.5}, b_double {2.5};\n  std::cout << std::format(\"The larger of double values {} and {} is {}\\n\",\n                           a_double, b_double, larger(a_double, b_double));\n\n  int a_int {15}, b_int {25};\n  std::cout << std::format(\"The larger of int values {} and {} is {}\\n\",\n                  a_int, b_int, \n                  larger(static_cast<long>(a_int), static_cast<long>(b_int)));\n}\n\n// Returns the larger of two floating point values\ndouble larger(double a, double b)\n{\n  std::cout << \"double larger() called.\" << std::endl;\n  return a > b ? a : b;\n}\n\n// Returns the larger of two long references\nlong& larger(long& a, long& b)\n{\n  std::cout << \"long ref larger() called\" << std::endl;\n  return a > b ? a : b;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_16.cpp",
    "content": "// Recursive version of function for x to the power n, n positive or negative\n#include <iostream>\n#include <format>\n\ndouble power(double x, int n);\n\nint main()\n{\n  for (int i{ -3 }; i <= 3; ++i)      // Calculate powers of 8 from -3 to +3\n    std::cout << std::format(\"{:10g}\", power(8.0, i));\n\n  std::cout << std::endl;\n}\n\n// Recursive function to calculate x to the power n\ndouble power(double x, int n)\n{\n  if (n == 0)      return 1.0;\n  else if (n > 0)  return x * power(x, n - 1);\n  else /* n < 0 */ return 1.0 / power(x, -n);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 08/Ex8_17.cpp",
    "content": "// Sorting words recursively\n#include <iostream>\n#include <format>\n#include <memory>\n#include <string>\nusing Words = std::vector<std::shared_ptr<std::string>>;\n\nvoid swap(Words& words, size_t first, size_t second);\nvoid sort(Words& words);\nvoid sort(Words& words, size_t start, size_t end);\nvoid extract_words(Words& words, const std::string& text, const std::string& separators);\nvoid show_words(const Words& words);\nsize_t max_word_length(const Words& words);\n\nint main()\n{\n  Words words;\n  std::string text;                    // The string to be sorted\n  const auto separators{\" ,.!?\\\"\\n\"};  // Word delimiters\n\n  // Read the string to be processed from the keyboard\n  std::cout << \"Enter a string terminated by *:\" << std::endl;\n  getline(std::cin, text, '*');\n\n  extract_words(words, text, separators);\n  if (words.empty())\n  {\n    std::cout << \"No words in text.\" << std::endl;\n    return 0;\n  }\n\n  sort(words);         // Sort the words\n  show_words(words);   // Output the words\n}\n\nvoid extract_words(Words& words, const std::string& text, const std::string& separators)\n{\n  size_t start {text.find_first_not_of(separators)}; // Start index of first word\n\n  while (start != std::string::npos)\n  {\n    size_t end{ text.find_first_of(separators, start + 1) }; // Find end of a word\n    if (end == std::string::npos)                    // Found a separator?\n      end = text.length();                           // Yes, so set to end of text\n    words.push_back(std::make_shared<std::string>(text.substr(start, end - start)));\n    start = text.find_first_not_of(separators, end + 1); // Find start next word\n  }\n}\n\nvoid swap(Words& words, size_t first, size_t second)\n{\n  auto temp{words[first]};\n  words[first] = words[second];\n  words[second] = temp;\n}\n\n// Sort strings in ascending sequence\nvoid sort(Words& words)\n{\n  if (!words.empty())\n    sort(words, 0, words.size() - 1);\n}\n\nvoid sort(Words& words, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle address to partition set\n  swap(words, start, (start + end) / 2);     // Swap middle address with start\n\n  // Check words against chosen word\n  size_t current {start};\n  for (size_t i {start + 1}; i <= end; i++)\n  {\n    if (*words[i] < *words[start])           // Is word less than chosen word?\n      swap(words, ++current, i);             // Yes, so swap to the left\n  }\n\n  swap(words, start, current);               // Swap chosen and last swapped words\n\n  if (current > start) sort(words, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) sort(words, current + 1, end); // Sort right subset if exists\n}\n\nsize_t max_word_length(const Words& words)\n{\n  size_t max {};\n  for (auto& pword : words)\n    if (max < pword->length()) max = pword->length();\n  return max;\n}\n\nvoid show_words(const Words& words)\n{\n  const size_t field_width {max_word_length(words) + 1};\n  const size_t words_per_line {8};\n  std::cout << std::format(\"{:{}}\", *words[0], field_width); // Output first word\n\n  size_t words_in_line {};         // Number of words in current line\n  for (size_t i {1}; i < words.size(); ++i)\n  { // Output newline when initial letter changes or after 8 per line\n    if ((*words[i])[0] != (*words[i - 1])[0] || ++words_in_line == words_per_line)\n    {\n      words_in_line = 0;\n      std::cout << std::endl;\n    }\n    std::cout << std::format(\"{:{}}\", *words[i], field_width); // Output a word\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 09/Ex9_01.cpp",
    "content": "// Working with std::optional<>\n#include <optional>     // std::optional<> is defined in the <optional> module\n#include <iostream>\n#include <string>\n\nstd::optional<size_t> find_last(\n   const std::string& string, char to_find,\n   std::optional<size_t> start_index = std::nullopt); // or: ... start_index = {});\n\nint main()\n{\n  const auto string{ \"Growing old is mandatory; growing up is optional.\" };\n\n  const std::optional<size_t> found_a{ find_last(string, 'a') };\n  if (found_a)\n    std::cout << \"Found the last a at index \" << *found_a << std::endl;\n\n  const auto found_b{ find_last(string, 'b') };\n  if (found_b.has_value())\n    std::cout << \"Found the last b at index \" << found_b.value() << std::endl;\n\n// following line gives an error (cannot convert std::optional<size_t> to size_t)\n// const size_t found_c{ find_last(string, 'c') }; \n                                                   \n  const auto found_early_i{ find_last(string, 'i', 10) };\n  if (found_early_i != std::nullopt)\n    std::cout << \"Found an early i at index \" << *found_early_i << std::endl;\n}\n\nstd::optional<size_t> find_last(const std::string& string, char to_find, \n                                std::optional<size_t> start_index)\n{\n  // code below will not work for empty strings  \n  if (string.empty())            \n    return std::nullopt;         // or: 'return std::optional<size_t>{};'\n                                 // or: 'return {};'\n  // determine the starting index for the loop that follows:\n  size_t index{ start_index.value_or(string.size() - 1) };\n\n  while (true)  // never use while (index >= 0) here, as size_t is always >= 0!\n  {\n    if (string[index] == to_find) return index;\n    if (index == 0) return std::nullopt;\n    --index;\n  }\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 09/Ex9_02.cpp",
    "content": "// Using std::string_view parameters\n#include <iostream>\n#include <format>\n#include <string>\n#include <string_view>\n#include <vector>\n\nusing std::string;\nusing std::string_view;\nusing std::vector;\n\nvoid find_words(vector<string>& words, string_view str, string_view separators);\nvoid list_words(const vector<string>& words);\n\nint main()\n{\n  std::string text;         // The string to be searched\n  std::cout << \"Enter some text terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n\n  const std::string separators{ \" ,;:.\\\"!?'\\n\" };  // Word delimiters\n  std::vector<std::string> words;                 // Words found\n\n  find_words(words, text, separators);\n  list_words(words);\n}\n\nvoid find_words(vector<string>& words, string_view text, string_view separators)\n{\n  size_t start{ text.find_first_not_of(separators) }; // First word start index\n\n  while (start != string_view::npos)                          // Find the words\n  {\n    size_t end{ text.find_first_of(separators, start + 1) };  // Find end of word\n    if (end == string_view::npos)                             // Found a separator?\n      end = text.length();                              // No, so set to end of text\n\n    words.push_back(std::string{ text.substr(start, end - start) }); // Store the word\n// Or: words.emplace_back(text.substr(start, end - start));    // (in-place construction)\n    start = text.find_first_not_of(separators, end + 1); // Find 1st character of next word\n  }\n}\n\nvoid list_words(const vector<string>& words)\n{\n  std::cout << \"Your string contains the following \" << words.size() << \" words:\\n\";\n  size_t count{};                 // Number of outputted words\n  for (const auto& word : words)\n  {\n    std::cout << std::format(\"{:>15}\", word);\n    if (!(++count % 5))\n      std::cout << std::endl;\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 09/Ex9_03.cpp",
    "content": "// Using std::span<> to reduce the number of overloads of largest()\n// Clearly the three resulting functions are still similar. \n// See Chapter 10 on how you can eliminate this duplication using function templates.\n#include <iostream>\n#include <string>\n#include <vector>\n#include <array>\n#include <span>\n\n// Old function prototypes\n//double largest(const double data[], size_t count);\n//double largest(const std::vector<double>& data);\n//int largest(const std::vector<int>& data);\n//std::string largest(const std::vector<std::string>& words);\n\n// New function prototypes\n// (these functions work for any sequential input, not just arrays or vectors)\n/* Caution: these signatures are not ideal yet: see Ex9_03A */\ndouble largest(std::span<double> data);\nint largest(std::span<int> data);\nstd::string largest(std::span<std::string> words);\n\nint main()\n{\n  double array[] {1.5, 44.6, 13.7, 21.2, 6.7};\n  std::vector numbers {15, 44, 13, 21, 6, 8, 5, 2};\n  std::vector data{3.5, 5.0, 6.0, -1.2, 8.7, 6.4};\n  std::array array_data{ 3.5, 5.0, 6.0, -1.2, 8.7, 6.4 }; // Throwing in an std::array for good measure\n  std::vector<std::string> names {\"Charles Dickens\", \"Emily Bronte\", \n                                  \"Jane Austen\", \"Henry James\", \"Arthur Miller\"};\n  std::cout << \"The largest of array is \" << largest(array) << std::endl;\n  std::cout << \"The largest of numbers is \" << largest(numbers) << std::endl;\n  std::cout << \"The largest of data is \" << largest(data) << std::endl;\n  std::cout << \"The largest of array_data is (also) \" << largest(array_data) << std::endl;\n  std::cout << \"The largest of names is \" << largest(names) << std::endl;\n}\n\n// Finds the largest of a span of values\ndouble largest(std::span<double> data)\n{\n  double max {data[0]};\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of int values\nint largest(std::span<int> data)\n{\n  int max {data[0]};\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of string objects\nstd::string largest(std::span<std::string> words)\n{\n  std::string max_word {words[0]};\n  for (const auto& word : words)\n    if (max_word < word) max_word = word;\n  return max_word;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 09/Ex9_03A.cpp",
    "content": "// Using std::span<const T> to ensure largest() works for const inputs\n#include <iostream>\n#include <string>\n#include <vector>\n#include <array>\n#include <span>\n\n// Old function prototypes\n//double largest(const double data[], size_t count);\n//double largest(const std::vector<double>& data);\n//int largest(const std::vector<int>& data);\n//std::string largest(const std::vector<std::string>& words);\n\n// New function prototypes\n// (these functions work for any sequential input, not just arrays or vectors)\ndouble largest(std::span<const double> data);\nint largest(std::span<const int> data);\nstd::string largest(std::span<const std::string> words);\n\nint main()\n{\n  const double array[] {1.5, 44.6, 13.7, 21.2, 6.7};\n  const std::vector numbers {15, 44, 13, 21, 6, 8, 5, 2};\n  const std::vector data{3.5, 5.0, 6.0, -1.2, 8.7, 6.4};\n  const std::array array_data{ 3.5, 5.0, 6.0, -1.2, 8.7, 6.4 }; // Throwing in an std::array for good measure\n  const std::vector<std::string> names {\"Charles Dickens\", \"Emily Bronte\", \n                                  \"Jane Austen\", \"Henry James\", \"Arthur Miller\"};\n  std::cout << \"The largest of array is \" << largest(array) << std::endl;\n  std::cout << \"The largest of numbers is \" << largest(numbers) << std::endl;\n  std::cout << \"The largest of data is \" << largest(data) << std::endl;\n  std::cout << \"The largest of array_data is (also) \" << largest(array_data) << std::endl;\n  std::cout << \"The largest of names is \" << largest(names) << std::endl;\n}\n\n// Finds the largest of a span of values\ndouble largest(std::span<const double> data)\n{\n  double max {data[0]};\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of int values\nint largest(std::span<const int> data)\n{\n  int max {data[0]};\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of string objects\nstd::string largest(std::span<const std::string> words)\n{\n  std::string max_word {words[0]};\n  for (const auto& word : words)\n    if (max_word < word) max_word = word;\n  return max_word;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 10/Ex10_01.cpp",
    "content": "// Using a function template\n#include <iostream>\n#include <format>\n#include <string>\n\ntemplate<typename T> T larger(T a, T b);    // Function template prototype\n\nint main()\n{\n  std::cout << \"Larger of 1.5 and 2.5 is \" << larger(1.5, 2.5) << std::endl;\n  std::cout << \"Larger of 3.5 and 4.5 is \" << larger(3.5, 4.5) << std::endl;\n\n  int big_int {17011983}, small_int {10};\n  std::cout << std::format(\"Larger of {} and {} is {}\\n\", \n                            big_int, small_int, larger(big_int, small_int));\n\n  std::string a_string {\"A\"}, z_string {\"Z\"};\n  std::cout << std::format(R\"(Larger of \"{}\" and \"{}\" is \"{}\")\", \n                           a_string, z_string, larger(a_string, z_string)) << std::endl;\n}\n\n// Template for functions to return the larger of two values\ntemplate <typename T>\nT larger(T a, T b)\n{\n    return a > b ? a : b;\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 10/Ex10_02.cpp",
    "content": "// Overloading function templates\n#include <iostream>\n#include <format>\n#include <string>\n\ntemplate<typename T> T larger(T a, T b);    // Function template prototype\ntemplate <typename T> T* larger(T*, T*);\ntemplate <typename T> const T* larger(const std::vector<T>& data);\n\nint main()\n{\n  int big_int {17011983}, small_int {10};\n  std::cout << std::format(\"Larger of {} and {} is {}\", \n                 big_int, small_int, larger(big_int, small_int)) << std::endl;\n  std::cout << std::format(\"Larger of {} and {} is {}\",\n                 big_int, small_int, *larger(&big_int, &small_int)) << std::endl;\n\n  std::vector<double> data {-1.4, 7.3, -100.0, 54.1, 16.3};\n  std::cout << \"The largest value in data is \" << *larger(data) << std::endl;\n\n  std::vector<std::string> words {\"The\", \"higher\", \"the\", \"fewer\"};\n  std::cout << std::format(R\"(The largest word in words is \"{}\")\", *larger(words)) \n            << std::endl;\n}\n\n// Template for functions to return the larger of two values\ntemplate <typename T>\nT larger(T a, T b)\n{\n    return a > b ? a : b;\n}\n\ntemplate<typename T>\nT* larger(T* a, T* b)\n{\n  return *a > * b ? a : b;\n}\n\ntemplate <typename T>\nconst T* larger(const std::vector<T>& data)\n{\n  const T* result {};       // The largest of an empty vector is nullptr\n  for (auto& value : data)\n    if (!result || value > *result) result = &value;\n  return result;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 10/Ex10_03.cpp",
    "content": "// Using return type deduction with templates\n#include <iostream>\n#include <string>\n\n// Template for functions to return the larger of two values\n// Supports implicit converion of differently-typed arguments\ntemplate <typename T1, typename T2>\nauto larger(const T1& a, const T2& b)\n{\n  return a > b ? a : b;\n}\n\nint main()\n{\n  int small_int {10};\n  std::cout << \"Larger of \" << small_int << \" and 9.6 is \"\n            << larger(small_int, 9.6) << std::endl;       // deduced return type: double\n  \n  std::string a_string {\"A\"};\n  std::cout << \"Larger of \\\"\" << a_string << \"\\\" and \\\"Z\\\" is \\\"\"\n            << larger(a_string, \"Z\") << '\"' << std::endl; // deduced return type: std::string\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 10/Ex10_03A.cpp",
    "content": "// Using return type deduction with templates (decltype(auto) instead of auto)\n#include <iostream>\n#include <string>\n#include <vector>\n\n// Template for functions to return the larger of two values\n// Supports implicit converion of differently-typed arguments\ntemplate <typename T1, typename T2>\ndecltype(auto) larger(const T1& a, const T2& b)\n{\n  return a > b ? a : b;\n}\n\nint main()\n{\n  const int small_int {10};\n  std::cout << \"Larger of \" << small_int << \" and 9.6 is \"\n            << larger(small_int, 9.6) << std::endl;       // deduced return type: double\n  \n  const std::string a_string {\"A\"};\n  std::cout << \"Larger of \\\"\" << a_string << \"\\\" and \\\"Z\\\" is \\\"\"\n            << larger(a_string, \"Z\") << '\"' << std::endl; // deduced return type: std::string\n\n  const std::vector v1{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n  const std::vector v2{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 11 };\n  std::cout << \"The larger of our two vectors ends with \" << larger(v1, v2).back();\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 10/Ex10_04.cpp",
    "content": "// Defining templates for functions that accept fixed-size arrays\n#include <iostream>\n\ntemplate <typename T, size_t N>\nT average(const T(&array)[N]);\n\nint main()\n{\n  double doubles[2]{ 1.0, 2.0 };\n  std::cout << average(doubles) << std::endl;\n\n  double moreDoubles[]{ 1.0, 2.0, 3.0, 4.0 };\n  std::cout << average(moreDoubles) << std::endl;\n\n  // double* pointer = doubles;\n  // std::cout << average(pointer) << std::endl;      /* will not compile */\n\n  std::cout << average({ 1.0, 2.0, 3.0, 4.0 }) << std::endl;\n\n  int ints[] = { 1, 2, 3, 4 };\n  std::cout << average(ints) << std::endl;\n}\n\ntemplate <typename T, size_t N>\nT average(const T(&array)[N])\n{\n  T sum{};                            // Accumulate total in here\n  for (size_t i{}; i < N; ++i)\n    sum += array[i];                   // Sum array elements\n  return sum / N;                      // Return average\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 11/Ex11_06/Ex11_06.cpp",
    "content": "// Defining and using a namespace\n\n#include <iostream>\n#include <numbers>\n\nnamespace math\n{\n  const double sqrt2{ 1.414213562373095 };      // the square root of 2\n  auto square(const auto& x) { return x * x; }\n  auto pow4(const auto& x) { return square(square(x)); }\n}\n\nint main()\n{\n  std::cout << \"math::sqrt2 has the value \" << math::sqrt2 << std::endl;\n  std::cout << \"This should be 0: \" << (math::sqrt2 - std::numbers::sqrt2) << std::endl;\n  std::cout << \"This should be 2: \" << math::square(math::sqrt2) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 11/Ex11_07/Ex11_07.cpp",
    "content": "// Separating declarations and definitions of functions\n// declared in a namespace.\n#include <iostream>\n#include \"math.h\"\n\nint main()\n{\n  const double values[]{ 10, 2, 1, 8, 3, 7, 4, 5, 6, 9 };\n  std::cout << \"Arithmetic mean: \" << math::averages::arithmetic_mean(values) << std::endl;\n  std::cout << \"Geometric mean: \" << math::averages::geometric_mean(values) << std::endl;\n  std::cout << \"Root mean square: \" << math::averages::rms(values) << std::endl;\n  std::cout << \"Median: \" << math::averages::median(values) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 11/Ex11_07/math.cpp",
    "content": "#include \"math.h\"\n#include <cmath>    // For std::pow(), std::sqrt(), ...\n#include <limits>   // For std::numeric_limits<double>::quiet_NaN()\n#include <vector>   // For std::numeric_limits<double>::quiet_NaN()\n\nnamespace\n{\n  void quicksort(std::vector<double>& data); // See Chapter 8\n}\n\n// Option 1: define in nested namespace block (compact syntax)\nnamespace math::averages\n{\n  double arithmetic_mean(std::span<const double> data)\n  {\n    // The arithmetic mean, the most commonly used average, \n    // is defined as the sum of all elements divided by the number of elements.\n    double sum {};\n    for (auto value : data)\n      sum += value;\n    \n    return data.empty() \n      ? std::numeric_limits<double>::quiet_NaN() // Or std::nan(\"\")\n      : sum / data.size();\n  }\n}\n\n// Option 2: define in nested namespace blocks\nnamespace math\n{\n  namespace averages\n  {\n    double geometric_mean(std::span<const double> data)\n    {\n      // The geometric mean of n elements\n      // is defined as the n-th root of the product of all n elements\n      double product{ 1 };\n      for (auto value : data)\n        product *= value;\n\n      return data.empty()\n        ? std::numeric_limits<double>::quiet_NaN() \n        : std::pow(product, 1.0 / data.size());\n    }\n  }\n}\n\n// Option 3: define using fully qualified function name\ndouble math::averages::rms(std::span<const double> data)\n{ \n  // The RMS or root mean square is defined as \n  // square root of the arithmetic mean of the squares of the elements.\n  double sum_squares{};\n  for (auto value : data)\n    sum_squares += square(value);\n\n  return data.empty()\n    ? std::numeric_limits<double>::quiet_NaN() // Or std::nan(\"\")\n    : std::sqrt(sum_squares / data.size());\n}\n\n// Option 4: define using qualified name in outer namespace block\nnamespace math\n{\n  double averages::median(std::span<const double> data)\n  {\n    // The median of an odd number of elements is the value \n    // that appears in the middle position of these elements when they are sorted.\n    // The median of an even number of elements is typically\n    // defined as the mean of the two middle elements in a sorted range.\n\n    // We cannot sort the data span itself, because it's elements are const.\n    // Therefore, we first copy the const input data to be able to sort it\n    std::vector<double> sorted;\n\n    // Use range-based for loop to copy the input data.\n    // See Chapter 20 for built-in means of copying a data range.\n    for (auto value : data)\n      sorted.push_back(value);\n\n    // See Chapter 20 for built-in means of (partially) sorting data\n    quicksort(sorted);\n\n    const size_t mid = data.size() / 2;\n    return data.empty() ? std::numeric_limits<double>::quiet_NaN() // Or std::nan\n         : data.size() % 2 == 1 ? sorted[mid]\n         : (sorted[mid - 1] + sorted[mid]) / 2;\n  }\n}\n\nnamespace\n{\n  void quicksort(std::vector<double>& data, size_t start, size_t end);\n  void quicksort(std::vector<double>& data)\n  {\n    if (!data.empty())\n      quicksort(data, 0, data.size() - 1);\n  }\n\n  void quicksort(std::vector<double>& data, size_t start, size_t end)\n  {\n    // start index must be less than end index for 2 or more elements\n    if (!(start < end))\n      return;\n\n    // Choose middle value to partition set, \n    // and move it to the front of the current range\n    std::swap(data[start], data[(start + end) / 2]);\n\n    // Compare all other values against chosen value at index start\n    size_t current{ start };\n    for (size_t i{ start + 1 }; i <= end; i++)\n    {\n      if (data[i] < data[start]) // Is the value less than chosen value?\n        std::swap(data[++current], data[i]); // Yes, so swap to the left\n    }\n\n    std::swap(data[start], data[current]); // Swap chosen and last swapped words\n\n    if (current > start) quicksort(data, start, current - 1); // Sort left subset if exists\n    if (end > current + 1) quicksort(data, current + 1, end); // Sort right subset if exists\n  }\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 11/Ex11_07/math.h",
    "content": "#ifndef MATH_H\n#define MATH_H\n\n#include <span>\n\nnamespace math\n{\n  auto square(const auto& x) { return x * x; };\n\n  namespace averages\n  {\n    double arithmetic_mean(std::span<const double> data);\n    double geometric_mean(std::span<const double> data);\n    double rms(std::span<const double> data);\n    double median(std::span<const double> data);\n  }\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 11/Ex11_08/Ex11_08.cpp",
    "content": "// Using using declarations and using directives\n#include <iostream>\n#include \"squaring.h\"\n\n/* Make names from the math namespace available locally */\nauto my_hypot(const auto& x, const auto& y) // Renamed to my_hypot to avoid clashes with hypot() function in <cmath>\n{\n  using namespace math;\n  // Or:\n  //   using math::square;\n  //   using math::sqrt;    /* Same as, of course: using std::sqrt; */\n  return sqrt(square(x) + square(y));\n}\n\nint main()\n{\n  std::cout << \"math::sqrt2 has the value \" << math::sqrt2 << std::endl;\n  std::cout << \"This should be 0: \" << (math::sqrt2 - std::numbers::sqrt2) << std::endl;\n  std::cout << \"This should be 2: \" << math::square(math::sqrt2) << std::endl;\n  std::cout << \"This should be 5: \" << my_hypot(3, 4) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 11/Ex11_08/squaring.h",
    "content": "#include <cmath>      // For std::sqrt()\n#include <numbers>    // For std::numbers::sqrt2 \n\n/* Re-export two existing entities from the math namespace using using declarations */\nnamespace math        // Exports all nested declarations at once\n{\n  using std::numbers::sqrt2;\n  using std::sqrt;    // Never 'using std::sqrt();' or 'using std::sqrt(double);'!\n  auto square(const auto& x) { return x * x; }\n  auto pow4(const auto& x) { return square(square(x)); }\n}\n\n/* Export all names from a namespace from the math namespace using a using directive */\n//namespace math\n//{\n//  export using namespace std::numbers;\n//}"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_01/Ex12_01.cpp",
    "content": "// Defining a class constructor\n#include <iostream>\n\n// Class to represent a box\nclass Box\n{\npublic:\n  // Constructor\n  Box(double length, double width, double height)\n  {\n    std::cout << \"Box constructor called.\"  << std::endl;\n    m_length = length;\n    m_width = width;\n    m_height = height;\n  }\n\n  // Function to calculate the volume of a box\n  double volume()\n  {\n    return m_length * m_width * m_height;\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\nint main()\n{\n  Box firstBox {80.0, 50.0, 40.0};            // Create a box\n  double firstBoxVolume {firstBox.volume()};  // Calculate the box volume\n  std::cout << \"Volume of Box object is \" << firstBoxVolume << std::endl;\n\n  // Box secondBox;        // Causes a compiler error message\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_01A/Ex12_01A.cpp",
    "content": "// Defining a default constructor\n#include <iostream>\n\n// Class to represent a box\nclass Box\n{\npublic:\n// Box() {}           // Explicitly defined default constructor\n  Box() = default;    // Defaulted default constructor\n\n  // Constructor\n  Box(double length, double width, double height)\n  {\n    std::cout << \"Box constructor called.\"  << std::endl;\n    m_length = length;\n    m_width = width;\n    m_height = height;\n  }\n\n  // Function to calculate the volume of a box\n  double volume()\n  {\n    return m_length * m_width * m_height;\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\nint main()\n{\n  Box firstBox {80.0, 50.0, 40.0};            // Create a box\n  double firstBoxVolume {firstBox.volume()};  // Calculate the box volume\n  std::cout << \"Volume of Box object is \" << firstBoxVolume << std::endl;\n\n  Box secondBox;        // No longer causes a compiler error message\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_02/Ex12_02.cpp",
    "content": "// Defining member functions outside a class\n// Note that, unlike what we said in the text, \n// in this example we put the function definitions after the main() function.\n// This illustrates that to invoke a member function,\n// the compiler again only needs access to the signature of the member function.\n#include <iostream>\n\n// Class to represent a box\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume();   // Function to calculate the volume of a box\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\nint main()\n{\n  Box firstBox {80.0, 50.0, 40.0};            // Create a box\n  double firstBoxVolume {firstBox.volume()};  // Calculate the box volume\n  std::cout << \"Volume of Box object is \" << firstBoxVolume << std::endl;\n\n  Box secondBox;        // No longer causes a compiler error message\n}\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n  m_length = length;\n  m_width = width;\n  m_height = height;\n}\n\n// Member function definition\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_03/Ex12_03.cpp",
    "content": "// Using a member initializer list\n#include <iostream>\n\n// Class to represent a box\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume();   // Function to calculate the volume of a box\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\nint main()\n{\n  Box firstBox {80.0, 50.0, 40.0};            // Create a box\n  double firstBoxVolume {firstBox.volume()};  // Calculate the box volume\n  std::cout << \"Volume of Box object is \" << firstBoxVolume << std::endl;\n\n  Box secondBox;        // No longer causes a compiler error message\n}\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{length}, m_width{width}, m_height{height}\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Member function definition\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_04/Ex12_04.cpp",
    "content": "// Using the explicit keyword\n// Uncomment \"explicit\" to make the compilation of \n// the expression \"box1.hasLargerVolumeThan(50.0)\" fail\n#include <iostream>\n\nclass Cube\n{\npublic:\n  /*explicit*/ Cube(double side);       // Constructor\n  double volume();                      // Calculate volume of a cube\n  bool hasLargerVolumeThan(Cube cube);  // Compare volume of a cube with another\nprivate:\n  double m_side;\n};\n\nCube::Cube(double side) : m_side{ side }\n{\n  std::cout << \"Cube constructor called.\" << std::endl;\n}\n\ndouble Cube::volume() { return m_side * m_side * m_side; }\nbool Cube::hasLargerVolumeThan(Cube cube) { return volume() > cube.volume(); }\n\nint main()\n{\n  Cube box1{ 7.0 };\n  Cube box2{ 3.0 };\n  if (box1.hasLargerVolumeThan(box2))\n    std::cout << \"box1 is larger than box2.\" << std::endl;\n  else\n    std::cout << \"Volume of box1 is less than or equal to that of box2.\" << std::endl;\n\n  std::cout << \"Volume of box1 is \" << box1.volume() << std::endl;\n  if (box1.hasLargerVolumeThan(50.0))\n    std::cout << \"Volume of box1 is greater than 50\" << std::endl;\n  else\n    std::cout << \"Volume of box1 is less than or equal to 50\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_05/Ex12_05.cpp",
    "content": "// Delegating constructors\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box(double length, double width, double height);\n  explicit Box(double side);   // Constructor for a cube (explicit!)\n  Box() = default;             // Defaulted default constructor\n\n  double volume();             // Function to calculate the volume of a box\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n};\n\n// A constructor that initializes all three member variables\nBox::Box(double length, double width, double height) \n  : m_length{length}, m_width{width}, m_height{height}\n{\n  std::cout << \"Box constructor 1 called.\" << std::endl;\n}\n\n// This second constructor forwards to the first one to initialize all members.\n// Note that you do not repeat the explicit keyword here!\nBox::Box(double side) : Box{ side, side, side }\n{\n  std::cout << \"Box constructor 2 called.\" << std::endl;\n}\n\nint main()\n{\n  Box box1{ 2.0, 3.0, 4.0 };     // An arbitrary box\n  Box box2{ 5.0 };               // A box that is a cube\n  std::cout << \"box1 volume = \" << box1.volume() << std::endl;\n  std::cout << \"box2 volume = \" << box2.volume() << std::endl;\n}\n\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_05A/Ex12_05A.cpp",
    "content": "// Implementing the copy constructor\n// Note: this example is explained but not named in the text\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box(double length, double width, double height);\n  explicit Box(double side);   // Constructor for a cube (explicit!)\n  Box() = default;             // Defaulted default constructor\n  Box(const Box& box);         // Copy constructor\n\n  double volume();             // Function to calculate the volume of a box\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n};\n\n// A basic copy constructor\nBox::Box(const Box& box)\n  : m_length{ box.m_length }, m_width{ box.m_width }, m_height{ box.m_height }\n{\n  std::cout << \"Copy constructor called.\" << std::endl;\n}\n\n// A delegating copy constructor\n//Box::Box(const Box& box) : Box{ box.m_length, box.m_width, box.m_height }\n//{\n//  std::cout << \"Copy constructor called.\" << std::endl;\n//}\n\n\nint main()\n{\n  Box box1{ 2.0, 3.0, 4.0 };     // An arbitrary box\n  Box box2{ 5.0 };               // A box that is a cube\n  std::cout << \"box1 volume = \" << box1.volume() << std::endl;\n  std::cout << \"box2 volume = \" << box2.volume() << std::endl;\n\n  Box box3{ box2 };\n  std::cout << \"box3 volume = \" << box3.volume() << std::endl;   // Volume = 125\t\n}\n\n// A constructor that initializes all three member variables\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor 1 called.\" << std::endl;\n}\n\n// This second constructor forwards to the first one to initialize all members.\n// Note that you do not repeat the explicit keyword here!\nBox::Box(double side) : Box{ side, side, side }\n{\n  std::cout << \"Box constructor 2 called.\" << std::endl;\n}\n\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_06/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>\n\n// Class to represent a box\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume();   // Function to calculate the volume of a box\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n// Constructor definition\n// (inline because this member is defined in a header file: see online Appendix A)\ninline Box::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Member function definition\n// (inline because this member is defined in a header file: see online Appendix A)\ninline double Box::volume()\n{\n  return m_length * m_width * m_height;\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_06/Ex12_06.cpp",
    "content": "// Defining classes in separate files.\n// Without modules, this normally means the class is defined in a header file,\n// and the member functions in source file. To mirror the book's exercise, though,\n// here we define all members in the header as well (as inline functions).\n// See online Appendix A for details.\n\n#include <iostream>   // For use of std::cout, std::endl, etc.\n#include \"Box.h\"      // For use of the Box class\n\nint main()\n{\n  Box myBox{ 6.0, 6.0, 18.5 }; // Create a box\n  std::cout << \"Volume of the first Box object is \" << myBox.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_06A/Box.cpp",
    "content": "#include <iostream>\n#include \"Box.h\"\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Member function definition\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_06A/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n// Class to represent a box\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume();   // Function to calculate the volume of a box\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_06A/Ex12_06A.cpp",
    "content": "// Defining classes in separate files.\n// Without modules, this normally means the class is defined in a header file,\n// and the member functions in source file like we did for this example. \n// See online Appendix A for details.\n\n#include <iostream>   // For use of std::cout, std::endl, etc.\n#include \"Box.h\"      // For use of the Box class\n\nint main()\n{\n  Box myBox{ 6.0, 6.0, 18.5 }; // Create a box\n  std::cout << \"Volume of the first Box object is \" << myBox.volume() << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_06B/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>\n\n// Class to represent a box\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height)\n    : m_length{ length }, m_width{ width }, m_height{ height }\n  {\n    std::cout << \"Box constructor called.\" << std::endl;\n  }\n\n  // Function to calculate the volume of a box\n  double volume() { return m_length * m_width * m_height; }\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_06B/Ex12_06B.cpp",
    "content": "// Defining classes with in-class member definitions.\n\n#include <iostream>   // For use of std::cout, std::endl, etc.\n#include \"Box.h\"      // For use of the Box class\n\nint main()\n{\n  Box myBox{ 6.0, 6.0, 18.5 }; // Create a box\n  std::cout << \"Volume of the first Box object is \" << myBox.volume() << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_07/Box.cpp",
    "content": "#include <iostream>\n#include \"Box.h\"\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Member function definition\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_07/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume();    // Function to calculate the volume of a box\n\n  // Functions to provide access to the values of member variables\n  double getLength() { return m_length; }\n  double getWidth()  { return m_width; }\n  double getHeight() { return m_height; }\n\n  // Functions to set member variable values\n  void setLength(double length) { if (length > 0) m_length = length; }\n  void setWidth(double width)   { if (width > 0)  m_width  = width;  }\n  void setHeight(double height) { if (height > 0) m_height = height; }\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_07/Ex12_07.cpp",
    "content": "// Accessing private members through getters and setters\n#include \"Box.h\"\n#include <iostream>\n\nint main()\n{\n  Box myBox {3.0, 4.0, 5.0};\n  std::cout << \"myBox dimensions are \" << myBox.getLength()\n            << \" by \" << myBox.getWidth()\n            << \" by \" << myBox.getHeight() << std::endl;\n\n  myBox.setLength(-20.0);       // ignored!\n  myBox.setWidth(40.0);\n  myBox.setHeight(10.0);\n  std::cout << \"myBox dimensions are now \" << myBox.getLength()  // 3 (unchanged)\n    << \" by \" << myBox.getWidth()                        // by 40\n    << \" by \" << myBox.getHeight() << std::endl;         // by 10\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_08/Box.cpp",
    "content": "#include <iostream>\n#include \"Box.h\"\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Member function definition\ndouble Box::volume()\n{\n  return m_length * m_width * m_height;\n}\n\n// Mutator function definitions\nBox& Box::setLength(double length)\n{\n  if (length > 0) m_length = length;\n  return *this;\n}\nBox& Box::setWidth(double width)\n{\n  if (width > 0) m_width = width;\n  return *this;\n}\nBox& Box::setHeight(double height)\n{\n  if (height > 0) m_height = height;\n  return *this;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_08/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume();    // Function to calculate the volume of a box\n\n  // Inspector functions\n  double getLength() { return m_length; }\n  double getWidth()  { return m_width; }\n  double getHeight() { return m_height; }\n\n  // Mutator functions\n  Box& setLength(double length);\n  Box& setWidth(double width);\n  Box& setHeight(double height);\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_08/Ex12_08.cpp",
    "content": "// Accessing private members through getters and setters (method chaining variant)\n#include \"Box.h\"\n#include <iostream>\n\nint main()\n{\n  Box myBox {3.0, 4.0, 5.0};\n  std::cout << \"myBox dimensions are \" << myBox.getLength()\n            << \" by \" << myBox.getWidth()\n            << \" by \" << myBox.getHeight() << std::endl;\n\n  myBox.setLength(-20.0).setWidth(40.0).setHeight(10.0); // Set all dimensions of myBox\n\n  std::cout << \"myBox dimensions are now \" << myBox.getLength()  // 3 (unchanged)\n    << \" by \" << myBox.getWidth()                        // by 40\n    << \" by \" << myBox.getHeight() << std::endl;         // by 10\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_09/Box.cpp",
    "content": "#include <iostream>\n#include \"Box.h\"\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Const member function definition\ndouble Box::volume() const\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_09/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume() const;    // Const function to calculate the volume of a box\n\n  // Functions to provide access to the values of member variables (all const!)\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions to set member variable values (not const!)\n  void setLength(double length) { if (length > 0) m_length = length; }\n  void setWidth(double width)   { if (width > 0)  m_width  = width;  }\n  void setHeight(double height) { if (height > 0) m_height = height; }\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_09/Ex12_09.cpp",
    "content": "// Const objects and const member functions\n#include \"Box.h\"\n#include <iostream>\n\nint main()\n{\n  // v-- this const was added...\n  const Box myBox {3.0, 4.0, 5.0};\n  std::cout << \"myBox dimensions are \" << myBox.getLength()\n            << \" by \" << myBox.getWidth()\n            << \" by \" << myBox.getHeight() << std::endl;\n\n  // Invoking mutators / setters is not possible on a const object:\n  //myBox.setLength(-20.0);       // ignored!\n  //myBox.setWidth(40.0);\n  //myBox.setHeight(10.0);\n  //std::cout << \"myBox dimensions are now \" << myBox.getLength()  // 3 (unchanged)\n  //  << \" by \" << myBox.getWidth()                        // by 40\n  //  << \" by \" << myBox.getHeight() << std::endl;         // by 10\n\n  std::cout << \"myBox's volume is \" << myBox.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_10/Box.cpp",
    "content": "#include <iostream>\n#include \"Box.h\"\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Const member function definition\ndouble Box::volume() const\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_10/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume() const;    // Const function to calculate the volume of a box\n\n  // Non-const overloads (return references to dimension variable)\n  double& length() { std::cout << \"non-const overload called\\n\"; return m_length; };\n  double& width()  { std::cout << \"non-const overload called\\n\"; return m_width; };\n  double& height() { std::cout << \"non-const overload called\\n\"; return m_height; };\n\n  // Const overloads (return references to const variables)\n  const double& length() const { std::cout << \"const overload called\\n\"; return m_length; };\n  const double& width()  const { std::cout << \"const overload called\\n\"; return m_width; };\n  const double& height() const { std::cout << \"const overload called\\n\"; return m_height; };\n\n  // Attempt to return non-const references to member variables from const functions\n// double& length() const { return m_length; };   // This must not be allowed to compile!\n// double& width()  const { return m_width; };\n// double& height() const { return m_height; };\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_10/Ex12_10.cpp",
    "content": "// Overloading on const\n#include \"Box.h\"\n#include <iostream>\n\nint main()\n{\n  const Box constBox{ 1, 2, 3 };\n  // constBox.length() = 2;                          // Does not compile: good!\n  std::cout << constBox.length() << std::endl;\n\n  Box nonConstBox{ 3, 2, 1 };\n  nonConstBox.length() *= 2;\n  std::cout << nonConstBox.length() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_11/Box.cpp",
    "content": "#include <iostream>\n#include \"Box.h\"\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Const member function definition\ndouble Box::volume() const\n{\n  return m_length * m_width * m_height;\n}\n\n// Modify mutable member variable from a const member function \nvoid Box::printVolume() const\n{\n  // Count how many times printVolume() is called using a mutable member in a const function\n  std::cout << \"The volume of this box is \" << volume() << std::endl;\n  std::cout << \"printVolume() has been called \" << ++m_count << \" time(s)\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_11/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double length, double width, double height);\n\n  double volume() const;      // Function to calculate the volume of a box\n  void printVolume() const;   // Function to print out the volume of a box (const!)\n\n  // Functions to provide access to the values of member variables (all const!)\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions to set member variable values (not const!)\n  void setLength(double length) { if (length > 0) m_length = length; }\n  void setWidth(double width)   { if (width > 0)  m_width  = width;  }\n  void setHeight(double height) { if (height > 0) m_height = height; }\n\nprivate:\n  double m_length{1.0};\n  double m_width {1.0};\n  double m_height{1.0};\n  mutable unsigned m_count{};   // Counts the amount of time printVolume() is called\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_11/Ex12_11.cpp",
    "content": "// Const objects and const member functions\n#include \"Box.h\"\n#include <iostream>\n\nint main()\n{\n  const Box myBox {3.0, 4.0, 5.0};\n  std::cout << \"myBox dimensions are \" << myBox.getLength()\n            << \" by \" << myBox.getWidth()\n            << \" by \" << myBox.getHeight() << std::endl;\n\n  myBox.printVolume();\n  myBox.printVolume();\n  myBox.printVolume();\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_12/Box.cpp",
    "content": "#include <iostream>\n#include \"Box.h\"\n\n// Constructor definition\nBox::Box(double length, double width, double height)\n  : m_length{ length }, m_width{ width }, m_height{ height }\n{\n  std::cout << \"Box constructor called.\" << std::endl;\n}\n\n// Const member function definition\ndouble Box::volume() const\n{\n  return m_length * m_width * m_height;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_12/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0} {}        // A delegating default constructor\n  Box(double length, double width, double height);\n\n  double volume() const;                // Function to calculate the volume of a box\n\n  friend double surfaceArea(const Box& box); // Friend function for the surface area\n\nprivate:\n  double m_length, m_width, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_12/Ex12_12.cpp",
    "content": "// Using a friend function of a class\n#include <iostream>\n#include <memory>\n#include \"Box.h\"\n\nint main()\n{\n  Box box1 {2.2, 1.1, 0.5};    // An arbitrary box\n  Box box2;                    // A default box\n  auto box3{ std::make_unique<Box>(15.0, 20.0, 8.0) }; // Dynamically allocated Box\n\n  std::cout << \"Volume of box1 = \" << box1.volume() << std::endl;\n  std::cout << \"Surface area of box1 = \" << surfaceArea(box1) << std::endl;\n\n  std::cout << \"Volume of box2 = \"<< box2.volume() << std::endl;\n  std::cout << \"Surface area of box2 = \" << surfaceArea(box2) << std::endl;\n\n  std::cout << \"Volume of box3 = \" << box3->volume() << std::endl;\n  std::cout << \"Surface area of box3 = \" << surfaceArea(*box3) << std::endl;\n}\n\n// friend function to calculate the surface area of a Box object\ndouble surfaceArea(const Box& box)\n{\n  return 2.0 * (box.m_length * box.m_width\n    + box.m_length * box.m_height + box.m_height * box.m_width);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_13/Box.cpp",
    "content": "#include <iostream>\n#include \"Box.h\"\n\nBox::Box(double length, double width, double height)  // Constructor definition\n  : m_length{length}, m_width{width}, m_height{height}\n{\n  std::cout << \"Box constructor 1 called.\" << std::endl;\n}\n\nBox::Box(double side) : Box{side, side, side}  // Constructor for a cube\n{\n  std::cout << \"Box constructor 2 called.\" << std::endl;\n}\n\nBox::Box()                                      // Default constructor\n{\n  std::cout << \"Default Box constructor called.\" << std::endl;\n}\n\nBox::Box(const Box& box)                        // Copy constructor\n  : m_length{box.m_length}, m_width{box.m_width}, m_height{box.m_height}\n{\n  std::cout << \"Box copy constructor called.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_13/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  /* Constructors */\n  Box(double length, double width, double height);\n  Box(double side);       // Constructor for a cube\n  Box();                  // Default constructor\n  Box(const Box& box);    // Copy constructor\n\n  double volume() const { return m_length * m_width * m_height; };\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_13/Ex12_13.cpp",
    "content": "// Creating an array of objects\n#include <iostream>\n#include \"Box.h\"\n\nint main()\n{\n  const Box box1 {2.0, 3.0, 4.0};  // An arbitrary box\n  Box box2 {5.0};                  // A box that is a cube\n  std::cout << \"box1 volume = \" << box1.volume() << std::endl;\n  std::cout << \"box2 volume = \" << box2.volume() << std::endl;\n  Box box3 {box2};\n  std::cout << \"box3 volume = \" << box3.volume() << std::endl;   // Volume = 125\n\n  std::cout << std::endl;\n\n  Box boxes[6] {box1, box2, box3, Box {2.0}};\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_14/Box.cpp",
    "content": "#include <iostream>\n#include \"Box.h\"\n\nBox::Box(double length, double width, double height)  // Constructor definition\n  : m_length{length}, m_width{width}, m_height{height}\n{\n  ++s_object_count;\n  std::cout << \"Box constructor 1 called.\" << std::endl;\n}\n\nBox::Box(double side) : Box{side, side, side}  // Constructor for a cube\n{\n  // Do not increment s_object_count in forwarding constructor: \n  // already incremented in the constructor this constructor forwards to!\n  std::cout << \"Box constructor 2 called.\" << std::endl;\n}\n\nBox::Box()                                      // Default constructor\n{\n  ++s_object_count;\n  std::cout << \"Default Box constructor called.\" << std::endl;\n}\n\nBox::Box(const Box& box)                        // Copy constructor\n  : m_length{box.m_length}, m_width{box.m_width}, m_height{box.m_height}\n{\n  ++s_object_count;\n  std::cout << \"Box copy constructor called.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_14/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box();                     // Default constructor  \n  Box(double side);          // Constructor for a cube\n  Box(const Box& box);       // Copy constructor\n  Box(double length, double width, double height);\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  size_t getObjectCount() const { return s_object_count; }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n  static inline size_t s_object_count {};   // Count of objects ever created\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_14/Ex12_14.cpp",
    "content": "// Using a static member variable\n#include <iostream>\n#include \"Box.h\"\n\nint main()\n{\n  const Box box1 {2.0, 3.0, 4.0};                              // An arbitrary box\n  Box box2 {5.0};                                              // A box that is a cube\n  std::cout << \"box1 volume = \" << box1.volume() << std::endl;\n  std::cout << \"box2 volume = \" << box2.volume() << std::endl;\n  Box box3 {box2};\n  std::cout << \"box3 volume = \" << box3.volume() << std::endl; // Volume = 125\n\n  std::cout << std::endl;\n\n  Box boxes[6] {box1, box2, box3, Box {2.0}};\n\n  std::cout << \"\\nThere are now \" << box1.getObjectCount() << \" Box objects.\\n\";\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_15/CylindricalBox.cpp",
    "content": "#include <iostream>\n#include \"CylindricalBox.h\"\n\nCylindricalBox::CylindricalBox(float radius, float height, std::string_view material)\n  : m_radius{ radius }\n  , m_height{ height }\n  , m_material{ material }\n{\n  std::cout << \"Box constructed consisting of \" << material;\n  if (material == s_default_material)\n  {\n    std::cout << \" (the default material!)\";\n  }\n  std::cout << std::endl;\n}\n\nfloat CylindricalBox::volume() const\n{\n  return PI * m_radius * m_radius * m_height;\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_15/CylindricalBox.h",
    "content": "#ifndef CYLINDRICAL_BOX_H\n#define CYLINDRICAL_BOX_H\n\n#include <string>\n#include <string_view>\n\nclass CylindricalBox\n{\npublic:\n  static inline const float s_max_radius { 35.0f };\n  static inline const float s_max_height { 60.0f };\n  static inline const std::string_view s_default_material { \"paperboard\" };\n\n  CylindricalBox(float radius, float height,\n                 std::string_view material = s_default_material);\n  float volume() const;\n\nprivate:\n  // The value of PI used by CylindricalBox's volume() function\n  static inline const float PI { 3.141592f };  \n\n  float m_radius;\n  float m_height;\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_15/Ex12_15.cpp",
    "content": "// Defining and using static constants\n#include <iostream>\n#include \"CylindricalBox.h\"\n\nint main()\n{\n  CylindricalBox bigBox{ 1.23f,\n            CylindricalBox::s_max_height, CylindricalBox::s_default_material };\n  std::cout << \"The volume of bigBox is \" <<  bigBox.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_16/Box.cpp",
    "content": "#include <iostream>\n#include \"Box.h\"\n\nBox::Box(double length, double width, double height)  // Constructor definition\n  : m_length{length}, m_width{width}, m_height{height}\n{\n  ++s_object_count;\n  std::cout << \"Box constructor 1 called.\" << std::endl;\n}\n\nBox::Box(double side) : Box{side, side, side}  // Constructor for a cube\n{\n  // Do not increment s_object_count in forwarding constructor: \n  // already incremented in the constructor this constructor forwards to!\n  std::cout << \"Box constructor 2 called.\" << std::endl;\n}\n\nBox::Box()                                      // Default constructor\n{\n  ++s_object_count;\n  std::cout << \"Default Box constructor called.\" << std::endl;\n}\n\nBox::Box(const Box& box)                        // Copy constructor\n  : m_length{box.m_length}, m_width{box.m_width}, m_height{box.m_height}\n{\n  ++s_object_count;\n  std::cout << \"Box copy constructor called.\" << std::endl;\n}\n\nBox::~Box()                              // Destructor\n{\n  std::cout << \"Box destructor called.\" << std::endl;\n  --s_object_count;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_16/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box();                     // Default constructor  \n  Box(double side);          // Constructor for a cube\n  Box(const Box& box);       // Copy constructor\n  Box(double length, double width, double height);\n  ~Box();   // Destructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  static size_t getObjectCount() { return s_object_count; }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n  static inline size_t s_object_count {};   // Count of objects ever created\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_16/Ex12_16.cpp",
    "content": "// Implementing a destructor\n#include <iostream>\n#include \"Box.h\"\n\nint main()\n{\n  std::cout << \"There are now \" << Box::getObjectCount() << \" Box objects.\" << std::endl;\n\n  const Box box1 {2.0, 3.0, 4.0};     // An arbitrary box\n  Box box2 {5.0};                     // A box that is a cube\n\n  std::cout << \"There are now \" << Box::getObjectCount() << \" Box objects.\" << std::endl;\n\n  for (double d {} ; d < 3.0 ; ++d)\n  {\n    Box box {d, d + 1.0, d + 2.0};\n    std::cout << \"Box volume is \" << box.volume() << std::endl;\n  }\n\n  std::cout << \"There are now \" << Box::getObjectCount() << \" Box objects.\" << std::endl;\n\n  auto pBox{ std::make_unique<Box>(1.5, 2.5, 3.5) };\n  std::cout << \"Box volume is \" << pBox->volume() << std::endl;\n  std::cout << \"There are now \" << pBox->getObjectCount() << \" Box objects.\" << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_17/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>\n#include <format>\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  void listBox() const\n  {\n    std::cout << std::format(\"Box({:.1f},{:.1f},{:.1f})\", m_length, m_width, m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_17/Ex12_17.cpp",
    "content": "// Using a linked list\n#include \"RandomBoxes.h\"\n#include \"Truckload.h\"\n\nint main()  \n{\n  Truckload load1;  // Create an empty list\n\n  // Add 12 random Box objects to the list\n  const size_t boxCount {12};\n  for (size_t i {} ; i < boxCount ; ++i)\n    load1.addBox(randomSharedBox());\n\n  std::cout << \"The first list:\\n\";\n  load1.listBoxes();\n\n  // Copy the truckload\n  Truckload copy{load1};\n  std::cout << \"The copied truckload:\\n\";\n  copy.listBoxes();\n\n  // Find the largest Box in the list\n  SharedBox largestBox{load1.getFirstBox()};\n\n  SharedBox nextBox{load1.getNextBox()};\n  while (nextBox)\n  {\n    if (nextBox->compare(*largestBox) > 0)\n      largestBox = nextBox;\n    nextBox = load1.getNextBox();\n  }\n\n  std::cout << \"\\nThe largest box in the first list is \";\n  largestBox->listBox();\n  std::cout << std::endl;\n  load1.removeBox(largestBox);\n  std::cout << \"\\nAfter deleting the largest box, the list contains:\\n\";\n  load1.listBoxes();\n\n  const size_t nBoxes {20};            // Number of vector elements\n  std::vector<SharedBox> boxes;        // Array of Box objects\n\n  for (size_t i {} ; i < nBoxes ; ++i)\n    boxes.push_back(randomSharedBox());\n\n  Truckload load2{boxes};\n  std::cout << \"\\nThe second list:\\n\";\n  load2.listBoxes();\n\n  auto smallestBox{ load2.getFirstBox() };\n  for (auto box{ load2.getNextBox() }; box; box = load2.getNextBox())\n    if (box->compare(*smallestBox) < 0)\n      smallestBox = box;\n\n  std::cout << \"\\nThe smallest box in the second list is \";\n  smallestBox->listBox();\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_17/Package.h",
    "content": "#ifndef PACKAGE_H\n#define PACKAGE_H\n\n#include \"SharedBox.h\"\n\nclass Package\n{\npublic:\n  Package(SharedBox box) : m_box{box}, m_next{nullptr} {}  // Constructor\n  ~Package() { delete m_next; }                            // Destructor\n\n  // Retrieve the Box pointer\n  SharedBox getBox() const { return m_box; }\n\n  // Retrieve or update the pointer to the next Package\n  Package* getNext() { return m_next; }\n  void setNext(Package* package) { m_next = package; }\n\nprivate:\n  SharedBox m_box;    // Pointer to the Box object contained in this Package\n  Package* m_next;    // Pointer to the next Package in the list\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_17/RandomBoxes.h",
    "content": "#ifndef RANDOM_BOXES_H\n#define RANDOM_BOXES_H\n\n#include \"Box.h\"\n#include <random>        // For random number generation\n#include <functional>    // For std::bind()\n#include <memory>        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\ninline auto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\ninline Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\ninline auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_17/SharedBox.h",
    "content": "#ifndef SHARED_BOX_H\n#define SHARED_BOX_H\n\n#include <memory>\n#include \"Box.h\"\n\nusing SharedBox = std::shared_ptr<Box>;\n\n#endif "
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_17/Truckload.cpp",
    "content": "#include \"Truckload.h\"\n#include \"Package.h\" \n\n#include <iostream>\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->getNext())\n  {\n    addBox(package->getBox());\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nvoid Truckload::listBoxes() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count {};  \n  for (Package* package{m_head}; package; package = package->getNext())\n  {\n    std::cout << ' ';\n    package->getBox()->listBox();\n    if (! (++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\n\nSharedBox Truckload::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->getBox() : nullptr;\n}\n\nSharedBox Truckload::getNextBox()\n{\n  if (!m_current)                                    // If there's no current...\n    return getFirstBox();                            // ...return the 1st Box\n\n  m_current = m_current->getNext();                  // Move to the next package\n\n  return m_current? m_current->getBox() : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->setNext(package);      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};      // no previous yet\n  Package* current {m_head};        // initialize current to the head of the list\n  while (current)\n  {\n    if (current->getBox() == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->setNext(current->getNext());\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->getNext();\n      if (current == m_tail) m_tail = previous;\n      if (current == m_current) m_current = current->getNext();\n\n      current->setNext(nullptr);        // Disconnect the current Package from the list\n      delete current;                   // and delete it\n\n      return true;                      // Return true: we found and removed the box\n    }\n                                        // Move both pointers along (mind the order!)\n    previous = current;                 //  - first current becomes the new previous\n    current = current->getNext();       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_17/Truckload.h",
    "content": "#ifndef TRUCKLOAD_H\n#define TRUCKLOAD_H\n\n#include \"SharedBox.h\"\n#include <vector>\n\n// Do not #include \"Package.inl\" here to avoid this class definition to leak into consumers of Truckload\n// (best we can do here to mimick internal module implementation partitions...)\nclass Package;  \n\nclass Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  SharedBox getFirstBox();          // Get the first Box\n  SharedBox getNextBox();           // Get the next Box\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n  void listBoxes() const;           // Output the Boxes\n\nprivate:\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n  Package* m_current {};            // Last retrieved from the list\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_18/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>\n#include <format>\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  void listBox() const\n  {\n    std::cout << std::format(\"Box({:.1f},{:.1f},{:.1f})\", m_length, m_width, m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_18/Ex12_18.cpp",
    "content": "// Using nested classes\n#include \"RandomBoxes.h\"\n#include \"Truckload.h\"\n\nint main()  \n{\n  Truckload load1;  // Create an empty list\n\n  // Add 12 random Box objects to the list\n  const size_t boxCount {12};\n  for (size_t i {} ; i < boxCount ; ++i)\n    load1.addBox(randomSharedBox());\n\n  std::cout << \"The first list:\\n\";\n  load1.listBoxes();\n\n  // Copy the truckload\n  Truckload copy{load1};\n  std::cout << \"The copied truckload:\\n\";\n  copy.listBoxes();\n\n  // Find the largest Box in the list\n  SharedBox largestBox{load1.getFirstBox()};\n\n  SharedBox nextBox{load1.getNextBox()};\n  while (nextBox)\n  {\n    if (nextBox->compare(*largestBox) > 0)\n      largestBox = nextBox;\n    nextBox = load1.getNextBox();\n  }\n\n  std::cout << \"\\nThe largest box in the first list is \";\n  largestBox->listBox();\n  std::cout << std::endl;\n  load1.removeBox(largestBox);\n  std::cout << \"\\nAfter deleting the largest box, the list contains:\\n\";\n  load1.listBoxes();\n\n  const size_t nBoxes {20};            // Number of vector elements\n  std::vector<SharedBox> boxes;        // Array of Box objects\n\n  for (size_t i {} ; i < nBoxes ; ++i)\n    boxes.push_back(randomSharedBox());\n\n  Truckload load2{boxes};\n  std::cout << \"\\nThe second list:\\n\";\n  load2.listBoxes();\n\n  auto smallestBox{ load2.getFirstBox() };\n  for (auto box{ load2.getNextBox() }; box; box = load2.getNextBox())\n    if (box->compare(*smallestBox) < 0)\n      smallestBox = box;\n\n  std::cout << \"\\nThe smallest box in the second list is \";\n  smallestBox->listBox();\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_18/RandomBoxes.h",
    "content": "#ifndef RANDOM_BOXES_H\n#define RANDOM_BOXES_H\n\n#include \"Box.h\"\n#include <random>        // For random number generation\n#include <functional>    // For std::bind()\n#include <memory>        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\ninline auto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\ninline Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\ninline auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_18/Truckload.cpp",
    "content": "#include \"Truckload.h\"\n\n#include <iostream>\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nvoid Truckload::listBoxes() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count {};  \n  for (Package* package{m_head}; package; package = package->m_next)\n  {\n    std::cout << ' ';\n    package->m_box->listBox();\n    if (! (++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\n\nSharedBox Truckload::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\nSharedBox Truckload::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n      if (current == m_current) m_current = current->m_next;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 12/Ex12_18/Truckload.h",
    "content": "#ifndef TRUCKLOAD_H\n#define TRUCKLOAD_H\n\n#include \"Box.h\"\n\n#include <memory>\n#include <vector>\n\nusing SharedBox = std::shared_ptr<Box>;\n\nclass Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  SharedBox getFirstBox();          // Get the first Box\n  SharedBox getNextBox();           // Get the next Box\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n  void listBoxes() const;           // Output the Boxes\n\nprivate:\n  class Package\n  {\n  public:\n    SharedBox m_box;      // Pointer to the Box object contained in this Package\n    Package* m_next;      // Pointer to the next Package in the list\n\n    Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n    ~Package() { delete m_next; }                           // Destructor\n  };\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n  Package* m_current {};            // Last retrieved from the list\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_01/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h} {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  bool operator<(const Box& aBox) const     // Less-than operator\n  { return volume() < aBox.volume(); }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_01/Ex13_01.cpp",
    "content": "// Implementing a less-than operator\n#include <iostream>\n#include <vector>\n#include \"Box.h\"\n\nint main()\n{\n  std::vector boxes {Box {2.0, 2.0, 3.0}, Box {1.0, 3.0, 2.0},\n                     Box {1.0, 2.0, 1.0}, Box {2.0, 3.0, 3.0}};\n  Box smallBox {boxes[0]};\n  for (const auto& box : boxes)\n  {\n    if (box < smallBox) smallBox = box;\n  }\n\n  std::cout << \"The smallest box has dimensions \"\n    << smallBox.getLength() << 'x'\n    << smallBox.getWidth()  << 'x'\n    << smallBox.getHeight() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_02/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  bool operator<(const Box& aBox) const    // Less-than operator\n  {\n    return volume() < aBox.volume();\n  }\n\n  bool operator<(double value) const;      // Compare Box volume < double value\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n// Compare the volume of a Box object with a constant\ninline bool Box::operator<(double value) const\n{\n\treturn volume() < value;\n}\n\n// Function comparing a constant with volume of a Box object\ninline bool operator<(double value, const Box& aBox)\n{\n  return value < aBox.volume();\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_02/Ex13_02.cpp",
    "content": "// Using the overloaded 'less-than' operators for Box ojects\n#include <iostream>\n#include <vector>\n#include <format>\n#include \"Box.h\"\n\n// Display box dimensions\nvoid show(const Box& box)\n{\n  std::cout << std::format(\"Box {:g}x{:g}x{:g}\", \n                 box.getLength(), box.getWidth(), box.getHeight()) << std::endl;\n}\n\nint main()\n{\n  std::vector boxes {Box {2.0, 2.0, 3.0}, Box {1.0, 3.0, 2.0},\n                     Box {1.0, 2.0, 1.0}, Box {2.0, 3.0, 3.0}};\n  const double minVolume{6.0};\n  std::cout << \"Objects with volumes less than \" << minVolume << \" are:\\n\";\n  for (const auto& box : boxes)\n    if (box < minVolume) show(box);\n\n  std::cout << \"Objects with volumes greater than \" << minVolume << \" are:\\n\";\n  for (const auto& box : boxes)\n    if (minVolume < box) show(box);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_03/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const\n  {\n    return m_length == otherBox.m_length\n        && m_width  == otherBox.m_width\n        && m_height == otherBox.m_height; \n  }\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_03/Ex13_03.cpp",
    "content": "// Overloading <=> and == to fully support all comparison operators\n#include <iostream>\n#include <format>\n#include <string_view>\n#include <vector>\n#include \"Box.h\"\n\nvoid show(const Box& box)\n{\n  std::cout << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\", \n                  box.getLength(), box.getWidth(), box.getHeight());\n}\nvoid show(const Box& box1, std::string_view relationship, const Box& box2)\n{\n  show(box1); std::cout << relationship; show(box2); std::cout << std::endl;\n}\n\nint main()\n{\n  const std::vector boxes {Box {2.0, 1.5, 3.0}, Box {1.0, 3.0, 5.0},\n                           Box {1.0, 2.0, 1.0}, Box {2.0, 3.0, 2.0}};\n  const Box theBox {3.0, 1.0, 4.0};\n\n  for (const auto& box : boxes)\n    if (theBox > box) show(theBox, \" is greater than \", box);  // > works\n\n  std::cout << std::endl;\n\n  for (const auto& box : boxes)\n    if (theBox != box) show(theBox, \" is not equal to \", box); // != works\n\n  std::cout << std::endl;  \n\n  for (const auto& box : boxes)\n    if (6.0 <= box)                     // Yes, even double <= Box works!!\n      { std::cout << \"6 is less than or equal to \"; show(box); std::cout << std::endl; }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_03A/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_03A/Ex13_03A.cpp",
    "content": "// Defaulting the == operator\n#include <iostream>\n#include <format>\n#include <string_view>\n#include <vector>\n#include \"Box.h\"\n\nvoid show(const Box& box)\n{\n  std::cout << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\", \n                  box.getLength(), box.getWidth(), box.getHeight());\n}\nvoid show(const Box& box1, std::string_view relationship, const Box& box2)\n{\n  show(box1); std::cout << relationship; show(box2); std::cout << std::endl;\n}\n\nint main()\n{\n  const std::vector boxes {Box {2.0, 1.5, 3.0}, Box {1.0, 3.0, 5.0},\n                           Box {1.0, 2.0, 1.0}, Box {2.0, 3.0, 2.0}};\n  const Box theBox {3.0, 1.0, 4.0};\n\n  for (const auto& box : boxes)\n    if (theBox > box) show(theBox, \" is greater than \", box);  // > works\n\n  std::cout << std::endl;\n\n  for (const auto& box : boxes)\n    if (theBox != box) show(theBox, \" is not equal to \", box); // != works\n\n  std::cout << std::endl;  \n\n  for (const auto& box : boxes)\n    if (6.0 <= box)                     // Yes, even double <= Box works!!\n      { std::cout << \"6 is less than or equal to \"; show(box); std::cout << std::endl; }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_04/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n#include <ostream>  // For std::ostream\n#include <format>\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                             box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_04/Ex13_04.cpp",
    "content": "// Overloading the << operator\n#include <iostream>\n#include <format>\n#include <string_view>\n#include <vector>\n#include \"Box.h\"\n\nint main()\n{\n  const std::vector boxes {Box {2.0, 1.5, 3.0}, Box {1.0, 3.0, 5.0},\n                           Box {1.0, 2.0, 1.0}, Box {2.0, 3.0, 2.0}};\n  const Box theBox {3.0, 1.0, 4.0};\n\n  for (const auto& box : boxes)\n    if (theBox > box) \n      std::cout << theBox << \" is greater than \" << box << std::endl;  // > works\n\n  std::cout << std::endl;\n\n  for (const auto& box : boxes)\n    if (theBox != box) \n      std::cout << theBox << \" is not equal to \" << box << std::endl; // != works\n\n  std::cout << std::endl;  \n\n  for (const auto& box : boxes)\n    if (6.0 <= box)                     // Yes, even double <= Box works!!\n      std::cout << \"6 is less than or equal to \" << box << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_05/Box.cpp",
    "content": "#include \"Box.h\"\n\n#include <format>\n#include <algorithm>    // For the min() and max() function templates\n\ndouble Box::volume() const\n{\n    return m_length * m_width * m_height;\n}\n\nBox Box::operator+(const Box& aBox) const\n{\n  // New object has larger length and width, and sum of heights\n  return Box{ std::max(m_length, aBox.m_length),\n              std::max(m_width, aBox.m_width),\n              m_height + aBox.m_height };\n}\n\nstd::partial_ordering Box::operator<=>(const Box& aBox) const\n{\n  return volume() <=> aBox.volume();\n}\n\nstd::partial_ordering Box::operator<=>(double value) const\n{\n  return volume() <=> value;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                          box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_05/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n#include <ostream>  // For std::ostream\n\nclass Box\n{\npublic:\n  Box() = default;       // Default constructor\n  Box(double length, double width, double height)\n    : m_length{ std::max(length,width) }\n    , m_width { std::min(length,width) }\n    , m_height{ height } \n  {}\n\n  double volume() const; // Function to calculate the volume\n  \n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions that add full support for comparison operators\n  std::partial_ordering operator<=>(const Box& aBox) const;\n  std::partial_ordering operator<=>(double value) const;\n  bool operator==(const Box& aBox) const = default;\n\n  Box operator+(const Box& aBox) const;   // Function to add two Box objects\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box);\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_05/Ex13_05.cpp",
    "content": "// Using the addition operator for Box objects\n#include <iostream>\n#include <format>\n#include <vector>\n#include <random>       // For random number generation\n#include <functional>   // For std::bind()\n#include \"Box.h\"\n\n// See Chapter 12 for an explanation of this function\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 1.0, max }; // Generate in [1, max) interval\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\nint main()\n{\n  const double limit {99};       // Upper limit on Box dimensions\n  auto random { createUniformPseudoRandomNumberGenerator(limit) };\n\n  const size_t boxCount {20}; // Number of Box object to be created\n  std::vector<Box> boxes;     // Vector of Box objects\n\n  // Create 20 Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    boxes.push_back(Box{ random(), random(), random() });\n\n  size_t first {};            // Index of first Box object of pair\n  size_t second {1};          // Index of second Box object of pair\n  double minVolume {(boxes[first] + boxes[second]).volume()};\n\n  for (size_t i {}; i < boxCount - 1; ++i)\n  {  \n    for (size_t j {i + 1}; j < boxCount; j++)\n    {\n      if (boxes[i] + boxes[j] < minVolume)\n      {\n        first = i;\n        second = j;\n        minVolume = (boxes[i] + boxes[j]).volume();\n      }\n    }\n  }\n\n  std::cout << \"The two boxes that sum to the smallest volume are \"\n            << boxes[first] << \" and \" << boxes[second] << '\\n';\n  std::cout << std::format(\"The volume of the first box is {:.1f}\\n\",\n                            boxes[first].volume());\n  std::cout << std::format(\"The volume of the second box is {:.1f}\\n\",\n                            boxes[second].volume());\n  std::cout << \"The sum of these boxes is \" << (boxes[first] + boxes[second]) << '\\n';\n  std::cout << std::format(\"The volume of the sum is {:.1f}\", minVolume) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_06/Box.cpp",
    "content": "#include \"Box.h\"\n\n#include <format>\n#include <cmath>    // For the min() and max() function templates\n\ndouble Box::volume() const\n{\n    return m_length * m_width * m_height;\n}\n\n// Overloaded += operator\nBox& Box::operator+=(const Box& aBox)\n{\n  // New object has larger length and width, and sum of heights\n  m_length = std::max(m_length, aBox.m_length);\n  m_width = std::max(m_width, aBox.m_width);\n  m_height += aBox.m_height;\n  return *this;\n}\n\n// Function to add two Box objects\nBox Box::operator+(const Box& aBox) const\n{\n  Box copy{ *this };\n  copy += aBox;\n  return copy;\n}\n\nstd::partial_ordering Box::operator<=>(const Box& aBox) const\n{\n  return volume() <=> aBox.volume();\n}\n\nstd::partial_ordering Box::operator<=>(double value) const\n{\n  return volume() <=> value;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                          box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_06/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n#include <ostream>  // For std::ostream\n\nclass Box\n{\npublic:\n  Box() = default;       // Default constructor\n  Box(double length, double width, double height)\n    : m_length{ std::max(length,width) }\n    , m_width { std::min(length,width) }\n    , m_height{ height } \n  {}\n\n  double volume() const; // Function to calculate the volume\n  \n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions that add full support for comparison operators\n  std::partial_ordering operator<=>(const Box& aBox) const;\n  std::partial_ordering operator<=>(double value) const;\n  bool operator==(const Box& aBox) const = default;\n\n  Box& operator+=(const Box& aBox);      // Function to add a Box objects\n  Box operator+(const Box& aBox) const; // Function to add two Box objects\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box);\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_06/Ex13_06.cpp",
    "content": "// Using the addition operator for Box objects\n#include <iostream>\n#include <format>\n#include <vector>\n#include <random>       // For random number generation\n#include <functional>   // For std::bind()\n#include \"Box.h\"\n\n// See Chapter 12 for an explanation of this function\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 1.0, max }; // Generate in [1, max) interval\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\nint main()\n{\n  const double limit {99};       // Upper limit on Box dimensions\n  auto random { createUniformPseudoRandomNumberGenerator(limit) };\n\n  const size_t boxCount {20}; // Number of Box object to be created\n  std::vector<Box> boxes;     // Vector of Box objects\n\n  // Create 20 Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    boxes.push_back(Box{ random(), random(), random() });\n\n  size_t first {};            // Index of first Box object of pair\n  size_t second {1};          // Index of second Box object of pair\n  double minVolume {(boxes[first] + boxes[second]).volume()};\n\n  for (size_t i {}; i < boxCount - 1; ++i)\n  {  \n    for (size_t j {i + 1}; j < boxCount; j++)\n    {\n      if (boxes[i] + boxes[j] < minVolume)\n      {\n        first = i;\n        second = j;\n        minVolume = (boxes[i] + boxes[j]).volume();\n      }\n    }\n  }\n\n  std::cout << \"The two boxes that sum to the smallest volume are \"\n            << boxes[first] << \" and \" << boxes[second] << '\\n';\n  std::cout << std::format(\"The volume of the first box is {:.1f}\\n\",\n                            boxes[first].volume());\n  std::cout << std::format(\"The volume of the second box is {:.1f}\\n\",\n                            boxes[second].volume());\n  std::cout << \"The sum of these boxes is \" << (boxes[first] + boxes[second]) << '\\n';\n  std::cout << std::format(\"The volume of the sum is {:.1f}\", minVolume) << std::endl;\n\n  Box sum{ 0, 0, 0 };            // Start from an empty Box\n  for (const auto& box : boxes)  // And then add all randomly generated Box objects\n    sum += box;\n\n  std::cout << \"The sum of \" << boxCount << \" random boxes is \" << sum << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_07/Ex13_07.cpp",
    "content": "// Implicit conversions reduce the number of operator functions\n#include <iostream>\n#include \"Integer.h\"\n\nint main() \n{\n  const Integer i{1};\n  const Integer j{2};\n  const auto result = (i * 2 + 4 / j - 1) % j;\n  std::cout << result.getValue() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_07/Integer.h",
    "content": "#ifndef INTEGER_H\n#define INTEGER_H\n\nclass Integer\n{\npublic:\n  Integer(int value = 0) : m_value{value} {}\n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\nprivate:\n  int m_value;\n};\n\ninline Integer operator+(const Integer& one, const Integer& other)\n{\n  return one.getValue() + other.getValue();\n}\ninline Integer operator-(const Integer& one, const Integer& other)\n{\n  return one.getValue() - other.getValue();\n}\ninline Integer operator*(const Integer& one, const Integer& other)\n{\n  return one.getValue() * other.getValue();\n}\ninline Integer operator/(const Integer& one, const Integer& other)\n{\n  return one.getValue() / other.getValue();\n}\ninline Integer operator%(const Integer& one, const Integer& other)\n{\n  return one.getValue() % other.getValue();\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_08/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n#include <ostream>  // For std::ostream\n#include <format>\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  Box operator~() const\n  {\n    return Box{m_width, m_length, m_height}; // Width and length are swapped\n  }\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                             box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_08/Ex13_08.cpp",
    "content": "// Overloading a unary \"rotate\" operator\n#include <iostream>\n#include \"Box.h\"\n\nint main()\n{\n  Box someBox{ 1, 2, 3 };\n  std::cout << ~someBox << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_09/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n#include <ostream>  // For std::ostream\n#include <format>\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  Box& operator++();         // Prefix ++operator\n  const Box operator++(int); // Postfix operator++\n  Box& operator--();         // Prefix --operator\n  const Box operator--(int); // Postfix operator--\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\ninline Box& Box::operator++()   // Prefix ++operator\n{\n  ++m_length;\n  ++m_width;\n  ++m_height;\n  return *this;\n}\n\ninline const Box Box::operator++(int)  // Postfix operator++\n{\n  auto copy{ *this };  // Create a copy of the current object\n  ++(*this);           // Increment the current object using the prefix operator...\n  return copy;         // Return the unincremented copy\n}\n\ninline Box& Box::operator--()   // Prefix --operator\n{\n  --m_length;\n  --m_width;\n  --m_height;\n  return *this;\n}\n\ninline const Box Box::operator--(int)  // Postfix operator--\n{\n  auto copy{ *this };  // Create a copy of the current object\n  --(*this);           // Decrement the current object using the prefix operator...\n  return copy;         // Return copy of the original value\n}\n\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                             box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_09/Ex13_09.cpp",
    "content": "// Overloading pre- and postfix inrement and decrement operators\n#include <iostream>\n#include \"Box.h\"\n\nint main()\n{\n  Box theBox{ 3.0, 1.0, 3.0 };\n\n  std::cout << \"Our test Box is \" << theBox << std::endl;\n\n  std::cout << \"Postfix increment evaluates to the original object: \"\n    << theBox++ << std::endl;\n\n  std::cout << \"After postfix increment: \" << theBox << std::endl;\n\n  std::cout << \"Prefix decrement evaluates to the decremented object: \"\n    << --theBox << std::endl;\n  std::cout << \"After prefix decrement: \" << theBox << std::endl;\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_10/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <ostream>\n#include <format>\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f},{:.1f},{:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_10/Ex13_10.cpp",
    "content": "// Using the subscript operator\n#include <iostream>\n#include <memory>\n#include <random>       // For random number generation\n#include <functional>   // For std::bind()\n#include \"Truckload.h\"\n\n// See Chapter 12 for an explanation of this function\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 1.0, max }; // Generate in [1, max) interval\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\nint main()\n{\n  const double limit {99.0};    // Upper limit on Box dimensions\n  auto random = createUniformPseudoRandomNumberGenerator(limit);\n\n  Truckload load;\n  const size_t boxCount {16};   // Number of Box object to be created\n\n  // Create boxCount Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    load.addBox(std::make_shared<Box>(random(), random(), random()));\n\n  std::cout << \"The boxes in the Truckload are:\\n\";\n  std::cout << load;\n\n  // Find the largest Box in the Truckload\n  double maxVolume {};\n  size_t maxIndex {};\n  size_t i {};\n  while (load[i])\n  {\n    if (load[i]->volume() > maxVolume)\n    {\n      maxIndex = i;\n      maxVolume = load[i]->volume();\n    }\n    ++i;\n  }\n\n  std::cout << \"\\nThe largest box is: \";\n  std::cout << *load[maxIndex] << std::endl;\n\n  load.removeBox(load[maxIndex]);\n  std::cout << \"\\nAfter deleting the largest box, the Truckload contains:\\n\";\n  std::cout << load;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_10/Truckload.cpp",
    "content": "#include \"Truckload.h\"\n\n#include <iostream>\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nSharedBox Truckload::operator[](size_t index) const\n{\n  size_t count{};             // Package count\n  for (Package* package{ m_head }; package; package = package->m_next)\n  {\n    if (count++ == index)      // Up to index yet?\n      return package->m_box;   // If so return the pointer to Box\n  }\n  return nullptr;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_10/Truckload.h",
    "content": "#ifndef TRUCKLOAD_H\n#define TRUCKLOAD_H\n\n#include \"Box.h\"\n\n#include <memory>\n#include <vector>\n#include <ostream>\n\nusing SharedBox = std::shared_ptr<Box>;\n\nclass Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox operator[](size_t index) const;   // Overloaded subscript operator\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load);\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_11/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <ostream>\n#include <format>\n#include <algorithm>    // For the std::min()/max() function templates\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f},{:.1f},{:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\n  Box operator+(const Box& aBox) const   // Function to add two Box objects\n  {\n    return Box{ std::max(m_length, aBox.m_length),\n                std::max(m_width, aBox.m_width),\n                m_height + aBox.m_height }; \n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_11/Ex13_11.cpp",
    "content": "// Modifying the result of an overloaded subscript operator\n#include <iostream>\n#include <memory>\n#include <random>       // For random number generation\n#include <functional>   // For std::bind()\n#include \"Truckload.h\"\n\n/*\n  Caution: in the text, we suggest to add \n    \n    static SharedBox nullBox{};\n  \n  to the Truckload class definition. This will not compile.\n  In-class definitions of non-const static members are only allowed\n  if you add the inline keyword, as we did in this solution.\n  See Chapter 12 for more explanation,\n  and for the alternative of defining the member out-of-class.\n*/\n\n// See Chapter 12 for an explanation of this function\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 1.0, max }; // Generate in [1, max) interval\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\nint main()\n{\n  const double limit {99.0};    // Upper limit on Box dimensions\n  auto random = createUniformPseudoRandomNumberGenerator(limit);\n\n  Truckload load;\n  const size_t boxCount {16};   // Number of Box object to be created\n\n  // Create boxCount Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    load.addBox(std::make_shared<Box>(random(), random(), random()));\n\n  std::cout << \"The boxes in the Truckload are:\\n\";\n  std::cout << load;\n\n  // Find the largest Box in the Truckload\n  double maxVolume {};\n  size_t maxIndex {};\n  size_t i {};\n  while (load[i])\n  {\n    if (load[i]->volume() > maxVolume)\n    {\n      maxIndex = i;\n      maxVolume = load[i]->volume();\n    }\n    ++i;\n  }\n\n  std::cout << \"\\nThe largest box is: \";\n  std::cout << *load[maxIndex] << std::endl;\n\n  load.removeBox(load[maxIndex]);\n  std::cout << \"\\nAfter deleting the largest box, the Truckload contains:\\n\";\n  std::cout << load;\n\n  load[0] = load[1];        // Copy 2nd element to the 1st\n  std::cout << \"\\nAfter copying the 2nd element to the 1st, the list contains:\\n\";\n  std::cout << load;\n\n  load[1] = std::make_shared<Box>(*load[2] + *load[3]);\n  std::cout << \"\\nAfter making the 2nd element a pointer to the 3rd plus 4th,\"\n                                                          \" the list contains:\\n\";\n  std::cout << load;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_11/Truckload.cpp",
    "content": "#include \"Truckload.h\"\n\n#include <iostream>\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nSharedBox& Truckload::operator[](size_t index) const\n{\n  size_t count{};             // Package count\n  for (Package* package{ m_head }; package; package = package->m_next)\n  {\n    if (count++ == index)      // Up to index yet?\n      return package->m_box;   // If so return the pointer to Box\n  }\n  return nullBox;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_11/Truckload.h",
    "content": "#ifndef TRUCKLOAD_H\n#define TRUCKLOAD_H\n\n#include \"Box.h\"\n\n#include <memory>\n#include <vector>\n#include <ostream>\n\nusing SharedBox = std::shared_ptr<Box>;\n\nclass Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox& operator[](size_t index) const;   // Overloaded subscript operator\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n\n  // Caution: inline is required to allow for this definition to appear in-class.\n  // In the text we forgot to add this. See Chapter 12 for more explanation,\n  // and for the alternative of defining the member out-of-class.\n  static inline SharedBox nullBox{}; // Pointer to nullptr\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load);\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_12/Ex13_12.cpp",
    "content": "// Defining a copy assignment operator\n#include \"Message.h\"\n#include <iostream>\n\nint main()\n{\n  Message beware{ \"Careful\" };\n  Message warning;\n  \n  warning = beware;    // Call assignment operator\n\n  std::cout << \"After assignment beware is: \" << beware.getText() << std::endl;\n  std::cout << \"After assignment warning is: \" << warning.getText() << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_12/Message.cpp",
    "content": "#include \"Message.h\"\n\nMessage& Message::operator=(const Message& message)\n{\n  if (&message != this)\n  {\n    delete[] m_text;                                    // Delete the previous char array\n    m_text = new char[std::strlen(message.m_text) + 1]; // Replace it with a new array\n    std::strcpy(m_text, message.m_text);                // Copy the text (mind the order!)\n  }\n  return *this;      // Return the left operand\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_12/Message.h",
    "content": "#ifndef MESSAGE_H\n#define MESSAGE_H\n\n#include <cstring> // For std::strlen() and std::strcpy()\n\nclass Message\n{\npublic:\n  explicit Message(const char* text = \"\")\n    : m_text(new char[std::strlen(text) + 1]) // Caution: include the null character!\n  {\n    std::strcpy(m_text, text);        // Mind the order: strcpy(destination, source)!\n  }\n  ~Message() { delete[] m_text; }\n\n  Message& operator=(const Message& message); // Assignment operator\n\n  const char* getText() const { return m_text; }\n\nprivate:\n  char* m_text;\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_12A/Ex13_12A.cpp",
    "content": "// Always define both copy members together\n// (see also 'Rule of Five' in Chapter 18!)\n#include \"Message.h\"\n#include <iostream>\n\nint main()\n{\n  Message beware{ \"Careful\" };\n  Message warning;\n  \n  warning = beware;    // Call assignment operator\n\n  Message caution{ warning };\n\n  std::cout << \"After assignment beware is: \" << beware.getText() << std::endl;\n  std::cout << \"After assignment warning is: \" << warning.getText() << std::endl;\n  std::cout << \"As a copy of warning, caution is: \" << caution.getText() << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_12A/Message.cpp",
    "content": "#include \"Message.h\"\n\nMessage::Message(const Message& message)\n  : Message{ message.m_text }  // By far easiest and preferred option: forward to existing constructor!\n{\n}\n\nMessage& Message::operator=(const Message& message)\n{\n  if (&message != this)\n  {\n    delete[] m_text;                                    // Delete the previous char array\n    m_text = new char[std::strlen(message.m_text) + 1]; // Replace it with a new array\n    std::strcpy(m_text, message.m_text);                // Copy the text (mind the order!)\n  }\n  return *this;      // Return the left operand\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_12A/Message.h",
    "content": "#ifndef MESSAGE_H\n#define MESSAGE_H\n\n#include <cstring> // For std::strlen() and std::strcpy()\n\nclass Message\n{\npublic:\n  explicit Message(const char* text = \"\")\n    : m_text(new char[std::strlen(text) + 1]) // Caution: include the null character!\n  {\n    std::strcpy(m_text, text);        // Mind the order: strcpy(destination, source)!\n  }\n  ~Message() { delete[] m_text; }\n\n  Message(const Message& message);            // Copy constructor\n  Message& operator=(const Message& message); // Copy assignment operator\n\n  const char* getText() const { return m_text; }\n\nprivate:\n  char* m_text;\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_12B/Ex13_12B.cpp",
    "content": "// Sneak preview: use copy-and-swap for copy assignment operator\n// (see Chapter 17 for details, including the noexcept keyword...)\n// In short, you eliminate duplicating the logic of copying an object\n// by expressing the copy assignment operator in terms of the copy constructor.\n// Less duplication means less room for error, less maintenance overhead, etc.\n// Note: this solution is hinted at in a Note in the text, but not explicitly named.\n#include \"Message.h\"\n#include <iostream>\n\nint main()\n{\n  Message beware{ \"Careful\" };\n  Message warning;\n  \n  warning = beware;    // Call assignment operator\n\n  Message caution{ warning };\n\n  std::cout << \"After assignment beware is: \" << beware.getText() << std::endl;\n  std::cout << \"After assignment warning is: \" << warning.getText() << std::endl;\n  std::cout << \"As a copy of warning, caution is: \" << caution.getText() << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_12B/Message.cpp",
    "content": "#include \"Message.h\"\n\n#include <utility>    // For std::swap()\n\nMessage::Message(const Message& message)\n  : Message{ message.m_text }  // By far easiest and preferred option: forward to existing constructor!\n{\n}\n\nMessage& Message::operator=(const Message& message)\n{\n  // Note: self-assignment test no longer required (or even recommended)\n  auto copy{ message }; // Copy-...\n  swap(copy);           // ...and-swap!\n  return *this;         // Always return reference to left operand\n}\n\nvoid Message::swap(Message& other) noexcept\n{\n  std::swap(m_text, other.m_text);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 13/Ex13_12B/Message.h",
    "content": "#ifndef MESSAGE_H\n#define MESSAGE_H\n\n#include <cstring> // For std::strlen() and std::strcpy()\n\nclass Message\n{\npublic:\n  explicit Message(const char* text = \"\")\n    : m_text(new char[std::strlen(text) + 1]) // Caution: include the null character!\n  {\n    std::strcpy(m_text, text);        // Mind the order: strcpy(destination, source)!\n  }\n  ~Message() { delete[] m_text; }\n\n  Message(const Message& message);            // Copy constructor \n  Message& operator=(const Message& message); // Copy assignment operator\n\n  void swap(Message& other) noexcept;\n\n  const char* getText() const { return m_text; }\n\nprivate:\n  char* m_text;\n};\n\ninline void swap(Message& one, Message& other) noexcept\n{\n  return one.swap(other);\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_01/Box.h",
    "content": "// Box.h - defines Box class\n#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height)\n    : m_length{ length }, m_width{ width }, m_height{ height }\n  {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprivate:\n  double m_length {1.0};\n  double m_width  {1.0};\n  double m_height {1.0};\n};\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_01/Carton.h",
    "content": "// Carton.h - defines the Carton class with the Box class as base\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  explicit Carton(std::string_view material = \"Cardboard\")  // Constructor\n    : m_material{material} {}\n\nprivate:\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_01/Ex14_01.cpp",
    "content": "// Defining and using a derived class\n#include <iostream>\n#include \"Box.h\"                 // For the Box class\n#include \"Carton.h\"              // For the Carton class\n\nint main()\n{\n  // Create a Box object and two Carton objects\n  Box box {40.0, 30.0, 20.0};\n  Carton carton;\n  Carton chocolateCarton {\"Solid bleached board\"};  // Good old SBB\n  // Check them out - sizes first of all\n  std::cout << \"box occupies \" << sizeof box << \" bytes\" << std::endl;\n  std::cout << \"carton occupies \" << sizeof carton << \" bytes\" << std::endl;\n  std::cout << \"candyCarton occupies \" << sizeof chocolateCarton << \" bytes\" << std::endl;\n\n  // Now volumes...\n  std::cout << \"box volume is \" << box.volume() << std::endl;\n  std::cout << \"carton volume is \" << carton.volume() << std::endl;\n  std::cout << \"chocolateCarton volume is \" << chocolateCarton.volume() << std::endl;\n\n  std::cout << \"chocolateCarton length is \" << chocolateCarton.getLength() << std::endl;\n\n  // Uncomment any of the following for an error...\n  // box.m_length = 10.0;\n  // chocolateCarton.m_length = 10.0;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_01A/Box.h",
    "content": "// Box.h - defines Box class\n#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height)\n      : m_length{ length }, m_width{ width }, m_height{ height }\n  {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprivate:\n  double m_length {1.0};\n  double m_width  {1.0};\n  double m_height {1.0};\n};\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_01A/Carton.h",
    "content": "// Carton.h - defines the Carton class with the Box class as private base\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : private Box\n{\npublic:\n  explicit Carton(std::string_view mat = \"Cardboard\") : m_material {mat} {}\n  using Box::volume; // Inherit as public\n\nprivate:\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_01A/Ex14_01A.cpp",
    "content": "// Changing the access specification of inherited members using using\n#include <iostream>\n#include \"Box.h\"                 // For the Box class\n#include \"Carton.h\"              // For the Carton class\n\nint main()\n{\n  // Create a Box object and two Carton objects\n  Box box {40.0, 30.0, 20.0};\n  Carton carton;\n  Carton chocolateCarton {\"Solid bleached board\"};  // Good old SBB\n  // Check them out - sizes first of all\n  std::cout << \"box occupies \" << sizeof box << \" bytes\" << std::endl;\n  std::cout << \"carton occupies \" << sizeof carton << \" bytes\" << std::endl;\n  std::cout << \"candyCarton occupies \" << sizeof chocolateCarton << \" bytes\" << std::endl;\n\n  // Now volumes...\n  std::cout << \"box volume is \" << box.volume() << std::endl;\n  std::cout << \"carton volume is \" << carton.volume() << std::endl;\n  std::cout << \"chocolateCarton volume is \" << chocolateCarton.volume() << std::endl;\n\n  // Uncomment any of the following for an error...\n  // std::cout << \"chocolateCarton length is \" << chocolateCarton.getLength() << std::endl;\n  //\n  // box.m_length = 10.0;\n  // chocolateCarton.m_length = 10.0;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_02/Box.h",
    "content": "// Box.h - defines Box class\n#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>     // For standard streams\n#include <format>       // For string formatting\n\nclass Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_02/Carton.h",
    "content": "// Carton.h - defines the Carton class with the Box class as base\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  Carton() { std::cout << \"Carton() called.\\n\"; }\n\n  explicit Carton(std::string_view material) : m_material{material}\n  { std::cout << \"Carton(string_view) called.\\n\"; }\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n/*\n  // This constructor won't compile!\n  Carton::Carton(double l, double w, double h, std::string_view material)\n    : m_length{ l }, m_width{ w }, m_height{ h }, m_material{ material }\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }\n*/\n/*\n  // Constructor that will compile!\n  Carton::Carton(double l, double w, double h, std::string_view material)\n    : m_material{material}\n  {\n    m_length = l;  // These should normally be initialized in a base class constructor...\n    m_width = w;\n    m_height = h;\n    std::cout << \"Carton(double,double,double,string_view) called.\\n\";\n  }\n*/\n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_02/Ex14_02.cpp",
    "content": "// Calling base class constructors in a derived class constructor\n#include <iostream>\n#include \"Carton.h\"       // For the Carton class\n\nint main()\n{\n  // Create four Carton objects\n  Carton carton1;                             std::cout << std::endl;\n  Carton carton2 {\"White-lined chipboard\"};   std::cout << std::endl;\n  Carton carton3 {4.0, 5.0, 6.0, \"PET\"};      std::cout << std::endl;\n  Carton carton4 {2.0, \"Folding boxboard\"};   std::cout << std::endl;\n\n  std::cout << \"carton1 volume is \" << carton1.volume() << std::endl;\n  std::cout << \"carton2 volume is \" << carton2.volume() << std::endl;\n  std::cout << \"carton3 volume is \" << carton3.volume() << std::endl;\n  std::cout << \"carton4 volume is \" << carton4.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_03/Box.h",
    "content": "// Box.h - defines Box class (with additional copy constuctor)\n#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>     // For standard streams\n#include <format>       // For string formatting\n\nclass Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  // Copy constructor\n  Box(const Box& b) : m_length{ b.m_length }, m_width{ b.m_width }, m_height{ b.m_height }\n  { std::cout << \"Box copy constructor\" << std::endl; }\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_03/Carton.h",
    "content": "// Carton.h - defines the Carton class (with additional copy constuctor)\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  Carton() { std::cout << \"Carton() called.\\n\"; }\n\n  explicit Carton(std::string_view material) : m_material{material}\n  { std::cout << \"Carton(string_view) called.\\n\"; }\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n\n  // Copy constructor (wrong)\n  Carton(const Carton& carton) : m_material {carton.m_material}\n  { std::cout << \"Carton copy constructor\" << std::endl; }\n/*\n  // Copy constructor (correct)\n  Carton(const Carton& carton) : Box{ carton }, m_material{ carton.m_material }\n  { std::cout << \"Carton copy constructor\" << std::endl; }\n*/\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_03/Ex14_03.cpp",
    "content": "// Using a derived class copy constructor\n#include <iostream>\n#include \"Carton.h\"\n\nint main()\n{\n  // Declare and initialize a Carton object\n  Carton carton{ 20.0, 30.0, 40.0, \"Expanded polystyrene\" };\n  std::cout << std::endl;\n\n  Carton cartonCopy{ carton };  // Use copy constructor\n  std::cout << std::endl;\n\n  std::cout << \"Volume of carton is \" << carton.volume() << std::endl\n            << \"Volume of cartonCopy is \" << cartonCopy.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_04/Box.h",
    "content": "// Box.h - defines Box class\n#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>     // For standard streams\n#include <format>       // For string formatting\n\nclass Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_04/Carton.h",
    "content": "// Carton.h - defines the Carton class with the Box class as base\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  Carton() = default;\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_04/Ex14_04.cpp",
    "content": "// Defaulting the default constructor in a derived class (working version)\n#include <iostream>\n#include \"Box.h\"                 // For the Box class\n#include \"Carton.h\"              // For the Carton class\n\nint main()\n{\n  // Create three Carton objects\n  Carton carton1;                             std::cout << std::endl;\n  Carton carton2 {4.0, 5.0, 6.0, \"PET\"};      std::cout << std::endl;\n  Carton carton3 {2.0, \"Folding boxboard\"};   std::cout << std::endl;\n\n  std::cout << \"carton1 volume is \" << carton1.volume() << std::endl;\n  std::cout << \"carton2 volume is \" << carton2.volume() << std::endl;\n  std::cout << \"carton3 volume is \" << carton3.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_04A/Box.h",
    "content": "// Box.h - defines Box class\n#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>     // For standard streams\n#include <format>       // For string formatting\n\nclass Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n//  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor removed!\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_04A/Carton.h",
    "content": "// Carton.h - defines the Carton class with the Box class as base\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  Carton() = default;\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_04A/Ex14_04A.cpp",
    "content": "// Defaulting the default constructor in a derived class\n// without a default constructor in the base class\n// is equivalent to deleting the default constructor.\n#include <iostream>\n#include \"Box.h\"                 // For the Box class\n#include \"Carton.h\"              // For the Carton class\n\n/* Note: this example will fail to compile! */\n\nint main()\n{\n  // Create three Carton objects\n  Carton carton1;                             std::cout << std::endl;\n  Carton carton2 {4.0, 5.0, 6.0, \"PET\"};      std::cout << std::endl;\n  Carton carton3 {2.0, \"Folding boxboard\"};   std::cout << std::endl;\n\n  std::cout << \"carton1 volume is \" << carton1.volume() << std::endl;\n  std::cout << \"carton2 volume is \" << carton2.volume() << std::endl;\n  std::cout << \"carton3 volume is \" << carton3.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_04B/Box.h",
    "content": "// Box.h - defines Box class\n#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>     // For standard streams\n#include <format>       // For string formatting\n\nclass Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() = delete;   // Default constructor explicitly deleted\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_04B/Carton.h",
    "content": "// Carton.h - defines the Carton class with the Box class as base\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  Carton() = default;\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_04B/Ex14_04B.cpp",
    "content": "// Defaulting the default constructor in a derived class\n// with a deleted default constructor in the base class\n// is equivalent to deleting the default constructor.\n#include <iostream>\n#include \"Box.h\"                 // For the Box class\n#include \"Carton.h\"              // For the Carton class\n\n/* Note: this example will fail to compile! */\n\nint main()\n{\n  // Create three Carton objects\n  Carton carton1;                             std::cout << std::endl;\n  Carton carton2 {4.0, 5.0, 6.0, \"PET\"};      std::cout << std::endl;\n  Carton carton3 {2.0, \"Folding boxboard\"};   std::cout << std::endl;\n\n  std::cout << \"carton1 volume is \" << carton1.volume() << std::endl;\n  std::cout << \"carton2 volume is \" << carton2.volume() << std::endl;\n  std::cout << \"carton3 volume is \" << carton3.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_04C/Box.h",
    "content": "// Box.h - defines Box class\n#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>     // For standard streams\n#include <format>       // For string formatting\n\nclass Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprivate:\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor (made private)\n\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_04C/Carton.h",
    "content": "// Carton.h - defines the Carton class with the Box class as base\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  Carton() = default;\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_04C/Ex14_04C.cpp",
    "content": "// Defaulting the default constructor in a derived class\n// with a private constructor in the base class\n// is equivalent to deleting the default constructor.\n#include <iostream>\n#include \"Box.h\"                 // For the Box class\n#include \"Carton.h\"              // For the Carton class\n\n/* Note: this example will fail to compile! */\n\nint main()\n{\n  // Create three Carton objects\n  Carton carton1;                             std::cout << std::endl;\n  Carton carton2 {4.0, 5.0, 6.0, \"PET\"};      std::cout << std::endl;\n  Carton carton3 {2.0, \"Folding boxboard\"};   std::cout << std::endl;\n\n  std::cout << \"carton1 volume is \" << carton1.volume() << std::endl;\n  std::cout << \"carton2 volume is \" << carton2.volume() << std::endl;\n  std::cout << \"carton3 volume is \" << carton3.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_05/Box.h",
    "content": "// Box.h - defines Box class\n#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>     // For standard streams\n#include <format>       // For string formatting\n\nclass Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_05/Carton.h",
    "content": "// Carton.h - defines the Carton class with the Box class as base\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\n  using Box::Box;  // Inherit Box class constructors \n\npublic:\n  Carton(double length, double width, double height, std::string_view mat)\n     : Box{length, width, height}, m_material{mat}\n     { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }\n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_05/Ex14_05.cpp",
    "content": "// Inheriting constructors\n#include <iostream>\n#include \"Carton.h\"       // For the Carton class\n\nint main()\n{\n  Carton cart;                                    // Calls inherited default constructor\n  Carton cube { 4.0 };                                 // Calls inherited constructor\n  Carton copy { cube };                                // Calls default copy constructor\n  Carton carton {1.0, 2.0, 3.0};                       // Calls inherited constructor\n  Carton cerealCarton (50.0, 30.0, 20.0, \"Chipboard\"); // Calls Carton class constructor\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_06/Box.h",
    "content": "// Box.h - defines Box class\n#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>     // For standard streams\n#include <format>       // For string formatting\n\nclass Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  // Copy constructor\n  Box(const Box& b) : m_length{ b.m_length }, m_width{ b.m_width }, m_height{ b.m_height }\n  { std::cout << \"Box copy constructor\" << std::endl; }\n\n  // Destructor\n  ~Box() { std::cout << \"Box destructor\" << std::endl; }\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_06/Carton.h",
    "content": "// Carton.h - defines the Carton class\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  Carton() { std::cout << \"Carton() called.\\n\"; }\n\n  explicit Carton(std::string_view material) : m_material{material}\n  { std::cout << \"Carton(string_view) called.\\n\"; }\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; }  \n\n  // Copy constructor (correct)\n  Carton(const Carton& carton) : Box{ carton }, m_material{ carton.m_material }\n  { std::cout << \"Carton copy constructor\" << std::endl; }\n\n  // Destructor\n  ~Carton() { std::cout << \"Carton destructor. Material = \" << m_material << std::endl; }\n\nprivate:\n  std::string m_material {\"Cardboard\"};\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_06/Ex14_06.cpp",
    "content": "// Destructors in a class hierarchy\n#include <iostream>\n#include \"Carton.h\"   // For the Carton class\n\nint main()\n{\n  Carton carton;\n  Carton candyCarton{50.0, 30.0, 20.0, \"SBB\"};\t// Solid bleached board\n\n  std::cout << \"carton volume is \" << carton.volume() << std::endl;\n  std::cout << \"candyCarton volume is \" << candyCarton.volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07/Box.h",
    "content": "// Box.h - defines Box class\n#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>     // For standard streams\n#include <format>       // For string formatting\n\nclass Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07/Carton.h",
    "content": "// Carton.h - defines the Carton class with the Box class as base\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  Carton() { std::cout << \"Carton() called.\\n\"; }\n\n  explicit Carton(std::string_view material) : m_material{material}\n  { std::cout << \"Carton(string_view) called.\\n\"; }\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; } \n\n  // One new constructor\n  Carton(double l, double w, double h, std::string_view m, double density, double thickness)\n    : Carton{l, w, h, m} \n  {\n    m_thickness = thickness; m_density = density;\n    std::cout << \"Carton(double,double,double,string_view,double,double) called.\\n\";\n  }\n\n  // Copy constructor\n  Carton(const Carton& carton) : Box{carton}, m_material{carton.m_material},\n     m_thickness{carton.m_thickness}, m_density{carton.m_density}\n  {\n    std::cout << \"Carton copy constructor\" << std::endl;\n  }\n\n  // Destructor\n  ~Carton()\n  {\n    std::cout << \"Carton destructor. Material = \" << m_material << std::endl;\n  }\n\n  double getWeight() const\n  {\n    return 2.0 * (m_length * m_width + m_width * m_height + m_height * m_length) \n               * m_thickness * m_density;\n  }\n\nprivate:\n  std::string m_material {\"Cardboard\"};\n  double m_thickness {0.125};   // Material thickness in inch\n  double m_density {0.2};       // Material density in pounds/cubic inch\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07/CerealPack.h",
    "content": "// Cerealpack.h - Class defining a carton of cereal\n#ifndef CEREALPACK_H\n#define CEREALPACK_H\n#include <iostream>\n#include \"Carton.h\"\n#include \"FoodContainer.h\"\n\nclass CerealPack : public Carton, public FoodContainer\n{\npublic:\n  CerealPack(double length, double width, double height, std::string_view cerealType)\n    : Carton {length, width, height, \"Chipboard\"}, FoodContainer {cerealType}\n  {\n    std::cout << \"CerealPack constructor\" << std::endl;\n    FoodContainer::volume = 0.9 * Carton::volume();   // Set food container's volume\n  }\n\n  ~CerealPack()\n  {\n    std::cout << \"CerealPack destructor\" << std::endl;\n  }\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07/Ex14_07.cpp",
    "content": "// Ex14_07 - doesn't compile!\n// Using multiple inheritance can lead to ambiguity if members with \n// the same name are inherited from different base classes.\n#include <iostream>\n#include \"CerealPack.h\"             // For the CerealPack class\n\nint main()\n{\n  CerealPack cornflakes{ 8.0, 3.0, 10.0, \"Cornflakes\" };\n\n  std::cout << \"cornflakes volume is \" << cornflakes.volume() << std::endl\n            << \"cornflakes weight is \" << cornflakes.getWeight() << std::endl;\n/*\n  // Here is one way to make this work (see Ex14_07A and B for alternatives)\n  std::cout << \"cornflakes volume is \" << cornflakes.Carton::volume() << std::endl\n          << \"cornflakes weight is \" << cornflakes.FoodContainer::getWeight() \n          << std::endl;\n*/\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07/FoodContainer.h",
    "content": "#ifndef FOOD_CONTAINER_H\n#define FOOD_CONTAINER_H\n\n#include <iostream>\n#include <string>\n#include <string_view>\n\nclass FoodContainer\n{\npublic:\n  FoodContainer() { std::cout << \"FoodContainer() called.\\n\"; }\n\n  FoodContainer(std::string_view name) : name {name}\n  { std::cout << \"FoodContainer(string_view) called.\\n\"; }\n\n  FoodContainer(std::string_view name, double density, double volume)\n    : name {name}, density {density}, volume {volume}\n  { std::cout << \"FoodContainer(string_view,double,double) called.\\n\"; }\n\n  ~FoodContainer() { std::cout << \"FoodContainer destructor\" << std::endl; }\n\n  double getWeight() const { return volume * density; }\n\nprotected:  // Protected to make initialization in CerealPack constructor work (book says private)\n  std::string name {\"cereal\"};  // Food type\n  double volume {};             // Cubic inches\n  double density {0.03};        // Pounds per cubic inch\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07A/Box.h",
    "content": "// Box.h - defines Box class\n#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>     // For standard streams\n#include <format>       // For string formatting\n\nclass Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07A/Carton.h",
    "content": "// Carton.h - defines the Carton class with the Box class as base\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  Carton() { std::cout << \"Carton() called.\\n\"; }\n\n  explicit Carton(std::string_view material) : m_material{material}\n  { std::cout << \"Carton(string_view) called.\\n\"; }\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; } \n\n  // One new constructor\n  Carton(double l, double w, double h, std::string_view m, double density, double thickness)\n    : Carton{l, w, h, m} \n  {\n    m_thickness = thickness; m_density = density;\n    std::cout << \"Carton(double,double,double,string_view,double,double) called.\\n\";\n  }\n\n  // Copy constructor\n  Carton(const Carton& carton) : Box{carton}, m_material{carton.m_material},\n     m_thickness{carton.m_thickness}, m_density{carton.m_density}\n  {\n    std::cout << \"Carton copy constructor\" << std::endl;\n  }\n\n  // Destructor\n  ~Carton()\n  {\n    std::cout << \"Carton destructor. Material = \" << m_material << std::endl;\n  }\n\n  double getWeight() const\n  {\n    return 2.0 * (m_length * m_width + m_width * m_height + m_height * m_length) \n               * m_thickness * m_density;\n  }\n\nprivate:\n  std::string m_material {\"Cardboard\"};\n  double m_thickness {0.125};   // Material thickness in inch\n  double m_density {0.2};       // Material density in pounds/cubic inch\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07A/CerealPack.h",
    "content": "// Cerealpack.h - Class defining a carton of cereal\n#ifndef CEREALPACK_H\n#define CEREALPACK_H\n#include <iostream>\n#include \"Carton.h\"\n#include \"FoodContainer.h\"\n\nclass CerealPack : public Carton, public FoodContainer\n{\npublic:\n  CerealPack(double length, double width, double height, std::string_view cerealType)\n    : Carton {length, width, height, \"Chipboard\"}, FoodContainer {cerealType}\n  {\n    std::cout << \"CerealPack constructor\" << std::endl;\n    FoodContainer::volume = 0.9 * Carton::volume();   // Set food container's volume\n  }\n\n  ~CerealPack()\n  {\n    std::cout << \"CerealPack destructor\" << std::endl;\n  }\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07A/Ex14_07A.cpp",
    "content": "// Ex14_07A - Disambiguating ambiguous member inheritance through casting\n#include <iostream>\n#include \"CerealPack.h\"             // For the CerealPack class\n\nint main()\n{\n  CerealPack cornflakes{ 8.0, 3.0, 10.0, \"Cornflakes\" };\n\n std::cout << \"cornflakes volume is \" << static_cast<Carton&>(cornflakes).volume()\n    << std::endl         \n    << \"cornflakes weight is \" << static_cast<FoodContainer&>(cornflakes).getWeight()\n    << std::endl;\n /*\n  // Alternate solution by explicitly qualifying the base class name (see also Ex14_07)\n  std::cout << \"cornflakes volume is \" << cornflakes.Carton::volume() << std::endl\n          << \"cornflakes weight is \" << cornflakes.FoodContainer::getWeight() \n          << std::endl;\n*/\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07A/FoodContainer.h",
    "content": "#ifndef FOOD_CONTAINER_H\n#define FOOD_CONTAINER_H\n\n#include <iostream>\n#include <string>\n#include <string_view>\n\nclass FoodContainer\n{\npublic:\n  FoodContainer() { std::cout << \"FoodContainer() called.\\n\"; }\n\n  FoodContainer(std::string_view name) : name {name}\n  { std::cout << \"FoodContainer(string_view) called.\\n\"; }\n\n  FoodContainer(std::string_view name, double density, double volume)\n    : name {name}, density {density}, volume {volume}\n  { std::cout << \"FoodContainer(string_view,double,double) called.\\n\"; }\n\n  ~FoodContainer() { std::cout << \"FoodContainer destructor\" << std::endl; }\n\n  double getWeight() const { return volume * density; }\n\nprotected:  // Protected to make initialization in CerealPack constructor work (book says private)\n  std::string name {\"cereal\"};  // Food type\n  double volume {};             // Cubic inches\n  double density {0.03};        // Pounds per cubic inch\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07B/Box.h",
    "content": "// Box.h - defines Box class\n#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>     // For standard streams\n#include <format>       // For string formatting\n\nclass Box\n{\npublic:\n  // Constructors\n  Box(double l, double w, double h) : m_length{l}, m_width{w}, m_height{h}\n  { std::cout << \"Box(double, double, double) called.\\n\"; }\n\n  explicit Box(double side) : Box{side, side, side} \n  { std::cout << \"Box(double) called.\\n\"; }\n\n  Box() { std::cout << \"Box() called.\\n\"; }   // Default constructor\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\nprotected:                   // Protected to facilitate further examples\n  double m_length {1.0};     // later this chapter (should normally be private)\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Stream output for Box objects\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  return stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n              box.getLength(), box.getWidth(), box.getHeight());\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07B/Carton.h",
    "content": "// Carton.h - defines the Carton class with the Box class as base\n#ifndef CARTON_H\n#define CARTON_H\n\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  Carton() { std::cout << \"Carton() called.\\n\"; }\n\n  explicit Carton(std::string_view material) : m_material{material}\n  { std::cout << \"Carton(string_view) called.\\n\"; }\n\n  Carton(double side, std::string_view material) : Box{side}, m_material{material}\n  { std::cout << \"Carton(double,string_view) called.\\n\"; }\n\n  Carton(double l, double w, double h, std::string_view material)\n    : Box{l, w, h}, m_material{material}\n    { std::cout << \"Carton(double,double,double,string_view) called.\\n\"; } \n\n  // One new constructor\n  Carton(double l, double w, double h, std::string_view m, double density, double thickness)\n    : Carton{l, w, h, m} \n  {\n    m_thickness = thickness; m_density = density;\n    std::cout << \"Carton(double,double,double,string_view,double,double) called.\\n\";\n  }\n\n  // Copy constructor\n  Carton(const Carton& carton) : Box{carton}, m_material{carton.m_material},\n     m_thickness{carton.m_thickness}, m_density{carton.m_density}\n  {\n    std::cout << \"Carton copy constructor\" << std::endl;\n  }\n\n  // Destructor\n  ~Carton()\n  {\n    std::cout << \"Carton destructor. Material = \" << m_material << std::endl;\n  }\n\n  double getWeight() const\n  {\n    return 2.0 * (m_length * m_width + m_width * m_height + m_height * m_length) \n               * m_thickness * m_density;\n  }\n\nprivate:\n  std::string m_material {\"Cardboard\"};\n  double m_thickness {0.125};   // Material thickness in inch\n  double m_density {0.2};       // Material density in pounds/cubic inch\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07B/CerealPack.h",
    "content": "// Cerealpack.h - Class defining a carton of cereal\n#ifndef CEREALPACK_H\n#define CEREALPACK_H\n#include <iostream>\n#include \"Carton.h\"\n#include \"FoodContainer.h\"\n\nclass CerealPack : public Carton, public FoodContainer\n{\npublic:\n  CerealPack(double length, double width, double height, std::string_view cerealType)\n    : Carton {length, width, height, \"Chipboard\"}, FoodContainer {cerealType}\n  {\n    std::cout << \"CerealPack constructor\" << std::endl;\n    FoodContainer::volume = 0.9 * Carton::volume();   // Set food container's volume\n  }\n\n  ~CerealPack()\n  {\n    std::cout << \"CerealPack destructor\" << std::endl;\n  }\n\n  using Carton::volume;\n  using FoodContainer::getWeight;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07B/Ex14_07B.cpp",
    "content": "// Ex14_07B - Disambiguating ambiguous member through \n// using declarations in the derived class (CerealPack)\n#include <iostream>\n#include \"CerealPack.h\"          // For the CerealPack class\n\nint main()\n{\n  CerealPack cornflakes{ 8.0, 3.0, 10.0, \"Cornflakes\" };\n\n  std::cout << \"cornflakes volume is \" << cornflakes.volume() << std::endl\n            << \"cornflakes weight is \" << cornflakes.getWeight() << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 14/Ex14_07B/FoodContainer.h",
    "content": "#ifndef FOOD_CONTAINER_H\n#define FOOD_CONTAINER_H\n\n#include <iostream>\n#include <string>\n#include <string_view>\n\nclass FoodContainer\n{\npublic:\n  FoodContainer() { std::cout << \"FoodContainer() called.\\n\"; }\n\n  FoodContainer(std::string_view name) : name {name}\n  { std::cout << \"FoodContainer(string_view) called.\\n\"; }\n\n  FoodContainer(std::string_view name, double density, double volume)\n    : name {name}, density {density}, volume {volume}\n  { std::cout << \"FoodContainer(string_view,double,double) called.\\n\"; }\n\n  ~FoodContainer() { std::cout << \"FoodContainer destructor\" << std::endl; }\n\n  double getWeight() const { return volume * density; }\n\nprotected:  // Protected to make initialization in CerealPack constructor work (book says private)\n  std::string name {\"cereal\"};  // Food type\n  double volume {};             // Cubic inches\n  double density {0.03};        // Pounds per cubic inch\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_01/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_01/Ex15_01.cpp",
    "content": "// Behavior of inherited functions in a derived class\n#include \"Box.h\"                                // For the Box class\n#include \"ToughPack.h\"                          // For the ToughPack class\n\nint main()\n{\n  Box box {20.0, 30.0, 40.0};            // Create a box\n  ToughPack hardcase {20.0, 30.0, 40.0}; // Create a tough pack - same size\n\n  box.showVolume();      // Display volume of base box (calls volume() for box)\n  hardcase.showVolume(); // Display volume of derived box (call volume() for hardcase)\n\n  //std::cout << \"hardcase volume is \" << hardcase.volume() << std::endl;\n  //Box* box_pointer{ &hardcase };\n  //std::cout << \"hardcase volume through a Box* pointer is \"\n  //          << box_pointer->volume() << std::endl;\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_01/ToughPack.h",
    "content": "#ifndef TOUGHPACK_H\n#define TOUGHPACK_H\n\n#include \"Box.h\"\n\nclass ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const { return 0.85 * m_length * m_width * m_height; }\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_02/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_02/Carton.h",
    "content": "#ifndef CARTON_H\n#define CARTON_H\n#include <algorithm>    // For std::max()\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_02/Ex15_02.cpp",
    "content": "// Using virtual functions\n#include <iostream>\n#include \"Box.h\"                                 // For the Box class\n#include \"ToughPack.h\"                           // For the ToughPack class\n#include \"Carton.h\"                              // For the Carton class\n\nint main()\n{\n  Box box {20.0, 30.0, 40.0};\n  ToughPack hardcase {20.0, 30.0, 40.0};        // A derived box - same size\n  Carton carton {20.0, 30.0, 40.0, \"Plastic\"};  // A different derived box\n\n  box.showVolume();        // Volume of Box\n  hardcase.showVolume();   // Volume of ToughPack\n  carton.showVolume();     // Volume of Carton\n\n  // Now using a base pointer...\n  Box* base {&box};        // Points to type Box\n  std::cout << \"\\nbox volume through base pointer is \" << base->volume() << std::endl;\n  base ->showVolume();\n\n  base = &hardcase;        // Points to type ToughPack\n  std::cout << \"hardcase volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n\n  base = &carton;          // Points to type Carton\n  std::cout << \"carton volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_02/ToughPack.h",
    "content": "#ifndef TOUGHPACK_H\n#define TOUGHPACK_H\n\n#include \"Box.h\"\n\nclass ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const { return 0.85 * m_length * m_width * m_height; }\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_03/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_03/Carton.h",
    "content": "#ifndef CARTON_H\n#define CARTON_H\n#include <algorithm>    // For std::max()\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_03/Ex15_03.cpp",
    "content": "// Access specifiers and virtual functions\n#include <iostream>\n#include \"Box.h\"                                 // For the Box class\n#include \"ToughPack.h\"                           // For the ToughPack class\n#include \"Carton.h\"                              // For the Carton class\n\nint main()\n{\n  Box box {20.0, 30.0, 40.0};\n  ToughPack hardcase {20.0, 30.0, 40.0};         // A derived box - same size\n  Carton carton {20.0, 30.0, 40.0, \"Plastic\"};   // A different derived box\n\n  box.showVolume();          // Volume of Box\n  hardcase.showVolume();     // Volume of ToughPack\n  carton.showVolume();       // Volume of Carton\n\n// Uncomment the following statement for an error\n// std::cout << \"\\nhardcase volume is \" << hardcase.volume() << std::endl;\n\n  // Now using a base pointer...\n  Box* base {&box};          // Points to type Box\n  std::cout << \"\\nbox volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n\n  base = &hardcase;          // Points to type ToughPack\n  std::cout << \"hardcase volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n\n  base = &carton;                // Points to type Carton\n  std::cout << \"carton volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_03/ToughPack.h",
    "content": "#ifndef TOUGHPACK_H\n#define TOUGHPACK_H\n\n#include \"Box.h\"\n\nclass ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\nprotected:\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * m_length * m_width * m_height; }\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_04/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume(int i = 5) const\n  { \n    std::cout << \"(Box argument = \" << i << \") \";\n    return m_length * m_width * m_height;\n  }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_04/Carton.h",
    "content": "#ifndef CARTON_H\n#define CARTON_H\n#include <algorithm>    // For std::max()\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume(int i = 50) const override\n  {\n    std::cout << \"(Carton argument = \" << i << \") \";\n    return std::max((m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5), 0.0);\n  }\n\nprivate:\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_04/Ex15_04.cpp",
    "content": "// Default parameter values in virtual functions\n#include <iostream>\n#include \"Box.h\"                                 // For the Box class\n#include \"ToughPack.h\"                           // For the ToughPack class\n#include \"Carton.h\"                              // For the Carton class\n\nint main()\n{\n  Box box{ 20.0, 30.0, 40.0 };\n  ToughPack hardcase{ 20.0, 30.0, 40.0 };        // A derived box - same size\n  Carton carton{ 20.0, 30.0, 40.0, \"Plastic\" };  // A different derived box\n\n  box.showVolume();        // Volume of Box\n  hardcase.showVolume();   // Volume of ToughPack\n  carton.showVolume();     // Volume of Carton\n\n  std::cout << \"\\nhardcase volume is \" << hardcase.volume() << std::endl;\n\n  // Now using a base pointer...\n  Box* base{ &box };        // Points to type Box\n  std::cout << \"\\nbox volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n\n  base = &hardcase;        // Points to type ToughPack\n  std::cout << \"hardcase volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n\n  base = &carton;          // Points to type Carton\n  std::cout << \"carton volume through base pointer is \" << base->volume() << std::endl;\n  base->showVolume();\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_04/ToughPack.h",
    "content": "#ifndef TOUGHPACK_H\n#define TOUGHPACK_H\n\n#include \"Box.h\"\n\nclass ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume(int i = 500) const override\n  {\n    std::cout << \"(ToughPack argument = \" << i << \") \";\n    return 0.85 * m_length * m_width * m_height;\n  }\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_05/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_05/Carton.h",
    "content": "#ifndef CARTON_H\n#define CARTON_H\n#include <algorithm>    // For std::max()\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_05/Ex15_05.cpp",
    "content": "// Using a reference parameter to call virtual function\n#include <iostream>\n#include \"Box.h\"            // For the Box class\n#include \"ToughPack.h\"      // For the ToughPack class\n#include \"Carton.h\"         // For the Carton class\n\n// Global function to display the volume of a box\nvoid showVolume(const Box& box)\n{\n  std::cout << \"Box usable volume is \" << box.volume() << std::endl;\n}\n\nint main()\n{\n  Box box {20.0, 30.0, 40.0};                  // A base box\n  ToughPack hardcase {20.0, 30.0, 40.0};       // A derived box - same size\n  Carton carton {20.0, 30.0, 40.0, \"Plastic\"}; // A different derived box\n\n  showVolume(box);       // Display volume of base box\n  showVolume(hardcase);  // Display volume of derived box\n  showVolume(carton);    // Display volume of derived box\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_05/ToughPack.h",
    "content": "#ifndef TOUGHPACK_H\n#define TOUGHPACK_H\n\n#include \"Box.h\"\n\nclass ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * m_length * m_width * m_height; }\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_06/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_06/Carton.h",
    "content": "#ifndef CARTON_H\n#define CARTON_H\n#include <algorithm>    // For std::max()\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_06/Ex15_06.cpp",
    "content": "// Polymorphic vectors of smart pointers\n#include <iostream>\n#include <memory>                                // For smart pointers\n#include <vector>                                // For vector\n#include \"Box.h\"                                 // For the Box class\n#include \"ToughPack.h\"                           // For the ToughPack class\n#include \"Carton.h\"                              // For the Carton class\n\nint main()\n{\n  // Careful: this first attempt at a mixed collection is a bad idea (object slicing!)\n  std::vector<Box> boxes;\n  boxes.push_back(Box{20.0, 30.0, 40.0});\n  boxes.push_back(ToughPack{20.0, 30.0, 40.0});\n  boxes.push_back(Carton{20.0, 30.0, 40.0, \"plastic\"});\n\n  for (const auto& box : boxes)\n    box.showVolume();\n\n  std::cout << std::endl;\n\n  // Next, we create a proper polymorphic vector<>:\n  std::vector<std::unique_ptr<Box>> polymorphicBoxes;\n  polymorphicBoxes.push_back(std::make_unique<Box>(20.0, 30.0, 40.0));\n  polymorphicBoxes.push_back(std::make_unique<ToughPack>(20.0, 30.0, 40.0));\n  polymorphicBoxes.push_back(std::make_unique<Carton>(20.0, 30.0, 40.0, \"plastic\"));\n\n  for (const auto& box : polymorphicBoxes)\n    box->showVolume();\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_06/ToughPack.h",
    "content": "#ifndef TOUGHPACK_H\n#define TOUGHPACK_H\n\n#include \"Box.h\"\n\nclass ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\nprotected:\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * m_length * m_width * m_height; }\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_07/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n  \n  // Uncomment virtual to ensure destructors of derived classes are called correctly\n  /*virtual*/ ~Box() { std::cout << \"Box destructor called\" << std::endl; }\n  \n  // More typical declaration of the destructor of a base class\n  // virtual ~Box() = default;\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_07/Carton.h",
    "content": "#ifndef CARTON_H\n#define CARTON_H\n#include <algorithm>    // For std::max()\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n  ~Carton() { std::cout << \"Carton destructor called\" << std::endl; }\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_07/Ex15_07.cpp",
    "content": "// Polymorphic vectors of smart pointers\n#include <iostream>\n#include <memory>                                // For smart pointers\n#include <vector>                                // For vector\n#include \"Box.h\"                                 // For the Box class\n#include \"ToughPack.h\"                           // For the ToughPack class\n#include \"Carton.h\"                              // For the Carton class\n\nint main()\n{\n  // Careful: this first attempt at a mixed collection is a bad idea (object slicing!)\n  std::vector<Box> boxes;\n  boxes.push_back(Box{20.0, 30.0, 40.0});\n  boxes.push_back(ToughPack{20.0, 30.0, 40.0});\n  boxes.push_back(Carton{20.0, 30.0, 40.0, \"plastic\"});\n\n  for (const auto& p : boxes)\n    p.showVolume();\n\n  std::cout << std::endl;\n  \n  // Next, we create a proper polymorphic vector<>:\n  std::vector<std::unique_ptr<Box>> polymorphicBoxes;\n  polymorphicBoxes.push_back(std::make_unique<Box>(20.0, 30.0, 40.0));\n  polymorphicBoxes.push_back(std::make_unique<ToughPack>(20.0, 30.0, 40.0));\n  polymorphicBoxes.push_back(std::make_unique<Carton>(20.0, 30.0, 40.0, \"plastic\"));\n\n  for (const auto& p : polymorphicBoxes)\n    p->showVolume();\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_07/ToughPack.h",
    "content": "#ifndef TOUGHPACK_H\n#define TOUGHPACK_H\n\n#include \"Box.h\"\n\nclass ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n  ~ToughPack() { std::cout << \"ToughPack destructor called\" << std::endl; }\n\nprotected:\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * m_length * m_width * m_height; }\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_07A/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n  \n  virtual ~Box() = default;\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_07A/Carton.h",
    "content": "#ifndef CARTON_H\n#define CARTON_H\n#include <algorithm>    // For std::max()\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n  ~Carton() override = default;\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_07A/Ex15_07A.cpp",
    "content": "// Calling the base class version of a virtual function (see ToughPack::volume())\n#include <iostream>\n#include <memory>                                // For smart pointers\n#include <vector>                                // For vector\n#include \"Box.h\"                                 // For the Box class\n#include \"ToughPack.h\"                           // For the ToughPack class\n#include \"Carton.h\"                              // For the Carton class\n\nint main()\n{\n  // Careful: this first attempt at a mixed collection is a bad idea (object slicing!)\n  std::vector<Box> boxes;\n  boxes.push_back(Box{20.0, 30.0, 40.0});\n  boxes.push_back(ToughPack{20.0, 30.0, 40.0});\n  boxes.push_back(Carton{20.0, 30.0, 40.0, \"plastic\"});\n\n  for (const auto& p : boxes)\n    p.showVolume();\n\n  std::cout << std::endl;\n  \n  // Next, we create a proper polymorphic vector<>:\n  std::vector<std::unique_ptr<Box>> polymorphicBoxes;\n  polymorphicBoxes.push_back(std::make_unique<Box>(20.0, 30.0, 40.0));\n  polymorphicBoxes.push_back(std::make_unique<ToughPack>(20.0, 30.0, 40.0));\n  polymorphicBoxes.push_back(std::make_unique<Carton>(20.0, 30.0, 40.0, \"plastic\"));\n\n  for (const auto& p : polymorphicBoxes)\n    p->showVolume();\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_07A/ToughPack.h",
    "content": "#ifndef TOUGHPACK_H\n#define TOUGHPACK_H\n\n#include \"Box.h\"\n\nclass ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\nprotected:\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * Box::volume(); }\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_08/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box(double length, double width, double height)\n    : m_length {length}, m_width {width}, m_height {height}\n  {\n    std::cout << \"Box constructor called for a Box of volume \" << volume() << std::endl;\n  }\n  virtual ~Box()\n  {\n    std::cout << \"Box destructor called for a Box of volume \" << volume() << std::endl;\n  }\n\n  // Function to calculate volume of a Box\n  virtual double volume() const { return m_length * m_width * m_height; }\n\n  void showVolume() const\n  {\n    std::cout << \"The volume from inside Box::showVolume() is \"\n              << volume() << std::endl;\n  }\n\nprivate:\n  double m_length, m_width, m_height;\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_08/Ex14_08.cpp",
    "content": "// Calling virtual functions from constructors and destructors\n#include \"Box.h\"\n#include \"ToughPack.h\"\n\nint main()\n{\n  ToughPack toughPack{ 1.0, 2.0, 3.0 };\n  toughPack.showVolume();     // Should show a volume equal to 85% of 1x2x3, or 5.1\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_08/ToughPack.h",
    "content": "#ifndef TOUGH_PACK_H\n#define TOUGH_PACK_H\n\n#include \"Box.h\"\n\nclass ToughPack : public Box\n{\npublic:\n  ToughPack(double length, double width, double height)\n    : Box{length, width, height}\n  {\n    std::cout << \"ToughPack constructor called for a Box of volume \"\n              << volume() << std::endl;\n  }\n  virtual ~ToughPack()\n  {\n    std::cout << \"ToughPack destructor called for a Box of volume \"\n              << volume() << std::endl;\n  }\n\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * Box::volume(); }\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_09/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {}\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n  virtual ~Box() = default;\n\n  // Function to show the volume of an object\n  void showVolume() const\n  { std::cout << \"Box usable volume is \" << volume() << std::endl; }\n\n  // Function to calculate the volume of a Box object\n  virtual double volume() const { return m_length * m_width * m_height; }\n\nprotected:      // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_09/Carton.h",
    "content": "#ifndef CARTON_H\n#define CARTON_H\n#include <algorithm>    // For std::max()\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_09/Ex15_09.cpp",
    "content": "// Using the typeid() operator\n#include <iostream>\n#include <typeinfo>         // For the std::type_info class\n#include \"Box.h\"\n#include \"Carton.h\"\n\n// Define trivial non-polymorphic base and derived classes:\nclass NonPolyBase {};\nclass NonPolyDerived : public NonPolyBase {};\n\nBox& getSomeBox();              // Function returning a reference to a polymorphic type\nNonPolyBase& getSomeNonPoly();  // Function returning a reference to a non-polymorphic type\n\nint main()\n{\n  // Part 1: typeid() on types and == operator\n  std::cout << \"Type double has name \" << typeid(double).name() << std::endl;\n  std::cout << \"1 is \" << (typeid(1) == typeid(int)? \"an int\" : \"no int\") << std::endl;\n\n  // Part 2: typeid() on polymorphic references\n  Carton carton{ 1, 2, 3, \"paperboard\" };\n  Box& boxReference{ carton };\n\n  std::cout << \"Type of carton is \"       << typeid(carton).name()       << std::endl;\n  std::cout << \"Type of boxReference is \" << typeid(boxReference).name() << std::endl;\n  std::cout << \"These are \" << (typeid(carton) == typeid(boxReference)? \"\" : \"not \")\n            << \"equal\" << std::endl;\n\n  // Part 3: typeid() on polymorphic pointers\n  Box* boxPointer{ &carton };\n  std::cout << \"Type of &carton is \"     << typeid(&carton).name()     << std::endl;\n  std::cout << \"Type of boxPointer is \"  << typeid(boxPointer).name()  << std::endl;\n  std::cout << \"Type of *boxPointer is \" << typeid(*boxPointer).name() << std::endl;\n\n  // Part 4: typeid() with non-polymorphic classes\n  NonPolyDerived derived;\n  NonPolyBase& baseRef{ derived };\n\n  std::cout << \"Type of baseRef is \" << typeid(baseRef).name() << std::endl;\n\n  // Part 5: typeid() on expressions\n  const auto& type_info1{ typeid(getSomeBox()) };       // function call evaluated\n  const auto& type_info2{ typeid(getSomeNonPoly()) };   // function call not evaluated\n  std::cout << \"Type of getSomeBox() is \" << type_info1.name() << std::endl;\n  std::cout << \"Type of getSomeNonPoly() is \"    << type_info2.name() << std::endl;\n}\n\nBox& getSomeBox()\n{\n  std::cout << \"getSomeBox() called...\" << std::endl;\n  static Carton carton{ 2, 3, 5, \"duplex\" };\n  return carton;\n}\nNonPolyBase& getSomeNonPoly()\n{\n  std::cout << \"getSomeNonPoly() called...\" << std::endl;\n  static NonPolyDerived derived;\n  return derived;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_10/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n#include <iostream>\n\nclass Box\n{\npublic:\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n  virtual ~Box() = default;            // Virtual destructor\n  virtual double volume() const = 0;   // Function to calculate the volume\n\nprotected:  // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_10/Carton.h",
    "content": "#ifndef CARTON_H\n#define CARTON_H\n#include <algorithm>    // For std::max()\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_10/Ex15_10.cpp",
    "content": "// Using an abstract class\n#include <iostream>\n#include \"Box.h\"                                 // For the Box class\n#include \"ToughPack.h\"                           // For the ToughPack class\n#include \"Carton.h\"                              // For the Carton class\n\nint main()\n{\n  // Box box{20.0, 30.0, 40.0};                  // Uncomment for compiler error\n\n  ToughPack hardcase {20.0, 30.0, 40.0};         // A derived box - same size\n  Carton carton {20.0, 30.0, 40.0, \"plastic\"};   // A different derived box\n\n  Box*pBox {&hardcase};                          // Base pointer - derived address\n  std::cout << \"hardcase volume is \" << pBox->volume() << std::endl;\n\n  pBox = &carton;                                // New derived address\n  std::cout << \"carton volume is \" << pBox->volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_10/ToughPack.h",
    "content": "#ifndef TOUGHPACK_H\n#define TOUGHPACK_H\n\n#include \"Box.h\"\n\nclass ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\nprotected:\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * m_length * m_width * m_height; }\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_11/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include \"Vessel.h\"\n\nclass Box : public Vessel\n{\npublic:\n  Box(double l, double w, double h) : m_length {l}, m_width {w}, m_height {h} {}\n\n  double volume() const override { return m_length * m_width * m_height; }\n\nprotected:   // Should be private in production-quality code (add getters to access)\n  double m_length, m_width, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_11/Can.h",
    "content": "// Can.h Class defining a cylindrical can of a given height and diameter\n#ifndef CAN_H\n#define CAN_H\n\n#include \"Vessel.h\"\n#include <numbers>\n\nclass Can : public Vessel\n{\npublic:\n  Can(double diameter, double height) \n    : m_diameter {diameter}, m_height {height} {}    \n\n  double volume() const override\n  { \n    return std::numbers::pi * m_diameter * m_diameter * m_height / 4;\n  }\n\nprivate:\n  double m_diameter, m_height;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_11/Carton.h",
    "content": "#ifndef CARTON_H\n#define CARTON_H\n#include <algorithm>    // For std::max()\n#include <string>\n#include <string_view>\n#include \"Box.h\"\n\nclass Carton : public Box\n{\npublic:\n  // Constructor explicitly calling the base constructor\n  Carton(double l, double w, double h, std::string_view mat = \"cardboard\")\n    : Box{l, w, h}, m_material{mat}\n  {}\n\n  // Function to calculate the volume of a Carton object\n  double volume() const override\n  {\n    const double volume {(m_length - 0.5) * (m_width - 0.5) * (m_height - 0.5)};\n    return std::max(volume, 0.0);     // Or: return volume > 0.0 ? volume : 0.0; \n  }\nprivate:\n  std::string m_material;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_11/Ex15_11.cpp",
    "content": "// Using an interface class and indirect base classes\n#include <iostream>\n#include <vector>                     // For the vector container\n#include \"Box.h\"                      // For the Box class\n#include \"ToughPack.h\"                // For the ToughPack class\n#include \"Carton.h\"                   // For the Carton class\n#include \"Can.h\"                      // for the Can class\n\nint main()\n{\n  Box box {40, 30, 20};\n  Can can {10, 3};\n  Carton carton {40, 30, 20, \"Plastic\"};\n  ToughPack hardcase {40, 30, 20};\n\n  std::vector<const Vessel*> vessels {&box, &can, &carton, &hardcase};\n\n  for (const auto* vessel : vessels)\n    std::cout << \"Volume is \" << vessel->volume() << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_11/ToughPack.h",
    "content": "#ifndef TOUGHPACK_H\n#define TOUGHPACK_H\n\n#include \"Box.h\"\n\nclass ToughPack : public Box\n{\npublic:\n  // Inherit the Box(length, width, height) constructor\n  using Box::Box;\n\nprotected:\n  // Function to calculate volume of a ToughPack allowing 15% for packing\n  double volume() const override { return 0.85 * m_length * m_width * m_height; }\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 15/Ex15_11/Vessel.h",
    "content": "// Vessel.h  Abstract class defining a vessel\n#ifndef VESSEL_H\n#define VESSEL_H\n\nclass Vessel\n{\npublic:\n  virtual ~Vessel() = default;         // As always: a virtual destructor!\n  virtual double volume() const = 0;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_01/Ex16_01.cpp",
    "content": "// Throwing and catching exceptions\n#include <iostream>\n\nint main()\n{\n  for (size_t i {}; i < 5; ++i)\n  {\n    try\n    {\n      if (i < 2)\n        throw i;\n\n      std::cout << \"i not thrown - value is \" << i << std::endl;\n\n      if (i > 3)\n        throw \"Here is another!\";\n\n      std::cout << \"End of the try block.\" << std::endl;\n    }\n    catch (size_t i)     // Catch exceptions of type size_t\n    {\n      std::cout << \"i caught - value is \" << i << std::endl;\n    }\n    catch (const char* message)    // Catch exceptions of type char*\n    {\n      std::cout << \"message caught - value is \\\"\" << message << '\"' << std::endl;\n    }\n\n    std::cout << \"End of the for loop body (after the catch blocks)\"\n              << \" - i is \" << i << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_02/Ex16_02.cpp",
    "content": "// Throw an exception object\n#include <iostream>\n#include \"Troubles.h\"\n\nvoid trySomething(int i);\n\nint main()\n{\n  for (int i {}; i < 2; ++i)\n  {\n    try\n    {\n      trySomething(i);\n    }\n    catch (const Trouble& t)\n    {\n      // What seems to be the trouble?\n      std::cout << \"Exception: \" << t.what() << std::endl;\n    }\n  }\n}\n\nvoid trySomething(int i)\n{\n  // There's always trouble when trying something...\n  if (i == 0)\n    throw Trouble {};\n  else\n    throw Trouble {\"Nobody knows the trouble I've seen...\"};\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_02/Troubles.h",
    "content": "// Exception class definition\n#ifndef MYTROUBLES_H\n#define MYTROUBLES_H\n#include <string>\n#include <string_view>\n\nclass Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\") \n    : m_message {message} \n  {}\n  std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_03/Ex16_03.cpp",
    "content": "// Throwing and catching objects in a hierarchy\n#include <iostream>\n#include \"Troubles.h\"\n\nint main()\n{\n  for (int i {}; i < 7; ++i)\n  {\n    try\n    {\n      if (i == 3)\n        throw Trouble{};\n      else if (i == 5)\n        throw MoreTrouble{};\n      else if (i == 6)\n        throw BigTrouble{};\n    }\n    catch (const BigTrouble& t)\n    {\n      std::cout << \"BigTrouble object caught: \" << t.what() << std::endl;\n    }\n    catch (const MoreTrouble& t)\n    {\n      std::cout << \"MoreTrouble object caught: \" << t.what() << std::endl;\n    }\n    catch (const Trouble& t)\n    {\n      std::cout << \"Trouble object caught: \" << t.what() << std::endl;\n    }\n\n    std::cout << \"End of the for loop (after the catch blocks) - i is \" << i << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_03/Troubles.h",
    "content": "// MyTroubles.h Exception classes\n#ifndef MYTROUBLES_H\n#define MYTROUBLES_H\n#include <string>\n#include <string_view>\n\nclass Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\") \n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nclass MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nclass BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_04/Ex16_04.cpp",
    "content": "// Catching exceptions with a base class handler\n#include <iostream>\n#include <typeinfo>\t\t\t// for the type_info type returned by the typeid operator\n#include \"Troubles.h\"\n\nint main()\n{\n  for (int i {}; i < 7; ++i)\n  {\n    try\n    {\n      if (i == 3)\n        throw Trouble{};\n      else if (i == 5)\n        throw MoreTrouble{};\n      else if (i == 6)\n        throw BigTrouble{};\n    }\n    catch (const Trouble& t)\n    {\n      //std::cout << \"Trouble object caught: \" << t.what() << std::endl;\n      std::cout << typeid(t).name() << \" object caught: \" << t.what() << std::endl;\n    }\n    std::cout << \"End of the for loop (after the catch blocks) - i is \" << i << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_04/Troubles.h",
    "content": "// MyTroubles.h Exception classes\n#ifndef MYTROUBLES_H\n#define MYTROUBLES_H\n#include <string>\n#include <string_view>\n\nclass Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nclass MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nclass BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_05/Ex16_05.cpp",
    "content": "// Rethrowing exceptions\n#include <iostream>\n#include <typeinfo>\n#include \"Troubles.h\"\n\nint main()\n{\n  for (int i {}; i < 7; ++i)\n  {\n    try\n    {\n      try\n      {\n        if (i == 3)\n          throw Trouble{};\n        else if (i == 5)\n          throw MoreTrouble{};\n        else if (i == 6)\n          throw BigTrouble{};\n      }\n      catch (const Trouble& t)\n      {\n        if (typeid(t) == typeid(Trouble))\n          std::cout << \"Trouble object caught in inner block: \" << t.what() << std::endl;\n        else\n          throw;     // Rethrow current exception\n      }\n    }\n    catch (const Trouble& t)\n    {\n      std::cout << typeid(t).name() << \" object caught in outer block: \"\n                << t.what() << std::endl;\n    }\n    std::cout << \"End of the for loop (after the catch blocks) - i is \" << i << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_05/Troubles.h",
    "content": "// MyTroubles.h Exception classes\n#ifndef MYTROUBLES_H\n#define MYTROUBLES_H\n#include <string>\n#include <string_view>\n\nclass Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\") \n    : m_message {message}\n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nclass MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nclass BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_06/Ex16_06.cpp",
    "content": "// Catching any exception\n#include <iostream>\n#include <typeinfo>         // For use of typeid()\n#include \"Troubles.h\"\n\nint main()\n{\n  for (int i {}; i < 7; ++i)\n  {\n    try\n    {\n      try\n      {\n        if (i == 3)\n          throw Trouble{};\n        else if (i == 5)\n          throw MoreTrouble{};\n        else if (i == 6)\n          throw BigTrouble{};\n      }\n      catch (const BigTrouble& bt)\n      {\n        std::cout << \"Oh dear, big trouble. Let's handle it here and now.\" << std::endl;\n        // Do not rethrow...\n      }\n      catch (...)   // Catch any other exception\n      {\n        std::cout << \"We caught something else! Let's rethrow it. \" << std::endl;\n        throw;      // Rethrow current exception\n      }\n    }\n    catch (const Trouble& t)\n    {\n      std::cout << typeid(t).name() << \" object caught in outer block: \"\n                << t.what() << std::endl;\n    }\n    std::cout << \"End of the for loop (after the catch blocks) - i is \" << i << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_06/Troubles.h",
    "content": "// MyTroubles.h Exception classes\n#ifndef MYTROUBLES_H\n#define MYTROUBLES_H\n#include <string>\n#include <string_view>\n\nclass Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nclass MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nclass BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_07/Ex16_07.cpp",
    "content": "// Exceptions may result in resource leaks!\n#include <iostream>\n#include <cmath>                    // For std::sqrt()\n#include \"Troubles.h\"\n\ndouble computeValue(size_t x);         // A function to compute a single value\ndouble* computeValues(size_t howMany); // A function to compute an array of values\n\nint main()\n{\n  try\n  {\n    double* values{ computeValues(10'000) };\n    // Unfortunately we won't be making it this far...\n    delete[] values;\n  }\n  catch (const Trouble&)\n  {\n    std::cout << \"No worries: I've caught it!\" << std::endl;\n  }\n}\n\ndouble* computeValues(size_t howMany)\n{\n  double* values{ new double[howMany] };\n  for (size_t i{}; i < howMany; ++i)\n    values[i] = computeValue(i);\n  return values;\n}\n\ndouble computeValue(size_t x)\n{\n  if (x < 100)\n    return std::sqrt(x);   // Return the square root of the input argument\n  else\n    throw Trouble{ \"The trouble with trouble is, it starts out as fun!\" };\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_07/Troubles.h",
    "content": "// MyTroubles.h Exception classes\n#ifndef MYTROUBLES_H\n#define MYTROUBLES_H\n#include <string>\n#include <string_view>\n\nclass Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nclass MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nclass BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_07A/Ex16_07A.cpp",
    "content": "// Use of a try-catch block to fix the memory leak!\n#include <iostream>\n#include <cmath>                    // For std::sqrt()\n#include \"Troubles.h\"\n\ndouble computeValue(size_t x);         // A function to compute a single value\ndouble* computeValues(size_t howMany); // A function to compute an array of values\n\nint main()\n{\n  try\n  {\n    double* values{ computeValues(10'000) };\n    // Unfortunately we won't be making it this far...\n    delete[] values;\n  }\n  catch (const Trouble&)\n  {\n    std::cout << \"No worries: I've caught it!\" << std::endl;\n  }\n}\n\ndouble* computeValues(size_t howMany)\n{\n  double* values{ new double[howMany] };\n  try\n  {\n    for (size_t i {}; i < howMany; ++i)\n      values[i] = computeValue(i);\n    return values;\n  }\n  catch (const Trouble&)\n  {\n    std::cout << \"I sense trouble... Freeing memory...\" << std::endl;\n    delete[] values;\n    throw;\n  }\n}\n\ndouble computeValue(size_t x)\n{\n  if (x < 100)\n    return std::sqrt(x);   // Return the square root of the input argument\n  else\n    throw Trouble{ \"The trouble with trouble is, it starts out as fun!\" };\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_07A/Troubles.h",
    "content": "// MyTroubles.h Exception classes\n#ifndef MYTROUBLES_H\n#define MYTROUBLES_H\n#include <string>\n#include <string_view>\n\nclass Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message}\n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nclass MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nclass BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_07B/DoubleArrayRAII.h",
    "content": "// A custom RAII class to manage a dynamic double[] array resource\n#ifndef DOUBLE_ARRAY_RAII_H\n#define DOUBLE_ARRAY_RAII_H\n\n#include <iostream>\n\nclass DoubleArrayRAII final\n{\npublic:\n  explicit DoubleArrayRAII(size_t size) : m_resource{ new double[size] } {}\n  ~DoubleArrayRAII()\n  {\n    std::cout << \"Freeing memory...\" << std::endl;\n    delete[] m_resource;\n  }\n\n  // Delete copy constructor and assignment operator\n  DoubleArrayRAII(const DoubleArrayRAII&) = delete;\n  DoubleArrayRAII& operator=(const DoubleArrayRAII&) = delete;\n\n  // Array subscript operator\n  double& operator[](size_t index) noexcept { return m_resource[index]; }\n  const double& operator[](size_t index) const noexcept { return m_resource[index]; }\n\n  // Function to access the encapsulated resource\n  double* get() const noexcept { return m_resource; }\n\n  // Function to instruct the RAII object to hand over the resource.\n  // Once called, the RAII object shall no longer release the resource\n  // upon destruction anymore. Returns the resource in the process.\n  double* release() noexcept\n  {\n    double* result = m_resource;\n    m_resource = nullptr;\n    return result;\n  }\n\nprivate:\n  double* m_resource;\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_07B/Ex16_07B.cpp",
    "content": "// Exceptions may result in resource leaks!\n#include <iostream>\n#include <cmath>                    // For std::sqrt()\n#include \"Troubles.h\"\n#include \"DoubleArrayRAII.h\"\n\ndouble computeValue(size_t x);         // A function to compute a single value\ndouble* computeValues(size_t howMany); // A function to compute an array of values\n\nint main()\n{\n  try\n  {\n    double* values{ computeValues(10'000) };\n    // Unfortunately we won't be making it this far...\n    delete[] values;\n  }\n  catch (const Trouble&)\n  {\n    std::cout << \"No worries: I've caught it!\" << std::endl;\n  }\n}\n\ndouble* computeValues(size_t howMany)\n{\n  DoubleArrayRAII values{ howMany };\n  for (size_t i{}; i < howMany; ++i)\n    values[i] = computeValue(i);\n  return values.release();\n}\n\ndouble computeValue(size_t x)\n{\n  if (x < 100)\n    return std::sqrt(x);   // Return the square root of the input argument\n  else\n    throw Trouble{ \"The trouble with trouble is, it starts out as fun!\" };\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_07B/Troubles.h",
    "content": "// MyTroubles.h Exception classes\n#ifndef MYTROUBLES_H\n#define MYTROUBLES_H\n#include <string>\n#include <string_view>\n\nclass Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nclass MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nclass BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_07C/Ex16_07C.cpp",
    "content": "// Avoid resource leaks due to exceptions using std::unique_ptr<>\n// Note: this example is given but not named in the text.\n// Instead of a custom RAII class DoubleArrayRAII, it uses std::unique_ptr<>.\n// Unlike the former, the latter can be returned from computeValues() as well.\n#include <iostream>\n#include <memory>\n#include <cmath>                    // For std::sqrt()\n#include \"Troubles.h\"\n\ndouble computeValue(size_t x);      // A function to compute a single value\nstd::unique_ptr<double[]> computeValues(size_t howMany); // A function to compute an array of values\n\nint main()\n{\n  try\n  {\n    auto values{ computeValues(10'000) }; // Cannot leak either: resource is managed by RAII object!\n  }\n  catch (const Trouble&)\n  {\n    std::cout << \"No worries: I've caught it!\" << std::endl;\n  }\n}\n\nstd::unique_ptr<double[]> computeValues(size_t howMany)\n{\n  auto values{ std::make_unique<double[]>(howMany) };\n  for (size_t i{}; i < howMany; ++i)\n    values[i] = computeValue(i);\n  return values;\n}\n\ndouble computeValue(size_t x)\n{\n  if (x < 100)\n    return std::sqrt(x);   // Return the square root of the input argument\n  else\n    throw Trouble{ \"The trouble with trouble is, it starts out as fun!\" };\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_07C/Troubles.h",
    "content": "// MyTroubles.h Exception classes\n#ifndef MYTROUBLES_H\n#define MYTROUBLES_H\n#include <string>\n#include <string_view>\n\nclass Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nclass MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nclass BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_07D/Ex16_07D.cpp",
    "content": "// Avoid resource leaks due to exceptions using std::unique_ptr<>\n// Note: this example is given but not named in the text.\n// Instead of a custom RAII class DoubleArrayRAII, it uses std::vector<>.\n// Unlike the former, the latter can of course be returned from computeValues() as well.\n#include <iostream>\n#include <vector>\n#include <cmath>                    // For std::sqrt()\n#include \"Troubles.h\"\n\ndouble computeValue(size_t x);      // A function to compute a single value\nstd::vector<double> computeValues(size_t howMany); // A function to compute an array of values\n\nint main()\n{\n  try\n  {\n    auto values{ computeValues(10'000) }; // Cannot leak either: resource is managed by RAII object!\n  }\n  catch (const Trouble&)\n  {\n    std::cout << \"No worries: I've caught it!\" << std::endl;\n  }\n}\n\nstd::vector<double> computeValues(size_t howMany)\n{\n  std::vector<double> values;\n  for (size_t i{}; i < howMany; ++i)\n    values.push_back(computeValue(i));\n  return values;\n}\n\ndouble computeValue(size_t x)\n{\n  if (x < 100)\n    return std::sqrt(x);   // Return the square root of the input argument\n  else\n    throw Trouble{ \"The trouble with trouble is, it starts out as fun!\" };\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_07D/Troubles.h",
    "content": "// MyTroubles.h Exception classes\n#ifndef MYTROUBLES_H\n#define MYTROUBLES_H\n#include <string>\n#include <string_view>\n\nclass Trouble\n{\npublic:\n  explicit Trouble(std::string_view message = \"There's a problem\")\n    : m_message {message} \n  {}\n  virtual ~Trouble() = default;   // Base classes must have a virtual destructor!\n\n  virtual std::string_view what() const { return m_message; }\nprivate:\n  std::string m_message;\n};\n\n// Derived exception class\nclass MoreTrouble : public Trouble\n{\npublic:\n  explicit MoreTrouble(std::string_view str = \"There's more trouble...\") \n    : Trouble {str} \n  {}\n};\n\n// Derived exception class\nclass BigTrouble : public MoreTrouble\n{\npublic:\n  explicit BigTrouble(std::string_view str = \"Really big trouble...\") \n    : MoreTrouble {str} \n  {}\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_09/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n#include <algorithm>                        // For std::min() function template\n#include \"DimensionError.h\"\n\nclass Box\n{\npublic:\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h }\n  {\n    if (l <= 0.0 || w <= 0.0 || h <= 0.0)\n      throw DimensionError{ std::min({l, w, h}) };\n  }\n\n  double volume() const { return m_length * m_width * m_height; }\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_09/DimensionError.h",
    "content": "#ifndef DIMENSION_ERROR_H\n#define DIMENSION_ERROR_H\n\n#include <stdexcept>        // For derived exception classes such as std::out_of_range\n#include <string>           // For std::to_string() and the std::string type\n\nclass DimensionError : public std::out_of_range\n{\npublic:\n  explicit DimensionError(double value)\n    : std::out_of_range{ \"Zero or negative dimension: \" + std::to_string(value) }\n    , m_value{ value } {}\n\n  // Function to obtain the invalid dimension value\n  double getValue() const noexcept { return m_value; }\nprivate:\n  double m_value;\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 16/Ex16_09/Ex16_09.cpp",
    "content": "// Using an exception class\n#include <iostream>\n#include \"Box.h\"                  // For the Box class\n#include \"DimensionError.h\"       // For the dimension_error class\n\nint main()\n{\n  try\n  {\n    Box box1 {1.0, 2.0, 3.0};\n    std::cout << \"box1 volume is \" << box1.volume() << std::endl;\n    Box box2 {1.0, -2.0, 3.0};\n    std::cout << \"box2 volume is \" << box2.volume() << std::endl;\n  }\n  catch (const std::exception& ex)\n  {\n    std::cout << \"Exception caught in main(): \" << ex.what() << std::endl;\n  }\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_01/Array.h",
    "content": "// This solution uses the const-and-back-again idiom to avoid code duplication\n// between the non-const and const overloads of the array subscript operators.\n// It does not yet use the copy-and-swap idiom for the copy assignment operator \n// template, though: see Ex17_01A.\n#ifndef ARRAY_H\n#define ARRAY_H\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Copy assignment operator template (not exception safe)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  if (&rhs != this)               // If lhs != rhs...\n  {                               // ...do the assignment...\n    delete[] m_elements;          // Release any free store memory\n\n    m_size = rhs.m_size;          // Copy the members of rhs into lhs\n    m_elements = new T[m_size];\n    for (size_t i {}; i < m_size; ++i)\n      m_elements[i] = rhs.m_elements[i];\n  }\n  return *this;                   // ... return lhs\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_01/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {};\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\nprivate:\n  double m_length, m_width, m_height;\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_01/Ex17_01.cpp",
    "content": "// Using a class template\n#include \"Box.h\"\n#include \"Array.h\"\n#include <iostream>\n#include <format>\n\nint main()\n{\n  try\n  {\n    const size_t numValues {20};\n    Array<double> values {numValues};\n\n    for (unsigned i {}; i < numValues; ++i)\n      values[i] = i + 1;\n\n    std::cout << \"Sums of pairs of elements:\";\n    size_t lines {};\n    for (size_t i {numValues - 1}; i >= 0; --i)\n    {\n      std::cout << (lines++ % 5 == 0 ? \"\\n\" : \"\")\n                << std::format(\"{:5g}\", values[i] + values[i-1]);\n    }\n  }\n  catch (const std::out_of_range& ex)\n  {\n    std::cerr << \"\\nout_of_range exception object caught! \" << ex.what() << std::endl;\n  }\n\n  try\n  {\n    const size_t numBoxes {5};\n    Array<Box> boxes {numBoxes};\n    for (size_t i {} ; i <= numBoxes ; ++i)\n      std::cout << \"Box volume is \" << boxes[i].volume() << std::endl;\n  }\n  catch (const std::out_of_range& ex)\n  {\n    std::cerr << \"\\nout_of_range exception object caught! \" << ex.what() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_01A/Array.h",
    "content": "// This solution uses \n//  1) the const-and-back-again idiom to avoid code duplication\n//     between the non-const and const overloads of the array subscript operators.\n//  2) the copy-and-swap idiom for a thread-safe copy assignment operator \n#ifndef ARRAY_H\n#define ARRAY_H\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_01A/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {};\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\nprivate:\n  double m_length, m_width, m_height;\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_01A/Ex17_01A.cpp",
    "content": "// Using a class template\n#include \"Box.h\"\n#include \"Array.h\"\n#include <iostream>\n#include <format>\n\nint main()\n{\n  try\n  {\n    const size_t numValues {20};\n    Array<double> values {numValues};\n\n    for (unsigned i {}; i < numValues; ++i)\n      values[i] = i + 1;\n\n    std::cout << \"Sums of pairs of elements:\";\n    size_t lines {};\n    for (size_t i {numValues - 1}; i >= 0; --i)\n    {\n      std::cout << (lines++ % 5 == 0 ? \"\\n\" : \"\")\n                << std::format(\"{:5g}\", values[i] + values[i-1]);\n    }\n  }\n  catch (const std::out_of_range& ex)\n  {\n    std::cerr << \"\\nout_of_range exception object caught! \" << ex.what() << std::endl;\n  }\n\n  try\n  {\n    const size_t numBoxes {5};\n    Array<Box> boxes {numBoxes};\n    for (size_t i {} ; i <= numBoxes ; ++i)\n      std::cout << \"Box volume is \" << boxes[i].volume() << std::endl;\n  }\n  catch (const std::out_of_range& ex)\n  {\n    std::cerr << \"\\nout_of_range exception object caught! \" << ex.what() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_02/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For to_string()\n#include <utility>                          // For std::as_const()\n\ntemplate <typename T, int startIndex>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor  \n  Array& operator=(const Array& rhs);       // Assignment operator\n  void swap(Array& other) noexcept;         // noexcept swap() function\n  T& operator[](int index);                 // Subscript operator\n  const T& operator[](int index) const;     // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for size\n\nprivate:\n  T* m_elements;   // Array of type T\n  size_t m_size;   // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T, int startIndex>\nArray<T, startIndex>::Array(size_t size) : m_elements{ new T[size] {} }, m_size{ size }\n{}\n\n// Copy constructor template\ntemplate <typename T, int startIndex>\nArray<T, startIndex>::Array(const Array& array) : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T, int startIndex>\nArray<T, startIndex>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T, int startIndex>\nconst T& Array<T, startIndex>::operator[](int index) const\n{\n  if (index < startIndex)\n    throw std::out_of_range{ \"Index too small: \" + std::to_string(index) };\n\n  if (index > startIndex + static_cast<int>(m_size) - 1)\n    throw std::out_of_range{ \"Index too large: \" + std::to_string(index) };\n\n  return m_elements[index - startIndex];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T, int startIndex>\nT& Array<T, startIndex>::operator[](int index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T, int startIndex>\nArray<T, startIndex>& Array<T, startIndex>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Swap member function template\ntemplate <typename T, int startIndex>\nvoid Array<T, startIndex>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (can only swap arrays with identical startIndex)\ntemplate <typename T, int startIndex>\nvoid swap(Array<T, startIndex>& one, Array<T, startIndex>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_02/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {};\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\nprivate:\n  double m_length, m_width, m_height;\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_02/Ex17_02.cpp",
    "content": "// Using a class template with a non-type parameter\n#include \"Box.h\"\n#include \"Array.h\"\n#include <iostream>\n#include <format>\n#include <typeinfo>         // For use of typeid()\n\nint main()\n{\n  try\n  {\n    try\n    {\n      const size_t size {21};                              // Number of array elements\n      const int start {-10};                               // Index for first element\n      const int end {start + static_cast<int>(size) - 1};  // Index for last element\n\n      Array<double, start> values {size};                  // Define array of double values\n\n      for (int i {start}; i <= end; ++i)                   // Initialize the elements\n        values[i] = i - start + 1;\n\n      std::cout << \"Sums of pairs of elements: \";\n      size_t lines {};\n      for (int i {end}; i >= start; --i)\n      {\n        std::cout << (lines++ % 5 == 0 ? \"\\n\" : \"\")\n                  << std::format(\"{:5g}\", values[i] + values[i-1]);\n      }\n    }\n    catch (const std::out_of_range& ex)\n    {\n      std::cerr << \"\\nout_of_range exception object caught! \" << ex.what() << std::endl;\n    }\n\n    // Create array of Box objects\n    const int numBoxes {9};\n    Array<Box, -numBoxes / 2> boxes { static_cast<size_t>(numBoxes) };    \n\n    for (int i { -numBoxes / 2 }; i <= numBoxes/2 + numBoxes%2; ++i)\n      std::cout << std::format(\"Volume of Box[{}] is {}\\n\", i, boxes[i].volume());\n  }\n  catch (const std::exception& ex)\n  {\n    std::cerr << typeid(ex).name() << \" exception caught in main()! \"\n      << ex.what() << std::endl;\n  }\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_02A/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For to_string()\n#include <utility>                          // For std::as_const()\n\ntemplate <typename T, int startIndex>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor  \n  Array& operator=(const Array& rhs);       // Assignment operator\n  void swap(Array& other) noexcept;         // noexcept swap() function\n  T& operator[](int index);                 // Subscript operator\n  const T& operator[](int index) const;     // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for size\n\nprivate:\n  T* m_elements;   // Array of type T\n  size_t m_size;   // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T, int startIndex>\nArray<T, startIndex>::Array(size_t size) : m_elements{ new T[size] {} }, m_size{ size }\n{}\n\n// Copy constructor template\ntemplate <typename T, int startIndex>\nArray<T, startIndex>::Array(const Array& array) : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T, int startIndex>\nArray<T, startIndex>::~Array() { delete[] m_elements; }\n\n// const subscript operator template (improved readability!)\ntemplate <typename T, int startIndex>\nconst T& Array<T, startIndex>::operator[](int index) const\n{\n  // Subtract startIndex to obtain the actual index into the m_elements array.\n  // If startIndex is 0, conventional 0-based array indexing is used.\n  const int actualIndex{ index - startIndex };\n\n  if (actualIndex < 0)\n    throw std::out_of_range {\"Index too small: \" + std::to_string(index)};\n\n  if (actualIndex >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n\n  return m_elements[actualIndex];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T, int startIndex>\nT& Array<T, startIndex>::operator[](int index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T, int startIndex>\nArray<T, startIndex>& Array<T, startIndex>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Swap member function template\ntemplate <typename T, int startIndex>\nvoid Array<T, startIndex>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (can only swap arrays with identical startIndex)\ntemplate <typename T, int startIndex>\nvoid swap(Array<T, startIndex>& one, Array<T, startIndex>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_02A/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {};\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\nprivate:\n  double m_length, m_width, m_height;\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_02A/Ex17_02A.cpp",
    "content": "// Using a class template with a non-type parameter\n// In this variant the code readability of the array subscript operator template\n// was improved (see Array<> source code).\n#include \"Box.h\"\n#include \"Array.h\"\n#include <iostream>\n#include <format>\n#include <typeinfo>         // For use of typeid()\n\nint main()\n{\n  try\n  {\n    try\n    {\n      const size_t size {21};                              // Number of array elements\n      const int start {-10};                               // Index for first element\n      const int end {start + static_cast<int>(size) - 1};  // Index for last element\n\n      Array<double, start> values {size};                  // Define array of double values\n\n      for (int i {start}; i <= end; ++i)                   // Initialize the elements\n        values[i] = i - start + 1;\n\n      std::cout << \"Sums of pairs of elements: \";\n      size_t lines {};\n      for (int i {end}; i >= start; --i)\n      {\n        std::cout << (lines++ % 5 == 0 ? \"\\n\" : \"\")\n                  << std::format(\"{:5g}\", values[i] + values[i-1]);\n      }\n    }\n    catch (const std::out_of_range& ex)\n    {\n      std::cerr << \"\\nout_of_range exception object caught! \" << ex.what() << std::endl;\n    }\n\n    // Create array of Box objects\n    const int numBoxes {9};\n    Array<Box, -numBoxes / 2> boxes { static_cast<size_t>(numBoxes) };    \n\n    for (int i { -numBoxes / 2 }; i <= numBoxes/2 + numBoxes%2; ++i)\n      std::cout << std::format(\"Volume of Box[{}] is {}\\n\", i, boxes[i].volume());\n  }\n  catch (const std::exception& ex)\n  {\n    std::cerr << typeid(ex).name() << \" exception caught in main()! \"\n      << ex.what() << std::endl;\n  }\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_03/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n#include <initializer_list>                 // For the std::initializer_list<> template\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(std::initializer_list<T> elements); // Initializer list constructor\n  Array(const Array& array);                // Copy constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Initializer list constructor template\ntemplate <typename T>\nArray<T>::Array(std::initializer_list<T> elements)\n  : m_elements{ new T[elements.size()] }, m_size{ elements.size() }\n{\n  // std::initializer_list<> has no operator[], but can be used in range-based for loop.\n  // The possibility to add variable initializations such as \"size_t i {};\" \n  // to a range-based for loop is new in C++20.\n  for (size_t i{}; const T & element : elements)\n    m_elements[i++] = element;\n}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_03/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box() : Box{ 1.0, 1.0, 1.0 } {};\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\nprivate:\n  double m_length, m_width, m_height;\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_03/Ex17_03.cpp",
    "content": "// Illustrating Class Template Argument Deduction (CTAD) \n// by adding an initializer list constructor to our Array<> template.\n#include \"Box.h\"\n#include \"Array.h\"\n#include <iostream>\n\nint main()\n{\n  // Class Template Argument Deduction (CTAD) in action:\n  Array integers{ 1, 2, 3, 4, 5 };           // Deduced type: Array<int>\n  Array doubles{ 1.0, 2.0, 3.0, 4.0, 5.0 };  // Deduced type: Array<double\n\n  // But... caution!\n  {\n    const size_t numValues{ 50 };\n    Array<double> values{ numValues };  // Now uses the initializer list constructor!\n\n    std::cout << \"Wrong constructor used, so \" << values.getSize() << \" != \" << numValues << std::endl;\n    std::cout << \"Single value contained in Array<> is \" << values[0] << std::endl;\n  }\n\n  // Workaround: do not use uniform initialization (or \"near uniform\", as is thus more appropriate...)\n  { \n    const size_t numValues{ 50 };\n    Array<double> values(numValues);    // Uses Array(size_t) constructor as before\n\n    std::cout << \"Intended constructor used, so \" << values.getSize() << \" == \" << numValues << std::endl;\n    std::cout << \"All values are equal to \" << values[numValues / 2] << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_04/Ex17_04.cpp",
    "content": "// Using a stack defined by nested class templates\n#include \"Stack.h\"\n#include <iostream>\n#include <string>\n\nint main()\n{\n  std::string words[]{ \"The\", \"quick\", \"brown\", \"fox\", \"jumps\" };\n  Stack<std::string> wordStack;              // A stack of strings\n\n  for (const auto& word : words)\n    wordStack.push(word);\n\n  Stack<std::string> newStack{ wordStack };  // Create a copy of the stack\n\n  // Display the words in reverse order\n  while (!newStack.isEmpty())\n    std::cout << newStack.pop() << ' ';\n  std::cout << std::endl;\n\n  // Reverse wordStack onto newStack\n  while (!wordStack.isEmpty())\n    newStack.push(wordStack.pop());\n\n  // Display the words in original order\n  while (!newStack.isEmpty())\n    std::cout << newStack.pop() << ' ';\n  std::cout << std::endl;\n\n  std::cout << std::endl << \"Enter a line of text:\" << std::endl;\n  std::string text;\n  std::getline(std::cin, text);    // Read a line into the string object\n\n  Stack<const char> characters;    // A stack for characters\n\n  for (size_t i{}; i < text.length(); ++i)\n    characters.push(text[i]);      // Push the string characters onto the stack\n\n  std::cout << std::endl;\n  while (!characters.isEmpty())\n    std::cout << characters.pop(); // Pop the characters off the stack\n\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_04/Stack.h",
    "content": "// Stack.h Templates to define stacks\n#ifndef STACK_H\n#define STACK_H\n#include <stdexcept>\n\ntemplate <typename T>\nclass Stack\n{\npublic:\n  Stack() = default;                  // Default constructor\n  ~Stack();                           // Destructor\n\n  Stack(const Stack & stack);          // Copy constructor\n  Stack& operator=(const Stack & rhs); // Copy assignment operator\n  void swap(Stack & other) noexcept;   // noexcept swap() function\n\n  void push(const T & item);           // Push an object onto the stack\n  T pop();                            // Pop an object off the stack\n  bool isEmpty() const;               // Empty test\n\nprivate:\n  // Nested class\n  class Node\n  {\n  public:\n    Node(const T& item) : m_item{ item } {} // Create a node from an object\n\n    T m_item;          // The object stored in this node\n    Node* m_next{};   // Pointer to next node\n  };\n\n  Node* m_head{};     // Points to the top of the stack\n};\n\n// Copy constructor\ntemplate <typename T>\nStack<T>::Stack(const Stack& stack)\n{\n  if (stack.m_head)\n  {\n    m_head = new Node {*stack.m_head}; // Copy the top node of the original\n    Node* oldNode {stack.m_head};      // Points to the top node of the original\n    Node* newNode {m_head};            // Points to the node in the new stack\n\n    while (oldNode = oldNode->m_next)  // If m_next was nullptr, the last node was copied\n    {     \n      newNode->m_next = new Node{*oldNode}; // Duplicate it\n      newNode = newNode->m_next;            // Move to the node just created\n    }\n  }\n}\n\n// Destructor\ntemplate <typename T>\nStack<T>::~Stack()\n{\n  while (m_head)\n  {                               // While current pointer is not null\n    auto* next{ m_head->m_next }; // Get the pointer to the next node\n    delete m_head;                // Delete the current head\n    m_head = next;                // Make m_head point to the next node\n  }\n}\n\n// Copy assignment operator\ntemplate <typename T>\nStack<T>& Stack<T>::operator=(const Stack& rhs)\n{\n  auto copy{ rhs }; // Copy...        (could go wrong and throw an exception)\n  swap(copy);       // ... and swap!  (noexcept)\n  return *this;\n}\n\n// Push an object onto the stack\ntemplate <typename T>\nvoid Stack<T>::push(const T& item)\n{\n  Node* node{ new Node{item} }; // Create the new node\n  node->m_next = m_head;  // Point to the old top node\n  m_head = node;          // Make the new node the top\n}\n\n// Pop an object off the stack\ntemplate <typename T>\nT Stack<T>::pop()\n{\n  if (isEmpty())     // If it's empty pop() is not valid so throw exception\n    throw std::logic_error {\"Stack empty\"}; \n\n  auto* next {m_head->m_next}; // Save pointer to the next node\n  T item {m_head->m_item};     // Save the T value to return later\n  delete m_head;               // Delete the current head\n  m_head = next;               // Make head point to the next node\n  return item;                 // Return the top object\n}\n\ntemplate <typename T>\nbool Stack<T>::isEmpty() const { return m_head == nullptr; }\n\n// noexcept swap member function\ntemplate <typename T>\nvoid Stack<T>::swap(Stack& other) noexcept\n{\n  std::swap(m_head, other.m_head);\n}\n\n// Conventional noexcept swap non-member function\ntemplate <typename T>\nvoid swap(Stack<T>& one, Stack<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_04A/Ex17_04A.cpp",
    "content": "// Using a stack defined by nested class templates\n// (with improvement suggested in the \"A Better Stack\" section: see Stack<> source)\n#include \"Stack.h\"\n#include <iostream>\n#include <string>\n\nint main()\n{\n  std::string words[]{ \"The\", \"quick\", \"brown\", \"fox\", \"jumps\" };\n  Stack<std::string> wordStack;              // A stack of strings\n\n  for (const auto& word : words)\n    wordStack.push(word);\n\n  Stack<std::string> newStack{ wordStack };  // Create a copy of the stack\n\n  // Display the words in reverse order\n  while (!newStack.isEmpty())\n    std::cout << newStack.pop() << ' ';\n  std::cout << std::endl;\n\n  // Reverse wordStack onto newStack\n  while (!wordStack.isEmpty())\n    newStack.push(wordStack.pop());\n\n  // Display the words in original order\n  while (!newStack.isEmpty())\n    std::cout << newStack.pop() << ' ';\n  std::cout << std::endl;\n\n  std::cout << std::endl << \"Enter a line of text:\" << std::endl;\n  std::string text;\n  std::getline(std::cin, text);    // Read a line into the string object\n\n  Stack<const char> characters;    // A stack for characters\n\n  for (size_t i{}; i < text.length(); ++i)\n    characters.push(text[i]);      // Push the string characters onto the stack\n\n  std::cout << std::endl;\n  while (!characters.isEmpty())\n    std::cout << characters.pop(); // Pop the characters off the stack\n\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_04A/Stack.h",
    "content": "// Stack.h Templates to define stacks \n// (with improvement suggested in the \"A Better Stack\" section)\n#ifndef STACK_H\n#define STACK_H\n#include <stdexcept>\n\ntemplate <typename T>\nclass Stack\n{\npublic:\n  Stack() = default;                  // Default constructor\n  ~Stack();                           // Destructor\n\n  Stack(const Stack & stack);          // Copy constructor\n  Stack& operator=(const Stack & rhs); // Copy assignment operator\n  void swap(Stack & other) noexcept;   // noexcept swap() function\n\n  void push(const T & item);           // Push an object onto the stack\n  T pop();                            // Pop an object off the stack\n  bool isEmpty() const;               // Empty test\n\nprivate:\n  // Nested class\n  class Node\n  {\n  public:\n    Node(const T& item) : m_item{ item } {} // Create a node from an object\n\n    T m_item;          // The object stored in this node\n    Node* m_next{};   // Pointer to next node\n  };\n\n  Node* m_head{};     // Points to the top of the stack\n};\n\n// Copy constructor\ntemplate <typename T>\nStack<T>::Stack(const Stack& stack)\n{\n  if (stack.m_head)\n  {\n    m_head = new Node {*stack.m_head}; // Copy the top node of the original\n    Node* oldNode {stack.m_head};      // Points to the top node of the original\n    Node* newNode {m_head};            // Points to the node in the new stack\n\n    while (oldNode = oldNode->m_next)  // If m_next was nullptr, the last node was copied\n    {     \n      newNode->m_next = new Node{*oldNode}; // Duplicate it\n      newNode = newNode->m_next;            // Move to the node just created\n    }\n  }\n}\n\n// Destructor\ntemplate <typename T>\nStack<T>::~Stack()\n{\n  while (!isEmpty()) pop();\n}\n\n// Copy assignment operator\ntemplate <typename T>\nStack<T>& Stack<T>::operator=(const Stack& rhs)\n{\n  auto copy{ rhs }; // Copy...        (could go wrong and throw an exception)\n  swap(copy);       // ... and swap!  (noexcept)\n  return *this;\n}\n\n// Push an object onto the stack\ntemplate <typename T>\nvoid Stack<T>::push(const T& item)\n{\n  Node* node{ new Node{item} }; // Create the new node\n  node->m_next = m_head;  // Point to the old top node\n  m_head = node;          // Make the new node the top\n}\n\n// Pop an object off the stack\ntemplate <typename T>\nT Stack<T>::pop()\n{\n  if (isEmpty())     // If it's empty pop() is not valid so throw exception\n    throw std::logic_error {\"Stack empty\"}; \n\n  auto* next {m_head->m_next}; // Save pointer to the next node\n  T item {m_head->m_item};     // Save the T value to return later\n  delete m_head;               // Delete the current head\n  m_head = next;               // Make head point to the next node\n  return item;                 // Return the top object\n}\n\ntemplate <typename T>\nbool Stack<T>::isEmpty() const { return m_head == nullptr; }\n\n// noexcept swap member function\ntemplate <typename T>\nvoid Stack<T>::swap(Stack& other) noexcept\n{\n  std::swap(m_head, other.m_head);\n}\n\n// Conventional noexcept swap non-member function\ntemplate <typename T>\nvoid swap(Stack<T>& one, Stack<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_04B/Ex17_04B.cpp",
    "content": "// Using a stack defined by nested class templates\n// (using std::unique_ptr<>: see Stack<> source)\n// Note: this is a bonus example that is only hinted at in the text (and not explicitly named). \n// It requires the use of std::move(), seen only in Chapter 18.\n#include \"Stack.h\"\n#include <iostream>\n#include <string>\n\nint main()\n{\n  std::string words[]{ \"The\", \"quick\", \"brown\", \"fox\", \"jumps\" };\n  Stack<std::string> wordStack;              // A stack of strings\n\n  for (const auto& word : words)\n    wordStack.push(word);\n\n  Stack<std::string> newStack{ wordStack };  // Create a copy of the stack\n\n  // Display the words in reverse order\n  while (!newStack.isEmpty())\n    std::cout << newStack.pop() << ' ';\n  std::cout << std::endl;\n\n  // Reverse wordStack onto newStack\n  while (!wordStack.isEmpty())\n    newStack.push(wordStack.pop());\n\n  // Display the words in original order\n  while (!newStack.isEmpty())\n    std::cout << newStack.pop() << ' ';\n  std::cout << std::endl;\n\n  std::cout << std::endl << \"Enter a line of text:\" << std::endl;\n  std::string text;\n  std::getline(std::cin, text);    // Read a line into the string object\n\n  Stack<const char> characters;    // A stack for characters\n\n  for (size_t i{}; i < text.length(); ++i)\n    characters.push(text[i]);      // Push the string characters onto the stack\n\n  std::cout << std::endl;\n  while (!characters.isEmpty())\n    std::cout << characters.pop(); // Pop the characters off the stack\n\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_04B/Stack.h",
    "content": "// Stack.h Templates to define stacks \n// (using std::unique_ptr<> instead of raw pointer)\n#ifndef STACK_H\n#define STACK_H\n#include <stdexcept>\n#include <memory>       // For std::unique_ptr<>\n\n/*\n    The required changes are minimal, \n    but they do require std::move() which we only cover in Chapter 18.\n\n    Other changes include:\n      - no need for the destructor anymore (all memory is managed by smart pointers)\n      - Nodes can no longer be copied, \n        so you need to construct all Nodes with the Node(const T&) constructor\n */\n\ntemplate <typename T>\nclass Stack\n{\npublic:\n  Stack() = default;                  // Default constructor\n\n  Stack(const Stack & stack);          // Copy constructor\n  Stack& operator=(const Stack & rhs); // Copy assignment operator\n  void swap(Stack & other) noexcept;   // noexcept swap() function\n\n  void push(const T & item);           // Push an object onto the stack\n  T pop();                            // Pop an object off the stack\n  bool isEmpty() const;               // Empty test\n\nprivate:\n  // Nested class\n  class Node\n  {\n  public:\n    Node(const T& item) : m_item{ item } {} // Create a node from an object\n\n    T m_item;          // The object stored in this node\n    std::unique_ptr<Node> m_next{};   // Pointer to next node\n  };\n\n  std::unique_ptr<Node> m_head;     // Points to the top of the stack\n};\n\n// Copy constructor\ntemplate <typename T>\nStack<T>::Stack(const Stack& stack)\n{\n  if (stack.m_head)\n  {\n    m_head = std::make_unique<Node>(stack.m_head->m_item); // Copy the top node of the original\n    Node* oldNode {stack.m_head.get()}; // Points to the top node of the original\n    Node* newNode {m_head.get()};       // Points to the node in the new stack\n\n    while (oldNode = oldNode->m_next.get()) // If m_next was nullptr, the last node was copied\n    {     \n      newNode->m_next = std::make_unique<Node>(oldNode->m_item); // Duplicate it\n      newNode = newNode->m_next.get();      // Move to the node just created\n    }\n  }\n}\n\n// Copy assignment operator\ntemplate <typename T>\nStack<T>& Stack<T>::operator=(const Stack& rhs)\n{\n  auto copy{ rhs }; // Copy...        (could go wrong and throw an exception)\n  swap(copy);       // ... and swap!  (noexcept)\n  return *this;\n}\n\n// Push an object onto the stack\ntemplate <typename T>\nvoid Stack<T>::push(const T& item)\n{\n  // See Chapter 18 for std::move()\n  auto node{ std::make_unique<Node>(item) }; // Create the new node\n  node->m_next = std::move(m_head);   // Point to the old top node\n  m_head = std::move(node);           // Make the new node the top\n}\n\n// Pop an object off the stack\ntemplate <typename T>\nT Stack<T>::pop()\n{\n  if (isEmpty())     // If it's empty pop() is not valid so throw exception\n    throw std::logic_error {\"Stack empty\"}; \n\n  // See Chapter 18 for std::move()\n  auto next {std::move(m_head->m_next)}; // Save pointer to the next node\n  T item {m_head->m_item};     // Save the T value to return later\n  m_head.reset();              // Delete the current head\n  m_head = std::move(next);    // Make head point to the next node\n  return item;                 // Return the top object\n}\n\ntemplate <typename T>\nbool Stack<T>::isEmpty() const { return m_head == nullptr; }\n\n// noexcept swap member function\ntemplate <typename T>\nvoid Stack<T>::swap(Stack& other) noexcept\n{\n  std::swap(m_head, other.m_head);\n}\n\n// Conventional noexcept swap non-member function\ntemplate <typename T>\nvoid swap(Stack<T>& one, Stack<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_05/Ex17_05A.cpp",
    "content": "// Disambiguating dependant names: this code will not compile. \n\ntemplate <typename T>\nclass Outer\n{\npublic:\n  class Nested { /* ... */ };  // Or a type alias of form 'using Nested = ...;'\n  // ...\n};\n\n// Uncomment the typename keyword to turn Outer<T>::Nested into \n// a dependent type name and fix the compilation\ntemplate <typename T>\nvoid someFunction() { /*typename*/ Outer<T>::Nested* nested; /* ... */ }\n"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_05/Ex17_05B.cpp",
    "content": "// Disambiguating dependant names\n// Note: not all compilers may implement the C++20 rules already,\n// any may still require additional typename keywords in front of T::Derived\n\ntemplate <typename T>\nclass Outer\n{\npublic:\n  class Nested { /* ... */ };  // Or a type alias of form 'using Nested = ...;'\n  // ...\n};\n\ntemplate <typename T>   // T assumed to define nested Base and Derived types / aliases\nvoid someOtherFunction()\n{\n  typename T::Base* b{ new T::Derived{} };                      // Or: auto* b{ ... }\n  const typename T::Derived& d{ static_cast<T::Derived&>(*b) }; // Or: const auto& d{ ... }\n  /* ... */\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_05/Ex17_05C.cpp",
    "content": "// Disambiguating dependant names\n\n// Note: not all compilers may implement the C++20 rules already,\n// any may still require additional typename keywords in front of Outer<T>::Nested\n\ntemplate <typename T>\nclass Outer\n{\npublic:\n  class Nested { /* ... */ };  // Or a type alias of form 'using Nested = ...;'\n  // ...\n};\n\ntemplate <typename T>\nclass MyClass\n{\npublic:\n  Outer<T>::Nested memberFunction(const Outer<T>::Nested& nested);\nprivate:\n  T::Nested m_member_variable;\n};\n\ntemplate<class T>\nT::Nested nonMemberFunction(const typename T::Nested* nested);\n\ntemplate<typename T>\nOuter<T>::Nested MyClass<T>::memberFunction(const typename Outer<T>::Nested& nested)\n{\n  return nested;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 17/Ex17_06/Ex17_06.cpp",
    "content": "// Disambiguating dependant base class names\n// (this code does not compile without changes)\n\n#include <iostream>\n\ntemplate <typename T>\nclass Base\n{\npublic:\n  void baseFun() { /* ... */ }\nprotected:\n  int m_base_var {};\n};\n\ntemplate <typename T>\nclass Derived : public Base<T>\n{\npublic:\n  void derivedFun();\n\n  // Option 3: using declarations (remove to see error messages)\n// using Base<T>::baseFun;\n// using Base<T>::m_base_var;\n};\n\ntemplate <typename T>\nvoid Derived<T>::derivedFun()\n{\n  // These two lines should give compiler errors.\n  // Uncomment the using declarations in the Derived<> template \n  // to make them work. Alternative solutions are illustrated below.\n  baseFun();\n  std::cout << m_base_var << std::endl;\n\n  // Option 1: add this->\n  this->baseFun();\n  std::cout << this->m_base_var << std::endl;\n\n  // Option 2: add Base<T>::\n  Base<T>::baseFun();\n  std::cout << Base<T>::m_base_var << std::endl;\n}\n\nint main()\n{\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_01/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n#include <iostream>\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_01/Ex18_01.cpp",
    "content": "// Copying objects into a vector\n#include \"Array.h\"\n#include <string>\n#include <vector>\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  const size_t numArrays{ 10 };       // Fill 10 Arrays with 1,000 strings each\n  const size_t numStringsPerArray{ 1000 };\n\n  std::vector<Array<std::string>> vectorOfArrays;\n  vectorOfArrays.reserve(numArrays);  // Inform the vector<> how many Arrays we'll be adding\n\n  for (size_t i {}; i < numArrays; ++i)\n  {\n     vectorOfArrays.push_back(buildStringArray(numStringsPerArray));\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_02/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n#include <iostream>\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array);                     // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved)\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_02/Ex18_02.cpp",
    "content": "// Moving objects into a vector\n#include \"Array.h\"\n#include <string>\n#include <vector>\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  const size_t numArrays{ 10 };       // Fill 10 Arrays with 1,000 strings each\n  const size_t numStringsPerArray{ 1000 };\n\n  std::vector<Array<std::string>> vectorOfArrays;\n  vectorOfArrays.reserve(numArrays);  // Inform the vector<> how many Arrays we'll be adding\n\n  for (size_t i {}; i < numArrays; ++i)\n  {\n     vectorOfArrays.push_back(buildStringArray(numStringsPerArray));\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_03/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n#include <iostream>\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array);                     // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs);            // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved)\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs)\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_03/Ex18_03.cpp",
    "content": "// Defining and using a move assignment operator\n#include \"Array.h\"\n#include <string>\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  Array<std::string> strings { 123 };\n  strings = buildStringArray(1'000);           // Assign an rvalue to strings\n\n  Array<std::string> more_strings{ 2'000 };\n  strings = more_strings;                      // Assign an lvalue to strings\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_04/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n#include <iostream>\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array);                     // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs);            // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved)\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs)\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_04/Ex18_04.cpp",
    "content": "// Using std::move() to force the move assignment of a named variable\n#include \"Array.h\"\n#include <string>\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  Array<std::string> strings { 123 };\n  strings = buildStringArray(1'000);           // Assign an rvalue to strings\n\n  Array<std::string> more_strings{ 2'000 };\n  strings = std::move(more_strings);           // Move more_strings into strings\n\n  /* Caution: once moved, an object should not be used anymore! */\n// std::cout << more_strings[101] << std::endl; // ???\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_05A/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n// Compared to Ex18_04, this variant adds two overloads of push_back().\n// The Array<>() default constructor is new as well.\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n#include <iostream>\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  Array();                                  // Default constructor\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array);                     // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs);            // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n  void push_back(const T& element);         // Add copy of given element to the back of the array\n  void push_back(T&& element);              // Move element to the back of the array\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T>\nArray<T>::Array() : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved)\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs)\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n// push_back() overload for lvalue references\ntemplate <typename T>\nvoid Array<T>::push_back(const T& element)\n{\n  Array<T> newArray{m_size + 1};      // Allocate a larger Array<>\n  for (size_t i{}; i < m_size; ++i)   // Move all existing elements...\n    newArray[i] = std::move(m_elements[i]);\n\n  newArray[m_size] = element;         // Copy the new one...\n\n  swap(newArray);                     // ... and swap!\n}\n\n// push_back() overload for rvalue references\ntemplate <typename T>\nvoid Array<T>::push_back(T&& element)\n{\n  Array<T> newArray{m_size + 1};      // Allocate a larger Array<>\n  for (size_t i{}; i < m_size; ++i)   // Move all existing elements...\n    newArray[i] = std::move(m_elements[i]);\n\n  newArray[m_size] = std::move(element); // Move the new one...\n\n  swap(newArray);                        // ... and swap!\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_05A/Ex18_05A.cpp",
    "content": "// Exercising two overloads of push_back(): one for lvalue arguments, and one for rvalue arguments\n#include \"Array.h\"\n#include <string>\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  Array<Array<std::string>> array_of_arrays;\n\n  Array<std::string> array{ buildStringArray(1'000) };  \n  array_of_arrays.push_back(array);              // Push an lvalue\n\n  array.push_back(\"One more for good measure\");\n  std::cout << std::endl;\n\n  array_of_arrays.push_back(std::move(array));   // Push an rvalue\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_05B/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n// This variant merges the two overloads of push_back() of Ex18_05 into one single member.\n// The push_back() function accepts a new element by value.\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n#include <iostream>\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  Array();                                  // Default constructor\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array);                     // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs);            // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n  void push_back(T element);                // Copy or move element to the back of the array\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T>\nArray<T>::Array() : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved)\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs)\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n// push_back() overload for lvalue references\ntemplate <typename T>\nvoid Array<T>::push_back(T element)   // Pass by value (copy of lvalue, or moved rvalue!)\n{\n  Array<T> newArray{m_size + 1};      // Allocate a larger Array<>\n  for (size_t i{}; i < m_size; ++i)   // Move all existing elements...\n    newArray[i] = std::move(m_elements[i]);\n\n  newArray[m_size] = std::move(element); // Move the new one (could itself be a copy already)...\n\n  swap(newArray);                     // ... and swap!\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_05B/Ex18_05B.cpp",
    "content": "// Exercising a single overload of push_back() \n// that can be used to either to add a copy of, or move, a new value into an Array<>.\n// The caller decides whether the element is copied or moved.\n#include \"Array.h\"\n#include <string>\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  Array<Array<std::string>> array_of_arrays;\n\n  Array<std::string> array{ buildStringArray(1'000) };\n  array_of_arrays.push_back(array);              // Push an lvalue\n\n  array.push_back(\"One more for good measure\");\n  std::cout << std::endl;\n\n  array_of_arrays.push_back(std::move(array));   // Push an rvalue\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_06/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n// Compared to Ex18_05B, this variant adds noexcept specifiers to all move members \n// and implements a strongly exception safe push_back().\n// It uses some mild template meta programming in move_assign_if_noexcept() to accomplish the latter.\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n#include <iostream>\n#include <type_traits>\n\ntemplate<class T>\nstd::conditional_t<std::is_nothrow_move_assignable_v<T>, T&&, const T&>\nmove_assign_if_noexcept(T& x) noexcept\n{\n  return std::move(x);\n}\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  Array();                                  // Default constructor\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array) noexcept;                     // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs) noexcept;   // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n  void push_back(T element);                // Copy or move element to the back of the array\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T>\nArray<T>::Array() : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved) noexcept\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs) noexcept\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n// push_back() overload for lvalue references\ntemplate <typename T>\nvoid Array<T>::push_back(T element)  // Pass by value (copy of lvalue, or moved rvalue!)\n{\n  Array<T> newArray{m_size + 1};     // Allocate a larger Array<>\n  for (size_t i {}; i < m_size; ++i) // Move existing elements (copy if not noexcept)...\n    newArray[i] = move_assign_if_noexcept(m_elements[i]);\n\n  newArray[m_size] = move_assign_if_noexcept(element);  // Move (or copy) the new one...\n\n  swap(newArray);                   // ... and swap!\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_06/Ex18_06.cpp",
    "content": "// Exercising a single, exception safe overload of push_back() \n// Remove the noexcept specifiers from Array<> to observe\n// that copying is then used instead of moving\n// (moving would be unsafe if an exception occurs).\n#include \"Array.h\"\n#include <string>\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  Array<Array<std::string>> array_of_arrays;\n\n  Array<std::string> array{ buildStringArray(1'000) };\n  array_of_arrays.push_back(array);              // Push an lvalue\n\n  array.push_back(\"One more for good measure\");\n  std::cout << std::endl;\n\n  array_of_arrays.push_back(std::move(array));   // Push an rvalue\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_07/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n// Exact same as template as Ex18_05B (that is: without noexcept specifiers!)\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n#include <iostream>\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  Array();                                  // Default constructor\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array) /*noexcept*/;        // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs) /*noexcept*/; // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n  void push_back(T element);                // Copy or move element to the back of the array\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T>\nArray<T>::Array() : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved) /*noexcept*/\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs) /*noexcept*/\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n// push_back() overload for lvalue references\ntemplate <typename T>\nvoid Array<T>::push_back(T element)   // Pass by value (copy of lvalue, or moved rvalue!)\n{\n  Array<T> newArray{m_size + 1};      // Allocate a larger Array<>\n  for (size_t i{}; i < m_size; ++i)   // Move all existing elements...\n    newArray[i] = std::move(m_elements[i]);\n\n  newArray[m_size] = std::move(element); // Move the new one (could itself be a copy already)...\n\n  swap(newArray);                     // ... and swap!\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 18/Ex18_07/Ex18_07.cpp",
    "content": "// The effect of not adding noexcept to move members\n// Uncomment the noexcept specifiers in the Array<> template source \n// to avoid copying when a std::vector<> grows its dynamic array.\n#include \"Array.h\"\n#include <string>\n#include <vector>\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  std::vector<Array<std::string>> v;\n\n  v.push_back(buildStringArray(1'000));\n\n  std::cout << std::endl;\n\n  v.push_back(buildStringArray(2'000));\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_01/Ex19_01.cpp",
    "content": "// Exercising pointers to functions\n#include <iostream>\n\nlong sum(long a, long b);           // Function prototype\nlong product(long a, long b);       // Function prototype\n\nint main()\n{\n  long(*fun_ptr)(long, long) {};    // Pointer to function\n\n  fun_ptr = product;\n  std::cout << \"3 * 5 = \" << fun_ptr(3, 5) << std::endl; // Call product() thru fun_ptr\n\n  fun_ptr = sum;                    // Reassign pointer to sum()\n  std::cout << \"3 * (4+5) + 6 = \"   // Call sum() thru fun_ptr twice\n    << fun_ptr(product(3, fun_ptr(4, 5)), 6) << std::endl; \n}\n\n// Function to multiply two values\nlong product(long a, long b) { return a * b; }\n\n// Function to add two values\nlong sum(long a, long b) { return a + b; }\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_02/Ex19_02.cpp",
    "content": "// Exercising the use of function pointers as callback functions\n#include <iostream>\n#include <string>\n#include \"Optimum.h\"\n\n// Comparison function prototypes:\nbool less(const int&, const int&);\ntemplate <typename T> bool greater(const T&, const T&);\nbool longer(const std::string&, const std::string&);\n\nint main()\n{\n  std::vector<int> numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \" << *findOptimum(numbers, less) << std::endl;\n  std::cout << \"Maximum element: \" << *findOptimum(numbers, greater<int>) << std::endl;\n\n  std::vector<std::string> names{ \"Moe\", \"Larry\", \"Shemp\", \"Curly\", \"Joe\", \"Curly Joe\" };\n  std::cout << \"Alphabetically last name: \"\n            << *findOptimum(names, greater<std::string>) << std::endl;\n  std::cout << \"Longest name: \" << *findOptimum(names, longer) << std::endl;\n}\n\nbool less(const int& one, const int& other) { return one < other; }\n\ntemplate <typename T>\nbool greater(const T& one, const T& other) { return one > other; }\n\nbool longer(const std::string& one, const std::string& other)\n{\n  return one.length() > other.length();\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_02/Optimum.h",
    "content": "// Optimum.h - a function template to determine the optimum element in a given vector\n#ifndef OPTIMUM_H\n#define OPTIMUM_H\n\n#include <cstddef>\t// For std::size_t\t(required here by some compilers)\n#include <vector>\n\ntemplate <typename T>\nconst T* findOptimum(const std::vector<T>& values, bool (*compare)(const T&, const T&))\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_03/Ex19_03.cpp",
    "content": "// Exercising the use of a functor as callback functions\n#include <iostream>\n#include \"Optimum.h\"\n#include \"Less.h\"\n\ntemplate <typename T>\nbool greater(const T& one, const T& other) { return one > other; }\n\nint main()\n{\n  Less less;     // Create a 'less than' functor\n\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \" << *findOptimum(numbers, less) << std::endl;\n  std::cout << \"Maximum element: \" << *findOptimum(numbers, greater<int>) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_03/Less.h",
    "content": "// Less.h - A basic class of functor objects\n#ifndef LESS_H\n#define LESS_H\n\nclass Less\n{\npublic:\n  bool operator()(int a, int b) const { return a < b; }\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_03/Optimum.h",
    "content": "// Optimum.h - a function template to determine the optimum element in a given vector\n#ifndef OPTIMUM_H\n#define OPTIMUM_H\n\n#include <cstddef>\t// For std::size_t\t(required here by some compilers)\n#include <vector>\n\ntemplate <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_03A/Ex19_03A.cpp",
    "content": "// Exercising the use of standard functors\n#include <iostream>\n#include <functional>\n#include \"Optimum.h\"\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \" << *findOptimum(numbers, std::less<>{}) << std::endl;\n  std::cout << \"Maximum element: \" << *findOptimum(numbers, std::greater<>{}) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_03A/Optimum.h",
    "content": "// Optimum.h - a function template to determine the optimum element in a given vector\n#ifndef OPTIMUM_H\n#define OPTIMUM_H\n\n#include <cstddef>\t// For std::size_t\t(required here by some compilers)\n#include <vector>\n\ntemplate <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_04/Ex19_04.cpp",
    "content": "// Exercising a function object with a member variable\n#include <iostream>\n#include <format>\n#include \"Optimum.h\"\n#include \"Nearer.h\"\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n\n  int number_to_search_for {};\n  std::cout << \"Please enter a number: \";\n  std::cin >> number_to_search_for;\n\n  std::cout << std::format(\"The number nearest to {} is {}\", \n                  number_to_search_for, \n                  *findOptimum(numbers, Nearer{ number_to_search_for })) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_04/Nearer.h",
    "content": "// A class of function objects that compare two values based on how close they are \n// to some third value that was provided to the functor at construction time.\n#ifndef NEARER_H\n#define NEARER_H\n\n#include <cmath>   // For std::abs()\n\nclass Nearer\n{\npublic:\n  explicit Nearer(int value) : m_value{ value } {}\n  bool operator()(int x, int y) const\n  { \n    return std::abs(x - m_value) < std::abs(y - m_value); \n  }\nprivate:\n  int m_value;\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_04/Optimum.h",
    "content": "// Optimum.h - a function template to determine the optimum element in a given vector\n#ifndef OPTIMUM_H\n#define OPTIMUM_H\n\n#include <cstddef>\t// For std::size_t\t(required here by some compilers)\n#include <vector>\n\ntemplate <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_05/Ex19_05.cpp",
    "content": "// Exercising the use of stateless lambda expressions as callback functions\n#include <iostream>\n#include <string>\n#include <string_view>\n#include \"Optimum.h\"\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \"\n            << *findOptimum(numbers, [](int x, int y) { return x < y; }) << std::endl;\n  std::cout << \"Maximum element: \"\n            << *findOptimum(numbers, [](int x, int y) { return x > y; }) << std::endl;\n\n  // Define two anonymous comparison functions for strings:\n  auto alpha{ [](std::string_view x, std::string_view y) { return x > y; } };\n  auto longer{ [](std::string_view x, std::string_view y) { return x.length() > y.length(); } };\n\n  std::vector<std::string> names{ \"Moe\", \"Larry\", \"Shemp\", \"Curly\", \"Joe\", \"Curly Joe\" };\n  std::cout << \"Alphabetically last name: \" << *findOptimum(names, alpha) << std::endl;\n  std::cout << \"Longest name: \" << *findOptimum(names, longer) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_05/Optimum.h",
    "content": "// Optimum.h - a function template to determine the optimum element in a given vector\n#ifndef OPTIMUM_H\n#define OPTIMUM_H\n\n#include <cstddef>\t// For std::size_t\t(required here by some compilers)\n#include <vector>\n\ntemplate <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_05A/Ex19_05A.cpp",
    "content": "// If possible, using the standard functors instead of lambda expressions \n// often leads to more compact and elegant code.\n#include <iostream>\n#include <string>\n#include <string_view>\n#include <functional>\n#include \"Optimum.h\"\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \"\n            << *findOptimum(numbers, std::less<>{}) << std::endl;\n  std::cout << \"Maximum element: \"\n            << *findOptimum(numbers, std::greater<>{}) << std::endl;\n\n  // Define two anonymous comparison functions for strings:\n  auto alpha{ std::greater<>{} };\n  auto longer{ [](std::string_view x, std::string_view y) { return x.length() > y.length(); } };\n\n  std::vector<std::string> names{ \"Moe\", \"Larry\", \"Shemp\", \"Curly\", \"Joe\", \"Curly Joe\" };\n  std::cout << \"Alphabetically last name: \" << *findOptimum(names, alpha) << std::endl;\n  std::cout << \"Longest name: \" << *findOptimum(names, longer) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_05A/Optimum.h",
    "content": "// Optimum.h - a function template to determine the optimum element in a given vector\n#ifndef OPTIMUM_H\n#define OPTIMUM_H\n\n#include <cstddef>\t// For std::size_t\t(required here by some compilers)\n#include <vector>\n\ntemplate <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_06/Ex19_06.cpp",
    "content": "// Using a default capture-by-value clause to access a local variable \n// from within the body of a lambda expression.\n#include <iostream>\n#include \"Optimum.h\"\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n\n  int number_to_search_for {};\n  std::cout << \"Please enter a number: \";\n  std::cin >> number_to_search_for;\n\n  auto nearer { [=](int x, int y) {\n    return std::abs(x - number_to_search_for) < std::abs(y - number_to_search_for);\n  }};\n  std::cout << \"The number nearest to \" << number_to_search_for << \" is \"\n            << *findOptimum(numbers, nearer) << std::endl;\n\n  //unsigned count{};\n  //auto counter{ [&](int x, int y) { ++count; return x < y; } };\n  //findOptimum(numbers, counter);\n  //std::cout << \"Number of comparisons: \" << count;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_06/Optimum.h",
    "content": "// Optimum.h - a function template to determine the optimum element in a given vector\n#ifndef OPTIMUM_H\n#define OPTIMUM_H\n\n#include <cstddef>\t// For std::size_t\t(required here by some compilers)\n#include <vector>\n\ntemplate <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_07/Ex19_07.cpp",
    "content": "// Using a lambda expression from inside a member function (see Finder.cpp)\n#include <iostream>\n#include \"Optimum.h\"\n#include \"Finder.h\"\n\nint main()\n{\n  std::vector<double> numbers{ 91, 18, 92, 22, 13, 43 };\n\n  int number_to_search_for {};\n  std::cout << \"Please enter a number: \";\n  std::cin >> number_to_search_for;\n\n  Finder finder;\n  finder.setNumberToSearchFor(number_to_search_for);\n  std::cout << \"The number nearest to \" << finder.getNumberToSearchFor() << \" is \"\n            << *finder.findNearest(numbers) << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_07/Finder.cpp",
    "content": "// Exercising capturing the this pointer\n#include \"Finder.h\"\n#include \"Optimum.h\"\n#include <cmath>       // For std::abs()\n\nstd::optional<double> Finder::findNearest(const std::vector<double>& values) const\n{\n  if (values.empty())\n    return std::nullopt;\n  else  \n    return *findOptimum(values, [this](double x, double y) {\n      return std::abs(x - m_number_to_search_for) < std::abs(y - m_number_to_search_for);\n    });\n}\n\ndouble Finder::getNumberToSearchFor() const\n{\n  return m_number_to_search_for;\n}\n\nvoid Finder::setNumberToSearchFor(double value)\n{\n  m_number_to_search_for = value;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_07/Finder.h",
    "content": "// Finder.h - A small class to illustrate the use of lambda expression in member functions\n#ifndef FINDER_H\n#define FINDER_H\n\n#include <vector>\n#include <optional>\n\nclass Finder\n{\npublic:\n  double getNumberToSearchFor() const;\n  void setNumberToSearchFor(double n);\n\n  std::optional<double> findNearest(const std::vector<double>& values) const;\nprivate:\n  double m_number_to_search_for {};\n};\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_07/Optimum.h",
    "content": "// Optimum.h - a function template to determine the optimum element in a given vector\n#ifndef OPTIMUM_H\n#define OPTIMUM_H\n\n#include <cstddef>\t// For std::size_t\t(required here by some compilers)\n#include <vector>\n\ntemplate <typename T, typename Comparison>\nconst T* findOptimum(const std::vector<T>& values, Comparison compare)\n{\n  if (values.empty()) return nullptr;\n\n  const T* optimum{ &values[0] };\n  for (size_t i {1}; i < values.size(); ++i)\n  {\n    if (compare(values[i], *optimum))\n      optimum = &values[i];\n  }\n  return optimum;\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 19/Ex19_08/Ex19_08.cpp",
    "content": "// Using the std::function<> template\n#include <iostream>\n#include <functional>\n#include <cmath>            // for std::abs()\n\n// A global less() function\nbool less(int x, int y) { return x < y; }\n\nint main()\n{\n  int a{ 18 }, b{ 8 };  \n  std::cout << std::boolalpha; // Print true/false rather than 1/0\n\n  std::function<bool(int,int)> compare;\n\n  compare = less;              // Store a function pointer into compare\n  std::cout << a << \" < \" << b << \": \" << compare(a, b) << std::endl;\n\n  compare = std::greater<>{};  // Store a function object into compare\n  std::cout << a << \" > \" << b << \": \" << compare(a, b) << std::endl;\n\n  int n{ 10 };                 // Store a lambda closure into compare\n  compare = [n](int x, int y) { return std::abs(x - n) < std::abs(y - n); };\n  std::cout << a << \" nearer to \" << n << \" than \" << b << \": \" << compare(a, b);\n\n  // Check whether a function<> object is tied to an actual function\n  std::function<void(const int&)> empty;\n  if (empty)             // Or, equivalently: 'if (empty != nullptr)'\n  {\n    std::cout << \"Calling a default-constructed std::function<>?\" << std::endl;\n    empty(a);\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_01/Ex20_01.cpp",
    "content": "// Working with std::deque<>\n#include <iostream>\n#include <deque>\n\nint main()\n{\n  std::deque<int> my_deque;  // A deque<> allows efficient insertions \n  my_deque.push_back(2);     // to both ends of the sequence\n  my_deque.push_back(4);\n  my_deque.push_front(1);\n\n  my_deque[2] = 3;           // A deque<> is a random-access sequence container\n\n  std::cout << \"There are \" << my_deque.size() << \" elements in my_deque: \";\n\n  for (int element : my_deque) // A deque<>, like all containers, is a range\n    std::cout << element << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_02/Ex20_02.cpp",
    "content": "// Working with stacks and queues\n#include <iostream>\n#include <stack>\n#include <queue>\n\nint main()\n{\n  std::stack<int> stack;\n  for (int i {}; i < 10; ++i)\n    stack.push(i);\n\n  std::cout << \"The elements coming off the top of the stack:    \";\n  while (!stack.empty())\n  {\n    std::cout << stack.top() << ' ';\n    stack.pop();    // pop() is a void function!\n  }\n  std::cout << std::endl;\n\n  std::queue<int> queue;\n  for (int i {}; i < 10; ++i)\n    queue.push(i);\n\n  std::cout << \"The elements coming from the front of the queue: \";\n  while (!queue.empty())\n  {\n    std::cout << queue.front() << ' ';\n    queue.pop();    // pop() is a void function!\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_03/Ex20_03.cpp",
    "content": "// Working with sets\n#include <iostream>\n#include <set>            // For the std::set<> container template\n\nvoid printSet(const std::set<int>& my_set);  // Print the contents of a set to std::cout\n\nint main()\n{\n  std::set<int> my_set;\n\n  // Insert elements 1 through 4 in arbitrary order:\n  my_set.insert(1);\n  my_set.insert(4);\n  my_set.insert(3);\n  my_set.insert(3);  // Elements 3 and 1 are added twice\n  my_set.insert(1);\n  my_set.insert(2);\n\n  printSet(my_set);\n\n  std::cout << \"The element 1 occurs \" << my_set.count(1) << \" time(s)\" << std::endl;\n\n  my_set.erase(1);   // Remove the element 1 once\n  printSet(my_set);\n\n  my_set.clear();    // Remove all elements\n  printSet(my_set);\n}\n\nvoid printSet(const std::set<int>& my_set)\n{\n  std::cout << \"There are \" << my_set.size() << \" elements in my_set: \";\n  for (int element : my_set)       // A set, like all containers, is a range\n    std::cout << element << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_04/Ex20_04.cpp",
    "content": "// Basic use of std::map<>\n#include <map>\n#include <iostream>\n#include <string>\n\nint main()\n{\n  std::map<std::string, unsigned long long> phone_book;\n  phone_book[\"Donald\"] = 202'456'1111;\n  phone_book[\"Melania\"] = 202'456'1111;\n  phone_book[\"Francis\"] = 39'06'6982;\n  phone_book[\"Elizabeth\"] = 44'020'7930'4832;\n\n  std::cout << \"The pope's number is \" << phone_book[\"Francis\"] << std::endl;\n\n  for (const auto& [name, number] : phone_book)\n    std::cout << name << \" can be reached at \" << number << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_05/Ex20_05.cpp",
    "content": "// Working with maps\n#include <iostream>\n#include <format>\n#include <map>\n#include <string>\n#include <string_view>\n#include <vector>\n\n// Type aliases\nusing Words = std::vector<std::string_view>;\nusing WordCounts = std::map<std::string_view, size_t>;\n\n// Function prototypes\nWords extractWords(std::string_view text, std::string_view separators = \" ,.!?\\\"\\n\");\nWordCounts countWords(const Words& words);\nvoid showWordCounts(const WordCounts& wordCounts);\nsize_t maxWordLength(const WordCounts& wordCounts);\n\nint main()\n{\n  std::string text;    // The string to count words in\n\n  // Read a string from the keyboard\n  std::cout << \"Enter a string terminated by *:\" << std::endl;\n  getline(std::cin, text, '*');\n\n  const Words words{ extractWords(text) };\n  if (words.empty())\n  {\n    std::cout << \"No words in text.\" << std::endl;\n    return 0;\n  }\n\n  WordCounts wordCounts = countWords(words);\n  showWordCounts(wordCounts);\n}\n\nWords extractWords(std::string_view text, std::string_view separators)\n{\n  Words words;\n  size_t start{ text.find_first_not_of(separators) };    // Start 1st word\n  size_t end{};                                          // Index for the end of a word\n                                                         \n  while (start != std::string_view::npos)                \n  {                                                      \n    end = text.find_first_of(separators, start + 1);     // Find end separator\n    if (end == std::string_view::npos)                   // End of text?\n      end = text.length();                               // Yes, so set to last+1\n    words.push_back(text.substr(start, end - start));    \n    start = text.find_first_not_of(separators, end + 1); // Find next word\n  }\n\n  return words;\n}\n\nWordCounts countWords(const Words& words)\n{\n  WordCounts result;\n  for (auto& word : words)\n    ++result[word];\n  return result;\n}\n\nsize_t maxWordLength(const WordCounts& wordCounts)\n{\n  size_t max{};\n  for (const auto& [word, count] : wordCounts)\n    if (count >= 2 && max < word.length()) max = word.length();\n  return max;\n}\n\nvoid showWordCounts(const WordCounts& wordCounts)\n{\n  const size_t field_width{maxWordLength(wordCounts) + 1};\n  const size_t words_per_line{5};\n\n  size_t words_in_line{};      // Number of words in the current line\n  char previous_initial{};\n  for (const auto& [word, count] : wordCounts)\n  {\n    if (count < 2) continue;   // Skip words that appear only once\n\n    // Output newline when initial letter changes or after 5 per line\n    if ( (previous_initial && word[0] != previous_initial)\n          || words_in_line++ == words_per_line)\n    {\n      words_in_line = 0;\n      std::cout << std::endl;\n    }\n    // Output \"word (count)\", where word has a dynamic field width\n    std::cout << std::format(\"{:>{}} ({:2})\", word, field_width, count); \n    previous_initial = word[0];\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_06/Ex20_06.cpp",
    "content": "// Creating and working with Standard iterators\n#include <vector>\n#include <iostream>\n\nint main()\n{\n  std::vector<char> letters{ 'a', 'b', 'c', 'd', 'e' };\n  auto my_iter{ letters.begin() };\n\n  std::cout << *my_iter << std::endl;       // a\n\n  *my_iter = 'x';\n  std::cout << letters[0] << std::endl;     // x\n\n  ++my_iter;                                // Move my_iter to the next element\n  std::cout << *my_iter << std::endl;       // b\n\n  my_iter += 2;                             // Move my_iter two elements further\n  std::cout << *my_iter-- << std::endl;     // d\n  std::cout << *my_iter << std::endl;       // c (iterator altered using the post-decrement\n                                            //    operator in the previous statement)\n  auto copy{ my_iter };                     // Create a copy of my_iter (pointing at c)\n  my_iter += 2;                             // Move my_iter two elements further\n  std::cout << *copy << std::endl;          // c (copy not affected by moving my_iter)\n  std::cout << *my_iter << std::endl;       // e\n  std::cout << my_iter - copy << std::endl; // 2\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_07/Ex20_07.cpp",
    "content": "// Iterating over the elements of a list<>\n#include <iostream>\n#include <list>\n\nint main()\n{\n  std::cout << \"Enter a sequence of positive numbers, terminated by -1: \";\n\n  std::list<unsigned> numbers;\n\n  while (true)\n  {\n    signed number{ -1 };\n    std::cin >> number;\n    if (number == -1) break;\n    numbers.push_back(static_cast<unsigned>(number));\n  }\n\n  std::cout << \"You entered the following numbers: \";\n  for (auto iter{ numbers.begin() }; iter != numbers.end(); ++iter)\n  {\n    std::cout << *iter << ' ';\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_08/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n// Class to represent a box\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height)\n    : m_length{ length }, m_width{ width }, m_height{ height }\n  {}\n\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  void setLength(double length) { if (length > 0) m_length = length; }\n  void setWidth(double width)   { if (width > 0) m_width = width; }\n  void setHeight(double height) { if (height > 0) m_height = height; }\n\n  // Function to calculate the volume of a box\n  double volume() const { return m_length * m_width * m_height; }\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_08/Ex20_08.cpp",
    "content": "// Altering elements through a mutable iterator\n#include <iostream>\n#include <vector>\n#include \"Box.h\"      // From Ex11_04\n\nint main()\n{\n  std::vector boxes{ Box{ 1.0, 2.0, 3.0 } };  // A vector containing 1 Box\n\n  auto iter{ boxes.begin() };\n  std::cout << iter->volume() << std::endl;        // 6 == 1.0 * 2.0 * 3.0\n  \n  *iter = Box{ 2.0, 3.0, 4.0 };\n  std::cout << iter->volume() << std::endl;        // 24 == 2.0 * 3.0 * 4.0\n\n  iter->setHeight(7.0);\n  std::cout << iter->volume() << std::endl;        // 42 == 2.0 * 3.0 * 7.0\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_09/Ex20_09.cpp",
    "content": "// Inserting in and erasing from sequence containers\n#include <iostream>\n#include <vector>\n\nvoid printVector(const std::vector<int>& v);\n\nint main()\n{\n  std::vector numbers{ 2, 4, 5 };     // Deduced type: std::vector<int>\n  numbers.insert(numbers.begin(), 1); // Add single element to the beginning of the sequence\n  printVector(numbers);   // 1 2 4 5\n\n  numbers.insert(numbers.begin() + numbers.size() / 2, 3); // Add in the middle\n  printVector(numbers);   // 1 2 3 4 5\n\n  std::vector more_numbers{ 6, 7, 8 };\n  numbers.insert(numbers.end(), more_numbers.begin(), more_numbers.end());\n  printVector(numbers);   // 1 2 3 4 5 6 7 8\n\n  numbers.erase(numbers.end() - 3, numbers.end());      // Erase last 3 elements\n  numbers.erase(numbers.begin() + numbers.size() / 2);  // Erase the middle element\n  numbers.erase(numbers.begin());                       // Erase the first element\n  printVector(numbers);   // 2 4 5\n}\n\nvoid printVector(const std::vector<int>& v)\n{\n  for (auto i : v) std::cout << i << ' ';\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_10/Ex20_10.cpp",
    "content": "// Removing all elements that satisfy a certain condition \n// while iterating over a container\n#include <vector>\n#include <string_view>\n#include <iostream>\n\nstd::vector<int> fillVector_1toN(size_t N);  // Fill a vector with 1, 2, ..., N\nvoid printVector(std::string_view message, const std::vector<int>& numbers);\n\nvoid removeEvenNumbers(auto& numbers)    /* Correct! */\n{\n  for (auto iter{ numbers.begin() }; iter != numbers.end(); )\n  {\n    if (*iter % 2 == 0)\n      iter = numbers.erase(iter);\n    else\n      ++iter;\n  }\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ fillVector_1toN(num_numbers) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  removeEvenNumbers(numbers);\n\n  printVector(\"The numbers that were kept\", numbers);\n}\n\nstd::vector<int> fillVector_1toN(size_t N)\n{\n  std::vector<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.push_back(i);\n  return numbers;\n}\n\nvoid printVector(std::string_view message, const std::vector<int>& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_11/Ex20_11.cpp",
    "content": "// Your first algorithms: std::min_element() and max_element()\n#include <iostream>\n#include <algorithm>\n#include <vector>\n#include <cmath>    // For std::abs()\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \"\n            << *std::min_element(begin(numbers), end(numbers)) << std::endl;\n  std::cout << \"Maximum element: \"\n            << *std::max_element(begin(numbers), end(numbers)) << std::endl;\n\n  int number_to_search_for {};\n  std::cout << \"Please enter a number: \";\n  std::cin >> number_to_search_for;\n\n  auto nearer { [=](int x, int y) {\n    return std::abs(x - number_to_search_for) < std::abs(y - number_to_search_for);\n  }};\n\n  std::cout << \"The number nearest to \" << number_to_search_for << \" is \"\n            << *std::min_element(begin(numbers), end(numbers), nearer) << std::endl;\n  std::cout << \"The number furthest from \" << number_to_search_for << \" is \"\n            << *std::max_element(begin(numbers), end(numbers), nearer) << std::endl;\n\n/*\n  const auto [nearest, furthest]\n    { std::minmax_element(begin(numbers), end(numbers), nearer) };\n\n  std::cout << \"The number nearest to \" << number_to_search_for << \" is \"\n            << *nearest << std::endl;\n  std::cout << \"The number furthest from \" << number_to_search_for << \" is \"\n            << *furthest << std::endl;\n*/\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_11A/Ex20_11A.cpp",
    "content": "// Your first algorithms: std::min_element() and max_element(),\n// this time using the range-based versions.\n#include <iostream>\n#include <algorithm>\n#include <vector>\n#include <cmath>    // For std::abs()\n\nint main()\n{\n  std::vector numbers{ 91, 18, 92, 22, 13, 43 };\n  std::cout << \"Minimum element: \"\n            << *std::ranges::min_element(numbers) << std::endl;\n  std::cout << \"Maximum element: \"\n            << *std::ranges::max_element(numbers) << std::endl;\n\n  int number_to_search_for {};\n  std::cout << \"Please enter a number: \";\n  std::cin >> number_to_search_for;\n\n  auto nearer { [=](int x, int y) {\n    return std::abs(x - number_to_search_for) < std::abs(y - number_to_search_for);\n  }};\n\n  std::cout << \"The number nearest to \" << number_to_search_for << \" is \"\n            << *std::ranges::min_element(numbers, nearer) << std::endl;\n  std::cout << \"The number furthest from \" << number_to_search_for << \" is \"\n            << *std::ranges::max_element(numbers, nearer) << std::endl;\n\n/*\n  const auto [nearest, furthest]\n    { std::ranges::minmax_element(numbers, nearer) };\n\n  std::cout << \"The number nearest to \" << number_to_search_for << \" is \"\n            << *nearest << std::endl;\n  std::cout << \"The number furthest from \" << number_to_search_for << \" is \"\n            << *furthest << std::endl;\n*/\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_12/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_12/Ex20_12.cpp",
    "content": "// Finding boxes.\n#include <iostream>\n#include <vector>\n#include <algorithm>\n#include \"Box.h\"      // From Ex13_03A\n\nint main()\n{\n  std::vector boxes{ Box{1,2,3}, Box{5,2,3}, Box{9,2,1}, Box{3,2,1} };\n\n  // Define a lambda functor to print the result of find() or find_if():\n  auto print_result{ [&boxes] (auto result)\n  {\n    if (result == end(boxes))\n      std::cout << \"No box found.\" << std::endl;\n    else\n      std::cout << \"Found matching box at position \"\n                << (result - begin(boxes)) << std::endl;\n  }};\n\n  // Find an exact box\n  Box box_to_find{ 3,2,1 };\n  auto result{ std::find(begin(boxes), end(boxes), box_to_find) };\n  print_result(result);\n\n  // Find a box with a volume larger than that of box_to_find\n  const auto required_volume{ box_to_find.volume() };\n  result = std::find_if(begin(boxes), end(boxes),\n              [required_volume](const Box& box) { return box > required_volume; });\n  print_result(result);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_12A/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_12A/Ex20_12A.cpp",
    "content": "// Finding boxes, this time using range-based algorithms.\n#include <iostream>\n#include <vector>\n#include <algorithm>\n#include \"Box.h\"      // From Ex13_03A\n\nint main()\n{\n  std::vector boxes{ Box{1,2,3}, Box{5,2,3}, Box{9,2,1}, Box{3,2,1} };\n\n  // Define a lambda functor to print the result of find() or find_if():\n  auto print_result{ [&boxes](auto result)\n  {\n    if (result == end(boxes))\n      std::cout << \"No box found.\" << std::endl;\n    else\n      std::cout << \"Found matching box at position \"\n                << (result - begin(boxes)) << std::endl;\n  }};\n\n  // Find an exact box\n  Box box_to_find{ 3,2,1 };\n  auto result{ std::ranges::find(boxes, box_to_find) };\n  print_result(result);\n\n  // Find a box with a volume larger than that of box_to_find\n  const auto required_volume{ box_to_find.volume() };\n  result = std::ranges::find_if(boxes,\n              [required_volume](const Box& box) { return box > required_volume; });\n  print_result(result);\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_13/Ex20_13.cpp",
    "content": "// Extracting all odd numbers.\n#include <iostream>\n#include <set>\n#include <vector>\n#include <algorithm>\n\nstd::set<int> fillSet_1toN(size_t N);        // Fill a set with 1, 2, ..., N\nvoid printVector(const std::vector<int>& v); // Print the contents of a vector to std::cout\n\nint main()\n{\n  const size_t num_numbers{20};\n\n  const auto numbers{ fillSet_1toN(num_numbers) };\n\n  std::vector<int> odd_numbers( numbers.size() ); // Caution: not { numbers.size() } here!\n  auto end_odd_numbers{ std::copy_if(begin(numbers), end(numbers), begin(odd_numbers),\n                                      [](int n) { return n % 2 == 1; }) };\n  odd_numbers.erase(end_odd_numbers, end(odd_numbers));\n\n  printVector(odd_numbers);\n}\n\nstd::set<int> fillSet_1toN(size_t N)   // Fill a set with 1, 2, ..., N\n{\n  std::set<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.insert(i);\n  return numbers;\n}\n\nvoid printVector(const std::vector<int>& v)\n{\n  for (auto i : v) std::cout << i << ' ';\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_13A/Ex20_13A.cpp",
    "content": "// Extracting all odd numbers using std::back_inserter().\n#include <iostream>\n#include <set>\n#include <vector>\n#include <algorithm>\n#include <iterator>\t           // For std::back_inserter()\n\nstd::set<int> fillSet_1toN(size_t N);        // Fill a set with 1, 2, ..., N\nvoid printVector(const std::vector<int>& v); // Print the contents of a vector to std::cout\n\nint main()\n{\n  const size_t num_numbers{20};\n\n  const auto numbers{ fillSet_1toN(num_numbers) };\n\n  std::vector<int> odd_numbers;\n  std::copy_if(begin(numbers), end(numbers), back_inserter(odd_numbers),\n               [](int n) { return n % 2 == 1; });\n\n  printVector(odd_numbers);\n}\n\nstd::set<int> fillSet_1toN(size_t N)   // Fill a set with 1, 2, ..., N\n{\n  std::set<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.insert(i);\n  return numbers;\n}\n\nvoid printVector(const std::vector<int>& v)\n{\n  for (auto i : v) std::cout << i << ' ';\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_13B/Ex20_13B.cpp",
    "content": "// Extracting all odd numbers using std::back_inserter().\n// This time using the range-based version of std::copy_if().\n#include <iostream>\n#include <set>\n#include <vector>\n#include <algorithm>\n#include <iterator>\t           // For std::back_inserter()\n\nstd::set<int> fillSet_1toN(size_t N);        // Fill a set with 1, 2, ..., N\nvoid printVector(const std::vector<int>& v); // Print the contents of a vector to std::cout\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  const auto numbers{ fillSet_1toN(num_numbers) };\n\n  std::vector<int> odd_numbers;\n  std::ranges::copy_if(numbers, back_inserter(odd_numbers),\n    [](int n) { return n % 2 == 1; });\n\n  printVector(odd_numbers);\n}\n\nstd::set<int> fillSet_1toN(size_t N)   // Fill a set with 1, 2, ..., N\n{\n  std::set<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.insert(i);\n  return numbers;\n}\n\nvoid printVector(const std::vector<int>& v)\n{\n  for (auto i : v) std::cout << i << ' ';\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_14/Ex20_14.cpp",
    "content": "// Removing all elements that satisfy a certain condition \n// usign the remove-erase idiom\n#include <vector>\n#include <string_view>\n#include <iostream>\n#include <algorithm>\n\nstd::vector<int> fillVector_1toN(size_t N);  // Fill a vector with 1, 2, ..., N\nvoid printVector(std::string_view message, const std::vector<int>& numbers);\n\nvoid removeEvenNumbers(std::vector<int>& numbers)\n{\n  // Use the remove_if() algorithm to remove all even numbers\n  auto first_to_erase{ std::remove_if(begin(numbers), end(numbers),\n                                      [](int number) { return number % 2 == 0; }) };\n  // Erase all elements including and beyond first_to_erase  \n  numbers.erase(first_to_erase, end(numbers));\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ fillVector_1toN(num_numbers) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  removeEvenNumbers(numbers);\n\n  printVector(\"The numbers that were kept\", numbers);\n}\n\nstd::vector<int> fillVector_1toN(size_t N)\n{\n  std::vector<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.push_back(i);\n  return numbers;\n}\n\nvoid printVector(std::string_view message, const std::vector<int>& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_14A/Ex20_14A.cpp",
    "content": "// Removing all elements that satisfy a certain condition usign std::erase_if()\n#include <vector>\n#include <string_view>\n#include <iostream>\n\nstd::vector<int> fillVector_1toN(size_t N);  // Fill a vector with 1, 2, ..., N\nvoid printVector(std::string_view message, const std::vector<int>& numbers);\n\nvoid removeEvenNumbers(std::vector<int>& numbers)\n{\n  std::erase_if(numbers, [](int number) { return number % 2 == 0; });\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ fillVector_1toN(num_numbers) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  removeEvenNumbers(numbers);\n\n  printVector(\"The numbers that were kept\", numbers);\n}\n\nstd::vector<int> fillVector_1toN(size_t N)\n{\n  std::vector<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.push_back(i);\n  return numbers;\n}\n\nvoid printVector(std::string_view message, const std::vector<int>& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_14B/Ex20_14B.cpp",
    "content": "// Removing all elements that satisfy a certain condition \n// usign the remove-erase idiom and the range-based version of std::remove_if.\n// Unlike the iterator-based version, std::ranges::erase_if() returns a subrange, \n// and not an iterator. \n// Note also that in this case std::erase_if() is even more compact (see Ex20_14A).\n#include <vector>\n#include <string_view>\n#include <iostream>\n#include <algorithm>\n\nstd::vector<int> fillVector_1toN(size_t N);  // Fill a vector with 1, 2, ..., N\nvoid printVector(std::string_view message, const std::vector<int>& numbers);\n\nvoid removeEvenNumbers(std::vector<int>& numbers)\n{\n  // Use the remove_if() algorithm to remove all even numbers\n  auto [first_to_erase, last_to_erase] \n    { std::ranges::remove_if(numbers, [](int number) { return number % 2 == 0; }) };\n  // Erase all elements including and beyond first_to_erase  \n  numbers.erase(first_to_erase, last_to_erase);\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ fillVector_1toN(num_numbers) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  removeEvenNumbers(numbers);\n\n  printVector(\"The numbers that were kept\", numbers);\n}\n\nstd::vector<int> fillVector_1toN(size_t N)\n{\n  std::vector<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.push_back(i);\n  return numbers;\n}\n\nvoid printVector(std::string_view message, const std::vector<int>& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_15/Ex20_15.cpp",
    "content": "// Sorting strings\n#include <iostream>\n#include <string>\n#include <vector>\n#include <algorithm>\n\nint main()\n{\n  std::vector<std::string> names{\"Frodo Baggins\", \"Gandalf the Gray\", \n    \"Aragon\", \"Samwise Gamgee\", \"Peregrin Took\", \"Meriadoc Brandybuck\", \n    \"Gimli\", \"Legolas Greenleaf\", \"Boromir\"};\n\n  // Sort the names lexicographically\n  std::sort(begin(names), end(names));\n  std::cout << \"Names sorted lexicographically:\" << std::endl;\n  for (const auto& name : names) std::cout << name << \", \";\n  std::cout << std::endl << std::endl;  \n\n  // Sort the names by length\n  std::sort(begin(names), end(names),\n    [](const auto& left, const auto& right) {return left.length() < right.length(); });\n  std::cout << \"Names sorted by length:\" << std::endl;\n  for (const auto& name : names) std::cout << name << \", \";\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_15A/Ex20_15A.cpp",
    "content": "// Sorting strings using range-based sort()\n#include <iostream>\n#include <string>\n#include <vector>\n#include <algorithm>\n\nint main()\n{\n  std::vector<std::string> names{\"Frodo Baggins\", \"Gandalf the Gray\", \n    \"Aragon\", \"Samwise Gamgee\", \"Peregrin Took\", \"Meriadoc Brandybuck\", \n    \"Gimli\", \"Legolas Greenleaf\", \"Boromir\"};\n\n  // Sort the names lexicographically\n  std::ranges::sort(names);\n  std::cout << \"Names sorted lexicographically:\" << std::endl;\n  for (const auto& name : names) std::cout << name << \", \";\n  std::cout << std::endl << std::endl;  \n\n  // Sort the names by length\n  std::ranges::sort(names,\n    [](const auto& left, const auto& right) {return left.length() < right.length(); });\n  std::cout << \"Names sorted by length:\" << std::endl;\n  for (const auto& name : names) std::cout << name << \", \";\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_16/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\n#endif\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_16/Ex20_16.cpp",
    "content": "// Using range adaptors\n#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <iterator>   // For std::back_inserter()\n#include <ranges>\n#include \"Box.h\"\n\nusing namespace std::ranges::views;\n\nint main()\n{\n  // Our challenge: given a sequence of boxes, \n  // gather pointers to all boxes larger than required_volume\n  std::vector<Box> boxes{ { 1, 2, 3 }, { 4, 5, 6}, { 7, 8, 9 }, { 10, 11, 12 } };\n  const double required_volume{ 200 };\n\n  // Without range-based algorithms and range adaptors (in two steps):\n  std::vector<Box*> box_pointers;\n  std::transform(begin(boxes), end(boxes), back_inserter(box_pointers),\n    [](Box& box) { return &box; });\n  std::vector<Box*> large_boxes;\n  std::copy_if(begin(box_pointers), end(box_pointers), back_inserter(large_boxes),\n    [=](const Box* box) { return *box >= required_volume; });\n\n  std::cout << \"There are \" << large_boxes.size() << \" large boxes.\" << std::endl;\n\n  // With range-based algorithm copy() and a filter-transform pipeline\n  std::vector<Box*> large_boxes_ranges_copy;\n  std::ranges::copy(\n    boxes | filter([=](const Box& box) { return box >= required_volume; })\n          | transform([](Box& box) { return &box; }),\n    back_inserter(large_boxes_ranges_copy)\n  );\n\n  // With range-based algorithm copy_if() and transform adaptor\n  std::vector<Box*> large_boxes_ranges_copy_if;\n  std::ranges::copy_if(    /* Transform using adaptor before filtering in copy_if() */\n     boxes | transform([](Box& box) { return &box; }),       // Input view of boxes\n     back_inserter(large_boxes_ranges_copy_if),              // Output iterator\n     [=](const Box* box) { return *box >= required_volume; } // Condition for copy_if()\n  );\n\n  // With range-based algorithm transform() and a filter adaptor\n  std::vector<Box*> large_boxes_ranges_transform;\n  std::ranges::transform(  /* Filter using adaptor before transforming using algorithm */\n     boxes | filter([=](const Box& box) { return box >= required_volume; }),\n     back_inserter(large_boxes_ranges_transform),          // Output iterator\n     [](Box& box) { return &box; }        // Transform functor of transform()\n  );\n\n  if (large_boxes_ranges_copy != large_boxes\n    || large_boxes_ranges_copy_if != large_boxes\n    || large_boxes_ranges_transform != large_boxes)\n  {\n    std::cerr << \"Oh dear... One of the range-based algorithms gave a different result!\" << std::endl;\n  }\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_17/Ex20_17.cpp",
    "content": "// Range factories and range adaptors\n#include <iostream>\n#include <ranges>   // For views, range factories, and range adaptors\n\nusing namespace std::ranges::views;\n\nbool isEven(int i) { return i % 2 == 0; }\nint squared(int i) { return i * i; }\n\nint main()\n{\n  for (int i : iota(1, 10))       // Lazily generate range [1,10)\n    std::cout << i << ' ';\n  std::cout << std::endl;\n\n  for (int i : iota(1, 1000) | filter(isEven) | transform(squared)\n    | drop(2) | take(5) | reverse)\n    std::cout << i << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 20/Ex20_18/Ex20_18.cpp",
    "content": "// Writing through a view\n#include <iostream>\n#include <vector>\n#include <ranges>   // For views, range factories, and range adaptors\n\nbool isEven(int i) { return i % 2 == 0; }\n\nint main()\n{\n  std::vector numbers{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n\n  for (int& i : numbers | std::ranges::views::filter(isEven))\n    i *= i;\n\n  for (int i : numbers) std::cout << i << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 21/Ex21_01/Ex21_01.cpp",
    "content": "// Class template instantiation errors\n#include <set>\n#include <list>\n#include <vector>\n#include <algorithm>\n\nclass MyClass { /* just a dummy class */ };\n\nint main()\n{\n  std::vector<int&> v;\n\n  MyClass one, other;\n  auto biggest{ std::max(one, other) };\n\n  std::set<MyClass> objects;\n  objects.insert(MyClass{});\n\n  std::list numbers{ 4, 1, 3, 2 };\n  std::sort(begin(numbers), end(numbers));\n}\n\n"
  },
  {
    "path": "Examples/NoModules/Chapter 21/Ex21_02/Ex21_02.cpp",
    "content": "// Asserting that a type models a concept\n#include <concepts>    // For the std::same_as<> and std::convertible_to<> concepts\n#include <ranges>      // For std::ranges::range<> concept\n#include <type_traits> // For the std::remove_cv<> type trait\n#include <list>\n#include <vector>\n#include <string>\n\ntemplate <typename Iter>\nconcept BidirectionalIterator = true; // Feel free to further work out all requirements...\n\ntemplate<class Iter>\nconcept RandomAccessIterator = BidirectionalIterator<Iter>\n  && requires(const Iter i, const Iter j, Iter k, const int n)\n     {\n       { i - n } -> std::same_as<Iter>;\n       { i + n } -> std::same_as<Iter>; { n + i } -> std::same_as<Iter>;\n       { k += n }-> std::same_as<Iter&>; { k -= n }-> std::same_as<Iter&>;\n       { i[n] }  -> std::same_as<decltype(*i)>;\n       { i < j } -> std::convertible_to<bool>;\n       { i > j } -> std::convertible_to<bool>;\n       { i <= j } -> std::convertible_to<bool>;\n       { i >= j } -> std::convertible_to<bool>;\n     };\n\ntemplate <typename T>\nconcept NoExceptDestructible = requires (T & value) { { value.~T() } noexcept; };\n\ntemplate <typename C>\nconcept Character = std::same_as<std::remove_cv_t<C>, char>\n                  || std::same_as<std::remove_cv_t<C>, char8_t>\n                  || std::same_as<std::remove_cv_t<C>, char16_t>\n                  || std::same_as<std::remove_cv_t<C>, char32_t>\n                  || std::same_as<std::remove_cv_t<C>, wchar_t>;\n\ntemplate <typename S>\nconcept String = std::ranges::range<S> && requires(S & s, const S & cs)\n{\n  typename S::value_type;\n  requires Character<typename S::value_type>;\n  { cs.length() } -> std::integral;\n  { s[0] } -> std::same_as<typename S::value_type&>;\n  { cs[0] } -> std::convertible_to<typename S::value_type>;\n  { s.data() } -> std::same_as<typename S::value_type*>;\n  { cs.data() } -> std::same_as<const typename S::value_type*>;\n  // ...\n};\n\nstatic_assert(NoExceptDestructible<std::string>);\nstatic_assert(NoExceptDestructible<int>);\nstatic_assert(String<std::string>);\nstatic_assert(!String<std::vector<char>>);\nstatic_assert(Character<char>);\nstatic_assert(Character<const char>);\nstatic_assert(RandomAccessIterator<std::vector<int>::iterator>);\nstatic_assert(!RandomAccessIterator<std::list<int>::iterator>);\nstatic_assert(RandomAccessIterator<int*>);\n\nint main()\n{\n}"
  },
  {
    "path": "Examples/NoModules/Chapter 21/Ex21_03/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n#include <concepts>\n\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nclass Array\n{\npublic:\n  Array();                                  \n  explicit Array(size_t size);              \n  ~Array();                                 \n  Array(const Array& array) requires std::copyable<T>;\n  Array& operator=(const Array& rhs) requires std::copyable<T>;\n  Array(Array&& array) noexcept requires std::movable<T>;\n  Array& operator=(Array&& rhs) noexcept requires std::movable<T>;\n  void swap(Array& other) noexcept;        \n  T& operator[](size_t index);             \n  const T& operator[](size_t index) const; \n  size_t getSize() const { return m_size; }\n  void push_back(T element) requires std::movable<T>;\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>::Array() \n  : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>::Array(size_t size) \n  : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>::Array(const Array& array) requires std::copyable<T> \n  : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>::Array(Array&& moved) noexcept requires std::movable<T>\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>& Array<T>::operator=(const Array& rhs) requires std::copyable<T>\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nArray<T>& Array<T>::operator=(Array&& rhs) noexcept requires std::movable<T>\n{\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n// push_back() overload for lvalue references\ntemplate <typename T> requires std::default_initializable<T> && std::destructible<T>\nvoid Array<T>::push_back(T element) requires std::movable<T>\n{\n  Array<T> newArray{m_size + 1};      // Allocate a larger Array<>\n  for (size_t i{}; i < m_size; ++i)   // Move all existing elements...\n    newArray[i] = std::move(m_elements[i]);\n\n  newArray[m_size] = std::move(element); // Move the new one (could itself be a copy already)...\n\n  swap(newArray);                     // ... and swap!\n}\n\n#endif"
  },
  {
    "path": "Examples/NoModules/Chapter 21/Ex21_03/Ex21_03.cpp",
    "content": "// Violating constraints of uninstantiated class members\n#include \"Array.h\"\n#include <memory>  // For std::unique_ptr<>\n\n// Assert that Array<std::unique_ptr<int>> is a valid type\nstatic_assert(requires { typename Array<std::unique_ptr<int>>; });\n\nint main()\n{\n  Array<std::unique_ptr<int>> tenSmartPointers(10);\n  Array<std::unique_ptr<int>> target;\n  // target = tenSmartPointers;   /* Constraint not satisfied: copyable<unique_ptr> */\n  target = std::move(tenSmartPointers);\n  target.push_back(std::make_unique<int>(123));\n}\n"
  },
  {
    "path": "Examples/NoModules/Chapter 21/Ex21_04/Ex21_04.cpp",
    "content": "// Constraint based specialization\n#include <concepts>  // For the std::equality_comparable<> concept\n#include <iterator>  // The iterator concepts and the iter_difference_t<>() trait\n#include <vector>\n#include <list>\n#include <iostream>\n\n// Precondition: incrementing first eventually leads to last\ntemplate <std::input_or_output_iterator Iter> requires std::equality_comparable<Iter>\nauto distanceBetween(Iter first, Iter last)\n{\n  std::cout << \"Distance determined by linear traversal: \";\n  std::iter_difference_t<Iter> result{};\n  while (first != last) { ++first; ++result; }\n  return result;\n}\n\ntemplate <std::random_access_iterator Iter>\nauto distanceBetween(Iter first, Iter last)\n{\n  std::cout << \"Distance determined in constant time: \";\n  return last - first;\n}\n\nint main()\n{\n  std::list l{ 'a', 'b', 'c' };\n  std::vector v{ 1, 2, 3, 4, 5 };\n  float a[] { 1.2f, 3.4f, 4.5f };\n\n  std::cout << distanceBetween(cbegin(l), cend(l)) << std::endl;\n  std::cout << distanceBetween(begin(v), end(v)) << std::endl;\n  std::cout << distanceBetween(a, a + std::size(a)) << std::endl;\n}\n"
  },
  {
    "path": "Examples/README.md",
    "content": "# Examples\n\nThis directory contains all source code for the examples given \nin [*Beginning C++20*](https://www.apress.com/9781484258835) by Ivor Horton and Peter Van Weert (Apress, 2020).\n\nThe [Modules](Modules) directory contains all source code as discussed in the book.\nIf your compiler does not support C++20 modules yet\n(which at the time of writing is likely),\nyou may be better off using the code in [NoModules](NoModules) instead, though.\nThis directory contains equivalents of all examples without the use of modules.\n\nConsult the [Workarounds](../Workarounds) directory on \nhow to work around compilation issues with other C++20 language and library features \nthat your compiler may not (fully) [support](https://en.cppreference.com/w/cpp/compiler_support) yet.\n"
  },
  {
    "path": "Exercises/Modules/Chapter 01/Exer1_03.cpp",
    "content": "// Exercise 1-3. Spot the errors. \n// The correct version should closely resemble the answer to Exercise 1.1.\n\ninclude <iostream>                            // # character missing before include\n\nInt main()                                    // Should be int, not Int\n{\n  std:cout << \"Hola Mundo!\" << std:endl       // A semicolon is missing from the end of this line\n                                              // cout and endl must be prefixed with std::, not std:\n)"
  },
  {
    "path": "Exercises/Modules/Chapter 01/Soln1_01.cpp",
    "content": "// Exercise 1-1 Writing the line \"Hello World\" to the screen.\n\nimport <iostream>;\n\nint main()\n{\n  std::cout << \"Hello World\" << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 01/Soln1_02.cpp",
    "content": "// Exercise 1-2. Write your name and age on successive lines.\n// There are several possibilities. You can do it in one statement for example.\n// You could also output '\\n' to go to a new line.\n\nimport <iostream>;\n\nint main()\n{\n  std::cout << \"Phil McCavity\" << std::endl;       // Name\n  std::cout << \"Age: 88\" << std::endl;             // and age\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 02/Soln2_01A.cpp",
    "content": "// Exercise 2-1. Convert inches to feet and inches\n// The number of inches per foot is constant, \n// and should not be changed within the program,\n// so we recognize this by declaring it as a const.\n//\n// This solution uses only std::cout. \n// See alternate solution for a version that uses std::format().\n//\n// Note: we always output \"feet\" and \"inches\", \n// even if it concerns only 1 foot or 1 inch.\n// In a later chapter you will learn about the conditional \n// statements and expressions that allow you to refine this.\n\nimport <iostream>;\n\nint main()\n{\n  const int inches_per_foot{ 12 };    // Initialize constant variable\n\n  std::cout << \"This program will convert inches to feet and inches.\" << std::endl;\n\n  int inches{};\n  std::cout << \"Please enter a number of inches: \";\n  std::cin >> inches;\n\n  const int feet{ inches / inches_per_foot };\n  const int remaining_inches{ inches % inches_per_foot };\n\n  std::cout << inches << \" inches equals \"\n    << feet << \" feet and \" << remaining_inches << \" inches.\"\n    << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 02/Soln2_01B.cpp",
    "content": "// Exercise 2-1. Convert inches to feet and inches\n// The number of inches per foot is constant, \n// and should not be changed within the program,\n// so we recognize this by declaring it as a const.\n//\n// This solution uses std::format().\n//\n// Note: we always output \"feet\" and \"inches\", \n// even if it concerns only 1 foot or 1 inch.\n// In a later chapter you will learn about the conditional \n// statements and expressions that allow you to refine this.\n\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  const int inches_per_foot { 12 };    // Initialize constant variable\n\n  std::cout << \"This program will convert inches to feet and inches.\" << std::endl;\n\n  int inches {};\n  std::cout << \"Please enter a number of inches: \";\n  std::cin >> inches;\n\n  const int feet = inches / inches_per_foot;\n  const int remaining_inches = inches % inches_per_foot;\n\n  std::cout \n    << std::format(\"{} inches equals {} feet and {} inches.\", inches, feet, remaining_inches) \n    << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 02/Soln2_02A.cpp",
    "content": "// Exercise 2-2 Compute the area of a circle\n// This solution uses only std::cout. \n// See alternate solution for a version that uses std::format().\n\nimport <iostream>;\nimport <numbers>;\n\nint main()\n{\n  std::cout << \"This program will compute the area of a circle.\" << std::endl;\n\n  double radius {};\n  std::cout << \"Please enter the radius of the circle: \";\n  std::cin >> radius;\n  \n  const auto area{ std::numbers::pi * radius * radius };\n\n  std::cout << \"The area of the circle is \" << area << \" square units.\" << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 02/Soln2_02B.cpp",
    "content": "// Exercise 2-2 Compute the area of a circle\n// This solution uses std::format() \n// to control the precision used when outputting the result\n// (we opted for 2 decimals after the decimal points).\n\nimport <iostream>;\nimport <numbers>;\nimport <format>;\n\nint main()\n{\n  std::cout << \"This program will compute the area of a circle.\" << std::endl;\n\n  double radius {};\n  std::cout << \"Please enter the radius of the circle: \";\n  std::cin >> radius;\n  \n  const auto area{ std::numbers::pi * radius * radius };\n\n  std::cout << std::format(\"The area of the circle is {:.2f} square units.\", area) << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 02/Soln2_03.cpp",
    "content": "// Exercise 2-3. Calculating the height of a tree\nimport <iostream>; \nimport <numbers>;\n\n#include <cmath>\n\nint main()\n{\n  const double inches_per_foot {12.0};\n  const double pi_degrees {180.0};\n  double feet {};\n  double inches {};\n\n  std::cout << \"Enter the distance from the tree in feet and inches: \";\n  std::cin >> feet >> inches;\n  const double distance {feet + inches / inches_per_foot};\n\n  double angle {};\n  std::cout << \"Enter the angle of the top of the tree in degrees: \";\n  std::cin >> angle;\n  \n  // First convert angle to radians \n  // (the trigoniometric functions of <cmath> operate with radians)\n  angle *= std::numbers::pi / pi_degrees;     \n                                              \n  double eye_height {};\n  std::cout << \"Enter your eye height from the ground in inches: \";\n  std::cin >> eye_height;\n  eye_height /= inches_per_foot;                                  // Convert to feet\n  \n  const double height {eye_height + distance * std::tan(angle)};  // Tree height in feet\n  const unsigned height_feet {static_cast<unsigned>(height)};\n  const unsigned height_inches {static_cast<unsigned>(std::round(inches_per_foot * (height - height_feet)))};\n\n  std::cout << \"\\nThe height of the tree is \"\n            << height_feet << \" feet \"\n            << height_inches << \" inches.\\n\" << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 02/Soln2_04.cpp",
    "content": "// Exercise 2-4. Calculating the Body Mass Index.\n// In the expression for bmi, both h_feet and h_inches will be implicitly converted to double\n// because the other operand of the sub-expression is double.\n\nimport <iostream>;\n\nint main()\n{\n  const double lbs_per_kg {2.2};\n  const double inches_per_foot {12.0};\n  const double meters_per_foot {0.3048};\n  \n  double w_lbs {};\n  unsigned int h_feet {};\n  unsigned int h_inches {};\n\n  std::cout << \"Enter your weight in pounds: \";\n  std::cin >> w_lbs;\n  std::cout << \"Enter you height in feet and inches: \";\n  std::cin >> h_feet >> h_inches;\n\n  const double w_kg {w_lbs / lbs_per_kg};\n  const double h_meters { meters_per_foot * (h_feet + h_inches / inches_per_foot) };\n  const double bmi {w_kg / (h_meters * h_meters)};\n  std::cout << \"Your BMI is \" << bmi << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 02/Soln2_05.cpp",
    "content": "// Exercise 2-5. Output your BMI with one decimal after the decimal point.\n\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  const double lbs_per_kg{ 2.2 };\n  const double inches_per_foot{ 12.0 };\n  const double meters_per_foot{ 0.3048 };\n\n  double w_lbs{};\n  unsigned int h_feet{};\n  unsigned int h_inches{};\n\n  std::cout << \"Enter your weight in pounds: \";\n  std::cin >> w_lbs;\n  std::cout << \"Enter you height in feet and inches: \";\n  std::cin >> h_feet >> h_inches;\n\n  const double w_kg{ w_lbs / lbs_per_kg };\n  const double h_meters{ meters_per_foot * h_feet + h_inches / inches_per_foot };\n  const double bmi{ w_kg / (h_meters * h_meters) };\n  std::cout << std::format(\"Your BMI is {:.1f}\\n\", bmi);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 02/Soln2_06.cpp",
    "content": "// Exercise 2-6. Format a table.\n\nimport <iostream>;\nimport <numbers>;\nimport <format>;\n\nint main()\n{\n  // Define the format strings for the various rows of the table first\n  const auto format_header     { \"{:20} {:35} {}\\n\" };\n  const auto format_precision5 { \"{:20} {:35} {:.5f}...\\n\" };\n  const auto format_precision3 { \"{:20} {:35} {:.3f}...\\n\" };\n\n  std::cout << std::format(format_header,     \"Constant\",            \"Description\",                       \"Approximation\");\n  std::cout << std::format(format_precision5, \"std::numbers::e\",     \"The base of the natural logarithm\", std::numbers::e);\n  std::cout << std::format(format_precision5, \"std::numbers::pi\",    \"pi\",                                std::numbers::pi);\n  std::cout << std::format(format_precision5, \"std::numbers::sqrt2\", \"Square root of 2\",                  std::numbers::sqrt2);\n  std::cout << std::format(format_precision3, \"std::numbers::phi\",   \"The golden ration constant\",        std::numbers::phi);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 02/Soln2_07.cpp",
    "content": "// Exercise 2-7. Fun with formatting.\n// You could always experiment further with various formatting options here!\n\nimport <iostream>;\nimport <numbers>;\nimport <format>;\n\n#include <cmath>\n\nint main()\n{\n  // Define the format strings for the various rows of the table first\n  const auto format_header    { \"{:20} {:35} {}\\n\" };\n  const auto format_precision5{ \"{:20} {:35} {:.5f}...\\n\" };\n  const auto format_precision3{ \"{:20} {:35} {:.3f}...\\n\" };\n  const auto format_extra_row { \"{:20} {:35} {:.5E}...\\n\" };\n\n  std::cout << std::format(format_header,     \"Constant\",            \"Description\",                       \"Approximation\");\n  std::cout << std::format(format_precision5, \"std::numbers::e\",     \"The base of the natural logarithm\", std::numbers::e);\n  std::cout << std::format(format_precision5, \"std::numbers::pi\",    \"pi\",                                std::numbers::pi);\n  std::cout << std::format(format_precision5, \"std::numbers::sqrt2\", \"Square root of 2\",                  std::numbers::sqrt2);\n  std::cout << std::format(format_precision3, \"std::numbers::phi\",   \"The golden ration constant\",        std::numbers::phi);\n  std::cout << std::format(format_extra_row,  \"sin(pi/4)\",           \"... in exponent notation\",          std::sin(std::numbers::pi / 4));\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 02/Soln2_08.cpp",
    "content": "// Exercise 2-8. Finding the largest of two integers without comparing them.\nimport <iostream>;\n\nint main()\n{\n  unsigned a {};\n  unsigned b {};\n\n  std::cout << \"Enter a positive integer: \";\n  std::cin >> a;\n  std::cout << \"Enter another positive integer: \";\n  std::cin >> b;\n\n  // The trick is that, for integer values x and y, \n  // x / y equals zero if x < y.\n  // So unless a and b are equal, either a/b or b/a is zero,\n  // meaning in (x * (a/b) + y * (b/a)) one of both operands of + equals 0.\n  // Once you have that, it's just a matter of working out the details.\n\n  const unsigned larger {(a * (a / b) + b * (b / a)) / (a / b + b / a)};\n  const unsigned smaller {(b * (a / b) + a * (b / a)) / (a / b + b / a)};\n  std::cout << \"The larger integer is \" << larger << \".\\n\"\n            << \"The smaller integer is \" << smaller << '.' << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 03/Soln3_01.cpp",
    "content": "// Exercise 3-1. Output an integer and its complements in binary and decimal.\n\n// This tests how well you remember string formatting using std::format()\n// (see Chapter 2 if you forgot some of the formatting options), \n// as well as two's complement binary encoding and bitwise ~.\n\nimport <iostream>;\nimport <format>;\n\n// See Appendix A (available online) for static_assert().\n// You should adjust the field widths of the table if ints have a different size.\nstatic_assert(sizeof(int) == 4, \"This program assumes 32 bit ints\");\n\nint main()\n{\n  int value {};\n  std::cout << \"Enter any integer: \";\n  std::cin >> value;\n  \n  const auto inverted{ static_cast<unsigned>(~value) };\n\n  // Output column headings (0b and 32 bits make for a width of 34)\n  std::cout << std::format(\" {:^34} {:^34} {:^34}\\n\", \"value\", \"~value\", \"~value + 1\");\n\n  // Output binary values (cast to unsigned integers first for more realistic output)\n  std::cout << std::format(\" {:#034b} {:#034b} {:#034b}\\n\", value, inverted, inverted + 1);\n\n  // Output decimal values\n  std::cout << std::format(\" {:^34} {:^34} {:^34}\\n\", value, ~value, ~value + 1);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 03/Soln3_02.cpp",
    "content": "// Exercise 3-2. Calculating the number of boxes that can be stored on a shelf, without overhang. \n// We have to calculate how many boxes we can get into a row,\n// and how many rows we can have, and then multiply these numbers together.\n// The 'no overhang' problem is easily handled: casting from double to long \n// (using static_cast<>()) ensures that the fractional part of the double value\n// is omitted, and only whole boxes are counted. \n// By including static_cast<>() in the code, we are effectively telling the\n// compiler that we know what information will be lost in the cast.\n\nimport <iostream>;\n\nint main() \n{\n  const int inches_per_foot {12};\n\n  double shelf_length {};\n  double shelf_depth {};\n  int box_size {};\n\n  // Prompt the user for both the shelf and box dimensions\n  std::cout << \"Enter shelf length (feet): \";\n  std::cin >> shelf_length;\n\n  std::cout << \"Enter shelf depth (feet): \";\n  std::cin >> shelf_depth;\n\n  std::cout << \"Enter length ofthe side of a box (inches): \";\n  std::cin >> box_size;\n\n  // Calculating the number of whole boxes needed to fill the shelf.\n  long boxes {static_cast<long>((shelf_length * inches_per_foot) / box_size) *\n                                static_cast<long>((shelf_depth * inches_per_foot) / box_size)};\n\n  // Displaying the number of boxes\n  std::cout << \"The number of boxes that can be contained in a single layer is \" << boxes << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 03/Soln3_03.cpp",
    "content": "/*********************************************************************************\nExercise 3-3. The output from the code is 2. Here's the important statement again:\n\nauto j {(k >> 4) & ~(~0u << 3)};\n\nThis question is an exercise in bit manipulation on k.\nFirst, (k >> 4) shifts the bits in k 4 places to the right;\nthe bitwise representation of 430 is 110101110,\nso a 4-bit shift leaves 11010.\nNext, ~0 is composed of all 1s; shifting that three places to the left\nand complementing the result will leave 111.\nFinally, doing a bitwise AND on 11010 and 111 leaves 10 (in binary)\nor 2 (in decimal) as the result.\n*********************************************************************************/\n\nimport <iostream>;\n\nint main()\n{\n  /* Note: try to figure out the solution to this exercise without actually running it */\n  auto k{ 430u };\n  auto j{ (k >> 4) & ~(~0u << 3) };\n  std::cout << j << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 03/Soln3_04.cpp",
    "content": "// Exercise 3-4. Packing and unpacking characters.\n\n// Strictly speaking, whether or not this program works is compiler-dependent.\n// Although it's extremely unlikely that you'll notice a problem.\n// Concretely: it'll only work if a single byte is 8 bit (virtually always the case),\n// and the fundamental type int counts at least 4 bytes (true for most modern systems).\n\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  unsigned int packed {};\n  unsigned char ch {};\n  std::cout << std::format(\"{:26}\", \"Enter a character: \");\n  std::cin >> ch;\n  packed |= ch;\n\n  std::cout << std::format(\"{:26}\", \"Enter a second character: \");\n  std::cin >> ch;\n  packed <<= 8;                                // Shift left 1 byte\n  packed |= ch;\n\n  std::cout << std::format(\"{:26}\", \"Enter a third character: \");\n  std::cin >> ch;\n  packed <<= 8;                                // Shift left 1 byte\n  packed |= ch;\n\n  std::cout << std::format(\"{:26}\", \"Enter a fourth character: \");\n  std::cin >> ch;\n  packed <<= 8;                                // Shift left 1 byte\n  packed |= ch;\n\n  std::cout << std::format(\"The word containing 4 packed characters is {:#0x}\", packed) << std::endl;\n\t\n  std::cout << \"Unpacking the characters again gives (low-order byte first): \";\n\n  // Unpacking packed... \n  // (without the static_cast<char>() conversions the bytes would be written as numbers,\n  // which would be fine as well...)\n\n  unsigned int mask {0x00000FF};  // Keep low order byte \n                                  // (could just use 0xFF as well, or, of course, 255)\n\n  ch = packed & mask;                    // Low order byte\n  std::cout << std::format(\"{:4}\", static_cast<char>(ch));\n  ch = (packed >> 8) & mask;                   // 2nd byte\n  std::cout << std::format(\"{:4}\", static_cast<char>(ch));\n  ch = (packed >> 16) & mask;                  // 3rd byte\n  std::cout << std::format(\"{:4}\", static_cast<char>(ch));\n  ch = (packed >> 24) & mask;                  // 4th byte\n  std::cout << std::format(\"{:4}\", static_cast<char>(ch)) \n            << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 03/Soln3_05.cpp",
    "content": "// Exercise 3-5. Using an enumeration type for colors.\n// Of course, you have to research the RGB components for the colors.\n// Biggest complication is that you cannot apply any binary or other arithmetic operations\n// on values of a scoped enumaration type. For this, you have to first cast them to an integer.\n\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  enum class Color : unsigned\n  {\n    Red    = 0xFF0000u,\n    Green  = 0x00FF00u,\n    Blue   = 0x0000FFu,\n    Yellow = 0xFFFF00u,\n    Purple = 0xFF00FFu,\n    Black  = 0x000000u,\n    White  = 0xFFFFFFu\n  };\n\n  const auto format_string \n       { \"The components of {:^6} are: red: {:3}, green: {:3}, blue: {:3}\\n\" };\n  \n  const Color yellow{ Color::Yellow };\n  const Color purple{ Color::Purple };\n  const Color green { Color::Green };\n\n  std::cout << std::format(format_string,\n    \"yellow\",\n    (static_cast<unsigned>(yellow) & static_cast<unsigned>(Color::Red)) >> 16,\n    (static_cast<unsigned>(yellow) & static_cast<unsigned>(Color::Green)) >> 8,\n    (static_cast<unsigned>(yellow) & static_cast<unsigned>(Color::Blue))\n  );\n\n  std::cout << std::format(format_string,\n    \"purple\",\n    (static_cast<unsigned>(purple) & static_cast<unsigned>(Color::Red)) >> 16,\n    (static_cast<unsigned>(purple) & static_cast<unsigned>(Color::Green)) >> 8,\n    (static_cast<unsigned>(purple) & static_cast<unsigned>(Color::Blue))\n  );\n\n  std::cout << std::format(format_string,\n    \"green\",\n    (static_cast<unsigned>(green) & static_cast<unsigned>(Color::Red)) >> 16,\n    (static_cast<unsigned>(green) & static_cast<unsigned>(Color::Green)) >> 8,\n    (static_cast<unsigned>(green) & static_cast<unsigned>(Color::Blue))\n  );\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 03/Soln3_06.cpp",
    "content": "// Exercise 3-6. Swapping integers.\n\nimport <iostream>;\n\nint main()\n{\n  int first {}, second {};\n  std::cout << \"Enter two integers separated by a space: \";\n  std::cin >> first >> second;\n\n  first ^= second;\n  second ^= first;\n  first ^= second;\n  std::cout << \"In reverse order they are \" << first << \" and \" << second << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 04/Soln4_01.cpp",
    "content": "// Exercise 4-1 Testing whether two integer values are equal. \n\nimport <iostream>;\n\nint main()\n{\n  int value1 {};\n  int value2 {};\n\n  std::cout << \"Please input two integers, separated by a space: \";\n  std::cin >> value1 >> value2;\n  std::cout << std::endl;\n\n  if (value1 == value2)\n    std::cout << \"The values you entered are the same (two times \" << value1 << \").\" << std::endl;\n  else \n    std::cout << \"The values you entered are not the same (\" << value1 << \" != \" << value2 << \").\" << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 04/Soln4_02.cpp",
    "content": "// Exercise 4-2 Testing for exact division of one integer by another.\n//              We can use an if statement to check that the input is valid \n//              and we can use another to arrange the input as we need. \n//              Then we use an if-else to generate the appropriate output.\n\nimport <iostream>;\n\nint main()\n{\n  int value1 {};\n  int value2 {};\n\n  std::cout << \"Please input two positive integers, separated by a space: \";\n  std::cin >> value1 >> value2;\n  std::cout << std::endl;\n\n  if (value1 <= 0 || value2 <= 0)  // Valid input?\n  {\n    std::cout << \"Sorry - positive integers only.\" << std::endl;\n    return 1;\n  }\n\n  // Ensure that value1 is not smaller than value2\n  if (value1 < value2)\n  {         \n    const auto temp{ value1 };    // swap if necessary\n    value1 = value2;\n    value2 = temp;\n  }\n\n  if (value1 % value2 == 0)\n    std::cout << value2 << \" divides into \" << value1 << \" exactly. \" << std::endl;\n  else \n    std::cout << value1 << \" is not exactly divisible by \" << value2 << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 04/Soln4_03.cpp",
    "content": "// Exercise 4-3 Using nested ifs and a logical && to check the value of a number.\n\nimport <iostream>;\n\nint main()\n{\n  double value {};\n\n  std::cout << \"Please enter a number between 1 and 100: \";\n  std::cin >> value;\n  std::cout << std::endl;\n\n  if (value >= 1 && value <= 100)\n  {\n    std::cout << \"The number you entered is \";\n    \n    if (value > 50)\n      std::cout << \"greater than 50\";\n    else if (value < 50)\n      std::cout << \"less than 50\" << std::endl;\n    else\n      std::cout << \"50\" << std::endl;\n  \n    std::cout << '.' << std::endl;\n  }\n  else\n  {\n    std::cout << \"The number is not between 1 and 100.\" << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 04/Soln4_04.cpp",
    "content": "// Exercise 4-4.\n// As promised, you're to go look for a person \"who is over 21, under 35, female, \n// has a bachelors or masters degree, is unmarried, and who speaks Hindi or Urdu\"\n\nimport <iostream>;\n\n#include <cctype>          // For std::tolower() / std::toupper()\n\nenum class AcademicDegree\n{\n  none, associate, bachelor, professional, master, doctor\n};\n\nint main()\n{\n  unsigned int age {};        // Initialized to 0\n  char gender {};             // Initialized to '\\0' (see Chapter 5)\n  AcademicDegree degree {};   // Initialized to AcademicDegree::none\n  bool married {};            // Initialized to false\n  bool speaksHindi {};\n  bool speaksUrdu {};\n\n  std::cout << \"What is your age, if I may ask? \";\n  std::cin >> age;\n  \n  if (age > 120)\n  {\n    std::cout << \"Sure it is, joker. Sadly, commedians don't qualify...\" << std::endl;\n    return 1;\n  }\n  \n  std::cout << \"What is your gender ([m]ale, [f]emale, or [o]ther)? \";\n  std::cin >> gender;\n  \n  gender = std::tolower(gender);\n  if (gender != 'm' && gender != 'f' && gender != 'o')\n  {\n    std::cout << \"That was not one of the options... \"\n                 \"The square brackets were not clear, perhaps? We were worried about that...\";\n    return 1;\n  }\n  \n  std::cout << \"What is your highest academic degree?\\n\"\n    << \"Possible values are:\\n\"\n    << \"\\tn: no academic degree\\n\"\n    << \"\\ta: associate's degree\\n\"\n    << \"\\tb: bachelor's dehree\\n\"\n    << \"\\tp: professional degree\\n\"\n    << \"\\tm: master's degree\\n\"\n    << \"\\td: doctorate\\n\";\n  char degreeChar {};\n  std::cin >> degreeChar;  \n  \n  switch (std::tolower(degreeChar))\n  {\n    case 'n': degree = AcademicDegree::none;         break;\n    case 'a': degree = AcademicDegree::associate;    break;\n    case 'b': degree = AcademicDegree::bachelor;     break;\t\n    case 'p': degree = AcademicDegree::professional; break;\n    case 'm': degree = AcademicDegree::master;       break;\n    case 'd': degree = AcademicDegree::doctor;       break;\n    default:\n      std::cout << \"Given that you cannot correctly enter your degree, shall I just note down 'none'?\\n\";\n      std::cout << \"On second thought: no, I do not believe you qualify. Goodbye.\" << std::endl;\n      return 1;\n  }\n  \n  // Now we ask a few yes/no questions, and use some variations on how to decide\n  // whether or not the user's input is valid or not. In real code, one should\n  // probably be consistent rather than using a different style each time...  \n  \n  char yes_no {};\n  std::cout << \"Are you married (y or n)? \";\n  std::cin >> yes_no;\n  \n  if (yes_no == 'y' || yes_no == 'Y')\n    married = true;\n  else if (yes_no == 'n' || yes_no == 'N')\n    married = false;\n  else\n  {\n    std::cout << \"Incapable of entering your marital status. Surely still single then...?\" << std::endl;\n    return 1;\n  }\n  \n  std::cout << \"Do you speak Hindi (y or n)? \";\n  std::cin >> yes_no;\n  \n  yes_no = std::toupper(yes_no);\n  if (yes_no == 'Y')\n    speaksHindi = true;\n  else if (yes_no == 'N')\n    speaksHindi = false;\n  else\n  {\n    std::cout << \"I'm sorry? I didn't catch that. Please answer in English next time...\" << std::endl;\n    return 1;\n  }\n  \n  std::cout << \"Do you speak Urdu (y or n)? \";\n  std::cin >> yes_no;\n  \n  switch (std::tolower(yes_no))\n  {\n    case 'y': speaksUrdu = true;  break;\n    case 'n': speaksUrdu = false; break;\n    default:\n      std::cout << \"I'm sorry? I didn't catch that. Please answer in English next time...\" << std::endl;\n      return 1;\n  }\n  \n  // Determine whether the user is someone \"who is over 21, under 35, female, has a bachelors or masters degree,\n  // is unmarried, and who speaks Hindi or Urdu\"\n  if ((age > 21 && age < 35) \n        && gender == 'f' \n        && (degree == AcademicDegree::bachelor || degree == AcademicDegree::master)\n        && !married\n        && (speaksHindi || speaksUrdu))\n  {\n    std::cout << \"Congratulations: you are precisely the person we were looking for! Are you willing to work for minimum wage?\" << std::endl;\n  }\n  else\n  {\n    std::cout << \"Sorry. You don't seem to meet our requirements to the letter. Don't call us, we'll call you...?\" << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 04/Soln4_05.cpp",
    "content": "// Exercise 4-05\n// Using the conditional operator to select output.\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  int mice {};      // Count of all mice\n  int brown {};     // Count of brown mice\n  int white {};     // Count of white mice\n\n  std::cout << \"How many brown mice do you have? \";\n  std::cin >> brown;\n  std::cout << \"How many white mice do you have? \";\n  std::cin >> white;\n  \n  if (brown < 0 || white < 0)\n  {\n    std::cout << \"One cannot have a negative amount of mice...\" << std::endl;\n    return 1;\n  }\n\n  mice = brown + white;\n\n  std::cout <<\n    std::format(\"You have {} {} in total.\\n\", mice, mice == 1 ? \"mouse\" : \"mice\");\n\n  if (mice == 1)\n  {\n    // Mind the parentheses around the conditional expression!\n    std::cout << \"It is a \" << (brown? \"brown\" : \"white\") << \" mouse.\" << std::endl;\n  }\n  else\n  {\n    // No need for parenthese around the conditional expressions here\n    std::cout << std::format(\"Of these mice, {} {} brown {}.\", \n        brown, \n        brown == 1 ? \"is a\" : \"are\", \n        brown == 1 ? \"mouse\" : \"mice\"\n    ) << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 04/Soln4_06.cpp",
    "content": "// Exercise 4-6 Finding the range for an integer. \n// This is just a question of bolting sufficient conditional operators together\n// in an expression. \n\nimport <iostream>;\nusing std::cin;\nusing std::cout;\nusing std::endl;\n\nint main()\n{\n  int n {};\n  std::cout << \"Enter an integer: \";\n  std::cin >> n;\n  \n  std::cout << \"The value is \" \n    << (n <= 20 ? \"not greater than 20\" : \n        n <= 30 ? \"greater than 20 and not greater than 30\" : \n        n <= 100? \"greater than 30 and not exceeding 100\" : \n                  \"greater than 100\")\n    << '.' << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 04/Soln4_07.cpp",
    "content": "// Exercise 4-7 Outputting the binary code for a letter.\n/*\n * Most of the program is fairly simple. \n * The cctype functions make determining upper or lower case easy. \n * Finding out if it's a vowel is also easy with a switch.\n * Only getting the binary code needs a little thought, though. \n * Each of the masks selects a different bit of the ch variable.\n * If the bit is '1', the expression will be non-zero, which is converted to Boolean true.\n * If it's '0', the whole expression will be zero, or Boolean false.\n * Ones and zeros are therefore output as appropriate.\n */\nimport <iostream>;\n\n#include <cctype>\n\nint main()\n{\n  char entered_letter {};\n  std::cout << \"Enter a letter: \";\n  std::cin >> entered_letter;\n\n  if (!std::isalpha(entered_letter)) \n  {\n    std::cout << \"That's not a letter!\" << std::endl;\n    return 1;\n  }\n\n  // We'll need the lower case letter...\n  const auto lower_case_letter{ static_cast<char>(std::tolower(entered_letter)) };\n\n  // Determine upper or lower case.\n  std::cout << \"'\" << entered_letter << \"' is \" << \n    (std::islower(entered_letter) ? \"lowercase\" : \"uppercase\") << '.' << std::endl;\n\n  // Determine whether it is a vowel or a consonant.\n  std::cout << \"'\" << entered_letter << \"' is a \";\n\n  switch (lower_case_letter)\n  {\n    case 'a': case 'e': case 'i': case 'o': case 'u':\n      std::cout << \"vowel\";\n      break;\n    default:\n      std::cout << \"consonant\";\n      break;\n  }\n  std::cout << '.' << std::endl;\n\n  // Output the character code as binary\n  std::cout << \"The binary code for '\" << lower_case_letter << \"' is \"\n     << ((lower_case_letter & 0b10000000)? 1 : 0) \n     << ((lower_case_letter & 0b01000000)? 1 : 0)\n     << ((lower_case_letter & 0b00100000)? 1 : 0) \n     << ((lower_case_letter & 0b00010000)? 1 : 0)\n     << ((lower_case_letter & 0b00001000)? 1 : 0) \n     << ((lower_case_letter & 0b00000100)? 1 : 0)\n     << ((lower_case_letter & 0b00000010)? 1 : 0) \n     << ((lower_case_letter & 0b00000001)? 1 : 0)\n     << std::endl;\n\n  return 0;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 04/Soln4_08.cpp",
    "content": "// Exercise 4-8\n// Dividing a cash amount into quarters, nickels, dimes and cents.\n\nimport <iostream>;\n\nint main()\n{\n  // Declare the constants (amounts of cents)\n  const unsigned quarter {25};\n  const unsigned dime {10};\n  const unsigned nickel {5};\n\n  double amountInDollars {0.0};\n  std::cout << std::endl << \"Please enter a cash amount between 0 and 10 dollars: $\";\n  std::cin >> amountInDollars;\n  \n  if (amountInDollars >= 0.0 && amountInDollars <= 10.0)\n  {\n    // Multiply dollar amount by 100 ($1 = 100 cents)\n    // We add 0.5 to compensate for errors in binary floating-point representation\n    auto amountInCents {static_cast<unsigned>(amountInDollars * 100.0 + 0.5)};\n\n    // Find the number of quarters\n    const auto quarters {amountInCents / quarter};\n    amountInCents %= quarter;               // Get the remainder\n\n    // Find the number of dimes\n    const auto dimes {amountInCents / dime};\n    amountInCents %= dime;                  // Get the remainder\n\n    // Find the number of nickels\n    const auto nickels {amountInCents / nickel};\n    amountInCents %= nickel;                // Get the remainder\n\n    // Find the number of pennies\n    const auto pennies {amountInCents};     // The remainder is already in pennies\n\n    std::cout << std::endl \n         << \"The dollar value $\" << amountInDollars << \" can be broken down into:\"  << std::endl\n         << quarters << \" quarter\" << (quarters == 1? \"\" : \"s\") << ',' << std::endl\n         << dimes    << \" dime\"    << (dimes    == 1? \"\" : \"s\") << ',' << std::endl\n         << nickels  << \" nickel\"  << (nickels  == 1? \"\" : \"s\") << ',' << std::endl\n         << pennies  << \" penn\"    << (pennies  == 1? \"y\" : \"ies\") << '.' << std::endl;\n  }\n  else\n  {\n    std::cout << std::endl << \"You did not enter a dollar amount between 0 and 10.\" << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 05/Soln5_01.cpp",
    "content": "// Exercise 5-1 Squaring odd numbers\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  int limit {};\n  std::cout << \"Enter the upper limit for squared odd numbers: \";\n  std::cin >> limit;\n  for (int i {1}; i <= limit; i += 2)\n  {\n    std::cout << std::format(\"{:4} squared is {:8}\\n\", i, i * i);\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 05/Soln5_02.cpp",
    "content": "// Exercise 5-2 Summing integers and calculating the average\nimport <iostream>;\nimport <format>;\n\n#include <cctype>\n\nint main()\n{\n  unsigned int count {};\n  long long total {};\n  \n  while (true)\n  {\n    std::cout << \"Enter an integer: \";\n    int n;\n    std::cin >> n;\n    total += n;\n    ++count;\n\n    char yesno {};\n    std::cout << \"Do you want to enter another (y/n)?\";\n    std::cin >> yesno;\n\n    if (std::tolower(yesno) == 'n')\n      break;\n  }\n  \n  std::cout \n    << std::format(\"The total is {}. The average is {:.2f}.\", \n                      total, static_cast<double>(total) / count) \n    << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 05/Soln5_03.cpp",
    "content": "// Exercise 5-3 Using a do-while loop to count characters\nimport <iostream>;\n\nint main()\n{\n  unsigned count {};\n  char ch {};\n\n  std::cout << \"Please enter a sequence of characters terminated by '#':\" << std::endl;\n\n  // We have to read at least one character so do-while is best\n  do\n  {\n    std::cin >> ch;\n    ++count;\n  } while (ch != '#');\n\n  // We do not count '#' as a character, so count must be adjusted\n  --count;\n  std::cout << \"You entered \" << count << \" characters (not counting spaces and the terminal #).\" << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 05/Soln5_04.cpp",
    "content": "// Exercise 5-4 Print out characters entered by the user in reverse order\nimport <iostream>;\n\nint main()\n{\n  const size_t max_num_characters {1'000};\n  char string[max_num_characters];\n\n  std::cout << \"Please enter a string: \";\n  std::cin.getline(string, max_num_characters);\n  \n  // Count the number of characters\n  size_t count {};\n  for (; count < max_num_characters && string[count] != '\\0'; ++count) {}\n\n/*\n  Take care: never write the following:\n    for (size_t i = count - 1; i >= 0; --i)\n      ...\n  Because size_t is unsigned, the loop continuation condition i >= 0 shall always and forever be true. \n  That is: every size_t value is always greater or equal to zero, by definition. \n  Subtracting one from zero wraps around to std::numeric_limits<size_t>::max(), a huge number.\n  \n  Other solutions besides the one we use below include:\n    // Cast to a signed integer (works even for count == 0!)\n    for (int i{ static_cast<int>(i) - 1 }; i != -1; --i)\n      ...\n    \n    // Subtract in second for expression (less readable, fails if count == 0)\n    for (size_t i{ count }; i-- > 0; )\n      ...\n  \n    // Use a break statement to end the loop (fails if count == 0)\n    for (size_t i{ count }; ; i--)\n    {\n      ...\n      if (i == 0) break;\n    }\n*/\n\n  // Print out the characters in reverse order\n  for (size_t i{ 1 }; i <= count; ++i)\n  {\n    std::cout << string[count - i];\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 05/Soln5_05.cpp",
    "content": "// Exercise 5-5 Print out characters entered by the user *after* reversing them\nimport <iostream>;\n\nint main()\n{\n  const size_t max_num_characters {1'000};\n  char string[max_num_characters];\n\n  std::cout << \"Please enter a string: \";\n  std::cin.getline(string, max_num_characters);\n  \n  // Count the number of characters\n  size_t count {};\n  while (count < max_num_characters && string[count] != '\\0') \n\t  ++count;\n  \n  // Reverse the characters of the string entered by the user\n  for (size_t i{ 0 }; i < count / 2; ++i)\n  {\n    char temp{ string[i] };\n    string[i] = string[count - i - 1];\n    string[count - i - 1] = temp;\n  }\n  \n  // Print out all characters, one by one\n  for (size_t i{ 0 }; i < count; ++i)\n  {\n    std::cout << string[i];\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 05/Soln5_06.cpp",
    "content": "// Exercise 5-6. Working with a vector container\nimport <iostream>;\nimport <format>;\nimport <vector>;\n\nint main()\n{\n  std::cout << \"What is the largest number I should check? \";\n  unsigned bound {};\n  std::cin >> bound;\n\n  std::vector<unsigned> values;\n  // Add element values 1 to bound\n  for (unsigned i {1}; i <= bound; ++i)\n    values.push_back(i);\n\n  size_t count {};              // Number of output values\n  size_t perline {10};          // Number output perline                 \n  for (auto value : values)\n  {\n    if (value % 7 == 0 || value % 13 == 0) continue;\n    std::cout << std::format(\"{:5}\", value);\n    if (++count % perline == 0) std::cout << \"\\n\";\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 05/Soln5_07.cpp",
    "content": "// Exercise 5-7. Outputting product records & cost\n// Getting the alignment right is tricky.\n// You have to adjust the field widths until it looks OK.\nimport <iostream>;\nimport <format>;\nimport <vector>;\n\n#include <cctype>\n\nint main()\n{\n  std::vector<size_t> product_id;\n  std::vector<size_t> quantity;\n  std::vector<double> unit_cost;\n\n  // Read the records\n  while (true)\n  {\n    std::cout << \"Enter a record - product number, quantity, unit cost separated by spaces: \";\n    size_t id {};\n    size_t n {};\n    double cost {};\n    std::cin >> id >> n >> cost;\n\n    product_id.push_back(id);\n    quantity.push_back(n);\n    unit_cost.push_back(cost);\n    \n    std::cout << \"Do you want to enter another record (Y or N): \";\n    char answer {};\n    std::cin >> answer;\n    if (std::toupper(answer) == 'N') break;\n  }\n  \n  // Column headings\n  std::cout << std::format(\"{:10} {:10} {:10} {:10}\\n\", \n    \"Product\", \"Quantity\", \"Unit Price\", \"Cost\");\n  \n  double total_cost {};\n  for (size_t i {}; i < product_id.size(); ++i)\n  {\n    const auto cost{ quantity[i] * unit_cost[i] };\n    \n    std::cout <<\n      std::format(\"{:<10} {:<10} ${:<9.2f} ${:<9.2f}\\n\",\n        product_id[i], quantity[i], unit_cost[i], cost);\n    \n    total_cost += cost;\n  }\n  // Note the little trick to add empty space...\n  std::cout << std::format(\"{:33}${:<9.2f}\\n\", \"\", total_cost);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 05/Soln5_08.cpp",
    "content": "// Exercise 5-08. Generate 93 Fibonacci numbers stored in an array.\n// Of course 93 was not an arbitrary choice for the number of Fibonacci numbers.\n// Fibonacci number grow fairly rapidly.\n// 93 is the most that are possible with type unsigned long long on most platforms.\n\nimport <iostream>;\nimport <array>;\n\n// See Appendix A (available online) for static_assert()\nstatic_assert(sizeof(unsigned long long) >= 8,\n  \"This program assumes the depth of unsigned long long is (at least) 64 bit.\");\n\nint main()\n{\n  const size_t n {93};\n  std::array<unsigned long long, n> fib;\n  fib[0] = fib[1] = 1UL;\n  for (size_t i {2}; i < n; ++i)\n    fib[i] = fib[i - 1] + fib[i - 2];\n\n  std::cout << \"The first \" << n << \" Fibonacci numbers are:\\n\";\n  for (auto number : fib)\n  {\n    std::cout << number << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 06/Soln6_01.cpp",
    "content": "// Exercise 6-1. Storing odd numbers in an array and accessing them using pointer notation\n\n/* Note that the use of pointer notation is just for the sake of the exercise,           *\n * to help you understand the intimate relation between pointers and array names.        *\n * In real code, you'd normally just use array notation, because it is that much easier. */\n\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  const size_t n {50};\n  size_t odds[n];\n  for (size_t i {}; i < n; ++i)\n    odds[i] = i * 2 + 1;\n\n  const size_t perline {10};\n  std::cout << \"The \" << n << \" first odd numbers are:\\n\";\n  for (size_t i {}; i < n; ++i)\n  {\n    std::cout << std::format(\"{:5}\", *(odds + i));\n    if ((i + 1) % perline == 0)                        // Uses the loop counter to decide when a newline is required\n      std::cout << std::endl;\n  }\n\n  std::cout << \"\\nIn reverse order these numbers are:\\n\";\n  for (int i {n - 1}; i >= 0; --i)                     // This won't work with size_t for the loop counter\n  {                                                    // because size_t cannot be negative\n    std::cout << std::format(\"{:5}\", *(odds + i));\n    if (i % perline == 0)\n      std::cout << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 06/Soln6_02.cpp",
    "content": "// Exercise 6-2. Traversing arrays using pointer arithmetics\n// An exercise to further deepen your understanding of the relation \n// between pointers, pointer arithmetic, and arrays.\n\nimport <iostream>;\nimport <format>;\n\nint main()\n{\n  const size_t n {50};\n  size_t odds[n];\n  for (size_t i {}; i < n; ++i)\n    odds[i] = i * 2 + 1;\n\n  const size_t perline {10};\n  std::cout << \"The \" << n << \" first odd numbers are:\\n\";\n  \n  size_t* traversal_pointer{ odds };\n  for (size_t i {}; i < n; ++i)\n  {\n    std::cout << std::format(\"{:5}\", *traversal_pointer++);\n    if ((i + 1) % perline == 0)      // Uses the loop counter to decide when a newline is required\n      std::cout << std::endl;\n  }\n\n  std::cout << \"\\nIn reverse order these numbers are:\\n\";\n  for (size_t i {}; i < n; ++i)      // No need to reverse the manipulation of the loop counter now\n  {\n    std::cout << std::format(\"{:5}\", *(--traversal_pointer)); // Use the pre-decrement operator to make sure the pointer is decremented\n    if ((i + 1) % perline == 0)                               // before it is dereferenced (at the start of this loop, \n      std::cout << std::endl;                                 // the pointer points one passed the last element of the odds array)\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 06/Soln6_03.cpp",
    "content": "// Exercise 6-3. Storing numbers in a dynamic array\n// Btw: notice anything about the result? \n// Try increasing numbers of array elements...\nimport <iostream>;\nimport <format>;\n\n#include <cmath>\n\nint main()\n{\n  size_t n {};\n  std::cout << \"Enter the number of array elements: \";\n  std::cin >> n;\n  auto* values{ new double[n] };\n  for (size_t i {}; i < n; ++i)\n    *(values+i) = 1.0 / ((i + 1)*(i + 1));\n\n  double sum {};\n  for (size_t i {}; i < n; ++i)\n    sum += values[i];\n\n  std::cout << std::format(\"The result is {}\", std::sqrt(6.0 * sum)) << std::endl;\n  \n  delete[] values;   // Don't forget to free the memory!\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 06/Soln6_04.cpp",
    "content": "// Exercise 6-4. Storing numbers in a vector\n\n/*\n * The result is an approximate value for pi. \n * The more values you use, the closer it becomes to pi.\n * In technical speak, this approximation does not converge to pi very fast though,\n * which basically means that you'll need quite some values \n * if you want to approximate pi beyond its first few digits.\n *\n * We must dereference values to use it with the subscript operator\n * because it is not a vector but a pointer to a vector.\n * \n * Note that allocating a vector<> like this in the free store is not often done.\n * Dynamic allocation is mostly reserved for objects of other class types,\n * in particular polymorphic ones. You'll learn all about this in later chapters!\n */\n\nimport <iostream>;\nimport <format>;\nimport <vector>;\n\n#include <cmath>\n\nint main()\n{\n  size_t n {};\n  std::cout << \"Enter the number of vector elements: \";\n  std::cin >> n;\n  auto* values{ new std::vector<double>(n) };\n\n  for (size_t i {}; i < n; ++i)\n    (*values)[i] = 1.0 / ((i + 1)*(i + 1));\n  \n  double sum {};\n  for (auto value : *values)\n    sum += value;\n\n  std::cout << std::format(\"Result is {}\", std::sqrt(6.0*sum)) << std::endl;\n  \n  delete values;                                              // It's not an array this time!\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 06/Soln6_05.cpp",
    "content": "// Exercise 6-5. Managing a dynamic array using a smart pointer\n// You can no longer use pointer notation now!\n// (You could, technically, call get() first and then use pointer notation,\n// though why make the syntax even more convoluted: just use array notation!)\n\nimport <iostream>;\nimport <format>;\nimport <memory>;\n\n#include <cmath>\n\nint main()\n{\n  size_t n {};\n  std::cout << \"Enter the number of array elements: \";\n  std::cin >> n;\n  auto values{ std::make_unique<double[]>(n) };\n  for (size_t i {}; i < n; ++i)\n    values[i] = 1.0 / ((i + 1)*(i + 1));\n\n  double sum {};\n  for (size_t i {}; i < n; ++i)\n    sum += values[i];\n\n  std::cout << std::format(\"The result is {}\", std::sqrt(6.0 * sum)) << std::endl;\n  \n  // No need to deallocate the memory yourself anymore: the smart pointer takes care of that for you!\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 06/Soln6_06.cpp",
    "content": "// Exercise 6-6. Storing a dynamically allocated vector in a smart pointer\n\nimport <iostream>;\nimport <format>;\nimport <vector>;\nimport <memory>;\n\n#include <cmath>\n\nint main()\n{\n  size_t n {};\n  std::cout << \"Enter the number of vector elements: \";\n  std::cin >> n;\n  auto values{ std::make_unique<std::vector<double>>(n) };\n\n  for (size_t i {}; i < n; ++i)\n    (*values)[i] = 1.0 / ((i + 1)*(i + 1));\n  \n  double sum {};\n  for (auto value : *values)\n    sum += value;\n\n  std::cout << std::format(\"Result is {}\", std::sqrt(6.0*sum)) << std::endl;\n  \n  // No need to deallocate the memory yourself anymore: the smart pointer takes care of that for you!\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 08/Soln8_01.cpp",
    "content": "// Exercise 8-1 Reading  and validating a date of birth. \n// As always, there are many ways of doing this!\nimport <iostream>;\nimport <format>;\nimport <string>;\n\nint validate_input(int lower, int upper, const std::string& description);\nint year();\nint month();\nint date(int month_value, int year_value);\nstd::string ending(int date_day);\n\nint main()\n{\n  std::cout << \"Enter your date of birth.\" << std::endl;\n  int date_year {year()};\n  int date_month {month()};\n  int date_day {date(date_month, date_year)};\n\n  std::string months[]  {\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\",\n                         \"August\", \"September\", \"October\", \"November\", \"December\"  };\n\n  std::cout << std::endl;\n  std::cout << \n    std::format(\"You were born on the {} of {}, {}.\", \n      std::to_string(date_day) + ending(date_day), \n      months[date_month - 1], \n      date_year\n    ) << std::endl;\n}\n\n// Reads an integer that is between lower and upper inclusive\nint validate_input(int lower, int upper, const std::string& description)\n{\n  int data {};\n  std::cout << std::format(\"Please enter {} from {} to {}: \", description, lower, upper);\n  std::cin >> data;\n  while (data < lower || data > upper)\n  {\n    std::cout << \"Invalid entry; please re-enter \" << description << \": \";\n    std::cin >> data;\n  }\n  return data;\n}\n\n// Reads the year\nint year()\n{\n  const int low_year {1870};         // Program only works for folks under 150 years old \n  const int high_year {2020};        // and those already born...\n  return validate_input(low_year, high_year, \"a year\");\n}\n\n// Reads the month\nint month()\n{\n  const int low_month {1};\n  const int high_month {12};\n  return validate_input(low_month, high_month, \"a month number\");\n}\n\n// Reads in the date in the given month and year\nint date(int month_number, int year)\n{\n  const int date_min {1};\n  const int feb {2};\n\n  // Days in month:            Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec\n  static const int date_max[]  {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};\n  // With the above array declared as static, it will only be created the first\n  // time the function is called. Of course, this doesn't save anything in this \n  // example as we only call it once...\n\n  // Feb has 29 days in a leap year. A leap year is a year that is divible by 4\n  // except years that are divisible by 100 but not divisible by 400\n  if (month_number == feb && year % 4 == 0 && !(year % 100 == 0 && year % 400 != 0))\n    return validate_input(date_min, 29, \"a date\");\n  else\n    return validate_input(date_min, date_max[month_number - 1], \"a date\");\n}\n\n// Select the ending of the ordinal day number\nstd::string ending(int date_day)\n{\n  if (date_day == 1 || date_day == 21 || date_day == 31)\n    return \"st\";\n  else if (date_day == 2 || date_day == 22)\n    return \"nd\";\n  else if (date_day == 3 || date_day == 23)\n    return \"rd\";\n  else\n    return \"th\";\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 08/Soln8_02.cpp",
    "content": "// Exercise 8-2 Reversing the order of a string of characters. \n/******************************************************************\nThe reverse() function works with an argument of type string, or a\nC-style string terminated with '\\0'.\n*******************************************************************/\nimport <iostream>;\nimport <string>;\n\nstd::string reverse(std::string str);\n\nint main()\n{\n  std::string sentence;\n  std::cout << \"Enter a sequence of characters, then press 'Enter': \" << std::endl;\n  getline(std::cin, sentence);\n\n  std::cout << \"\\nYour sequence in reverse order is:\\n\";\n  std::cout << reverse(sentence) << std::endl;\n\n  std::cout << \"\\nHere is a demonstration of reverse() working with a C-style string:\\n\";\n\n  char stuff[] {\"abcdefg\"};                      // C-style string\n  std::cout << \"\\nThe original string is: \\\"\" << stuff << \"\\\"\"\n            << \"\\nReversed it becomes: \\\"\" << reverse(stuff) << \"\\\"\" << std::endl;\n}\n\n// Reverse a string in place\n// The code here is working with a copy of the argument\n// so the original is not affected.\nstd::string reverse(std::string str)\n{\n  const size_t length {str.length()};\n  for (size_t i {}; i < length / 2; ++i)\n  {\n    char temp = str[i];\n    str[i] = str[length - i - 1];\n    str[length - i - 1] = temp;\n  }\n  return str;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 08/Soln8_03.cpp",
    "content": "// Exercise 8_3 Checking the number of arguments entered at the command line. \nimport <iostream>;\n\nint main(int numArguments, char* arguments[])\n{\n  switch (numArguments - 1)\n  {\n  case 2: case 3: case 4:\n    for (size_t i {1}; i < numArguments; ++i)\n      std::cout << \"Argument \" << i << \" is \" << arguments[i] << std::endl;\n    break;\n  default:\n    std::cout << \"You entered the incorrect number of arguments.\\n\"\n              << \"Please enter 2, 3 or 4 arguments. \" << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 08/Soln8_04.cpp",
    "content": "// Exercise 8_4 An overloaded plus() function. \nimport <iostream>;\nimport <string>;\n\nint plus(int a, int b);\ndouble plus(double x, double y);\nstd::string plus(const std::string& s1, const std::string& s2);\n\nint main()\n{\n  const int n {plus(3, 4)};\n  std::cout << \"plus(3, 4) returns \" << n << std::endl;\n  \n  const double d {plus(3.2, 4.2)};\n  std::cout << \"plus(3.2, 4.2) returns \" << d << std::endl;\n  \n  const std::string s {plus(\"he\", \"llo\")};\n  std::cout << \"plus(\\\"he\\\", \\\"llo\\\") returns \" << s << std::endl;\n  \n  const std::string s1 {\"aaa\"};\n  const std::string s2 {\"bbb\"};\n  const std::string s3 {plus(s1, s2)};\n  std::cout << \"With s1 as \" << s1 << \" and s2 as \" << s2 << std::endl;\n  std::cout << \"plus(s1, s2) returns \" << s3 << std::endl;\n\n  /*\n  const auto d {plus(3, 4.2)};\n  This won't compile because there is more than one overloaded plus() function for the arguments.\n  The compiler will not choose so there must be a unique match with a function signature.\n  */\n}\n\n// Adding integer values\nint plus(int a, int b)\n{\n  return a + b;\n}\n\n// Adding floating-point values\ndouble plus(double x, double y)\n{\n  return x + y;\n}\n\n// Adding strings\nstd::string plus(const std::string& s1, const std::string& s2)\n{\n  return s1 + s2;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 08/Soln8_05.cpp",
    "content": "// Exercise 8_5 Listing prime numbers\nimport <iostream>;\nimport <format>;\nimport <vector>;\n\n#include <cmath>    // for std::sqrt()\n\nbool isPrime(unsigned number);\n\n// Option 1: return vector<>\n// Remember: starting with C++11, returning a vector is efficient. \n// In modern C++, this is therefore the recommended approach.\nstd::vector<unsigned> generateNumbers(unsigned to, unsigned from = 1);\nstd::vector<unsigned> filterPrimeNumbers(const std::vector<unsigned>& numbers);\n\n/* \n// Option 2: vector<> output variables (not implemented)\n// This is the traditional approach. \n// In modern C++, returning using return value is recommended.\nvoid generateNumbers(std::vector<unsigned>& output, unsigned to, unsigned from = 1);\nvoid filterPrimeNumbers(std::vector<unsigned>& output, const std::vector<unsigned>& numbers);\n*/\n\nint main()\n{\n  unsigned user_number{};\n  std::cout << \"Would you be so kind as to enter a number? \" << std::endl;\n  std::cin >> user_number;\n  \n  const auto numbers{ generateNumbers(user_number) };\n  const auto primes{ filterPrimeNumbers(numbers) };\n  \n  unsigned count{};\n  for (auto& prime : primes)\n  {\n    std::cout << std::format(\"{:6}\", prime);\n    if (++count % 15 == 0)\n      std::cout << '\\n';\n  }\n  \n  std::cout << std::endl;\n}\n\n/* \n  The sqrt() in the for loop below is not required. \n  The following loop would be equally correct, just a bit slower:\n  \n  for (unsigned i = 2; i < number; ++i)\n  {\n    ...\n  }\n  \n  It is a quite common optimisation though to stop testing at \n  the square root of the number. Think about why this is correct!\n*/\nbool isPrime(unsigned number)\n{\n  // a prime number is a natural number strictly greater than 1...\n  if (number <= 1) return false;\n  \n  // ...and with no positive divisors other than 1 and itself\n  for (unsigned i{ 2 }; i < std::sqrt(number); ++i)\n  {\n    if (number % i == 0)\n    {\n      return false;\n    }\n  }\n  \n  return true;\n}\n\nstd::vector<unsigned> generateNumbers(unsigned to, unsigned from)\n{\n  std::vector<unsigned> result;\n  result.reserve(to - from + 1);\n  for (unsigned i{ from }; i <= to; ++i)\n    result.push_back(i);\n  return result;\n}\n\nstd::vector<unsigned> filterPrimeNumbers(const std::vector<unsigned>& numbers)\n{\n  std::vector<unsigned> result;\n  for (auto number : numbers)\n  {\n    if (isPrime(number))\n      result.push_back(number);\n  }\n  return result;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 08/Soln8_06.cpp",
    "content": "// Exercise 8_6 Computing grade statistics\n/*\n  This is a bigger excercise, and thus many variations will be valid and correct.\n  The focus here isn't on performance, it's on writing and calling functions.\n  Main thing is that you:\n    (1) got the parameter types right---mostly pass-by-reference-to-const \n        for the input parameters, except for sort() which modifies its argument.\n    (2) made sure that the program does something correctly for empty grade lists,\n        small grade lists (< 5 values), and for grade lists of both odd and even size.\n  \n  Some things worth noticing in our solution:\n    - we overloaded the recursive sort() function by adding a helper function \n      that users can call without having to know what the second and third parameters are,\n      and without having to think about the empty input case. \n      This is common with recursive algorithms: the interface that users use \n      will often not contain the actual recursive function.\n    - we defined NOT_AVAILABLE equal to std::numeric_limits<unsigned>::max() \n      (equivalent to static_cast<unsigned>(-1))\n      to encode missing values in case there are less than 5 inputs,\n      and used NaN values elsewhere in case the user enters no value at all.\n      Other solutions for the former could've been signed values,\n      or in fact any number larger than 100.\n      In Chapter 9 you will learn about std::optional<>\n      which allows you to handle such \"not available\" or \"undefined\" cases more elegantly, though.\n*/\nimport <iostream>;\nimport <vector>;\nimport <string>;\nimport <limits>;    // for std::numeric_limits's max() and quiet_nan()\n\n#include <cmath>    // for std::sqrt() and std::isnan()\n\nvoid sort(std::vector<unsigned>& numbers);\n\nvoid getHighest(const std::vector<unsigned>& sortedNumbers, unsigned(&highest)[5]);\nvoid getLowest(const std::vector<unsigned>& sortedNumbers, unsigned(&lowest)[5]);\n\ndouble computeAverage(const std::vector<unsigned>& numbers);\ndouble computeMedian(const std::vector<unsigned>& numbers);\ndouble computeStandardDeviation(const std::vector<unsigned>& numbers);\ndouble computeVariance(const std::vector<unsigned>& numbers);\n\nvoid printNumber(const std::string& label, double number);\nvoid printNumbers(const std::string& label, const unsigned(&numbers)[5]);\n\nconst unsigned NOT_AVAILABLE = std::numeric_limits<unsigned>::max();\n\nint main()\n{\n  std::vector<unsigned> grades;\n\n  std::cout << \"Please enter a number of grades (0-100), terminated by a negative one:\" << std::endl;\n  while (true)\n  {\n    int number{};\n    std::cin >> number;\n    if (number < 0)\n      break;\n    else if (number > 100)\n      std::cout << \"Only numbers < 100, please...\" << std::endl;\n    else\n      grades.push_back(number);\n  }\n\n  sort(grades);\n\n  // Note: thruth be told, this is based on an old solution.\n  // It would be better and/or easier \n  //    a) to use std::array<> instead of C-style arrays; and\n  //    b) to return the values requested rather than using output parameters\n  // Perhaps you can improve our solution accordingly?\n  unsigned highest[5]{};\n  unsigned lowest[5]{};\n\n  getHighest(grades, highest);\n  getLowest(grades, lowest);\n\n  printNumbers(\"Five highest grades\", highest);\n  printNumbers(\"Five lowest grades\", lowest);\n  printNumber(\"The grade average\", computeAverage(grades));\n  printNumber(\"The median grade\", computeMedian(grades));\n  printNumber(\"The standard deviation of the grades\", computeStandardDeviation(grades));\n  printNumber(\"The variance of the grades\", computeVariance(grades));\n}\n\n// Swap numbers at position first with address at position second\nvoid swap(std::vector<unsigned>& numbers, size_t first, size_t second)\n{\n  auto temp{ numbers[first] };\n  numbers[first] = numbers[second];\n  numbers[second] = temp;\n}\n\n// Recursive helper function to sort numbers in ascending sequence\n// Numbers to be sorted are from words[start] to words[end]\nvoid sort(std::vector<unsigned>& numbers, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle of the [start, end] range to partition\n  swap(numbers, start, (start + end) / 2); // Swap middle number with start\n\n  // Check values against chosen word\n  size_t current{ start };\n  for (size_t i{ start + 1 }; i <= end; i++)\n  {\n    if (numbers[i] < numbers[start])   // Is word less than chosen value?\n      swap(numbers, ++current, i);     // Yes, so swap to the left\n  }\n\n  swap(numbers, start, current);       // Swap the chosen value with the last swapped number\n\n  if (current > start) sort(numbers, start, current - 1);  // Sort left subset if exists\n  if (end > current + 1) sort(numbers, current + 1, end);  // Sort right subset if exists\n}\n\n// Sort numbers in ascending sequence\nvoid sort(std::vector<unsigned>& numbers)\n{\n  if (!numbers.empty())\n    sort(numbers, 0, numbers.size() - 1);\n}\n\nvoid getHighest(const std::vector<unsigned>& sortedNumbers, unsigned(&highest)[5])\n{\n  const auto numHighest{ static_cast<int>(std::size(highest)) };\n\n  for (int i{}; i < numHighest; ++i)\n  {\n    const int numberIndex{ static_cast<int>(sortedNumbers.size()) - numHighest + i };\n    if (numberIndex >= 0)\n      highest[i] = sortedNumbers[numberIndex];\n    else\n      highest[i] = NOT_AVAILABLE;\n  }\n}\n\nvoid getLowest(const std::vector<unsigned>& sortedNumbers, unsigned(&lowest)[5])\n{\n  for (size_t i{}; i < std::size(lowest); ++i)\n  {\n    if (i < sortedNumbers.size())\n      lowest[i] = sortedNumbers[i];\n    else\n      lowest[i] = NOT_AVAILABLE;\n  }\n}\n\ndouble computeAverage(const std::vector<unsigned>& numbers)\n{\n  if (numbers.empty())\n    return std::numeric_limits<double>::quiet_NaN();\n\n  double average{};\n  for (auto& number : numbers)\n    average += number;\n  return average / numbers.size();\n}\n\ndouble computeMedian(const std::vector<unsigned>& numbers)\n{\n  if (numbers.empty())\n    return std::numeric_limits<double>::quiet_NaN();\n\n  const auto numNumbers{ numbers.size() };\n  const auto middleIndex{ numNumbers / 2 };\n  if (numNumbers % 2)\n  {\n    return numbers[middleIndex];\n  }\n  else\n  {\n    return (numbers[middleIndex] + numbers[middleIndex - 1]) / 2.0;\n  }\n}\n\ndouble computeStandardDeviation(const std::vector<unsigned>& numbers)\n{\n  if (numbers.empty())\n    return std::numeric_limits<double>::quiet_NaN();\n\n  const double average{ computeAverage(numbers) };\n  double sum{};\n  for (auto& number : numbers)\n    sum += (number - average) * (number - average);\n  return std::sqrt(sum / numbers.size());\n}\n\ndouble computeVariance(const std::vector<unsigned>& numbers)\n{\n  if (numbers.empty())\n    return std::numeric_limits<double>::quiet_NaN();\n\n  const double standardDeviation{ computeStandardDeviation(numbers) };\n  return standardDeviation * standardDeviation;\n}\n\nvoid printNumber(const std::string& label, double number)\n{\n  std::cout << label << \": \";\n\n  if (std::isnan(number))\n    std::cout << \"n/a\";\n  else\n    std::cout << number;\n\n  std::cout << std::endl;\n}\n\nvoid printNumbers(const std::string& label, const unsigned(&numbers)[5])\n{\n  std::cout << label << \": \";\n\n  for (const auto number : numbers)\n  {\n    if (number != NOT_AVAILABLE)\n      std::cout << number << ' ';\n  }\n\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 08/Soln8_07.cpp",
    "content": "// Exercise 8-7 Computing Fibinacci numbers recursively. \n// Main thing to realise is that the recursion needs two base cases.\n// Key is also to use unsigned values (function would fail for negative numbers)\n// and not to forget about zero either (using n == 1 and n == 2 as base cases \n// would mean trouble if n == 0 is passed)\nimport <iostream>;\n\nunsigned long long fib(size_t n);\n\nint main()\n{\n  size_t num{};\n  std::cout << \"Good day, master. How many Fibonacci numbers shall I compute today?\" << std::endl;\n  std::cin >> num;\n  \n  for (size_t i{1}; i <= num; ++i)\n     std::cout << \"fib(\" << i << \") = \" << fib(i) << '\\n';\n}\n\nunsigned long long fib(size_t n)\n{\n  switch (n)\n  {\n    case 0:  return 0;\n    case 1:  return 1;\n    default: return fib(n-2) + fib(n-1);\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 08/Soln8_07A.cpp",
    "content": "// Exercise 8-7 Computing Fibinacci numbers iteratively. \n// On most systems (it depends on sizeof(unsigned long long)),\n// you can correctly compute up to 93 Fibonacci numbers with this program.\nimport <iostream>;\n\nunsigned long long fib(size_t n);\n\nint main()\n{\n  size_t num{};\n  std::cout << \"Good day, master. How many Fibonacci numbers shall I compute today?\" << std::endl;\n  std::cin >> num;\n  \n  for (size_t i{1}; i <= num; ++i)\n     std::cout << \"fib(\" << i << \") = \" << fib(i) << '\\n';\n}\n\nunsigned long long fib(size_t n)\n{\n\t// Initialise fib(i) and fib(i+1) for the first iteration of the loop where i == 0\n\tunsigned long long fib_i{0};         // fib(i)   = fib(0) = 0\n\tunsigned long long fib_i_1{1};       // fib(i+1) = fib(1) = 1\n\t\n\tfor (size_t i{}; i < n; ++i)\n\t{\n\t\tauto fib_i_2{ fib_i + fib_i_1 };   // fib(i+2) = fib(i) + fib(i+1)\n\t\t\n\t\t// Get ready for the next iteration (mind the order!):\n\t\tfib_i   = fib_i_1;\n\t\tfib_i_1 = fib_i_2;\n\t}\n\t\n\t// At the end of the loop, i was equal to n, so fib(i) == fib(n), which is what we needed\n\treturn fib_i;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 08/Soln8_08.cpp",
    "content": "// Exercise 8_8 More efficient recursive version of function for x to the power n, n positive or negative\n// Based on Ex8_17.cpp\nimport <iostream>;\nimport <iomanip>;\n\nlong double power(double x, int n);\n\nint main()\n{\n  for (int i {-3}; i <= 3; ++i)     // Calculate powers of 8 from -3 to +3\n    std::cout << std::setw(10) << power(8.0, i);\n\n  std::cout << std::endl;\n}\n\n// Recursive function to calculate x to the power n\nlong double power(double x, int n)\n{\n  if (n == 0)     return 1.0;\n  else if (n < 0) return 1.0 / power(x, -n);\n  else if (n % 2) return x * power(x, n - 1);     // n is odd\n  \n  // If we make it this far, n > 0 and even\n  const auto y{ power(x, n / 2) };\n  return y * y;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 08/Soln8_09.cpp",
    "content": "// Exercise 8_9 Count the number of multiplications performed by \n// the divide and conquer power() function of Soln8_08.cpp\nimport <iostream>;\nimport <iomanip>;\n\nlong double power(double x, int n);\n\nint main()\n{\n  std::cout << power(1.5, 1000) << std::endl;\n}\n\ninline auto mult(long double l, long double r)\n{\n  static size_t count{};\n  std::cout << ++count << \" multiplications\" << std::endl;\n  return l * r;\n}\n\n// Recursive function to calculate x to the power n\nlong double power(double x, int n)\n{\n  if (n == 0)     return 1.0;\n  else if (n < 0) return 1.0 / power(x, -n);\n  else if (n % 2) return mult(x, power(x, n - 1));     // x is odd\n  \n  // If we make it this far, x > 0 and even\n  const auto y{ power(x, n / 2) };\n  return mult(y, y);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 09/Soln9_01.cpp",
    "content": "// Exercise 9-1 Working with std::string_view<>\nimport <optional>;     // std::optional<> is defined in the <optional> module\nimport <iostream>;\nimport <string_view>;\n\nstd::optional<size_t> find_last(\n  std::string_view string, char to_find,\n  std::optional<size_t> start_index = std::nullopt); // or: ... start_index = {});\n\nint main()\n{\n  const auto string{ \"Growing old is mandatory; growing up is optional.\" };\n\n  const std::optional<size_t> found_a{ find_last(string, 'a') };\n  if (found_a)\n    std::cout << \"Found the last a at index \" << *found_a << std::endl;\n\n  const auto found_b{ find_last(string, 'b') };\n  if (found_b.has_value())\n    std::cout << \"Found the last b at index \" << found_b.value() << std::endl;\n\n  // following line gives an error (cannot convert std::optional<size_t> to size_t)\n  // const size_t found_c{ find_last(string, 'c') }; \n\n  const auto found_early_i{ find_last(string, 'i', 10) };\n  if (found_early_i != std::nullopt)\n    std::cout << \"Found an early i at index \" << *found_early_i << std::endl;\n}\n\nstd::optional<size_t> find_last(std::string_view string, char to_find,\n  std::optional<size_t> start_index)\n{\n  // code below will not work for empty strings  \n  if (string.empty())\n    return std::nullopt;         // or: 'return std::optional<size_t>{};'\n                                 // or: 'return {};'\n  // determine the starting index for the loop that follows:\n  size_t index{ start_index.value_or(string.size() - 1) };\n\n  while (true)  // never use while (index >= 0) here, as size_t is always >= 0!\n  {\n    if (string[index] == to_find) return index;\n    if (index == 0) return std::nullopt;\n    --index;\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 09/Soln9_02.cpp",
    "content": "// Exercise 9-2 Working with std::string_view<> and std::span<>\nimport <iostream>;\nimport <format>;\nimport <string_view>;\nimport <span>;\n\n// The function prototype including defaults for parameters\nvoid show_data(\n  std::span<const int> data,\n  std::string_view title = \"Data Values\",\n  size_t width = 10, size_t perLine = 5);\n\n// Extra overload to output a single value (.\nvoid show_data(\n  int data,\n  std::string_view title = \"Data Values\",\n  size_t width = 10);\n\nint main()\n{\n  int samples[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };\n\n  int dataItem{ -99 };\n  show_data({ &dataItem, 1 });  // Call original function directly\n\n  dataItem = 13;\n  show_data(dataItem, \"Unlucky for some!\"); // Use extra overload\n\n  show_data(samples);\n  show_data(samples, \"Samples\");\n  show_data(samples, \"Samples\", 6);\n  show_data(samples, \"Samples\", 8, 4);\n}\n\nvoid show_data(\n  std::span<const int> data, \n  std::string_view title,\n  size_t width, size_t perLine)\n{\n  std::cout << title << std::endl;    // Display the title\n\n  // Output the data values\n  for (size_t i{}; i < data.size(); ++i)\n  {\n    std::cout << std::format(\"{:{}}\", data[i], width); // Display a data item\n    if ((i + 1) % perLine == 0)                        // Newline after perLine values\n      std::cout << '\\n';\n  }\n  std::cout << std::endl;\n}\n\nvoid show_data(int data, std::string_view title, size_t width)\n{\n  show_data({ &data, 1 }, title, width);\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 09/Soln9_03.cpp",
    "content": "// Exercise 9.3. Using vocabulary types \n// Your solution should use all types you learned about in Chapter 9!\nimport <iostream>;\nimport <format>;\nimport <string_view>;\nimport <span>;\nimport <optional>;\n\nvoid show_data(std::span<const double> data, \n               std::string_view title = \"Data Values\",\n               size_t width = 10, size_t perLine = 5);\nstd::optional<double> largest(std::span<const double> data);\nstd::optional<double> smallest(std::span<const double> data);\nstd::span<double> shift_range(std::span<double> data, double delta);\nstd::span<double> scale_range(std::span<double> data, double divisor);\nstd::span<double> normalize_range(std::span<double> data);\n\nint main()\n{\n  double samples[] {\n                     11.0,  23.0,  13.0,  4.0,\n                     57.0,  36.0, 317.0, 88.0,\n                      9.0, 100.0, 121.0, 12.0\n                   };\n\n  show_data(samples, \"Original Values\");        // Output original values\n  normalize_range(samples);                     // Normalize the values\n  show_data(samples, \"Normalized Values\", 12);  // Output normalized values\n}\n\n// Outputs an array of double values\nvoid show_data(std::span<const double> data,\n               std::string_view title, size_t width, size_t perLine)\n{\n  std::cout << title << std::endl;  // Display the title\n\n  // Output the data values\n  for (size_t i {}; i < data.size(); ++i)\n  {\n    // Display a data item (uses a dynamic field width: see Chapter 7)\n    std::cout << std::format(\"{:{}.6g}\", data[i], width); \n    if ((i + 1) % perLine == 0)     // Newline after perLine values\n      std::cout << '\\n';\n  }\n  std::cout << std::endl;\n}\n\nstd::optional<double> smallest(std::span<const double> data)\n{\n  if (data.empty()) return {};     // There is no smallest in an empty sequence\n\n  size_t index_min {};\n  for (size_t i {1}; i < data.size(); ++i)\n    if (data[index_min] > data[i])\n      index_min = i;\n\n  return data[index_min];\n}\n\nstd::span<double> shift_range(std::span<double> data, double delta)\n{\n  for (size_t i {}; i < data.size(); ++i)\n    data[i] += delta;\n  return data;\n}\n\nstd::optional<double> largest(std::span<const double> data)\n{\n  if (data.empty()) return {};    // There is no largest in an empty array\n\n  size_t index_max {};\n  for (size_t i {1}; i < data.size(); ++i)\n    if (data[index_max] < data[i])\n      index_max = i;\n\n  return data[index_max];\n}\n\nstd::span<double> scale_range(std::span<double> data, double divisor)\n{\n  if (!divisor) return data;     // Do nothing for a zero divisor\n\n  for (size_t i{}; i < data.size(); ++i)\n    data[i] /= divisor;\n  return data;\n}\n\nstd::span<double> normalize_range(std::span<double> data)\n{\n  shift_range(data, -(*smallest(data)));\n  return scale_range(data, *largest(data));\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 09/Soln9_04.cpp",
    "content": "// Exercise 9-4. Using std::optional<>\nimport <iostream>;\nimport <string>;\nimport <vector>;\nimport <array>;\nimport <span>;\nimport <optional>;\n\n// Function prototypes\nstd::optional<double> largest(std::span<const double> data);\nstd::optional<int> largest(std::span<const int> data);\nstd::optional<std::string> largest(std::span<const std::string> words);\n\nint main()\n{\n  const double array[]{ 1.5, 44.6, 13.7, 21.2, 6.7 };\n  const std::vector numbers{ 15, 44, 13, 21, 6, 8, 5, 2 };\n  const std::vector data{ 3.5, 5.0, 6.0, -1.2, 8.7, 6.4 };\n  const std::array array_data{ 3.5, 5.0, 6.0, -1.2, 8.7, 6.4 }; // Throwing in an std::array for good measure\n  const std::vector<std::string> names{ \"Charles Dickens\", \"Emily Bronte\",\n                                  \"Jane Austen\", \"Henry James\", \"Arthur Miller\" };\n  std::cout << \"The largest of array is \" << *largest(array) << std::endl;            // Crashes if nullopt is returned\n  std::cout << \"The largest of numbers is \" << largest(numbers).value() << std::endl; // Throws exception (see Chapter 16) for nullopt\n  std::cout << \"The largest of data is \" << largest(data).value() << std::endl;\n  std::cout << \"The largest of array_data is (also) \" << *largest(array_data) << std::endl;\n  std::cout << \"The largest of names is \" << largest(names).value_or(\"<null>\") << std::endl;\n}\n\n// Finds the largest of a span of values\nstd::optional<double> largest(std::span<const double> data)\n{\n  if (data.empty()) return {};  // Or return std::nullopt;\n\n  double max{ data[0] };\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of int values\nstd::optional<int> largest(std::span<const int> data)\n{\n  if (data.empty()) return {};  // Or return std::nullopt;\n\n  int max{ data[0] };\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of string objects\nstd::optional<std::string> largest(std::span<const std::string> words)\n{\n  if (words.empty()) return {};  // Or return std::nullopt;\n\n  std::string max_word{ words[0] };\n  for (const auto& word : words)\n    if (max_word < word) max_word = word;\n  return max_word;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 09/Soln9_05.cpp",
    "content": "// Exercise 9-5. Using fixed-size std::span<>\nimport <iostream>;\nimport <span>;\n\ndouble average10(std::span<const double, 10> data);        // Function prototype\n\nint main()\n{\n  double values[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\n  // double values[]{ 1.0, 2.0, 3.0 };           // Only three values!!!\n  std::cout << \"Average = \" << average10(values) << std::endl;\n}\n\n// Function to compute an average\ndouble average10(std::span<const double, 10> data)\n{\n  double sum{};               // Accumulate total in here\n  for (double val : data)\n    sum += val;               // Sum array elements\n  return sum / data.size();   // Return average\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 09/Soln9_06.cpp",
    "content": "// Exercise 9-6. Passing a vector to a fixed-size std::span<>\nimport <iostream>;\nimport <vector>;\nimport <span>;\n\ndouble average10(std::span<const double, 10> data);        // Function prototype\n\nint main()\n{\n  std::vector values { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\n  // double values[]{ 1.0, 2.0, 3.0 };           // Only three values!!!\n  std::cout << \"Average = \" \n    << average10(std::span<const double, 10>{ values.data(), values.size() }) << std::endl;\n}\n\n// Function to compute an average\ndouble average10(std::span<const double, 10> data)\n{\n  double sum{};               // Accumulate total in here\n  for (double val : data)\n    sum += val;               // Sum array elements\n  return sum / data.size();   // Return average\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 10/Soln10_01.cpp",
    "content": "// Exercise 10-1.cpp\n// Create a function template for my_clamp(), \n// a template that produces functions to clamp values to a given interval.\n// Different variations are possible, but we opted for the same as in the Standard Library:\n// namely one where all three arguments are of the same type, and passed by reference-to-const.\nimport <iostream>;\nimport <format>;\nimport <string>;\n\n/*\n  Caution: the actual std::clamp() function uses a different argument order.\n  Where the exercise suggests:\n    my_clamp(value, low, high)\n  but for the Standard Library function the order is as follows:\n    std::clamp(low, value, high)\n  This solution does as instructed, but keep this in mind if ever using std::clamp()!\n */\n\ntemplate<typename T> \nconst T& my_clamp(const T& value, const T& low, const T& high);    // Function template prototype\n\nint main() \n{\n  std::cout << \"2.0 clamped to interval [1.5, 2.5] is \" << my_clamp(2.0, 1.5, 2.5) << std::endl;\n  std::cout << \"5.0 clamped to interval [1.5, 2.5] is \" << my_clamp(5.0, 1.5, 2.5) << std::endl;\n\n  int big_int {17011983}, small_int {10}, negative_int {-123};\n  std::cout \n    << std::format(\"{} clamped to the interval [{},{}] is {}\", \n          negative_int, small_int, big_int, my_clamp(negative_int, small_int, big_int))\n    << std::endl;\n\n  // And now for a less useful example...\n  std::string a_string {\"A\"}, z_string {\"Z\"};\n  std::string shakespeare{\"It is not in the stars to hold our destiny but in ourselves\"};\n  std::cout << \"William Shakespeare's quote clamped to [A-Z] is: \" \n            << my_clamp(shakespeare, a_string, z_string) << std::endl;\n}\n\n// Template for functions to clamp a value to a closed interval\ntemplate<typename T> \nconst T& my_clamp(const T& value, const T& low, const T& high)\n{\n  if (value < low) return low;\n  else if (value < high) return value;\n  else return high;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 10/Soln10_02.cpp",
    "content": "// Exercise 10-2.cpp\n// Using auto instead of std::string resulted in a type change for a_string and z_string:\n// they now both have the type const char[], the type given to string literals.\n// If you instantiate the original template for this type, it therefore becomes\n//   \n//   const char* larger(const char* a, const char* b)\n//   {\n//     return a > b? a : b;\n//   }\n//\n// This function now compares the pointers of both string literals rather than the \n// string literals themselves. To solve this, you should create a specialisation \n// for const char* arrays. \n\nimport <iostream>;\nimport <string_view>;\n\ntemplate<typename T>                     // Function template prototype\nT larger(T a, T b);                      \n\ntemplate<>                               // Function template specialization prototype\nconst char* larger(const char* a, const char* b);  \n\nint main() \n{\n  std::cout << \"Larger of 1.5 and 2.5 is \" << larger(1.5, 2.5) << std::endl;\n  std::cout << \"Larger of 3.5 and 4.5 is \" << larger(3.5, 4.5) << std::endl;\n\n  const int big_int {17011983}, small_int {10};\n  std::cout << \"Larger of \" << big_int << \" and \" << small_int << \" is \"\n            << larger(big_int, small_int) << std::endl;\n\n  const auto a_string {\"A\"}, z_string {\"Z\"};\t\t// now string literals (type const char[])!\n  std::cout << \"Larger of \\\"\" << a_string << \"\\\" and \\\"\" << z_string << \"\\\" is \"\n            << '\"' << larger(a_string, z_string) << '\"' << std::endl;\n}\n\n// Template for functions to return the larger of two values\ntemplate <typename T>\nT larger(T a, T b)\n{\n  return a > b? a : b;\n}\n\n// Template specialization for returning the larger of two character arrays \n// (such as string literals).\n//\n// Note: instead of std::string_view, you could've used std::string as well,\n// but that would've involved copying the character arrays. \n// std::string_view is therefore the preferred C++ type to use here.\ntemplate<>\nconst char* larger(const char* a, const char* b)\n{\n  return std::string_view{a} > std::string_view{b}? a : b;\n}\n\n/*\n// Template specialization for returning the larger of two character arrays \n// (such as string literals).\n// Alternative implementation using the C-style function strcmp() \n// (you'll need to include the <cstring> header to make this compile).\n// The strcmp() function returns a value larger than zero if a > b; \n// zero if both arguments are equal, a negative value if a < b.\ntemplate<>\nconst char* larger(const char* a, const char* b)\n{\n  return std::strcmp(a, b) > 0;\n}\n*/"
  },
  {
    "path": "Exercises/Modules/Chapter 10/Soln10_03.cpp",
    "content": "// Exercise 10-3.cpp\n// Defining a function template for adding numbers, \n// and an overload that works for pointer types.\n// Extra: also make plus() work with string literals...\nimport <iostream>;\nimport <string>;\nimport <string_view>;\n\ntemplate <typename T>\nT plus(const T& a, const T& b)\n{\n    return a + b;\n}\n\n// Overload with another template for pointer types\ntemplate <typename T>\nT plus(const T* a, const T* b)\n{\n    return *a + *b;\n}\n\n// Result cannot be const char*, but has to be a new object.\n// Function template specialization can thus not be used either\n// (but that is, as you know, never a good idea anyway!).\nstd::string plus(const char* a, const char* b)\n{\n  return std::string{ a } + b;\n}\n\nint main()\n{\n    int n{ plus(3, 4) };\n    std::cout << \"plus(3, 4) returns \" << n << std::endl;\n    \n    double d{ plus(3.2, 4.2) };\n    std::cout << \"plus(3.2, 4.2) returns \" << d << std::endl;\n    \n    std::string s1{ \"aaa\" };\n    std::string s2{ \"bbb\" };\n    auto s3{ plus(s1, s2) };\n    std::cout << \"With s1 as \" << s1 << \" and s2 as \" << s2 << std::endl;\n    std::cout << \"plus(s1, s2) returns \" << s3 << std::endl;\n\n    // The extra part:\n    std::string s{ plus(\"he\", \"llo\") };\n    std::cout << \"plus(\\\"he\\\", \\\"llo\\\") returns \" << s << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 10/Soln10_04.cpp",
    "content": "// Exercise 10-4.cpp\n// Your very own interpretation of std::size()\nimport <iostream>;\nimport <array>;\nimport <vector>;\nimport <span>;\n\n// Look ma, no sizeof()!\ntemplate <typename T, size_t N>\nsize_t my_size(const T (&array)[N]) { return N; }\n\n// Overload with two other templates for std::vector<> and array<> \ntemplate <typename T>\nsize_t my_size(const std::vector<T>& vector) { return vector.size(); }\n\ntemplate <typename T, size_t N>\nsize_t my_size(const std::array<T,N>& array) { return N; }  // or array.size();\n\n/*\nInstead of the latter two templates, you can create one template that would make my_size \naccept any argument and call size() on it. This will make it work\nfor std::array<> and std::vector<>, as well as std::string and many other containers:\n\ntemplate <typename Collection>\nsize_t my_size(const Collection& collection) { return collection.size(); }\n\nPotential downside is that this will instantiate for int and double type arguments\nas well, which may result in somewhat verbose compiler errors.\nThis issue can easily be fixed using a requires clause, though (see Chapter 21).\n\ntemplate <typename Collection> requires requires (const Collection c) { c.size(); }\nsize_t my_size(const Collection& collection) { return collection.size(); }\n*/\n\nint main()\n{\n  int array[] {4, 8, 15, 16, 23, 42};\n  std::cout << \"Size of numbers is \" << my_size(array) << std::endl;\n  \n  // A string literal is also an array:\n  std::cout << \"Size of life lesson is \" \n            << my_size(\"Always wear a smile. One size fits all.\") << std::endl;\n  \n  std::vector<int> vector{4, 8, 15, 16, 23, 42};\n  std::cout << \"Size of vector is \" << my_size(vector) << std::endl;\n  \n  std::array<int, 6> array_object{4, 8, 15, 16, 23, 42};\n  std::cout << \"Size of array_object is \" << my_size(array_object) << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 10/Soln10_05.cpp",
    "content": "// Exercise 10-5.cpp\n// The easiest way to verify this is using a static variable.\n// If indeed each function is only instantiated once, \n// then all calls should share the same static variable...\n// You should see this being reflected in the program's output\n// as main() starts by calling the function for doubles twice.\nimport <iostream>;\nimport <format>;\nimport <string>;\n\ntemplate<typename T> T larger(T a, T b);    // Function template prototype\n\nint main()\n{\n  std::cout << \"Larger of 1.5 and 2.5 is \" << larger(1.5, 2.5) << std::endl;\n  std::cout << \"Larger of 3.5 and 4.5 is \" << larger(3.5, 4.5) << std::endl;\n\n  int big_int {17011983}, small_int {10};\n  std::cout << std::format(\"Larger of {} and {} is {}\\n\", \n                            big_int, small_int, larger(big_int, small_int));\n\n  std::string a_string {\"A\"}, z_string {\"Z\"};\n  std::cout << std::format(R\"(Larger of \"{}\" and \"{}\" is \"{}\")\", \n                           a_string, z_string, larger(a_string, z_string)) << std::endl;\n}\n\n// Template for functions to return the larger of two values\ntemplate <typename T>\nT larger(T a, T b)\n{\n  static size_t counter{};\n  std::cout << \"This instantation has now been called \" << ++counter << \" time(s)\\n\";\n  return a > b? a : b;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 10/Soln10_06.cpp",
    "content": "// Exercise 10-6 A Quicksort function template\n\nimport <iostream>;\nimport <format>;\nimport <vector>;\n\ntemplate <typename T>\nvoid swap(std::vector<T>& data, size_t first, size_t second);\ntemplate <typename T>\nvoid sort(std::vector<T>& data);\ntemplate <typename T>\nvoid sort(std::vector<T>& data, size_t start, size_t end);\ntemplate <typename T>\nvoid show(const std::vector<T>& data, size_t width = 5);\n\nint main()\n{\n  std::vector<int> numbers{ -2, 4, -5, 6, 10, -40, 56, 4, 67, 45 };\n  show(numbers);\n  sort(numbers);\n  std::cout << \"\\nSorted integers:\\n\";\n  show(numbers);\n\n  std::cout << \"\\nCharacters to be sorted:\\n\";\n  std::vector<char> letters{ 'C', 'd', 'a', 'z', 't', 'S', 'p', 'm', 'D', 'f' };\n  show(letters, 2);\n  sort(letters);\n  std::cout << \"\\nSorted characters:\\n\";\n  show(letters, 2);\n\n  std::cout << \"\\nFloating-point values to be sorted:\\n\";\n  std::vector<double> values{ -2.5, 1.4, -2.55, 6.3, 10.1, -40.5, 56.0, 4.7, 67.3, 45.0 };\n  show(values, 10);\n  sort(values);\n  std::cout << \"\\nSorted floaating-point values:\\n\";\n  show(values, 10);\n}\n\ntemplate <typename T>\nvoid swap(std::vector<T>& data, size_t first, size_t second)\n{\n  auto temp{data[first]};\n  data[first] = data[second];\n  data[second] = temp;\n}\n\n// Sort data in ascending sequence\ntemplate <typename T>\nvoid sort(std::vector<T>& data)\n{\n  if (!data.empty())\n    sort(data, 0, data.size() - 1);\n}\n\ntemplate <typename T>\nvoid sort(std::vector<T>& data, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle address to partition set\n  swap(data, start, (start + end) / 2);    // Swap middle element with start element\n\n  // Check data against chosen element\n  size_t current {start};\n  for (size_t i {start + 1}; i <= end; i++)\n  {\n    if (data[i] < data[start])     // Is element less than chosen element?\n      swap(data, ++current, i);    // Yes, so swap to the left\n  }\n\n  swap(data, start, current);      // Swap chosen and last swapped elements\n\n  if (current > start) sort(data, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) sort(data, current + 1, end); // Sort right subset if exists\n}\n\ntemplate <typename T>\nvoid show(const std::vector<T>& data, size_t width)\n{\n  const size_t data_per_line{ 80 / width - 1};\n  std::cout << std::format(\"{:{}}\", data[0], width); // Output first element\n\n  size_t data_in_line {};         // Number of data in current line\n  for (size_t i {1}; i < data.size(); ++i)\n  {\n    if (++data_in_line == data_per_line)\n    {\n      data_in_line = 0;\n      std::cout << std::endl;\n    }\n    std::cout << std::format(\"{:{}}\", data[i], width); // Output an element\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_01/Soln11_01.cpp",
    "content": "// Move all functions from Ex8_17.cpp (and not Ex8_18.cpp as the text says...)\n// to a words function, exporting only the functions used by main().\nimport <string>;\nimport <iostream>;\nimport words;\n\nint main()\n{\n  words::Words the_words;  /* Renamed to sidestep name clash with words namespace! */\n  std::string text;                    // The string to be sorted\n  const auto separators{\" ,.!?\\\"\\n\"};  // Word delimiters\n\n  // Read the string to be processed from the keyboard\n  std::cout << \"Enter a string terminated by *:\" << std::endl;\n  getline(std::cin, text, '*');\n\n  words::extract_words(the_words, text, separators);\n  if (the_words.empty())\n  {\n    std::cout << \"No words in text.\" << std::endl;\n    return 0;\n  }\n\n  words::sort(the_words);         // Sort the words\n  words::show_words(the_words);   // Output the words\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_01/words.cppm",
    "content": "export module words;\n\nimport <iostream>;\nimport <format>;\nimport <memory>;\nimport <string>;\nimport <vector>;\n\nexport namespace words\n{\n  using Words = std::vector<std::shared_ptr<std::string>>;\n\n  void sort(Words& words);\n  void extract_words(Words& words, const std::string& text, const std::string& separators);\n  void show_words(const Words& words);\n}\n\nnamespace words\n{\n  size_t max_word_length(const Words& words);\n}\n\nvoid words::extract_words(Words& words, const std::string& text, const std::string& separators)\n{\n  size_t start {text.find_first_not_of(separators)}; // Start index of first word\n\n  while (start != std::string::npos)\n  {\n    size_t end{ text.find_first_of(separators, start + 1) }; // Find end of a word\n    if (end == std::string::npos)                    // Found a separator?\n      end = text.length();                           // Yes, so set to end of text\n    words.push_back(std::make_shared<std::string>(text.substr(start, end - start)));\n    start = text.find_first_not_of(separators, end + 1); // Find start next word\n  }\n}\n\n/* Additional helpers for word::sort(Words&) */\nnamespace words\n{\n  void swap(Words& words, size_t first, size_t second)\n  {\n    auto temp{ words[first] };\n    words[first] = words[second];\n    words[second] = temp;\n  }\n\n  void sort(Words& words, size_t start, size_t end);\n}\n\n// Sort strings in ascending sequence\n\nvoid words::sort(Words& words)\n{\n  if (!words.empty())\n    sort(words, 0, words.size() - 1);\n}\n\nvoid words::sort(Words& words, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle address to partition set\n  swap(words, start, (start + end) / 2);     // Swap middle address with start\n\n  // Check words against chosen word\n  size_t current {start};\n  for (size_t i {start + 1}; i <= end; i++)\n  {\n    if (*words[i] < *words[start])           // Is word less than chosen word?\n      swap(words, ++current, i);             // Yes, so swap to the left\n  }\n\n  swap(words, start, current);               // Swap chosen and last swapped words\n\n  if (current > start) sort(words, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) sort(words, current + 1, end); // Sort right subset if exists\n}\n\nsize_t words::max_word_length(const Words& words)\n{\n  size_t max {};\n  for (auto& pword : words)\n    if (max < pword->length()) max = pword->length();\n  return max;\n}\n\nvoid words::show_words(const Words& words)\n{\n  const size_t field_width {max_word_length(words) + 1};\n  const size_t words_per_line {8};\n  std::cout << std::format(\"{:{}}\", *words[0], field_width); // Output first word\n\n  size_t words_in_line {};         // Number of words in current line\n  for (size_t i {1}; i < words.size(); ++i)\n  { // Output newline when initial letter changes or after 8 per line\n    if ((*words[i])[0] != (*words[i - 1])[0] || ++words_in_line == words_per_line)\n    {\n      words_in_line = 0;\n      std::cout << std::endl;\n    }\n    std::cout << std::format(\"{:{}}\", *words[i], field_width); // Output a word\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_02/Soln11_02.cpp",
    "content": "// Moving the implementation of functions from the module interface file \n// to a module implementation file.\nimport <string>;\nimport <iostream>;\nimport words;\n\nint main()\n{\n  words::Words the_words;\n  std::string text;                    // The string to be sorted\n  const auto separators{\" ,.!?\\\"\\n\"};  // Word delimiters\n\n  // Read the string to be processed from the keyboard\n  std::cout << \"Enter a string terminated by *:\" << std::endl;\n  getline(std::cin, text, '*');\n\n  words::extract_words(the_words, text, separators);\n  if (the_words.empty())\n  {\n    std::cout << \"No words in text.\" << std::endl;\n    return 0;\n  }\n\n  words::sort(the_words);         // Sort the words\n  words::show_words(the_words);   // Output the words\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_02/words.cpp",
    "content": "module words;\n\nimport <iostream>;\nimport <format>;\n\nsize_t max_word_length(const words::Words& words);\n\nvoid words::extract_words(Words& words, const std::string& text, const std::string& separators)\n{\n  size_t start {text.find_first_not_of(separators)}; // Start index of first word\n\n  while (start != std::string::npos)\n  {\n    size_t end{ text.find_first_of(separators, start + 1) }; // Find end of a word\n    if (end == std::string::npos)                    // Found a separator?\n      end = text.length();                           // Yes, so set to end of text\n    words.push_back(std::make_shared<std::string>(text.substr(start, end - start)));\n    start = text.find_first_not_of(separators, end + 1); // Find start next word\n  }\n}\n\n/* Additional helpers for word::sort(Words&) */\nvoid swap(words::Words& words, size_t first, size_t second)\n{\n  auto temp{ words[first] };\n  words[first] = words[second];\n  words[second] = temp;\n}\n\nvoid sort(words::Words& words, size_t start, size_t end);\n\n// Sort strings in ascending sequence\nvoid words::sort(Words& words)\n{\n  if (!words.empty())\n    ::sort(words, 0, words.size() - 1);\n}\n\nvoid sort(words::Words& words, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle address to partition set\n  swap(words, start, (start + end) / 2);     // Swap middle address with start\n\n  // Check words against chosen word\n  size_t current {start};\n  for (size_t i {start + 1}; i <= end; i++)\n  {\n    if (*words[i] < *words[start])           // Is word less than chosen word?\n      swap(words, ++current, i);             // Yes, so swap to the left\n  }\n\n  swap(words, start, current);               // Swap chosen and last swapped words\n\n  if (current > start) sort(words, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) sort(words, current + 1, end); // Sort right subset if exists\n}\n\nsize_t max_word_length(const words::Words& words)\n{\n  size_t max {};\n  for (auto& pword : words)\n    if (max < pword->length()) max = pword->length();\n  return max;\n}\n\nvoid words::show_words(const Words& words)\n{\n  const size_t field_width {max_word_length(words) + 1};\n  const size_t words_per_line {8};\n  std::cout << std::format(\"{:{}}\", *words[0], field_width); // Output first word\n\n  size_t words_in_line {};         // Number of words in current line\n  for (size_t i {1}; i < words.size(); ++i)\n  { // Output newline when initial letter changes or after 8 per line\n    if ((*words[i])[0] != (*words[i - 1])[0] || ++words_in_line == words_per_line)\n    {\n      words_in_line = 0;\n      std::cout << std::endl;\n    }\n    std::cout << std::format(\"{:{}}\", *words[i], field_width); // Output a word\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_02/words.cppm",
    "content": "export module words;\n\nimport <memory>;\nimport <string>;\nimport <vector>;\n\nexport namespace words\n{\n  using Words = std::vector<std::shared_ptr<std::string>>;\n\n  void sort(Words& words);\n  void extract_words(Words& words, const std::string& text, const std::string& separators);\n  void show_words(const Words& words);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_03/Soln11_03.cpp",
    "content": "// Splitting a module in multiple submodules\nimport words;\n\nimport <string>;\nimport <iostream>;\n\nint main()\n{\n  words::Words the_words;\n  std::string text;                    // The string to be sorted\n  const auto separators{\" ,.!?\\\"\\n\"};  // Word delimiters\n\n  // Read the string to be processed from the keyboard\n  std::cout << \"Enter a string terminated by *:\" << std::endl;\n  getline(std::cin, text, '*');\n\n  words::utils::extract_words(the_words, text, separators);\n  if (the_words.empty())\n  {\n    std::cout << \"No words in text.\" << std::endl;\n    return 0;\n  }\n\n  words::sorting::sort(the_words);         // Sort the words\n  words::utils::show_words(the_words);   // Output the words\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_03/words.cppm",
    "content": "export module words;\n\nexport import words.sorting;\nexport import words.utils;"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_03/words.sorting.cpp",
    "content": "module words.sorting;\n\n/* Additional helpers for word::sort(Words&) */\nvoid swap(words::Words& words, size_t first, size_t second)\n{\n  auto temp{ words[first] };\n  words[first] = words[second];\n  words[second] = temp;\n}\n\nvoid sort(words::Words& words, size_t start, size_t end);\n\n// Sort strings in ascending sequence\nvoid words::sorting::sort(Words& words)\n{\n  if (!words.empty())\n    ::sort(words, 0, words.size() - 1);\n}\n\nvoid sort(words::Words& words, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle address to partition set\n  swap(words, start, (start + end) / 2);     // Swap middle address with start\n\n  // Check words against chosen word\n  size_t current {start};\n  for (size_t i {start + 1}; i <= end; i++)\n  {\n    if (*words[i] < *words[start])           // Is word less than chosen word?\n      swap(words, ++current, i);             // Yes, so swap to the left\n  }\n\n  swap(words, start, current);               // Swap chosen and last swapped words\n\n  if (current > start) sort(words, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) sort(words, current + 1, end); // Sort right subset if exists\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_03/words.sorting.cppm",
    "content": "export module words.sorting;\n\nimport <memory>;\nimport <string>;\nimport <vector>;\n\nexport namespace words\n{\n  using Words = std::vector<std::shared_ptr<std::string>>;\n\n  namespace sorting\n  {\n    void sort(Words& words);\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_03/words.utils.cpp",
    "content": "module words.utils;\n\nimport <iostream>;\nimport <format>;\n\nsize_t max_word_length(const words::Words& words)\n{\n  size_t max{};\n  for (auto& pword : words)\n    if (max < pword->length()) max = pword->length();\n  return max;\n}\n\nvoid words::utils::extract_words(Words& words, const std::string& text, const std::string& separators)\n{\n  size_t start {text.find_first_not_of(separators)}; // Start index of first word\n\n  while (start != std::string::npos)\n  {\n    size_t end{ text.find_first_of(separators, start + 1) }; // Find end of a word\n    if (end == std::string::npos)                    // Found a separator?\n      end = text.length();                           // Yes, so set to end of text\n    words.push_back(std::make_shared<std::string>(text.substr(start, end - start)));\n    start = text.find_first_not_of(separators, end + 1); // Find start next word\n  }\n}\n\nvoid words::utils::show_words(const Words& words)\n{\n  const size_t field_width {max_word_length(words) + 1};\n  const size_t words_per_line {8};\n  std::cout << std::format(\"{:{}}\", *words[0], field_width); // Output first word\n\n  size_t words_in_line {};         // Number of words in current line\n  for (size_t i {1}; i < words.size(); ++i)\n  { // Output newline when initial letter changes or after 8 per line\n    if ((*words[i])[0] != (*words[i - 1])[0] || ++words_in_line == words_per_line)\n    {\n      words_in_line = 0;\n      std::cout << std::endl;\n    }\n    std::cout << std::format(\"{:{}}\", *words[i], field_width); // Output a word\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_03/words.utils.cppm",
    "content": "export module words.utils;\n\nimport <memory>;\nimport <string>;\nimport <vector>;\n\nnamespace words\n{\n  export using Words = std::vector<std::shared_ptr<std::string>>;\n}\n\nexport namespace words::utils\n{\n  void extract_words(Words& words, const std::string& text, const std::string& separators);\n  void show_words(const Words& words);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_04/Soln11_04.cpp",
    "content": "// Creating a module implementation partition\nimport <string>;\nimport <iostream>;\nimport words;\n\nint main()\n{\n  words::Words the_words;\n  std::string text;                    // The string to be sorted\n  const auto separators{\" ,.!?\\\"\\n\"};  // Word delimiters\n\n  // Read the string to be processed from the keyboard\n  std::cout << \"Enter a string terminated by *:\" << std::endl;\n  getline(std::cin, text, '*');\n\n  words::extract_words(the_words, text, separators);\n  if (the_words.empty())\n  {\n    std::cout << \"No words in text.\" << std::endl;\n    return 0;\n  }\n\n  words::sort(the_words);         // Sort the words\n  words::show_words(the_words);   // Output the words\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_04/internals.cpp",
    "content": "module words:internals;\n\nimport words; // For use of words::Words\n\nvoid swap(words::Words& words, size_t first, size_t second)\n{\n  auto temp{ words[first] };\n  words[first] = words[second];\n  words[second] = temp;\n}\n\nsize_t max_word_length(const words::Words& words)\n{\n  size_t max {};\n  for (auto& pword : words)\n    if (max < pword->length()) max = pword->length();\n  return max;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_04/words.cpp",
    "content": "module words;\n\nimport <iostream>;\nimport <format>;\nimport :internals;\n\nvoid words::extract_words(Words& words, const std::string& text, const std::string& separators)\n{\n  size_t start {text.find_first_not_of(separators)}; // Start index of first word\n\n  while (start != std::string::npos)\n  {\n    size_t end{ text.find_first_of(separators, start + 1) }; // Find end of a word\n    if (end == std::string::npos)                    // Found a separator?\n      end = text.length();                           // Yes, so set to end of text\n    words.push_back(std::make_shared<std::string>(text.substr(start, end - start)));\n    start = text.find_first_not_of(separators, end + 1); // Find start next word\n  }\n}\n\n/* Additional helper for word::sort(Words&) */\nvoid sort(words::Words& words, size_t start, size_t end);\n\n// Sort strings in ascending sequence\nvoid words::sort(Words& words)\n{\n  if (!words.empty())\n    ::sort(words, 0, words.size() - 1);\n}\n\nvoid sort(words::Words& words, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle address to partition set\n  swap(words, start, (start + end) / 2);     // Swap middle address with start\n\n  // Check words against chosen word\n  size_t current {start};\n  for (size_t i {start + 1}; i <= end; i++)\n  {\n    if (*words[i] < *words[start])           // Is word less than chosen word?\n      swap(words, ++current, i);             // Yes, so swap to the left\n  }\n\n  swap(words, start, current);               // Swap chosen and last swapped words\n\n  if (current > start) sort(words, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) sort(words, current + 1, end); // Sort right subset if exists\n}\n\nvoid words::show_words(const Words& words)\n{\n  const size_t field_width {max_word_length(words) + 1};\n  const size_t words_per_line {8};\n  std::cout << std::format(\"{:{}}\", *words[0], field_width); // Output first word\n\n  size_t words_in_line {};         // Number of words in current line\n  for (size_t i {1}; i < words.size(); ++i)\n  { // Output newline when initial letter changes or after 8 per line\n    if ((*words[i])[0] != (*words[i - 1])[0] || ++words_in_line == words_per_line)\n    {\n      words_in_line = 0;\n      std::cout << std::endl;\n    }\n    std::cout << std::format(\"{:{}}\", *words[i], field_width); // Output a word\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_04/words.cppm",
    "content": "export module words;\n\nimport <memory>;\nimport <string>;\nimport <vector>;\n\nexport namespace words\n{\n  using Words = std::vector<std::shared_ptr<std::string>>;\n\n  void sort(Words& words);\n  void extract_words(Words& words, const std::string& text, const std::string& separators);\n  void show_words(const Words& words);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_05/Soln11_05.cpp",
    "content": "// Splitting a module interface into partitions\nimport <string>;\nimport <iostream>;\nimport words;\n\nint main()\n{\n  words::Words the_words;  /* Renamed to sidestep name clash with words namespace! */\n  std::string text;                    // The string to be sorted\n  const auto separators{\" ,.!?\\\"\\n\"};  // Word delimiters\n\n  // Read the string to be processed from the keyboard\n  std::cout << \"Enter a string terminated by *:\" << std::endl;\n  getline(std::cin, text, '*');\n\n  words::extract_words(the_words, text, separators);\n  if (the_words.empty())\n  {\n    std::cout << \"No words in text.\" << std::endl;\n    return 0;\n  }\n\n  words::sort(the_words);         // Sort the words\n  words::show_words(the_words);   // Output the words\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_05/alias.cppm",
    "content": "export module words:alias;\n\nimport <memory>;\nimport <string>;\nimport <vector>;\n\nnamespace words\n{\n  export using Words = std::vector<std::shared_ptr<std::string>>;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_05/internals.cpp",
    "content": "module words:internals;\n\nimport :alias; // For use of words::Words\n\nvoid swap(words::Words& words, size_t first, size_t second)\n{\n  auto temp{ words[first] };\n  words[first] = words[second];\n  words[second] = temp;\n}\n\nsize_t max_word_length(const words::Words& words)\n{\n  size_t max {};\n  for (auto& pword : words)\n    if (max < pword->length()) max = pword->length();\n  return max;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_05/sorting.cppm",
    "content": "// A module interface partition containing words::sort()\nexport module words:sorting;\n\nimport :alias;   // For the use of words::Words\nimport :internals;\n\nexport namespace words\n{\n  void sort(Words& words);\n}\n\n/* Recursive helper for word::sort(Words&) */\nnamespace words\n{\n  void sort(Words& words, size_t start, size_t end);\n}\n\n// Sort strings in ascending sequence\nvoid words::sort(Words& words)\n{\n  if (!words.empty())\n    sort(words, 0, words.size() - 1);\n}\n\nvoid words::sort(Words& words, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle address to partition set\n  swap(words, start, (start + end) / 2);     // Swap middle address with start\n\n  // Check words against chosen word\n  size_t current {start};\n  for (size_t i {start + 1}; i <= end; i++)\n  {\n    if (*words[i] < *words[start])           // Is word less than chosen word?\n      swap(words, ++current, i);             // Yes, so swap to the left\n  }\n\n  swap(words, start, current);               // Swap chosen and last swapped words\n\n  if (current > start) sort(words, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) sort(words, current + 1, end); // Sort right subset if exists\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_05/utils.cppm",
    "content": "// A module interface partition containing some extra words-related utilities\nexport module words:utils;\n\nimport :alias;   // For use of words::Words alias\nimport :internals;\n\nimport <iostream>;\nimport <format>;\n\nexport namespace words\n{\n  void extract_words(Words& words, const std::string& text, const std::string& separators);\n  void show_words(const Words& words);\n}\n\nvoid words::extract_words(Words& words, const std::string& text, const std::string& separators)\n{\n  size_t start {text.find_first_not_of(separators)}; // Start index of first word\n\n  while (start != std::string::npos)\n  {\n    size_t end{ text.find_first_of(separators, start + 1) }; // Find end of a word\n    if (end == std::string::npos)                    // Found a separator?\n      end = text.length();                           // Yes, so set to end of text\n    words.push_back(std::make_shared<std::string>(text.substr(start, end - start)));\n    start = text.find_first_not_of(separators, end + 1); // Find start next word\n  }\n}\n\nvoid words::show_words(const Words& words)\n{\n  const size_t field_width {max_word_length(words) + 1};\n  const size_t words_per_line {8};\n  std::cout << std::format(\"{:{}}\", *words[0], field_width); // Output first word\n\n  size_t words_in_line {};         // Number of words in current line\n  for (size_t i {1}; i < words.size(); ++i)\n  { // Output newline when initial letter changes or after 8 per line\n    if ((*words[i])[0] != (*words[i - 1])[0] || ++words_in_line == words_per_line)\n    {\n      words_in_line = 0;\n      std::cout << std::endl;\n    }\n    std::cout << std::format(\"{:{}}\", *words[i], field_width); // Output a word\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_05/words.cppm",
    "content": "export module words;\n\nexport import :alias;\nexport import :sorting;\nexport import :utils;"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_06/Soln11_06.cpp",
    "content": "// Defining alternate names for a namespace\nimport <string>;\nimport <iostream>;\nimport words;\n\nnamespace wrds\n{\n  // A using directive us not a declaration, \n  // and can therefore not be exported from a module.\n  // Namespace aliases are therefore the preferred over \n  // using directives inside a namespace...\n  using namespace words;\n}\n\nint main()\n{\n  wrds::Words the_words;\n  std::string text;                    // The string to be sorted\n  const auto separators{\" ,.!?\\\"\\n\"};  // Word delimiters\n\n  // Read the string to be processed from the keyboard\n  std::cout << \"Enter a string terminated by *:\" << std::endl;\n  getline(std::cin, text, '*');\n\n  w::extract_words(the_words, text, separators);\n  if (the_words.empty())\n  {\n    std::cout << \"No words in text.\" << std::endl;\n    return 0;\n  }\n\n  wrds::sort(the_words);         // Sort the words\n  w::show_words(the_words);   // Output the words\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_06/words.cpp",
    "content": "module words;\n\nimport <iostream>;\nimport <format>;\n\nsize_t max_word_length(const words::Words& words);\n\nvoid words::extract_words(Words& words, const std::string& text, const std::string& separators)\n{\n  size_t start {text.find_first_not_of(separators)}; // Start index of first word\n\n  while (start != std::string::npos)\n  {\n    size_t end{ text.find_first_of(separators, start + 1) }; // Find end of a word\n    if (end == std::string::npos)                    // Found a separator?\n      end = text.length();                           // Yes, so set to end of text\n    words.push_back(std::make_shared<std::string>(text.substr(start, end - start)));\n    start = text.find_first_not_of(separators, end + 1); // Find start next word\n  }\n}\n\n/* Additional helpers for word::sort(Words&) */\nvoid swap(words::Words& words, size_t first, size_t second)\n{\n  auto temp{ words[first] };\n  words[first] = words[second];\n  words[second] = temp;\n}\n\nvoid sort(words::Words& words, size_t start, size_t end);\n\n// Sort strings in ascending sequence\nvoid words::sort(Words& words)\n{\n  if (!words.empty())\n    ::sort(words, 0, words.size() - 1);\n}\n\nvoid sort(words::Words& words, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle address to partition set\n  swap(words, start, (start + end) / 2);     // Swap middle address with start\n\n  // Check words against chosen word\n  size_t current {start};\n  for (size_t i {start + 1}; i <= end; i++)\n  {\n    if (*words[i] < *words[start])           // Is word less than chosen word?\n      swap(words, ++current, i);             // Yes, so swap to the left\n  }\n\n  swap(words, start, current);               // Swap chosen and last swapped words\n\n  if (current > start) sort(words, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) sort(words, current + 1, end); // Sort right subset if exists\n}\n\nsize_t max_word_length(const words::Words& words)\n{\n  size_t max {};\n  for (auto& pword : words)\n    if (max < pword->length()) max = pword->length();\n  return max;\n}\n\nvoid words::show_words(const Words& words)\n{\n  const size_t field_width {max_word_length(words) + 1};\n  const size_t words_per_line {8};\n  std::cout << std::format(\"{:{}}\", *words[0], field_width); // Output first word\n\n  size_t words_in_line {};         // Number of words in current line\n  for (size_t i {1}; i < words.size(); ++i)\n  { // Output newline when initial letter changes or after 8 per line\n    if ((*words[i])[0] != (*words[i - 1])[0] || ++words_in_line == words_per_line)\n    {\n      words_in_line = 0;\n      std::cout << std::endl;\n    }\n    std::cout << std::format(\"{:{}}\", *words[i], field_width); // Output a word\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 11/Soln11_06/words.cppm",
    "content": "export module words;\n\nimport <memory>;\nimport <string>;\nimport <vector>;\n\nexport namespace words\n{\n  using Words = std::vector<std::shared_ptr<std::string>>;\n\n  void sort(Words& words);\n  void extract_words(Words& words, const std::string& text, const std::string& separators);\n  void show_words(const Words& words);\n}\n\nexport namespace w = words;\n\n/* This does not work:\n\n  namespace wrds\n  {\n    // A using directive is not a declaration, \n    // and can therefore not be exported from a module.\n    // Namespace aliases are therefore preferred over \n    // using directives inside a namespace...\n    export using namespace words;\n  }\n*/\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_01/Integer.cpp",
    "content": "module integer;\nimport <iostream>;\n\nInteger::Integer(int value) : m_value{value}\n{\n  std::cout << \"Object created.\" << std::endl;\n}\n\nvoid Integer::show() const\n{\n  std::cout << \"Value is \" << m_value << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_01/Integer.cppm",
    "content": "export module integer;\n\nexport class Integer\n{\npublic:\n  Integer(int value);\n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\n  void show() const;\n\nprivate:\n  int m_value;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_01/Soln12_01.cpp",
    "content": "// Implementing an Integer class\nimport integer;\nimport <iostream>;\n\nint main() \n{\n  std::cout << \"Create i with the value 10.\" << std::endl;\n  Integer i {10};\n  i.show();\n  std::cout << \"Change value  of i to 15.\" << std::endl;\n//  i.m_value = 15;\t// Cannot assign directly to m_value\n  i.setValue(15);\n  i.show();\n \n  std::cout << \"Create j with a value that is 150 times that of i.\" << std::endl;\n  const Integer j {150 * i.getValue()};\n  j.show();\n  std::cout << \"Set value of j to .\" << std::endl;\n// j.setValue(5000);  // Cannot call setValue() on const object \n                      // (show() and getValue() work, though)\n\n  std::cout << \"Create k with the value 789.\" << std::endl;\n  Integer k {789};\n  k.show();\n  std::cout << \"Set value of k to sum of i and j values.\" << std::endl;\n  k.setValue(i.getValue() + j.getValue());\n  k.show();\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_02/Integer.cpp",
    "content": "module integer;\nimport <iostream>;\n\n// Constructor\nInteger::Integer(int value)\n  : m_value{ value }\n{\n  std::cout << \"Object created.\" << std::endl;\n}\n\n// Copy constructor\nInteger::Integer(const Integer& obj) \n  : m_value{ obj.m_value }\n{\n  std::cout << \"Object created by copy constructor.\" << std::endl;\n}\n\n// Compare function with reference parameter\nint Integer::compare(const Integer& obj) const\n{\n  if (m_value < obj.m_value)\n    return -1;\n  else if (m_value == obj.m_value)\n    return 0;\n  else\n    return 1;\n}\n\nvoid Integer::show() const\n{\n  std::cout << \"Value is \" << m_value << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_02/Integer.cppm",
    "content": "/***************************************************************\\\n This file shows two distinct ways of allowing an Integer\n to be constructed without an argument:\n  1) The first is to add a default constructor. \n\t   To make sure m_value is zero, \n     it adds zero initialization to the declaration of m_value.\n  2) The second (at the bottom of the file) is commented out \n     and uses a default parameter value for the existing \n     single-argument constructor.\n\\***************************************************************/\n\nexport module integer;\n\n// Option 1: zero-initialize n and add a default constructor\nexport class Integer\n{\npublic:\n  Integer() = default;                     // Zero-arg constructor\n  Integer(int value);                      // Contructor with given value\n  Integer(const Integer& obj);             // Copy constructor\n\n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\n\n//  int compare(Integer obj) const;        // Compare function with value parameter\n  int compare(const Integer& obj) const;   // Compare function with reference parameter\n\n  void show() const;\n\nprivate:\n  int m_value{};\n};\n\n// Option 2: use zero a default parameter value\n/*\nexport class Integer\n{\npublic:\n  Integer(int value = 0);                  // Contructor with given value\n\n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\n\n//  int compare(Integer obj) const;        // Compare function with value parameter\n  int compare(const Integer& obj) const;   // Compare function with reference parameter\n\n  void show() const;\n\nprivate:\n  int m_value;\n};\n*/\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_02/Soln12_02.cpp",
    "content": "// Using a function with a reference parameter in the Integer class\nimport <iostream>;\nimport integer;\n\n/*****************************************************************\\\n Using the version of compare() with the pass-by-value parameter,\n the copy constructor is called because a copy of the argument\n is passed to the function.\n\n Using the version with the reference parameter a reference\n to the object is passed to the function so no constructor call\n is necessary.\n\n You cannot overload a function with a reference parameter with\n a function that has a non-reference parameter because the\n compiler cannot tell which function should be called in any\n particular instance.\n\\*****************************************************************/\n\nint main()\n{\n  std::cout << \"Create i with the value 0.\" << std::endl;\n  Integer i;\n  i.show();\n  std::cout << \"Change value  of i to 15.\" << std::endl;\n  i.setValue(15);\n  i.show();\n \n  std::cout << \"Create j from object i.\" << std::endl;\n  Integer j {i};\n  j.show();\n  std::cout << \"Set value of j to 150 times that of i.\" << std::endl;\n  j.setValue(150 * i.getValue());\n  j.show();\n\n  std::cout << \"Create k with the value 789.\" << std::endl;\n  Integer k {789};\n  k.show();\n  std::cout << \"Set value of k to sum of i and j values.\" << std::endl;\n  k.setValue(i.getValue() + j.getValue());\n  k.show();\n\n  std::cout << \"Result of comparing i and j is \" << i.compare(j) << std::endl;\n  std::cout << \"Result of comparing k and j is \" << k.compare(j) << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_03/Integer.cpp",
    "content": "module integer;\nimport <iostream>;\n\n// Constructor\nInteger::Integer(int value) \n  : m_value{ value }\n{\n}\n\n// Copy constructor\nInteger::Integer(const Integer& obj) \n  : m_value{obj.m_value} \n{\n}\n\nInteger& Integer::add(const Integer& obj)\n{ \n  m_value += obj.m_value;\n  return *this;\n}\n\nInteger& Integer::subtract(const Integer& obj) \n{\n  m_value -= obj.m_value;\n  return *this;\n}\n\nInteger& Integer::multiply(const Integer& obj) \n{\n  m_value *= obj.m_value;\n  return *this;\n}\n\nint Integer::compare(const Integer& obj) const\n{\n  if (m_value < obj.m_value)\n    return -1;\n  else if (m_value == obj.m_value)\n    return 0;\n  else\n  \treturn 1;\n}\n\nvoid Integer::show() const\n{\n  std::cout << \"Value is \" << m_value << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_03/Integer.cppm",
    "content": "export module integer;\n\nexport class Integer\n{\npublic:\n  Integer(int value = 0);\n  Integer(const Integer& obj);\n\n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\n  \n  Integer& add(const Integer& obj);\n  Integer& subtract(const Integer& obj);\n  Integer& multiply(const Integer& obj);\n\n  int compare(const Integer& obj) const;\n  \n  void show() const;\n\nprivate:\n  int m_value;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_03/Soln12_03.cpp",
    "content": "// Implementing add(), subtract() and multiply() \nimport <iostream>;\nimport integer;\n\n/***********************************************************\n By returning the dereferenced this pointer in the functions\n we can call the functions successively in a single statement.\n Note the parameter is a reference-to-const;\n const because the argument is not changed by the function\n and a reference to avoid the overhead of copying objects.\n The only other requirement for achieving the calculation\n in a single statement is figuring out how to sequence to\n operations to allow this.\n ***********************************************************/\n\nint main()\n{\n  // Create the even operands as Integers, \n  // and use implicit conversions from int for the odd values\n  const Integer four{4};\n  const Integer six{6};\n  const Integer eight{8};\n  \n  // We can calculate 4*5*5*5+6*5*5+7*5+8 as:\n  //     ((4*5+6)*5+7)*5+8\n  Integer result {four};                       // Set result object as copy of four\n  std::cout << \"Result is \"\n            << result.multiply(5).add(six).multiply(5).add(7).multiply(5).add(eight).getValue()\n            << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_04/Integer.cpp",
    "content": "module integer;\nimport <iostream>;\n\n/****************************************************************\\\n Implementing compare() as a friend is quite simple.\n We must declare the function as a friend in the class definition.\n We now need both objects as arguments and the code in the\n body of the function just compares the n members of the arguments.\n Both parameters are references-to-const.\n\n However, other than the need for you to exercise friend functions,\n there's no real reason for the compare() function to be a friend\n of the Integer class: it can be implemented perfectly fine\n using the public getValue() function as well.\n The nonFriendCompare() function given below is therefore \n preferred over a friend function.\n\\****************************************************************/\n\n\n// Constructor\nInteger::Integer(int value) : m_value{value}\n{\n  std::cout << \"Object created.\" << std::endl;\n}\n\n// Copy constructor\nInteger::Integer(const Integer& obj) : m_value{ obj.m_value }\n{\n  std::cout << \"Object created by copy constructor.\" << std::endl;\n}\n\nvoid Integer::show() const\n{\n  std::cout << \"Value is \" << m_value << std::endl;\n}\n\n// friend compare function\nint compare(const Integer& obj1, const Integer& obj2)\n{\n  if (obj1.m_value < obj2.m_value)\n    return -1;\n  else if (obj1.m_value == obj2.m_value)\n    return 0;\n  else\n\t  return 1;\n}\n\n// non-friend compare function\nint nonFriendCompare(const Integer& obj1, const Integer& obj2)\n{\n  if (obj1.getValue() < obj2.getValue())\n    return -1;\n  else if (obj1.getValue() == obj2.getValue())\n    return 0;\n  else\n  \treturn 1;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_04/Integer.cppm",
    "content": "export module integer;\n\nexport class Integer\n{\npublic:\n  Integer(int value = 0);\n  Integer(const Integer& obj);\n  \n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\n\n  void show() const;\n\n  friend int compare(const Integer& obj1, const Integer& obj2);  // friend compare function\n\nprivate:\n  int m_value;\n};\n\n// A non-friend function that implements the same function\nexport int nonFriendCompare(const Integer& obj1, const Integer& obj2);\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_04/Soln12_04.cpp",
    "content": "// Using a friend function\nimport <iostream>;\nimport integer;\n\nint main()\n{\n  std::cout << \"Create i with the value 10.\" << std::endl;\n  Integer i {10};\n  i.show();\n  std::cout << \"Change value  of i to 15.\" << std::endl;\n  i.setValue(15);\n  i.show();\n \n  std::cout << \"Create j from object i.\" << std::endl;\n  Integer j {i};\n  j.show();\n  std::cout << \"Set value of j to 150 times that of i.\" << std::endl;\n  j.setValue(150 * i.getValue());\n  j.show();\n\n  std::cout << \"Create k with the value 789.\" << std::endl;\n  Integer k {789};\n  k.show();\n  std::cout << \"Set value of k to sum of i and j values.\" << std::endl;\n  k.setValue(i.getValue() + j.getValue());\n  k.show();\n\n  std::cout << \"Result of comparing i and j is \" << compare(i, j) << std::endl;\n  std::cout << \"Result of comparing k and j is \" << compare(k, j) << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_05/Integer.cpp",
    "content": "/*****************************************************************\\\n To implement printCount(), you first need a static member variable\n to store the object count. Every constructor should then increment\n this count, and you need to add a destructor that decrements it. \n\\*****************************************************************/\nmodule integer;\nimport <iostream>;\n\n// Constructor\nInteger::Integer(int value) : m_value{value}\n{\n  ++s_count;\n  std::cout << \"Object created.\" << std::endl;\n}\n\n// Copy constructor\nInteger::Integer(const Integer& obj) : m_value{obj.m_value}\n{\n  ++s_count;\n  std::cout << \"Object created by copy constructor.\" << std::endl;\n}\n\n// Destructor\nInteger::~Integer()\n{\n  --s_count;\n  std::cout << \"Object deleted.\" << std::endl;\n}\n\nvoid Integer::show() const\n{\n  std::cout << \"Value is \" << m_value << std::endl;\n}\n\nint Integer::compare(const Integer& obj) const\n{\n  if (m_value < obj.m_value)\n    return -1;\n  else if (m_value == obj.m_value)\n    return 0;\n  else\n    return 1;\n}\n\nvoid Integer::printCount()\n{\n  std::cout << \"There are now \" << s_count << \" Integer object(s).\" << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_05/Integer.cppm",
    "content": "export module integer;\n\nexport class Integer\n{\npublic:\n  Integer(int value = 0);                  // Contructor with given value\n  Integer(const Integer& obj);             // Copy constructor\n  ~Integer();                              // Destructor\n\n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\n\n  int compare(const Integer& obj) const;   // Compare function with reference parameter\n\n  void show() const;\n  \n  static void printCount();\n\nprivate:\n  int m_value;\n  static inline unsigned int s_count {};\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_05/Soln12_05.cpp",
    "content": "// Using static members and a destructor to keep track of an object count\nimport <iostream>;\nimport integer;\n\nvoid showIntegerVal(Integer it)\n{\n  it.show();\n  Integer::printCount();    // passed by value, so object count temporarily increases\n}\nvoid showIntegerRef(const Integer& it)\n{\n  it.show();\n  Integer::printCount();    // passed by reference, so object count did not increase\n}\n\nint main()\n{\n  std::cout << \"Create i with the value 0.\" << std::endl;\n  Integer i;\n  i.show();\n  \n  Integer::printCount();\t// 1 object\n \n  if (i.getValue() == 0)\n  {\n    std::cout << \"Create j from object i.\" << std::endl;\n    Integer j {i};\n    j.show();\n    Integer::printCount();\t// 2 objects\n  }\n  \n  Integer::printCount();\t// 1 object again (Integer j was deleted because its scope ended)\n\n  Integer array[] { 1, 2, 3 };\n  \n  Integer::printCount();   // 4 objects\n  \n  showIntegerRef(array[0]);\n  showIntegerVal(array[1]);\n  \n  Integer::printCount();   // 4 objects again\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_06/Box.cppm",
    "content": "export module box;\n\nimport <iostream>;\nimport <format>;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  void listBox() const\n  {\n    std::cout << std::format(\"Box({:.1f},{:.1f},{:.1f})\", m_length, m_width, m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_06/RandomBoxes.cppm",
    "content": "export module box.random;\n\nimport box;\nimport <random>;        // For random number generation\nimport <functional>;    // For std::bind()\nimport <memory>;        // For std::make_shared<>() and std::shared_ptr<>;\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\nexport Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\nexport auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_06/Soln12_06.cpp",
    "content": "// Creating a nested iterator class\nimport box.random;\nimport truckload;\nimport <iostream>;\n\n/* \n Turns out moving the getFirstBox() and getLastBox() functions \n to the nested iterator class is easy. We used the same names for\n the member variables, so it is just a matter of changing \"Truckload::\"\n into \"Truckload::Iterator::\".\n \n Makes sense: the logic for iterating the linked lists has not changed.\n The only difference is that now there are m_current and m_head pointers\n per iteration, instead of only the one pair in the Truckload object.\n This allows nested iterations, concurrent iterations, and so on.\n You will encounter this iterator pattern again in Chapters 19 and 20.\n\n Btw: if it strikes you as sub-optimal that our findLargestBox() and\n findSmallestBox() are so similar, do not despair: in Chapter 19 we teach\n you the techniques you need to avoid this so-called code duplication.\n*/\n\nSharedBox findLargestBox(const Truckload& truckload);\nSharedBox findSmallestBox(const Truckload& truckload);\n\nint main()\n{\n  Truckload load1;  // Create an empty list\n\n  // Add 12 random Box objects to the list\n  const size_t boxCount{ 12 };\n  for (size_t i{}; i < boxCount; ++i)\n    load1.addBox(randomSharedBox());\n\n  std::cout << \"The first list:\\n\";\n  load1.listBoxes();\n\n  // Copy the truckload\n  Truckload copy{ load1 };\n  std::cout << \"The copied truckload:\\n\";\n  copy.listBoxes();\n\n  // Find the largest Box in the list\n  const auto largestBox{ findLargestBox(load1) };\n\n  std::cout << \"\\nThe largest box in the first list is \";\n  largestBox->listBox();\n  std::cout << std::endl;\n  load1.removeBox(largestBox);\n  std::cout << \"\\nAfter deleting the largest box, the list contains:\\n\";\n  load1.listBoxes();\n\n  const size_t nBoxes{ 20 };            // Number of vector elements\n  std::vector<SharedBox> boxes;        // Array of Box objects\n\n  for (size_t i{}; i < nBoxes; ++i)\n    boxes.push_back(randomSharedBox());\n\n  Truckload load2{ boxes };\n  std::cout << \"\\nThe second list:\\n\";\n  load2.listBoxes();\n\n  const auto smallestBox{ findSmallestBox(load2) };\n\n  std::cout << \"\\nThe smallest box in the second list is \";\n  smallestBox->listBox();\n  std::cout << std::endl;\n}\n\nSharedBox findLargestBox(const Truckload& truckload)\n{\n  auto iterator{ truckload.getIterator() };  // Type of iterator is Truckload::Iterator\n  SharedBox largestBox{ iterator.getFirstBox() };\n\n  SharedBox nextBox{ iterator.getNextBox() };\n  while (nextBox)\n  {\n    if (nextBox->compare(*largestBox) > 0)\n      largestBox = nextBox;\n    nextBox = iterator.getNextBox();\n  }\n\n  return largestBox;\n}\n\nSharedBox findSmallestBox(const Truckload& truckload)\n{\n  auto iterator{ truckload.getIterator() };  // Type of iterator is Truckload::Iterator\n  SharedBox smallestBox{ iterator.getFirstBox() };\n\n  SharedBox nextBox{ iterator.getNextBox() };\n  while (nextBox)\n  {\n    if (nextBox->compare(*smallestBox) < 0)\n      smallestBox = nextBox;\n    nextBox = iterator.getNextBox();\n  }\n\n  return smallestBox;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_06/Truckload.cpp",
    "content": "module truckload;\n\nimport <iostream>;\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nvoid Truckload::listBoxes() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count {};  \n  for (Package* package{m_head}; package; package = package->m_next)\n  {\n    std::cout << ' ';\n    package->m_box->listBox();\n    if (! (++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n\n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_06/Truckload.cppm",
    "content": "export module truckload;\n\nimport box;\n\nimport <memory>;\nimport <vector>;\n\nexport using SharedBox = std::shared_ptr<Box>;\n\nexport class Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  void listBoxes() const;           // Output the Boxes\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the module interface)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_07/Box.cppm",
    "content": "export module box;\n\nimport <iostream>;\nimport <format>;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  void listBox() const\n  {\n    std::cout << std::format(\"Box({:.1f},{:.1f},{:.1f})\", m_length, m_width, m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_07/RandomBoxes.cppm",
    "content": "export module box.random;\n\nimport box;\nimport <random>;        // For random number generation\nimport <functional>;    // For std::bind()\nimport <memory>;        // For std::make_shared<>() and std::shared_ptr<>;\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\nexport Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\nexport auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_07/Soln12_07.cpp",
    "content": "// Create a doubly-linked list of Packages\nimport box.random;\nimport truckload;\nimport <iostream>;\n\n/*\n   To show reverse iteration, we've modified findSmallestBox() to iterate in reverse order\n */\n\nSharedBox findLargestBox(const Truckload& truckload);\nSharedBox findSmallestBox(const Truckload& truckload);\n\nint main()\n{\n  Truckload load;  // Create an empty list\n\n  // Add 12 random Box objects to the list\n  const size_t boxCount{ 12 };\n  for (size_t i{}; i < boxCount; ++i)\n    load.addBox(randomSharedBox());\n\n  std::cout << \"The random truckload:\\n\";\n  load.listBoxes();\n  std::cout << std::endl;\n\n  std::cout << \"The same random truckload in reverse:\\n\";\n  load.listBoxesReversed();\n  std::cout << std::endl;\n\n  std::cout << \"The largest box (found using forward iteration) is \";\n  findLargestBox(load)->listBox();\n  std::cout << std::endl;\n\n  std::cout << \"The smallest box (found using reverse iteration) is \";\n  findSmallestBox(load)->listBox();\n  std::cout << std::endl;\n}\n\nSharedBox findLargestBox(const Truckload& truckload)\n{\n  auto iterator{ truckload.getIterator() };  // Type of iterator is Truckload::Iterator\n  SharedBox largestBox{ iterator.getFirstBox() };\n\n  SharedBox nextBox{ iterator.getNextBox() };\n  while (nextBox)\n  {\n    if (nextBox->compare(*largestBox) > 0)\n      largestBox = nextBox;\n    nextBox = iterator.getNextBox();\n  }\n\n  return largestBox;\n}\n\nSharedBox findSmallestBox(const Truckload& truckload)\n{\n  auto iterator{ truckload.getIterator() };  // Type of iterator is Truckload::Iterator\n  SharedBox smallestBox{ iterator.getLastBox() };\n\n  SharedBox nextBox{ iterator.getPreviousBox() };\n  while (nextBox)\n  {\n    if (nextBox->compare(*smallestBox) < 0)\n      smallestBox = nextBox;\n    nextBox = iterator.getPreviousBox();\n  }\n\n  return smallestBox;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_07/Truckload.cpp",
    "content": "module truckload;\n\nimport <iostream>;\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n  Package* m_previous;  // Pointer to the previous Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{}, m_previous{} {}\n  ~Package() { delete m_next; }\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nvoid Truckload::listBoxes() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count {};  \n  for (Package* package{m_head}; package; package = package->m_next)\n  {\n    std::cout << ' ';\n    package->m_box->listBox();\n    if (! (++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\nvoid Truckload::listBoxesReversed() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count{};\n  for (Package* package{ m_tail }; package; package = package->m_previous)\n  {\n    std::cout << ' ';\n    package->m_box->listBox();\n    if (!(++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\nTruckload::Iterator Truckload::getIterator() const\n{ \n  return Iterator{ m_head, m_tail }; \n}\n\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\nSharedBox Truckload::Iterator::getLastBox()\n{\n  // Return m_tail's box (or nullptr if the list is empty)\n  m_current = m_tail;\n  return m_current ? m_current->m_box : nullptr;\n}\n\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nSharedBox Truckload::Iterator::getPreviousBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getLastBox();                          // ...return the last Box\n\n  m_current = m_current->m_previous;              // Move to the next package\n\n  return m_current ? m_current->m_box : nullptr;  // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n  {\n    package->m_previous = m_tail;  // The package is added after the old tail\n    m_tail->m_next = package;      // Append the new object to the tail\n  }\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n  \n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  // No need for a trailing pointer anymore!\n  // (We can go back one using the m_previous pointer of the doubly-linked list...)\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // Update the doubly-linked list pointers \n      // (make a sketch of this to better see what is going on here!)\n      if (current->m_previous) current->m_previous->m_next = current->m_next;\n      if (current->m_next) current->m_next->m_previous = current->m_previous;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = current->m_previous;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }  \n\n    current = current->m_next;       //  Move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_07/Truckload.cppm",
    "content": "export module truckload;\n\nimport box;\n\nimport <memory>;\nimport <vector>;\n\nexport using SharedBox = std::shared_ptr<Box>;\n\nexport class Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  void listBoxes() const;           // Output the Boxes\n  void listBoxesReversed() const;   // Output the Boxes in reversed order\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the module interface)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();    // Get the first Box\n  SharedBox getLastBox();     // Get the first Box\n  SharedBox getNextBox();     // Get the next Box\n  SharedBox getPreviousBox(); // Get the previous Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_tail;          // The tail of the linked list (needed for getLastBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head, Package* tail) \n    : m_head{ head }\n    , m_tail{ tail }\n    , m_current{ nullptr } \n  {}\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_08/Box.cppm",
    "content": "export module box;\n\nimport <iostream>;\nimport <format>;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  void listBox() const\n  {\n    std::cout << std::format(\"Box({:.1f},{:.1f},{:.1f})\", m_length, m_width, m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_08/RandomBoxes.cppm",
    "content": "export module box.random;\n\nimport box;\nimport <random>;        // For random number generation\nimport <functional>;    // For std::bind()\nimport <memory>;        // For std::make_shared<>() and std::shared_ptr<>;\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\nexport Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\nexport auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_08/Soln12_08.cpp",
    "content": "// Remove Boxes from a Truckload without searching a second time\nimport box.random;\nimport truckload;\nimport <iostream>;\n\n/********************************************************************************\\\n  The key to the solution is that the Iterator object already contains\n  a pointer to the Package that needs to be removed.\n  Of course, external code cannot use a Package, but it can use the Iterator.\n  To exploit the knowledge contained in the Iterator, we add an overload\n  of the removeBox() function with an Iterator parameter instead of a Box.\n\n  To facilitate things, we also added getCurrentBox() to Iterator,\n  which allowed us to remove some duplicated code in the various other getters\n  of that class.\n  \n  Both findLargestBox() and findSmallestBox() are updated to return an Iterator\n  as well. Note that the same technique is used by all Standard Library \n  containers and algorithms (see Chapter 20)!\n\n  Notice also that we created removePackage() to avoid duplicating this code\n  in the two overloads of removeBox().\n\n  An alternative solution that also does not duplicate the removal logic\n  consists of using an Iterator in removeBox(SharedBox), \n  and then invoke removeBox(Iterator) once the box is found. \n  removePackage() is then no longer required. We recommend you give this a try!\n\\**********************************************************************************/\n\nTruckload::Iterator findLargestBox(const Truckload& truckload);\nTruckload::Iterator findSmallestBox(const Truckload& truckload);\n\nint main()\n{\n  Truckload load;  // Create an empty list\n\n  // Add 12 random Box objects to the list\n  const size_t boxCount{ 12 };\n  for (size_t i{}; i < boxCount; ++i)\n    load.addBox(randomSharedBox());\n\n  std::cout << \"The random truckload:\\n\";\n  load.listBoxes();\n  std::cout << std::endl;\n\n  const auto largestIter{ findLargestBox(load) };\n  const auto smallestIter{ findSmallestBox(load) };\n\n  std::cout << \"The largest box (found using forward iteration) is \";\n  largestIter.getCurrentBox()->listBox();\n  std::cout << '\\n' << std::endl;\n\n  load.removeBox(largestIter);\n\n  std::cout << \"The truckload without its largest box:\\n\";\n  load.listBoxes();\n  std::cout << std::endl;\n\n  std::cout << \"The smallest box (found using reverse iteration) is \";\n  smallestIter.getCurrentBox()->listBox();\n  std::cout << '\\n' << std::endl;\n  \n  load.removeBox(smallestIter);\n\n  std::cout << \"The truckload without its smallest box (in reverse order):\\n\";\n  load.listBoxesReversed();\n}\n\nTruckload::Iterator findLargestBox(const Truckload& truckload)\n{\n  auto iterator{ truckload.getIterator() };  // Type of iterator is Truckload::Iterator\n  iterator.getFirstBox();\n  auto largestBoxIterator{ iterator };\n\n  while (iterator.getNextBox())\n  {\n    if (iterator.getCurrentBox()->compare(*largestBoxIterator.getCurrentBox()) > 0)\n    {\n      largestBoxIterator = iterator;\n    }\n  }\n\n  return largestBoxIterator;\n}\n\nTruckload::Iterator findSmallestBox(const Truckload& truckload)\n{\n  auto iterator{ truckload.getIterator() };  // Type of iterator is Truckload::Iterator\n  iterator.getLastBox();\n  auto smallestBoxIterator{ iterator };\n\n  while (iterator.getPreviousBox())\n  {\n    if (iterator.getCurrentBox()->compare(*smallestBoxIterator.getCurrentBox()) < 0)\n    {\n      smallestBoxIterator = iterator;\n    }\n  }\n\n  return smallestBoxIterator;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_08/Truckload.cpp",
    "content": "module truckload;\n\nimport <iostream>;\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n  Package* m_previous;  // Pointer to the previous Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{}, m_previous{} {}\n  ~Package() { delete m_next; }\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nvoid Truckload::listBoxes() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count {};  \n  for (Package* package{m_head}; package; package = package->m_next)\n  {\n    std::cout << ' ';\n    package->m_box->listBox();\n    if (! (++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\nvoid Truckload::listBoxesReversed() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count{};\n  for (Package* package{ m_tail }; package; package = package->m_previous)\n  {\n    std::cout << ' ';\n    package->m_box->listBox();\n    if (!(++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\nTruckload::Iterator Truckload::getIterator() const\n{ \n  return Iterator{ m_head, m_tail }; \n}\n\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return getCurrentBox();\n}\n\nSharedBox Truckload::Iterator::getLastBox()\n{\n  // Return m_tail's box (or nullptr if the list is empty)\n  m_current = m_tail;\n  return getCurrentBox();\n}\n\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return getCurrentBox();\n}\n\nSharedBox Truckload::Iterator::getPreviousBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getLastBox();                          // ...return the last Box\n\n  m_current = m_current->m_previous;              // Move to the next package\n\n  return getCurrentBox();\n}\n\nSharedBox Truckload::Iterator::getCurrentBox() const\n{\n  return m_current ? m_current->m_box : nullptr;\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n  {\n    package->m_previous = m_tail;  // The package is added after the old tail\n    m_tail->m_next = package;      // Append the new object to the tail\n  }\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n  \n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  for (auto* current{ m_head }; current != nullptr; current = current->m_next)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      removePackage(current);\n      return true;\n    }  \n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nbool Truckload::removeBox(Iterator iter)\n{\n  if (iter.m_current)\n  {\n    removePackage(iter.m_current);\n    return true;\n  }\n  else\n  {\n    return false;\n  }\n}\n\nvoid Truckload::removePackage(Package* package)\n{\n  // Update the doubly-linked list pointers\n  if (package->m_previous) package->m_previous->m_next = package->m_next;\n  if (package->m_next) package->m_next->m_previous = package->m_previous;\n\n  // Update pointers in member variables where required:\n  if (package == m_head) m_head = package->m_next;\n  if (package == m_tail) m_tail = package->m_previous;\n\n  package->m_next = nullptr;     // Disconnect the current Package from the list\n  delete package;                // and delete it\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 12/Soln12_08/Truckload.cppm",
    "content": "export module truckload;\n\nimport box;\n\nimport <memory>;\nimport <vector>;\n\nexport using SharedBox = std::shared_ptr<Box>;\n\nexport class Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n  bool removeBox(Iterator iter);    // Remove the Box pointed to by this Iterator\n\n  void listBoxes() const;           // Output the Boxes\n  void listBoxesReversed() const;   // Output the Boxes in reversed order\n\nprivate:\n  class Package;\n\n  void removePackage(Package* package);\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the module interface)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();    // Get the first Box\n  SharedBox getLastBox();     // Get the first Box\n  SharedBox getNextBox();     // Get the next Box\n  SharedBox getPreviousBox(); // Get the previous Box\n  SharedBox getCurrentBox() const;  // Get the current Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_tail;          // The tail of the linked list (needed for getLastBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head, Package* tail) \n    : m_head{ head }\n    , m_tail{ tail }\n    , m_current{ nullptr } \n  {}\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_01/Box.cpp",
    "content": "module box;\n\nimport <format>;\nimport <algorithm>;    // For the min() and max() function templates\n\ndouble Box::volume() const\n{\n    return m_length * m_width * m_height;\n}\n\nBox Box::operator+(const Box& aBox) const\n{\n  // New object has larger length and width, and sum of heights\n  return Box{ std::max(m_length, aBox.m_length),\n              std::max(m_width, aBox.m_width),\n              m_height + aBox.m_height };\n}\n\nBox Box::operator*(double factor) const\n{\n  return Box{ m_length * factor, m_width * factor, m_height * factor, };\n}\n\nstd::partial_ordering Box::operator<=>(const Box& aBox) const\n{\n  return volume() <=> aBox.volume();\n}\n\nstd::partial_ordering Box::operator<=>(double value) const\n{\n  return volume() <=> value;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                          box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_01/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\nimport <ostream>;  // For std::ostream\n\nexport class Box\n{\npublic:\n  Box() = default;       // Default constructor\n  Box(double length, double width, double height)\n    : m_length{ std::max(length,width) }\n    , m_width { std::min(length,width) }\n    , m_height{ height } \n  {}\n\n  double volume() const; // Function to calculate the volume\n  \n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions that add full support for comparison operators\n  std::partial_ordering operator<=>(const Box& aBox) const;\n  std::partial_ordering operator<=>(double value) const;\n  bool operator==(const Box& aBox) const = default;\n\n  Box operator+(const Box& aBox) const; // Function to add two Box objects\n  Box operator*(double factor) const;   // Function to multiply a Box with a given factor\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Box& box);\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_01/Soln13_01.cpp",
    "content": "// Exercise 13-1\n// Implementing the * operator for the Box class\n// to post-multiply by an integer\nimport <iostream>;\nimport box;\n\nint main()\n{\n  Box box {2, 3, 4};\n  std::cout << \"Box is \" << box << std::endl;\n  unsigned n {3};\n  Box newBox{ box * n };\n  std::cout << \"After multiplying by \" << n << \" box is \" << newBox << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_02/Box.cpp",
    "content": "module box;\n\nimport <format>;\nimport <algorithm>;    // For the min() and max() function templates\n\ndouble Box::volume() const\n{\n    return m_length * m_width * m_height;\n}\n\nBox Box::operator+(const Box& aBox) const\n{\n  // New object has larger length and width, and sum of heights\n  return Box{ std::max(m_length, aBox.m_length),\n              std::max(m_width, aBox.m_width),\n              m_height + aBox.m_height };\n}\n\nBox Box::operator*(double factor) const\n{\n  return Box{ m_length * factor, m_width * factor, m_height * factor };\n}\n\nBox operator*(double factor, const Box& box)\n{\n  // Or: return box * factor;\n  return Box{ box.getLength() * factor, box.getWidth() * factor, box.getHeight() * factor };\n}\n\nstd::partial_ordering Box::operator<=>(const Box& aBox) const\n{\n  return volume() <=> aBox.volume();\n}\n\nstd::partial_ordering Box::operator<=>(double value) const\n{\n  return volume() <=> value;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                          box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_02/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\nimport <ostream>;  // For std::ostream\n\nexport class Box\n{\npublic:\n  Box() = default;       // Default constructor\n  Box(double length, double width, double height)\n    : m_length{ std::max(length,width) }\n    , m_width { std::min(length,width) }\n    , m_height{ height } \n  {}\n\n  double volume() const; // Function to calculate the volume\n  \n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions that add full support for comparison operators\n  std::partial_ordering operator<=>(const Box& aBox) const;\n  std::partial_ordering operator<=>(double value) const;\n  bool operator==(const Box& aBox) const = default;\n\n  Box operator+(const Box& aBox) const; // Function to add two Box objects\n  Box operator*(double factor) const;   // Function to multiply a Box with a given factor\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Function to pre-multiply a Box with a given factor\nexport Box operator*(double factor, const Box& box);\n\nexport std::ostream& operator<<(std::ostream& stream, const Box& box);\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_02/Soln13_02.cpp",
    "content": "// Exercise 13-2\n// Implementing the * operator for the Box class to pre-multiply by a number\nimport <iostream>;\nimport box;\n\nint main()\n{\n  Box box {2, 3, 4};\n  std::cout << \"Box is \" << box << std::endl;\n  unsigned n {3};\n  Box newBox{ n * box };\n  std::cout << \"After pre-multiplying by \" << n << \" box is \" << newBox << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_03/Box.cpp",
    "content": "module box;\n\nimport <format>;\nimport <algorithm>;    // For the min() and max() function templates\n\ndouble Box::volume() const\n{\n    return m_length * m_width * m_height;\n}\n\nBox Box::operator+(const Box& aBox) const\n{\n  Box copy{ *this };  // Implement in terms of += operator (avoid duplication)\n  copy += aBox;\n  return copy;        // Return new object (convention)\n}\n\nBox Box::operator*(double factor) const\n{\n  Box copy{ *this };  // Implement in terms of *= operator (avoid duplication)\n  copy *= factor;\n  return copy;        // Return new object (convention)\n}\n\nBox Box::operator/(double divisor) const\n{\n  Box copy{ *this };  // Implement in terms of /= operator (avoid duplication)\n  copy /= divisor;\n  return copy;        // Return new object (convention)\n}\n\nBox& Box::operator+=(const Box& aBox)\n{\n  // New object has larger length and width, and sum of heights\n  m_length = std::max(m_length, aBox.m_length);\n  m_width  = std::max(m_width, aBox.m_width);\n  m_height += aBox.m_height;\n  return *this;   // Return a reference to the left operand (convention)\n}\n\nBox& Box::operator*=(double factor)\n{\n  m_length *= factor;\n  m_width  *= factor;\n  m_height *= factor;\n  return *this;   // Return a reference to the left operand (convention)\n}\n\nBox& Box::operator/=(double divisor)\n{\n  m_length /= divisor;\n  m_width  /= divisor;\n  m_height /= divisor;\n  return *this;   // Return a reference to the left operand (convention)\n}\n\nBox operator*(double factor, const Box& box)\n{\n  return box * factor;\n}\n\nstd::partial_ordering Box::operator<=>(const Box& aBox) const\n{\n  return volume() <=> aBox.volume();\n}\n\nstd::partial_ordering Box::operator<=>(double value) const\n{\n  return volume() <=> value;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                          box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_03/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\nimport <ostream>;  // For std::ostream\n\nexport class Box\n{\npublic:\n  Box() = default;       // Default constructor\n  Box(double length, double width, double height)\n    : m_length{ std::max(length,width) }\n    , m_width { std::min(length,width) }\n    , m_height{ height } \n  {}\n\n  double volume() const; // Function to calculate the volume\n  \n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions that add full support for comparison operators\n  std::partial_ordering operator<=>(const Box& aBox) const;\n  std::partial_ordering operator<=>(double value) const;\n  bool operator==(const Box& aBox) const = default;\n\n  Box operator+(const Box& aBox) const; // Function to add two Box objects\n  Box operator*(double factor) const;   // Function to multiply a Box with a given factor\n  Box operator/(double divisor) const;  // Function to divide a Box by a given divisor\n\n  Box& operator+=(const Box& aBox);\n  Box& operator*=(double factor);\n  Box& operator/=(double divisor);\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Function to pre-multiply a Box with a given factor\nexport Box operator*(double factor, const Box& box);\n\nexport std::ostream& operator<<(std::ostream& stream, const Box& box);\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_03/Soln13_03.cpp",
    "content": "// Exercise 13-3\n// Implementing the missing /, *=, +=, and /= operators for the Box class\nimport <iostream>;\nimport box;\n\nint main()\n{\n  Box box {2, 3, 4};\n  std::cout << \"Box is \" << box << std::endl;\n  size_t n {3};\n  box *= 3;\n  std::cout << \"After multiplying by \" << n << \" box is \" << box << std::endl;\n  box /= 3;\n  std::cout << \"After dividing by \" << n << \", the box is again \" << box << std::endl;\n  \n  Box newBox {2 * box};\n  std::cout << \"Twice \" << box << \" is \" << newBox << std::endl;\n  \n  std::cout << \"Half that is again \" << (newBox / 2) << std::endl;\n  \n  std::cout << \"Adding both boxes gives \" << (box + newBox) << std::endl;\n  \n  box += newBox;\n  \n  std::cout << \"The same can be obtained by usign += as well: \" << box << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_04/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\nimport <ostream>;  // For std::ostream\nimport <format>;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\n  bool operator==(double otherVolume) const\n  {\n    return volume() == otherVolume;\n  }\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                             box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_04/Soln13_04.cpp",
    "content": "// Exercise 13-4\n// Adding support for equality operators that compare Boxes and volumes\nimport <iostream>;\nimport box;\n\n/*\n  Because the C++20 compiler automatically rewrites != expression \n  in terms of == and/or even reverses the order of the operands,\n  only one additional operator overload definition is required to make it all work.\n*/\n\nint main()\n{\n  Box box1{ 1, 2, 3 };\n  Box box2{ 3, 2, 1 };\n  Box box3{ 1, 2, 3 };\n\n  // Try out all == and != operators (old and new, the latter in both directions)\n  std::cout << \"box1 and box2 are \" << (box1 == box2 ? \"\" : \"not \") << \"equal\\n\";\n  std::cout << \"box1 and box3 are \" << (box1 != box3 ? \"not \" : \"\") << \"equal\\n\";\n  std::cout << \"box1 is \" << (box1 == 6.0 ? \"\" : \"not \") << \"equal to 6.0\\n\";\n  std::cout << \"10.0 is \" << (10 != box2 ? \"not \" : \"\") << \"equal to box2\\n\";\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_05/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\nimport <ostream>;  // For std::ostream\nimport <format>;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\n  // Unary negation operator (!box is true if the Box has no volume)\n  bool operator!() const { return volume() == 0; }  \n\n  // Type conversion operator (converts a Box to a Boolean; true if it has volume)\n  operator bool() const  { return volume() != 0; }  \n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                             box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_05/Soln13_05.cpp",
    "content": "// Exercise 13-5\n// Implementing the obvious operators for the Box class \n// to allow it to be used, for instance, in if statements.\n// A Box is \"true\" if and only if its volume is non-zero.\nimport <iostream>;\nimport box;\n\nvoid testBox(const Box& box)\n{\n  std::cout << \"The box's volume is \" << box.volume() << \".\\n\";\n  if (box)\n\t  std::cout << \"This volume is non-zero.\";\n  if (!box)\n\t  std::cout << \"This volume is zero.\";\n  std::cout << std::endl;\n}\n\nint main()\n{\n  Box box1{2, 3, 4};\n  std::cout << \"box1 is \" << box1 << std::endl;\n  testBox(box1);\n  \n  std::cout << std::endl;;\n\n  Box box2{0, 0, 0};\n  std::cout << \"box2 is \" << box2 << std::endl;\n  testBox(box2);  \n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_06/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\nimport <ostream>;  // For std::ostream\nimport <format>;\n\nexport class Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\n  // Explicit type conversion operator (converts a Box to a Boolean; true if it has volume)\n  explicit operator bool() const  { return volume() != 0; }  \n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                             box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_06/Soln13_06.cpp",
    "content": "// Exercise 13-6\n// In canonical C++, you should only implement a single operator to allow \n// objects to be used in if statements, and in Boolean expressions in general:\n// a conversion operator for type bool.\n//\n// This conversion operator, moreover, is normally qualified as explicit.\n// This is far from obvious: despite the explicit qualifier,\n// objects still implicitly convert to bool in, for instance, if statements.\n// As illustrated at the bottom of main(), however, \n// simply assigning a Box to a variable of type bool indeed no longer works\n// without an explicit type conversion (in most cases this is the desired behavior).\nimport <iostream>;\nimport box;\n\nvoid testBox(const Box& box)\n{\n  std::cout << \"The box's volume is \" << box.volume() << \".\\n\";\n  if (box)\n\t  std::cout << \"This volume is non-zero.\";\n  if (!box)\n\t  std::cout << \"This volume is zero.\";\n  std::cout << std::endl;\n}\n\nint main()\n{\n  Box box1{2, 3, 4};\n  std::cout << \"box1 is \" << box1 << std::endl;\n  testBox(box1);\n  \n  std::cout << std::endl;;\n\n  Box box2{0, 0, 0};\n  std::cout << \"box2 is \" << box2 << std::endl;\n  testBox(box2);  \n\n  // bool b1{ box1 };    /* Does not compile! */\n  bool b2{ static_cast<bool>(box2) };  // Needs an explicit type conversion\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_07/Rational.cppm",
    "content": "export module rational;\nimport <iostream>;\n\nexport class Rational\n{\npublic:\n  // Constructor\n  Rational(int numerator = 0, int denominator = 1) \n    : m_numerator {numerator}, m_denominator {denominator}\n  {}\n\n  // Accessors\n  int getNumerator() const { return m_numerator; }\n  int getDenominator() const { return m_denominator; }\n  \n  // Mutators\n  void setNumerator(int numerator) { m_numerator = numerator; }\n  void setDenominator(int denominator) { m_denominator = denominator; }\n  \n  // Casting operators (could be non-explicit as well: is a matter of taste)\n  explicit operator double() const { return static_cast<double>(m_numerator) / m_denominator; }\n  explicit operator float() const { return static_cast<float>(m_numerator) / m_denominator; }\n  \n  // Full support for all comparison operators with both Rational and double\n  // through the magic of the spaceship operator. \n  // The only other operator you need to define here is equality\n  // (because the spaceship operator cannot be defaulted).\n  auto operator<=>(const Rational& other)\n  {\n    return m_numerator * other.m_denominator <=> other.m_numerator * m_denominator;\n  }\n  auto operator<=>(double value)\n  {\n    return static_cast<double>(*this) <=> value;\n  }\n  bool operator==(const Rational& other)\n  {\n    return m_numerator * other.m_denominator == other.m_numerator * m_denominator;\n  }\n  bool operator==(double value)\n  {\n    return static_cast<double>(*this) == value;\n  }\n\n  // Unary arithmetic operator\n  Rational operator-() const { return Rational{-m_numerator, m_denominator}; }   \n  \n  // A Rational is false if and only if its numerator equals zero.\n  // Note: for operator bool(), we used explicit here to sidestep ambiguities with other operators.\n  // We did not add operator!, \n  // because this conversion operator covers all use in Boolean expressions \n  // (see also previous exercise).\n  explicit operator bool() const  { return m_numerator != 0; }         \n  \n  // Compound assignment operators\n  Rational& operator+=(const Rational& other)\n  {\n    m_numerator = m_numerator * other.m_denominator + other.m_numerator * m_denominator;\n    m_denominator = m_denominator * other.m_denominator;\n    return *this;\n  };\n  Rational& operator-=(const Rational& other)\n  { \n    m_numerator = m_numerator * other.m_denominator - other.m_numerator * m_denominator;\n    m_denominator = m_denominator * other.m_denominator;\n    return *this;\n  };\n  Rational& operator*=(const Rational& other)\n  { \n    m_numerator *= other.m_numerator;\n\t  m_denominator *= other.m_denominator;\n\t  return *this;\n  };\n  Rational& operator/=(const Rational& other)\n  { \n    m_numerator *= other.m_denominator;\n    m_denominator *= other.m_numerator;\n    return *this;\n  };\n\n  // Prefix and postfix increment and decrement operators\n  Rational& operator++() \n  { \n    m_numerator += m_denominator;\n    return *this;\n  }\n  const Rational operator++(int)\n  {\n    auto copy(*this);   // Create a copy of the current object\n    ++(*this);          // Increment the current object using the prefix operator...\n    return copy;        // Return the unincremented copy\n  }\n  Rational& operator--() \n  { \n    m_numerator -= m_denominator;\n    return *this;\n  }\n\n  const Rational operator--(int)\n  {\n    auto copy(*this);   // Create a copy of the current object\n    --(*this);          // Increment the current object using the prefix operator...\n    return copy;        // Return the unincremented copy\n  }\n\nprivate:\n  int m_numerator, m_denominator;\n};\n\n// Stream output operator\nexport std::ostream& operator<<(std::ostream& stream, const Rational& r)\n{\n\treturn stream << r.getNumerator() << '/' << r.getDenominator();\n}\n\n// Binary arithmetic operators: non-member functions to allow for implicit conversions\n// This allows expressions such as 2 * (myRationale + 1)\nexport Rational operator+(const Rational& one, const Rational& other) { auto copy{ one }; return copy += other; }\nexport Rational operator-(const Rational& one, const Rational& other) { auto copy{ one }; return copy -= other; }\nexport Rational operator*(const Rational& one, const Rational& other) { auto copy{ one }; return copy *= other; }\nexport Rational operator/(const Rational& one, const Rational& other) { auto copy{ one }; return copy /= other; }\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_07/Soln13_07.cpp",
    "content": "// Exercise 13-7\n// Rational operators\nimport <iostream>;\nimport rational;\n\nint main()\n{\n  Rational x{3, 4};\n  Rational y{1, 2};\n  \n  std::cout << \"x = \" << x << std::endl;\n  std::cout << \"y = \" << y << std::endl;\n  \n  std::cout << \"x = \" << static_cast<float>(x) << std::endl;\n  std::cout << \"y = \" << static_cast<double>(y) << std::endl;\n  \n  std::cout << \"-x = \" << -x << std::endl;\n  \n  std::cout << \"x + y = \" << x + y << std::endl;\n  std::cout << \"x - y = \" << x - y << std::endl;\n  std::cout << \"x * y = \" << x * y << std::endl;\n  std::cout << \"x / y = \" << x / y << std::endl;\n  \n  std::cout << \"x + 2 = \" << x + 2 << std::endl;\n  std::cout << \"3 - y = \" << 3 - y << std::endl;\n  std::cout << \"x * 4 = \" << x * 4 << std::endl;\n  std::cout << \"5 / y = \" << 5 / y << std::endl;\n  \n  std::cout << std::boolalpha;  // Print true and false as \"true\" and \"false\" instead of \"1\" and \"0\"\n  std::cout << \"x < y = \" << (x < y) << std::endl;\n  std::cout << \"x > y = \" << (x > y) << std::endl;\n  std::cout << \"x == y = \" << (x == y) << std::endl;\n  std::cout << \"x != y = \" << (x != y) << std::endl;\n  std::cout << \"x >= y = \" << (x >= y) << std::endl;\n  std::cout << \"x >= y = \" << (x <= y) << std::endl;\n  \n  std::cout << \"x < 1 = \" << (x < 1) << std::endl;\n  std::cout << \"2 > y = \" << (2 > y) << std::endl;\n  std::cout << \"x == 3 = \" << (x == 3) << std::endl;\n  std::cout << \"4 != y = \" << (4 != y) << std::endl;\n  std::cout << \"x >= 5 = \" << (x >= 5) << std::endl;\n  std::cout << \"6 >= y = \" << (6 <= y) << std::endl;\n  \n  std::cout << \"x < 1.0 = \" << (x < 1.0) << std::endl;\n  std::cout << \"2 > y = \" << (2.0 > y) << std::endl;\n  std::cout << \"x == 0.75 = \" << (x == 0.75) << std::endl;\n  std::cout << \"1.5 != y = \" << (1.5 != y) << std::endl;\n  std::cout << \"x >= 5 = \" << (x >= 5.0) << std::endl;\n  std::cout << \"6 >= y = \" << (6.0 <= y) << std::endl;\n  \n  x += Rational(1, 4);\n  std::cout << \"x += 1/4 --> x = \" << x << std::endl;\n  x *= 2;\n  std::cout << \"x *= 2 --> x = \" << x << std::endl;\n  \n  y += 1;\n  std::cout << \"y += 1 --> y = \" << y << std::endl;\n  \n  std::cout << \"y++ = \" << y++ << std::endl;\n  std::cout << \"y = \" << y << std::endl;\n  std::cout << \"--y = \" << --y << std::endl;\n}\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_08/Box.cpp",
    "content": "module;\n#include <cmath>    // For the min() and max() function templates\nmodule box;\n\nimport <format>;\n\ndouble Box::volume() const\n{\n    return m_length * m_width * m_height;\n}\n\n// Overloaded += operator\nBox& Box::operator+=(const Box& aBox)\n{\n  // New object has larger length and width, and sum of heights\n  m_length = std::max(m_length, aBox.m_length);\n  m_width = std::max(m_width, aBox.m_width);\n  m_height += aBox.m_height;\n  return *this;\n}\n\n// Function to add two Box objects\nBox Box::operator+(const Box& aBox) const\n{\n  Box copy{ *this };\n  copy += aBox;\n  return copy;\n}\n\nstd::partial_ordering Box::operator<=>(const Box& aBox) const\n{\n  return volume() <=> aBox.volume();\n}\n\nstd::partial_ordering Box::operator<=>(double value) const\n{\n  return volume() <=> value;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                          box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_08/Box.cppm",
    "content": "export module box;\n\nimport <compare>;  // For std::partial_ordering (see Chapter 4)\nimport <ostream>;  // For std::ostream\n\nexport class Box\n{\npublic:\n  Box() = default;       // Default constructor\n  Box(double length, double width, double height)\n    : m_length{ std::max(length,width) }\n    , m_width { std::min(length,width) }\n    , m_height{ height } \n  {}\n\n  double volume() const; // Function to calculate the volume\n  \n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions that add full support for comparison operators\n  std::partial_ordering operator<=>(const Box& aBox) const;\n  std::partial_ordering operator<=>(double value) const;\n  bool operator==(const Box& aBox) const = default;\n\n  Box& operator+=(const Box& aBox);      // Function to add a Box objects\n  Box operator+(const Box& aBox) const; // Function to add two Box objects\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Box& box);\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_08/PRNG.cppm",
    "content": "export module PRNG;\n\nexport class PseudoRandomNumberGenerator\n{\npublic:\n  PseudoRandomNumberGenerator(int n = 0)\n    : m_n{ n }\n  {}\n\n  // A function call operator (no parameters, return type int)\n  // Unlike many function call operators, this one alters the state of the object.\n  int operator()()\n  {\n    const int current{ m_n };\n    m_n = (m_n * 41 + 7) % 100; // See chapter 12\n    return current;\n  }\n\nprivate:\n  int m_n;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_08/Soln13_08.cpp",
    "content": "// Exercise 13-8\n// Creating a simply pseudo-random number generator (PRNG) functor class.\n// Ours is a very limited one that generates numbers between 0 and 100.\n// Seeding and using it requires some type conversions,\n// but other than that our PRNG functor acts as a drop-in replacement to the original one!\nimport <iostream>;\nimport <format>;\nimport <vector>;\nimport <random>;       // For random number generation\nimport <functional>;   // For std::bind()\nimport box;\nimport PRNG;\n\nint main()\n{\n  const double limit {99};       // Upper limit on Box dimensions\n\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  auto random{ PseudoRandomNumberGenerator{ static_cast<int>(seeder()) } };\n\n  const size_t boxCount {20}; // Number of Box object to be created\n  std::vector<Box> boxes;     // Vector of Box objects\n\n  // Create 20 Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    boxes.push_back(Box{ static_cast<double>(random()), static_cast<double>(random()), static_cast<double>(random()) });\n\n  size_t first {};     // Index of first Box object of pair\n  size_t second {1};   // Index of second Box object of pair\n  double minVolume {(boxes[first] + boxes[second]).volume()};\n\n  for (size_t i {}; i < boxCount - 1; ++i)\n  {  \n    for (size_t j {i + 1}; j < boxCount; j++)\n    {\n      if (boxes[i] + boxes[j] < minVolume)\n      {\n        first = i;\n        second = j;\n        minVolume = (boxes[i] + boxes[j]).volume();\n      }\n    }\n  }\n\n  std::cout << \"The two boxes that sum to the smallest volume are \"\n            << boxes[first] << \" and \" << boxes[second] << '\\n';\n  std::cout << std::format(\"The volume of the first box is {:.1f}\\n\",\n                            boxes[first].volume());\n  std::cout << std::format(\"The volume of the second box is {:.1f}\\n\",\n                            boxes[second].volume());\n  std::cout << \"The sum of these boxes is \" << (boxes[first] + boxes[second]) << '\\n';\n  std::cout << std::format(\"The volume of the sum is {:.1f}\", minVolume) << std::endl;\n\n  Box sum{ 0, 0, 0 };            // Start from an empty Box\n  for (const auto& box : boxes)  // And then add all randomly generated Box objects\n    sum += box;\n\n  std::cout << \"The sum of \" << boxCount << \" random boxes is \" << sum << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_09/Box.cppm",
    "content": "export module box;\n\nimport <ostream>;\nimport <format>;\nimport <algorithm>;    // For the std::min()/max() function templates\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f},{:.1f},{:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\n  Box operator+(const Box& aBox) const   // Function to add two Box objects\n  {\n    return Box{ std::max(m_length, aBox.m_length),\n                std::max(m_width, aBox.m_width),\n                m_height + aBox.m_height }; \n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_09/Soln13_09.cpp",
    "content": "// Exercise 13-9\n// Adding an assignment operator for Truckload\nimport <iostream>;\nimport <memory>;\nimport <random>;       // For random number generation\nimport <functional>;   // For std::bind()\nimport truckload;\n\n// See Chapter 12 for an explanation of this function\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 1.0, max }; // Generate in [1, max) interval\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\nint main()\n{\n  const double limit{ 99.0 };    // Upper limit on Box dimensions\n  auto random{ createUniformPseudoRandomNumberGenerator(limit) };\n\n  Truckload load;\n  const size_t boxCount {20};               // Number of Box object to be created\n\n  // Create boxCount Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    load.addBox(std::make_shared<Box>(random(), random(), random()));\n\n  std::cout << \"The boxes in the Truckload are:\\n\";\n  std::cout << load << std::endl;\n\n  Truckload copied;\n  copied = load;\t\t// Use copy assignment\n \n  std::cout << \"The boxes in the copied Truckload are:\\n\";\n  std::cout << copied;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_09/Truckload.cpp",
    "content": "module truckload;\n\nimport <iostream>;\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\nTruckload& Truckload::operator=(const Truckload& other)\n{\n  if (&other != this)   // Do not forget: avoid issues with self-assignment!\n  {\n    delete m_head;              // Delete all current packages\n    m_head = m_tail = nullptr;  // Reset both pointers\n\n    // Same as copy constructor \n    // (see Chapter 17 for the copy-and-swap idiom that allows you to avoid \n    // duplicating logic like this...)\n    for (Package* package{ other.m_head }; package; package = package->m_next)\n    {\n      addBox(package->m_box);\n    }\n  }\n\n  return *this;\n}\n\n// Destructor: clean up the list\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nSharedBox& Truckload::operator[](size_t index) const\n{\n  size_t count{};             // Package count\n  for (Package* package{ m_head }; package; package = package->m_next)\n  {\n    if (count++ == index)      // Up to index yet?\n      return package->m_box;   // If so return the pointer to Box\n  }\n  return nullBox;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 13/Soln13_09/Truckload.cppm",
    "content": "export module truckload;\n\nimport box;\n\nimport <memory>;\nimport <vector>;\nimport <ostream>;\n\nusing SharedBox = std::shared_ptr<Box>;\n\nexport class Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  \n  Truckload(const Truckload& src);  // Copy constructor\n  Truckload& operator=(const Truckload& other);  // Copy assignment operator\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox& operator[](size_t index) const;   // Overloaded subscript operator\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n\n  static inline SharedBox nullBox{}; // Pointer to nullptr\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Truckload& load);\n"
  },
  {
    "path": "Exercises/Modules/Chapter 14/Soln14_01/Animals.cppm",
    "content": "// Animal class and classes derived from Animal\nexport module animals;\n\n// Note: Animal, Lion, and Aardvark would typically be defined each in their own (sub)module.\n// This example shows that this does not have to be the case; that is:\n//  - file and module names do not have to match the name of a class; and\n//  - multiple classes may be declared and defined in the same module\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\n\nexport class Animal\n{\npublic:\n  Animal(std::string_view name, int weight)     // Constructor\n    : m_name{ name }, m_weight{ weight }\n  {}\n  \n  void who() const                  // Display name and weight\n  {\n    std::cout << \"My name is \" << m_name << \" and I weigh \" << m_weight << \"lbs.\" << std::endl;\n  }\n\nprivate:\n  std::string m_name;                    // Name of the animal\n  int m_weight;                        // Weight of the animal\n};\n\nexport class Lion : public Animal\n{\npublic:\n  // Define Lion constructor that calls base class constructor\n  Lion(std::string_view name, int weight)  \n\t  : Animal{name, weight} {}\n};\n\nexport class Aardvark : public Animal\n{\npublic:\n  using Animal::Animal;  // Inherit constructor instead (preferred)\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 14/Soln14_01/Soln14_01.cpp",
    "content": "// Exercise 14-1 Exercising the Animal classes\n// The solution shows two options, with the second one being the preferred option.\nimport animals;\n\nint main()\n{\n  Lion myLion{\"Leo\", 400};\n  Aardvark myAardvark{\"Algernon\", 50};\n  myLion.who();\n  myAardvark.who();\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 14/Soln14_02/Animals.cppm",
    "content": "// Animal class and classes derived from Animal\n\nexport module animals;\n\nimport <string>;\nimport <string_view>;\nimport <iostream>;\n\nexport class Animal\n{\npublic:\n  Animal(std::string_view name, int weight)     // Constructor\n    : m_name{ name }, m_weight{ weight }\n  {}\n\nprotected:\n  void who() const                  // Display name and weight\n  {\n    std::cout << \"My name is \" << m_name << \" and I weigh \" << m_weight << \"lbs.\" << std::endl;\n  }\n\nprivate:\n  std::string m_name;                    // Name of the animal\n  int m_weight;                        // Weight of the animal\n};\n\nexport class Lion : public Animal\n{\npublic:\n  // Define Lion constructor that calls base class constructor\n  Lion(std::string_view name, int weight)  \n\t  : Animal{name, weight} {}\n\n  // Create function in derived class that hides and explicitly \n  // invokes the protected function of the base class\n  void who() { return Animal::who(); }\n};\n\nexport class Aardvark : public Animal\n{\npublic:\n  using Animal::Animal;   // Inherit constructor instead (preferred)\n  using Animal::who;      // Use using to alter acccess specifier instead (preferred)\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 14/Soln14_02/Soln14_02.cpp",
    "content": "// Exercise 14-2 The who() function for the base class has the protected access specifier,\n// so we ensure the derived classes allow public access to the who() function. \n// The solution shows two alternatives, the second one being the preferred option.\n\nimport animals;\n\nint main()\n{\n  Lion myLion{\"Leo\", 400};\n  Aardvark myAardvark{\"Algernon\", 50};\n  myLion.who();\n  myAardvark.who();\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 14/Soln14_03/Animals.cpp",
    "content": "// Exercise 14-3 - Animals.cpp\n// Implementations of the Animal class and classes derived from Animal\nmodule animals;\nimport <iostream>;\n\n// Identify the animal\nvoid Animal::who() const\n{\n  std::cout << \"My name is \" << m_name << \" and I weigh \" << m_weight << \"lbs.\" << std::endl;\n}\n\n// Identify the Lion\nvoid Lion::who() const\n{\n  std::cout << \"Rrroarrrr... I am a lion. \";\n  Animal::who();                       // Call base function\n}\n\n// Identify the Aardvark\nvoid Aardvark::who() const\n{\n  Animal::who();                       // Call base function\n  std::cout << \"Oh. And I'm an aardvark. \" << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 14/Soln14_03/Animals.cppm",
    "content": "// Animal class and classes derived from Animal\nexport module animals;\n\nimport <string>;\nimport <string_view>;\n\nexport class Animal\n{\npublic:\n  Animal(std::string_view name, int weight)     // Constructor\n      : m_name{ name }, m_weight{ weight }\n  {}\n\n  void who() const;                 // Display name and weight\n\nprivate:\n  std::string m_name;                    // Name of the animal\n  int m_weight;                        // Weight of the animal\n};\n\nexport class Lion : public Animal\n{\npublic:\n  // Define Lion constructor that calls base class constructor\n  Lion(std::string_view name, int weight)  \n\t: Animal{name, weight} {}\n\n  void who() const;           // Define Lion-specific function\n};\n\nexport class Aardvark : public Animal\n{\npublic:\n  using Animal::Animal;                 // Inherit constructor\n  \n  void who() const;       // Define Aardvark-specific function\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 14/Soln14_03/Soln14_03.cpp",
    "content": "// Exercise 14-3 By adding a few lines to the test program, we can see the difference \n// between the calls to the base class and derived class who() functions. \n\nimport <iostream>;\nimport animals;\n\nint main()\n{\n  Lion myLion{\"Leo\", 400};\n  Aardvark myAardvark{\"Algernon\", 50};\n  std::cout << \"Calling derived versions of who():\\n\";\n  myLion.who();\n  myAardvark.who();\n\n  std::cout << \"\\nCalling base versions of who():\\n\";\n  myLion.Animal::who();     // By qualifying the base class\n  static_cast<Animal&>(myAardvark).who();     // By casting\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 14/Soln14_04/Person.cpp",
    "content": "// Person class implementation\n\nmodule person;\nimport <iostream>;\n\nPerson::Person(size_t age, std::string_view name, Gender gender) \n  : m_age {age}, m_name {name}, m_gender {gender}\n{\n  // Instead of just initializing the members with the argument values, \n  // you could validate the arguments by doing reasonableness checks. \n  // e.g. Name mustn't be empty, and age should be less than 130 say.\n  // To handle a failure sensibly we really need exceptions, \n  // but we don't get to those until chapter 16. \n}\n\n// Display details of Person object\nvoid Person::who() const \n{\n  std::cout << \"\\nThis is \" << m_name << \" who is \" << m_age << \" years old.\" << std::endl;\n}\n\nvoid Person::haveBirthday()\n{\n\t++m_age;\n}\n\nstd::string_view Person::getGenderString() const\n{\n  switch (m_gender)\n  {\n  case Gender::male:   return \"a male\";\n  case Gender::female: return \"a female\";\n  case Gender::other:  return \"an other-gendered\";\n  }\n\n  // Unreachable return statement required by some compilers \n  // (switch statement is exhaustive)\n  return {};\n}\n\n// Display details of Employee object\nvoid Employee::who() const\n{\n  std::cout << getName() << \" is \" << getGenderString() << \" employee aged \" << getAge() << \".\" << std::endl;\n}\n\n// Display details of Executive object (execs are particularly sensitive about their age...)\nvoid Executive::who() const\n{\n  std::cout << getName() << \" is \" << getGenderString() << \" executive.\" << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 14/Soln14_04/Person.cppm",
    "content": "// Person class and classes derived from Person\nexport module person;\nimport <string>;\nimport <string_view>;\n\n/*\n  We covered the advantages of the principle of data hiding extensively in Chapter 12.\n  In practice, a common convention is to make all data members of a class private. \n  This should thus probably become your default as well. \n  Getter and setter member functions can then be added to either the public \n  or protected interface to control access and/or modifications.\n   \n  Alternatively, you could make the member variables of Person and Employee themselves protected.\n  Often, people take this shortcut because it is somewhat less work:\n  then you wouldn't need the protected getter functions.\n  However, protected data is a bad idea, much for the same reason as public ones are.\n  We refer to the corresponding section in Chapter 14 for a more detailed motivation.\n*/\n\n// Possible alternatives for representing a gender include:\n//  - a Boolean value, but limited, and which is the 'true' gender?\n//  - a char value (say 'm', 'f', 'o'), but then how to enforce that no other values are assigned?\n//  - a string (\"male\", \"female\", etc), but same problem as with chars (and also excessively expensive)\n// The safest, most readable solution is therefore probably an enumeration:\nexport enum class Gender { male, female, other };\n\nexport class Person\n{\npublic:\n  Person() = default;   // Default constructor - necessary to define arrays\n  Person(size_t age, std::string_view name, Gender gender);\n  \n  void who() const;     // Display details\n  \n  void haveBirthday();\n\nprotected:  \n  // Functions to allow derived classes to access to a Person's details\n  size_t getAge() const    { return m_age; } \n  const std::string& getName() const { return m_name; }\n  Gender getGender() const { return m_gender; }\n  \n  // Convenience function:\n  std::string_view getGenderString() const;\n\nprivate:\n  size_t m_age{};      // Age in years\n  std::string m_name;\n  Gender m_gender{ Gender::female };\n};\n\nexport class Employee : public Person\n{\npublic:\n  Employee() = default;   // Default constructor - necessary to define arrays\n  Employee(size_t age, std::string_view name, Gender gender, long num)\n    : Person{age, name, gender}, m_personnelNumber {num} {}\n  \n  void who() const;       // Display details\n\nprotected:\n  long getPersonnelNumber() { return m_personnelNumber; }\n\nprivate:\n  long m_personnelNumber{};\n};\n\nexport class Executive : public Employee\n{\npublic:\n  using Employee::Employee;   // Inherit all constructors\n  \n  void who() const;           // Display details\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 14/Soln14_04/Soln14_04.cpp",
    "content": "// Exercise 14-4 Working with Employee and Executive objects\n\nimport <iostream>;\nimport <vector>;\nimport person;\n\nint main()\n{\n  std::vector<Employee> employees\n  {\n    Employee{ 21, \"Randy Marathon\", Gender::male, 34567 },\n    Employee{ 32, \"Anna Pothecary\", Gender::female, 34578 },\n    Employee{ 46, \"Peter Out\", Gender::male, 34589 },\n    Employee{ 37, \"Sheila Rangeit\", Gender::female, 34598 },\n    Employee{ 65, \"Jack Ittin\", Gender::male, 34667 }\n  };\n\n  for (const auto& employee : employees)\n    employee.who();\n\n  std::cout << std::endl;\n\n  // Note: explicitly specifying the type in front of every {...} \n  // in a vector's initializer list, like we did for Employees, \n  // is actually not required...\n  std::vector<Executive> executives\n  {\n    { 44, \"Irwin Pootlemeyer\", Gender::other, 35567 },\n    { 32, \"Alexa Workwell\", Gender::female, 35578 },\n    { 42, \"Steve Stove\", Gender::male, 35589 },\n    { 33, \"Sue Neenuf\", Gender::female, 35598 },\n    { 29, \"Melanie Clair\", Gender::female, 35667 }\n  };\n\n  for (const auto& executive : executives)\n  {\n    executive.who();\n    executive.Employee::who();  // Executive, I shall know thy age!\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_01/Animals.cpp",
    "content": "// Implementations of the Animal class and classes derived from Animal\n\nmodule animals;\n\n// Constructor\nAnimal::Animal(std::string_view name, unsigned weight) \n  : m_name{ name }, m_weight{ weight }\n{}\n\n// Return string describing the animal\nstd::string Animal::who() const\n{\n  return \"My name is \" + m_name + \". My weight is \" + std::to_string(m_weight) + \" lbs.\";\n}\n\n// Make like a sheep\nstd::string_view Sheep::sound() const\n{\n  return \"Baaaa!!\";\n}\n\n// Make like a dog\nstd::string_view Dog::sound() const\n{\n  return \"Woof woof!!\";\n}\n\n// Make like a cow\nstd::string_view Cow::sound() const\n{\n  return \"Mooooo!!\";\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_01/Animals.cppm",
    "content": "// Exercise 15-1 Animals.cppm \n// Animal classes\nexport module animals;\n\nimport <string>;\nimport <string_view>;\n\nexport class Animal\n{\npublic:\n  Animal(std::string_view name, unsigned weight);// Constructor\n  virtual ~Animal() = default;                   // Very important: a virtual destructor!\n  virtual std::string who() const;               // Return string containing name and weight\n  virtual std::string_view sound() const = 0;    // Return the sound of an animal\n\nprivate:\n  std::string m_name;                            // Name of the animal\n  unsigned m_weight;                             // Weight of the animal\n};\n\nexport class Sheep : public Animal\n{\npublic:\n  using Animal::Animal;                          // Inherit constructor\n  std::string_view sound() const override;       // Return the sound of a sheep\n};\n\nexport class Dog : public Animal\n{\npublic:\n  using Animal::Animal;                          // Inherit constructor\n  std::string_view sound() const override;       // Return the sound of a dog\n};\n\nexport class Cow : public Animal\n{\npublic:\n  using Animal::Animal;                          // Inherit constructor\n  std::string_view sound() const override;       // Return the sound of a cow\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_01/Soln15_01.cpp",
    "content": "// Exercise 15-1 Exercising Zoo and Animal classes\nimport zoo;\nimport <random>;     // For random number generation\nimport <functional>; // For std::bind()\nimport <iostream>;\nimport <array>;\nimport <string_view>;\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main() \n{\n  const size_t num_name_options{ 10 };\n  using NameOptions = std::array<std::string_view, num_name_options>;\n\n  const NameOptions dogNames {\n    \"Fido\", \"Rover\"  , \"Lassie\" , \"Lambikins\",  \"Poochy\",\n    \"Spit\", \"Gnasher\", \"Samuel\" , \"Wellington\", \"Patch\"\n  };\n  const NameOptions sheepNames {\n    \"Bozo\",    \"Killer\", \"Tasty\", \"Pete\", \"Chops\",\n    \"Blackie\", \"Whitey\", \"Eric\" , \"Sean\", \"Shep\"\n  };\n  const NameOptions cowNames {\n    \"Dolly\", \"Daisy\",   \"Shakey\", \"Amy\",   \"Dilly\",\n    \"Dizzy\", \"Eleanor\", \"Zippy\" , \"Zappy\", \"Happy\"\n  };\n\n  const unsigned minDogWt{ 1 };     // Minimum weight of a dog in pounds\n  const unsigned maxDogWt{ 120 };   // Maximum weight of a dog in pounds\n  const unsigned minSheepWt{ 80 };  // Minimum weight of a dog in pounds\n  const unsigned maxSheepWt{ 150 }; // Maximum weight of a dog in pounds\n  const unsigned minCowWt{ 800 };   // Minimum weight of a dog in pounds\n  const unsigned maxCowWt{ 1500 };  // Maximum weight of a dog in pounds\n\n  auto randomAnimalType { createUniformPseudoRandomNumberGenerator(0, 2) }; // 0, 1, or 2\n  auto randomNameIndex  { createUniformPseudoRandomNumberGenerator(0, num_name_options - 1) };\n  auto randomDogWeight  { createUniformPseudoRandomNumberGenerator(minDogWt, maxDogWt) };\n  auto randomSheepWeight{ createUniformPseudoRandomNumberGenerator(minSheepWt, maxSheepWt) };\n  auto randomCowWeight  { createUniformPseudoRandomNumberGenerator(minCowWt, maxCowWt) } ;\n\n  std::vector<AnimalPtr> animals;   // Stores smart pointers to animals\n  size_t numAnimals {};             // Number of animals to be created\n  std::cout << \"How many animals in the zoo? \";\n  std::cin >> numAnimals;\n  \n  Zoo zoo;                  // Create an empty Zoo\n  \n  // Create random animals and add them to the Zoo\n  for (size_t i {}; i < numAnimals; ++i)\n  {\n    switch (randomAnimalType())\n    {\n    case 0:                // Create a sheep\n      zoo.addAnimal(std::make_shared<Sheep>(sheepNames[randomNameIndex()], randomSheepWeight()));\n      break;\n    case 1:                // Create a dog\n      zoo.addAnimal(std::make_shared<Dog>(dogNames[randomNameIndex()], randomDogWeight()));\n      break;\n    case 2:                // Create a cow\n      zoo.addAnimal(std::make_shared<Cow>(cowNames[randomNameIndex()], randomCowWeight()));\n      break;\n    }\n  }\n  \n  zoo.showAnimals();                             // Display the animals\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_01/Zoo.cpp",
    "content": "// Implementations of the Zoo class that stores pointers to Animals\nmodule zoo;\nimport animals;\nimport <iostream>;\nimport <string>;        // For operator<<\nimport <string_view>;   // For operator<<\n\n// Constructor from a vector of animals\nZoo::Zoo(const std::vector<AnimalPtr>& animals) \n  : m_animals{ animals } \n{}\n\n// Add an animal to the zoo\nvoid Zoo::addAnimal(AnimalPtr animal)\n{\n  m_animals.push_back(animal);\n}\n\n// Output the animals and the sound they make\nvoid Zoo::showAnimals() const\n{\n  for (const auto& animal : m_animals)\n  {\n    std::cout << animal->who() << ' ' << animal->sound() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_01/Zoo.cppm",
    "content": "// The Zoo class representing a collection of animals \nexport module zoo;\n\nimport animals;\nimport <vector>;\nimport <memory>;\n\nexport using AnimalPtr = std::shared_ptr<Animal>;         // Define a type alias for convenience\n\nexport class Zoo\n{\npublic:\n  Zoo() = default;                                 // Default constructor for an empty zoo\n  Zoo(const std::vector<AnimalPtr>& new_animals);  // Constructor from a vector of animals\n  virtual ~Zoo() = default;                        // Add a virtual destructor to allow classes to safely derive from Zoo;\n                                                   // possible examples of Zoo specializations include SafariPark, PettingZoo, ...\n  void addAnimal(AnimalPtr animal);                // Add an animal to the zoo\n  void showAnimals() const;                        // Output the animals and the sound they make\n\nprivate:\n  std::vector<AnimalPtr> m_animals;      // Stores pointers to the animals\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_02/Animals.cpp",
    "content": "// Implementations of the Animal class and classes derived from Animal\n\nmodule animals;\n\n// Constructor\nAnimal::Animal(std::string_view name, unsigned weight) \n  : m_name{ name }, m_weight{ weight }\n{}\n\n// Return string describing the animal\nstd::string Animal::who() const\n{\n  return \"My name is \" + m_name + \". My weight is \" + std::to_string(m_weight) + \" lbs.\";\n}\n\n// Sheep constructors\nSheep::Sheep(std::string_view name, unsigned weight)\n  : Sheep{name, weight, static_cast<unsigned>(0.1 * weight)}\n{\n}\n\nSheep::Sheep(std::string_view name, unsigned weight, unsigned wool)\n  : Animal{name, weight}\n  , m_wool_weight{wool}\n{\n}\n\n// Override the behaviour of who() for Sheep to prepend \"Woolly \" to their name, \n// and subtract the weight of their wool from weight.\nstd::string Sheep::who() const\n{\n  return \"My name is Woolly \" + getName() + \". My weight is \" + std::to_string(getWeight() - m_wool_weight) + \" lbs.\";\n}\n\n// Make like a sheep\nstd::string_view Sheep::sound() const\n{\n  return \"Baaaa!!\";\n}\n\n// Make like a dog\nstd::string_view Dog::sound() const\n{\n  return \"Woof woof!!\";\n}\n\n// Override the behaviour of who() for Cows to hide their weight\nstd::string Cow::who() const\n{\n  return \"My name is \" + getName() + \".\";\n}\n\n// Make like a cow\nstd::string_view Cow::sound() const\n{\n  return \"Mooooo!!\";\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_02/Animals.cppm",
    "content": "// Animal classes\nexport module animals;\n\nimport <string>;\nimport <string_view>;\n\nexport class Animal\n{\npublic:\n  Animal(std::string_view name, unsigned weight);  // Constructor\n  virtual ~Animal() = default;                     // Very important: a virtual destructor!\n  \n  virtual std::string who() const;                 // Return string containing name and weight\n  virtual std::string_view sound() const = 0;      // Return the sound of an animal\n\nprotected:              // Protected getters for use in derived classes\n  const std::string& getName() const { return m_name; }\n  unsigned getWeight() const { return m_weight; }\n\nprivate:\n  std::string m_name;   // Name of the animal\n  unsigned m_weight;    // Weight of the animal\n};\n\nexport class Sheep : public Animal\n{\npublic:\n  Sheep(std::string_view name, unsigned weight);\n  Sheep(std::string_view name, unsigned weight, unsigned wool);\n  \n  std::string who() const override;         // Override the behaviour of who() for Sheep\n  std::string_view sound() const override;  // Return the sound of a sheep\n\nprivate:\n  unsigned m_wool_weight;\n};\n\nexport class Dog : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string_view sound() const override;  // Return the sound of a dog\n};\n\nexport class Cow : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string who() const override;         // Override the behaviour of who() for Cows\n  std::string_view sound() const override;  // Return the sound of a cow\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_02/Soln15_02.cpp",
    "content": "// Exercise 15-2 Exercising Zoo and Animal classes\nimport zoo;\nimport <random>;     // For random number generation\nimport <functional>; // For std::bind()\nimport <iostream>;\nimport <array>;\nimport <string_view>;\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main() \n{\n  const size_t num_name_options{ 10 };\n  using NameOptions = std::array<std::string_view, num_name_options>;\n\n  const NameOptions dogNames {\n    \"Fido\", \"Rover\"  , \"Lassie\" , \"Lambikins\",  \"Poochy\",\n    \"Spit\", \"Gnasher\", \"Samuel\" , \"Wellington\", \"Patch\"\n  };\n  const NameOptions sheepNames {\n    \"Bozo\",    \"Killer\", \"Tasty\", \"Pete\", \"Chops\",\n    \"Blackie\", \"Whitey\", \"Eric\" , \"Sean\", \"Shep\"\n  };\n  const NameOptions cowNames {\n    \"Dolly\", \"Daisy\",   \"Shakey\", \"Amy\",   \"Dilly\",\n    \"Dizzy\", \"Eleanor\", \"Zippy\" , \"Zappy\", \"Happy\"\n  };\n\n  const unsigned minDogWt{ 1 };     // Minimum weight of a dog in pounds\n  const unsigned maxDogWt{ 120 };   // Maximum weight of a dog in pounds\n  const unsigned minSheepWt{ 80 };  // Minimum weight of a dog in pounds\n  const unsigned maxSheepWt{ 150 }; // Maximum weight of a dog in pounds\n  const unsigned minCowWt{ 800 };   // Minimum weight of a dog in pounds\n  const unsigned maxCowWt{ 1500 };  // Maximum weight of a dog in pounds\n\n  auto randomAnimalType { createUniformPseudoRandomNumberGenerator(0, 2) }; // 0, 1, or 2\n  auto randomNameIndex  { createUniformPseudoRandomNumberGenerator(0, num_name_options - 1) };\n  auto randomDogWeight  { createUniformPseudoRandomNumberGenerator(minDogWt, maxDogWt) };\n  auto randomSheepWeight{ createUniformPseudoRandomNumberGenerator(minSheepWt, maxSheepWt) };\n  auto randomCowWeight  { createUniformPseudoRandomNumberGenerator(minCowWt, maxCowWt) };\n\n  std::vector<AnimalPtr> animals;   // Stores smart pointers to animals\n  size_t numAnimals {};             // Number of animals to be created\n  std::cout << \"How many animals in the zoo? \";\n  std::cin >> numAnimals;\n  \n  Zoo zoo;                  // Create an empty Zoo\n  \n  // Create random animals and add them to the Zoo\n  for (size_t i {}; i < numAnimals; ++i)\n  {\n    switch (randomAnimalType())\n    {\n    case 0:                // Create a sheep\n      zoo.addAnimal(std::make_shared<Sheep>(sheepNames[randomNameIndex()], randomSheepWeight()));\n      break;\n    case 1:                // Create a dog\n      zoo.addAnimal(std::make_shared<Dog>(dogNames[randomNameIndex()], randomDogWeight()));\n      break;\n    case 2:                // Create a cow\n      zoo.addAnimal(std::make_shared<Cow>(cowNames[randomNameIndex()], randomCowWeight()));\n      break;\n    }\n  }\n  \n  zoo.showAnimals();                             // Display the animals\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_02/Zoo.cpp",
    "content": "// Implementations of the Zoo class that stores pointers to Animals\nmodule zoo;\nimport animals;\nimport <iostream>;\nimport <string>;        // For operator<<\nimport <string_view>;   // For operator<<\n\n// Constructor from a vector of animals\nZoo::Zoo(const std::vector<AnimalPtr>& animals) \n  : m_animals{ animals } \n{}\n\n// Add an animal to the zoo\nvoid Zoo::addAnimal(AnimalPtr animal)\n{\n  m_animals.push_back(animal);\n}\n\n// Output the animals and the sound they make\nvoid Zoo::showAnimals() const\n{\n  for (const auto& animal : m_animals)\n  {\n    std::cout << animal->who() << ' ' << animal->sound() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_02/Zoo.cppm",
    "content": "// The Zoo class representing a collection of animals \nexport module zoo;\n\nimport animals;\nimport <vector>;\nimport <memory>;\n\nexport using AnimalPtr = std::shared_ptr<Animal>;         // Define a type alias for convenience\n\nexport class Zoo\n{\npublic:\n  Zoo() = default;                                 // Default constructor for an empty zoo\n  Zoo(const std::vector<AnimalPtr>& new_animals);  // Constructor from a vector of animals\n  virtual ~Zoo() = default;                        // Add a virtual destructor to allow classes to safely derive from Zoo;\n                                                   // possible examples of Zoo specializations include SafariPark, PettingZoo, ...\n  void addAnimal(AnimalPtr animal);                // Add an animal to the zoo\n  void showAnimals() const;                        // Output the animals and the sound they make\n\nprivate:\n  std::vector<AnimalPtr> m_animals;      // Stores pointers to the animals\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_03/Animals.cpp",
    "content": "// Implementations of the Animal class and classes derived from Animal\n\nmodule animals;\n\n// Constructor\nAnimal::Animal(std::string_view name, unsigned weight) \n  : m_name{ name }, m_weight{ weight }\n{}\n\n// Return string describing the animal\nstd::string Animal::who() const\n{\n  return \"My name is \" + m_name + \". My weight is \" + std::to_string(m_weight) + \" lbs.\";\n}\n\n// Sheep constructors\nSheep::Sheep(std::string_view name, unsigned weight)\n  : Sheep{name, weight, static_cast<unsigned>(0.1 * weight)}\n{\n}\n\nSheep::Sheep(std::string_view name, unsigned weight, unsigned wool)\n  : Animal{name, weight}\n  , m_wool_weight{wool}\n{\n}\n\n// Override the behaviour of getName() for Sheep to prepend \"Woolly \"\nstd::string Sheep::getName() const\n{\n  return \"Woolly \" + Animal::getName();\n}\n\n// Override getWeight() to subtract the weight of their wool from weight.\nunsigned Sheep::getWeight() const\n{\n  return Animal::getWeight() - m_wool_weight;\n}\n\n// Make like a sheep\nstd::string_view Sheep::sound() const\n{\n  return \"Baaaa!!\";\n}\n\n// Make like a dog\nstd::string_view Dog::sound() const\n{\n  return \"Woof woof!!\";\n}\n\n// Override the behaviour of who() for Cows to hide their weight\nstd::string Cow::who() const\n{\n  return \"My name is \" + getName() + \".\";\n}\n\n// Make like a cow\nstd::string_view Cow::sound() const\n{\n  return \"Mooooo!!\";\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_03/Animals.cppm",
    "content": "// Animal classes\nexport module animals;\n\nimport <string>;\nimport <string_view>;\n\nexport class Animal\n{\npublic:\n  Animal(std::string_view name, unsigned weight);  // Constructor\n  virtual ~Animal() = default;                     // Very important: a virtual destructor!\n  \n  virtual std::string who() const;                 // Return string containing name and weight\n  virtual std::string_view sound() const = 0;      // Return the sound of an animal\n\nprotected:              // Protected getters for use in derived classes\n  virtual std::string getName() const { return m_name; }\n  virtual unsigned getWeight() const { return m_weight; }\n\nprivate:\n  std::string m_name;   // Name of the animal\n  unsigned m_weight;    // Weight of the animal\n};\n\nexport class Sheep : public Animal\n{\npublic:\n  Sheep(std::string_view name, unsigned weight);\n  Sheep(std::string_view name, unsigned weight, unsigned wool);\n  \n  std::string_view sound() const override;  // Return the sound of a sheep\n\nprotected:\n  std::string getName() const override;\n  unsigned getWeight() const override;\n\nprivate:\n  unsigned m_wool_weight;\n};\n\nexport class Dog : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string_view sound() const override;  // Return the sound of a dog\n};\n\nexport class Cow : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string who() const override;         // Override the behaviour of who() for Cows\n  std::string_view sound() const override;  // Return the sound of a cow\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_03/Soln15_03.cpp",
    "content": "// Exercise 15-3 Exercising Zoo and Animal classes\nimport zoo;\nimport <random>;     // For random number generation\nimport <functional>; // For std::bind()\nimport <iostream>;\nimport <array>;\nimport <string_view>;\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main() \n{\n  const size_t num_name_options{ 10 };\n  using NameOptions = std::array<std::string_view, num_name_options>;\n\n  const NameOptions dogNames {\n    \"Fido\", \"Rover\"  , \"Lassie\" , \"Lambikins\",  \"Poochy\",\n    \"Spit\", \"Gnasher\", \"Samuel\" , \"Wellington\", \"Patch\"\n  };\n  const NameOptions sheepNames {\n    \"Bozo\",    \"Killer\", \"Tasty\", \"Pete\", \"Chops\",\n    \"Blackie\", \"Whitey\", \"Eric\" , \"Sean\", \"Shep\"\n  };\n  const NameOptions cowNames {\n    \"Dolly\", \"Daisy\",   \"Shakey\", \"Amy\",   \"Dilly\",\n    \"Dizzy\", \"Eleanor\", \"Zippy\" , \"Zappy\", \"Happy\"\n  };\n\n  const unsigned minDogWt{ 1 };     // Minimum weight of a dog in pounds\n  const unsigned maxDogWt{ 120 };   // Maximum weight of a dog in pounds\n  const unsigned minSheepWt{ 80 };  // Minimum weight of a dog in pounds\n  const unsigned maxSheepWt{ 150 }; // Maximum weight of a dog in pounds\n  const unsigned minCowWt{ 800 };   // Minimum weight of a dog in pounds\n  const unsigned maxCowWt{ 1500 };  // Maximum weight of a dog in pounds\n\n  auto randomAnimalType { createUniformPseudoRandomNumberGenerator(0, 2) }; // 0, 1, or 2\n  auto randomNameIndex  { createUniformPseudoRandomNumberGenerator(0, num_name_options - 1) };\n  auto randomDogWeight  { createUniformPseudoRandomNumberGenerator(minDogWt, maxDogWt) };\n  auto randomSheepWeight{ createUniformPseudoRandomNumberGenerator(minSheepWt, maxSheepWt) };\n  auto randomCowWeight  { createUniformPseudoRandomNumberGenerator(minCowWt, maxCowWt) };\n\n  std::vector<AnimalPtr> animals;   // Stores smart pointers to animals\n  size_t numAnimals {};             // Number of animals to be created\n  std::cout << \"How many animals in the zoo? \";\n  std::cin >> numAnimals;\n  \n  Zoo zoo;                  // Create an empty Zoo\n  \n  // Create random animals and add them to the Zoo\n  for (size_t i {}; i < numAnimals; ++i)\n  {\n    switch (randomAnimalType())\n    {\n    case 0:                // Create a sheep\n      zoo.addAnimal(std::make_shared<Sheep>(sheepNames[randomNameIndex()], randomSheepWeight()));\n      break;\n    case 1:                // Create a dog\n      zoo.addAnimal(std::make_shared<Dog>(dogNames[randomNameIndex()], randomDogWeight()));\n      break;\n    case 2:                // Create a cow\n      zoo.addAnimal(std::make_shared<Cow>(cowNames[randomNameIndex()], randomCowWeight()));\n      break;\n    }\n  }\n  \n  zoo.showAnimals();                             // Display the animals\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_03/Zoo.cpp",
    "content": "// Implementations of the Zoo class that stores pointers to Animals\nmodule zoo;\nimport animals;\nimport <iostream>;\nimport <string>;        // For operator<<\nimport <string_view>;   // For operator<<\n\n// Constructor from a vector of animals\nZoo::Zoo(const std::vector<AnimalPtr>& animals) \n  : m_animals{ animals } \n{}\n\n// Add an animal to the zoo\nvoid Zoo::addAnimal(AnimalPtr animal)\n{\n  m_animals.push_back(animal);\n}\n\n// Output the animals and the sound they make\nvoid Zoo::showAnimals() const\n{\n  for (const auto& animal : m_animals)\n  {\n    std::cout << animal->who() << ' ' << animal->sound() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_03/Zoo.cppm",
    "content": "// The Zoo class representing a collection of animals \nexport module zoo;\n\nimport animals;\nimport <vector>;\nimport <memory>;\n\nexport using AnimalPtr = std::shared_ptr<Animal>;         // Define a type alias for convenience\n\nexport class Zoo\n{\npublic:\n  Zoo() = default;                                 // Default constructor for an empty zoo\n  Zoo(const std::vector<AnimalPtr>& new_animals);  // Constructor from a vector of animals\n  virtual ~Zoo() = default;                        // Add a virtual destructor to allow classes to safely derive from Zoo;\n                                                   // possible examples of Zoo specializations include SafariPark, PettingZoo, ...\n  void addAnimal(AnimalPtr animal);                // Add an animal to the zoo\n  void showAnimals() const;                        // Output the animals and the sound they make\n\nprivate:\n  std::vector<AnimalPtr> m_animals;      // Stores pointers to the animals\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_04/Animals.cpp",
    "content": "// Implementations of the Animal class and classes derived from Animal\n\n/*\n  Because the Animal::m_weight member currently represents the total weight of the animal\n  (we kept this from previous versions of these classes),\n  we need to update the Animal's (total) weight during Sheep::shear().\n  \n  In an alternate, arguably more elegant solution:\n    - Animal::m_weight could reprent the \"true\" weight of the animal\n    - Sheep::getWeight() could return Animal::getWeight() + m_wool_weight\n    - Sheep::shear() could simply set m_wool_weight to 0\n */\n\nmodule animals;\n\n// Constructor\nAnimal::Animal(std::string_view name, unsigned weight) \n  : m_name{ name }, m_weight{ weight }\n{}\n\n// Return string describing the animal\nstd::string Animal::who() const\n{\n  return \"My name is \" + getName() + \". My weight is \" + std::to_string(getWeight()) + \" lbs.\";\n}\n\nvoid Animal::setWeight(unsigned weight)\n{\n  m_weight = weight;\n}\n\n// Sheep constructors\nSheep::Sheep(std::string_view name, unsigned weight)\n  : Sheep{name, weight, static_cast<unsigned>(0.1 * weight)}\n{\n}\n\nSheep::Sheep(std::string_view name, unsigned weight, unsigned wool)\n  : Animal{name, weight}\n  , m_wool_weight{wool}\n{\n}\n\n// Override the behaviour of getName() for Sheep to prepend \"Woolly \"\nstd::string Sheep::getName() const\n{\n  return \"Woolly \" + Animal::getName();\n}\n\n// Override getWeight() to subtract the weight of their wool from weight.\nunsigned Sheep::getWeight() const\n{\n  return Animal::getWeight() - m_wool_weight;\n}\n\nunsigned Sheep::shear()\n{\n  // Somewhat odd statement that updates the total weight (stored in the Animal subobject)\n  // to the actual weight of the sheep (see Sheep::getWeight()). \n  // Of course, we do this *before* setting the wool's weight to 0.\n  setWeight(getWeight());\n  \n  const unsigned wool_weight{ m_wool_weight };\n  m_wool_weight = 0;\n  return wool_weight;\n\n  // Alternative: use std::exchange() (see Exercise 18-5)\n  //return std::exchange(m_wool_weight, 0);\n}\n\n// Make like a sheep\nstd::string_view Sheep::sound() const\n{\n  return \"Baaaa!!\";\n}\n\n// Make like a dog\nstd::string_view Dog::sound() const\n{\n  return \"Woof woof!!\";\n}\n\n// Override the behaviour of who() for Cows to hide their weight\nstd::string Cow::who() const\n{\n  return \"My name is \" + getName() + \".\";\n}\n\n// Make like a cow\nstd::string_view Cow::sound() const\n{\n  return \"Mooooo!!\";\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_04/Animals.cppm",
    "content": "// Animal classes\nexport module animals;\n\nimport <string>;\nimport <string_view>;\n\nexport class Animal\n{\npublic:\n  Animal(std::string_view name, unsigned weight);  // Constructor\n  virtual ~Animal() = default;                     // Very important: a virtual destructor!\n  \n  virtual std::string who() const;                 // Return string containing name and weight\n  virtual std::string_view sound() const = 0;      // Return the sound of an animal\n\nprotected:              // Protected getters for use in derived classes\n  virtual std::string getName() const { return m_name; }\n  virtual unsigned getWeight() const { return m_weight; }\n  void setWeight(unsigned weight);\n\nprivate:\n  std::string m_name;   // Name of the animal\n  unsigned m_weight;    // Weight of the animal\n};\n\nexport class Sheep : public Animal\n{\npublic:\n  Sheep(std::string_view name, unsigned weight);\n  Sheep(std::string_view name, unsigned weight, unsigned wool);\n  \n  std::string_view sound() const override;  // Return the sound of a sheep\n  unsigned shear();\n\nprotected:\n  std::string getName() const override;\n  unsigned getWeight() const override;\n\nprivate:\n  unsigned m_wool_weight;\n};\n\nexport class Dog : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string_view sound() const override;  // Return the sound of a dog\n};\n\nexport class Cow : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string who() const override;         // Override the behaviour of who() for Cows\n  std::string_view sound() const override;  // Return the sound of a cow\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_04/Soln15_04.cpp",
    "content": "// Exercise 15-4 Exercising Zoo and Animal classes\nimport zoo;\nimport <random>;     // For random number generation\nimport <functional>; // For std::bind()\nimport <iostream>;\nimport <array>;\nimport <string_view>;\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main() \n{\n  const size_t num_name_options{ 10 };\n  using NameOptions = std::array<std::string_view, num_name_options>;\n\n  const NameOptions dogNames {\n    \"Fido\", \"Rover\"  , \"Lassie\" , \"Lambikins\",  \"Poochy\",\n    \"Spit\", \"Gnasher\", \"Samuel\" , \"Wellington\", \"Patch\"\n  };\n  const NameOptions sheepNames {\n    \"Bozo\",    \"Killer\", \"Tasty\", \"Pete\", \"Chops\",\n    \"Blackie\", \"Whitey\", \"Eric\" , \"Sean\", \"Shep\"\n  };\n  const NameOptions cowNames {\n    \"Dolly\", \"Daisy\",   \"Shakey\", \"Amy\",   \"Dilly\",\n    \"Dizzy\", \"Eleanor\", \"Zippy\" , \"Zappy\", \"Happy\"\n  };\n\n  const unsigned minDogWt{ 1 };     // Minimum weight of a dog in pounds\n  const unsigned maxDogWt{ 120 };   // Maximum weight of a dog in pounds\n  const unsigned minSheepWt{ 80 };  // Minimum weight of a dog in pounds\n  const unsigned maxSheepWt{ 150 }; // Maximum weight of a dog in pounds\n  const unsigned minCowWt{ 800 };   // Minimum weight of a dog in pounds\n  const unsigned maxCowWt{ 1500 };  // Maximum weight of a dog in pounds\n\n  auto randomAnimalType { createUniformPseudoRandomNumberGenerator(0, 2) }; // 0, 1, or 2\n  auto randomNameIndex  { createUniformPseudoRandomNumberGenerator(0, num_name_options - 1) };\n  auto randomDogWeight  { createUniformPseudoRandomNumberGenerator(minDogWt, maxDogWt) };\n  auto randomSheepWeight{ createUniformPseudoRandomNumberGenerator(minSheepWt, maxSheepWt) };\n  auto randomCowWeight  { createUniformPseudoRandomNumberGenerator(minCowWt, maxCowWt) };\n\n  std::vector<AnimalPtr> animals;   // Stores smart pointers to animals\n  size_t numAnimals {};             // Number of animals to be created\n  std::cout << \"How many animals in the zoo? \";\n  std::cin >> numAnimals;\n  \n  Zoo zoo;                  // Create an empty Zoo\n  \n  // Create random animals and add them to the Zoo\n  for (size_t i {}; i < numAnimals; ++i)\n  {\n    switch (randomAnimalType())\n    {\n    case 0:                // Create a sheep\n      zoo.addAnimal(std::make_shared<Sheep>(sheepNames[randomNameIndex()], randomSheepWeight()));\n      break;\n    case 1:                // Create a dog\n      zoo.addAnimal(std::make_shared<Dog>(dogNames[randomNameIndex()], randomDogWeight()));\n      break;\n    case 2:                // Create a cow\n      zoo.addAnimal(std::make_shared<Cow>(cowNames[randomNameIndex()], randomCowWeight()));\n      break;\n    }\n  }\n  \n  zoo.showAnimals();       // Display the animals\n\n  std::cout << \"\\nHerding and shearing all sheep...\" << std::endl;\n  for (auto* sheep : zoo.herd())\n  {\n    sheep->shear();\n  }\n\n  zoo.showAnimals();       // Display the animals again\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_04/Zoo.cpp",
    "content": "// Implementations of the Zoo class that stores pointers to Animals\nmodule zoo;\nimport animals;\nimport <iostream>;\nimport <string>;        // For operator<<\nimport <string_view>;   // For operator<<\n\n// Constructor from a vector of animals\nZoo::Zoo(const std::vector<AnimalPtr>& animals) \n  : m_animals{ animals } \n{}\n\n// Add an animal to the zoo\nvoid Zoo::addAnimal(AnimalPtr animal)\n{\n  m_animals.push_back(animal);\n}\n\n// Output the animals and the sound they make\nvoid Zoo::showAnimals() const\n{\n  for (const auto& animal : m_animals)\n  {\n    std::cout << animal->who() << ' ' << animal->sound() << std::endl;\n  }\n}\n\n// Collect all Sheep in the Zoo using dynamic cast (the recommended way)\nstd::vector<Sheep*> Zoo::herd() const\n{\n  std::vector<Sheep*> sheep;\n  for (auto animal : m_animals)\n  {\n    auto* casted{ dynamic_cast<Sheep*>(animal.get()) };\n    if (casted)\n    {\n      sheep.push_back(casted);\n    }\n  }\n  return sheep;\n}\n\n/*\n// Collect all Sheep in the Zoo using the typeid() operator and a static cast\n// (for the sake of the exercise only)\nimport <typeinfo>;       // required when using typeid()\n\nstd::vector<Sheep*> Zoo::herd() const\n{\n  std::vector<Sheep*> sheep;\n  for (auto animal : m_animals)\n  {\n    if (typeid(*animal) == typeid(Sheep))\n    {\n      sheep.push_back(static_cast<Sheep*>(animal.get()));\n    }\n  }\n  return sheep;\n}\n*/"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_04/Zoo.cppm",
    "content": "// The Zoo class representing a collection of animals \nexport module zoo;\n\nimport animals;\nimport <vector>;\nimport <memory>;\n\nexport using AnimalPtr = std::shared_ptr<Animal>;         // Define a type alias for convenience\n\nexport class Zoo\n{\npublic:\n  Zoo() = default;                                 // Default constructor for an empty zoo\n  Zoo(const std::vector<AnimalPtr>& new_animals);  // Constructor from a vector of animals\n  virtual ~Zoo() = default;                        // Add a virtual destructor to allow classes to safely derive from Zoo;\n                                                   // possible examples of Zoo specializations include SafariPark, PettingZoo, ...\n  void addAnimal(AnimalPtr animal);                // Add an animal to the zoo\n  void showAnimals() const;                        // Output the animals and the sound they make\n\n  std::vector<Sheep*> herd() const;                // Collect all Sheep in the Zoo\n\nprivate:\n  std::vector<AnimalPtr> m_animals;                // Stores pointers to the animals\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_05/Animals.cpp",
    "content": "// Implementations of the Animal class and classes derived from Animal\n\n/*\n  Because the Animal::m_weight member currently represents the total weight of the animal\n  (we kept this from previous versions of these classes),\n  we need to update the Animal's (total) weight during Sheep::shear().\n  \n  In an alternate, arguably more elegant solution:\n    - Animal::m_weight could reprent the \"true\" weight of the animal\n    - Sheep::getWeight() could return Animal::getWeight() + m_wool_weight\n    - Sheep::shear() could simply set m_wool_weight to 0\n */\n\nmodule animals;\n\n// Constructor\nAnimal::Animal(std::string_view name, unsigned weight) \n  : m_name{ name }, m_weight{ weight }\n{}\n\n// Return string describing the animal\nstd::string Animal::who() const\n{\n  return \"My name is \" + getName() + \". My weight is \" + std::to_string(getWeight()) + \" lbs.\";\n}\n\nvoid Animal::setWeight(unsigned weight)\n{\n  m_weight = weight;\n}\n\n// Sheep constructors\nSheep::Sheep(std::string_view name, unsigned weight)\n  : Sheep{name, weight, static_cast<unsigned>(0.1 * weight)}\n{\n}\n\nSheep::Sheep(std::string_view name, unsigned weight, unsigned wool)\n  : Animal{name, weight}\n  , m_wool_weight{wool}\n{\n}\n\n// Override the behaviour of getName() for Sheep to prepend \"Woolly \"\nstd::string Sheep::getName() const\n{\n  return \"Woolly \" + Animal::getName();\n}\n\n// Override getWeight() to subtract the weight of their wool from weight.\nunsigned Sheep::getWeight() const\n{\n  return Animal::getWeight() - m_wool_weight;\n}\n\nunsigned Sheep::shear()\n{\n  // Somewhat odd statement that updates the total weight (stored in the Animal subobject)\n  // to the actual weight of the sheep (see Sheep::getWeight()). \n  // Of course, we do this *before* setting the wool's weight to 0.\n  setWeight(getWeight()); \n\n  const unsigned wool_weight{ m_wool_weight };\n  m_wool_weight = 0;\n  return wool_weight;\n\n  // Alternative: use std::exchange() (see Exercise 18-5)\n  //return std::exchange(m_wool_weight, 0);\n}\n\n// Make like a sheep\nstd::string_view Sheep::sound() const\n{\n  return \"Baaaa!!\";\n}\n\n// Make like a dog\nstd::string_view Dog::sound() const\n{\n  return \"Woof woof!!\";\n}\n\n// Override the behaviour of who() for Cows to hide their weight\nstd::string Cow::who() const\n{\n  return \"My name is \" + getName() + \".\";\n}\n\n// Make like a cow\nstd::string_view Cow::sound() const\n{\n  return \"Mooooo!!\";\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_05/Animals.cppm",
    "content": "// Animal classes\nexport module animals;\n\nimport <string>;\nimport <string_view>;\n\nexport class Animal\n{\npublic:\n  Animal(std::string_view name, unsigned weight);  // Constructor\n  virtual ~Animal() = default;                     // Very important: a virtual destructor!\n  \n  virtual std::string who() const;                 // Return string containing name and weight\n  virtual std::string_view sound() const = 0;      // Return the sound of an animal\n\nprotected:              // Protected getters for use in derived classes\n  virtual std::string getName() const { return m_name; }\n  virtual unsigned getWeight() const { return m_weight; }\n  void setWeight(unsigned weight);\n\nprivate:\n  std::string m_name;   // Name of the animal\n  unsigned m_weight;    // Weight of the animal\n};\n\nexport class Sheep : public Animal\n{\npublic:\n  Sheep(std::string_view name, unsigned weight);\n  Sheep(std::string_view name, unsigned weight, unsigned wool);\n  \n  std::string_view sound() const override;  // Return the sound of a sheep\n  unsigned shear();\n\nprotected:\n  std::string getName() const override;\n  unsigned getWeight() const override;\n\nprivate:\n  unsigned m_wool_weight;\n};\n\nexport class Dog : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string_view sound() const override;  // Return the sound of a dog\n};\n\nexport class Cow : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string who() const override;         // Override the behaviour of who() for Cows\n  std::string_view sound() const override;  // Return the sound of a cow\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_05/Soln15_05.cpp",
    "content": "// Exercise 15-5 Exercising Zoo and Animal classes\nimport zoo;\nimport <random>;     // For random number generation\nimport <functional>; // For std::bind()\nimport <iostream>;\nimport <array>;\nimport <string_view>;\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main() \n{\n  const size_t num_name_options{ 10 };\n  using NameOptions = std::array<std::string_view, num_name_options>;\n\n  const NameOptions dogNames {\n    \"Fido\", \"Rover\"  , \"Lassie\" , \"Lambikins\",  \"Poochy\",\n    \"Spit\", \"Gnasher\", \"Samuel\" , \"Wellington\", \"Patch\"\n  };\n  const NameOptions sheepNames {\n    \"Bozo\",    \"Killer\", \"Tasty\", \"Pete\", \"Chops\",\n    \"Blackie\", \"Whitey\", \"Eric\" , \"Sean\", \"Shep\"\n  };\n  const NameOptions cowNames {\n    \"Dolly\", \"Daisy\",   \"Shakey\", \"Amy\",   \"Dilly\",\n    \"Dizzy\", \"Eleanor\", \"Zippy\" , \"Zappy\", \"Happy\"\n  };\n\n  const unsigned minDogWt{ 1 };     // Minimum weight of a dog in pounds\n  const unsigned maxDogWt{ 120 };   // Maximum weight of a dog in pounds\n  const unsigned minSheepWt{ 80 };  // Minimum weight of a dog in pounds\n  const unsigned maxSheepWt{ 150 }; // Maximum weight of a dog in pounds\n  const unsigned minCowWt{ 800 };   // Minimum weight of a dog in pounds\n  const unsigned maxCowWt{ 1500 };  // Maximum weight of a dog in pounds\n\n  auto randomAnimalType { createUniformPseudoRandomNumberGenerator(0, 2) }; // 0, 1, or 2\n  auto randomNameIndex  { createUniformPseudoRandomNumberGenerator(0, num_name_options - 1) };\n  auto randomDogWeight  { createUniformPseudoRandomNumberGenerator(minDogWt, maxDogWt) };\n  auto randomSheepWeight{ createUniformPseudoRandomNumberGenerator(minSheepWt, maxSheepWt) };\n  auto randomCowWeight  { createUniformPseudoRandomNumberGenerator(minCowWt, maxCowWt) };\n\n  std::vector<AnimalPtr> animals;   // Stores smart pointers to animals\n  size_t numAnimals {};             // Number of animals to be created\n  std::cout << \"How many animals in the zoo? \";\n  std::cin >> numAnimals;\n  \n  Zoo zoo;                  // Create an empty Zoo\n  \n  // Create random animals and add them to the Zoo\n  for (size_t i {}; i < numAnimals; ++i)\n  {\n    switch (randomAnimalType())\n    {\n    case 0:                // Create a sheep\n      zoo.addAnimal(std::make_shared<Sheep>(sheepNames[randomNameIndex()], randomSheepWeight()));\n      break;\n    case 1:                // Create a dog\n      zoo.addAnimal(std::make_shared<Dog>(dogNames[randomNameIndex()], randomDogWeight()));\n      break;\n    case 2:                // Create a cow\n      zoo.addAnimal(std::make_shared<Cow>(cowNames[randomNameIndex()], randomCowWeight()));\n      break;\n    }\n  }\n  \n  zoo.showAnimals();       // Display the animals\n\n  std::cout << \"\\nHerding and shearing all sheep...\" << std::endl;\n  for (auto sheep : zoo.herd())\n  {\n    sheep->shear();\n  }\n\n  zoo.showAnimals();       // Display the animals again\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_05/Zoo.cpp",
    "content": "// Implementations of the Zoo class that stores pointers to Animals\nmodule zoo;\nimport animals;\nimport <iostream>;\nimport <string>;        // For operator<<\nimport <string_view>;   // For operator<<\n\n// Constructor from a vector of animals\nZoo::Zoo(const std::vector<AnimalPtr>& animals) \n  : m_animals{ animals } \n{}\n\n// Add an animal to the zoo\nvoid Zoo::addAnimal(AnimalPtr animal)\n{\n  m_animals.push_back(animal);\n}\n\n// Output the animals and the sound they make\nvoid Zoo::showAnimals() const\n{\n  for (const auto& animal : m_animals)\n  {\n    std::cout << animal->who() << ' ' << animal->sound() << std::endl;\n  }\n}\n\n// Collect all Sheep in the Zoo using dynamic cast (the recommended way)\nstd::vector<SheepPtr> Zoo::herd() const\n{\n  std::vector<SheepPtr> sheep;\n  for (auto animal : m_animals)\n  {\n    auto casted{ std::dynamic_pointer_cast<Sheep>(animal) };\n    if (casted)\n    {\n      sheep.push_back(casted);\n    }\n  }\n  return sheep;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_05/Zoo.cppm",
    "content": "// The Zoo class representing a collection of animals \nexport module zoo;\n\nimport animals;\nimport <vector>;\nimport <memory>;\n\nexport using AnimalPtr = std::shared_ptr<Animal>;         // Define a type alias for convenience\nexport using SheepPtr = std::shared_ptr<Sheep>;\n\nexport class Zoo\n{\npublic:\n  Zoo() = default;                                 // Default constructor for an empty zoo\n  Zoo(const std::vector<AnimalPtr>& new_animals);  // Constructor from a vector of animals\n  virtual ~Zoo() = default;                        // Add a virtual destructor to allow classes to safely derive from Zoo;\n                                                   // possible examples of Zoo specializations include SafariPark, PettingZoo, ...\n  void addAnimal(AnimalPtr animal);                // Add an animal to the zoo\n  void showAnimals() const;                        // Output the animals and the sound they make\n\n  std::vector<SheepPtr> herd() const;                // Collect all Sheep in the Zoo\n\nprivate:\n  std::vector<AnimalPtr> m_animals;                // Stores pointers to the animals\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_06/Point.cppm",
    "content": "// A simple class for 2-dimensional points\nexport module point;\n\nexport class Point final\n{\npublic:\n  Point(double x, double y) : m_x{x}, m_y{y} {}\n  \n  double getX() const { return m_x; }\n  double getY() const { return m_y; }\n  \n  void setX(double x) { m_x = x; }\n  void setY(double y) { m_y = y; }\n  \nprivate:\n  double m_x;\n  double m_y;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_06/Shapes.cppm",
    "content": "// Shape classes\nexport module shapes;\n\nimport point;\nimport <numbers>;\n\n// Generic base class for shapes\nexport class Shape\n{\npublic:\n  Shape(const Point& position) : m_position {position} {}\n  virtual ~Shape() = default; // Remember: always use virtual destructors for base classes!\n\n  virtual double area() const = 0;       // Pure virtual function to compute a shape's area\n  virtual double perimeter() const = 0;  // Pure virtual function to compute a shape's perimeter\n  virtual void scale(double factor) = 0; // Pure virtual function to scale a shape\n\n  // Regular virtual function to move a shape\n  virtual void move(const Point& position) { m_position = position; };  \n\nprivate:\n  Point m_position;          // Position of a shape\n};\n\n// Class defining a circle\nexport class Circle : public Shape\n{\npublic:\n  Circle(const Point& center, double radius) : Shape{center}, m_radius{radius} {}\n\n  double area() const override\n  { \n    return m_radius * m_radius * std::numbers::pi;\n  }\n  double perimeter() const override\n  {\n    return 2 * std::numbers::pi * m_radius;\n  }\n\n  void scale(double factor) override { m_radius *= factor; }\n\nprivate:\n  double m_radius;   // Radius of a circle\n};\n\n// Class defining a rectangle\nexport class Rectangle : public Shape\n{\n\npublic:\n  Rectangle(const Point& center, double rectWidth, double rectHeight) \n    : Shape{center}, m_width{rectWidth}, m_height{rectHeight} \n  {}\n\n  double area() const override { return m_width * m_height; }\n  double perimeter() const override { return 2 * (m_width + m_height); }\n \n  void scale(double factor) override\n  { \n    m_width *= factor; \n    m_height *= factor; \n  }\n\nprivate:\n  double m_width;        // Width of a rectangle\n  double m_height;       // Height of a rectangle\n};\n\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 15/Soln15_06/Soln15_06.cpp",
    "content": "// Exercise 15-6 Exercising Shape classes\nimport shapes;\nimport point;\nimport <iostream>;\nimport <vector>;\n\ndouble calculateSumAreas(const std::vector<Shape*>& shapes);\ndouble calculateSumPerimeters(const std::vector<Shape*>& shapes);\nvoid printSums(const std::vector<Shape*>& shapes);\n\nint main() \n{\n  Circle c1{ Point{1, 1}, 1 };\n  Circle c2{ Point{2, 2}, 2 };\n  Circle c3{ Point{3, 3}, 3 };\n  Rectangle r1{ {4, 5}, 4, 5 }; // Shorter notation (omitted Point type) could of course be used for Circles as well!\n  Rectangle r2{ {6, 7}, 6, 7 };\n  Rectangle r3{ {8, 9}, 8, 9 };\n  \n  std::vector<Shape*> shapes{ &c1, &r1, &r2, &c2, &c3, &r3 };\n  \n  printSums(shapes);\n  \n  for (auto* shape : shapes) shape->scale(1.5);\n  \n  std::cout << std::endl;\n  printSums(shapes);\n}\n\ndouble calculateSumAreas(const std::vector<Shape*>& shapes)\n{\n  double sum {};\n  for (auto* shape : shapes)\n  {\n    sum += shape->area();\n  }\n  return sum;\n}\n\ndouble calculateSumPerimeters(const std::vector<Shape*>& shapes)\n{\n  double sum {};\n  for (auto* shape : shapes)\n  {\n    sum += shape->perimeter();\n  }\n  return sum;\n}\n\nvoid printSums(const std::vector<Shape*>& shapes)\n{\n  std::cout << \"Sum of areas: \" << calculateSumAreas(shapes) << std::endl;\n  std::cout << \"Sum of perimeters: \" << calculateSumPerimeters(shapes) << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Exer16_06/Customer.cpp",
    "content": "// A simple C++ customer class\nmodule customer;\n\nCustomer::Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city)\n  : m_surname{ surname }\n  , m_name{ name }\n  , m_street{ street }\n  , m_streetNumber{ streetNumber }\n  , m_city{ city }\n{}\n\nstd::string Customer::toString() const\n{\n  std::string result;\n  result += m_surname;\n  result += ' ';\n  result += m_name;\n  result += \", \";\n  result += m_street;\n  result += ' ';\n  result += std::to_string(m_streetNumber);\n  result += \", \";\n  result += m_city;\n  return result;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Exer16_06/Customer.cppm",
    "content": "// A simple C++ customer class\n\nexport module customer;\n\nimport <string>;\nimport <string_view>;\n\nexport class Customer\n{\npublic:\n  Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city\n  );\n\n  std::string toString() const;\n  \nprivate:\n  std::string m_surname;\n  std::string m_name;\n  std::string m_street;\n  int m_streetNumber;\n  std::string m_city;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Exer16_06/DB.cpp",
    "content": "// A mocked database\n\n#include \"DB.h\"\n#include <cstring>     // For std::strcmp()\n#include <memory>\n#include <vector>\n\nnamespace\n{\n  struct QueryResult\n  {\n    std::vector<std::vector<const char*>> data;\n    size_t index {};\n  };\n\n  class Database\n  {\n  public:\n    Database() = default;\n    \n\t  bool hasConnection() const { return m_connected; }\n    void connect() { m_connected = true; }\n    void disconnect() { m_connected = false; }\n    \n    QueryResult* query(const char* query);\n    \n  private:  \n    bool m_connected{};\n  };\n}\n\nDB_CONNECTION* db_connect()\n{\n  // We only have one single database, which allows only one single connection:\n  static Database theDatabase;\n  if (theDatabase.hasConnection())\n  {\n    return nullptr;\n  }\n  else\n  {\n    theDatabase.connect();\n    return &theDatabase;\n  }\n}\n\nvoid db_disconnect(DB_CONNECTION* connection)\n{\n  // reinterpret_cast<> is used to cast between pointers/references of \n  // unrelated types (such as void* and Database*)\n  reinterpret_cast<Database*>(connection)->disconnect();\n}\n\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query)\n{\n  return reinterpret_cast<Database*>(connection)->query(query);\n}\n\nQueryResult* Database::query(const char* query)\n{\n  if (!hasConnection())\n  {\n    return nullptr;\n  }\n  \n  // Our database only understands one single query!\n  if (std::strcmp(query, \"SELECT * FROM CUSTOMER_TABEL\") != 0)\n  {\n    return nullptr;\n  }\n  \n  auto result{ std::make_unique<QueryResult>() };\n  result->data = std::vector<std::vector<const char*>>{\n    { \"Sherlock\", \"Holmes\", \"Baker Street\", \"221\", \"London\" },\n    { \"Joe\", \"Biden\", \"Pennsylvania Avenue\", \"1600\", \"Washington DC\" },\n    { \"Donald\", \"Duck\", \"Webfoot Walk\", \"1313\", \"Duckville\" },\n    { \"Sirius\", \"Black\", \"Grimmauld Place\", \"12\", \"London\" },\n    { \"Nemo\", \"Clownfish\", \"Wallaby Way\", \"42\", \"Sydney\" },\n    { \"Sam\", \"Malone\", \"Beacon Street\", \"112\", \"Boston\" }\n  };\n  return result.release();\n}\n\nint db_num_fields(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->data.empty())\n  {\n    return -1;\n  }\n  else\n  {\n    return static_cast<int>(theResult->data.front().size());\n  }\n}\n\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->index >= theResult->data.size())\n  {\n    return nullptr;\n  }\n  else\n  {\n     return theResult->data[theResult->index++].data();\n  }\n}\n\nvoid db_free_result(DB_QUERY_RESULT* result)\n{\n  delete reinterpret_cast<QueryResult*>(result);\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Exer16_06/DB.h",
    "content": "// A C-style interface to a mock database\n// (a simplified subset of the MySQL C interface)\n\n#ifndef DB_INCLUDES\n#define DB_INCLUDES\n\nusing DB_CONNECTION = void;\nusing DB_QUERY_RESULT = void;\nusing DB_ROW = const char**;\n\n/*! Make a connection to the database\n * Do not forget to close the database connection (db_disconnect()) once done with it.\n * \\return a DB_CONNECTION handle; nullptr upon failure\n */\nDB_CONNECTION* db_connect();\n\n/*! Query the database\n * \\param[in] connection A database connection handle returned by db_connect()\n * \\param[in] query      A SQL query\n * \\return A handle to the result of the query (memory to be freed using db_free_result()!)\n */\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query);\n\n/*! Retrieve the number of fields per row stored by the given query result\n * \\param[in] result A handle returned by db_query \n * \\return The number of fields per row stored by the result; -1 upon failure\n */\nint db_num_fields(DB_QUERY_RESULT* result);\n\n/*! Fetch a single row from the result.\n * \\param[in] result A handle returned by db_query\n * \\return An array of strings. Each field is represented as a string (zero-terminated char array). \n *    Let row be the result, then the first field is accessed using result[0]. \n */\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result);\n\n/*! Release the memory allocated for the result.\n * \\param[in] result A handle returned by db_query()\n */\nvoid db_free_result(DB_QUERY_RESULT* result);\n\n/*! Disconnect from the database\n * \\param[in] connection   A connection handle returned by db_connect()\n */\nvoid db_disconnect(DB_CONNECTION* connection);\n\n#endif"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Exer16_06/DBException.cppm",
    "content": "// A simple C++ exception type\n\nexport module db_exception;\nimport <stdexcept>;\n\nexport class DatabaseException : public std::runtime_error\n{\npublic:\n  using std::runtime_error::runtime_error;  // Inherit constructor\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Exer16_06/Exer16_06.cpp",
    "content": "/* \n  Creating RAII classes to manage resource handles returned by a C interface\n  Remember: RAII is not just for dynamic memory: every resource should be managed by an object!\n */\n\nimport <iostream>;\nimport <vector>;\n\n#include \"DB.h\"\nimport db_exception;\nimport customer;\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result);           // Sanity check on the number of fields returned by our query\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result); // Convert the DB result to a series of C++ objects\nvoid print(std::ostream& stream, const Customer& customer);   // Print a given customer to a given output stream\n\nint main()\n{\n  auto* connection{ db_connect() };\n  try\n  {\n    auto* result{ db_query(connection, \"SELECT * FROM CUSTOMER_TABEL\") };\n    if (!result)\n    {\n      db_disconnect(connection);\n      throw DatabaseException{\"Query failed\"};\n    }\n  \n    std::vector customers{ readCustomers(result) };\n  \n    if (customers.empty())\n    {\n      std::cerr << \"No customers found?\" << std::endl;\n      return 2;\n    }\n    \n    for (auto& customer : customers)\n    {\n       print(std::cout, customer);\n    }\n  \n    db_free_result(result);\n  }\n  catch (std::exception& caught)\n  {\n    std::cerr << caught.what() << std::endl;\n    return 1;\n  }\n  \n  db_disconnect(connection);\n  return 0;\n}\n\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result)\n{\n  // Sanity check \n  // (if the number of fields does not match 5, \n  // the code below would crash!)\n  verifyCustomerFields(result);\n   \n  std::vector<Customer> customers;\n  \n  auto row{ db_fetch_row(result) };\n  while (row)\n  {\n    customers.push_back(Customer{\n      row[0],            // Surname\n      row[1],            // Name\n      row[2],            // Street\n      std::stoi(row[3]), // Street number\n      row[4]             // City\n    });\n    \n    row = db_fetch_row(result);\n  }\n  \n  return customers;\n}\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result)\n{\n  const int numFields{ db_num_fields(result) };\n  if (numFields < 0)\n  {\n    throw DatabaseException{\"db_num_fields() failed\"};\n  }\n  if (numFields != 5)\n  {\n    throw DatabaseException{\"Unexpected number of fields: \" + std::to_string(numFields)};\n  }\n}\n\nvoid print(std::ostream& stream, const Customer& customer)\n{\n  stream << customer.toString() << std::endl;\n  if (std::cout.fail())\n  {\n    std::cout.clear();\n    throw std::runtime_error(\"Failed to output customer\");\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_01/Curveball.cppm",
    "content": "// Definition of Curveball exception class\n\nexport module curveball;\nimport <exception>;\n\nexport class Curveball : public std::exception\n{\npublic:\n  const char* what() const noexcept override\n  {\n    return \"Curveball exception\";\n  }\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_01/Soln16_01.cpp",
    "content": "// Throwing and catching Curveballs\nimport curveball;\nimport <iostream>;\n\nimport <random>;     // For random number generation\nimport <functional>; // For std::bind()\n\nvoid throwCurveballSometimes();           // Suggested solution\nvoid throwCurveballSometimesBernouilli(); // Alternate solution\n\nint main() \n{\n  size_t number {1000};                             // Number of loop iterations\n  size_t exceptionCount {};                         // Count of exceptions thrown\n\n  for (size_t i {}; i < number; ++i)\n  {\n    try\n    {\n      throwCurveballSometimes();\n      // throwCurveballSometimesBernouilli();\n    }\n    catch (const Curveball&)\n    {\n      exceptionCount++;\n    }\n  }\n  \n  std::cout << \"Curveball exception thrown \" << exceptionCount << \" times out of \" << number << \".\\n\";\n}\n\n// See Chapter 12 for an explanation of this function principle.\nauto createUniformPseudoRandomNumberGenerator(double min, double max)\n{\n  std::random_device seeder;          // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };      // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ min, max }; // Generate in [min, max) interval\n  return std::bind(distribution, generator);             //... and in the darkness bind them!\n}\n\n// Throw a Curveball exception 25% of the time\nvoid throwCurveballSometimes()\n{\n  static auto random{ createUniformPseudoRandomNumberGenerator(0, 100) };\n  if (random() < 25)\n    throw Curveball{};\n}\n\n/*\n Alternate solution: instead of generating numbers in the interval [0,100)\n using a std::uniform_real_distribution, and comparing against 25,\n you could also generate Boolean values directly using a std::bernoulli_distribution\n (see https://en.cppreference.com/w/cpp/numeric/random/bernoulli_distribution;\n  named after https://en.wikipedia.org/wiki/Bernoulli_distribution):\n*/\nauto createUniformPseudoRandomBooleanGenerator(double probabilityOfTrue)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::bernoulli_distribution distribution{ probabilityOfTrue }; // The name says it all...\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\n// Throw a Curveball exception 25% of the time\nvoid throwCurveballSometimesBernouilli()\n{\n  static auto random{ createUniformPseudoRandomBooleanGenerator(0.25) };\n  if (random())\n    throw Curveball{};\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_02/Curveball.cppm",
    "content": "// Definition of Curveball exception class\n\nexport module curveball;\nimport <exception>;\n\nexport class Curveball : public std::exception\n{\npublic:\n  const char* what() const noexcept override\n  {\n    return \"Curveball exception\";\n  }\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_02/Soln16_02.cpp",
    "content": "// Throwing and catching Curveballs and throwing TooManyExceptions\nimport curveball;\nimport too_many;\n\nimport <iostream>;\nimport <random>;     // For random number generation\nimport <functional>; // For std::bind()\n\nvoid throwCurveballSometimes();\n\n// This program will terminate abnormally when the TooManyExceptions exception is thrown.\nint main()\n{\n  size_t number{ 1000 };             // Number of loop iterations\n  size_t exceptionCount {};          // Count of exceptions thrown\n  const size_t maxExceptions{ 10 };  // Maximum number of exceptions\n\n  for (size_t i {}; i < number; ++i)\n  {\n    try\n    {\n      throwCurveballSometimes();\n    }\n    catch(Curveball& e)\n    {\n      std::cout << e.what() << std::endl;\n    \n      if (++exceptionCount > maxExceptions)\n        throw TooManyExceptions{ maxExceptions };\n    }\n  }\n}\n\n// See Soln16_01 (to generate Booleans, a bernoulli_distribution is actually most appropriate)\nauto createUniformPseudoRandomBooleanGenerator(double probabilityOfTrue)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::bernoulli_distribution distribution{ probabilityOfTrue }; // The name says it all...\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\n// Throw a Curveball exception 25% of the time\nvoid throwCurveballSometimes()\n{\n  static auto random{ createUniformPseudoRandomBooleanGenerator(0.25) };\n  if (random())\n    throw Curveball{};\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_02/TooManyExceptions.cppm",
    "content": "// Definition of TooManyExceptions exception class\n// We added an extra \"how many\" members to illustrate derived \n// exceptions can carry extra information regarding their cause.\n// Notice how the constructor is explicit (implicit conversions\n// from size_t to TooManyExceptions are not desired).\n\nexport module too_many;\nimport <exception>;\nimport <string>;     // For std::string / std::to_string()\n\nexport class TooManyExceptions : public std::exception\n{\npublic:\n  explicit TooManyExceptions(size_t howMany)\n    : m_how_many{ howMany }\n    , m_message{ \"Too many exceptions occurred: \" + std::to_string(m_how_many) }\n  {}\n\n  const char* what() const noexcept override\n  {\n    return m_message.c_str();\n  }\n\n  size_t howMany() const noexcept\n  {\n    return m_how_many;\n  }\n\nprivate:\n  size_t m_how_many;\n  std::string m_message;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_03/Box.cppm",
    "content": "export module box;\n\nimport <ostream>;\nimport <format>;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_03/RandomBoxes.cppm",
    "content": "export module box.random;\nimport box;\nimport <random>;        // For random number generation\nimport <functional>;    // For std::bind()\nimport <memory>;        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\nexport Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\nexport auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_03/Soln16_03.cpp",
    "content": "// Using exceptions to signal index-out-of-bounds errors.\nimport <iostream>;\nimport <memory>;\nimport truckload;\nimport box.random;\n\nint main()\n{\n  Truckload load;\n  const size_t boxCount {20};               // Number of Box object to be created\n\n  // Create boxCount Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    load.addBox(randomSharedBox());\n\n  try\n  {\n    std::cout << \"The truckload contains the following boxes: \" << std::endl;\n    for (size_t i {}; i < 100; ++i)\n    {\n\t    std::cout << *load[i] << std::endl;\n    }\n  }\n  catch (const std::exception& caughtException)\n  {\n    std::cerr << \"Oops: \" << caughtException.what() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_03/Truckload.cpp",
    "content": "module truckload;\n\nimport <iostream>;\nimport <stdexcept>;    // For standard exception type std::out_of_range \nimport <string>;       // For std::string and std::to_string()\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\nTruckload& Truckload::operator=(const Truckload& other)\n{\n  if (&other != this)   // Do not forget: avoid issues with self-assignment!\n  {\n    delete m_head;              // Delete all current packages\n    m_head = m_tail = nullptr;  // Reset both pointers\n\n    // Same as copy constructor \n    // (see Chapter 17 for the copy-and-swap idiom that allows you to avoid \n    // duplicating logic like this...)\n    for (Package* package{ other.m_head }; package; package = package->m_next)\n    {\n      addBox(package->m_box);\n    }\n  }\n\n  return *this;\n}\n\n// Destructor: clean up the list\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nSharedBox& Truckload::operator[](size_t index) const\n{\n  size_t count{};             // Package count\n  for (Package* package{ m_head }; package; package = package->m_next)\n  {\n    if (count++ == index)      // Up to index yet?\n      return package->m_box;   // If so return the pointer to Box\n  }\n  throw std::out_of_range{ \"Index too large: \" + std::to_string(index) };\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_03/Truckload.cppm",
    "content": "export module truckload;\nimport box;\n\nimport <memory>;\nimport <vector>;\nimport <ostream>;\n\nexport using SharedBox = std::shared_ptr<Box>;\n\nexport class Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  \n  Truckload(const Truckload& src);  // Copy constructor\n  Truckload& operator=(const Truckload& other);  // Copy assignment operator\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox& operator[](size_t index) const;   // Overloaded subscript operator\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in a module interface file)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Truckload& load);\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_04/Soln16_04.cpp",
    "content": "// Throwing and catching standard exceptions\nimport <iostream>;\nimport <stdexcept>;\nimport <vector>;\nimport <format>;\nimport <typeinfo>;\nimport <optional>;\n\n/*\n  This solution triggers all exceptions mentioned in the text \n  accompanying the Table with all Standard Library exceptions, in order.\n  To know how to trigger any other type, \n  you will have to consult your Standard Library reference.\n\n  Note: while you'll typically catch exceptions by reference-to-const-std::exception \n  (unless more specific handling for concrete types is required, of course),\n  we specify the concrete exception type instead here for clarity.\n */\n\n// First, some dummy class types...\nclass BaseClass\n{\npublic:\n  virtual ~BaseClass() = default;\n};\n\nclass DerivedClass1 : public BaseClass {};\nclass DerivedClass2 : public BaseClass {};\n\nint main()\n{\n  try\n  {\n    std::vector v{ 1, 2, 3, 4, 5 };\n    std::cout << v.at(10) << std::endl;\n  }\n  catch (const std::out_of_range& exception)\n  {\n    std::cout << \"std::out_of_range: \" << exception.what() << std::endl;\n  }\n\n  try\n  {\n    std::cout << std::format(\"Hello {:g}!\\n\", \"World\");\n  }\n  catch (const std::format_error& exception)\n  {\n    std::cout << \"std::format_error: \" << exception.what() << std::endl;\n  }\n\n  try\n  {\n    // Remember: a polymorphic class is a class with at least one virtual function.\n    BaseClass* polymorphic{ nullptr };\n    std::cout << typeid(*polymorphic).name();\n  }\n  catch (const std::bad_typeid& exception)\n  {\n    std::cout << \"std::bad_typeid: \" << exception.what() << std::endl;\n  }\n\n  try\n  {\n    DerivedClass1 derived;\n    BaseClass& reference_to_base{ derived };\n    dynamic_cast<DerivedClass2&>(reference_to_base);\n  }\n  catch (const std::bad_cast& exception)\n  {\n    std::cout << \"std::bad_cast: \" << exception.what() << std::endl;\n  }\n\n  try\n  {\n    std::optional<int> empty;\n    std::cout << empty.value() << std::endl;\n  }\n  catch (const std::bad_optional_access& exception)\n  {\n    std::cout << \"std::bad_optional_access: \" << exception.what() << std::endl;\n  }\n\n  try\n  {\n    int size{ -1 };\n    new int[size];\n  }\n  catch (const std::bad_alloc& exception)\n  {\n    std::cout << \"std::bad_alloc: \" << exception.what() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_05/Curveball.cppm",
    "content": "// Definition of Curveball exception class\n\nexport module curveball;\nimport <exception>;\n\nexport class Curveball : public std::exception\n{\npublic:\n  const char* what() const noexcept override\n  {\n    return \"Curveball exception\";\n  }\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_05/DomainExceptions.cppm",
    "content": "// Definitions of various domain exception classes\nexport module domain_exceptions;\nimport <stdexcept>;\nimport <string>;\n\n/*\n\tstd::domain_error is one of the exception types defined by\n\tthe Standard Libray. It is intended to be used mostly inside\n\tmathematical functions in case an argument is provided for which\n\tthe function is not defined (for instance, should a regular \n\tsquare root function be called with a negative number)\n*/\n\nexport class NotANumber : public std::domain_error\n{\npublic:\n  explicit NotANumber(const std::string& nan) \n    : std::domain_error{\"Not a number: \" + nan} \n  {}\n};\n\nexport class NegativeNumber : public std::domain_error\n{\npublic:\n  explicit NegativeNumber(int number)\n    : std::domain_error{\"A negative number was entered: \" + std::to_string(number)}\n  {}\n};\n\nexport class OddNumber : public std::domain_error\n{\npublic:\n  explicit OddNumber(int number)\n    : std::domain_error{\"An odd number was entered: \" + std::to_string(number)}\n  {}\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_05/Soln16_05.cpp",
    "content": "// Exercise 16-5\n/* Somewhat artificial example to practice lists of different, \n * related exception types (mind the order + catch-by-reference!)\n * and rethrowing (catch-by-reference + \"throw;\" !)\n */\n\nimport <iostream>;\nimport <random>;     // For random number generation\nimport <functional>; // For std::bind()\nimport <format>;\nimport <string>;\nimport curveball;\nimport domain_exceptions;\n\nvoid askEvenNumber();           // Ask the user to provide an even number\n\nint main()\n{\n  try\n  {\n    askEvenNumber();\n  }\n  catch (const Curveball& /*caught*/)\n  {\n    std::cerr << \"...hit it out of the park!\" << std::endl;\n  }\n}\n\n/* Helper functions for askEvenNumber() */\nvoid throwCurveballSometimes(); // Throw a Curveball exception 25% of the time\nint readEvenNumber();           // Reads an even number from std::cin and verifies the input \n                                // (throws upon failure)\n\n// Option 1: use recursion\nvoid askEvenNumber()\n{\n  try\n  {\n    std::cout << \"Please enter an even number: \";\n    const int read = readEvenNumber();\n    std::cout << std::format(\"Well done. {} is a beautiful even number. Thank you!\\n\", read);\n  }\n  catch (const NotANumber& nan)\n  {\n    std::cerr << nan.what() << std::endl;\n    return;\n  }\n  catch (const std::domain_error& domainException)\n  {\n    std::cerr << domainException.what() << std::endl;\n    askEvenNumber();  // Recursive call\n  }\n  catch (const std::exception& exception)\n  {\n    std::cerr << exception.what() << std::endl;\n    throw;\n  }\n}\n\n/*\n// Option 2: use a loop\nvoid askEvenNumber()\n{\n  while (true)\n  {\n    try\n    {\n      std::cout << \"Please enter an even number: \";\n      const int read = readEvenNumber();\n      std::cout << std::format(\"Well done. {} is a beautiful even number. Thank you!\\n\", read);\n      break;\n    }\n    catch (const NotANumber& nan)\n    {\n      std::cerr << nan.what() << std::endl;\n      return;\n    }\n    catch (const std::out_of_range& range)\n    {\n      std::cerr << range.what() << std::endl;\n    }\n    catch (const std::exception& exception)\n    {\n      std::cerr << exception.what() << std::endl;\n      throw;\n    }\n  }\n}\n*/\n\nint readEvenNumber()\n{\n  int number;\n  std::cin >> number;\n  if (std::cin.fail()) // Check whether the user has effectively entered a number\n  {\n    std::cin.clear();  // Reset the stream's failure state\n    std::string line;  // Read the erroneous input and discard it\n    std::getline(std::cin, line);\n    throw NotANumber{line};\n  }\n  \n  throwCurveballSometimes();\n  \n  if (number < 0)\n    throw NegativeNumber{number};\n  if (number % 2)\n    throw OddNumber{number};\n\n  return number;\n}\n\n// See Soln16_01 for an explanation of this function\nauto createUniformPseudoRandomBooleanGenerator(double probabilityOfTrue)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::bernoulli_distribution distribution{ probabilityOfTrue }; // The name says it all...\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\n// Throw a Curveball exception 25% of the time\nvoid throwCurveballSometimes()\n{\n  static auto random{ createUniformPseudoRandomBooleanGenerator(0.25) };\n  if (random())\n    throw Curveball{};\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_06/Customer.cpp",
    "content": "// A simple C++ customer class\n\nmodule customer;\n\nCustomer::Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city)\n  : m_surname{ surname }\n  , m_name{ name }\n  , m_street{ street }\n  , m_streetNumber{ streetNumber }\n  , m_city{ city }\n{}\n\nstd::string Customer::toString() const\n{\n  std::string result;\n  result += m_surname;\n  result += ' ';\n  result += m_name;\n  result += \", \";\n  result += m_street;\n  result += ' ';\n  result += std::to_string(m_streetNumber);\n  result += \", \";\n  result += m_city;\n  return result;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_06/Customer.cppm",
    "content": "// A simple C++ customer class\n\nexport module customer;\n\nimport <string>;\nimport <string_view>;\n\nexport class Customer\n{\npublic:\n  Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city\n  );\n\n  std::string toString() const;\n  \nprivate:\n  std::string m_surname;\n  std::string m_name;\n  std::string m_street;\n  int m_streetNumber;\n  std::string m_city;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_06/DB.cpp",
    "content": "// A mocked database\n\n#include \"DB.h\"\n#include <cstring>    // For std::strcmp()\nimport <memory>;\nimport <vector>;\n\nnamespace\n{\n  struct QueryResult\n  {\n    std::vector<std::vector<const char*>> data;\n    size_t index {};\n  };\n\n  class Database\n  {\n  public:\n    Database() = default;\n    \n    bool hasConnection() const { return m_connected; }\n    void connect() { m_connected = true; }\n    void disconnect() { m_connected = false; }\n    \n    QueryResult* query(const char* query);\n    \n  private:  \n    bool m_connected{};\n  };\n}\n\nDB_CONNECTION* db_connect()\n{\n  // We only have one single database, which allows only one single connection:\n  static Database theDatabase;\n  if (theDatabase.hasConnection())\n  {\n    return nullptr;\n  }\n  else\n  {\n    theDatabase.connect();\n    return &theDatabase;\n  }\n}\n\nvoid db_disconnect(DB_CONNECTION* connection)\n{\n  // reinterpret_cast<> is used to cast between pointers/references of \n  // unrelated types (such as void* and Database*)\n  reinterpret_cast<Database*>(connection)->disconnect();\n}\n\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query)\n{\n  return reinterpret_cast<Database*>(connection)->query(query);\n}\n\nQueryResult* Database::query(const char* query)\n{\n  if (!hasConnection())\n  {\n    return nullptr;\n  }\n  \n  // Our database only understands one single query!\n  if (std::strcmp(query, \"SELECT * FROM CUSTOMER_TABEL\") != 0)\n  {\n    return nullptr;\n  }\n  \n  auto result{ std::make_unique<QueryResult>() };\n  result->data = std::vector<std::vector<const char*>>{\n    { \"Sherlock\", \"Holmes\", \"Baker Street\", \"221\", \"London\" },\n    { \"Joe\", \"Biden\", \"Pennsylvania Avenue\", \"1600\", \"Washington DC\" },\n    { \"Donald\", \"Duck\", \"Webfoot Walk\", \"1313\", \"Duckville\" },\n    { \"Sirius\", \"Black\", \"Grimmauld Place\", \"12\", \"London\" },\n    { \"Nemo\", \"Clownfish\", \"Wallaby Way\", \"42\", \"Sydney\" },\n    { \"Sam\", \"Malone\", \"Beacon Street\", \"112\", \"Boston\" }\n  };\n  return result.release();\n}\n\nint db_num_fields(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->data.empty())\n  {\n    return -1;\n  }\n  else\n  {\n    return static_cast<int>(theResult->data.front().size());\n  }\n}\n\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->index >= theResult->data.size())\n  {\n    return nullptr;\n  }\n  else\n  {\n     return theResult->data[theResult->index++].data();\n  }\n}\n\nvoid db_free_result(DB_QUERY_RESULT* result)\n{\n  delete reinterpret_cast<QueryResult*>(result);\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_06/DB.h",
    "content": "// A C-style interface to a mock database\n// (a simplified subset of the MySQL C interface)\n\n#ifndef DB_INCLUDES\n#define DB_INCLUDES\n\nusing DB_CONNECTION = void;\nusing DB_QUERY_RESULT = void;\nusing DB_ROW = const char**;\n\n/*! Make a connection to the database\n * Do not forget to close the database connection (db_disconnect()) once done with it.\n * \\return a DB_CONNECTION handle; nullptr upon failure\n */\nDB_CONNECTION* db_connect();\n\n/*! Query the database\n * \\param[in] connection A database connection handle returned by db_connect()\n * \\param[in] query      A SQL query\n * \\return A handle to the result of the query (memory to be freed using db_free_result()!)\n */\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query);\n\n/*! Retrieve the number of fields per row stored by the given query result\n * \\param[in] result A handle returned by db_query \n * \\return The number of fields per row stored by the result; -1 upon failure\n */\nint db_num_fields(DB_QUERY_RESULT* result);\n\n/*! Fetch a single row from the result.\n * \\param[in] result A handle returned by db_query\n * \\return An array of strings. Each field is represented as a string (zero-terminated char array). \n * \tLet row be the result, then the first field is accessed using result[0]. \n */\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result);\n\n/*! Release the memory allocated for the result.\n * \\param[in] result A handle returned by db_query()\n */\nvoid db_free_result(DB_QUERY_RESULT* result);\n\n/*! Disconnect from the database\n * \\param[in] connection   A connection handle returned by db_connect()\n */\nvoid db_disconnect(DB_CONNECTION* connection);\n\n#endif"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_06/DBException.cppm",
    "content": "// A simple C++ exception type\n\nexport module db.exception;\nimport <stdexcept>;\n\nexport class DatabaseException : public std::runtime_error\n{\npublic:\n  using std::runtime_error::runtime_error;  // Inherit constructor\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_06/DB_RAII.cppm",
    "content": "// RAII classes for handles returned by DB.h C interface functions\n\n/*\n  In this solution we have the RAII classes accept the resource handle in their constructor.\n  Alternatively, you could also acquire the resources inside the constructors of the RAII class.\n  For instance: you could call db_connect() from within the DBConnectionRAII() contructor.\n*/\n\nmodule;\n#include \"DB.h\"\nexport module db.raii;\n\n/**\n * RAII object that ensures that a given database connection is closed\n * once the RAII object goes out of scope.\n */ \nexport class DBConnectionRAII\n{\npublic:\n  DBConnectionRAII(DB_CONNECTION* connection) noexcept\n    : m_connection{ connection }\n  {\n  }  \n  ~DBConnectionRAII() // implicitly noexcept\n  {\n    if (m_connection)\n    {\n      db_disconnect(m_connection);\n    }\n  }\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_CONNECTION*() const noexcept { return m_connection; }\n  \nprivate:\n  DB_CONNECTION* m_connection;\n};\n\n/* RAII object that takes a DB_QUERY_RESULT and ensures it is closed */\nexport class DBQueryResultRAII\n{\npublic:\n  DBQueryResultRAII(DB_QUERY_RESULT* result) noexcept \n    : m_result{ result }\n  {\n  }\n  \n  ~DBQueryResultRAII() // implicitly noexcept\n  {\n    if (m_result)\n    {\n      db_free_result(m_result);\n    }\n  }\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_QUERY_RESULT* () const noexcept { return m_result; }\n\nprivate:\n  DB_QUERY_RESULT* m_result;\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 16/Soln16_06/Soln16_06.cpp",
    "content": "// Exercise 16-6\n/* Creating RAII classes to manage resource handles returned by a C interface\n   Remember: RAII is not just for dynamic memory: every resource should be managed by an object!\n   \n   Leaks in the original code:\n   - The database connection was not disconnected if an exception occurred indirectly \n     in the main try-catch block. For the DatabaseException thrown in the block of db_query()\n     the connection was correctly disconnected. Possible other exceptions, though, include:\n      a) verifyCustomerFields() discovers a problem. This verification step \n         may've been added later by someone trying to make the program more robuust, \n         but not familiar enough with the surrounding program...\n      b) std::stoi() throws std::invalid_argument because an empty string was passed, \n         or a string that does not start with a number\n      c) Customer::toString() throws std::bad_alloc because memory allocation failed for the new string\n\t    d) If the output stream used fails for whatever reason, a std::runtime_exception occurs.\n         While for std::cout this is less likely, perhaps the program is changed later to output\n         to some other stream that writes to a GUI element or a file. These might fail...\n   - The memory leaks for the query result are analogous\n   - If no customers are found, someone decided to add an extra return statement. \n     This again leaks all resources...\n   \n   Bottom line: the larger the program becomes, the more resources there are to keep track of,\n   and at the same time the more exceptions and return statements there appear.\n   Moreover, in real life often many different people collaborate on the same code,\n   often less familiar with the original program and the resources it uses.\n   It is just too easy to forget one case, and introduce a leak. \n   Even the most disciplined developer will make mistakes this way---believe us!\n   Hence: always use some form of RAII to manage a resource!\n*/\n\nimport <iostream>;\nimport <vector>;\n\n#include \"DB.h\"\nimport db.exception;\nimport db.raii;\nimport customer;\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result);           // Sanity check on the number of fields returned by our query\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result); // Convert the DB result to a series of C++ objects\nvoid print(std::ostream& stream, const Customer& customer);   // Print a given customer to a given output stream\n\nint main()\n{\n  DBConnectionRAII connection{ db_connect() };\n  try\n  {\n    DBQueryResultRAII result{ db_query(connection, \"SELECT * FROM CUSTOMER_TABEL\") };\n    if (!result)\n    {\n      throw DatabaseException{\"Query failed\"};\n    }\n  \n    std::vector customers{ readCustomers(result) };\n  \n    if (customers.empty())\n    {\n      std::cerr << \"No customers found?\" << std::endl;\n      return 2;\n    }\n    \n    for (auto& customer : customers)\n    {\n        print(std::cout, customer);\n    }\n  }\n  catch (const std::exception& caught)\n  {\n    std::cerr << caught.what() << std::endl;\n    return 1;\n  }\n}\n\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result)\n{\n  // Sanity check \n  // (if the number of fields does not match 5, \n  // the code below would crash!)\n  verifyCustomerFields(result);\n   \n  std::vector<Customer> customers;\n  \n  auto row{ db_fetch_row(result) };\n  while (row)\n  {\n    customers.push_back(Customer{\n      row[0],            // Surname\n      row[1],            // Name\n      row[2],            // Street\n      std::stoi(row[3]), // Street number\n      row[4]             // City\n    });\n    \n    row = db_fetch_row(result);\n  }\n  \n  return customers;\n}\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result)\n{\n  const int numFields{ db_num_fields(result) };\n  if (numFields < 0)\n  {\n    throw DatabaseException{\"db_num_fields() failed\"};\n  }\n  if (numFields != 5)\n  {\n    throw DatabaseException{\"Unexpected number of fields: \" + std::to_string(numFields)};\n  }\n}\n\nvoid print(std::ostream& stream, const Customer& customer)\n{\n  stream << customer.toString() << std::endl;\n  if (std::cout.fail())\n  {\n    std::cout.clear();\n    throw std::runtime_error(\"Failed to output customer\");\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_01/Array.cppm",
    "content": "// Same as Ex17_01B, but with a push_back() member and a default constructor\nexport module array;\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\n\nexport template <typename T>\nclass Array\n{\npublic:\n  Array();                                  // Default constructor\n  Array(size_t size);                       // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  void push_back(const T& element);         // Function to add new element to the end\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T>\nArray<T>::Array() : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Template for functions that add new element to the end of the array\n// Uses the 'copy-and-swap' idiom.\n// If either the Array<> constructor throws\n// (std::bad_alloc or some exception from T's default constructor) \n// or any of the copy assignments of a T element throw,\n// then the original Array<> remains untouched.\ntemplate <typename T>\nvoid Array<T>::push_back(const T& newElement)\n{\n  Array<T> copy{ m_size + 1 };        // Copy...\n  for (size_t i {}; i < m_size; ++i)\n    copy[i] = m_elements[i];\n\n  copy[m_size] = newElement;          // ... modify ...\n\n  swap(copy);                         // ... and swap!  (noexcept)\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_01/Soln17_01.cpp",
    "content": "// Adding a push_back() member function and a default constructor to the Array<> \n// class template. Using copy-and-swap for a memory-safe push_back().\nimport array;\nimport <iostream>;\n\nint main()\n{\n  const unsigned numElements{ 100 };\n\n  Array<unsigned> squares;       // default construction\n  for (unsigned i {}; i < numElements; ++i)\n\t  squares.push_back(i * i);    // push_back()\n\n  std::cout << squares.getSize() << \" squares were added.\" << std::endl;\n  std::cout << \"For instance: 13 squared equals \" << squares[13] << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_02/Pair.cppm",
    "content": "export module pair;\nimport <compare>;\n\nexport template <typename First, typename Second>\nclass Pair\n{\npublic:\n  // Public members + no m_ prefix analogous to std::pair<> (see <utility> module)\n  First first;    \n  Second second;\n\n  Pair() = default;\n  Pair(const First& f, const Second& s);\n  \n  // In retrospect, this is no longer such an interesting exercise on writing\n  // member function templates now that the compiler generates all lexicographical \n  // comparison operators for you.\n  //\n  // Note: not all compiler may fully support this generation yet (C++20)...\n  // (replacing auto with std::strong_ordering may make Soln17_02.cpp compile then,\n  // but in general auto is better because First and/or Second could be types \n  // that are not strongly ordered, such as a floating-point types)\n  auto operator<=>(const Pair& other) const = default;\n};\n\n// Constructor\ntemplate <typename First, typename Second>\nPair<First, Second>::Pair(const First& f, const Second& s)\n  : first{f}, second{s}\n{}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_02/Soln17_02.cpp",
    "content": "// Exercise 16-2\n// Create a basic Pair template\nimport pair;\nimport <iostream>;\nimport <string>;\n\nint main()\n{\n  auto my_pair{ Pair<int, std::string>{122, \"abc\"} };\n  ++my_pair.first;\n  std::cout << \"my_pair equals (\" << my_pair.first \n            << \", \" << my_pair.second << ')' << std::endl;\n\n  auto pair1{ Pair<int, std::string>{0, \"def\"} };\n\n  using namespace std::string_literals; // To make s suffix work (see below)\n  \n  // CTAD works as well. The deduced type for both pair2 and pair3 is Pair<int, std::string>:\n  auto pair2{ Pair{123, std::string{\"abc\"}} }; // Option 1: specify std::string yourself (otherwise the type is const char[])\n  auto pair3{ Pair{123, \"def\"s} };             // Option 2: use string literals: s suffix creates a std::string object\n\n  std::cout << (pair1 < pair2 && pair2 < pair3? \"operator< seems to be working\" : \"oops\") << std::endl;\n  std::cout << (pair1 == pair2? \"oops\" : \"operator== works as well\") << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_03/Pair.cppm",
    "content": "export module pair;\n\nimport <compare>;\nimport <iostream>;\n\nexport template <typename First, typename Second>\nclass Pair\n{\npublic:\n  // Public members + no m_ prefix analogous to std::pair<> (see <utility> module)\n  First first;    \n  Second second;\n\n  Pair() = default;\n  Pair(const First& f, const Second& s);\n  \n  // Note: not all compiler may fully support this generation yet (C++20)...\n  // (replacing auto with std::strong_ordering may make Soln17_02.cpp compile then,\n  // but in general auto is better because First and/or Second could be types \n  // that are not strongly ordered, such as a floating-point types)\n  auto operator<=>(const Pair& other) const = default;\n};\n\n// Constructor\ntemplate <typename First, typename Second>\nPair<First, Second>::Pair(const First& f, const Second& s)\n  : first{f}, second{s}\n{}\n\nexport template <typename First, typename Second>\nstd::ostream& operator<<(std::ostream& out, const Pair<First, Second>& pair)\n{\n  return out << '(' << pair.first << \", \" << pair.second << ')';\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_03/Soln17_03.cpp",
    "content": "// Create a << operator template for Pairs\nimport pair;\nimport <iostream>;\nimport <string>;\n\nint main()\n{\n  // To make the s string literal suffix work \n  // (facilitates creation of Pairs using CTAD, or Constructor Template Argument Deduction).\n  // This syntactic sugar for creating std::string objects is not really covered in the book.\n  using namespace std::string_literals;\n\n  auto my_pair{ Pair{122, \"abc\"s} };\n  ++my_pair.first;\n  std::cout << \"my_pair equals \" << my_pair << std::endl;\n\n  auto pair1{ Pair{  0, \"def\"s} };\n  auto pair2{ Pair{123, \"abc\"s} };\n  auto pair3{ Pair{123, \"def\"s} };\n\n  std::cout << (pair1 < pair2 && pair2 < pair3? \"operator< seems to be working\" : \"oops\") << std::endl;\n  std::cout << (pair1 == pair2? \"oops\" : \"operator== works as well\") << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_04/Pair.cppm",
    "content": "export module pair;\n\nimport <compare>;\nimport <iostream>;\n\nexport template <typename First, typename Second>\nclass Pair\n{\npublic:\n  // Public members + no m_ prefix analogous to std::pair<> (see <utility> module)\n  First first;    \n  Second second;\n\n  Pair() = default;\n  Pair(const First& f, const Second& s);\n  \n  // Note: not all compiler may fully support this generation yet (C++20)...\n  // (replacing auto with std::strong_ordering may make Soln17_02.cpp compile then,\n  // but in general auto is better because First and/or Second could be types \n  // that are not strongly ordered, such as a floating-point types)\n  auto operator<=>(const Pair& other) const = default;\n};\n\n// Constructor\ntemplate <typename First, typename Second>\nPair<First, Second>::Pair(const First& f, const Second& s)\n  : first{f}, second{s}\n{}\n\nexport template <typename First, typename Second>\nstd::ostream& operator<<(std::ostream& out, const Pair<First, Second>& pair)\n{\n  return out << '(' << pair.first << \", \" << pair.second << ')';\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_04/Soln17_04.cpp",
    "content": "// Exercising the SparseArray class template\n// We create a sparse array of integers, populate 20 of its entries \n// (checking for duplicates among the randomly generated indices)\n// and output the resulting index/value pairs.\n\nimport sparse_array;\nimport <iostream>;\n\nimport <random>;     // For random number generation\nimport <functional>; // For std::bind()\nimport <memory>;     // For std::make_shared<>() and std::shared_ptr<>\n\n// See Chapter 12 for an explanation of this principle.\n// The main difference here is that we need a std::uniform_int_distribution \n// instead of a std::uniform_real_distribution to generate integers instead \n// of float-point (or, \"real\") numbers.\nauto createUniformPseudoRandomNumberGenerator(int min, int max)\n{\n  std::random_device seeder;         // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };     // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max }; // Generate in [min, max) interval\n  return std::bind(distribution, generator);            //... and in the darkness bind them!\n}\n\nint main()\n{\n  const size_t count {20};                 // Number of elements to be created\n  const int min_value{32};\n  const int max_value{212};\n  const size_t max_index{499};\n  \n  // Create the (pseudo)-random number generators \n  // (we use +1 because these generate integers in a half-open interval [min,max)...)\n  auto generate_random_index{ createUniformPseudoRandomNumberGenerator(0, max_index + 1) };\n  auto generate_random_value{ createUniformPseudoRandomNumberGenerator(min_value, max_value + 1) };\n\n  SparseArray<int> numbers;               // Create empty sparse array\n  \n  for (size_t i {}; i < count; ++i)       // Create count entries in numbers array\n  {\n    size_t index {};                      // Stores new index value\n\n    // Must ensure that indexes after the first are not duplicates\n    do\n    {\n      index = generate_random_index();    // Get a random index 0 to max_index-1\n    }\n    while (numbers.element_exists_at(index));\n\n    numbers[index] = generate_random_value();  // Store value at new index position\n  }\n\n  for (size_t i {}; i <= max_index; ++i)       // Create count entries in numbers array\n  {\n    if (numbers.element_exists_at(i))\n      std::cout << \"Element at index \" << i << \" equals \" << numbers.at(i) << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_04/SparseArray.cppm",
    "content": "// SparseArray class template definition\n// Note the use of the find() helper function and the const-and-back-again idiom to minimize code duplication\n\nexport module sparse_array;\n\nimport pair;\nimport <vector>;\nimport <string>;       // For std::to_string()\nimport <utility>;      // For std::as_const()\nimport <stdexcept>;\n\nexport template<typename T>\nclass SparseArray\n{\npublic:\n  T& operator[](size_t index);              // Subscript operator (creates default-constructed value if no value exists for the given index)\n  T& at(size_t index);                      // Access function (throws std::out_of_range if no value exists for the given index)\n  const T& at(size_t index) const;          // const overload of at()\n  bool element_exists_at(size_t index) const;  // Return true iff an element exists at the given index\n\nprivate:\n  T* find(size_t index);                    // Helper function (returns nullptr if no value exists for the given index)\n  const T* find(size_t index) const;\n  \n  std::vector<Pair<size_t, T>> m_values;\n};\n\ntemplate<typename T>\nT& SparseArray<T>::operator[](size_t index)\n{\n  if (auto* found{ find(index) }; found)   // Using C++17 initialization statements for if statement \n  {                                        // (see at() function for common, traditional equivalent)\n\t  return *found;\n  }\n  else\n  {\n    m_values.push_back({ index, T{} });    // Or push_back(Pair{...}), or push_back(Pair<size_t, T>{...})\n    return m_values.back().second;         // Remember: std::vector<>::back() returns a reference to its last element\n  }\n}\n\ntemplate<typename T>\nconst T& SparseArray<T>::at(size_t index) const\n{\n  const auto* found{ find(index) };\n  if (found)\n  {\n\t  return *found;\n  }\n  else\n  {\n    throw std::out_of_range{\"No value exists at index \" + std::to_string(index)};\n  }\n}\n\ntemplate<typename T>\nT& SparseArray<T>::at(size_t index)\n{\n  return const_cast<T&>(std::as_const(*this).at(index));\n}\n\ntemplate<typename T>\nbool SparseArray<T>::element_exists_at(size_t index) const\n{\n  return find(index) != nullptr;\n}\n\ntemplate<typename T>\nconst T* SparseArray<T>::find(size_t index) const\n{\n  for (auto& pair : m_values)\n  {\n    if (pair.first == index)\n      return &pair.second;\n  }\n  return nullptr;\n}\n\ntemplate<typename T>\nT* SparseArray<T>::find(size_t index)\n{\n  return const_cast<T*>(std::as_const(*this).find(index));\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_05/LinkedList.cppm",
    "content": "export module linked_list;\n\n/*\nThis LinkedList template follows some (not all) conventions of Standard Library containers:\nsome member function names are analogous,\nas is the choice not to work with exceptions in case you do something wrong\n(such as calling back() or pop_front() on an empty list).\nThe latter has the implication that if you mis-use the container,\nyour program will likely crash...\n*/\n\nimport <utility>;        // for std::swap()\n\nexport template<typename T>\nclass LinkedList\n{\npublic:\n\tLinkedList() = default;                      // Default constructor (all pointers are initialised to nullptr)\n\t~LinkedList();\n\n\tLinkedList(const LinkedList& list);          // Copy constructor\n\tLinkedList& operator=(LinkedList list);      // Assignment operator\n\n\tvoid push_front(const T& value);             // Add an object to the head\n\tvoid push_back(const T& value);              // Add an object to the tail\n\n\tvoid pop_back();                             // Removes the last element from the list (undefined behavior for empty lists)\n\tvoid pop_front();                            // Removes the first element from the list (undefined behavior for empty lists)\n\n\tT& front();                                  // Get the object at the head (undefined behavior for empty lists)\n\tT& back();                                   // Get the object at the tail (undefined behavior for empty lists)\n\tconst T& front() const;                      // Get the object at the head (undefined behavior for empty lists)\n\tconst T& back() const;                       // Get the object at the tail (undefined behavior for empty lists)\n\n\tbool empty() const;                          // Checks whether the list is empty or not\n\tvoid clear();                                // Function to remove all elements from the list\n\tsize_t size() const;                         // Get the number of elements from the list\n\n\tclass Iterator;                              // Nested Iterator class declaration (definition below)\n\tIterator front_iterator() const;             // Get an Iterator that starts at the head\n\tIterator back_iterator() const;              // Get an Iterator that starts at the tail\n\n\tvoid swap(LinkedList& other) noexcept;       // Swap function\n\nprivate:\n\tclass Node                                   // Node class definition\n\t{\n\tpublic:\n\t\tNode(const T& theValue)\n\t\t\t: m_value{ theValue }, m_next{}, m_previous{}\n\t\t{}\n\n\t\tT m_value;\n\t\tNode* m_next;\n\t\tNode* m_previous;\n\t};\n\n\tNode* m_head{};    // Pointer to first node\n\tNode* m_tail{};    // Pointer to last node\n\tsize_t m_size{};\n};\n\n// Non-member swap function.\n// Convention dictates swap is present as non-member function.\n// For class types it is often easiest (and recommended) \n// to implement it using a member swap function.\nexport template<typename T>\nvoid swap(LinkedList<T>& one, LinkedList<T>& other)\n{\n\tone.swap(other);\n}\n\n// ---------------------------------------------\n// Member definitions\n// ---------------------------------------------\n\n// Destructor template\ntemplate<typename T>\nLinkedList<T>::~LinkedList()\n{\n\tclear();\n}\n\n// Copy constructor template\ntemplate<typename T>\nLinkedList<T>::LinkedList(const LinkedList& list)\n{\n  // Use existing members (iteration, push_back()) to implement the copying\n  // This avoids duplicating any code that manipulates the list's pointers / size members.\n  for (auto iterator{ list.front_iterator() }; iterator; iterator.next())\n    push_back(iterator.value());\n}\n\n// Assignment operator template (uses copy-and-swap idiom)\ntemplate<typename T>\nLinkedList<T>& LinkedList<T>::operator=(LinkedList copy)\n{\n\tswap(*this, copy);\n\treturn *this;\n}\n\n// Template for member functions that add an object to the head of the list\ntemplate<typename T> \nvoid LinkedList<T>::push_front(const T& value)\n{\n\t// Note: this function is strongly exception-safe because\n\t// any and all change occur after the line annotated with (*),\n\t// which is the only line that may throw.\n\n\tNode* oldHead{ m_head };\n\tm_head = new Node{ value };  // (*)\n\t++m_size;\n\n\tif (oldHead)\n\t{\n\t\toldHead->m_previous = m_head;\n\t\tm_head->m_next = oldHead;\n\t}\n\telse  // list was empty before, and now has one element\n\t{\n\t\tm_tail = m_head;\n\t}\n}\n\n// Template for member functions that add an object to the tail of the list\ntemplate<typename T>\nvoid LinkedList<T>::push_back(const T& value)\n{\n\t// Note: this function is strongly exception-safe because\n\t// any and all change occur after the line annotated with (*),\n\t// which is the only line that may throw.\n\n\tNode* oldTail{ m_tail };\n\tm_tail = new Node{value};\t // (*)\n\t++m_size;                 \n\n\tif (oldTail)\n\t{\n\t\toldTail->m_next = m_tail;\n\t\tm_tail->m_previous = oldTail;\n\t}\n\telse  // list was empty before, and now has one element\n\t{\n\t\tm_head = m_tail;\n\t}\n}\n\n// Template for member functions that remove an object from the head of the list\ntemplate<typename T> \nvoid LinkedList<T>::pop_front()\n{\n\tNode* oldHead{ m_head };\n\tif (oldHead == m_tail)\n\t{\n\t\tm_head = m_tail = nullptr;\n\t}\n\telse\n\t{\n\t\tm_head = oldHead->m_next;\n\t\tm_head->m_previous = nullptr;\n\t}\n\t\n\t--m_size;\n\tdelete oldHead;\n}\n\n// Template function member to remove an object from the tail of the list\ntemplate<typename T>\nvoid LinkedList<T>::pop_back()\n{\n\tNode* oldTail{ m_tail };\n\tif (oldTail == m_head)\n\t{\n\t\tm_head = m_tail = nullptr;\n\t}\n\telse\n\t{\n\t\tm_tail = oldTail->m_previous;\n\t\tm_tail->next = nullptr;\n\t}\n\n\t--m_size;\n\tdelete oldTail;\n}\n\n// Template function members to get the object at the head of the list\ntemplate<typename T>\nT& LinkedList<T>::front()\n{\n\treturn m_head->value;\n}\ntemplate<typename T>\nconst T& LinkedList<T>::front() const\n{\n\treturn m_head->value;\n}\n\n// Template function members to get the object at the tail of the list\ntemplate<typename T>\nT& LinkedList<T>::back()\n{\n\treturn m_tail->value;\n}\ntemplate<typename T>\nconst T& LinkedList<T>::back() const\n{\n\treturn m_tail->value;\n}\n\n// Check whether list is empty or not\ntemplate<typename T>\nbool LinkedList<T>::empty() const\n{\n\treturn m_size == 0;  // (or m_head == nullptr, or m_tail == nullptr)\n}\n\n// Template to get the size of a list\ntemplate<typename T> \nsize_t LinkedList<T>::size() const\n{\n\treturn m_size;\n}\n\n// Template to clear a list\ntemplate<typename T>\nvoid LinkedList<T>::clear()\n{\n\t// Use existing functions (avoid code duplication!)\n\twhile (!empty()) pop_front();\n}\n\n// Member function template to swap two lists\ntemplate<typename T>\nvoid LinkedList<T>::swap(LinkedList& other) noexcept\n{\n\tstd::swap(m_head, other.m_head);\n\tstd::swap(m_tail, other.m_tail);\n\tstd::swap(m_size, other.m_size);\n}\n\n// Definition of the nested Iterator class\ntemplate<typename T>\nclass LinkedList<T>::Iterator\n{\npublic:\n\texplicit Iterator(Node* node) \n\t\t: m_current{ node }\n\t{}\n\n\tconst T& value() const { return m_current->m_value; }\n\n\tbool hasValue() const { return m_current != nullptr; }\n\toperator bool() const { return m_current != nullptr; }\n\n\tvoid next() { m_current = m_current->m_next; }\n\tvoid previous() { m_current = m_current->m_previous; }\n\nprivate:\n\tNode* m_current;\n};\n\n// Get an Iterator that starts at the head\ntemplate<typename T>\ntypename LinkedList<T>::Iterator LinkedList<T>::front_iterator() const\n{\n  return Iterator{ m_head };\n}\n\n// Get an Iterator that starts at the tail\ntemplate<typename T>\ntypename LinkedList<T>::Iterator LinkedList<T>::back_iterator() const\n{\n  return Iterator{ m_tail };\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_05/Soln17_05.cpp",
    "content": "// Exercise 17-5 Exercising the LinkedList template class\n// This program reverses the text that is entered\nimport linked_list;\nimport <string>;\nimport <string_view>;\nimport <iostream>;\n\nint main()\n{\n  std::string text;                              // Stores input prose or poem\n  std::cout << \"\\nEnter a poem or prose over one or more lines.\\n\"\n            << \"Terminate the input with #:\\n\";\n  getline(std::cin, text, '#');\n\n  LinkedList<std::string> words;                 // List to store words\n\n  // Extract words and store in the list\n  std::string_view separators{ \" ,.\\\"?!;:\\n\" };  // Separators between words\n  size_t start {};                               // Start of a word\n  size_t end {};                                 // separator position after a word\n  while (std::string::npos != (start = text.find_first_not_of(separators, start)))\n  {\n    end = text.find_first_of(separators, start+1);\n    words.push_back(text.substr(start,end-start));\n    start = end;\n  }\n\n  // List the words 5 to a line\n  std::cout << \"\\nThe words are:\\n\\n\";\n  auto iterator{ words.front_iterator() };\n  size_t count {};                               // Word counter\n  const size_t perline {5};                      // Worde per line\n  while (iterator.hasValue())\n  {\n    std::cout << iterator.value() << ' ';\n    if (!(++count % perline))\n      std::cout << std::endl;\n    iterator.next();\n  }\n  std::cout << std::endl;\n\n  // List the words in reverse order 5 to a line\n  std::cout << \"\\nIn reverse order, the words are:\\n\\n\";\n  iterator = words.back_iterator();\n  count = 0;\n  while (iterator.hasValue())\n  {\n    std::cout << iterator.value() << ' ';\n    if(!(++count % perline))\n      std::cout << std::endl;\n    iterator.previous();\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_06/LinkedList.cppm",
    "content": "export module linked_list;\n\n/*\nThis LinkedList template follows some (not all) conventions of Standard Library containers:\nsome member function names are analogous,\nas is the choice not to work with exceptions in case you do something wrong\n(such as calling back() or pop_front() on an empty list).\nThe latter has the implication that if you mis-use the container,\nyour program will likely crash...\n*/\n\nimport <utility>;        // for std::swap()\n\nexport template<typename T>\nclass LinkedList\n{\npublic:\n\tLinkedList() = default;                      // Default constructor (all pointers are initialised to nullptr)\n\t~LinkedList();\n\n\tLinkedList(const LinkedList& list);          // Copy constructor\n\tLinkedList& operator=(LinkedList list);      // Assignment operator\n\n\tvoid push_front(const T& value);             // Add an object to the head\n\tvoid push_back(const T& value);              // Add an object to the tail\n\n\tvoid pop_back();                             // Removes the last element from the list (undefined behavior for empty lists)\n\tvoid pop_front();                            // Removes the first element from the list (undefined behavior for empty lists)\n\n\tT& front();                                  // Get the object at the head (undefined behavior for empty lists)\n\tT& back();                                   // Get the object at the tail (undefined behavior for empty lists)\n\tconst T& front() const;                      // Get the object at the head (undefined behavior for empty lists)\n\tconst T& back() const;                       // Get the object at the tail (undefined behavior for empty lists)\n\n\tbool empty() const;                          // Checks whether the list is empty or not\n\tvoid clear();                                // Function to remove all elements from the list\n\tsize_t size() const;                         // Get the number of elements from the list\n\n\tclass Iterator;                              // Nested Iterator class declaration (definition below)\n\tIterator front_iterator() const;             // Get an Iterator that starts at the head\n\tIterator back_iterator() const;              // Get an Iterator that starts at the tail\n\n\tvoid swap(LinkedList& other) noexcept;       // Swap function\n\nprivate:\n\tclass Node                                   // Node class definition\n\t{\n\tpublic:\n\t\tNode(const T& theValue)\n\t\t\t: m_value{ theValue }, m_next{}, m_previous{}\n\t\t{}\n\n\t\tT m_value;\n\t\tNode* m_next;\n\t\tNode* m_previous;\n\t};\n\n\tNode* m_head{};    // Pointer to first node\n\tNode* m_tail{};    // Pointer to last node\n\tsize_t m_size{};\n};\n\n// Non-member swap function.\n// Convention dictates swap is present as non-member function.\n// For class types it is often easiest (and recommended) \n// to implement it using a member swap function.\nexport template<typename T>\nvoid swap(LinkedList<T>& one, LinkedList<T>& other)\n{\n\tone.swap(other);\n}\n\n// ---------------------------------------------\n// Member definitions\n// ---------------------------------------------\n\n// Destructor template\ntemplate<typename T>\nLinkedList<T>::~LinkedList()\n{\n\tclear();\n}\n\n// Copy constructor template\ntemplate<typename T>\nLinkedList<T>::LinkedList(const LinkedList& list)\n{\n  // Use existing members (iteration, push_back()) to implement the copying\n  // This avoids duplicating any code that manipulates the list's pointers / size members.\n  for (auto iterator{ list.front_iterator() }; iterator; iterator.next())\n    push_back(iterator.value());\n}\n\n// Assignment operator template (uses copy-and-swap idiom)\ntemplate<typename T>\nLinkedList<T>& LinkedList<T>::operator=(LinkedList copy)\n{\n\tswap(*this, copy);\n\treturn *this;\n}\n\n// Template for member functions that add an object to the head of the list\ntemplate<typename T> \nvoid LinkedList<T>::push_front(const T& value)\n{\n\t// Note: this function is strongly exception-safe because\n\t// any and all change occur after the line annotated with (*),\n\t// which is the only line that may throw.\n\n\tNode* oldHead{ m_head };\n\tm_head = new Node{ value };  // (*)\n\t++m_size;\n\n\tif (oldHead)\n\t{\n\t\toldHead->m_previous = m_head;\n\t\tm_head->m_next = oldHead;\n\t}\n\telse  // list was empty before, and now has one element\n\t{\n\t\tm_tail = m_head;\n\t}\n}\n\n// Template for member functions that add an object to the tail of the list\ntemplate<typename T>\nvoid LinkedList<T>::push_back(const T& value)\n{\n\t// Note: this function is strongly exception-safe because\n\t// any and all change occur after the line annotated with (*),\n\t// which is the only line that may throw.\n\n\tNode* oldTail{ m_tail };\n\tm_tail = new Node{value};\t // (*)\n\t++m_size;                 \n\n\tif (oldTail)\n\t{\n\t\toldTail->m_next = m_tail;\n\t\tm_tail->m_previous = oldTail;\n\t}\n\telse  // list was empty before, and now has one element\n\t{\n\t\tm_head = m_tail;\n\t}\n}\n\n// Template for member functions that remove an object from the head of the list\ntemplate<typename T> \nvoid LinkedList<T>::pop_front()\n{\n\tNode* oldHead{ m_head };\n\tif (oldHead == m_tail)\n\t{\n\t\tm_head = m_tail = nullptr;\n\t}\n\telse\n\t{\n\t\tm_head = oldHead->m_next;\n\t\tm_head->m_previous = nullptr;\n\t}\n\t\n\t--m_size;\n\tdelete oldHead;\n}\n\n// Template function member to remove an object from the tail of the list\ntemplate<typename T>\nvoid LinkedList<T>::pop_back()\n{\n\tNode* oldTail{ m_tail };\n\tif (oldTail == m_head)\n\t{\n\t\tm_head = m_tail = nullptr;\n\t}\n\telse\n\t{\n\t\tm_tail = oldTail->m_previous;\n\t\tm_tail->next = nullptr;\n\t}\n\n\t--m_size;\n\tdelete oldTail;\n}\n\n// Template function members to get the object at the head of the list\ntemplate<typename T>\nT& LinkedList<T>::front()\n{\n\treturn m_head->value;\n}\ntemplate<typename T>\nconst T& LinkedList<T>::front() const\n{\n\treturn m_head->value;\n}\n\n// Template function members to get the object at the tail of the list\ntemplate<typename T>\nT& LinkedList<T>::back()\n{\n\treturn m_tail->value;\n}\ntemplate<typename T>\nconst T& LinkedList<T>::back() const\n{\n\treturn m_tail->value;\n}\n\n// Check whether list is empty or not\ntemplate<typename T>\nbool LinkedList<T>::empty() const\n{\n\treturn m_size == 0;  // (or m_head == nullptr, or m_tail == nullptr)\n}\n\n// Template to get the size of a list\ntemplate<typename T> \nsize_t LinkedList<T>::size() const\n{\n\treturn m_size;\n}\n\n// Template to clear a list\ntemplate<typename T>\nvoid LinkedList<T>::clear()\n{\n\t// Use existing functions (avoid code duplication!)\n\twhile (!empty()) pop_front();\n}\n\n// Member function template to swap two lists\ntemplate<typename T>\nvoid LinkedList<T>::swap(LinkedList& other) noexcept\n{\n\tstd::swap(m_head, other.m_head);\n\tstd::swap(m_tail, other.m_tail);\n\tstd::swap(m_size, other.m_size);\n}\n\n// Definition of the nested Iterator class\ntemplate<typename T>\nclass LinkedList<T>::Iterator\n{\npublic:\n\texplicit Iterator(Node* node) \n\t\t: m_current{ node }\n\t{}\n\n\tconst T& value() const { return m_current->m_value; }\n\n\tbool hasValue() const { return m_current != nullptr; }\n\toperator bool() const { return m_current != nullptr; }\n\n\tvoid next() { m_current = m_current->m_next; }\n\tvoid previous() { m_current = m_current->m_previous; }\n\nprivate:\n\tNode* m_current;\n};\n\n// Get an Iterator that starts at the head\ntemplate<typename T>\ntypename LinkedList<T>::Iterator LinkedList<T>::front_iterator() const\n{\n  return Iterator{ m_head };\n}\n\n// Get an Iterator that starts at the tail\ntemplate<typename T>\ntypename LinkedList<T>::Iterator LinkedList<T>::back_iterator() const\n{\n  return Iterator{ m_tail };\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_06/Pair.cppm",
    "content": "export module pair;\n\nimport <compare>;\nimport <iostream>;\n\nexport template <typename First, typename Second>\nclass Pair\n{\npublic:\n  // Public members + no m_ prefix analogous to std::pair<> (see <utility> module)\n  First first;    \n  Second second;\n\n  Pair() = default;\n  Pair(const First& f, const Second& s);\n  \n  // Note: not all compiler may fully support this generation yet (C++20)...\n  // (replacing auto with std::strong_ordering may make Soln17_02.cpp compile then,\n  // but in general auto is better because First and/or Second could be types \n  // that are not strongly ordered, such as a floating-point types)\n  auto operator<=>(const Pair& other) const = default;\n};\n\n// Constructor\ntemplate <typename First, typename Second>\nPair<First, Second>::Pair(const First& f, const Second& s)\n  : first{f}, second{s}\n{}\n\nexport template <typename First, typename Second>\nstd::ostream& operator<<(std::ostream& out, const Pair<First, Second>& pair)\n{\n  return out << '(' << pair.first << \", \" << pair.second << ')';\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_06/Soln17_06.cpp",
    "content": "// Exercising the SparseArray class template in combination with the LinkedList class template\nimport sparse_array;\nimport linked_list;\nimport <string>;\nimport <string_view>;\nimport <iostream>;\nimport <utility>;\n\n#include <cctype>\n\nint main()\n{\n  std::string text;                                // Stores input prose or poem\n  std::cout << \"Enter a poem or prose over one or more lines.\\n\"\n            << \"Terminate the input with #:\\n\";\n  getline(std::cin, text, '#');\n\n  SparseArray<LinkedList<std::string>> lists;      // Sparse array of linked lists\n  const std::string_view letters {\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"};\n\n  // Extract words and store in the appropriate list\n  // A list in the SparseArray is selected by the index in letters of the first letter in a word.\n  const std::string_view separators {\" \\n\\t,.\\\"?!;:\"};  // Separators between words\n  size_t start {};                                 // Start of a word\n  size_t end {};                                   // separator position after a word\n  while (std::string::npos != (start = text.find_first_not_of(separators, start)))\n  {\n    end = text.find_first_of(separators, start+1);\n    const auto word{ text.substr(start, end - start) };\n    const auto letter{ static_cast<char>(std::toupper(word[0])) };\n    lists[letters.find(letter)].push_back(word);\n    start = end;\n  }\n\n  // List the words in order 5 to a line\n  const size_t perline {5};\n  \n  for (size_t i {}; i < std::size(letters); ++i)\n  {\n    if (!lists.element_exists_at(i))\n      continue;\n  \n    size_t count {};                               // Word counter\n    for (auto iterator { lists[i].front_iterator() }; iterator; iterator.next())\n    {\n      std::cout << iterator.value() << ' ';\n      if (!(++count % perline))\n        std::cout << std::endl;\n    }\n    std::cout << std::endl;\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_06/SparseArray.cppm",
    "content": "// SparseArray class template definition\n// Note the use of the find() helper function and the const-and-back-again idiom to minimize code duplication\n\nexport module sparse_array;\n\nimport pair;\nimport <vector>;\nimport <string>;       // For std::to_string()\nimport <utility>;      // For std::as_const()\nimport <stdexcept>;\n\nexport template<typename T>\nclass SparseArray\n{\npublic:\n  T& operator[](size_t index);              // Subscript operator (creates default-constructed value if no value exists for the given index)\n  T& at(size_t index);                      // Access function (throws std::out_of_range if no value exists for the given index)\n  const T& at(size_t index) const;          // const overload of at()\n  bool element_exists_at(size_t index) const;  // Return true iff an element exists at the given index\n\nprivate:\n  T* find(size_t index);                    // Helper function (returns nullptr if no value exists for the given index)\n  const T* find(size_t index) const;\n  \n  std::vector<Pair<size_t, T>> m_values;\n};\n\ntemplate<typename T>\nT& SparseArray<T>::operator[](size_t index)\n{\n  if (auto* found{ find(index) }; found)   // Using C++17 initialization statements for if statement \n  {                                        // (see at() function for common, traditional equivalent)\n\t  return *found;\n  }\n  else\n  {\n    m_values.push_back({ index, T{} });    // Or push_back(Pair{...}), or push_back(Pair<size_t, T>{...})\n    return m_values.back().second;         // Remember: std::vector<>::back() returns a reference to its last element\n  }\n}\n\ntemplate<typename T>\nconst T& SparseArray<T>::at(size_t index) const\n{\n  const auto* found{ find(index) };\n  if (found)\n  {\n\t  return *found;\n  }\n  else\n  {\n    throw std::out_of_range{\"No value exists at index \" + std::to_string(index)};\n  }\n}\n\ntemplate<typename T>\nT& SparseArray<T>::at(size_t index)\n{\n  return const_cast<T&>(std::as_const(*this).at(index));\n}\n\ntemplate<typename T>\nbool SparseArray<T>::element_exists_at(size_t index) const\n{\n  return find(index) != nullptr;\n}\n\ntemplate<typename T>\nconst T* SparseArray<T>::find(size_t index) const\n{\n  for (auto& pair : m_values)\n  {\n    if (pair.first == index)\n      return &pair.second;\n  }\n  return nullptr;\n}\n\ntemplate<typename T>\nT* SparseArray<T>::find(size_t index)\n{\n  return const_cast<T*>(std::as_const(*this).find(index));\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_07/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  double getLength() const { return m_length; }\n  double getWidth() const { return m_width; }\n  double getHeight() const { return m_height; }\n  \nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_07/BoxFormatter.cppm",
    "content": "export module box.formatter;\nimport box;\nimport <format>;\n\n// Adding specific specializations to the std namespace is allowed\nexport template <>\nclass std::formatter<Box> : public std::formatter<double>\n{\npublic:\n  \n  /* This was no easy exercise. Fixes required compared to the outline in the exercise:\n      - the member is called advance_to() and not advance() \n        (we actually used advance() by mistake in the book, but hey, \n         it did force you to practice consulting a Standard Library reference?)\n      - you need to specify std::formatter<double> to access the base class format() function\n      - of course you still needed to add \"Box(., ., .)\" as well.\n        One way to do this is repeatedly call std::format_to(),\n        a function similar to std::format() except that it outputs not to a stream but an output iterator.\n        You can also manipulate the iterator directly, as we show in for outputting \n        the second \", \" and the \")\".\n        (Iterator manipulation is explained in more detail in Chapter 20...)\n   */\n  auto format(const Box& box, auto& context)\n  {\n    auto iter{ std::format_to(context.out(), \"Box(\") };\n    context.advance_to(iter);\n    iter = std::formatter<double>::format(box.getLength(), context);\n    iter = std::format_to(iter, \", \");\n    context.advance_to(iter);\n    iter = std::formatter<double>::format(box.getWidth(), context);\n    *iter++ = ',';\n    *iter++ = ' ';\n    context.advance_to(iter);\n    std::formatter<double>::format(box.getHeight(), context);\n    *iter++ = ')';\n    context.advance_to(iter);\n    return iter;\n  }\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_07/Soln17_07.cpp",
    "content": "// Implementing a custom std::formatter<> specialization to format Box objects\nimport box;\nimport box.formatter;\nimport <iostream>;\n\nint main()\n{\n  Box box{ 1, 2, 3 };\n  std::cout << std::format(\"My new box, {:.2}, is fabulous!\", box);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_07A/Box.cppm",
    "content": "export module box;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  double getLength() const { return m_length; }\n  double getWidth() const { return m_width; }\n  double getHeight() const { return m_height; }\n  \nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_07A/BoxFormatter.cppm",
    "content": "export module box.formatter;\n\nimport box;\nimport <format>;\nimport <string>;\n\n// Adding specific specializations to the std namespace is allowed\nexport template <>\nclass std::formatter<Box>\n{\npublic:\n  auto parse(auto& context)\n  {\n    // [context.begin(), context.end()) is a character range that contains a part of\n    // the format string starting from the format specifications to be parsed,\n    // e.g. in\n    //\n    //   std::format(\"My new box, {:.2}, is fabulous!\", box)\n    //\n    // the range will contain \".2}, is fabulous!\". The formatter should\n    // parse specifiers until '}' or the end of the range.\n    //\n    // Our goal for this same example is to store \"Box({:.2}, {:.2}, {:.2})\" in m_format.\n    // We first find the range where for instance \".2\" is present,\n    // and then inject that three times into a format string of the correct form.\n\n    auto iter{ context.begin() };\n    if (iter == context.end())  // May happen for empty {} format specifiers\n    {\n      m_format = \"Box({}, {}, {})\";\n      return iter;\n    }\n\n    // Search for the closing '}'\n    while (iter != context.end() && *iter != '}') ++iter;\n\n    if (*iter != '}') // If not found, fail\n    {\n      throw std::format_error{ \"missing closing braces, }\" };\n    }\n    \n    // Main trick in this format expression is that to get { or } \n    // in the output you have to write {{ or }}. \n    // Otherwise std::format() will see these characters as the begin or end of a replacement field.\n    m_format = std::format(\"Box({{:{0}}}, {{:{0}}}, {{:{0}}})\", std::string(context.begin(), iter));\n\n    return iter;\n  }\n\n  auto format(const Box& box, auto& context)\n  {\n    return std::format_to(\n      context.out(), \n      m_format, \n      box.getLength(), box.getWidth(), box.getHeight()\n    );\n  }\n\nprivate:\n  std::string m_format;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 17/Soln17_07A/Soln17_07A.cpp",
    "content": "// Implementing a custom std::formatter<> specialization to format Box objects\n// (Alternate solution)\nimport box;\nimport box.formatter;\nimport <iostream>;\n\nint main()\n{\n  Box box{ 1, 2, 3 };\n  std::cout << std::format(\"My new box, {:.2}, is fabulous!\", box);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_01/Box.cppm",
    "content": "export module box;\n\nimport <ostream>;\nimport <format>;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_01/RandomBoxes.cppm",
    "content": "export module box.random;\n\nimport box;\nimport <random>;        // For random number generation\nimport <functional>;    // For std::bind()\nimport <memory>;        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\nexport Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\nexport auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_01/Soln18_01.cpp",
    "content": "// Exercise 18-1 Define move operators for the Truckload class\nimport <iostream>;\nimport <memory>;\nimport truckload;\nimport box.random;\n\n/*\n  Things to watch out for:\n    - use of copy-and-swap / move-and-swap function\n    - noexcept move and swap members\n    - dislodge the linked list from the moved load in the move constructor\n*/\n\nint main()\n{\n  const double dimLimit {99.0};             // Upper limit on Box dimensions\n  Truckload load;\n  const size_t boxCount {20};               // Number of Box object to be created\n\n  // Create boxCount Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    load.addBox(randomSharedBox());\n\n  std::cout << \"The boxes in the Truckload are:\\n\";\n  std::cout << load << std::endl;\n\n  Truckload moveConstructedLoad{ std::move(load) };\n\n  std::cout << \"The boxes in the move constructed Truckload are:\\n\";\n  std::cout << moveConstructedLoad << std::endl;\n\n  Truckload moveAssignedLoad;\n  moveAssignedLoad = std::move(moveConstructedLoad);\n  \n  std::cout << \"The boxes in the move assigned Truckload are:\\n\";\n  std::cout << moveAssignedLoad << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_01/Truckload.cpp",
    "content": "module truckload;\n\nimport <iostream>;\nimport <stdexcept>;    // For standard exception type std::out_of_range \nimport <string>;       // For std::string and std::to_string()\nimport <utility>;      // For std::swap()\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Copy assignment operator (updated to use copy-and-swap of course!)\nTruckload& Truckload::operator=(const Truckload& src)\n{\n  auto copy{src};\n  swap(copy);\n  return *this;\n}\n\n// Move constructor (noexcept!)\nTruckload::Truckload(Truckload&& src) noexcept\n  : m_head{ src.m_head }\n  , m_tail{ src.m_tail }\n{\n  // Do not forget to dislodge the linked list from the moved src Truckload\n  src.m_head = src.m_tail = nullptr;\n}\n\n// Move assignment operator (noexcept + move-and-swap of course!)\nTruckload& Truckload::operator=(Truckload&& src) noexcept\n{\n  auto moved{std::move(src)};\n  swap(moved);\n  return *this;\n}\n\n// Swap assignment operator (noexcept + move-and-swap of course!)\nvoid Truckload::swap(Truckload& other) noexcept\n{\n  std::swap(m_head, other.m_head);\n  std::swap(m_tail, other.m_tail);\n}\n\n// Optional yet conventional non-member function (forwards to member function)\nvoid swap(Truckload& one, Truckload& other) noexcept\n{\n  one.swap(other);\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n                \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nSharedBox& Truckload::operator[](size_t index) const\n{\n  size_t count{};             // Package count\n  for (Package* package{ m_head }; package; package = package->m_next)\n  {\n    if (count++ == index)      // Up to index yet?\n      return package->m_box;   // If so return the pointer to Box\n  }\n  throw std::out_of_range{ \"Index too large: \" + std::to_string(index) };\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_01/Truckload.cppm",
    "content": "export module truckload;\n\nimport box;\n\nimport <memory>;\nimport <vector>;\nimport <ostream>;\n\nexport using SharedBox = std::shared_ptr<Box>;\n\nexport class Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n  ~Truckload();                     // Destructor\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n\n  Truckload(const Truckload& src);  // Copy constructor\n  Truckload& operator=(const Truckload& src);  // Copy assignment operator\n\n  Truckload(Truckload&& src) noexcept;  // Move constructor\n  Truckload& operator=(Truckload&& src) noexcept;  // Move assignment operator\n\n  void swap(Truckload& other) noexcept;\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox& operator[](size_t index) const;   // Overloaded subscript operator\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in a module interface file)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Truckload& load);\n\n// Optional yet conventional non-member function (forwards to member function)\nexport void swap(Truckload& one, Truckload& other) noexcept;\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_02/LinkedList.cppm",
    "content": "export module linked_list;\n\n/*\nThe LinkedList template below follows some (not all) conventions of Standard Library containers:\nsome member function names are analogous,\nas is the choice not to work with exceptions in case you do something wrong\n(such as calling back() or pop_front() on an empty list).\nThe latter has the implication that if you mis-use the container,\nyour program will likely crash...\n\nNew in this version are the move constructor / assignment operators \n(mind the noexcepts, as always), and the fact that the push_back() and push_front() \nmembers have been updated to allow new T values to be moved in as well.\nDo not forget to add a move constructor for the nested Node class as well\nto prevent any unnecessary copies there!\n\nNote that if you are not defining a generic container template, \nyou'd usually not add multiple overloads for copying and moving anymore.\nEven here, you could consider simply defining these two pass-by-value members:\n\n  void push_front(T value);       // Copy or move an object to the head\n  void push_back(T value);        // Copy or move an object to the tail\n\nAnd then apply the same simplification to the constructor of the nested Node class.\nThe only downside then is that this is not optimal for objects without support for move semantics, \nbit given that move semantics has been around for almost a decade should be increasingly unlikely.\nWe invite you to give it a try, and simplify the code along these lines.\n*/\n\nimport <utility>;        // for std::swap()\n\nexport template<typename T>\nclass LinkedList\n{\npublic:\n  LinkedList() = default;                  // Default constructor (all pointers are initialised to nullptr)\n  ~LinkedList();\n\n  LinkedList(const LinkedList& list);      // Copy constructor\n  LinkedList& operator=(const LinkedList& list); // Copy assignment operator\n\n  LinkedList(LinkedList&& list) noexcept;  // Move constructor\n  LinkedList& operator=(LinkedList&& list) noexcept; // Move assignment operator\n\n  void push_front(const T& value);         // Add an object to the head\n  void push_back(const T& value);          // Add an object to the tail\n  void push_front(T&& value);              // Move an object to the head\n  void push_back(T&& value);               // Move an object to the tail\n\n  void pop_back();                         // Removes the last element from the list (undefined behavior for empty lists)\n  void pop_front();                        // Removes the first element from the list (undefined behavior for empty lists)\n\n  T& front();                              // Get the object at the head (undefined behavior for empty lists)\n  T& back();                               // Get the object at the tail (undefined behavior for empty lists)\n  const T& front() const;                  // Get the object at the head (undefined behavior for empty lists)\n  const T& back() const;                   // Get the object at the tail (undefined behavior for empty lists)\n\n  bool empty() const;                      // Checks whether the list is empty or not\n  void clear();                            // Function to remove all elements from the list\n  size_t size() const;                     // Get the number of elements from the list\n\n  class Iterator;                          // Nested Iterator class declaration (definition below)\n  Iterator front_iterator() const;         // Get an Iterator that starts at the head\n  Iterator back_iterator() const;          // Get an Iterator that starts at the tail\n\n  void swap(LinkedList& other) noexcept;   // Swap function\n\nprivate:\n  class Node                               // Node class definition\n  {\n  public:\n    Node(const T& value)\n      : m_value{ value }\n    {}\n    Node(T&& value)\n      : m_value{ std::move(value) }\n    {}\n\n    T m_value;\n    Node* m_next{};\n    Node* m_previous{};\n  };\n\n  void push_front(Node* node) noexcept;\n  void push_back(Node* node) noexcept;\n\n  Node* m_head{};    // Pointer to first node\n  Node* m_tail{};    // Pointer to last node\n  size_t m_size{};\n};\n\n// Non-member swap function.\n// Convention dictates swap is present as non-member function.\n// For class types it is often easiest (and recommended) \n// to implement it using a member swap function.\nexport template<typename T>\nvoid swap(LinkedList<T>& one, LinkedList<T>& other)\n{\n  one.swap(other);\n}\n\n// ---------------------------------------------\n// Member definitions\n// ---------------------------------------------\n\n// Destructor template\ntemplate<typename T>\nLinkedList<T>::~LinkedList()\n{\n  clear();\n}\n\n// Copy constructor template\ntemplate<typename T>\nLinkedList<T>::LinkedList(const LinkedList& list)\n{\n  // Use existing members (iteration, push_back()) to implement the copying\n  // This avoids duplicating any code that manipulates the list's pointers / size members.\n  for (auto iterator{ list.front_iterator() }; iterator; iterator.next())\n    push_back(iterator.value());\n}\n\n// Move constructor template\ntemplate<typename T>\nLinkedList<T>::LinkedList(LinkedList&& list) noexcept\n  : m_head{ list.m_head }\n  , m_tail{ list.m_tail }\n  , m_size{ list.m_size }\n{\n  // Make sure list no longer deletes the nodes when destructed\n  list.m_size = 0;\n  list.m_head = list.m_tail = nullptr;  // <-- optional\n}\n\n// Copy assignment operator template (uses copy-and-swap idiom)\ntemplate<typename T>\nLinkedList<T>& LinkedList<T>::operator=(const LinkedList& other)\n{\n  auto copy{ other };\n  swap(copy);\n  return *this;\n}\n\n// Move assignment operator template (uses move-and-swap idiom)\ntemplate<typename T>\nLinkedList<T>& LinkedList<T>::operator=(LinkedList&& other) noexcept\n{\n  auto moved{ std::move(other) };\n  swap(moved);\n  return *this;\n}\n\n// Template for member functions that adds a node to the head of the list\ntemplate<typename T> \nvoid LinkedList<T>::push_front(Node* node) noexcept\n{\n  Node* oldHead{ m_head };\n  m_head = node;\n  ++m_size;\n\n  if (oldHead)\n  {\n    oldHead->m_previous = m_head;\n    m_head->m_next = oldHead;\n  }\n  else  // list was empty before, and now has one element\n  {\n    m_tail = m_head;\n  }\n}\n\n// Template for member functions that copy a value to the head of the list\n// Use push_front(Node*) to avoid any duplication!\ntemplate<typename T>\nvoid LinkedList<T>::push_front(const T& value)\n{\n  push_front(new Node{value});\n}\n\n// Template for member functions that moves a value to the head of the list\n// Use push_front(Node*) to avoid any duplication!\ntemplate<typename T>\nvoid LinkedList<T>::push_front(T&& value)\n{\n  push_front(new Node{std::move(value)});\n}\n\n// Template for member functions that add a node to the tail of the list\ntemplate<typename T>\nvoid LinkedList<T>::push_back(Node* node) noexcept\n{\n  Node* oldTail{ m_tail };\n  m_tail = node;\n  ++m_size;                 \n\n  if (oldTail)\n  {\n    oldTail->m_next = m_tail;\n    m_tail->m_previous = oldTail;\n  }\n  else  // list was empty before, and now has one element\n  {\n    m_head = m_tail;\n  }\n}\n\n// Template for member functions that copy a value to the tail of the list\n// Use push_back(Node*) to avoid any duplication!\ntemplate<typename T>\nvoid LinkedList<T>::push_back(const T& value)\n{\n  push_back(new Node{value});\n}\n\n// Template for member functions that moves a value to the tail of the list\n// Use push_back(Node*) to avoid any duplication!\ntemplate<typename T>\nvoid LinkedList<T>::push_back(T&& value)\n{\n  push_back(new Node{std::move(value)});\n}\n\n// Template for member functions that remove an object from the head of the list\ntemplate<typename T> \nvoid LinkedList<T>::pop_front()\n{\n  Node* oldHead{ m_head };\n  if (oldHead == m_tail)\n  {\n    m_head = m_tail = nullptr;\n  }\n  else\n  {\n    m_head = oldHead->m_next;\n    m_head->m_previous = nullptr;\n  }\n  \n  --m_size;\n  delete oldHead;\n}\n\n// Template function member to remove an object from the tail of the list\ntemplate<typename T>\nvoid LinkedList<T>::pop_back()\n{\n  Node* oldTail{ m_tail };\n  if (oldTail == m_head)\n  {\n    m_head = m_tail = nullptr;\n  }\n  else\n  {\n    m_tail = oldTail->m_previous;\n    m_tail->next = nullptr;\n  }\n\n  --m_size;\n  delete oldTail;\n}\n\n// Template function members to get the object at the head of the list\ntemplate<typename T>\nT& LinkedList<T>::front()\n{\n  return m_head->value;\n}\ntemplate<typename T>\nconst T& LinkedList<T>::front() const\n{\n  return m_head->value;\n}\n\n// Template function members to get the object at the tail of the list\ntemplate<typename T>\nT& LinkedList<T>::back()\n{\n  return m_tail->value;\n}\ntemplate<typename T>\nconst T& LinkedList<T>::back() const\n{\n  return m_tail->value;\n}\n\n// Check whether list is empty or not\ntemplate<typename T>\nbool LinkedList<T>::empty() const\n{\n  return m_size == 0;  // (or m_head == nullptr, or m_tail == nullptr)\n}\n\n// Template to get the size of a list\ntemplate<typename T> \nsize_t LinkedList<T>::size() const\n{\n  return m_size;\n}\n\n// Template to clear a list\ntemplate<typename T>\nvoid LinkedList<T>::clear()\n{\n  // Use existing functions (avoid code duplication!)\n  while (!empty()) pop_front();\n}\n\n// Member function template to swap two lists\ntemplate<typename T>\nvoid LinkedList<T>::swap(LinkedList& other) noexcept\n{\n  std::swap(m_head, other.m_head);\n  std::swap(m_tail, other.m_tail);\n  std::swap(m_size, other.m_size);\n}\n\n// Definition of the nested Iterator class\ntemplate<typename T>\nclass LinkedList<T>::Iterator\n{\npublic:\n  explicit Iterator(Node* node) \n    : m_current{ node }\n  {}\n\n  const T& value() const { return m_current->m_value; }\n\n  bool hasValue() const { return m_current != nullptr; }\n  operator bool() const { return m_current != nullptr; }\n\n  void next() { m_current = m_current->m_next; }\n  void previous() { m_current = m_current->m_previous; }\n\nprivate:\n  Node* m_current;\n};\n\n// Get an Iterator that starts at the head\ntemplate<typename T>\ntypename LinkedList<T>::Iterator LinkedList<T>::front_iterator() const\n{\n  return Iterator{ m_head };\n}\n\n// Get an Iterator that starts at the tail\ntemplate<typename T>\ntypename LinkedList<T>::Iterator LinkedList<T>::back_iterator() const\n{\n  return Iterator{ m_tail };\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_02/Soln18_02.cpp",
    "content": "// Exercise 18-2 Exercising the LinkedList's move capabilities\n// We do so by creating a linked list of std::unique_ptr<> elements: \n// a perfect example of an element type that cannot be copied!\nimport linked_list;\nimport <memory>;     // for std::unique_ptr<>\nimport <iostream>;\nimport <string_view>;\n\nvoid printList(std::string_view message, const LinkedList<std::unique_ptr<int>>& list)\n{\n  std::cout << message << \": \";\n  for (auto iterator{ list.front_iterator() }; iterator; iterator.next())\n  {\n    std::cout << *iterator.value() << ' ';\n  }\n  std::cout << std::endl;\n}\n\nint main()\n{\n  // In real life, you'd rarely use std::unique_ptr<int>. \n  // A more realistic use would be std::unique_ptr<ClassType>, \n  // where ClassType is a (potentially polymorphic) class type.\n  // For our example here, std::unique_ptr<int> will do just fine:\n  // the idea is simply to use an uncopyable type as template type argument for LinkedList.\n  \n  LinkedList<std::unique_ptr<int>> number_pointers;\n  \n  auto one{ std::make_unique<int>(1) };\n  number_pointers.push_back(std::move(one));\n  number_pointers.push_back(std::make_unique<int>(2));\n  \n  printList(\"Elements in the original list\", number_pointers);\n  \n  LinkedList<std::unique_ptr<int>> move_constructed{std::move(number_pointers)};\n  \n  printList(\"Elements in the move constructed list\", move_constructed);\n  \n  LinkedList<std::unique_ptr<int>> move_assigned;\n  move_assigned = std::move(move_constructed);\n  \n  printList(\"Elements in the move assigned list\", move_assigned);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_03/Customer.cpp",
    "content": "// A simple C++ customer class\n\nmodule customer;\n\nCustomer::Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city)\n  : m_surname{ surname }\n  , m_name{ name }\n  , m_street{ street }\n  , m_streetNumber{ streetNumber }\n  , m_city{ city }\n{}\n\nstd::string Customer::toString() const\n{\n  std::string result;\n  result += m_surname;\n  result += ' ';\n  result += m_name;\n  result += \", \";\n  result += m_street;\n  result += ' ';\n  result += std::to_string(m_streetNumber);\n  result += \", \";\n  result += m_city;\n  return result;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_03/Customer.cppm",
    "content": "// A simple C++ customer class\n\nexport module customer;\n\nimport <string>;\nimport <string_view>;\n\nexport class Customer\n{\npublic:\n  Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city\n  );\n\n  std::string toString() const;\n  \nprivate:\n  std::string m_surname;\n  std::string m_name;\n  std::string m_street;\n  int m_streetNumber;\n  std::string m_city;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_03/DB.cpp",
    "content": "// A mocked database\n\n#include \"DB.h\"\n#include <cstring>    // For std::strcmp()\nimport <vector>;\nimport <memory>;\n\nnamespace\n{\n  struct QueryResult\n  {\n    std::vector<std::vector<const char*>> data;\n    size_t index {};\n  };\n\n  class Database\n  {\n  public:\n    Database() = default;\n    \n\t  bool hasConnection() const { return m_connected; }\n    void connect() { m_connected = true; }\n    void disconnect() { m_connected = false; }\n    \n    QueryResult* query(const char* query);\n    \n  private:  \n    bool m_connected{};\n  };\n}\n\nDB_CONNECTION* db_connect()\n{\n  // We only have one single database, which allows only one single connection:\n  static Database theDatabase;\n  if (theDatabase.hasConnection())\n  {\n    return nullptr;\n  }\n  else\n  {\n    theDatabase.connect();\n    return &theDatabase;\n  }\n}\n\nvoid db_disconnect(DB_CONNECTION* connection)\n{\n  // reinterpret_cast<> is used to cast between pointers/references of \n  // unrelated types (such as void* and Database*)\n  reinterpret_cast<Database*>(connection)->disconnect();\n}\n\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query)\n{\n  return reinterpret_cast<Database*>(connection)->query(query);\n}\n\nQueryResult* Database::query(const char* query)\n{\n  if (!hasConnection())\n  {\n    return nullptr;\n  }\n  \n  // Our database only understands one single query!\n  if (std::strcmp(query, \"SELECT * FROM CUSTOMER_TABEL\") != 0)\n  {\n    return nullptr;\n  }\n  \n  auto result{ std::make_unique<QueryResult>() };\n  result->data = std::vector<std::vector<const char*>>{\n    { \"Sherlock\", \"Holmes\", \"Baker Street\", \"221\", \"London\" },\n    { \"Joe\", \"Biden\", \"Pennsylvania Avenue\", \"1600\", \"Washington DC\" },\n    { \"Donald\", \"Duck\", \"Webfoot Walk\", \"1313\", \"Duckville\" },\n    { \"Sirius\", \"Black\", \"Grimmauld Place\", \"12\", \"London\" },\n    { \"Nemo\", \"Clownfish\", \"Wallaby Way\", \"42\", \"Sydney\" },\n    { \"Sam\", \"Malone\", \"Beacon Street\", \"112\", \"Boston\" }\n  };\n  return result.release();\n}\n\nint db_num_fields(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->data.empty())\n  {\n    return -1;\n  }\n  else\n  {\n    return static_cast<int>(theResult->data.front().size());\n  }\n}\n\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->index >= theResult->data.size())\n  {\n    return nullptr;\n  }\n  else\n  {\n     return theResult->data[theResult->index++].data();\n  }\n}\n\nvoid db_free_result(DB_QUERY_RESULT* result)\n{\n  delete reinterpret_cast<QueryResult*>(result);\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_03/DB.h",
    "content": "// A C-style interface to a mock database\n// (a simplified subset of the MySQL C interface)\n\n#ifndef DB_INCLUDES\n#define DB_INCLUDES\n\nusing DB_CONNECTION = void;\nusing DB_QUERY_RESULT = void;\nusing DB_ROW = const char**;\n\n/*! Make a connection to the database\n * Do not forget to close the database connection (db_disconnect()) once done with it.\n * \\return a DB_CONNECTION handle; nullptr upon failure\n */\nDB_CONNECTION* db_connect();\n\n/*! Query the database\n * \\param[in] connection A database connection handle returned by db_connect()\n * \\param[in] query      A SQL query\n * \\return A handle to the result of the query (memory to be freed using db_free_result()!)\n */\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query);\n\n/*! Retrieve the number of fields per row stored by the given query result\n * \\param[in] result A handle returned by db_query \n * \\return The number of fields per row stored by the result; -1 upon failure\n */\nint db_num_fields(DB_QUERY_RESULT* result);\n\n/*! Fetch a single row from the result.\n * \\param[in] result A handle returned by db_query\n * \\return An array of strings. Each field is represented as a string (zero-terminated char array). \n * \tLet row be the result, then the first field is accessed using result[0]. \n */\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result);\n\n/*! Release the memory allocated for the result.\n * \\param[in] result A handle returned by db_query()\n */\nvoid db_free_result(DB_QUERY_RESULT* result);\n\n/*! Disconnect from the database\n * \\param[in] connection   A connection handle returned by db_connect()\n */\nvoid db_disconnect(DB_CONNECTION* connection);\n\n#endif"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_03/DBException.cppm",
    "content": "// A simple C++ exception type\n\nexport module db.exception;\nimport <stdexcept>;\n\nexport class DatabaseException : public std::runtime_error\n{\npublic:\n  using std::runtime_error::runtime_error;  // Inherit constructor\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_03/DB_RAII.cppm",
    "content": "module;\n#include \"DB.h\"\nexport module db.raii;\n\n/*\n  In this solution we have the RAII classes accept the resource handle in their constructor.\n  Alternatively, you could also acquire the resources inside the constructors of the RAII class.\n  For instance: you could call db_connect() from within the DBConnectionRAII() contructor.\n\n  When creating RAII classes, it is typically crucial they cannot be copied\n  (otherwise multiple objects would be releasing the same resource, \n   which is typically not allowed). To accomplish this, you delete both copy members.\n*/\n\n/**\n * RAII object that ensures that a given database connection is closed\n * once the RAII object goes out of scope.\n */ \nexport class DBConnectionRAII\n{\npublic:\n  DBConnectionRAII(DB_CONNECTION* connection) noexcept\n    : m_connection(connection)\n  {\n  }  \n  ~DBConnectionRAII() // implicitly noexcept\n  {\n    if (m_connection)\n    {\n      db_disconnect(m_connection);\n    }\n  }\n\n  // Prevent copying by deleting both copy members\n  DBConnectionRAII(const DBConnectionRAII& other) = delete;\n  DBConnectionRAII& operator=(const DBConnectionRAII& other) = delete;\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_CONNECTION*() const noexcept { return m_connection; }\n  \nprivate:\n  DB_CONNECTION* m_connection;\n};\n\n/* RAII object that takes a DB_QUERY_RESULT and ensures it is freed */\nexport class DBQueryResultRAII\n{\npublic:\n  DBQueryResultRAII(DB_QUERY_RESULT* result) noexcept \n    : m_result(result)\n  {\n  }\n  \n  ~DBQueryResultRAII() // implicitly noexcept\n  {\n    if (m_result)\n    {\n      db_free_result(m_result);\n    }\n  }\n\n  // Prevent copying by deleting both copy members\n  DBQueryResultRAII(const DBQueryResultRAII& other) = delete;\n  DBQueryResultRAII& operator=(const DBQueryResultRAII& other) = delete;\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_QUERY_RESULT* () const noexcept { return m_result; }\n\nprivate:\n  DB_QUERY_RESULT* m_result;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_03/Soln18_03.cpp",
    "content": "// Exercise 18-3\n/*\n  Below is the same test program as used in Exercise 16-6, \n  with some additional commented lines to show that the RAII objects cannot be copied.\n*/\n\nimport <iostream>;\nimport <vector>;\n\n#include \"DB.h\"\nimport db.exception;\nimport db.raii;\nimport customer;\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result);           // Sanity check on the number of fields returned by our query\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result); // Convert the DB result to a series of C++ objects\nvoid print(std::ostream& stream, const Customer& customer);   // Print a given customer to a given output stream\n\nint main()\n{\n  DBConnectionRAII connection{ db_connect() };\n  /*\n    DBConnectionRAII copy{ connection };  // Will not compile (copy constructor is deleted)\n  \n    DBConnectionRAII otherConnection{ db_connect() };\n    otherConnection = connection;         // Will not compile (copy assignment operator is deleted)\n  */\n  try\n  {\n    DBQueryResultRAII result{ db_query(connection, \"SELECT * FROM CUSTOMER_TABEL\") };\n    if (!result)\n    {\n      throw DatabaseException{\"Query failed\"};\n    }\n  \n  /*\n    DBQueryResultRAII copy{ result };    // Will not compile (copy constructor is deleted)\n  \n    DBQueryResultRAII otherResult{ db_query(connection, \"SELECT * FROM CUSTOMER_TABEL\") };\n    otherResult = result;                // Will not compile (copy assignment operator is deleted)\n  */\n  \n    std::vector<Customer> customers{ readCustomers(result) };\n  \n  if (customers.empty())\n  {\n    std::cerr << \"No customers found?\" << std::endl;\n    return 2;\n  }\n    \n  for (auto& customer : customers)\n  {\n     print(std::cout, customer);\n  }\n  }\n  catch (std::exception& caught)\n  {\n    std::cerr << caught.what() << std::endl;\n    return 1;\n  }\n}\n\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result)\n{\n  // Sanity check \n  // (if the number of fields does not match 5, \n  // the code below would crash!)\n  verifyCustomerFields(result);\n   \n  std::vector<Customer> customers;\n  \n  auto row{ db_fetch_row(result) };\n  while (row)\n  {\n    customers.push_back(Customer{\n      row[0],            // Surname\n      row[1],            // Name\n      row[2],            // Street\n      std::stoi(row[3]), // Street number\n      row[4]             // City\n    });\n    \n    row = db_fetch_row(result);\n  }\n  \n  return customers;\n}\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result)\n{\n  int numFields{ db_num_fields(result) };\n  if (numFields < 0)\n  {\n    throw DatabaseException{\"db_num_fields() failed\"};\n  }\n  if (numFields != 5)\n  {\n    throw DatabaseException{\"Unexpected number of fields: \" + std::to_string(numFields)};\n  }\n}\n\nvoid print(std::ostream& stream, const Customer& customer)\n{\n  stream << customer.toString() << std::endl;\n  if (std::cout.fail())\n  {\n    std::cout.clear();\n    throw std::runtime_error(\"Failed to output customer\");\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_04/Customer.cpp",
    "content": "// A simple C++ customer class\n\nmodule customer;\n\nCustomer::Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city)\n  : m_surname{ surname }\n  , m_name{ name }\n  , m_street{ street }\n  , m_streetNumber{ streetNumber }\n  , m_city{ city }\n{}\n\nstd::string Customer::toString() const\n{\n  std::string result;\n  result += m_surname;\n  result += ' ';\n  result += m_name;\n  result += \", \";\n  result += m_street;\n  result += ' ';\n  result += std::to_string(m_streetNumber);\n  result += \", \";\n  result += m_city;\n  return result;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_04/Customer.cppm",
    "content": "// A simple C++ customer class\n\nexport module customer;\n\nimport <string>;\nimport <string_view>;\n\nexport class Customer\n{\npublic:\n  Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city\n  );\n\n  std::string toString() const;\n  \nprivate:\n  std::string m_surname;\n  std::string m_name;\n  std::string m_street;\n  int m_streetNumber;\n  std::string m_city;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_04/DB.cpp",
    "content": "// A mocked database\n\n#include \"DB.h\"\n#include <cstring>    // For std::strcmp()\nimport <memory>;\nimport <vector>;\n\nnamespace\n{\n  struct QueryResult\n  {\n    std::vector<std::vector<const char*>> data;\n    size_t index {};\n  };\n\n  class Database\n  {\n  public:\n    Database() = default;\n    \n\t  bool hasConnection() const { return m_connected; }\n    void connect() { m_connected = true; }\n    void disconnect() { m_connected = false; }\n    \n    QueryResult* query(const char* query);\n    \n  private:  \n    bool m_connected{};\n  };\n}\n\nDB_CONNECTION* db_connect()\n{\n  // We only have one single database, which allows only one single connection:\n  static Database theDatabase;\n  if (theDatabase.hasConnection())\n  {\n    return nullptr;\n  }\n  else\n  {\n    theDatabase.connect();\n    return &theDatabase;\n  }\n}\n\nvoid db_disconnect(DB_CONNECTION* connection)\n{\n  // reinterpret_cast<> is used to cast between pointers/references of \n  // unrelated types (such as void* and Database*)\n  reinterpret_cast<Database*>(connection)->disconnect();\n}\n\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query)\n{\n  return reinterpret_cast<Database*>(connection)->query(query);\n}\n\nQueryResult* Database::query(const char* query)\n{\n  if (!hasConnection())\n  {\n    return nullptr;\n  }\n  \n  // Our database only understands one single query!\n  if (std::strcmp(query, \"SELECT * FROM CUSTOMER_TABEL\") != 0)\n  {\n    return nullptr;\n  }\n  \n  auto result{ std::make_unique<QueryResult>() };\n  result->data = std::vector<std::vector<const char*>>{\n    { \"Sherlock\", \"Holmes\", \"Baker Street\", \"221\", \"London\" },\n    { \"Donald\", \"Trump\", \"Pennsylvania Avenue\", \"1600\", \"Washington DC\" },\n    { \"Donald\", \"Duck\", \"Webfoot Walk\", \"1313\", \"Duckville\" },\n    { \"Sirius\", \"Black\", \"Grimmauld Place\", \"12\", \"London\" },\n    { \"Nemo\", \"Clownfish\", \"Wallaby Way\", \"42\", \"Sydney\" },\n    { \"Sam\", \"Malone\", \"Beacon Street\", \"112\", \"Boston\" }\n  };\n  return result.release();\n}\n\nint db_num_fields(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->data.empty())\n  {\n    return -1;\n  }\n  else\n  {\n    return static_cast<int>(theResult->data.front().size());\n  }\n}\n\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->index >= theResult->data.size())\n  {\n    return nullptr;\n  }\n  else\n  {\n     return theResult->data[theResult->index++].data();\n  }\n}\n\nvoid db_free_result(DB_QUERY_RESULT* result)\n{\n  delete reinterpret_cast<QueryResult*>(result);\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_04/DB.h",
    "content": "// A C-style interface to a mock database\n// (a simplified subset of the MySQL C interface)\n\n#ifndef DB_INCLUDES\n#define DB_INCLUDES\n\nusing DB_CONNECTION = void;\nusing DB_QUERY_RESULT = void;\nusing DB_ROW = const char**;\n\n/*! Make a connection to the database\n * Do not forget to close the database connection (db_disconnect()) once done with it.\n * \\return a DB_CONNECTION handle; nullptr upon failure\n */\nDB_CONNECTION* db_connect();\n\n/*! Query the database\n * \\param[in] connection A database connection handle returned by db_connect()\n * \\param[in] query      A SQL query\n * \\return A handle to the result of the query (memory to be freed using db_free_result()!)\n */\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query);\n\n/*! Retrieve the number of fields per row stored by the given query result\n * \\param[in] result A handle returned by db_query \n * \\return The number of fields per row stored by the result; -1 upon failure\n */\nint db_num_fields(DB_QUERY_RESULT* result);\n\n/*! Fetch a single row from the result.\n * \\param[in] result A handle returned by db_query\n * \\return An array of strings. Each field is represented as a string (zero-terminated char array). \n * \tLet row be the result, then the first field is accessed using result[0]. \n */\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result);\n\n/*! Release the memory allocated for the result.\n * \\param[in] result A handle returned by db_query()\n */\nvoid db_free_result(DB_QUERY_RESULT* result);\n\n/*! Disconnect from the database\n * \\param[in] connection   A connection handle returned by db_connect()\n */\nvoid db_disconnect(DB_CONNECTION* connection);\n\n#endif"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_04/DBException.cppm",
    "content": "// A simple C++ exception type\n\nexport module db.exception;\n\nimport <stdexcept>;\n\nexport class DatabaseException : public std::runtime_error\n{\npublic:\n  using std::runtime_error::runtime_error;  // Inherit constructor\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_04/DB_RAII.cppm",
    "content": "// RAII classes for handles returned by DB.h C interface functions\n\n/*\n  In this solution we have the RAII classes accept the resource handle in their constructor.\n  Alternatively, you could also acquire the resources inside the constructors of the RAII class.\n  For instance: you could call db_connect() from within the DBConnectionRAII() contructor.\n\n  When creating RAII classes, it is typically crucial they cannot be copied\n  (otherwise multiple objects would be releasing the same resource, \n  which is typically not allowed). To accomplish this, you delete both copy members.\n  Moving RAII objects, on the other hand, is usually possible.\n*/\n\nmodule;\n#include \"DB.h\"\nexport module db.raii;\n\n/**\n * RAII object that ensures that a given database connection is closed\n * once the RAII object goes out of scope.\n */ \nexport class DBConnectionRAII\n{\npublic:\n  DBConnectionRAII(DB_CONNECTION* connection = nullptr) noexcept\n    : m_connection(connection)\n  {\n  }  \n  ~DBConnectionRAII() // implicitly noexcept\n  {\n    if (m_connection)\n    {\n      db_disconnect(m_connection);\n    }\n  }\n\n  // Prevent copying by deleting both copy members\n  DBConnectionRAII(const DBConnectionRAII& other) = delete;\n  DBConnectionRAII& operator=(const DBConnectionRAII& other) = delete;\n\n  // Allow moving by adding the appropriate members\n  DBConnectionRAII(DBConnectionRAII&& other) noexcept\n    : m_connection{ other.m_connection }\n  {\n    other.m_connection = nullptr; // Make sure other no longer closes the connection\n  }\n  DBConnectionRAII& operator=(DBConnectionRAII&& other) noexcept\n  {\n    // You could consider move-and-swap here, but it's so trivial we decided against it here.\n    m_connection = other.m_connection;\n    other.m_connection = nullptr;\n    return *this;\n  }\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_CONNECTION*() const noexcept { return m_connection; }\n  \nprivate:\n  DB_CONNECTION* m_connection;\n};\n\n/* RAII object that takes a DB_QUERY_RESULT and ensures it is freed */\nexport class DBQueryResultRAII\n{\npublic:\n  DBQueryResultRAII(DB_QUERY_RESULT* result = nullptr) noexcept\n    : m_result{ result }\n  {\n  }\n  \n  ~DBQueryResultRAII() // implicitly noexcept\n  {\n    if (m_result)\n    {\n      db_free_result(m_result);\n    }\n  }\n\n  // Prevent copying by deleting both copy members\n  DBQueryResultRAII(const DBQueryResultRAII& other) = delete;\n  DBQueryResultRAII& operator=(const DBQueryResultRAII& other) = delete;\n\n  // Allow moving by adding the appropriate members\n  DBQueryResultRAII(DBQueryResultRAII&& other) noexcept\n    : m_result{ other.m_result }\n  {\n    other.m_result = nullptr; // Make sure other no longer closes the connection\n  }\n  DBQueryResultRAII& operator=(DBQueryResultRAII&& other) noexcept\n  {\n    // You could consider move-and-swap here, but it's so trivial we decided against it here.\n    m_result = other.m_result;\n    other.m_result = nullptr;\n    return *this;\n  }\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_QUERY_RESULT* () const noexcept { return m_result; }\n\nprivate:\n  DB_QUERY_RESULT* m_result;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_04/Soln18_04.cpp",
    "content": "// Exercise 18-4\n/* \n  Below is the same test program as used in Exercise 16-6, \n  with some additional lines to show that the RAII objects can be moved.\n*/\n\nimport <iostream>;\nimport <vector>;\n\n#include \"DB.h\"\nimport db.exception;\nimport db.raii;\nimport customer;\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result);           // Sanity check on the number of fields returned by our query\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result); // Convert the DB result to a series of C++ objects\nvoid print(std::ostream& stream, const Customer& customer);   // Print a given customer to a given output stream\n\nint main()\n{\n  DBConnectionRAII connection{ db_connect() };\n  DBConnectionRAII moved_connection{ std::move(connection) };\n  \n  try\n  {\n    DBQueryResultRAII result{ db_query(moved_connection, \"SELECT * FROM CUSTOMER_TABEL\") };\n    if (!result)\n    {\n      throw DatabaseException{\"Query failed\"};\n    }\n\t\n\tDBQueryResultRAII moved_result;\n\tmoved_result = std::move(result);\n\t\n    std::vector<Customer> customers{ readCustomers(moved_result) };\n  \n  if (customers.empty())\n  {\n    std::cerr << \"No customers found?\" << std::endl;\n    return 2;\n  }\n    \n  for (auto& customer : customers)\n  {\n     print(std::cout, customer);\n  }\n  }\n  catch (std::exception& caught)\n  {\n    std::cerr << caught.what() << std::endl;\n    return 1;\n  }\n}\n\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result)\n{\n  // Sanity check \n  // (if the number of fields does not match 5, \n  // the code below would crash!)\n  verifyCustomerFields(result);\n   \n  std::vector<Customer> customers;\n  \n  auto row{ db_fetch_row(result) };\n  while (row)\n  {\n    customers.push_back(Customer{\n      row[0],            // Surname\n      row[1],            // Name\n      row[2],            // Street\n      std::stoi(row[3]), // Street number\n      row[4]             // City\n    });\n    \n    row = db_fetch_row(result);\n  }\n  \n  return customers;\n}\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result)\n{\n  int numFields{ db_num_fields(result) };\n  if (numFields < 0)\n  {\n    throw DatabaseException{\"db_num_fields() failed\"};\n  }\n  if (numFields != 5)\n  {\n    throw DatabaseException{\"Unexpected number of fields: \" + std::to_string(numFields)};\n  }\n}\n\nvoid print(std::ostream& stream, const Customer& customer)\n{\n  stream << customer.toString() << std::endl;\n  if (std::cout.fail())\n  {\n    std::cout.clear();\n    throw std::runtime_error(\"Failed to output customer\");\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_05/Customer.cpp",
    "content": "// A simple C++ customer class\n\nmodule customer;\n\nCustomer::Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city)\n  : m_surname{ surname }\n  , m_name{ name }\n  , m_street{ street }\n  , m_streetNumber{ streetNumber }\n  , m_city{ city }\n{}\n\nstd::string Customer::toString() const\n{\n  std::string result;\n  result += m_surname;\n  result += ' ';\n  result += m_name;\n  result += \", \";\n  result += m_street;\n  result += ' ';\n  result += std::to_string(m_streetNumber);\n  result += \", \";\n  result += m_city;\n  return result;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_05/Customer.cppm",
    "content": "// A simple C++ customer class\n\nexport module customer;\n\nimport <string>;\nimport <string_view>;\n\nexport class Customer\n{\npublic:\n  Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city\n  );\n\n  std::string toString() const;\n  \nprivate:\n  std::string m_surname;\n  std::string m_name;\n  std::string m_street;\n  int m_streetNumber;\n  std::string m_city;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_05/DB.cpp",
    "content": "// A mocked database\n\n#include \"DB.h\"\n#include <cstring>    // For std::strcmp()\n#include <memory>\n#include <vector>\n\nnamespace\n{\n  struct QueryResult\n  {\n    std::vector<std::vector<const char*>> data;\n    size_t index {};\n  };\n\n  class Database\n  {\n  public:\n    Database() = default;\n    \n\t  bool hasConnection() const { return m_connected; }\n    void connect() { m_connected = true; }\n    void disconnect() { m_connected = false; }\n    \n    QueryResult* query(const char* query);\n    \n  private:  \n    bool m_connected{};\n  };\n}\n\nDB_CONNECTION* db_connect()\n{\n  // We only have one single database, which allows only one single connection:\n  static Database theDatabase;\n  if (theDatabase.hasConnection())\n  {\n    return nullptr;\n  }\n  else\n  {\n    theDatabase.connect();\n    return &theDatabase;\n  }\n}\n\nvoid db_disconnect(DB_CONNECTION* connection)\n{\n  // reinterpret_cast<> is used to cast between pointers/references of \n  // unrelated types (such as void* and Database*)\n  reinterpret_cast<Database*>(connection)->disconnect();\n}\n\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query)\n{\n  return reinterpret_cast<Database*>(connection)->query(query);\n}\n\nQueryResult* Database::query(const char* query)\n{\n  if (!hasConnection())\n  {\n    return nullptr;\n  }\n  \n  // Our database only understands one single query!\n  if (std::strcmp(query, \"SELECT * FROM CUSTOMER_TABEL\") != 0)\n  {\n    return nullptr;\n  }\n  \n  auto result{ std::make_unique<QueryResult>() };\n  result->data = std::vector<std::vector<const char*>>{\n    { \"Sherlock\", \"Holmes\", \"Baker Street\", \"221\", \"London\" },\n    { \"Joe\", \"Biden\", \"Pennsylvania Avenue\", \"1600\", \"Washington DC\" },\n    { \"Donald\", \"Duck\", \"Webfoot Walk\", \"1313\", \"Duckville\" },\n    { \"Sirius\", \"Black\", \"Grimmauld Place\", \"12\", \"London\" },\n    { \"Nemo\", \"Clownfish\", \"Wallaby Way\", \"42\", \"Sydney\" },\n    { \"Sam\", \"Malone\", \"Beacon Street\", \"112\", \"Boston\" }\n  };\n  return result.release();\n}\n\nint db_num_fields(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->data.empty())\n  {\n    return -1;\n  }\n  else\n  {\n    return static_cast<int>(theResult->data.front().size());\n  }\n}\n\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->index >= theResult->data.size())\n  {\n    return nullptr;\n  }\n  else\n  {\n     return theResult->data[theResult->index++].data();\n  }\n}\n\nvoid db_free_result(DB_QUERY_RESULT* result)\n{\n  delete reinterpret_cast<QueryResult*>(result);\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_05/DB.h",
    "content": "// A C-style interface to a mock database\n// (a simplified subset of the MySQL C interface)\n\n#ifndef DB_INCLUDES\n#define DB_INCLUDES\n\nusing DB_CONNECTION = void;\nusing DB_QUERY_RESULT = void;\nusing DB_ROW = const char**;\n\n/*! Make a connection to the database\n * Do not forget to close the database connection (db_disconnect()) once done with it.\n * \\return a DB_CONNECTION handle; nullptr upon failure\n */\nDB_CONNECTION* db_connect();\n\n/*! Query the database\n * \\param[in] connection A database connection handle returned by db_connect()\n * \\param[in] query      A SQL query\n * \\return A handle to the result of the query (memory to be freed using db_free_result()!)\n */\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query);\n\n/*! Retrieve the number of fields per row stored by the given query result\n * \\param[in] result A handle returned by db_query \n * \\return The number of fields per row stored by the result; -1 upon failure\n */\nint db_num_fields(DB_QUERY_RESULT* result);\n\n/*! Fetch a single row from the result.\n * \\param[in] result A handle returned by db_query\n * \\return An array of strings. Each field is represented as a string (zero-terminated char array). \n * \tLet row be the result, then the first field is accessed using result[0]. \n */\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result);\n\n/*! Release the memory allocated for the result.\n * \\param[in] result A handle returned by db_query()\n */\nvoid db_free_result(DB_QUERY_RESULT* result);\n\n/*! Disconnect from the database\n * \\param[in] connection   A connection handle returned by db_connect()\n */\nvoid db_disconnect(DB_CONNECTION* connection);\n\n#endif"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_05/DBException.cppm",
    "content": "// A simple C++ exception type\n\nexport module db.exception;\n\nimport <stdexcept>;\n\nexport class DatabaseException : public std::runtime_error\n{\npublic:\n  using std::runtime_error::runtime_error;  // Inherit constructor\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_05/DB_RAII.cppm",
    "content": "// RAII classes for handles returned by DB.h C interface functions\n\n/*\n  In this solution we have the RAII classes accept the resource handle in their constructor.\n  Alternatively, you could also acquire the resources inside the constructors of the RAII class.\n  For instance: you could call db_connect() from within the DBConnectionRAII() contructor.\n\n  When creating RAII classes, it is typically crucial they cannot be copied\n  (otherwise multiple objects would be releasing the same resource, \n  which is typically not allowed). To accomplish this, you delete both copy members.\n  Moving RAII objects, on the other hand, is usually possible.\n*/\n\nmodule;\n#include \"DB.h\"\nexport module db.raii;\n\nimport <utility>;    // For std::exchange<>()\n\n/**\n * RAII object that ensures that a given database connection is closed\n * once the RAII object goes out of scope.\n */ \nexport class DBConnectionRAII\n{\npublic:\n  DBConnectionRAII(DB_CONNECTION* connection = nullptr) noexcept\n    : m_connection(connection)\n  {\n  }  \n  ~DBConnectionRAII() // implicitly noexcept\n  {\n    if (m_connection)\n    {\n      db_disconnect(m_connection);\n    }\n  }\n\n  // Prevent copying by deleting both copy members\n  DBConnectionRAII(const DBConnectionRAII& other) = delete;\n  DBConnectionRAII& operator=(const DBConnectionRAII& other) = delete;\n\n  // Allow moving by adding the appropriate members\n  DBConnectionRAII(DBConnectionRAII&& other) noexcept\n    : m_connection{ std::exchange(other.m_connection, nullptr) }\n  {\n  }\n  DBConnectionRAII& operator=(DBConnectionRAII&& other) noexcept\n  {\n    // You could consider move-and-swap here, but it's so trivial (especially now)\n    // that we decided against it here.\n    m_connection = std::exchange(other.m_connection, nullptr);\n    return *this;\n  }\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_CONNECTION*() const noexcept { return m_connection; }\n  \nprivate:\n  DB_CONNECTION* m_connection;\n};\n\n/* RAII object that takes a DB_QUERY_RESULT and ensures it is freed */\nexport class DBQueryResultRAII\n{\npublic:\n  DBQueryResultRAII(DB_QUERY_RESULT* result = nullptr) noexcept\n    : m_result{ result }\n  {\n  }\n  \n  ~DBQueryResultRAII() // implicitly noexcept\n  {\n    if (m_result)\n    {\n      db_free_result(m_result);\n    }\n  }\n\n  // Prevent copying by deleting both copy members\n  DBQueryResultRAII(const DBQueryResultRAII& other) = delete;\n  DBQueryResultRAII& operator=(const DBQueryResultRAII& other) = delete;\n\n  // Allow moving by adding the appropriate members\n  DBQueryResultRAII(DBQueryResultRAII&& other) noexcept\n    : m_result{ std::exchange(other.m_result, nullptr) }\n  {\n  }\n  DBQueryResultRAII& operator=(DBQueryResultRAII&& other) noexcept\n  {\n    // You could consider move-and-swap here, but it's so trivial (especially now)\n    // that we decided against it here.\n    m_result = std::exchange(other.m_result, nullptr);\n    return *this;\n  }\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_QUERY_RESULT* () const noexcept { return m_result; }\n\nprivate:\n  DB_QUERY_RESULT* m_result;\n};\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 18/Soln18_05/Soln18_05.cpp",
    "content": "// Exercise 18-5\n// Only difference is the use of std::exchange() in the RAII classes\n\nimport <iostream>;\nimport <vector>;\n\n#include \"DB.h\"\nimport db.exception;\nimport db.raii;\nimport customer;\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result);           // Sanity check on the number of fields returned by our query\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result); // Convert the DB result to a series of C++ objects\nvoid print(std::ostream& stream, const Customer& customer);   // Print a given customer to a given output stream\n\nint main()\n{\n  DBConnectionRAII connection{ db_connect() };\n  DBConnectionRAII moved_connection{ std::move(connection) };\n  \n  try\n  {\n    DBQueryResultRAII result{ db_query(moved_connection, \"SELECT * FROM CUSTOMER_TABEL\") };\n    if (!result)\n    {\n      throw DatabaseException{\"Query failed\"};\n    }\n\t\n\tDBQueryResultRAII moved_result;\n\tmoved_result = std::move(result);\n\t\n    std::vector<Customer> customers{ readCustomers(moved_result) };\n  \n  if (customers.empty())\n  {\n    std::cerr << \"No customers found?\" << std::endl;\n    return 2;\n  }\n    \n  for (auto& customer : customers)\n  {\n     print(std::cout, customer);\n  }\n  }\n  catch (std::exception& caught)\n  {\n    std::cerr << caught.what() << std::endl;\n    return 1;\n  }\n}\n\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result)\n{\n  // Sanity check \n  // (if the number of fields does not match 5, \n  // the code below would crash!)\n  verifyCustomerFields(result);\n   \n  std::vector<Customer> customers;\n  \n  auto row{ db_fetch_row(result) };\n  while (row)\n  {\n    customers.push_back(Customer{\n      row[0],            // Surname\n      row[1],            // Name\n      row[2],            // Street\n      std::stoi(row[3]), // Street number\n      row[4]             // City\n    });\n    \n    row = db_fetch_row(result);\n  }\n  \n  return customers;\n}\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result)\n{\n  int numFields{ db_num_fields(result) };\n  if (numFields < 0)\n  {\n    throw DatabaseException{\"db_num_fields() failed\"};\n  }\n  if (numFields != 5)\n  {\n    throw DatabaseException{\"Unexpected number of fields: \" + std::to_string(numFields)};\n  }\n}\n\nvoid print(std::ostream& stream, const Customer& customer)\n{\n  stream << customer.toString() << std::endl;\n  if (std::cout.fail())\n  {\n    std::cout.clear();\n    throw std::runtime_error(\"Failed to output customer\");\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_01/Soln19_01.cpp",
    "content": "// Exercise 19-1. \n// A lambda expression returning the number of vector elements that begin with a given letter.\n\nimport <iostream>;\nimport <format>;\nimport <string>;\nimport <vector>;\n\nint main()\n{\n  std::vector<std::string> words{\"apple\", \"pear\", \"plum\", \"orange\", \"peach\", \"grape\", \"greengage\"};\n  std::cout << \"Words are:\\n\";\n  for (const auto& word : words)\n    std::cout << std::format(\"{:10}\", word);\n  std::cout << std::endl;\n\n  const auto count {\n    [&words](char letter)\n    {\n      size_t n {};\n      for (auto& word : words)\n        if (letter == word[0]) ++n;\n      return n;\n    }\n  };\n  \n  char ch {'p'};\n  std::cout << std::format(\"There are {} words that begin with {}.\\n\", count(ch), ch);\n  ch = 'g';\n  std::cout << std::format(\"There are {} words that begin with {}.\\n\", count(ch), ch);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_02/Soln19_02.cpp",
    "content": "// Exercise 19-2. \n// Sorting in various ways using higher-order functions, functors, and lambda expressions.\n\nimport <iostream>;\nimport <format>;\nimport <functional>;\nimport <vector>;\n\nimport sort;\n\n#include <cctype>         // For std::tolower()\n#include <cmath>          // For std::abs()\n\n// Output vector elements\ntemplate<typename T>\nvoid list(const std::vector<T>& values, size_t width = 5)\n{\n  for (auto value : values)\n    std::cout << std::format(\"{:{}}\", value, width);\n  std::cout << std::endl;\n}\n\nint main()\n{\n  std::vector numbers{ -2, 4, -5, 6, 10, -40, 56, 4, 67, 45 };\n  std::cout << \"\\nIntegers to be sorted:\\n\";\n  list(numbers);\n  sort(numbers, std::greater<>{});\n  std::cout << \"\\nSorted integers:\\n\";\n  list(numbers);\n\n  std::cout << \"\\nCharacters to be sorted:\\n\";\n  std::vector letters{ 'C', 'd', 'a', 'z', 't', 'S', 'p', 'm', 'D', 'f' };\n  list(letters, 2);\n  sort(letters, [](char x, char y) { return std::tolower(x) < std::tolower(y); });\n  std::cout << \"\\nSorted characters:\\n\";\n  list(letters, 2);\n\n  std::cout << \"\\nFloating-point values to be sorted:\\n\";\n  std::vector values{ -2.5, 1.4, -2.55, 6.3, 10.1, -40.5, 56.0, 4.7, 67.3, 45.0 };\n  list(values, 10);\n  sort(values, [](double x, double y) { return std::abs(x) < std::abs(y); });\n  std::cout << \"\\nSorted floaating-point values:\\n\";\n  list(values, 10);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_02/Sort.cppm",
    "content": "export module sort;\n\nimport <utility>;    // for std::swap()\nimport <vector>;\n\n// The primary, exported sort() template with two function parameters calls \n// this internal sort() template with four parameters\ntemplate<typename T, typename Compare>\nvoid sort(std::vector<T>& data, Compare compare, size_t start, size_t end);\n\n// Sort all vector elements\nexport template<typename T, typename Compare>\nvoid sort(std::vector<T>& data, Compare compare)\n{\n  if (!data.empty())\n    sort(data, compare, 0, data.size() - 1);\n}\n\n// Swap two vector elements\ntemplate<typename T>\nvoid swap(std::vector<T>& data, size_t first, size_t second)\n{\n  std::swap(data[first], data[second]);\n}\n\n// Sort a range of vector elements\ntemplate<typename T, typename Compare>\nvoid sort(std::vector<T>& data, Compare compare, size_t start, size_t end)\n{\n  // Start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle value to partition set\n  swap(data, start, (start + end) / 2);       // Swap middle value with start\n \n  // Check data against chosen value\n  size_t current{ start };                    // The index of the last element less than the chosen element (after partitioning)\n  for (size_t i{ start + 1 }; i <= end; ++i)\n  {\n    if (compare(data[i], data[start]))        // Is value less than chosen word?\n      swap(data, ++current, i);               // Yes, so swap to the left\n  }\n\n  swap(data, start, current);                 // Swap the chosen value with last in\n\n  if (current > start) sort(data, compare, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) sort(data, compare, current + 1, end); // Sort right subset if exists\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_03/BubbleSort.cppm",
    "content": "export module sort.bubble;\n\nimport <utility>;    // for std::swap()\nimport <vector>;\n\n// The sorting algorithm exported by this module\nexport template<typename T, typename Compare>\nvoid bubbleSort(std::vector<T>& data, Compare compare);\n\n// Utility to swap two vector elements\ntemplate<typename T>\nvoid swap(std::vector<T>& data, size_t first, size_t second)\n{\n  std::swap(data[first], data[second]);\n}\n\ntemplate<typename T, typename Compare>\nvoid bubbleSort(std::vector<T>& data, Compare compare)\n{\n  if (data.empty())\n    return;\n\n  while (true)\n  {\n    bool swapped{ false };    // Becomes true when not all values are in order\n    for (size_t i {}; i < data.size() - 1; ++i)\n    {\n      if (compare(data[i+1], data[i]))  // Out of order so swap them\n      {\n        swap(data, i, i+1);\n        swapped = true;\n      }\n    }\n\t\n    if (!swapped)   // If there were no swaps\n      break;        // ...they are in order...\n  }                 // ...otherwise, go round again.\n}\t\n"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_03/Quicksort.cppm",
    "content": "export module sort.quick;\n\nimport <utility>;    // for std::swap()\nimport <vector>;\n\n// The sorting algorithm exported by this module\nexport template<typename T, typename Compare>\nvoid quicksort(std::vector<T>& values, Compare compare);\n\n// Utility to swap two vector elements\ntemplate<typename T>\nvoid swap(std::vector<T>& data, size_t first, size_t second)\n{\n  std::swap(data[first], data[second]);\n}\n\n// The primary, exported quicksort() template with two parameter \n// calls the quicksort() template with four parameters\n\n// Sort a range of vector elements\ntemplate<typename T, typename Compare>\nvoid quicksort(std::vector<T>& data, Compare compare, size_t start, size_t end)\n{\n  // Start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle value to partition set\n  swap(data, start, (start + end) / 2);       // Swap middle value with start\n \n  // Check data against chosen value\n  size_t current{ start };                    // The index of the last element less than the chosen element (after partitioning)\n  for (size_t i{ start + 1 }; i <= end; ++i)\n  {\n    if (compare(data[i], data[start]))        // Is value less than chosen word?\n      swap(data, ++current, i);               // Yes, so swap to the left\n  }\n\n  swap(data, start, current);                 // Swap the chosen value with last in\n\n  if (current > start) quicksort(data, compare, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) quicksort(data, compare, current + 1, end); // Sort right subset if exists\n}\n\n// Sort all vector elements using quicksort\ntemplate<typename T, typename Compare>\nvoid quicksort(std::vector<T>& data, Compare compare)\n{\n  if (!data.empty())\n    quicksort(data, compare, 0, data.size() - 1);\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_03/Soln19_03.cpp",
    "content": "// Exercise 19-3. Comparing sorting algorithms\n\nimport <iostream>;\nimport <format>;\nimport <random>;        // For random number generation\nimport <functional>;    // For std::bind() and \nimport <algorithm>;     // For std::ranges::sort() (bonus algorithm)\nimport <vector>;\n\nimport sort;\n\n#include <cmath>        // For std::log2()\n\n/*\n  If you look carefully, you will notice that our implementation of quicksort\n  deviates from the theoretical expectations. The larger the input size,\n  the more it deviates (as shown by the ratios in our output).\n  Better implementations of quicksort are no doubt possible:\n  on random data an optimal quicksort algorithm should perform, on average,\n  at a ratio 1.39 of the log-linear best case performance.\n  But better algorithms exist as well. As a reference, we also compared with\n  the Standard Library's sort() algorithm you'll learn about in Chapter 20.\n  This algorithm should perform very close to the theoretical optimum.\n*/\n\n// Function to generate a random integer 1 to 100 (both inclusive)\n// Caution: unlike uniform_real_distribution, uniform_int_distribution \n// generates numbers in a closed interval [min, max].\nauto createUniformPseudoRandomNumberGenerator()\n{\n  std::random_device seeder;       // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };   // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ 1u, 100u }; // Generate in [0, 100] interval\n  return std::bind(distribution, generator);          //... and in the darkness bind them!\n}\n\nauto generateRandomNumbers(unsigned number)\n{\n  static auto random{ createUniformPseudoRandomNumberGenerator() };\n  std::vector<unsigned> random_numbers;\n  for (unsigned i{}; i < number; ++i)\n    random_numbers.push_back(random());\n  return random_numbers;\n}\n\nint main()\n{  \n  unsigned count {};\n  const auto counting_less{ [&count](int x, int y) { ++count; return x < y; } };\n  \n  for (auto size : { 500u, 1'000u, 2'000u, 4'000u })\n  {\n    const auto numbers{ generateRandomNumbers(size) };\n    \n    count = 0;                 // Reset the count\n    auto copy{ numbers };      // Ensure both sorrting algorithms work on exact same random sequence\n    quicksort(copy, counting_less);\n    const auto quicksort_count{ count };\n    \n    count = 0;                 // Repeat for bubble sort algorithm\n    copy = numbers;\n    bubbleSort(copy, counting_less);\n    const auto bubble_sort_count{ count };\n    \n    // Not requested, but it is interesting (see earlier) \n    // to also compare with the sorting algorithm of the C++ Standard Library \n    count = 0;                 // Repeat once more for std::ranges::sort()  (see Chapter 20)\n    copy = numbers;\n    std::ranges::sort(copy, counting_less);\n    const auto std_sort_count{ count };\n\n    const auto quick_sort_theory = static_cast<unsigned>(size * std::log2(size));\n    const auto bubble_sort_theory = size * size;\n    const auto std_sort_theory = static_cast<unsigned>(size * std::log2(size));\n\n    std::cout \n      << std::format(\n          \"Number of comparisons for {} elements:\\n\"\n          \" - quicksort: {} (n*log(n): {}; ratio: {:.2})\\n\"\n          \" - bubble sort: {} (n*n: {}; ratio: {:.2})\\n\"\n          \" - Standard Library sort: {} (n*log(n): {}; ratio: {:.2})\\n\",\n          size,\n          quicksort_count, quick_sort_theory, static_cast<float>(quick_sort_theory) / quicksort_count,\n          bubble_sort_count, bubble_sort_theory, static_cast<float>(bubble_sort_theory) / bubble_sort_count,\n          std_sort_count, std_sort_theory, static_cast<float>(std_sort_theory) / std_sort_count\n        ) \n     << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_03/Sort.cppm",
    "content": "export module sort;\n\n// The two algorithms that we are comparing:\nexport import sort.quick;\nexport import sort.bubble;\n"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_04/Collect.cppm",
    "content": "export module collect;\n\nimport <vector>;\n\nexport template <typename T, typename Predicate>\nstd::vector<T> collect(const std::vector<T>& values, Predicate predicate)\n{\n  std::vector<T> result;\n  \n  for (auto& value : values)\n    if (predicate(value))\n      result.push_back(value);\n  \n  return result;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_04/Soln19_04.cpp",
    "content": "// Exercise 19-4. \n// Collecting values using higher-order functions, functors, and lambda expressions.\n\n/*\n\tThere are several ways to check for palindromes. \n\tOne of the more elegant solutions probably though is the recursive one shown here.\n\tWhile recursive lambdas are possible, more or less, recursion is far easier with a regular function.\n\n\tNote that to collect upper case letters, there's no need for a lambda either.\n\tJust use a pointer to the std::isupper() function as the callback!\n*/\n\nimport <iostream>;\nimport <format>;\nimport <functional>;\nimport <string>;\nimport <vector>;\n\nimport collect;\n\n#include <cctype>;         // For std::isupper()\n\n// Output vector elements\ntemplate<typename T>\nvoid list(const std::vector<T>& values, size_t width = 5)\n{\n  for (auto value : values)\n    std::cout << std::format(\"{:{}}\", value, width);\n  std::cout << std::endl;\n}\n\nbool is_palindrome(std::string_view s)\n{\n  return s.length() == 0\n    || (s.front() == s.back() && is_palindrome(s.substr(1, s.length() - 2)));\n}\n\nint main()\n{\n  const std::vector numbers{ -2, 4, -5, 6, 10, -40, 56, 4, 67, 45 };\n  std::cout << \"\\nAll numbers:\\n\";\n  list(numbers);\n  \n  int threshold {};\n  std::cout << \"\\nPlease enter a threshold: \";\n  std::cin >> threshold;\n  \n  const auto greater{ collect(numbers, [threshold](int i) { return i > threshold; }) };\n  std::cout << \"Numbers greater than \" << threshold << \":\\n\";\n  list(greater);\n\n  const std::vector letters{ 'C', 'd', 'a', 'z', 't', 'S', 'p', 'm', 'D', 'f' };\n  std::cout << \"\\nAll characters:\\n\";\n  list(letters, 2);\n  //const auto capitals{ collect(letters, std::isupper) };\t// <-- This should but does not work with all compilers\n  const auto capitals{ collect(letters, isupper) };\n  std::cout << \"\\nCapital letters:\\n\";\n  list(capitals, 2);\n\n  const std::vector<std::string> strings{ \"palindrome\", \"racecar\", \"rubarb\", \"noon\", \"kayak\", \"ananas\", \"madam\", \"backwards\" };\n  std::cout << \"\\nAll strings:\\n\";\n  list(strings, 12);\n  const auto palindromes{ collect(strings, is_palindrome) };\n  std::cout << \"\\nPalindromes:\\n\";\n  list(palindromes, 10);\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_05/Box.cppm",
    "content": "export module box;\n\nimport <ostream>;\nimport <format>;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_05/DeliveryTruck.cpp",
    "content": "module delivery_truck;\n\nDeliveryTruck::DeliveryTruck(Truckload aTruckload)\n  : m_truckload{ std::move(aTruckload) }   // Do not copy!\n{}\n\nvoid DeliveryTruck::deliverBox(SharedBox box)\n{\n  m_truckload.removeBox(box);\n  \n  // Notify all interested parties (aka \"observers\") that the Box was delivered\n  for (auto& callback : m_callbacks)\n    callback(box);\n}\n\nvoid DeliveryTruck::registerOnDelivered(Callback callback)\n{\n  m_callbacks.push_back(std::move(callback));   // Do not copy!\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_05/DeliveryTruck.cppm",
    "content": "export module delivery_truck;\nimport truckload;\n\nimport <functional>;      // For std::function<>\nimport <vector>;          // For std::vector<>\n\nexport class DeliveryTruck\n{\npublic:\n  using Callback = std::function<void(SharedBox)>;  // Type alias for the type of the delivery callback functions\n\t\n  DeliveryTruck(Truckload truckload);   // Create a delivery truck (pass-by-value to allow a Truckload to be either copied or moved!)\n  \n  void deliverBox(SharedBox box);\n  \n  void registerOnDelivered(Callback callback);\n  \nprivate:\n  Truckload m_truckload;\n  \n  std::vector<Callback> m_callbacks;\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_05/RandomBoxes.cppm",
    "content": "export module box.random;\n\nimport box;\nimport <random>;        // For random number generation\nimport <functional>;    // For std::bind()\nimport <memory>;        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\nexport Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\nexport auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_05/Soln19_05.cpp",
    "content": "// Exercise 19-5. \n// Using callback functions to implement the so-called observer pattern,\n// where a callback function is called whenever a certain event occurs \n// (in this case: when a Box is delivered).\n\nimport <iostream>;\nimport truckload;\nimport delivery_truck;\nimport box.random;\n\nvoid logDelivary(SharedBox box)\n{\n  std::cout << \"The box \" << *box << \" was delivered. On time, as always!\" << std::endl;\n}\n\nint main()\n{\n  const size_t boxCount {20};               // Number of Box object to be created\n\n  // Create boxCount Box objects\n  Truckload load;\n  for (size_t i {}; i < boxCount; ++i)\n    load.addBox(randomSharedBox());\n\n  DeliveryTruck truck{ load };  // Copy the load, because we still need it below. \n                                // Note that all Boxes are shared, so the they themselves are not copied.\n  \n  // Register two callback functions:\n  truck.registerOnDelivered(logDelivary);\n  \n  unsigned count {};\n  truck.registerOnDelivered([&count](SharedBox) { ++count; });\n  \n  // Deliver some boxes:\n  for (size_t i : { 5u, 8u, 11u })\n    truck.deliverBox(load[i]);\n\n  std::cout << count << \" boxes were delivered. On time, as always!\" << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_05/Truckload.cpp",
    "content": "module truckload;\n\nimport <iostream>;\nimport <stdexcept>;    // For standard exception type std::out_of_range \nimport <string>;       // For std::string and std::to_string()\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\nTruckload& Truckload::operator=(const Truckload& other)\n{\n  if (&other != this)   // Do not forget: avoid issues with self-assignment!\n  {\n    delete m_head;              // Delete all current packages\n    m_head = m_tail = nullptr;  // Reset both pointers\n\n    // Same as copy constructor \n    // (see Chapter 17 for the copy-and-swap idiom that allows you to avoid \n    // duplicating logic like this...)\n    for (Package* package{ other.m_head }; package; package = package->m_next)\n    {\n      addBox(package->m_box);\n    }\n  }\n\n  return *this;\n}\n\n// Destructor: clean up the list\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nSharedBox& Truckload::operator[](size_t index) const\n{\n  size_t count{};             // Package count\n  for (Package* package{ m_head }; package; package = package->m_next)\n  {\n    if (count++ == index)      // Up to index yet?\n      return package->m_box;   // If so return the pointer to Box\n  }\n  throw std::out_of_range{ \"Index too large: \" + std::to_string(index) };\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 19/Soln19_05/Truckload.cppm",
    "content": "export module truckload;\n\nimport box;\n\nimport <memory>;\nimport <vector>;\nimport <ostream>;\n\nexport using SharedBox = std::shared_ptr<Box>;\n\nexport class Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  \n  Truckload(const Truckload& src);  // Copy constructor\n  Truckload& operator=(const Truckload& other);  // Copy assignment operator\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox& operator[](size_t index) const;   // Overloaded subscript operator\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in a module interface file)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Truckload& load);\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_01/Box.cppm",
    "content": "export module box;\n\nimport <ostream>;\nimport <format>;\n\nexport class Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_01/RandomBoxes.cppm",
    "content": "export module box.random;\n\nimport box;\nimport <random>;        // For random number generation\nimport <functional>;    // For std::bind()\nimport <memory>;        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\nexport Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\nexport auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_01/Soln20_01.cpp",
    "content": "// Exercise 20-1 Rework the Truckload class using std::vector<>\nimport <iostream>;\nimport <memory>;\nimport truckload;\nimport box.random;\n\n/*\n  In this solution we preserved the interface of the nested Iterator class.\n  An alternative, of course, would be to define Iterator as an alias \n  for std::vector<Box>::iterator, and introduce begin() and end() members.\n  But then all code using the iterators would have to be updated as well.\n*/\n\nint main()\n{\n  const double dimLimit{ 99.0 };             // Upper limit on Box dimensions\n  Truckload load;\n  const size_t boxCount{ 20 };               // Number of Box object to be created\n\n  // Create boxCount Box objects\n  for (size_t i{}; i < boxCount; ++i)\n    load.addBox(randomSharedBox());\n\n  std::cout << \"The boxes in the Truckload are:\\n\";\n  std::cout << load << std::endl;\n\n  Truckload moveConstructedLoad{ std::move(load) };\n\n  std::cout << \"The boxes in the move constructed Truckload are:\\n\";\n  std::cout << moveConstructedLoad << std::endl;\n\n  Truckload moveAssignedLoad;\n  moveAssignedLoad = std::move(moveConstructedLoad);\n\n  std::cout << \"The boxes in the move assigned Truckload are:\\n\";\n  std::cout << moveAssignedLoad << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_01/Truckload.cpp",
    "content": "module truckload;\n\nimport <iostream>;\nimport <algorithm>;\n\n// Constructor - one Box\nTruckload::Truckload(SharedBox box)\n  : m_boxes{ 1, box }\n{\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(std::vector<SharedBox> boxes)\n  : m_boxes{ std::move(boxes) }\n{\n}\n\n// Swap assignment operator (noexcept)\nvoid Truckload::swap(Truckload& other) noexcept\n{\n  m_boxes.swap(other.m_boxes);\n}\n\n// Optional yet conventional non-member function (forwards to member function)\nvoid swap(Truckload& one, Truckload& other) noexcept\n{\n  one.swap(other);\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_boxes }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_boxes->begin();\n  return m_current != m_boxes->end() ? *m_current : SharedBox{};\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (m_current == m_boxes->end())                // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  ++m_current;                                    // Move to the next package\n\n  return m_current != m_boxes->end() ? *m_current : SharedBox{};\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  m_boxes.push_back(std::move(box));\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  // Unlike the original implementation, \n  // std::erase() removes all occurrences of boxToRemove.\n  // If that is not acceptable, you can use find() as shown below...\n  return std::erase(m_boxes, boxToRemove) > 0;\n\n// Remove only the first occurrence of boxToRemove\n/*\n  if (auto found{ std::ranges::find(m_boxes, boxToRemove) }; found != end(m_boxes))\n  {\n    m_boxes.erase(found);\n    return true;\n  }\n  else\n  {\n    return false;\n  }\n*/\n}\n\nSharedBox& Truckload::operator[](size_t index)\n{\n  // Original implementation performed bounds checking, so use at() instead of []\n  return m_boxes.at(index);\n}\n\nSharedBox Truckload::operator[](size_t index) const\n{\n  // Original implementation performed bounds checking, so use at() instead of []\n  return m_boxes.at(index);\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_01/Truckload.cppm",
    "content": "export module truckload;\n\nimport box;\n\nimport <memory>;\nimport <vector>;\nimport <ostream>;\n\nexport using SharedBox = std::shared_ptr<Box>;\n\nexport class Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(std::vector<SharedBox> boxes);  // Constructor - vector of Boxes (accept by value!)\n\n  void swap(Truckload& other) noexcept;\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox& operator[](size_t index);      // Overloaded subscript operator (can no longer be const!)\n  SharedBox operator[](size_t index) const; // Overloaded subscript operator (new const version returns by value)\n\nprivate:\n  std::vector<SharedBox> m_boxes;\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in a module interface file)\n// Note that this is effectively a const iterator...\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  const std::vector<SharedBox>* m_boxes;            // Pointer to the underlying vector\n  std::vector<SharedBox>::const_iterator m_current; // Iterator pointing to the Box that was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(const std::vector<SharedBox>& boxes) \n    : m_boxes{ &boxes }, m_current{ boxes.end() } {}\n};\n\nexport std::ostream& operator<<(std::ostream& stream, const Truckload& load);\n\n// Optional yet conventional non-member function (forwards to member function)\nexport void swap(Truckload& one, Truckload& other) noexcept;\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_02/Soln20_02.cpp",
    "content": "// Exercise 20-2\n// Replace a custom stack container by the standard stack container adapter\nimport <stack>;\nimport <iostream>;\nimport <string>;\n\n/*\n  Two challenges:\n  - std::stack<>::pop() is a void function. \n    To access the top of the stack, you use std::stack<>::top().\n  - std::stack<const T> is not allowed\n*/\n\nint main()\n{\n  std::string words[]{ \"The\", \"quick\", \"brown\", \"fox\", \"jumps\" };\n  std::stack<std::string> wordStack;              // A stack of strings\n\n  for (const auto& word : words)\n    wordStack.push(word);\n\n  std::stack<std::string> newStack{ wordStack };  // Create a copy of the stack\n\n  // Display the words in reverse order\n  while (!newStack.empty())\n  {\n    std::cout << newStack.top() << ' ';\n    newStack.pop();\n  }\n    \n  std::cout << std::endl;\n\n  // Reverse wordStack onto newStack\n  while (!wordStack.empty())\n  {\n    newStack.push(wordStack.top());\n    wordStack.pop();\n  }\n\n  // Display the words in original order\n  while (!newStack.empty())\n  {\n    std::cout << newStack.top() << ' ';\n    newStack.pop();\n  }\n    \n  std::cout << std::endl;\n\n  std::cout << std::endl << \"Enter a line of text:\" << std::endl;\n  std::string text;\n  std::getline(std::cin, text);    // Read a line into the string object\n\n  std::stack<char> characters;     // A stack for characters\n\n  for (size_t i{}; i < text.length(); ++i)\n    characters.push(text[i]);      // Push the string characters onto the stack\n\n  std::cout << std::endl;\n  while (!characters.empty())\n  {\n    std::cout << characters.top(); // Pop the characters off the stack\n    characters.pop();\n  }\n\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_03/Soln20_03.cpp",
    "content": "// Exercise 20-3 Replacing custom container types with standard ones\n/*\n\tThe following replacements were made compared to Soln17_06.cpp:\n\t\t- LinkedList<T> --> std::vector<T> (not std::list<>, because vector<> should\n\t\t\tbe your go-to container; there's rarely a good reason to use linked lists)\n\t\t- SparseArray<T> --> std::map<char, T> (no need to use a size_t as the key!)\n\t\n  Notice how much more elegant inserting and retrieving values from the map is.\n  All loops at the end of the solution can now also be replaced with elegant range-based for loops.\n\n  At the bottom, there's two alternative loops: one close to the original one,\n  and one even more elegant one that takes advantage of the fact that the keys \n  in the map are already sorted.\n\n\tSoln20_03A contains alternative solutions based on std::multimap<>\n*/\nimport <vector>;\nimport <map>;\nimport <string>;\nimport <iostream>;\nimport <utility>;\n\n#include <cctype>\n\nint main()\n{\n  std::string text;                                // Stores input prose or poem\n  std::cout << \"Enter a poem or prose over one or more lines.\\n\"\n            << \"Terminate the input with #:\\n\";\n  getline(std::cin, text, '#');\n\n  std::map<char, std::vector<std::string>> lists;\n  \n  // Extract words and store in the appropriate list\n  const std::string_view separators {\" \\n\\t,.\\\"?!;:\"}; // Separators between words\n  size_t start {};                                 // Start of a word\n  size_t end {};                                   // separator position after a word\n  while (std::string::npos != (start = text.find_first_not_of(separators, start)))\n  {\n    end = text.find_first_of(separators, start+1);\n    const auto word{ text.substr(start, end - start) };\n    const auto letter{ static_cast<char>(std::toupper(word[0])) };\n    lists[letter].push_back(word);\n    start = end;\n  }\n\n  // List the words in order 5 to a line\n  const size_t perline {5};\n  \n  /* Option 1: use a loop similar to the original one */\n  const std::string_view letters{ \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" };\n  for (char letter : letters)\n  {\n    if (!lists.contains(letter))\n      continue;\n  \n    size_t count {};                               // Word counter\n    for (const auto& word : lists[letter])\n    {\n      if (count++ % perline == 0 && count != 1)\n        std::cout << std::endl;\n      std::cout << word << ' ';\n    }\n    std::cout << std::endl;\n  }\n\n  std::cout << std::endl;\n\n  /* Option 2: take advantage of the fact that the keys are already sorted in the map */\n  for (const auto& [letter, list] : lists)\n  {\n    size_t count{};                               // Word counter\n    for (const auto& word : list)\n    {\n      if (count++ % perline == 0 && count != 1)\n        std::cout << std::endl;\n      std::cout << word << ' ';\n    }\n    std::cout << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_03A/Soln20_03A.cpp",
    "content": "// Exercise 20-3 Replacing custom container types with standard ones\n/*\n\tThe following replacements were made compared to Soln17_06.cpp:\n\t\t- SparseArray<LinkedList<T>> --> std::multimap<size_t, T>\n\t\n\tThis means that compared to Soln20_03, we replaced std::map<Key, std::vector<Value>>\n\twith the more compact (and efficient) std::multimap<Key, Value>. \n  This data structure was less discussed in the main text (as it is less used in practice), \n  but is actually more appropriate here.\n\n  At the bottom, there's two alternative loops: one close to the original one,\n  and one that takes advantage of the fact that the keys in the multimap are sorted.\n*/\nimport <vector>;\nimport <map>;\nimport <string>;\nimport <iostream>;\nimport <utility>;\n\n#include <cctype>\n\nint main()\n{\n  std::string text;                                // Stores input prose or poem\n  std::cout << \"Enter a poem or prose over one or more lines.\\n\"\n    << \"Terminate the input with #:\\n\";\n  getline(std::cin, text, '#');\n\n  std::multimap<char, std::string> words;\n  const std::string_view letters{ \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" };\n\n  // Extract words and store in the appropriate list\n  // A list in the SparseArray is selected by the index in letters of the first letter in a word.\n  const std::string_view separators{ \" \\n\\t,.\\\"?!;:\" }; // Separators between words\n  size_t start{};                                 // Start of a word\n  size_t end{};                                   // separator position after a word\n  while (std::string::npos != (start = text.find_first_not_of(separators, start)))\n  {\n    end = text.find_first_of(separators, start + 1);\n    const auto word{ text.substr(start, end - start) };\n    const auto letter{ static_cast<char>(std::toupper(word[0])) };\n    words.insert({ letter, word });\n    start = end;\n  }\n\n  // List the words in order 5 to a line\n  const size_t perline{ 5 };\n\n  /* Option 1: use a loop similar to the original one */\n  for (char letter : letters)\n  {\n    if (!words.contains(letter))\n      continue;\n\n    size_t count{};                               // Word counter\n    // Retrieve the range of all words that begin with letter\n    const auto [begin, end] { words.equal_range(letter) };\n    for (auto iter{ begin }; iter != end; ++iter)\n    {\n      if (count++ % perline == 0 && count != 1)\n        std::cout << std::endl;\n      std::cout << iter->second << ' ';\n      \n    }\n    std::cout << std::endl;\n  }\n\n  std::cout << std::endl;\n\n  /* Option 2: take advantage of the fact that the keys are already sorted in the multimap */\n  size_t count{};          // Word counter\n  char previous_letter{};\n  for (const auto& [letter, word] : words)\n  {\n    // Add extra enter after each new letter (but not the first time)\n    if (count && letter != previous_letter)\n    {\n      std::cout << std::endl;\n      count = 0;\n    }\n\n    if (count++ % perline == 0 && count != 1)\n      std::cout << std::endl;\n    std::cout << word << ' ';\n\n    previous_letter = letter;\n  }\n\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_04/Soln20_04.cpp",
    "content": "// Removing all elements that satisfy a certain condition using std::partition() / stable_partition().\n\n/*\n  Notes:\n   - Normally one would use std::remove() (as this is slightly faster and more to the point),\n     though std::partition() can be used for this as well.\n   - You may notice that std::partition() reorders the elements that it keeps.\n     It is implementation-defined whether this partition() preserves the original order or not.\n     If you want to make sure the original order of the numbers is preserved,\n     you need to use std::stable_partition()\n*/\nimport <vector>;\nimport <string_view>;\nimport <iostream>;\nimport <algorithm>;\n\nstd::vector<int> fillVector_1toN(size_t N);  // Fill a vector with 1, 2, ..., N\nvoid printVector(std::string_view message, const std::vector<int>& numbers);\n\nvoid removeEvenNumbers(std::vector<int>& numbers)\n{\n  const auto first_even_number\n    { std::stable_partition(begin(numbers), end(numbers), [](auto num) { return num % 2 == 1; }) };\n  /*       ^^^^^^^^^^^^^^^^ if you use partition(), the order of the odd elements may become scrambled */ \n  \n  numbers.erase(first_even_number, end(numbers));\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ fillVector_1toN(num_numbers) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  removeEvenNumbers(numbers);\n\n  printVector(\"The numbers that were kept\", numbers);\n}\n\nstd::vector<int> fillVector_1toN(size_t N)\n{\n  std::vector<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.push_back(i);\n  return numbers;\n}\n\nvoid printVector(std::string_view message, const std::vector<int>& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_05/Soln20_05.cpp",
    "content": "// Exercise 20-5 Create a generic average() algorithm using std::accumulate()\nimport <iostream>;\nimport <numeric>;\nimport <utility>;     // for std::pair<> (only required for Solution 2 below)\nimport <optional>;\nimport <vector>;\n\n// Solution 1: simply use accumulate to sum, and determine the count using std::distance() \n// (the latter is more general than using iterator arithmetic, end - begin, \n// which only works for random-access iterators)\ntemplate <typename T, typename IterType>\nstd::optional<T> average(IterType begin, IterType end)\n{\n\tconst auto count{ std::distance(begin, end) };\n\tconst auto sum{ std::accumulate(begin, end, T{}) };\n\n\treturn count ? std::optional<T>{ sum / count } : std::nullopt;\n}\n\n// Solution 2: accumulate a pair<> that counts both the number of elements and the sum\n//template <typename T, typename IterType>\n//std::optional<T> average(IterType begin, IterType end)\n//{\n//  const auto accumulated { \n//    std::accumulate(begin, end, std::make_pair(0u, T{}), [](const auto& accumulated, const auto& element)\n//    { \n//      return std::make_pair(accumulated.first + 1, accumulated.second + element); \n//    })\n//\t};\n//\n//  return accumulated.first ? std::optional<T>{ accumulated.second / accumulated.first } : std::nullopt;\n//}\n\n\nint main()\n{\n  std::vector<double> numbers{ 1, 2, 4, 8, 16, 32, 64, 128, 256 };\n  std::cout << *average<double>(begin(numbers), end(numbers)) << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_06/Soln20_06.cpp",
    "content": "// Removing all elements that satisfy a certain condition \n// while iterating over a container\nimport <vector>;\nimport <string_view>;\nimport <iostream>;\nimport <algorithm>;   // for std::remove_if()\nimport <numeric>;     // for std::iota()\n\n/*\n  Note: std::ranges::iota() does not exist. No doubt because \n  the <ranges> module defines a std::ranges::views::iota range factory.\n  Maybe you can alter this solution to use that view instead to fill the vector?\n  (Note: in the next exercise you are asked to not use a vector at all,\n   but operate directly with views...)\n*/\n\nstd::vector<int> fillVector_1toN(size_t N);       // Fill a vector with 1, 2, ..., N\nvoid printVector(std::string_view message, const std::vector<int>& numbers);\n\ntemplate <typename Auto>\nvoid removeEvenNumbers(Auto& numbers)    /* Using more elegant std::erase_if() */\n{\n  std::erase_if(numbers, [](auto number) { return number % 2 == 0; });\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ fillVector_1toN(num_numbers) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  removeEvenNumbers(numbers);\n\n  printVector(\"The numbers that were kept\", numbers);\n}\n\nstd::vector<int> fillVector_1toN(size_t N)\n{\n  std::vector<int> numbers(N);\n  std::iota(begin(numbers), end(numbers), 1);\n  return numbers;\n}\n\nvoid printVector(std::string_view message, const std::vector<int>& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_07/Soln20_07.cpp",
    "content": "// Removing all elements that satisfy a certain condition \n// while iterating over a container\nimport <vector>;\nimport <string_view>;\nimport <iostream>;\nimport <ranges>;\n\nusing namespace std::ranges::views;\n\ntemplate <typename Auto>\nvoid printVector(std::string_view message, Auto& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ iota(1, 20) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  auto odd_numbers{ numbers | filter([](int i) { return i % 2 != 0; }) };\n\n  printVector(\"The numbers that were kept\", odd_numbers);\n}\n\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_08/Soln20_08.cpp",
    "content": "// Exercise 20-8 Apply remove-erase idiom to remove duplicate elements\nimport <iostream>;\nimport <random>;     // For random number generation\nimport <functional>; // For std::bind() and std::ref()\nimport <algorithm>;\nimport <vector>;\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main()\n{\n  const size_t num_numbers{ 25'000 };\n  std::vector<int> numbers(num_numbers);\n\n  // Why not use an algorithm as well to generate the random numbers!!\n  // (Note: technically generate() is allowed to copy a function object \n  //  as often as it wants. std::ref() ensures that the algorithm \n  //  at all times operates on a reference to our random-number generator)\n  auto generator{ createUniformPseudoRandomNumberGenerator(0, 10'000) };\n  std::ranges::generate(numbers, std::ref(generator));\n\n  // Algorithm number two\n  std::ranges::sort(numbers);\n\n  // And number three; this time combined with the remove-erase idiom (or unique-erase, if you will)\n  /* Option 1: iterator-based */\n  numbers.erase(std::unique(begin(numbers), end(numbers)), end(numbers));\n  /* Option 2: range-based (sadly requires two statements...) */\n  //const auto [to_erase_begin, to_erase_end] { std::ranges::unique(numbers) };\n  //numbers.erase(to_erase_begin, to_erase_end);\n\n  std::cout << \"Number of unique numbers: \" << numbers.size() << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_09/Soln20_09.cpp",
    "content": "// Exercise 20-9 Parallel version of 20-8\nimport <iostream>;\nimport <random>;     // For random number generation\nimport <functional>; // For std::bind() and std::ref()\nimport <algorithm>;\nimport <vector>;\nimport <execution>;\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main()\n{\n  const size_t num_numbers{ 25'000 };\n  std::vector<int> numbers(num_numbers);\n\n  /* Caution: a pseudo-random number generator cannot safely be accessed concurrently! */\n  auto generator{ createUniformPseudoRandomNumberGenerator(0, 10'000) };\n  std::ranges::generate(numbers, std::ref(generator));\n\n  // Algorithm number two\n  std::sort(std::execution::par, begin(numbers), end(numbers));\n\n  // And number three; this time combined with the remove-erase idiom (or unique-erase, if you will)\n  numbers.erase(std::unique(std::execution::par, begin(numbers), end(numbers)), end(numbers));\n\n  std::cout << \"Number of unique numbers: \" << numbers.size() << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_10/Soln20_10.cpp",
    "content": "// Exercise 20-10: exercising projection with range-based algorithms\nimport <iostream>;\nimport <string>;\nimport <vector>;\nimport <algorithm>;\n\nint main()\n{\n  std::vector<std::string> names{\"Frodo Baggins\", \"Gandalf the Gray\", \n    \"Aragon\", \"Samwise Gamgee\", \"Peregrin Took\", \"Meriadoc Brandybuck\", \n    \"Gimli\", \"Legolas Greenleaf\", \"Boromir\"};\n\n  // Sort the names lexicographically\n  std::ranges::sort(names);\n  std::cout << \"Names sorted lexicographically:\" << std::endl;\n  for (const auto& name : names) std::cout << name << \", \";\n  std::cout << std::endl << std::endl;  \n\n  // Sort the names by length\n  /* Option 1: projection using member function pointer */\n  std::ranges::sort(names, std::less<>{}, &std::string::length);\n  /* Option 2: projection using lambda expression */\n//  std::ranges::sort(names, std::less<>{}, [](const auto& name) { return name.length(); });\n  std::cout << \"Names sorted by length:\" << std::endl;\n  for (const auto& name : names) std::cout << name << \", \";\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_11/Soln20_11.cpp",
    "content": "// Exercise 20-11: exercising range factories and range adaptors\nimport <iostream>;\nimport <algorithm>;\nimport <ranges>;\n#include <cmath>\n\nusing namespace std::ranges::views;\n\nbool isPrime(unsigned number)   \n{\n  // Of course we use an algorithm and a range factory here as well!\n  // Caution: mind the corner cases where number is 0, 1, or 2!\n  return number >= 2 \n    && std::ranges::none_of(\n          iota(2u, static_cast<unsigned>(std::sqrt(number) + 1)),\n          [number](unsigned divisor) { return number % divisor == 0; }\n       );\n}\n\nint main()\n{\n  const unsigned num_primes{ 100 };\n  const unsigned per_line{ 10 };\n\n  unsigned count{};\n  for (auto prime : iota(2) | filter(&isPrime) | take(num_primes) | reverse)\n  {\n    std::cout << prime << ' ';\n    if (++count % per_line == 0)\n      std::cout << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_12/Soln20_12.cpp",
    "content": "// Exercise 20-12: exercising new range adaptors\nimport <iostream>;\nimport <algorithm>;\nimport <ranges>;\n#include <cmath>\n\nusing namespace std::ranges::views;\n\nbool isPrime(unsigned number)   \n{\n  // Of course we use an algorithm and a range factory here as well!\n  // Caution: mind the corner cases where number is 0, 1, or 2!\n  return number >= 2 \n    && std::ranges::none_of(\n          iota(2u, static_cast<unsigned>(std::sqrt(number) + 1)),\n          [number](unsigned divisor) { return number % divisor == 0; }\n       );\n}\n\nint main()\n{\n  const unsigned max{ 1'000 };\n  const unsigned per_line{ 10 };\n\n  // As you no doubt deduced, drop_while() is not really applicable here,\n  // but take_while() fits nicely!\n  unsigned count{};\n  for (auto prime : iota(2u) \n        | filter(&isPrime) \n        | take_while([max](unsigned prime) { return prime < max; }) \n        | reverse)\n  {\n    std::cout << prime << ' ';\n    if (++count % per_line == 0)\n      std::cout << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_13/Soln20_13.cpp",
    "content": "// Exercise 20-13: more fun with algorithms and ranges\nimport <iostream>;\nimport <format>;\nimport <map>;\nimport <string>;\nimport <string_view>;\nimport <vector>;\nimport <algorithm>;\nimport <ranges>;\n\nusing namespace std::ranges::views;\n\n// Type aliases\nusing Words = std::vector<std::string_view>;\nusing WordCounts = std::map<std::string_view, size_t>;\n\n// Function prototypes\nWords extractWords(std::string_view text, std::string_view separators = \" ,.!?\\\"\\n\");\nWordCounts countWords(const Words& words);\nvoid showWordCounts(const WordCounts& wordCounts);\n\n/*\n  Below we list a number of possible solutions.\n  We're sure there are plenty more variations possible...\n */\n\nsize_t maxWordLength(const WordCounts& wordCounts)\n{\n  // Filter out words that occur only once + transform to word lengths using lambda expression\n  auto frequentWordLengths {\n    wordCounts\n      | filter([](const auto wordCount) { return wordCount.second >= 2; })\n      | transform([](const auto wordCount) { return wordCount.first.length(); })\n  };\n\n  return std::ranges::empty(frequentWordLengths) ? 0 : *std::ranges::max_element(frequentWordLengths);\n}\n\nsize_t maxWordLength_1(const WordCounts& wordCounts)\n{\n  // Filter out words that occur only once, transform twice in a row with member pointers.\n  auto frequentWordLengths {\n    wordCounts\n      | filter([](const auto wordCount) { return wordCount.second >= 2; })\n      | transform(&WordCounts::value_type::first)  // Or, without alias: transform(&std::pair<const std::string_view, size_t>::first)\n      | transform(&std::string_view::length)\n  };\n\n  return std::ranges::empty(frequentWordLengths) ? 0 : *std::ranges::max_element(frequentWordLengths);\n}\n\nsize_t maxWordLength_2(const WordCounts& wordCounts)\n{\n  // Filter out words that occur only once, transform to words, project to lengths.\n  auto frequentWords {\n    wordCounts\n      | filter([](const auto wordCount) { return wordCount.second >= 2; })\n      | transform([](const auto wordCount) { return wordCount.first; })\n  };\n\n  return std::ranges::empty(frequentWords) \n    ? 0 \n    : (*std::ranges::max_element(frequentWords, std::less<>{}, &std::string_view::length)).length();\n}\n\nsize_t maxWordLength_3(const WordCounts& wordCounts)\n{\n  // Filter out words that occur only once\n  auto frequentWordCounts \n    { wordCounts | filter([](const auto wordCount) { return wordCount.second >= 2; }) };\n  \n  // Project to obtain the words (the first element of the pairs in the map), \n  // and compare their lengths using a lambda expression\n  return std::ranges::empty(frequentWordCounts) \n    ? 0 \n    : std::ranges::max_element(\n        frequentWordCounts,\n        [](auto word1, auto word2) { return word1.length() < word2.length(); },\n        &WordCounts::value_type::first  // Or, without alias: std::pair<const std::string_view, size_t>::first\n      )->first.size();\n}\n\n\nint main()\n{\n  std::string text;    // The string to count words in\n\n  // Read a string from the keyboard\n  std::cout << \"Enter a string terminated by *:\" << std::endl;\n  getline(std::cin, text, '*');\n\n  const Words words{ extractWords(text) };\n  if (words.empty())\n  {\n    std::cout << \"No words in text.\" << std::endl;\n    return 0;\n  }\n\n  const WordCounts wordCounts{ countWords(words) };\n  showWordCounts(wordCounts);\n}\n\nWords extractWords(std::string_view text, std::string_view separators)\n{\n  Words words;\n  size_t start{ text.find_first_not_of(separators) };    // Start 1st word\n  size_t end{};                                          // Index for the end of a word\n                                                         \n  while (start != std::string_view::npos)                \n  {                                                      \n    end = text.find_first_of(separators, start + 1);     // Find end separator\n    if (end == std::string_view::npos)                   // End of text?\n      end = text.length();                               // Yes, so set to last+1\n    words.push_back(text.substr(start, end - start));    \n    start = text.find_first_not_of(separators, end + 1); // Find next word\n  }\n\n  return words;\n}\n\nWordCounts countWords(const Words& words)\n{\n  WordCounts result;\n  for (auto& word : words)\n    ++result[word];\n  return result;\n}\n\nvoid showWordCounts(const WordCounts& wordCounts)\n{\n  const size_t field_width{ maxWordLength(wordCounts) + 1};\n  const size_t words_per_line{5};\n\n  size_t words_in_line{};      // Number of words in the current line\n  char previous_initial{};\n  for (const auto& [word, count] : wordCounts)\n  {\n    if (count < 2) continue;   // Skip words that appear only once\n\n    // Output newline when initial letter changes or after 5 per line\n    if ( (previous_initial && word[0] != previous_initial)\n          || words_in_line++ == words_per_line)\n    {\n      words_in_line = 0;\n      std::cout << std::endl;\n    }\n    // Output \"word (count)\", where word has a dynamic field width\n    std::cout << std::format(\"{:>{}} ({:2})\", word, field_width, count); \n    previous_initial = word[0];\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 20/Soln20_14/Soln20_14.cpp",
    "content": "// Exercise 20-14: the hard nut\nimport <iostream>;\nimport <algorithm>;\nimport <ranges>;\nimport <iterator>;\n#include <cmath>\n\nusing namespace std::ranges::views;\n\nbool isPrime(unsigned number)\n{\n  return number >= 2 \n      && std::ranges::none_of(\n           iota(2u, static_cast<unsigned>(std::sqrt(number) + 1)),\n           [number](unsigned divisor) { return number % divisor == 0; }\n         );\n}\n\nint main()\n{\n  // This first version is one that compiled (with some help) on at least one compiler.\n  // It uses one thing you have not encountered yet: std::ranges::views::common.\n  // This range adaptor transforms a given range into a view where begin() and end()\n  // return values of the same type, something which in general is not true for ranges. \n  // Legacy algorithms, such as the iterator-pair-based std::copy() algorithm, \n  // often expect iterator pairs to have the same type, though.\n  auto view { \n    std::ranges::istream_view<int>(std::cin)\n      | take_while([](int i) { return i >= 0; })\n      | transform([](int i) { return static_cast<unsigned>(i); })\n      | filter(isPrime)\n      | transform([](unsigned i) { return \"Yes, that is a prime!\"; })\n      | common \n  };\n\n  std::copy(view.begin(), view.end(), std::ostream_iterator<std::string>(std::cout, \"\\n\"));\n\n/*\n  // Same as the previous one, but then without the legacy iterator-pair-based copy()\n  // (and thus without the common range adaptor).\n  // At the time we tried this, this did not compile yet in any compiler.\n  auto view {\n    std::ranges::istream_view<int>(std::cin)\n      | take_while([](int i) { return i >= 0; })\n      | transform([](int i) { return static_cast<unsigned>(i); })\n      | filter(isPrime)\n      | transform([](unsigned i) { return \"Yes, that is a prime!\"; })\n  };\n\n  std::ranges::copy(view, std::ostream_iterator<std::string>(std::cout, \"\\n\"));\n*/\n\n/*\n  // A variation that uses std::ranges::for_each(). \n  // But, like the exercise says, this is cheating though, \n  // as for_each() is just a poorly disguised range-based for loop,\n  // and loops were not allowed!\n  std::ranges::for_each(\n    std::ranges::istream_view<int>(std::cin)\n      | take_while([](int i) { return i >= 0; })\n      | transform([](int i) { return static_cast<unsigned>(i); })\n      | filter(isPrime)\n      | transform([](unsigned i) { return \"Yes, that is a prime!\"; })\n    , [](const auto& s) { std::cout << s << std::endl; }\n  );\n*/\n\n/*\n  // A \"clever\" version where we print during a filter step\n  auto view {\n    std::ranges::istream_view<int>(std::cin)\n      | take_while([](int i) { return i >= 0; })\n      | transform([](int i) { return static_cast<unsigned>(i); })\n      | filter(isPrime)\n      | filter([](unsigned i) { std::cout << \"Yes, that is a prime!\\n\"; return false; })\n  };\n  view.begin(); // Try to find the begin of the view\n                // Since the last step filters out all elements, though,\n                // this will never find a begin, and eventually return view.end()...\n*/\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 21/Soln21_01/Soln21_01.cpp",
    "content": "// Exercise 21-1  Understanding compound and simple requirements\nimport <concepts>;    // For the std::same_as<> and std::convertible_to<> concepts\nimport <ranges>;      // For std::ranges::range<> concept\nimport <type_traits>; // For the std::remove_cv<> type trait\nimport <list>;\nimport <vector>;\nimport <string>;\n\ntemplate <typename Iter>\nconcept BidirectionalIterator = true; // Feel free to further work out all requirements...\n\n// A compound requirement \"{ expr } -> concept<Args>;\" is equivalent to \n// the simple requirement \"expr;\", \n// combined with the nested requirement \"requires concept<decltype(expr),Args>;\"\ntemplate<class Iter>\nconcept RandomAccessIterator = BidirectionalIterator<Iter>\n  && requires(const Iter i, const Iter j, Iter k, const int n)\n     {\n       { i - n }; { i + n }; { n + i };\n       requires std::same_as<decltype(i - n), Iter>;\n       requires std::same_as<decltype(i + n), Iter>;\n       requires std::same_as<decltype(n + i), Iter>;\n       { k += n }; { k -= n };\n       requires std::same_as<decltype(k += n), Iter&>;\n       requires std::same_as<decltype(k -= n), Iter&>;\n       i[n];\n       requires std::same_as<decltype(i[n]), decltype(*i)>;\n       i < j; i > j; i <= j; i >= j;\n       requires std::convertible_to<decltype(i < j), bool>\n             && std::convertible_to<decltype(i > j), bool>\n             && std::convertible_to<decltype(i <= j), bool>\n             && std::convertible_to<decltype(i >= j), bool>;\n     };\n\n// To rewrite a compound requirement with noexcept you should know \n// that noexcept(expr) is a valid constant expression as well...\ntemplate <typename T>\nconcept NoExceptDestructible = requires (T& value) \n{ \n  value.~T();\n  noexcept(value.~T());\n};\n\ntemplate <typename C>\nconcept Character = std::same_as<std::remove_cv_t<C>, char>\n                  || std::same_as<std::remove_cv_t<C>, char8_t>\n                  || std::same_as<std::remove_cv_t<C>, char16_t>\n                  || std::same_as<std::remove_cv_t<C>, char32_t>\n                  || std::same_as<std::remove_cv_t<C>, wchar_t>;\n\n// More of the same...\ntemplate <typename S>\nconcept String = std::ranges::range<S> && requires(S & s, const S & cs)\n{\n  typename S::value_type;\n  requires Character<typename S::value_type>;\n  cs.length();\n  requires std::integral<decltype(cs.length())>;\n  s[0]; cs[0];\n  requires std::same_as<decltype(s[0]), typename S::value_type&>\n        && std::convertible_to<decltype(cs[0]), typename S::value_type>;\n  s.data(); cs.data();\n  requires std::same_as<decltype(s.data()), typename S::value_type*>\n        && std::same_as<decltype(cs.data()), const typename S::value_type*>;\n  // ...\n};\n\nstatic_assert(NoExceptDestructible<std::string>);\nstatic_assert(NoExceptDestructible<int>);\nstatic_assert(String<std::string>);\nstatic_assert(!String<std::vector<char>>);\nstatic_assert(Character<char>);\nstatic_assert(Character<const char>);\nstatic_assert(RandomAccessIterator<std::vector<int>::iterator>);\nstatic_assert(!RandomAccessIterator<std::list<int>::iterator>);\nstatic_assert(RandomAccessIterator<int*>);\n\nint main()\n{\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 21/Soln21_02/Soln21_02.cpp",
    "content": "// Exercise 21-2  Writing a proper, modern algorithm is hard...\n// It involves adding support for projection, member pointers,\n// and iterator pairs where the end iterator (or, sentinel) \n// is of a different type than the begin iterator,\n// all with proper type constraints.\nimport <iostream>;\nimport <concepts>;    // Standard concepts\nimport <ranges>;      // Range factories and adaptors\nimport <functional>;  // For the std::identity and std::ranges::less functor classes, and std::invoke()\nimport <iterator>;    // Iterator-based concepts, std::sentinel_for, and std::projected\nimport <vector>;\n\nusing namespace std::ranges::views;\n\n// The original function template which requires begin and end to be of the same type\n// Similar to the original iterator-pair based algorithms of <algorithm>,\n// only with type constraints.\ntemplate <std::forward_iterator Iterator,\n          std::indirect_strict_weak_order<Iterator> Comparison>\nIterator original_find_optimum(Iterator begin, Iterator end, Comparison compare)\n{\n  if (begin == end) return end;\n\n  Iterator optimum{ begin };\n  for (auto iter{ ++begin }; iter != end; ++iter)\n  {\n    if (compare(*iter, *optimum)) optimum = iter;\n  }\n  return optimum;\n}\n\n// Our improved function template supporting projection and differently-typed sentinels.\n// Appropriate default values were added as well.\ntemplate <std::forward_iterator Iterator,\n          std::sentinel_for<Iterator> Sentinel, \n          typename Projection = std::identity,\n          std::indirect_strict_weak_order<std::projected<Iterator, Projection>> Comparison = std::ranges::less>\nIterator find_optimum(Iterator begin, Sentinel end, Comparison compare = {}, Projection projection = {})\n{\n  if (begin == end) return begin; // Do not return end as before...\n\n  Iterator optimum{ begin };\n  for (auto iter{ ++begin }; iter != end; ++iter)\n  {\n    // Note 1: std::invoke() is required to support comparison and projection through member pointers \n    // Note 2: this re-invokes projection(*optimum) for each comparison, same as std::max_element()\n    if (std::invoke(compare, std::invoke(projection, *iter), std::invoke(projection, *optimum)))\n      optimum = iter;\n  }\n  return optimum;\n}\n\n/* A simple Box class to exercise our member-based comparison and projection facilities.\n  It lacks an operator<(), so with classical algorithms you'd need lambdas to compare these Boxes...\n */\nclass Box\n{\npublic:\n  Box() : Box{ 1, 1, 1 } {};\n  Box(double length, double width, double height)\n    : m_length{ length }, m_width{ width }, m_height{ height }\n  {}\n   \n  double volume() const { return m_length * m_width * m_height; }\n  double isSmallerThan(const Box& other) const { return volume() < other.volume(); }\n\nprivate:\n  double m_length, m_width, m_height;\n};\n\nint main()\n{\n  std::vector<Box> boxes{ {2.0, 2.0, 3.0}, {1.0, 3.0, 2.0}, {1.0, 2.0, 1.0}, {2.0, 3.0, 3.0} };\n\n  // Step 1: create a view where begin() and end() are different.\n  // The result of the take_while() range adapter has this property\n  // (or, at least, it should have as per its specification in the Standard).\n  auto first_boxes{ boxes | take_while([](const Box& box) { return box.volume() < 15; }) };\n  \n  /* This therefore generally does not compile... */\n  //std::cout << \"Volume of smallest box: \" \n  //  << original_find_optimum(first_boxes.begin(), first_boxes.end(),\n  //        [](const Box& box1, const Box& box2) { return box1.isSmallerThan(box2); })->volume()\n  //  << std::endl;\n\n  // Side-note: you can use the std::ranges::views::common to turn a range\n  // where begin and end have a different type into a view where they do.\n  auto common_boxes{ first_boxes | common };\n  std::cout << \"Volume of smallest box: \" \n    << original_find_optimum(common_boxes.begin(), common_boxes.end(),\n          [](const Box& box1, const Box& box2) { return box1.isSmallerThan(box2); })->volume()\n    << std::endl;\n  \n  // Step 2: Show off our shiny new, modernised version of find_optimum()\n  // First off: no need for the common adapter!\n  std::cout << \"Volume of largest box: \"\n    << find_optimum(first_boxes.begin(), first_boxes.end(),\n          [](const Box& box1, const Box& box2) { return !box1.isSmallerThan(box2); })->volume()\n    << std::endl;\n\n  // Other cool features of our modern find_optimum() version include projection \n  // and the support for member function pointers. So no more lambdas required here!\n\n  // Use a member-function pointer for the comparison function\n  std::cout << \"Volume of smallest box: \" \n    << find_optimum(first_boxes.begin(), first_boxes.end(), &Box::isSmallerThan)->volume() \n    << std::endl;\n\n  // Use a member-function pointer for the new projection functionality\n  std::cout << \"Volume of largest box: \" \n    << find_optimum(first_boxes.begin(), first_boxes.end(), std::greater<>{}, &Box::volume)->volume()\n    << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 21/Soln21_03/Soln21_03.cpp",
    "content": "// Exercise 21-3 \nimport <iostream>;\nimport <concepts>;\nimport <span>;\nimport <array>;\nimport <string>;\n\n/* Not requested, but just for fun, here is a concept that prescribes \n   a complete set of operations one would require to take an average */\ntemplate <typename T>\nconcept Averagable = requires (const T x, const T y, T z, const int i)\n{\n  { x + y }  -> std::same_as<T>;\n  { x - y }  -> std::same_as<T>;\n  { z += y } -> std::same_as<T&>;\n  { z -= y } -> std::same_as<T&>;\n  { x / i }  -> std::same_as<T>;\n  { x * i }  -> std::same_as<T>;\n  { z /= i } -> std::same_as<T&>;\n  { z *= i } -> std::same_as<T&>;\n};\n\n// By default, take the N / 2'th element\n// (Note: this template covers both the case if T would not be Averageble,\n//  and the case where N % 2 == 1).\ntemplate <typename T, size_t N>\nauto& medianOfSorted(std::span<T, N> span)\n{\n  static_assert(N != 0, \"The median of an empty span is not defined\");\n  return span[N / 2];\n}\n\ntemplate <Averagable T, size_t N> requires (N % 2 == 0)\nauto medianOfSorted(std::span<T, N> span)\n{\n  static_assert(N != 0, \"The median of an empty span is not defined\");\n  return (span[N / 2 - 1] + span[N / 2]) / 2;\n}\n\nint main()\n{\n  std::array values_odd{ 1, 2, 3, 4, 5, 6, 7 };\n  std::cout << medianOfSorted(std::span{ values_odd }) << std::endl;\n\n  std::array values_even{ 1., 2., 3., 4., 5., 6. };\n  std::cout << medianOfSorted(std::span{ values_even }) << std::endl;\n\n  std::string strings_odd[] { \"1\", \"2\", \"3\", \"4\", \"5\" };\n  std::cout << medianOfSorted(std::span{ strings_odd }) << std::endl;\n\n  std::string strings_even[] { \"1\", \"2\", \"3\", \"4\", \"5\", \"6\" };\n  std::cout << medianOfSorted(std::span{ strings_even }) << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 21/Soln21_04/Soln21_04.cpp",
    "content": "// Exercise 21-4  Generalising medianOfSorted()\nimport <iostream>;\nimport <concepts>;\nimport <array>;\nimport <string>;\nimport <vector>;\nimport <list>;\nimport <forward_list>;\nimport <span>;\nimport <ranges>;\nimport <iterator>;\n\n/*\n  Apologies. When we wrote the exercise, we misread what a std::sized_range() was.\n  std::sized_range() is no concept for statically fixed-size ranges, \n  but for ranges for which std::ranges::size() may be invoked *at runtime*.\n  So this solution presents the next best thing: a medianOfSorted() that works\n  for any range (not just fixed-size ranges), with appropriate type constraints.\n  Key point is that underlying, range-based algorithms still very much work with iterators.\n  Most requirements use Standard Library concepts in the std::ranges namespace,\n  and the function implementations use Standard Library functions in that same namespace.\n */\n\n/* Not requested, but just for fun, here is a concept that prescribes \n   a complete set of operations one would require to take an average */\ntemplate <typename T>\nconcept Averagable = requires (const T x, const T y, T z, const int i)\n{\n  { x + y }  -> std::same_as<T>;\n  { x - y }  -> std::same_as<T>;\n  { z += y } -> std::same_as<T&>;\n  { z -= y } -> std::same_as<T&>;\n  { x / i }  -> std::same_as<T>;\n  { x * i }  -> std::same_as<T>;\n  { z /= i } -> std::same_as<T&>;\n  { z *= i } -> std::same_as<T&>;\n};\n\n// By default, take the N/2'th element\ntemplate <std::ranges::sized_range Range>   // Requires being able to determine the range's size using std::ranges::size()\n  requires std::ranges::input_range<Range>  // Requires being able to dereference an iterator over the range.\nauto& medianOfSorted(Range&& range)\n{\n  auto iter{ std::ranges::begin(range) };   // Supported for every range\n  std::ranges::advance(iter, std::ranges::size(range) / 2);  // Advances in constant time for random-access ranges, linearly otherwise.\n  return *iter;                             // Only possible with input iterators...\n}\n\n// When we can take an average, check the size \n// (dynamically, not statically as was the original intent) \n// to decide whether we need to do so...\ntemplate <std::ranges::sized_range Range> \n  requires std::ranges::forward_range<Range>  // More strict than before: we need the multi-pass guarantee\n        && Averagable<std::ranges::range_value_t<Range>>\nauto medianOfSorted(Range&& range)\n{\n  const auto N{ std::ranges::size(range) };\n  auto iter{ std::ranges::begin(range) };\n  if (N % 2 == 0)\n  {\n    std::ranges::advance(iter, N / 2 - 1);\n    const auto& value1{ *iter };      // Reference remains valid because iter is a forward iterator!\n    std::ranges::advance(iter, 1);\n    return (value1 + *iter) / 2;\n  }\n  else\n  {\n    std::ranges::advance(iter, N / 2);\n    return *iter;\n  }\n}\n\nint main()\n{\n  std::array values_odd{ 1, 2, 3, 4, 5, 6, 7 };\n  std::cout << medianOfSorted(values_odd) << std::endl;\n\n  std::array values_even{ 1., 2., 3., 4., 5., 6. };\n  std::cout << medianOfSorted(values_even) << std::endl;\n\n  std::string strings_odd[] { \"1\", \"2\", \"3\", \"4\", \"5\" };\n  std::cout << medianOfSorted(strings_odd) << std::endl;\n\n  std::string strings_even[] { \"1\", \"2\", \"3\", \"4\", \"5\", \"6\" };\n  std::cout << medianOfSorted(std::span{ strings_even }) << std::endl;\n\n  std::vector dynamically_sized{ 1.f, 2.f, 3.f, 4.f };\n  std::cout << medianOfSorted(dynamically_sized) << std::endl;\n\n  std::list non_random_access{ 4.f, 3.f, 2.f, 1.f, 0.f };\n  std::cout << medianOfSorted(non_random_access) << std::endl;\n\n  std::forward_list non_sized_ranged{ 123, 456, 789 };\n  //std::cout << medianOfSorted(non_sized_ranged) << std::endl; /* Error: not sized! */\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 21/Soln21_05/Soln21_05.cpp",
    "content": "// Exercise 21-5  Recreating std::advance() using constraint-based specialisation\nimport <iostream>;\nimport <iterator>;\n\nimport <vector>;\nimport <list>;\nimport <forward_list>;\n\ntemplate <std::random_access_iterator Iter>\nauto my_advance(Iter iter, std::iter_difference_t<Iter> n)\n{\n  return iter + n;\n}\n\ntemplate <std::bidirectional_iterator Iter>\nauto my_advance(Iter iter, std::iter_difference_t<Iter> n)\n{\n  while (n > 0) { ++iter; --n; }\n  while (n < 0) { --iter; ++n; }\n  return iter;\n}\n\ntemplate <std::input_or_output_iterator Iter>\nauto my_advance(Iter iter, std::iter_difference_t<Iter> n)\n{\n  while (n > 0) { ++iter; --n; }\n  return iter;\n}\n\nint main()\n{\n  // Random-access iterators:\n  std::vector v{ 1, 2, 3, 4, 5 };\n  std::cout << *my_advance(v.begin(), 3) << std::endl;\n\n  // Bidirectional iterators:\n  std::list l{ 1, 2, 3, 4, 5 };\n  std::cout << *my_advance(l.end(), -3) << std::endl;\n\n  // Forward iterators:\n  std::forward_list f{ 1, 2, 3, 4, 5 };\n  std::cout << *my_advance(f.begin(), 3) << std::endl;\n}"
  },
  {
    "path": "Exercises/Modules/Chapter 21/Soln21_06/Array.cppm",
    "content": "export module array;\n\nimport <stdexcept>;                        // For standard exception types\nimport <string>;                           // For std::to_string()\nimport <utility>;                          // For std::as_const()\nimport <iostream>;\n\n/*\n// Original template based on type traits and some mild template meta-programming\ntemplate<class T>\nstd::conditional_t<std::is_nothrow_move_assignable_v<T>, T&&, const T&>\nmove_assign_if_noexcept(T& x) noexcept\n{\n  return std::move(x);\n}\n*/\n\n// A straightforward concept with a single compound requirement\ntemplate <typename T>\nconcept NoThrowMoveAssignable =\n  requires (T left, T right) { { left = std::move(right) } noexcept -> std::same_as<T&>; };\n\n// By default: return lvalue reference (will result in x being copied)\n// (Note: this default move_assign_if_noexcept() template in itself is noexcept, \n//  the copy assignment that generally follows is not...)\nauto& move_assign_if_noexcept(auto& x) noexcept { return x; }\n\n// Specialization that moves if possible without throwing\n// Uses abbreviated template syntax with a type constraint on auto)\nauto&& move_assign_if_noexcept(NoThrowMoveAssignable auto& x) noexcept { return std::move(x); }\n\n\nexport template <typename T>\nclass Array\n{\npublic:\n  Array();                                  // Default constructor\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array) noexcept;            // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs) noexcept;   // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n  void push_back(T element);                // Copy or move element to the back of the array\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T>\nArray<T>::Array() : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved) noexcept\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs) noexcept\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\nexport template <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n// push_back() overload for lvalue references\ntemplate <typename T>\nvoid Array<T>::push_back(T element)  // Pass by value (copy of lvalue, or moved rvalue!)\n{\n  Array<T> newArray{m_size + 1};     // Allocate a larger Array<>\n  for (size_t i {}; i < m_size; ++i) // Move existing elements (copy if not noexcept)...\n    newArray[i] = move_assign_if_noexcept(m_elements[i]);\n\n  newArray[m_size] = move_assign_if_noexcept(element);  // Move (or copy) the new one...\n\n  swap(newArray);                   // ... and swap!\n}\n"
  },
  {
    "path": "Exercises/Modules/Chapter 21/Soln21_06/Soln21_06.cpp",
    "content": "// Exercise 21-6  Simplifying move_assign_if_noexcept using concepts (see Array.h)\nimport array;\nimport <string>;\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  Array<Array<std::string>> array_of_arrays;\n\n  Array<std::string> array{ buildStringArray(1'000) };\n  array_of_arrays.push_back(array);              // Push an lvalue\n\n  array.push_back(\"One more for good measure\");\n  std::cout << std::endl;\n\n  array_of_arrays.push_back(std::move(array));   // Push an rvalue\n}"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_01/ASSERT.h",
    "content": "#ifndef ASSERT_H    // Do not forget the #includ guard!\n#define ASSERT_H\n\n#include <iostream>\n#include <cstdlib> \n\n/* \n  Only real complication is the need for () around condition to avoid\n  expanding to expressions such as !x < y. Best do the same for message\n  as well to avoid similar operator precedence issues there.\n  This confirms, yet again, that using function-like macros often leads\n  to needlessly fragile code.\n */\n\n#define ASSERT(condition, message)       \\\n  if (!(condition))                      \\\n  {                                      \\\n    std::cerr << (message) << std::endl; \\\n    std::abort();                        \\\n  }                                      \\\n\n#endif // End of the #include guard"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_01/SolnA_01.cpp",
    "content": "// Exercise A-1   Defining a function-like macro\n#include <iostream>\n#include <format>\n\n#include \"ASSERT.h\"\n\nint main()\n{\n  int y{ 5 };\n\n  for (int x{}; x < 20; ++x)\n  {\n    std::cout << std::format(\"x = {}\\ty = {}\", x, y) << std::endl;\n    ASSERT(x < y, \"Whoopsidaisies, too far!\");\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_02/ASSERT.h",
    "content": "#ifndef ASSERT_H\n#define ASSERT_H\n\n#include <iostream>\n#include <cstdlib> \n\n#ifndef NDEBUG\n  #define ASSERT(condition, message)       \\\n    if (!(condition))                      \\\n    {                                      \\\n      std::cerr << (message) << std::endl; \\\n      std::abort();                        \\\n    }\n#else\n  #define ASSERT(condition, message)\n#endif\n\n#endif // End of the #include guard"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_02/SolnA_02.cpp",
    "content": "// Exercise A-2   Conditional compilation\n#include <iostream>\n#include <format>\n\n// Define (before including ASSERT.h) to disable the assertion\n#define NDEBUG\n#include \"ASSERT.h\"\n\nint main()\n{\n  int y{ 5 };\n\n  for (int x{}; x < 20; ++x)\n  {\n    std::cout << std::format(\"x = {}\\ty = {}\", x, y) << std::endl;\n    ASSERT(x < y, \"Whoopsidaisies, too far!\");\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_03/SmartException.cpp",
    "content": "#include \"SmartException.h\"\n\nSmartException::SmartException(const std::string& message, std::source_location location)\n  : std::logic_error{ message }\n  , m_location{ std::move(location) }\n{\n}\n\nvoid SmartException::throwFromHere(std::source_location location)\n{\n  m_location = std::move(location);\n  throw *this;\n}\n\nconst std::source_location& SmartException::where() const\n{\n  return m_location;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_03/SmartException.h",
    "content": "#ifndef SMART_EXCEPTION_H\n#define SMART_EXCEPTION_H\n\n#include <stdexcept>\n#include <source_location>\n\nclass SmartException : public std::logic_error\n{\npublic:\n  SmartException(const std::string& message, std::source_location location = std::source_location::current());\n\n  /* Throws the exception at this location\n   * For cases where the exception is not created at the same line where it is thrown:\n   *   SmartException exception{ \"BOOM!\", {} };\n   *   ... // more code\n   *   exception.throwFromHere();\n   * Note: in the example above, {} is optional \n   * (it avoids calling std::source_location::current() during construction)\n   */\n  void throwFromHere(std::source_location location = std::source_location::current());\n\n  const std::source_location& where() const;\n\nprivate:\n  std::source_location m_location;\n};\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_03/SolnA_03.cpp",
    "content": "// Exercise A-3   Writing an exception class that records where \n// the exception object was created/thrown.\n#include <iostream>\n#include \"SmartException.h\"\n\nint main()\n{\n  try\n  {\n    throw SmartException{ \"Throwing directly...\" };\n  }\n  catch (const SmartException& exception)\n  {\n    std::cerr << \"Something went wrong at line \" << exception.where().line() << std::endl;\n  }\n\n  // Advanced use. This was no requirement of the exercise, \n  // but it seems like something a smart exception could use...\n  try\n  {\n    SmartException exception{ \"Throwing later...\", {} };  // Optional: {} to avoid calling std::source_location::current()\n    // ...\n    exception.throwFromHere();\n  }\n  catch (const SmartException& exception)\n  {\n    std::cerr << \"Something went wrong at line \" << exception.where().line() << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_04/SmartException.h",
    "content": "#ifndef SMART_EXCEPTION_H\n#define SMART_EXCEPTION_H\n\n#include <stdexcept>\n#include <source_location>\n\nclass SmartException : public std::logic_error\n{\npublic:\n  SmartException(const std::string& message, std::source_location location = std::source_location::current())\n    : std::logic_error{ message }\n    , m_location{ std::move(location) }\n  {\n  }\n\n  /* Throws the exception at this location\n   * For cases where the exception is not created at the same line where it is thrown:\n   *   SmartException exception{ \"BOOM!\", {} };\n   *   ... // more code\n   *   exception.throwFromHere();\n   * Note: in the example above, {} is optional \n   * (it avoids calling std::source_location::current() during construction)\n   */\n  void throwFromHere(std::source_location location = std::source_location::current());\n\n  const std::source_location& where() const;\n\nprivate:\n  std::source_location m_location;\n};\n\n// Note: do not repeat the default argument value!\ninline void SmartException::throwFromHere(std::source_location location)\n{\n  m_location = std::move(location);\n  throw *this;\n}\n\ninline const std::source_location& SmartException::where() const\n{\n  return m_location;\n}\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_04/SolnA_04.cpp",
    "content": "// Exercise A-4   Defining class member functions in the header\n#include <iostream>\n#include \"SmartException.h\"\n\nint main()\n{\n  try\n  {\n    throw SmartException{ \"Throwing directly...\" };\n  }\n  catch (const SmartException& exception)\n  {\n    std::cerr << \"Something went wrong at line \" << exception.where().line() << std::endl;\n  }\n\n  // Advanced use. This was no requirement of the exercise, \n  // but it seems like something a smart exception could use...\n  try\n  {\n    SmartException exception{ \"Throwing later...\", {} };  // Optional: {} to avoid calling std::source_location::current()\n    // ...\n    exception.throwFromHere();\n  }\n  catch (const SmartException& exception)\n  {\n    std::cerr << \"Something went wrong at line \" << exception.where().line() << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_05/Print.cpp",
    "content": "#include <iostream>\n#include <string_view>\n\nvoid print(std::string_view string)\n{\n  std::cout << string << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_05/PrintThat.cpp",
    "content": "#include \"PrintThat.h\"\n\n// Note: extern keyword is optional, \n// but does make clear that external linkage is used here.\nextern void print(std::string_view string);\n\nvoid print_that(std::string_view string)\n{\n  print(string);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_05/PrintThat.h",
    "content": "// Note: #include guards are strictly speaking optional for headers\n// that contain only function prototypes, \n// but convention dictates you add them regardless.\n#ifndef PRINT_THAT_H\n#define PRINT_THAT_H\n\n#include <string_view>\n\nvoid print_that(std::string_view string);\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_05/PrintThis.cpp",
    "content": "#include \"PrintThis.h\"\n\n// Note: extern keyword is optional, \n// but does make clear that external linkage is used here.\nextern void print(std::string_view string);\n\nvoid print_this(std::string_view string)\n{\n  print(string);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_05/PrintThis.h",
    "content": "// Note: #include guards are strictly speaking optional for headers\n// that contain only function prototypes, \n// but convention dictates you add them regardless.\n#ifndef PRINT_THIS_H\n#define PRINT_THIS_H\n\n#include <string_view>\n\nvoid print_this(std::string_view string);\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_05/SolnA_05.cpp",
    "content": "// Exercise A-5   External functions and header files...\n#include <iostream>\n#include \"PrintThis.h\"\n#include \"PrintThat.h\"\n\nint main()\n{\n  print_this(\"Happiness can be found even in the darkest of times, \");\n  print_that(\"if one only remembers to turn on the light.\");\n                                          // -- Albus Dumbledore \n}"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_06/Print.h",
    "content": "#ifndef PRINT_H\n#define PRINT_H\n\n#include <iostream>\n#include <string_view>\n\ninline void print(std::string_view string)\n{\n  std::cout << string << std::endl;\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_06/PrintThat.cpp",
    "content": "#include \"PrintThat.h\"\n#include \"Print.h\"\n\nvoid print_that(std::string_view string)\n{\n  print(string);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_06/PrintThat.h",
    "content": "// Note: #include guards are strictly speaking optional for headers\n// that contain only function prototypes, \n// but convention dictates you add them regardless.\n#ifndef PRINT_THAT_H\n#define PRINT_THAT_H\n\n#include <string_view>\n\nvoid print_that(std::string_view string);\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_06/PrintThis.cpp",
    "content": "#include \"PrintThis.h\"\n#include \"Print.h\"\n\nvoid print_this(std::string_view string)\n{\n  print(string);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_06/PrintThis.h",
    "content": "// Note: #include guards are strictly speaking optional for headers\n// that contain only function prototypes, \n// but convention dictates you add them regardless.\n#ifndef PRINT_THIS_H\n#define PRINT_THIS_H\n\n#include <string_view>\n\nvoid print_this(std::string_view string);\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_06/SolnA_06.cpp",
    "content": "// Exercise A-6   Inline function definitions\n#include <iostream>\n#include \"PrintThis.h\"\n#include \"PrintThat.h\"\n\nint main()\n{\n  print_this(\"I have found that it is the small everyday deed of ordinary folks \");\n  print_that(\"that keep the darkness at bay. Small acts of kindness and love.\");\n                                          // -- Gandalf the Grey\n}"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_07A/Print.cpp",
    "content": "#include <iostream>\n#include <string_view>\n\nunsigned count;\n\nvoid print(std::string_view string)\n{\n  std::cout << string << std::endl;\n  ++count;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_07A/PrintThat.cpp",
    "content": "#include \"PrintThat.h\"\n\n// Note: extern keyword is optional, \n// but does make clear that external linkage is used here.\nextern void print(std::string_view string);\n\nvoid print_that(std::string_view string)\n{\n  print(string);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_07A/PrintThat.h",
    "content": "// Note: #include guards are strictly speaking optional for headers\n// that contain only function prototypes, \n// but convention dictates you add them regardless.\n#ifndef PRINT_THAT_H\n#define PRINT_THAT_H\n\n#include <string_view>\n\nvoid print_that(std::string_view string);\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_07A/PrintThis.cpp",
    "content": "#include \"PrintThis.h\"\n\n// Note: extern keyword is optional, \n// but does make clear that external linkage is used here.\nextern void print(std::string_view string);\n\nvoid print_this(std::string_view string)\n{\n  print(string);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_07A/PrintThis.h",
    "content": "// Note: #include guards are strictly speaking optional for headers\n// that contain only function prototypes, \n// but convention dictates you add them regardless.\n#ifndef PRINT_THIS_H\n#define PRINT_THIS_H\n\n#include <string_view>\n\nvoid print_this(std::string_view string);\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_07A/SolnA_07A.cpp",
    "content": "// Exercise A-7   External variables (based on Exercise A-5)\n#include <iostream>\n#include \"PrintThis.h\"\n#include \"PrintThat.h\"\n\nextern unsigned count;\n\nint main()\n{\n  print_this(\"It is our choices that show what we truly are, \");\n  print_that(\"far more than our abilities.\");\n                                          // -- Albus Dumbledore\n\n  std::cout << \"\\n(print() was called \" << count << \" times)\";\n}"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_07B/Print.h",
    "content": "#ifndef PRINT_H\n#define PRINT_H\n\n#include <iostream>\n#include <string_view>\n\ninline int count {};\n\ninline void print(std::string_view string)\n{\n  std::cout << string << std::endl;\n  ++count;\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_07B/PrintThat.cpp",
    "content": "#include \"PrintThat.h\"\n#include \"Print.h\"\n\nvoid print_that(std::string_view string)\n{\n  print(string);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_07B/PrintThat.h",
    "content": "// Note: #include guards are strictly speaking optional for headers\n// that contain only function prototypes, \n// but convention dictates you add them regardless.\n#ifndef PRINT_THAT_H\n#define PRINT_THAT_H\n\n#include <string_view>\n\nvoid print_that(std::string_view string);\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_07B/PrintThis.cpp",
    "content": "#include \"PrintThis.h\"\n#include \"Print.h\"\n\nvoid print_this(std::string_view string)\n{\n  print(string);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_07B/PrintThis.h",
    "content": "// Note: #include guards are strictly speaking optional for headers\n// that contain only function prototypes, \n// but convention dictates you add them regardless.\n#ifndef PRINT_THIS_H\n#define PRINT_THIS_H\n\n#include <string_view>\n\nvoid print_this(std::string_view string);\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Appendix A/SolnA_07B/SolnA_07B.cpp",
    "content": "// Exercise A-7   External variables (based on Exercise A-6)\n#include <iostream>\n#include \"PrintThis.h\"\n#include \"PrintThat.h\"\n#include \"Print.h\"\n\nint main()\n{\n  print_this(\"All we have to decide is what to do \");\n  print_that(\"with the time that is given to us.\");\n                                 // -- Gandalf the Grey\n\n  std::cout << \"\\n(print() was called \" << count << \" times)\";\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 01/Exer1_03.cpp",
    "content": "// Exercise 1-3. Spot the errors. \n// The correct version should closely resemble the answer to Exercise 1.1.\n\ninclude <iostream>                            // # character missing before include\n\nInt main()                                    // Should be int, not Int\n{\n  std:cout << \"Hola Mundo!\" << std:endl       // A semicolon is missing from the end of this line\n                                              // cout and endl must be prefixed with std::, not std:\n)"
  },
  {
    "path": "Exercises/NoModules/Chapter 01/Soln1_01.cpp",
    "content": "// Exercise 1-1 Writing the line \"Hello World\" to the screen.\n\n#include <iostream>\n\nint main()\n{\n  std::cout << \"Hello World\" << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 01/Soln1_02.cpp",
    "content": "// Exercise 1-2. Write your name and age on successive lines.\n// There are several possibilities. You can do it in one statement for example.\n// You could also output '\\n' to go to a new line.\n\n#include <iostream>\n\nint main()\n{\n  std::cout << \"Phil McCavity\" << std::endl;       // Name\n  std::cout << \"Age: 88\" << std::endl;             // and age\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 02/Soln2_01A.cpp",
    "content": "// Exercise 2-1. Convert inches to feet and inches\n// The number of inches per foot is constant, \n// and should not be changed within the program,\n// so we recognize this by declaring it as a const.\n//\n// This solution uses only std::cout. \n// See alternate solution for a version that uses std::format().\n//\n// Note: we always output \"feet\" and \"inches\", \n// even if it concerns only 1 foot or 1 inch.\n// In a later chapter you will learn about the conditional \n// statements and expressions that allow you to refine this.\n\n#include <iostream>\n\nint main()\n{\n  const int inches_per_foot{ 12 };    // Initialize constant variable\n\n  std::cout << \"This program will convert inches to feet and inches.\" << std::endl;\n\n  int inches{};\n  std::cout << \"Please enter a number of inches: \";\n  std::cin >> inches;\n\n  const int feet{ inches / inches_per_foot };\n  const int remaining_inches{ inches % inches_per_foot };\n\n  std::cout << inches << \" inches equals \"\n    << feet << \" feet and \" << remaining_inches << \" inches.\"\n    << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 02/Soln2_01B.cpp",
    "content": "// Exercise 2-1. Convert inches to feet and inches\n// The number of inches per foot is constant, \n// and should not be changed within the program,\n// so we recognize this by declaring it as a const.\n//\n// This solution uses std::format().\n//\n// Note: we always output \"feet\" and \"inches\", \n// even if it concerns only 1 foot or 1 inch.\n// In a later chapter you will learn about the conditional \n// statements and expressions that allow you to refine this.\n\n#include <iostream>\n#include <format>\n\nint main()\n{\n  const int inches_per_foot { 12 };    // Initialize constant variable\n\n  std::cout << \"This program will convert inches to feet and inches.\" << std::endl;\n\n  int inches {};\n  std::cout << \"Please enter a number of inches: \";\n  std::cin >> inches;\n\n  const int feet = inches / inches_per_foot;\n  const int remaining_inches = inches % inches_per_foot;\n\n  std::cout \n    << std::format(\"{} inches equals {} feet and {} inches.\", inches, feet, remaining_inches) \n    << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 02/Soln2_02A.cpp",
    "content": "// Exercise 2-2 Compute the area of a circle\n// This solution uses only std::cout. \n// See alternate solution for a version that uses std::format().\n\n#include <iostream>\n#include <numbers>\n\nint main()\n{\n  std::cout << \"This program will compute the area of a circle.\" << std::endl;\n\n  double radius {};\n  std::cout << \"Please enter the radius of the circle: \";\n  std::cin >> radius;\n  \n  const auto area{ std::numbers::pi * radius * radius };\n\n  std::cout << \"The area of the circle is \" << area << \" square units.\" << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 02/Soln2_02B.cpp",
    "content": "// Exercise 2-2 Compute the area of a circle\n// This solution uses std::format() \n// to control the precision used when outputting the result\n// (we opted for 2 decimals after the decimal points).\n\n#include <iostream>\n#include <numbers>\n#include <format>\n\nint main()\n{\n  std::cout << \"This program will compute the area of a circle.\" << std::endl;\n\n  double radius {};\n  std::cout << \"Please enter the radius of the circle: \";\n  std::cin >> radius;\n  \n  const auto area{ std::numbers::pi * radius * radius };\n\n  std::cout << std::format(\"The area of the circle is {:.2f} square units.\", area) << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 02/Soln2_03.cpp",
    "content": "// Exercise 2-3. Calculating the height of a tree\n#include <iostream> \n#include <numbers>\n#include <cmath>\n\nint main()\n{\n  const double inches_per_foot {12.0};\n  const double pi_degrees {180.0};\n  double feet {};\n  double inches {};\n\n  std::cout << \"Enter the distance from the tree in feet and inches: \";\n  std::cin >> feet >> inches;\n  const double distance {feet + inches / inches_per_foot};\n\n  double angle {};\n  std::cout << \"Enter the angle of the top of the tree in degrees: \";\n  std::cin >> angle;\n  \n  // First convert angle to radians \n  // (the trigoniometric functions of <cmath> operate with radians)\n  angle *= std::numbers::pi / pi_degrees;     \n                                              \n  double eye_height {};\n  std::cout << \"Enter your eye height from the ground in inches: \";\n  std::cin >> eye_height;\n  eye_height /= inches_per_foot;                                  // Convert to feet\n  \n  const double height {eye_height + distance * std::tan(angle)};  // Tree height in feet\n  const unsigned height_feet {static_cast<unsigned>(height)};\n  const unsigned height_inches {static_cast<unsigned>(std::round(inches_per_foot * (height - height_feet)))};\n\n  std::cout << \"\\nThe height of the tree is \"\n            << height_feet << \" feet \"\n            << height_inches << \" inches.\\n\" << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 02/Soln2_04.cpp",
    "content": "// Exercise 2-4. Calculating the Body Mass Index.\n// In the expression for bmi, both h_feet and h_inches will be implicitly converted to double\n// because the other operand of the sub-expression is double.\n\n#include <iostream>\n\nint main()\n{\n  const double lbs_per_kg {2.2};\n  const double inches_per_foot {12.0};\n  const double meters_per_foot {0.3048};\n  \n  double w_lbs {};\n  unsigned int h_feet {};\n  unsigned int h_inches {};\n\n  std::cout << \"Enter your weight in pounds: \";\n  std::cin >> w_lbs;\n  std::cout << \"Enter you height in feet and inches: \";\n  std::cin >> h_feet >> h_inches;\n\n  const double w_kg {w_lbs / lbs_per_kg};\n  const double h_meters { meters_per_foot * (h_feet + h_inches / inches_per_foot) };\n  const double bmi {w_kg / (h_meters * h_meters)};\n  std::cout << \"Your BMI is \" << bmi << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 02/Soln2_05.cpp",
    "content": "// Exercise 2-5. Output your BMI with one decimal after the decimal point.\n\n#include <iostream>\n#include <format>\n\nint main()\n{\n  const double lbs_per_kg{ 2.2 };\n  const double inches_per_foot{ 12.0 };\n  const double meters_per_foot{ 0.3048 };\n\n  double w_lbs{};\n  unsigned int h_feet{};\n  unsigned int h_inches{};\n\n  std::cout << \"Enter your weight in pounds: \";\n  std::cin >> w_lbs;\n  std::cout << \"Enter you height in feet and inches: \";\n  std::cin >> h_feet >> h_inches;\n\n  const double w_kg{ w_lbs / lbs_per_kg };\n  const double h_meters{ meters_per_foot * h_feet + h_inches / inches_per_foot };\n  const double bmi{ w_kg / (h_meters * h_meters) };\n  std::cout << std::format(\"Your BMI is {:.1f}\\n\", bmi);\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 02/Soln2_06.cpp",
    "content": "// Exercise 2-6. Format a table.\n\n#include <iostream>\n#include <numbers>\n#include <format>\n\nint main()\n{\n  // Define the format strings for the various rows of the table first\n  const auto format_header     { \"{:20} {:35} {}\\n\" };\n  const auto format_precision5 { \"{:20} {:35} {:.5f}...\\n\" };\n  const auto format_precision3 { \"{:20} {:35} {:.3f}...\\n\" };\n\n  std::cout << std::format(format_header,     \"Constant\",            \"Description\",                       \"Approximation\");\n  std::cout << std::format(format_precision5, \"std::numbers::e\",     \"The base of the natural logarithm\", std::numbers::e);\n  std::cout << std::format(format_precision5, \"std::numbers::pi\",    \"pi\",                                std::numbers::pi);\n  std::cout << std::format(format_precision5, \"std::numbers::sqrt2\", \"Square root of 2\",                  std::numbers::sqrt2);\n  std::cout << std::format(format_precision3, \"std::numbers::phi\",   \"The golden ration constant\",        std::numbers::phi);\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 02/Soln2_07.cpp",
    "content": "// Exercise 2-7. Fun with formatting.\n// You could always experiment further with various formatting options here!\n\n#include <iostream>\n#include <numbers>\n#include <format>\n#include <cmath>\n\nint main()\n{\n  // Define the format strings for the various rows of the table first\n  const auto format_header    { \"{:20} {:35} {}\\n\" };\n  const auto format_precision5{ \"{:20} {:35} {:.5f}...\\n\" };\n  const auto format_precision3{ \"{:20} {:35} {:.3f}...\\n\" };\n  const auto format_extra_row { \"{:20} {:35} {:.5E}...\\n\" };\n\n  std::cout << std::format(format_header,     \"Constant\",            \"Description\",                       \"Approximation\");\n  std::cout << std::format(format_precision5, \"std::numbers::e\",     \"The base of the natural logarithm\", std::numbers::e);\n  std::cout << std::format(format_precision5, \"std::numbers::pi\",    \"pi\",                                std::numbers::pi);\n  std::cout << std::format(format_precision5, \"std::numbers::sqrt2\", \"Square root of 2\",                  std::numbers::sqrt2);\n  std::cout << std::format(format_precision3, \"std::numbers::phi\",   \"The golden ration constant\",        std::numbers::phi);\n  std::cout << std::format(format_extra_row,  \"sin(pi/4)\",           \"... in exponent notation\",          std::sin(std::numbers::pi / 4));\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 02/Soln2_08.cpp",
    "content": "// Exercise 2-8. Finding the largest of two integers without comparing them.\n#include <iostream>\n\nint main()\n{\n  unsigned a {};\n  unsigned b {};\n\n  std::cout << \"Enter a positive integer: \";\n  std::cin >> a;\n  std::cout << \"Enter another positive integer: \";\n  std::cin >> b;\n\n  // The trick is that, for integer values x and y, \n  // x / y equals zero if x < y.\n  // So unless a and b are equal, either a/b or b/a is zero,\n  // meaning in (x * (a/b) + y * (b/a)) one of both operands of + equals 0.\n  // Once you have that, it's just a matter of working out the details.\n\n  const unsigned larger {(a * (a / b) + b * (b / a)) / (a / b + b / a)};\n  const unsigned smaller {(b * (a / b) + a * (b / a)) / (a / b + b / a)};\n  std::cout << \"The larger integer is \" << larger << \".\\n\"\n            << \"The smaller integer is \" << smaller << '.' << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 03/Soln3_01.cpp",
    "content": "// Exercise 3-1. Output an integer and its complements in binary and decimal.\n\n// This tests how well you remember string formatting using std::format()\n// (see Chapter 2 if you forgot some of the formatting options), \n// as well as two's complement binary encoding and bitwise ~.\n\n#include <iostream>\n#include <format>\n\n// See Appendix A (available online) for static_assert().\n// You should adjust the field widths of the table if ints have a different size.\nstatic_assert(sizeof(int) == 4, \"This program assumes 32 bit ints\");\n\nint main()\n{\n  int value {};\n  std::cout << \"Enter any integer: \";\n  std::cin >> value;\n  \n  const auto inverted{ static_cast<unsigned>(~value) };\n\n  // Output column headings (0b and 32 bits make for a width of 34)\n  std::cout << std::format(\" {:^34} {:^34} {:^34}\\n\", \"value\", \"~value\", \"~value + 1\");\n\n  // Output binary values (cast to unsigned integers first for more realistic output)\n  std::cout << std::format(\" {:#034b} {:#034b} {:#034b}\\n\", value, inverted, inverted + 1);\n\n  // Output decimal values\n  std::cout << std::format(\" {:^34} {:^34} {:^34}\\n\", value, ~value, ~value + 1);\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 03/Soln3_02.cpp",
    "content": "// Exercise 3-2. Calculating the number of boxes that can be stored on a shelf, without overhang. \n// We have to calculate how many boxes we can get into a row,\n// and how many rows we can have, and then multiply these numbers together.\n// The 'no overhang' problem is easily handled: casting from double to long \n// (using static_cast<>()) ensures that the fractional part of the double value\n// is omitted, and only whole boxes are counted. \n// By including static_cast<>() in the code, we are effectively telling the\n// compiler that we know what information will be lost in the cast.\n\n#include <iostream>\n\nint main() \n{\n  const int inches_per_foot {12};\n\n  double shelf_length {};\n  double shelf_depth {};\n  int box_size {};\n\n  // Prompt the user for both the shelf and box dimensions\n  std::cout << \"Enter shelf length (feet): \";\n  std::cin >> shelf_length;\n\n  std::cout << \"Enter shelf depth (feet): \";\n  std::cin >> shelf_depth;\n\n  std::cout << \"Enter length ofthe side of a box (inches): \";\n  std::cin >> box_size;\n\n  // Calculating the number of whole boxes needed to fill the shelf.\n  long boxes {static_cast<long>((shelf_length * inches_per_foot) / box_size) *\n                                static_cast<long>((shelf_depth * inches_per_foot) / box_size)};\n\n  // Displaying the number of boxes\n  std::cout << \"The number of boxes that can be contained in a single layer is \" << boxes << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 03/Soln3_03.cpp",
    "content": "/*********************************************************************************\nExercise 3-3. The output from the code is 2. Here's the important statement again:\n\nauto j {(k >> 4) & ~(~0u << 3)};\n\nThis question is an exercise in bit manipulation on k.\nFirst, (k >> 4) shifts the bits in k 4 places to the right;\nthe bitwise representation of 430 is 110101110,\nso a 4-bit shift leaves 11010.\nNext, ~0 is composed of all 1s; shifting that three places to the left\nand complementing the result will leave 111.\nFinally, doing a bitwise AND on 11010 and 111 leaves 10 (in binary)\nor 2 (in decimal) as the result.\n*********************************************************************************/\n\n#include <iostream>\n\nint main()\n{\n  /* Note: try to figure out the solution to this exercise without actually running it */\n  auto k{ 430u };\n  auto j{ (k >> 4) & ~(~0u << 3) };\n  std::cout << j << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 03/Soln3_04.cpp",
    "content": "// Exercise 3-4. Packing and unpacking characters.\n\n// Strictly speaking, whether or not this program works is compiler-dependent.\n// Although it's extremely unlikely that you'll notice a problem.\n// Concretely: it'll only work if a single byte is 8 bit (virtually always the case),\n// and the fundamental type int counts at least 4 bytes (true for most modern systems).\n\n#include <iostream>\n#include <format>\n\nint main()\n{\n  unsigned int packed {};\n  unsigned char ch {};\n  std::cout << std::format(\"{:26}\", \"Enter a character: \");\n  std::cin >> ch;\n  packed |= ch;\n\n  std::cout << std::format(\"{:26}\", \"Enter a second character: \");\n  std::cin >> ch;\n  packed <<= 8;                                // Shift left 1 byte\n  packed |= ch;\n\n  std::cout << std::format(\"{:26}\", \"Enter a third character: \");\n  std::cin >> ch;\n  packed <<= 8;                                // Shift left 1 byte\n  packed |= ch;\n\n  std::cout << std::format(\"{:26}\", \"Enter a fourth character: \");\n  std::cin >> ch;\n  packed <<= 8;                                // Shift left 1 byte\n  packed |= ch;\n\n  std::cout << std::format(\"The word containing 4 packed characters is {:#0x}\", packed) << std::endl;\n\t\n  std::cout << \"Unpacking the characters again gives (low-order byte first): \";\n\n  // Unpacking packed... \n  // (without the static_cast<char>() conversions the bytes would be written as numbers,\n  // which would be fine as well...)\n\n  unsigned int mask {0x00000FF};  // Keep low order byte \n                                  // (could just use 0xFF as well, or, of course, 255)\n\n  ch = packed & mask;                    // Low order byte\n  std::cout << std::format(\"{:4}\", static_cast<char>(ch));\n  ch = (packed >> 8) & mask;                   // 2nd byte\n  std::cout << std::format(\"{:4}\", static_cast<char>(ch));\n  ch = (packed >> 16) & mask;                  // 3rd byte\n  std::cout << std::format(\"{:4}\", static_cast<char>(ch));\n  ch = (packed >> 24) & mask;                  // 4th byte\n  std::cout << std::format(\"{:4}\", static_cast<char>(ch)) \n            << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 03/Soln3_05.cpp",
    "content": "// Exercise 3-5. Using an enumeration type for colors.\n// Of course, you have to research the RGB components for the colors.\n// Biggest complication is that you cannot apply any binary or other arithmetic operations\n// on values of a scoped enumaration type. For this, you have to first cast them to an integer.\n\n#include <iostream>\n#include <format>\n\nint main()\n{\n  enum class Color : unsigned\n  {\n    Red    = 0xFF0000u,\n    Green  = 0x00FF00u,\n    Blue   = 0x0000FFu,\n    Yellow = 0xFFFF00u,\n    Purple = 0xFF00FFu,\n    Black  = 0x000000u,\n    White  = 0xFFFFFFu\n  };\n\n  const auto format_string \n       { \"The components of {:^6} are: red: {:3}, green: {:3}, blue: {:3}\\n\" };\n  \n  const Color yellow{ Color::Yellow };\n  const Color purple{ Color::Purple };\n  const Color green { Color::Green };\n\n  std::cout << std::format(format_string,\n    \"yellow\",\n    (static_cast<unsigned>(yellow) & static_cast<unsigned>(Color::Red)) >> 16,\n    (static_cast<unsigned>(yellow) & static_cast<unsigned>(Color::Green)) >> 8,\n    (static_cast<unsigned>(yellow) & static_cast<unsigned>(Color::Blue))\n  );\n\n  std::cout << std::format(format_string,\n    \"purple\",\n    (static_cast<unsigned>(purple) & static_cast<unsigned>(Color::Red)) >> 16,\n    (static_cast<unsigned>(purple) & static_cast<unsigned>(Color::Green)) >> 8,\n    (static_cast<unsigned>(purple) & static_cast<unsigned>(Color::Blue))\n  );\n\n  std::cout << std::format(format_string,\n    \"green\",\n    (static_cast<unsigned>(green) & static_cast<unsigned>(Color::Red)) >> 16,\n    (static_cast<unsigned>(green) & static_cast<unsigned>(Color::Green)) >> 8,\n    (static_cast<unsigned>(green) & static_cast<unsigned>(Color::Blue))\n  );\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 03/Soln3_06.cpp",
    "content": "// Exercise 3-6. Swapping integers.\n\n#include <iostream>\n\nint main()\n{\n  int first {}, second {};\n  std::cout << \"Enter two integers separated by a space: \";\n  std::cin >> first >> second;\n\n  first ^= second;\n  second ^= first;\n  first ^= second;\n  std::cout << \"In reverse order they are \" << first << \" and \" << second << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 04/Soln4_01.cpp",
    "content": "// Exercise 4-1 Testing whether two integer values are equal. \n\n#include <iostream>\n\nint main()\n{\n  int value1 {};\n  int value2 {};\n\n  std::cout << \"Please input two integers, separated by a space: \";\n  std::cin >> value1 >> value2;\n  std::cout << std::endl;\n\n  if (value1 == value2)\n    std::cout << \"The values you entered are the same (two times \" << value1 << \").\" << std::endl;\n  else \n    std::cout << \"The values you entered are not the same (\" << value1 << \" != \" << value2 << \").\" << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 04/Soln4_02.cpp",
    "content": "// Exercise 4-2 Testing for exact division of one integer by another.\n//              We can use an if statement to check that the input is valid \n//              and we can use another to arrange the input as we need. \n//              Then we use an if-else to generate the appropriate output.\n\n#include <iostream>\n\nint main()\n{\n  int value1 {};\n  int value2 {};\n\n  std::cout << \"Please input two positive integers, separated by a space: \";\n  std::cin >> value1 >> value2;\n  std::cout << std::endl;\n\n  if (value1 <= 0 || value2 <= 0)  // Valid input?\n  {\n    std::cout << \"Sorry - positive integers only.\" << std::endl;\n    return 1;\n  }\n\n  // Ensure that value1 is not smaller than value2\n  if (value1 < value2)\n  {         \n    const auto temp{ value1 };    // swap if necessary\n    value1 = value2;\n    value2 = temp;\n  }\n\n  if (value1 % value2 == 0)\n    std::cout << value2 << \" divides into \" << value1 << \" exactly. \" << std::endl;\n  else \n    std::cout << value1 << \" is not exactly divisible by \" << value2 << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 04/Soln4_03.cpp",
    "content": "// Exercise 4-3 Using nested ifs and a logical && to check the value of a number.\n\n#include <iostream>\n\nint main()\n{\n  double value {};\n\n  std::cout << \"Please enter a number between 1 and 100: \";\n  std::cin >> value;\n  std::cout << std::endl;\n\n  if (value >= 1 && value <= 100)\n  {\n    std::cout << \"The number you entered is \";\n    \n    if (value > 50)\n      std::cout << \"greater than 50\";\n    else if (value < 50)\n      std::cout << \"less than 50\" << std::endl;\n    else\n      std::cout << \"50\" << std::endl;\n  \n    std::cout << '.' << std::endl;\n  }\n  else\n  {\n    std::cout << \"The number is not between 1 and 100.\" << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 04/Soln4_04.cpp",
    "content": "// Exercise 4-4.\n// As promised, you're to go look for a person \"who is over 21, under 35, female, \n// has a bachelors or masters degree, is unmarried, and who speaks Hindi or Urdu\"\n\n#include <iostream>\n#include <cctype>          // For std::tolower() / std::toupper()\n\nenum class AcademicDegree\n{\n  none, associate, bachelor, professional, master, doctor\n};\n\nint main()\n{\n  unsigned int age {};        // Initialized to 0\n  char gender {};             // Initialized to '\\0' (see Chapter 5)\n  AcademicDegree degree {};   // Initialized to AcademicDegree::none\n  bool married {};            // Initialized to false\n  bool speaksHindi {};\n  bool speaksUrdu {};\n\n  std::cout << \"What is your age, if I may ask? \";\n  std::cin >> age;\n  \n  if (age > 120)\n  {\n    std::cout << \"Sure it is, joker. Sadly, commedians don't qualify...\" << std::endl;\n    return 1;\n  }\n  \n  std::cout << \"What is your gender ([m]ale, [f]emale, or [o]ther)? \";\n  std::cin >> gender;\n  \n  gender = std::tolower(gender);\n  if (gender != 'm' && gender != 'f' && gender != 'o')\n  {\n    std::cout << \"That was not one of the options... \"\n                 \"The square brackets were not clear, perhaps? We were worried about that...\";\n    return 1;\n  }\n  \n  std::cout << \"What is your highest academic degree?\\n\"\n    << \"Possible values are:\\n\"\n    << \"\\tn: no academic degree\\n\"\n    << \"\\ta: associate's degree\\n\"\n    << \"\\tb: bachelor's dehree\\n\"\n    << \"\\tp: professional degree\\n\"\n    << \"\\tm: master's degree\\n\"\n    << \"\\td: doctorate\\n\";\n  char degreeChar {};\n  std::cin >> degreeChar;  \n  \n  switch (std::tolower(degreeChar))\n  {\n    case 'n': degree = AcademicDegree::none;         break;\n    case 'a': degree = AcademicDegree::associate;    break;\n    case 'b': degree = AcademicDegree::bachelor;     break;\t\n    case 'p': degree = AcademicDegree::professional; break;\n    case 'm': degree = AcademicDegree::master;       break;\n    case 'd': degree = AcademicDegree::doctor;       break;\n    default:\n      std::cout << \"Given that you cannot correctly enter your degree, shall I just note down 'none'?\\n\";\n      std::cout << \"On second thought: no, I do not believe you qualify. Goodbye.\" << std::endl;\n      return 1;\n  }\n  \n  // Now we ask a few yes/no questions, and use some variations on how to decide\n  // whether or not the user's input is valid or not. In real code, one should\n  // probably be consistent rather than using a different style each time...  \n  \n  char yes_no {};\n  std::cout << \"Are you married (y or n)? \";\n  std::cin >> yes_no;\n  \n  if (yes_no == 'y' || yes_no == 'Y')\n    married = true;\n  else if (yes_no == 'n' || yes_no == 'N')\n    married = false;\n  else\n  {\n    std::cout << \"Incapable of entering your marital status. Surely still single then...?\" << std::endl;\n    return 1;\n  }\n  \n  std::cout << \"Do you speak Hindi (y or n)? \";\n  std::cin >> yes_no;\n  \n  yes_no = std::toupper(yes_no);\n  if (yes_no == 'Y')\n    speaksHindi = true;\n  else if (yes_no == 'N')\n    speaksHindi = false;\n  else\n  {\n    std::cout << \"I'm sorry? I didn't catch that. Please answer in English next time...\" << std::endl;\n    return 1;\n  }\n  \n  std::cout << \"Do you speak Urdu (y or n)? \";\n  std::cin >> yes_no;\n  \n  switch (std::tolower(yes_no))\n  {\n    case 'y': speaksUrdu = true;  break;\n    case 'n': speaksUrdu = false; break;\n    default:\n      std::cout << \"I'm sorry? I didn't catch that. Please answer in English next time...\" << std::endl;\n      return 1;\n  }\n  \n  // Determine whether the user is someone \"who is over 21, under 35, female, has a bachelors or masters degree,\n  // is unmarried, and who speaks Hindi or Urdu\"\n  if ((age > 21 && age < 35) \n        && gender == 'f' \n        && (degree == AcademicDegree::bachelor || degree == AcademicDegree::master)\n        && !married\n        && (speaksHindi || speaksUrdu))\n  {\n    std::cout << \"Congratulations: you are precisely the person we were looking for! Are you willing to work for minimum wage?\" << std::endl;\n  }\n  else\n  {\n    std::cout << \"Sorry. You don't seem to meet our requirements to the letter. Don't call us, we'll call you...?\" << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 04/Soln4_05.cpp",
    "content": "// Exercise 4-05\n// Using the conditional operator to select output.\n#include  <iostream>\n#include  <format>\n\nint main()\n{\n  int mice {};      // Count of all mice\n  int brown {};     // Count of brown mice\n  int white {};     // Count of white mice\n\n  std::cout << \"How many brown mice do you have? \";\n  std::cin >> brown;\n  std::cout << \"How many white mice do you have? \";\n  std::cin >> white;\n  \n  if (brown < 0 || white < 0)\n  {\n    std::cout << \"One cannot have a negative amount of mice...\" << std::endl;\n    return 1;\n  }\n\n  mice = brown + white;\n\n  std::cout <<\n    std::format(\"You have {} {} in total.\\n\", mice, mice == 1 ? \"mouse\" : \"mice\");\n\n  if (mice == 1)\n  {\n    // Mind the parentheses around the conditional expression!\n    std::cout << \"It is a \" << (brown? \"brown\" : \"white\") << \" mouse.\" << std::endl;\n  }\n  else\n  {\n    // No need for parenthese around the conditional expressions here\n    std::cout << std::format(\"Of these mice, {} {} brown {}.\", \n        brown, \n        brown == 1 ? \"is a\" : \"are\", \n        brown == 1 ? \"mouse\" : \"mice\"\n    ) << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 04/Soln4_06.cpp",
    "content": "// Exercise 4-6 Finding the range for an integer. \n// This is just a question of bolting sufficient conditional operators together\n// in an expression. \n\n#include <iostream>\nusing std::cin;\nusing std::cout;\nusing std::endl;\n\nint main()\n{\n  int n {};\n  std::cout << \"Enter an integer: \";\n  std::cin >> n;\n  \n  std::cout << \"The value is \" \n    << (n <= 20 ? \"not greater than 20\" : \n        n <= 30 ? \"greater than 20 and not greater than 30\" : \n        n <= 100? \"greater than 30 and not exceeding 100\" : \n                  \"greater than 100\")\n    << '.' << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 04/Soln4_07.cpp",
    "content": "// Exercise 4-7 Outputting the binary code for a letter.\n/*\n * Most of the program is fairly simple. \n * The cctype functions make determining upper or lower case easy. \n * Finding out if it's a vowel is also easy with a switch.\n * Only getting the binary code needs a little thought, though. \n * Each of the masks selects a different bit of the ch variable.\n * If the bit is '1', the expression will be non-zero, which is converted to Boolean true.\n * If it's '0', the whole expression will be zero, or Boolean false.\n * Ones and zeros are therefore output as appropriate.\n */\n#include <iostream>\n#include <cctype>\n\nint main()\n{\n  char entered_letter {};\n  std::cout << \"Enter a letter: \";\n  std::cin >> entered_letter;\n\n  if (!std::isalpha(entered_letter)) \n  {\n    std::cout << \"That's not a letter!\" << std::endl;\n    return 1;\n  }\n\n  // We'll need the lower case letter...\n  const auto lower_case_letter{ static_cast<char>(std::tolower(entered_letter)) };\n\n  // Determine upper or lower case.\n  std::cout << \"'\" << entered_letter << \"' is \" << \n    (std::islower(entered_letter) ? \"lowercase\" : \"uppercase\") << '.' << std::endl;\n\n  // Determine whether it is a vowel or a consonant.\n  std::cout << \"'\" << entered_letter << \"' is a \";\n\n  switch (lower_case_letter)\n  {\n    case 'a': case 'e': case 'i': case 'o': case 'u':\n      std::cout << \"vowel\";\n      break;\n    default:\n      std::cout << \"consonant\";\n      break;\n  }\n  std::cout << '.' << std::endl;\n\n  // Output the character code as binary\n  std::cout << \"The binary code for '\" << lower_case_letter << \"' is \"\n     << ((lower_case_letter & 0b10000000)? 1 : 0) \n     << ((lower_case_letter & 0b01000000)? 1 : 0)\n     << ((lower_case_letter & 0b00100000)? 1 : 0) \n     << ((lower_case_letter & 0b00010000)? 1 : 0)\n     << ((lower_case_letter & 0b00001000)? 1 : 0) \n     << ((lower_case_letter & 0b00000100)? 1 : 0)\n     << ((lower_case_letter & 0b00000010)? 1 : 0) \n     << ((lower_case_letter & 0b00000001)? 1 : 0)\n     << std::endl;\n\n  return 0;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 04/Soln4_08.cpp",
    "content": "// Exercise 4-8\n// Dividing a cash amount into quarters, nickels, dimes and cents.\n\n#include <iostream>\n\nint main()\n{\n  // Declare the constants (amounts of cents)\n  const unsigned quarter {25};\n  const unsigned dime {10};\n  const unsigned nickel {5};\n\n  double amountInDollars {0.0};\n  std::cout << std::endl << \"Please enter a cash amount between 0 and 10 dollars: $\";\n  std::cin >> amountInDollars;\n  \n  if (amountInDollars >= 0.0 && amountInDollars <= 10.0)\n  {\n    // Multiply dollar amount by 100 ($1 = 100 cents)\n    // We add 0.5 to compensate for errors in binary floating-point representation\n    auto amountInCents {static_cast<unsigned>(amountInDollars * 100.0 + 0.5)};\n\n    // Find the number of quarters\n    const auto quarters {amountInCents / quarter};\n    amountInCents %= quarter;               // Get the remainder\n\n    // Find the number of dimes\n    const auto dimes {amountInCents / dime};\n    amountInCents %= dime;                  // Get the remainder\n\n    // Find the number of nickels\n    const auto nickels {amountInCents / nickel};\n    amountInCents %= nickel;                // Get the remainder\n\n    // Find the number of pennies\n    const auto pennies {amountInCents};     // The remainder is already in pennies\n\n    std::cout << std::endl \n         << \"The dollar value $\" << amountInDollars << \" can be broken down into:\"  << std::endl\n         << quarters << \" quarter\" << (quarters == 1? \"\" : \"s\") << ',' << std::endl\n         << dimes    << \" dime\"    << (dimes    == 1? \"\" : \"s\") << ',' << std::endl\n         << nickels  << \" nickel\"  << (nickels  == 1? \"\" : \"s\") << ',' << std::endl\n         << pennies  << \" penn\"    << (pennies  == 1? \"y\" : \"ies\") << '.' << std::endl;\n  }\n  else\n  {\n    std::cout << std::endl << \"You did not enter a dollar amount between 0 and 10.\" << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 05/Soln5_01.cpp",
    "content": "// Exercise 5-1 Squaring odd numbers\n#include <iostream>\n#include <format>\n\nint main()\n{\n  int limit {};\n  std::cout << \"Enter the upper limit for squared odd numbers: \";\n  std::cin >> limit;\n  for (int i {1}; i <= limit; i += 2)\n  {\n    std::cout << std::format(\"{:4} squared is {:8}\\n\", i, i * i);\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 05/Soln5_02.cpp",
    "content": "// Exercise 5-2 Summing integers and calculating the average\n#include <iostream>\n#include <format>\n#include <cctype>\n\nint main()\n{\n  unsigned int count {};\n  long long total {};\n  \n  while (true)\n  {\n    std::cout << \"Enter an integer: \";\n    int n;\n    std::cin >> n;\n    total += n;\n    ++count;\n\n    char yesno {};\n    std::cout << \"Do you want to enter another (y/n)?\";\n    std::cin >> yesno;\n\n    if (std::tolower(yesno) == 'n')\n      break;\n  }\n  \n  std::cout \n    << std::format(\"The total is {}. The average is {:.2f}.\", \n                      total, static_cast<double>(total) / count) \n    << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 05/Soln5_03.cpp",
    "content": "// Exercise 5-3 Using a do-while loop to count characters\n#include <iostream>\n\nint main()\n{\n  unsigned count {};\n  char ch {};\n\n  std::cout << \"Please enter a sequence of characters terminated by '#':\" << std::endl;\n\n  // We have to read at least one character so do-while is best\n  do\n  {\n    std::cin >> ch;\n    ++count;\n  } while (ch != '#');\n\n  // We do not count '#' as a character, so count must be adjusted\n  --count;\n  std::cout << \"You entered \" << count << \" characters (not counting spaces and the terminal #).\" << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 05/Soln5_04.cpp",
    "content": "// Exercise 5-4 Print out characters entered by the user in reverse order\n#include <iostream>\n\nint main()\n{\n  const size_t max_num_characters {1'000};\n  char string[max_num_characters];\n\n  std::cout << \"Please enter a string: \";\n  std::cin.getline(string, max_num_characters);\n  \n  // Count the number of characters\n  size_t count {};\n  for (; count < max_num_characters && string[count] != '\\0'; ++count) {}\n\n/*\n  Take care: never write the following:\n    for (size_t i = count - 1; i >= 0; --i)\n      ...\n  Because size_t is unsigned, the loop continuation condition i >= 0 shall always and forever be true. \n  That is: every size_t value is always greater or equal to zero, by definition. \n  Subtracting one from zero wraps around to std::numeric_limits<size_t>::max(), a huge number.\n  \n  Other solutions besides the one we use below include:\n    // Cast to a signed integer (works even for count == 0!)\n    for (int i{ static_cast<int>(i) - 1 }; i != -1; --i)\n      ...\n    \n    // Subtract in second for expression (less readable, fails if count == 0)\n    for (size_t i{ count }; i-- > 0; )\n      ...\n  \n    // Use a break statement to end the loop (fails if count == 0)\n    for (size_t i{ count }; ; i--)\n    {\n      ...\n      if (i == 0) break;\n    }\n*/\n\n  // Print out the characters in reverse order\n  for (size_t i{ 1 }; i <= count; ++i)\n  {\n    std::cout << string[count - i];\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 05/Soln5_05.cpp",
    "content": "// Exercise 5-5 Print out characters entered by the user *after* reversing them\n#include <iostream>\n\nint main()\n{\n  const size_t max_num_characters {1'000};\n  char string[max_num_characters];\n\n  std::cout << \"Please enter a string: \";\n  std::cin.getline(string, max_num_characters);\n  \n  // Count the number of characters\n  size_t count {};\n  while (count < max_num_characters && string[count] != '\\0') \n\t  ++count;\n  \n  // Reverse the characters of the string entered by the user\n  for (size_t i{ 0 }; i < count / 2; ++i)\n  {\n    char temp{ string[i] };\n    string[i] = string[count - i - 1];\n    string[count - i - 1] = temp;\n  }\n  \n  // Print out all characters, one by one\n  for (size_t i{ 0 }; i < count; ++i)\n  {\n    std::cout << string[i];\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 05/Soln5_06.cpp",
    "content": "// Exercise 5-6. Working with a vector container\n#include <iostream>\n#include <format>\n#include <vector>\n\nint main()\n{\n  std::cout << \"What is the largest number I should check? \";\n  unsigned bound {};\n  std::cin >> bound;\n\n  std::vector<unsigned> values;\n  // Add element values 1 to bound\n  for (unsigned i {1}; i <= bound; ++i)\n    values.push_back(i);\n\n  size_t count {};              // Number of output values\n  size_t perline {10};          // Number output perline                 \n  for (auto value : values)\n  {\n    if (value % 7 == 0 || value % 13 == 0) continue;\n    std::cout << std::format(\"{:5}\", value);\n    if (++count % perline == 0) std::cout << \"\\n\";\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 05/Soln5_07.cpp",
    "content": "// Exercise 5-7. Outputting product records & cost\n// Getting the alignment right is tricky.\n// You have to adjust the field widths until it looks OK.\n#include <iostream>\n#include <format>\n#include <cctype>\n#include <vector>\n\nint main()\n{\n  std::vector<size_t> product_id;\n  std::vector<size_t> quantity;\n  std::vector<double> unit_cost;\n\n  // Read the records\n  while (true)\n  {\n    std::cout << \"Enter a record - product number, quantity, unit cost separated by spaces: \";\n    size_t id {};\n    size_t n {};\n    double cost {};\n    std::cin >> id >> n >> cost;\n\n    product_id.push_back(id);\n    quantity.push_back(n);\n    unit_cost.push_back(cost);\n    \n    std::cout << \"Do you want to enter another record (Y or N): \";\n    char answer {};\n    std::cin >> answer;\n    if (std::toupper(answer) == 'N') break;\n  }\n  \n  // Column headings\n  std::cout << std::format(\"{:10} {:10} {:10} {:10}\\n\", \n    \"Product\", \"Quantity\", \"Unit Price\", \"Cost\");\n  \n  double total_cost {};\n  for (size_t i {}; i < product_id.size(); ++i)\n  {\n    const auto cost{ quantity[i] * unit_cost[i] };\n    \n    std::cout <<\n      std::format(\"{:<10} {:<10} ${:<9.2f} ${:<9.2f}\\n\",\n        product_id[i], quantity[i], unit_cost[i], cost);\n    \n    total_cost += cost;\n  }\n  // Note the little trick to add empty space...\n  std::cout << std::format(\"{:33}${:<9.2f}\\n\", \"\", total_cost);\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 05/Soln5_08.cpp",
    "content": "// Exercise 5-08. Generate 93 Fibonacci numbers stored in an array.\n// Of course 93 was not an arbitrary choice for the number of Fibonacci numbers.\n// Fibonacci number grow fairly rapidly.\n// 93 is the most that are possible with type unsigned long long on most platforms.\n\n#include <iostream>\n#include <array>\n\n// See Appendix A (available online) for static_assert()\nstatic_assert(sizeof(unsigned long long) >= 8,\n  \"This program assumes the depth of unsigned long long is (at least) 64 bit.\");\n\nint main()\n{\n  const size_t n {93};\n  std::array<unsigned long long, n> fib;\n  fib[0] = fib[1] = 1UL;\n  for (size_t i {2}; i < n; ++i)\n    fib[i] = fib[i - 1] + fib[i - 2];\n\n  std::cout << \"The first \" << n << \" Fibonacci numbers are:\\n\";\n  for (auto number : fib)\n  {\n    std::cout << number << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 06/Soln6_01.cpp",
    "content": "// Exercise 6-1. Storing odd numbers in an array and accessing them using pointer notation\n\n/* Note that the use of pointer notation is just for the sake of the exercise,           *\n * to help you understand the intimate relation between pointers and array names.        *\n * In real code, you'd normally just use array notation, because it is that much easier. */\n\n#include <iostream>\n#include <format>\n\nint main()\n{\n  const size_t n {50};\n  size_t odds[n];\n  for (size_t i {}; i < n; ++i)\n    odds[i] = i * 2 + 1;\n\n  const size_t perline {10};\n  std::cout << \"The \" << n << \" first odd numbers are:\\n\";\n  for (size_t i {}; i < n; ++i)\n  {\n    std::cout << std::format(\"{:5}\", *(odds + i));\n    if ((i + 1) % perline == 0)                        // Uses the loop counter to decide when a newline is required\n      std::cout << std::endl;\n  }\n\n  std::cout << \"\\nIn reverse order these numbers are:\\n\";\n  for (int i {n - 1}; i >= 0; --i)                     // This won't work with size_t for the loop counter\n  {                                                    // because size_t cannot be negative\n    std::cout << std::format(\"{:5}\", *(odds + i));\n    if (i % perline == 0)\n      std::cout << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 06/Soln6_02.cpp",
    "content": "// Exercise 6-2. Traversing arrays using pointer arithmetics\n// An exercise to further deepen your understanding of the relation \n// between pointers, pointer arithmetic, and arrays.\n\n#include <iostream>\n#include <format>\n\nint main()\n{\n  const size_t n {50};\n  size_t odds[n];\n  for (size_t i {}; i < n; ++i)\n    odds[i] = i * 2 + 1;\n\n  const size_t perline {10};\n  std::cout << \"The \" << n << \" first odd numbers are:\\n\";\n  \n  size_t* traversal_pointer{ odds };\n  for (size_t i {}; i < n; ++i)\n  {\n    std::cout << std::format(\"{:5}\", *traversal_pointer++);\n    if ((i + 1) % perline == 0)      // Uses the loop counter to decide when a newline is required\n      std::cout << std::endl;\n  }\n\n  std::cout << \"\\nIn reverse order these numbers are:\\n\";\n  for (size_t i {}; i < n; ++i)      // No need to reverse the manipulation of the loop counter now\n  {\n    std::cout << std::format(\"{:5}\", *(--traversal_pointer)); // Use the pre-decrement operator to make sure the pointer is decremented\n    if ((i + 1) % perline == 0)                               // before it is dereferenced (at the start of this loop, \n      std::cout << std::endl;                                 // the pointer points one passed the last element of the odds array)\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 06/Soln6_03.cpp",
    "content": "// Exercise 6-3. Storing numbers in a dynamic array\n// Btw: notice anything about the result? \n// Try increasing numbers of array elements...\n#include <iostream>\n#include <format>\n#include <cmath>\n\nint main()\n{\n  size_t n {};\n  std::cout << \"Enter the number of array elements: \";\n  std::cin >> n;\n  auto* values{ new double[n] };\n  for (size_t i {}; i < n; ++i)\n    *(values+i) = 1.0 / ((i + 1)*(i + 1));\n\n  double sum {};\n  for (size_t i {}; i < n; ++i)\n    sum += values[i];\n\n  std::cout << std::format(\"The result is {}\", std::sqrt(6.0 * sum)) << std::endl;\n  \n  delete[] values;   // Don't forget to free the memory!\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 06/Soln6_04.cpp",
    "content": "// Exercise 6-4. Storing numbers in a vector\n\n/*\n * The result is an approximate value for pi. \n * The more values you use, the closer it becomes to pi.\n * In technical speak, this approximation does not converge to pi very fast though,\n * which basically means that you'll need quite some values \n * if you want to approximate pi beyond its first few digits.\n *\n * We must dereference values to use it with the subscript operator\n * because it is not a vector but a pointer to a vector.\n * \n * Note that allocating a vector<> like this in the free store is not often done.\n * Dynamic allocation is mostly reserved for objects of other class types,\n * in particular polymorphic ones. You'll learn all about this in later chapters!\n */\n\n#include <iostream>\n#include <format>\n#include <cmath>\n#include <vector>\n\nint main()\n{\n  size_t n {};\n  std::cout << \"Enter the number of vector elements: \";\n  std::cin >> n;\n  auto* values{ new std::vector<double>(n) };\n\n  for (size_t i {}; i < n; ++i)\n    (*values)[i] = 1.0 / ((i + 1)*(i + 1));\n  \n  double sum {};\n  for (auto value : *values)\n    sum += value;\n\n  std::cout << std::format(\"Result is {}\", std::sqrt(6.0*sum)) << std::endl;\n  \n  delete values;                                              // It's not an array this time!\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 06/Soln6_05.cpp",
    "content": "// Exercise 6-5. Managing a dynamic array using a smart pointer\n// You can no longer use pointer notation now!\n// (You could, technically, call get() first and then use pointer notation,\n// though why make the syntax even more convoluted: just use array notation!)\n\n#include <iostream>\n#include <format>\n#include <cmath>\n#include <memory>\n\nint main()\n{\n  size_t n {};\n  std::cout << \"Enter the number of array elements: \";\n  std::cin >> n;\n  auto values{ std::make_unique<double[]>(n) };\n  for (size_t i {}; i < n; ++i)\n    values[i] = 1.0 / ((i + 1)*(i + 1));\n\n  double sum {};\n  for (size_t i {}; i < n; ++i)\n    sum += values[i];\n\n  std::cout << std::format(\"The result is {}\", std::sqrt(6.0 * sum)) << std::endl;\n  \n  // No need to deallocate the memory yourself anymore: the smart pointer takes care of that for you!\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 06/Soln6_06.cpp",
    "content": "// Exercise 6-6. Storing a dynamically allocated vector in a smart pointer\n\n#include <iostream>\n#include <format>\n#include <cmath>\n#include <vector>\n#include <memory>\n\nint main()\n{\n  size_t n {};\n  std::cout << \"Enter the number of vector elements: \";\n  std::cin >> n;\n  auto values{ std::make_unique<std::vector<double>>(n) };\n\n  for (size_t i {}; i < n; ++i)\n    (*values)[i] = 1.0 / ((i + 1)*(i + 1));\n  \n  double sum {};\n  for (auto value : *values)\n    sum += value;\n\n  std::cout << std::format(\"Result is {}\", std::sqrt(6.0*sum)) << std::endl;\n  \n  // No need to deallocate the memory yourself anymore: the smart pointer takes care of that for you!\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 07/Soln7_01.cpp",
    "content": "// Exercise 7-1 Storing student names and grades. \n// This uses a vector of string objects to store the names.\n#include <iostream>\n#include <format>\n#include <cctype>\n#include <vector>\n#include <string>\n\nint main()\n{\n  std::vector<std::string> names;\n  std::vector<double> grades;\n  \n  size_t max_length {};        // Longest name length\n  double average_grade {};     // First accumulates the sum of the grades, \n                               // to be divided by the number of grades later\n  // Data entry loop. \n  // This loop reads the name and grade for each student.\n  while (true)\n  {\n    std::cout << \"Enter a student's name: \";\n    std::string name;                       // Stores a student name\n    std::getline(std::cin, name);\n\n    names.push_back(name);\n    \n    if (max_length < name.length()) \n        max_length = name.length();\n\n    std::cout << \"Enter \" << name << \"\\'s grade: \";\n    double grade {};                        // Stores a student grade\n    std::cin >> grade;\n    grades.push_back(grade);\n\n    average_grade += grade;\n\n    std::cout << \"Do you wish to enter another student's details (y/n): \";\n    char answer {};\n    std::cin >> answer;\n    \n    // Ignore the line break that is still on the input stream after reading the y/n character\n    // Otherwise the next std::getline() always returns an empty line...\n    // (Note: we'll try to remember to add this annoyance as a hint in the next edition...)\n    std::cin.ignore();\n    \n    if (std::toupper(answer) == 'N') break;\n  } \n\n  // Calculating the class average.\n  average_grade /= grades.size();\n\n  // Displaying the class average.\n  std::cout << \n    std::format(\"\\nThe class average for {} students is {:.2f}\\n\", names.size(), average_grade);\n\n  // Displaying the students' names and grades.\n  const size_t perline {3};\n  for (size_t i {}; i < names.size(); ++i)\n  {\n    std::cout << std::format(\"{:<{}} {:>4}\\t\", names[i], max_length, grades[i]);\n    if ((i + 1) % perline) continue;\n    std::cout << std::endl;\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 07/Soln7_02.cpp",
    "content": "// Exercise 7-2 Frequency of words in text.\n#include <iostream>\n#include <format>\n#include <string> \n#include <vector>\n\nint main()\n{\n  std::string text;                                          // The text to be searched\n  std::cout << \"Enter some text terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n\n  const std::string separators {\" ,;:.\\\"!?'\\n\"};             // Word delimiters\n  std::vector<std::string> words;                            // Words found\n  std::vector<size_t> counts;                                // Words counts (same order as words)\n\n  size_t start {text.find_first_not_of(separators)};         // First word start index\n  while (start != std::string::npos)                         // Find the words\n  {\n    size_t end {text.find_first_of(separators, start + 1)};  // Find end of word\n    if (end == std::string::npos)                            // Found a separator?\n      end = text.length();                                   // No, so set to last + 1\n    std::string word{ text.substr(start, end - start) };     // Record the word\n\n    // Check for word already in vector\n    bool is_in {false};                  // true when word has been found before\n    for (int i {}; i < words.size(); ++i)\n    {\n      if (words[i] == word)\n      {\n        ++counts[i];\n        is_in = true;\n        break;\n      }\n    }\n    if (!is_in)                          // If it's a new word...\n    {\n      words.push_back(word);             // ...store the word...\n      counts.push_back(1);               // ...and record the count\n    }\n    start = text.find_first_not_of(separators, end + 1);  // Find 1st character of next word\n  }\n\n  // Find maximum word length\n  size_t max_length {};\n  for (auto& word : words)\n    if (max_length < word.length()) max_length = word.length();\n\n  std::cout << \"Your string contains the following \" << words.size() << \" words and counts:\\n\";\n  size_t count {};                       // Numbers of words output\n  const size_t perline {3};              // Number per line\n  for (size_t i {}; i < words.size(); ++i)\n  {\n    std::cout << std::format(\"{:<{}}{:>4}  \", words[i], max_length, counts[i]);\n    if (!(++count % perline))\n      std::cout << std::endl;\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 07/Soln7_03.cpp",
    "content": "// Exercise 7-3 Replacing a word in text by asterisks.\n// Because we are looking for the word regardless of case,\n// the best way is to scan the text character by character.\n#include <iostream>\n#include <string> \n#include <cctype>\n\nint main()\n{\n  std::string text;     // The text to be searched\n  std::string word;     // Stores the word to be replaced\n\n  std::cout << \"Enter some text terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n  std::cout << \"\\nEnter the word to be replaced: \";\n  std::cin >> word;\n  \n  std::string lower_word;    // Convert word to lower case\n  for (char ch : word)       // (we do so once, rather than with every iteration of the loop)\n    lower_word += std::tolower(ch);\n\n  const std::string separators {\" ,;:.\\\"!?'\\n\"};            // Word delimiters\n\n  size_t start {text.find_first_not_of(separators)};        // First word start index\n  while (start != std::string::npos)                        // Find the words\n  {\n    auto end{ text.find_first_of(separators, start + 1) };  // Find end of word\n    if (end == std::string::npos)                           // Found a separator?\n      end = text.length();                                  // No, so set to last + 1\n\n    // Compare the word found with lower_word\n    if (end - start == word.length())\n    {\n      bool is_same_word{ true };                            // Assume it is the word we need to replace\n      for (size_t i {start}; i < end; ++i)\n      {\n        if (lower_word[i - start] != std::tolower(text[i])) // If a character differs...\n        {\n          is_same_word = false;                             // ...it is not the word                                 \n          break;      \n        }\n      }\n      if (is_same_word)                                     // If it is the word...\n      {\n        for (size_t i {start}; i < end; ++i)                // ... replace by asterisks\n          text[i] = '*';\n      }\n    }\n    start = text.find_first_not_of(separators, end + 1);    // Find 1st character of next word\n  }\n\n  std::cout << std::endl << text << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 07/Soln7_04.cpp",
    "content": "// Exercise 7-4 Check for anagrams.\n// There's more than one way to do this. \n// We chose to delete characters in one word that are common to both.\n// If the length of the word that has characters deleted is zero, they are anagrams.\n#include <iostream>\n#include <cctype>\n#include <string>\n\nint main() \n{\n  std::string word1, word2;\n\n  std::cout << \"Enter the first word: \";\n  std::cin >> word1;\n  std::cout << \"Enter the second word: \";\n  std::cin >> word2;\n\n  // Test the pathological case of the strings being different lengths\n  if (word1.length() != word2.length())\n  {\n    std::cout << word1 << \" and \" << word2 << \" are different lengths so they can't be anagrams!\" << std::endl;\n    return 0;\n  }\n\n  std::string word2_copy {word2};                // Copy word2 - because we will delete characters\n  // Loop over all the characters in word1\n  for (char c : word1)\n  {\n    // Loop over all the characters in word2 (we need the index now, so a range-based for loop won't do)\n    for (size_t i {}; i < word2_copy.length(); ++i)\n    {\n      if (std::tolower(word2_copy[i]) == std::tolower(c)) \n      {\n        word2_copy.erase(i, 1);                  // Character found so erase from word2\n        break;                                   // Caution: do not use erase(i), because that erases the entire substring starting at index i!\n      }\n    }\n  }\n\n  std::cout << word1 << \" and \" << word2 << \" are \"\n    << (word2_copy.empty() ? \"\" : \"not \")\n    << \"anagrams of one another.\"\n    << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 07/Soln7_05.cpp",
    "content": "// Exercise 7-5 Check for anagrams, ignoring spaces.\n// We chose to ignore all non-alphanumeric characters, not just spaces.\n#include <iostream>\n#include <cctype>\n#include <string>\n\nint main() \n{\n  std::string word1, word2;\n\n  std::cout << \"Enter the first word or phrase: \";\n  std::getline(std::cin, word1);\n  std::cout << \"Enter the second word or phrase: \";\n  std::getline(std::cin, word2);\n\n  std::string word2_copy {word2};                // Copy word2 - because we will delete characters\n  \n  bool anagrams{true};                           // Assume anagrams: becomes false if found otherwise\n  \n  // Loop over all the characters in word1\n  for (char c : word1)\n  {\n    if (!std::isalnum(c)) continue;              // Ignore characters that aren't alphanumeric.\n    \n    bool found {false};                          // Becomes true if c is found\n    // Loop over all the characters in word2 (we need the index now, so a range-based for loop won't do)\n    for (size_t i {}; i < word2_copy.length(); ++i)\n    {\n      if (std::tolower(word2_copy[i]) == std::tolower(c)) \n      {\n        word2_copy.erase(i, 1);                  // Character found so erase from word2\n        found = true;\n        break;                                   // Caution: do not use erase(i), because that erases the entire substring starting at index i!\n      }\n    }\n    if (!found)\n    {\n      anagrams = false;\n      break;\n    }\n  }\n  \n  // No alphanumeric characters are allowed to be left in word2_copy anymore at this point\n  for (char c : word2_copy)\n  {\n    if (std::isalnum(c))\n    {\n      anagrams = false;\n      break;\n    }\n  }\n\n  std::cout << word1 << \" and \" << word2 << \" are \"\n    << (anagrams? \"\" : \"not \")\n    << \"anagrams of one another.\"\n    << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 07/Soln7_06.cpp",
    "content": "// Exercise 7-6 Finding words that begin with a given letter.\n// If you wanted the words ordered by the first letter, you could sort the contents of letter first.\n// You could also retain all the sets of words for each letter in a separate vector for each set;\n// for this you could in other words use a std::vector<std::vector<std::string>>.\n// Here, we opted to gather the words for one letter and print out the results \n// during one iteration in the same loop.\n\n#include <iostream>\n#include <format>\n#include <cctype>\n#include <string> \n#include <vector> \n\nint main()\n{\n  std::string text;                                            // The text to be searched\n  std::string letters;\n  std::cout << \"Enter some text terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n  std::cout << \"\\nEnter the starting letters for the words you want to find: \";\n  std::cin >> letters;\n\n  const std::string separators {\" ,;:.\\\"!?'\\n\"};               // Word delimiters\n  std::vector<std::string> words;                              // Words found\n  const size_t perline {5};                                    // Words output per line\n  size_t count {};                                             // Number of words found\n  for (auto ch : letters)\n  {\n    size_t start {text.find_first_not_of(separators)};         // First word start index\n    size_t max_length {};                                      // Maximum word length\n    while (start != std::string::npos)                         // Find the words\n    {\n      auto end{ text.find_first_of(separators, start + 1) };   // Find end of word\n      if (end == std::string::npos)                            // Found a separator?\n        end = text.length();                                   // No, so set to last + 1\n      auto word{ text.substr(start, end - start) };            // Record the word\n      if (std::toupper(word[0]) == std::toupper(ch))           // If it begins with the current letter...\n      {\n        words.push_back(word);                                 // ...save the word\n        if (max_length < word.length()) max_length = word.length();\n      }\n\n      start = text.find_first_not_of(separators, end + 1);     // Find 1st character of next word\n    }\n    // List words for current letter\n    std::cout << \"\\nWords beginning with '\" << ch << \"' are:\\n\";\n    for (auto& word : words)\n    {\n      std::cout << std::format(\"{:<{}}\", word, max_length + 2);\n      if (++count % perline) continue;\n      std::cout << std::endl;\n    }\n    std::cout << std::endl;\n    words.clear();\n    count = 0;\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 07/Soln7_07.cpp",
    "content": "// Exercise 7-7\n// Practice string concatenation, looping over strings, and stoi()-like functions\n#include <iostream>\n#include <string>\n\nint main()\n{\n  std::cout << \"Enter a sequence of numbers terminated by #:\\n\";\n  \n  // Read a long string containing any number of integers\n  std::string numbers;\n  std::getline(std::cin, numbers, '#');\n\n  long sum {};\n  \n  size_t index {};\n  while (true)  // An indefinite loop, stopped using a break statement.\n  {\n    // Note: this solution does not verify that in between the numbers there's only whitespace. \n    // In real programs, such input validation may be appropriate...\n\n    // Search for the start of the next (signed!) number\n    const size_t start{ numbers.find_first_of(\"-0123456789\", index) }; \n    if (start == std::string::npos) \n      break;  // Stop once there's no numbers left\n\n    // Search for the end of the number\n    size_t end{ numbers.find_first_not_of(\"0123456789\", start + 1) };\n    if (end == std::string::npos)\n      end = numbers.length();\n\n    const size_t length{ end - start };   // To access substrings, we need the length of the string\n    const auto substring{ numbers.substr(start, length) };\n\n    // Just in case: skip minus signs not followed by a number (would otherwise crash...)\n    if (substring != \"-\")\n    {\n      const int number{ std::stoi(substring) };\n\n      sum += number;\n    }\n    \n    index = end;   // Advance to the next input (if any)\n  }\n    \n  std::cout << \"The sum of the numbers you entered is: \" << sum << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 07/Soln7_08A.cpp",
    "content": "// Exercise 7-8. Testing whether something is a tautogram.\n//\n// The loop based on find_first_of/find_first_not_of we use here is only one of many possible solutions.\n// See Soln7_08A for an alternate solution that first splits the text into a vector of words.\n//\n// Our solution in this file more or less assumes you enter only characters \n// that are either a letter or whitespace, \n// although it does cope with commas or dots that come directly after a word.\n// The alternate solution is more robust against non-letter characters.\n\n#include <iostream>\n#include <string>\n#include <cctype>\n\nint main()\n{\n  std::string text;      // The text to be checked\n  std::cout << \"Enter some text terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n\n  const auto whitespace{ \" \\t\\n\\r\\f\\v\" };  // Can be solved using std::isspace() as well...\n\n  const size_t first_letter_index{ text.find_first_not_of(whitespace) };\n  if (first_letter_index == std::string::npos)\n  {\n    // Is an empty string a tautogram? Let's not go there.\n    return 0;\n  }\n\n  const char start_letter{ static_cast<char>(std::toupper(text[first_letter_index])) };\n  bool tautogram{ true };\n\n  for (size_t start_current_word{ first_letter_index };;)  // Use an indefinite loop (see the break; statements)\n  {\n    const size_t next_space_index{ text.find_first_of(whitespace, start_current_word) };\n    if (next_space_index == std::string::npos)\n    {\n      break;\n    }\n\n    const size_t next_letter_index{ text.find_first_not_of(whitespace, next_space_index) };\n    if (next_letter_index == std::string::npos)\n    {\n      break;\n    }\n\n    if (std::toupper(text[next_letter_index]) != start_letter)\n    {\n      tautogram = false;\n      break;\n    }\n\n    start_current_word = next_letter_index;\n  }\n  \n  std::cout << \"The text that you entered is \" << (tautogram ? \"\" : \"not \") << \"a tautogram.\\n\";\n  if (tautogram)\n  {\n    std::cout << \"All words start with the letter \" << start_letter << '.';\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 07/Soln7_08B.cpp",
    "content": "// Exercise 7-8. Testing whether something is a tautogram.\n// This version uses a totally different technique (first splits the text into words), \n// and as a bonus ignores small words, and only requires 70% of the words to start with the same letter.\n// With this looser definition of tautogram \"The only verdict is vengeance; a vendetta, held as a votive not in vain.\", \n// not entirely coincidentally, passes as a \"near tautogram\".\n\n#include <iostream>\n#include <string>\n#include <cctype>\n#include <vector>\n\nint main()\n{\n  // Ignore small words\n  const size_t small_word_bound{ 3 };             // Set to 0 to not ignore small words at all\n  const double near_tautology_ratio_bound{ 0.7 }; // Set to 1 to always require 100% of the words to begin with the same letter\n\n  std::string text;      // The text to be checked\n  std::cout << \"Enter some text terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n  \n  std::vector<std::string> words;\n  for (size_t i {}; i < text.length(); )\n  {\n    // Skip spaces until we find the start of a word...\n    while (i < text.length() && !std::isalpha(text[i])) ++i;\n\n    const size_t start{ i };\n\n    // Search for the end of the word...\n    while (i < text.length() && std::isalpha(text[i])) ++i;\n\n    if (i > start)\n    {\n      words.push_back(text.substr(start, i - start));\n    }\n  }\n\n  // Only search for tautograms where words start with Latin letters A - Z\n  size_t counts[26] {}; // All counts are initialized to 0\n  size_t long_word_count{};\n\n  for (auto& word : words)\n  {\n    if (word.length() > small_word_bound)\n    {\n      ++long_word_count;\n      const auto start_letter{ std::toupper(word[0]) };\n      if (start_letter >= 'A' && start_letter <= 'Z')\n      {\n        ++counts[start_letter - 'A'];\n      }\n    }\n  }\n\n  // Look for the most common start letter\n  size_t most_common_index{ 0 };\n  for (size_t i{ 1 }; i < std::size(counts); ++i)\n  {\n    if (counts[i] > counts[most_common_index])\n    {\n      most_common_index = i;\n    }\n  }\n\n  const auto most_common_start_letter{ static_cast<char>('A' + most_common_index) };\n\n  if (counts[most_common_index] == words.size())\n  {\n    std::cout << \"The text that you entered is a true tautogram.\\n\";\n    std::cout << \"All words start with the letter \" << most_common_start_letter << '.';\n  }\n  else if (static_cast<double>(counts[most_common_index]) / long_word_count >= near_tautology_ratio_bound)\n  {\n    std::cout << \"It is a \\\"near tautogram\\\", though, as most longer words do start with the letter \" << most_common_start_letter << '.';\n  }\n  else\n  {\n    std::cout << \"The text that you entered is no tautogram. Not even close.\\n\";\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 07/Soln7_09A.cpp",
    "content": "// Exercise 7-9. Remove the begin letter of the tautogram (the easy way)\n\n#include <iostream>\n#include <string>\n#include <cctype>\n\nint main()\n{\n  std::string text;      // The text to be checked\n  std::cout << \"Enter some text terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n\n  const auto whitespace{ \" \\t\\n\\r\\f\\v\" };  // Can be solved using std::isspace() as well...\n\n  const size_t first_letter_index{ text.find_first_not_of(whitespace) };\n  if (first_letter_index == std::string::npos)\n  {\n    // Is an empty string a tautogram? Let's not go there.\n    return 0;\n  }\n\n  const char start_letter{ static_cast<char>(std::toupper(text[first_letter_index])) };\n  bool tautogram{ true };\n\n  for (size_t start_current_word{ first_letter_index };;)  // Use an indefinite loop (see the break; statements)\n  {\n    const size_t next_space_index{ text.find_first_of(whitespace, start_current_word) };\n    if (next_space_index == std::string::npos)\n    {\n      break;\n    }\n\n    const size_t next_letter_index{ text.find_first_not_of(whitespace, next_space_index) };\n    if (next_letter_index == std::string::npos)\n    {\n      break;\n    }\n\n    if (std::toupper(text[next_letter_index]) != start_letter)\n    {\n      tautogram = false;\n      break;\n    }\n\n    start_current_word = next_letter_index;\n  }\n  \n  std::cout << \"The text that you entered is \" << (tautogram ? \"\" : \"not \") << \"a tautogram.\\n\";\n  if (tautogram)\n  {\n    std::cout << \"All words start with the letter \" << start_letter << \".\\n\";\n\n    std::erase(text, start_letter);\n    std::erase(text, std::tolower(start_letter));\n\n    std::cout << \"After removing this letter, the text becomes as follows:\\n\" << text << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 07/Soln7_09B.cpp",
    "content": "// Exercise 7-9. Remove the begin letter of the tautogram (the hard way)\n\n#include <iostream>\n#include <string>\n#include <cctype>\n\nint main()\n{\n  std::string text;      // The text to be checked\n  std::cout << \"Enter some text terminated by *:\\n\";\n  std::getline(std::cin, text, '*');\n\n  const auto whitespace{ \" \\t\\n\\r\\f\\v\" };  // Can be solved using std::isspace() as well...\n\n  const size_t first_letter_index{ text.find_first_not_of(whitespace) };\n  if (first_letter_index == std::string::npos)\n  {\n    // Is an empty string a tautogram? Let's not go there.\n    return 0;\n  }\n\n  const char start_letter{ static_cast<char>(std::toupper(text[first_letter_index])) };\n  bool tautogram{ true };\n\n  for (size_t start_current_word{ first_letter_index };;)  // Use an indefinite loop (see the break; statements)\n  {\n    const size_t next_space_index{ text.find_first_of(whitespace, start_current_word) };\n    if (next_space_index == std::string::npos)\n    {\n      break;\n    }\n\n    const size_t next_letter_index{ text.find_first_not_of(whitespace, next_space_index) };\n    if (next_letter_index == std::string::npos)\n    {\n      break;\n    }\n\n    if (std::toupper(text[next_letter_index]) != start_letter)\n    {\n      tautogram = false;\n      break;\n    }\n\n    start_current_word = next_letter_index;\n  }\n  \n  std::cout << \"The text that you entered is \" << (tautogram ? \"\" : \"not \") << \"a tautogram.\\n\";\n  if (tautogram)\n  {\n    std::cout << \"All words start with the letter \" << start_letter << \".\\n\";\n\n    std::string text_without_start_letter;\n    for (char c : text)\n    {\n      if (std::toupper(c) != start_letter)\n      {\n        text_without_start_letter.push_back(c);\n      }\n    }\n\n    std::cout << \"After removing this letter, the text becomes as follows:\\n\" << text_without_start_letter << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 08/Soln8_01.cpp",
    "content": "// Exercise 8-1 Reading  and validating a date of birth. \n// As always, there are many ways of doing this!\n#include <iostream>\n#include <format>\n#include <string>\n\nint validate_input(int lower, int upper, const std::string& description);\nint year();\nint month();\nint date(int month_value, int year_value);\nstd::string ending(int date_day);\n\nint main()\n{\n  std::cout << \"Enter your date of birth.\" << std::endl;\n  int date_year {year()};\n  int date_month {month()};\n  int date_day {date(date_month, date_year)};\n\n  std::string months[]  {\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\",\n                         \"August\", \"September\", \"October\", \"November\", \"December\"  };\n\n  std::cout << std::endl;\n  std::cout << \n    std::format(\"You were born on the {} of {}, {}.\", \n      std::to_string(date_day) + ending(date_day), \n      months[date_month - 1], \n      date_year\n    ) << std::endl;\n}\n\n// Reads an integer that is between lower and upper inclusive\nint validate_input(int lower, int upper, const std::string& description)\n{\n  int data {};\n  std::cout << std::format(\"Please enter {} from {} to {}: \", description, lower, upper);\n  std::cin >> data;\n  while (data < lower || data > upper)\n  {\n    std::cout << \"Invalid entry; please re-enter \" << description << \": \";\n    std::cin >> data;\n  }\n  return data;\n}\n\n// Reads the year\nint year()\n{\n  const int low_year {1870};         // Program only works for folks under 150 years old \n  const int high_year {2020};        // and those already born...\n  return validate_input(low_year, high_year, \"a year\");\n}\n\n// Reads the month\nint month()\n{\n  const int low_month {1};\n  const int high_month {12};\n  return validate_input(low_month, high_month, \"a month number\");\n}\n\n// Reads in the date in the given month and year\nint date(int month_number, int year)\n{\n  const int date_min {1};\n  const int feb {2};\n\n  // Days in month:            Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec\n  static const int date_max[]  {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};\n  // With the above array declared as static, it will only be created the first\n  // time the function is called. Of course, this doesn't save anything in this \n  // example as we only call it once...\n\n  // Feb has 29 days in a leap year. A leap year is a year that is divible by 4\n  // except years that are divisible by 100 but not divisible by 400\n  if (month_number == feb && year % 4 == 0 && !(year % 100 == 0 && year % 400 != 0))\n    return validate_input(date_min, 29, \"a date\");\n  else\n    return validate_input(date_min, date_max[month_number - 1], \"a date\");\n}\n\n// Select the ending of the ordinal day number\nstd::string ending(int date_day)\n{\n  if (date_day == 1 || date_day == 21 || date_day == 31)\n    return \"st\";\n  else if (date_day == 2 || date_day == 22)\n    return \"nd\";\n  else if (date_day == 3 || date_day == 23)\n    return \"rd\";\n  else\n    return \"th\";\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 08/Soln8_02.cpp",
    "content": "// Exercise 8-2 Reversing the order of a string of characters. \n/******************************************************************\nThe reverse() function works with an argument of type string, or a\nC-style string terminated with '\\0'.\n*******************************************************************/\n#include <iostream>\n#include <string>\n\nstd::string reverse(std::string str);\n\nint main()\n{\n  std::string sentence;\n  std::cout << \"Enter a sequence of characters, then press 'Enter': \" << std::endl;\n  getline(std::cin, sentence);\n\n  std::cout << \"\\nYour sequence in reverse order is:\\n\";\n  std::cout << reverse(sentence) << std::endl;\n\n  std::cout << \"\\nHere is a demonstration of reverse() working with a C-style string:\\n\";\n\n  char stuff[] {\"abcdefg\"};                      // C-style string\n  std::cout << \"\\nThe original string is: \\\"\" << stuff << \"\\\"\"\n            << \"\\nReversed it becomes: \\\"\" << reverse(stuff) << \"\\\"\" << std::endl;\n}\n\n// Reverse a string in place\n// The code here is working with a copy of the argument\n// so the original is not affected.\nstd::string reverse(std::string str)\n{\n  const size_t length {str.length()};\n  for (size_t i {}; i < length / 2; ++i)\n  {\n    char temp = str[i];\n    str[i] = str[length - i - 1];\n    str[length - i - 1] = temp;\n  }\n  return str;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 08/Soln8_03.cpp",
    "content": "// Exercise 8_3 Checking the number of arguments entered at the command line. \n#include <iostream>\n\nint main(int numArguments, char* arguments[])\n{\n  switch (numArguments - 1)\n  {\n  case 2: case 3: case 4:\n    for (size_t i {1}; i < numArguments; ++i)\n      std::cout << \"Argument \" << i << \" is \" << arguments[i] << std::endl;\n    break;\n  default:\n    std::cout << \"You entered the incorrect number of arguments.\\n\"\n              << \"Please enter 2, 3 or 4 arguments. \" << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 08/Soln8_04.cpp",
    "content": "// Exercise 8_4 An overloaded plus() function. \n#include <iostream>\n#include <string>\n\nint plus(int a, int b);\ndouble plus(double x, double y);\nstd::string plus(const std::string& s1, const std::string& s2);\n\nint main()\n{\n  const int n {plus(3, 4)};\n  std::cout << \"plus(3, 4) returns \" << n << std::endl;\n  \n  const double d {plus(3.2, 4.2)};\n  std::cout << \"plus(3.2, 4.2) returns \" << d << std::endl;\n  \n  const std::string s {plus(\"he\", \"llo\")};\n  std::cout << \"plus(\\\"he\\\", \\\"llo\\\") returns \" << s << std::endl;\n  \n  const std::string s1 {\"aaa\"};\n  const std::string s2 {\"bbb\"};\n  const std::string s3 {plus(s1, s2)};\n  std::cout << \"With s1 as \" << s1 << \" and s2 as \" << s2 << std::endl;\n  std::cout << \"plus(s1, s2) returns \" << s3 << std::endl;\n\n  /*\n  const auto d {plus(3, 4.2)};\n  This won't compile because there is more than one overloaded plus() function for the arguments.\n  The compiler will not choose so there must be a unique match with a function signature.\n  */\n}\n\n// Adding integer values\nint plus(int a, int b)\n{\n  return a + b;\n}\n\n// Adding floating-point values\ndouble plus(double x, double y)\n{\n  return x + y;\n}\n\n// Adding strings\nstd::string plus(const std::string& s1, const std::string& s2)\n{\n  return s1 + s2;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 08/Soln8_05.cpp",
    "content": "// Exercise 8_5 Listing prime numbers\n#include <iostream>\n#include <format>\n#include <vector>\n#include <cmath>    // for std::sqrt()\n\nbool isPrime(unsigned number);\n\n// Option 1: return vector<>\n// Remember: starting with C++11, returning a vector is efficient. \n// In modern C++, this is therefore the recommended approach.\nstd::vector<unsigned> generateNumbers(unsigned to, unsigned from = 1);\nstd::vector<unsigned> filterPrimeNumbers(const std::vector<unsigned>& numbers);\n\n/* \n// Option 2: vector<> output variables (not implemented)\n// This is the traditional approach. \n// In modern C++, returning using return value is recommended.\nvoid generateNumbers(std::vector<unsigned>& output, unsigned to, unsigned from = 1);\nvoid filterPrimeNumbers(std::vector<unsigned>& output, const std::vector<unsigned>& numbers);\n*/\n\nint main()\n{\n  unsigned user_number{};\n  std::cout << \"Would you be so kind as to enter a number? \" << std::endl;\n  std::cin >> user_number;\n  \n  const auto numbers{ generateNumbers(user_number) };\n  const auto primes{ filterPrimeNumbers(numbers) };\n  \n  unsigned count{};\n  for (auto& prime : primes)\n  {\n    std::cout << std::format(\"{:6}\", prime);\n    if (++count % 15 == 0)\n      std::cout << '\\n';\n  }\n  \n  std::cout << std::endl;\n}\n\n/* \n  The sqrt() in the for loop below is not required. \n  The following loop would be equally correct, just a bit slower:\n  \n  for (unsigned i = 2; i < number; ++i)\n  {\n    ...\n  }\n  \n  It is a quite common optimisation though to stop testing at \n  the square root of the number. Think about why this is correct!\n*/\nbool isPrime(unsigned number)\n{\n  // a prime number is a natural number strictly greater than 1...\n  if (number <= 1) return false;\n  \n  // ...and with no positive divisors other than 1 and itself\n  for (unsigned i{ 2 }; i < std::sqrt(number); ++i)\n  {\n    if (number % i == 0)\n    {\n      return false;\n    }\n  }\n  \n  return true;\n}\n\nstd::vector<unsigned> generateNumbers(unsigned to, unsigned from)\n{\n  std::vector<unsigned> result;\n  result.reserve(to - from + 1);\n  for (unsigned i{ from }; i <= to; ++i)\n    result.push_back(i);\n  return result;\n}\n\nstd::vector<unsigned> filterPrimeNumbers(const std::vector<unsigned>& numbers)\n{\n  std::vector<unsigned> result;\n  for (auto number : numbers)\n  {\n    if (isPrime(number))\n      result.push_back(number);\n  }\n  return result;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 08/Soln8_06.cpp",
    "content": "// Exercise 8_6 Computing grade statistics\n/*\n  This is a bigger excercise, and thus many variations will be valid and correct.\n  The focus here isn't on performance, it's on writing and calling functions.\n  Main thing is that you:\n    (1) got the parameter types right---mostly pass-by-reference-to-const \n        for the input parameters, except for sort() which modifies its argument.\n    (2) made sure that the program does something correctly for empty grade lists,\n        small grade lists (< 5 values), and for grade lists of both odd and even size.\n  \n  Some things worth noticing in our solution:\n    - we overloaded the recursive sort() function by adding a helper function \n      that users can call without having to know what the second and third parameters are,\n      and without having to think about the empty input case. \n      This is common with recursive algorithms: the interface that users use \n      will often not contain the actual recursive function.\n    - we defined NOT_AVAILABLE equal to std::numeric_limits<unsigned>::max() \n      (equivalent to static_cast<unsigned>(-1))\n      to encode missing values in case there are less than 5 inputs,\n      and used NaN values elsewhere in case the user enters no value at all.\n      Other solutions for the former could've been signed values,\n      or in fact any number larger than 100.\n      In Chapter 9 you will learn about std::optional<>\n      which allows you to handle such \"not available\" or \"undefined\" cases more elegantly, though.\n*/\n#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>    // for std::sqrt() and std::isnan()\n#include <limits>   // for std::numeric_limits's max() and quiet_nan()\n\nvoid sort(std::vector<unsigned>& numbers);\n\nvoid getHighest(const std::vector<unsigned>& sortedNumbers, unsigned(&highest)[5]);\nvoid getLowest(const std::vector<unsigned>& sortedNumbers, unsigned(&lowest)[5]);\n\ndouble computeAverage(const std::vector<unsigned>& numbers);\ndouble computeMedian(const std::vector<unsigned>& numbers);\ndouble computeStandardDeviation(const std::vector<unsigned>& numbers);\ndouble computeVariance(const std::vector<unsigned>& numbers);\n\nvoid printNumber(const std::string& label, double number);\nvoid printNumbers(const std::string& label, const unsigned(&numbers)[5]);\n\nconst unsigned NOT_AVAILABLE = std::numeric_limits<unsigned>::max();\n\nint main()\n{\n  std::vector<unsigned> grades;\n\n  std::cout << \"Please enter a number of grades (0-100), terminated by a negative one:\" << std::endl;\n  while (true)\n  {\n    int number{};\n    std::cin >> number;\n    if (number < 0)\n      break;\n    else if (number > 100)\n      std::cout << \"Only numbers < 100, please...\" << std::endl;\n    else\n      grades.push_back(number);\n  }\n\n  sort(grades);\n\n  // Note: thruth be told, this is based on an old solution.\n  // It would be better and/or easier \n  //    a) to use std::array<> instead of C-style arrays; and\n  //    b) to return the values requested rather than using output parameters\n  // Perhaps you can improve our solution accordingly?\n  unsigned highest[5]{};\n  unsigned lowest[5]{};\n\n  getHighest(grades, highest);\n  getLowest(grades, lowest);\n\n  printNumbers(\"Five highest grades\", highest);\n  printNumbers(\"Five lowest grades\", lowest);\n  printNumber(\"The grade average\", computeAverage(grades));\n  printNumber(\"The median grade\", computeMedian(grades));\n  printNumber(\"The standard deviation of the grades\", computeStandardDeviation(grades));\n  printNumber(\"The variance of the grades\", computeVariance(grades));\n}\n\n// Swap numbers at position first with address at position second\nvoid swap(std::vector<unsigned>& numbers, size_t first, size_t second)\n{\n  auto temp{ numbers[first] };\n  numbers[first] = numbers[second];\n  numbers[second] = temp;\n}\n\n// Recursive helper function to sort numbers in ascending sequence\n// Numbers to be sorted are from words[start] to words[end]\nvoid sort(std::vector<unsigned>& numbers, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle of the [start, end] range to partition\n  swap(numbers, start, (start + end) / 2); // Swap middle number with start\n\n  // Check values against chosen word\n  size_t current{ start };\n  for (size_t i{ start + 1 }; i <= end; i++)\n  {\n    if (numbers[i] < numbers[start])   // Is word less than chosen value?\n      swap(numbers, ++current, i);     // Yes, so swap to the left\n  }\n\n  swap(numbers, start, current);       // Swap the chosen value with the last swapped number\n\n  if (current > start) sort(numbers, start, current - 1);  // Sort left subset if exists\n  if (end > current + 1) sort(numbers, current + 1, end);  // Sort right subset if exists\n}\n\n// Sort numbers in ascending sequence\nvoid sort(std::vector<unsigned>& numbers)\n{\n  if (!numbers.empty())\n    sort(numbers, 0, numbers.size() - 1);\n}\n\nvoid getHighest(const std::vector<unsigned>& sortedNumbers, unsigned(&highest)[5])\n{\n  const auto numHighest{ static_cast<int>(std::size(highest)) };\n\n  for (int i{}; i < numHighest; ++i)\n  {\n    const int numberIndex{ static_cast<int>(sortedNumbers.size()) - numHighest + i };\n    if (numberIndex >= 0)\n      highest[i] = sortedNumbers[numberIndex];\n    else\n      highest[i] = NOT_AVAILABLE;\n  }\n}\n\nvoid getLowest(const std::vector<unsigned>& sortedNumbers, unsigned(&lowest)[5])\n{\n  for (size_t i{}; i < std::size(lowest); ++i)\n  {\n    if (i < sortedNumbers.size())\n      lowest[i] = sortedNumbers[i];\n    else\n      lowest[i] = NOT_AVAILABLE;\n  }\n}\n\ndouble computeAverage(const std::vector<unsigned>& numbers)\n{\n  if (numbers.empty())\n    return std::numeric_limits<double>::quiet_NaN();\n\n  double average{};\n  for (auto& number : numbers)\n    average += number;\n  return average / numbers.size();\n}\n\ndouble computeMedian(const std::vector<unsigned>& numbers)\n{\n  if (numbers.empty())\n    return std::numeric_limits<double>::quiet_NaN();\n\n  const auto numNumbers{ numbers.size() };\n  const auto middleIndex{ numNumbers / 2 };\n  if (numNumbers % 2)\n  {\n    return numbers[middleIndex];\n  }\n  else\n  {\n    return (numbers[middleIndex] + numbers[middleIndex - 1]) / 2.0;\n  }\n}\n\ndouble computeStandardDeviation(const std::vector<unsigned>& numbers)\n{\n  if (numbers.empty())\n    return std::numeric_limits<double>::quiet_NaN();\n\n  const double average{ computeAverage(numbers) };\n  double sum{};\n  for (auto& number : numbers)\n    sum += (number - average) * (number - average);\n  return std::sqrt(sum / numbers.size());\n}\n\ndouble computeVariance(const std::vector<unsigned>& numbers)\n{\n  if (numbers.empty())\n    return std::numeric_limits<double>::quiet_NaN();\n\n  const double standardDeviation{ computeStandardDeviation(numbers) };\n  return standardDeviation * standardDeviation;\n}\n\nvoid printNumber(const std::string& label, double number)\n{\n  std::cout << label << \": \";\n\n  if (std::isnan(number))\n    std::cout << \"n/a\";\n  else\n    std::cout << number;\n\n  std::cout << std::endl;\n}\n\nvoid printNumbers(const std::string& label, const unsigned(&numbers)[5])\n{\n  std::cout << label << \": \";\n\n  for (const auto number : numbers)\n  {\n    if (number != NOT_AVAILABLE)\n      std::cout << number << ' ';\n  }\n\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 08/Soln8_07.cpp",
    "content": "// Exercise 8-7 Computing Fibinacci numbers recursively. \n// Main thing to realise is that the recursion needs two base cases.\n// Key is also to use unsigned values (function would fail for negative numbers)\n// and not to forget about zero either (using n == 1 and n == 2 as base cases \n// would mean trouble if n == 0 is passed)\n#include <iostream>\n\nunsigned long long fib(size_t n);\n\nint main()\n{\n  size_t num{};\n  std::cout << \"Good day, master. How many Fibonacci numbers shall I compute today?\" << std::endl;\n  std::cin >> num;\n  \n  for (size_t i{1}; i <= num; ++i)\n     std::cout << \"fib(\" << i << \") = \" << fib(i) << '\\n';\n}\n\nunsigned long long fib(size_t n)\n{\n  switch (n)\n  {\n    case 0:  return 0;\n    case 1:  return 1;\n    default: return fib(n-2) + fib(n-1);\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 08/Soln8_07A.cpp",
    "content": "// Exercise 8-7 Computing Fibinacci numbers iteratively. \n// On most systems (it depends on sizeof(unsigned long long)),\n// you can correctly compute up to 93 Fibonacci numbers with this program.\n#include <iostream>\n\nunsigned long long fib(size_t n);\n\nint main()\n{\n  size_t num{};\n  std::cout << \"Good day, master. How many Fibonacci numbers shall I compute today?\" << std::endl;\n  std::cin >> num;\n  \n  for (size_t i{1}; i <= num; ++i)\n     std::cout << \"fib(\" << i << \") = \" << fib(i) << '\\n';\n}\n\nunsigned long long fib(size_t n)\n{\n\t// Initialise fib(i) and fib(i+1) for the first iteration of the loop where i == 0\n\tunsigned long long fib_i{0};         // fib(i)   = fib(0) = 0\n\tunsigned long long fib_i_1{1};       // fib(i+1) = fib(1) = 1\n\t\n\tfor (size_t i{}; i < n; ++i)\n\t{\n\t\tauto fib_i_2{ fib_i + fib_i_1 };   // fib(i+2) = fib(i) + fib(i+1)\n\t\t\n\t\t// Get ready for the next iteration (mind the order!):\n\t\tfib_i   = fib_i_1;\n\t\tfib_i_1 = fib_i_2;\n\t}\n\t\n\t// At the end of the loop, i was equal to n, so fib(i) == fib(n), which is what we needed\n\treturn fib_i;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 08/Soln8_08.cpp",
    "content": "// Exercise 8_8 More efficient recursive version of function for x to the power n, n positive or negative\n// Based on Ex8_17.cpp\n#include <iostream>\n#include <iomanip>\n\nlong double power(double x, int n);\n\nint main()\n{\n  for (int i {-3}; i <= 3; ++i)     // Calculate powers of 8 from -3 to +3\n    std::cout << std::setw(10) << power(8.0, i);\n\n  std::cout << std::endl;\n}\n\n// Recursive function to calculate x to the power n\nlong double power(double x, int n)\n{\n  if (n == 0)     return 1.0;\n  else if (n < 0) return 1.0 / power(x, -n);\n  else if (n % 2) return x * power(x, n - 1);     // n is odd\n  \n  // If we make it this far, n > 0 and even\n  const auto y{ power(x, n / 2) };\n  return y * y;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 08/Soln8_09.cpp",
    "content": "// Exercise 8_9 Count the number of multiplications performed by \n// the divide and conquer power() function of Soln8_08.cpp\n#include <iostream>\n#include <iomanip>\n\nlong double power(double x, int n);\n\nint main()\n{\n  std::cout << power(1.5, 1000) << std::endl;\n}\n\ninline auto mult(long double l, long double r)\n{\n  static size_t count{};\n  std::cout << ++count << \" multiplications\" << std::endl;\n  return l * r;\n}\n\n// Recursive function to calculate x to the power n\nlong double power(double x, int n)\n{\n  if (n == 0)     return 1.0;\n  else if (n < 0) return 1.0 / power(x, -n);\n  else if (n % 2) return mult(x, power(x, n - 1));     // x is odd\n  \n  // If we make it this far, x > 0 and even\n  const auto y{ power(x, n / 2) };\n  return mult(y, y);\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 09/Soln9_01.cpp",
    "content": "// Exercise 9-1 Working with std::string_view<>\n#include <optional>     // std::optional<> is defined in the <optional> module\n#include <iostream>\n#include <string_view>\n\nstd::optional<size_t> find_last(\n  std::string_view string, char to_find,\n  std::optional<size_t> start_index = std::nullopt); // or: ... start_index = {});\n\nint main()\n{\n  const auto string{ \"Growing old is mandatory; growing up is optional.\" };\n\n  const std::optional<size_t> found_a{ find_last(string, 'a') };\n  if (found_a)\n    std::cout << \"Found the last a at index \" << *found_a << std::endl;\n\n  const auto found_b{ find_last(string, 'b') };\n  if (found_b.has_value())\n    std::cout << \"Found the last b at index \" << found_b.value() << std::endl;\n\n  // following line gives an error (cannot convert std::optional<size_t> to size_t)\n  // const size_t found_c{ find_last(string, 'c') }; \n\n  const auto found_early_i{ find_last(string, 'i', 10) };\n  if (found_early_i != std::nullopt)\n    std::cout << \"Found an early i at index \" << *found_early_i << std::endl;\n}\n\nstd::optional<size_t> find_last(std::string_view string, char to_find,\n  std::optional<size_t> start_index)\n{\n  // code below will not work for empty strings  \n  if (string.empty())\n    return std::nullopt;         // or: 'return std::optional<size_t>{};'\n                                 // or: 'return {};'\n  // determine the starting index for the loop that follows:\n  size_t index{ start_index.value_or(string.size() - 1) };\n\n  while (true)  // never use while (index >= 0) here, as size_t is always >= 0!\n  {\n    if (string[index] == to_find) return index;\n    if (index == 0) return std::nullopt;\n    --index;\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 09/Soln9_02.cpp",
    "content": "// Exercise 9-2 Working with std::string_view<> and std::span<>\n#include <iostream>\n#include <format>\n#include <string_view>\n#include <span>\n\n// The function prototype including defaults for parameters\nvoid show_data(\n  std::span<const int> data,\n  std::string_view title = \"Data Values\",\n  size_t width = 10, size_t perLine = 5);\n\n// Extra overload to output a single value (.\nvoid show_data(\n  int data,\n  std::string_view title = \"Data Values\",\n  size_t width = 10);\n\nint main()\n{\n  int samples[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };\n\n  int dataItem{ -99 };\n  show_data({ &dataItem, 1 });  // Call original function directly\n\n  dataItem = 13;\n  show_data(dataItem, \"Unlucky for some!\"); // Use extra overload\n\n  show_data(samples);\n  show_data(samples, \"Samples\");\n  show_data(samples, \"Samples\", 6);\n  show_data(samples, \"Samples\", 8, 4);\n}\n\nvoid show_data(\n  std::span<const int> data, \n  std::string_view title,\n  size_t width, size_t perLine)\n{\n  std::cout << title << std::endl;    // Display the title\n\n  // Output the data values\n  for (size_t i{}; i < data.size(); ++i)\n  {\n    std::cout << std::format(\"{:{}}\", data[i], width); // Display a data item\n    if ((i + 1) % perLine == 0)                        // Newline after perLine values\n      std::cout << '\\n';\n  }\n  std::cout << std::endl;\n}\n\nvoid show_data(int data, std::string_view title, size_t width)\n{\n  show_data({ &data, 1 }, title, width);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 09/Soln9_03.cpp",
    "content": "// Exercise 9.3. Using vocabulary types \n// Your solution should use all types you learned about in Chapter 9!\n#include <iostream>\n#include <format>\n#include <string_view>\n#include <span>\n#include <optional>\n\nvoid show_data(std::span<const double> data, \n               std::string_view title = \"Data Values\",\n               size_t width = 10, size_t perLine = 5);\nstd::optional<double> largest(std::span<const double> data);\nstd::optional<double> smallest(std::span<const double> data);\nstd::span<double> shift_range(std::span<double> data, double delta);\nstd::span<double> scale_range(std::span<double> data, double divisor);\nstd::span<double> normalize_range(std::span<double> data);\n\nint main()\n{\n  double samples[] {\n                     11.0,  23.0,  13.0,  4.0,\n                     57.0,  36.0, 317.0, 88.0,\n                      9.0, 100.0, 121.0, 12.0\n                   };\n\n  show_data(samples, \"Original Values\");        // Output original values\n  normalize_range(samples);                     // Normalize the values\n  show_data(samples, \"Normalized Values\", 12);  // Output normalized values\n}\n\n// Outputs an array of double values\nvoid show_data(std::span<const double> data,\n               std::string_view title, size_t width, size_t perLine)\n{\n  std::cout << title << std::endl;  // Display the title\n\n  // Output the data values\n  for (size_t i {}; i < data.size(); ++i)\n  {\n    // Display a data item (uses a dynamic field width: see Chapter 7)\n    std::cout << std::format(\"{:{}.6g}\", data[i], width); \n    if ((i + 1) % perLine == 0)     // Newline after perLine values\n      std::cout << '\\n';\n  }\n  std::cout << std::endl;\n}\n\nstd::optional<double> smallest(std::span<const double> data)\n{\n  if (data.empty()) return {};     // There is no smallest in an empty sequence\n\n  size_t index_min {};\n  for (size_t i {1}; i < data.size(); ++i)\n    if (data[index_min] > data[i])\n      index_min = i;\n\n  return data[index_min];\n}\n\nstd::span<double> shift_range(std::span<double> data, double delta)\n{\n  for (size_t i {}; i < data.size(); ++i)\n    data[i] += delta;\n  return data;\n}\n\nstd::optional<double> largest(std::span<const double> data)\n{\n  if (data.empty()) return {};    // There is no largest in an empty array\n\n  size_t index_max {};\n  for (size_t i {1}; i < data.size(); ++i)\n    if (data[index_max] < data[i])\n      index_max = i;\n\n  return data[index_max];\n}\n\nstd::span<double> scale_range(std::span<double> data, double divisor)\n{\n  if (!divisor) return data;     // Do nothing for a zero divisor\n\n  for (size_t i{}; i < data.size(); ++i)\n    data[i] /= divisor;\n  return data;\n}\n\nstd::span<double> normalize_range(std::span<double> data)\n{\n  shift_range(data, -(*smallest(data)));\n  return scale_range(data, *largest(data));\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 09/Soln9_04.cpp",
    "content": "// Exercise 9-4. Using std::optional<>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <array>\n#include <span>\n#include <optional>\n\n// Function prototypes\nstd::optional<double> largest(std::span<const double> data);\nstd::optional<int> largest(std::span<const int> data);\nstd::optional<std::string> largest(std::span<const std::string> words);\n\nint main()\n{\n  const double array[]{ 1.5, 44.6, 13.7, 21.2, 6.7 };\n  const std::vector numbers{ 15, 44, 13, 21, 6, 8, 5, 2 };\n  const std::vector data{ 3.5, 5.0, 6.0, -1.2, 8.7, 6.4 };\n  const std::array array_data{ 3.5, 5.0, 6.0, -1.2, 8.7, 6.4 }; // Throwing in an std::array for good measure\n  const std::vector<std::string> names{ \"Charles Dickens\", \"Emily Bronte\",\n                                  \"Jane Austen\", \"Henry James\", \"Arthur Miller\" };\n  std::cout << \"The largest of array is \" << *largest(array) << std::endl;            // Crashes if nullopt is returned\n  std::cout << \"The largest of numbers is \" << largest(numbers).value() << std::endl; // Throws exception (see Chapter 16) for nullopt\n  std::cout << \"The largest of data is \" << largest(data).value() << std::endl;\n  std::cout << \"The largest of array_data is (also) \" << *largest(array_data) << std::endl;\n  std::cout << \"The largest of names is \" << largest(names).value_or(\"<null>\") << std::endl;\n}\n\n// Finds the largest of a span of values\nstd::optional<double> largest(std::span<const double> data)\n{\n  if (data.empty()) return {};  // Or return std::nullopt;\n\n  double max{ data[0] };\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of int values\nstd::optional<int> largest(std::span<const int> data)\n{\n  if (data.empty()) return {};  // Or return std::nullopt;\n\n  int max{ data[0] };\n  for (auto value : data)\n    if (max < value) max = value;\n  return max;\n}\n\n// Finds the largest of a vector of string objects\nstd::optional<std::string> largest(std::span<const std::string> words)\n{\n  if (words.empty()) return {};  // Or return std::nullopt;\n\n  std::string max_word{ words[0] };\n  for (const auto& word : words)\n    if (max_word < word) max_word = word;\n  return max_word;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 09/Soln9_05.cpp",
    "content": "// Exercise 9-5. Using fixed-size std::span<>\n#include <iostream>\n#include <span>\n\ndouble average10(std::span<const double, 10> data);        // Function prototype\n\nint main()\n{\n  double values[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\n  // double values[]{ 1.0, 2.0, 3.0 };           // Only three values!!!\n  std::cout << \"Average = \" << average10(values) << std::endl;\n}\n\n// Function to compute an average\ndouble average10(std::span<const double, 10> data)\n{\n  double sum{};               // Accumulate total in here\n  for (double val : data)\n    sum += val;               // Sum array elements\n  return sum / data.size();   // Return average\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 09/Soln9_06.cpp",
    "content": "// Exercise 9-6. Passing a vector to a fixed-size std::span<>\n#include <iostream>\n#include <vector>\n#include <span>\n\ndouble average10(std::span<const double, 10> data);        // Function prototype\n\nint main()\n{\n  std::vector values { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\n  // double values[]{ 1.0, 2.0, 3.0 };           // Only three values!!!\n  std::cout << \"Average = \" \n    << average10(std::span<const double, 10>{ values.data(), values.size() }) << std::endl;\n}\n\n// Function to compute an average\ndouble average10(std::span<const double, 10> data)\n{\n  double sum{};               // Accumulate total in here\n  for (double val : data)\n    sum += val;               // Sum array elements\n  return sum / data.size();   // Return average\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 10/Soln10_01.cpp",
    "content": "// Exercise 10-1.cpp\n// Create a function template for my_clamp(), \n// a template that produces functions to clamp values to a given interval.\n// Different variations are possible, but we opted for the same as in the Standard Library:\n// namely one where all three arguments are of the same type, and passed by reference-to-const.\n#include <iostream>\n#include <format>\n#include <string>\n\n/*\n  Caution: the actual std::clamp() function uses a different argument order.\n  Where the exercise suggests:\n    my_clamp(value, low, high)\n  but for the Standard Library function the order is as follows:\n    std::clamp(low, value, high)\n  This solution does as instructed, but keep this in mind if ever using std::clamp()!\n */\n\ntemplate<typename T> \nconst T& my_clamp(const T& value, const T& low, const T& high);    // Function template prototype\n\nint main() \n{\n  std::cout << \"2.0 clamped to interval [1.5, 2.5] is \" << my_clamp(2.0, 1.5, 2.5) << std::endl;\n  std::cout << \"5.0 clamped to interval [1.5, 2.5] is \" << my_clamp(5.0, 1.5, 2.5) << std::endl;\n\n  int big_int {17011983}, small_int {10}, negative_int {-123};\n  std::cout \n    << std::format(\"{} clamped to the interval [{},{}] is {}\", \n          negative_int, small_int, big_int, my_clamp(negative_int, small_int, big_int))\n    << std::endl;\n\n  // And now for a less useful example...\n  std::string a_string {\"A\"}, z_string {\"Z\"};\n  std::string shakespeare{\"It is not in the stars to hold our destiny but in ourselves\"};\n  std::cout << \"William Shakespeare's quote clamped to [A-Z] is: \" \n            << my_clamp(shakespeare, a_string, z_string) << std::endl;\n}\n\n// Template for functions to clamp a value to a closed interval\ntemplate<typename T> \nconst T& my_clamp(const T& value, const T& low, const T& high)\n{\n  if (value < low) return low;\n  else if (value < high) return value;\n  else return high;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 10/Soln10_02.cpp",
    "content": "// Exercise 10-2.cpp\n// Using auto instead of std::string resulted in a type change for a_string and z_string:\n// they now both have the type const char[], the type given to string literals.\n// If you instantiate the original template for this type, it therefore becomes\n//   \n//   const char* larger(const char* a, const char* b)\n//   {\n//     return a > b? a : b;\n//   }\n//\n// This function now compares the pointers of both string literals rather than the \n// string literals themselves. To solve this, you should create a specialisation \n// for const char* arrays. \n\n#include <iostream>\n#include <string_view>\n\ntemplate<typename T>                     // Function template prototype\nT larger(T a, T b);                      \n\ntemplate<>                               // Function template specialization prototype\nconst char* larger(const char* a, const char* b);  \n\nint main() \n{\n  std::cout << \"Larger of 1.5 and 2.5 is \" << larger(1.5, 2.5) << std::endl;\n  std::cout << \"Larger of 3.5 and 4.5 is \" << larger(3.5, 4.5) << std::endl;\n\n  const int big_int {17011983}, small_int {10};\n  std::cout << \"Larger of \" << big_int << \" and \" << small_int << \" is \"\n            << larger(big_int, small_int) << std::endl;\n\n  const auto a_string {\"A\"}, z_string {\"Z\"};\t\t// now string literals (type const char[])!\n  std::cout << \"Larger of \\\"\" << a_string << \"\\\" and \\\"\" << z_string << \"\\\" is \"\n            << '\"' << larger(a_string, z_string) << '\"' << std::endl;\n}\n\n// Template for functions to return the larger of two values\ntemplate <typename T>\nT larger(T a, T b)\n{\n  return a > b? a : b;\n}\n\n// Template specialization for returning the larger of two character arrays \n// (such as string literals).\n//\n// Note: instead of std::string_view, you could've used std::string as well,\n// but that would've involved copying the character arrays. \n// std::string_view is therefore the preferred C++ type to use here.\ntemplate<>\nconst char* larger(const char* a, const char* b)\n{\n  return std::string_view{a} > std::string_view{b}? a : b;\n}\n\n/*\n// Template specialization for returning the larger of two character arrays \n// (such as string literals).\n// Alternative implementation using the C-style function strcmp() \n// (you'll need to include the <cstring> header to make this compile).\n// The strcmp() function returns a value larger than zero if a > b; \n// zero if both arguments are equal, a negative value if a < b.\ntemplate<>\nconst char* larger(const char* a, const char* b)\n{\n  return std::strcmp(a, b) > 0;\n}\n*/"
  },
  {
    "path": "Exercises/NoModules/Chapter 10/Soln10_03.cpp",
    "content": "// Exercise 10-3.cpp\n// Defining a function template for adding numbers, \n// and an overload that works for pointer types.\n// Extra: also make plus() work with string literals...\n#include <iostream>\n#include <string>\n#include <string_view>\n\ntemplate <typename T>\nT plus(const T& a, const T& b)\n{\n    return a + b;\n}\n\n// Overload with another template for pointer types\ntemplate <typename T>\nT plus(const T* a, const T* b)\n{\n    return *a + *b;\n}\n\n// Result cannot be const char*, but has to be a new object.\n// Function template specialization can thus not be used either\n// (but that is, as you know, never a good idea anyway!).\nstd::string plus(const char* a, const char* b)\n{\n  return std::string{ a } + b;\n}\n\nint main()\n{\n    int n{ plus(3, 4) };\n    std::cout << \"plus(3, 4) returns \" << n << std::endl;\n    \n    double d{ plus(3.2, 4.2) };\n    std::cout << \"plus(3.2, 4.2) returns \" << d << std::endl;\n    \n    std::string s1{ \"aaa\" };\n    std::string s2{ \"bbb\" };\n    auto s3{ plus(s1, s2) };\n    std::cout << \"With s1 as \" << s1 << \" and s2 as \" << s2 << std::endl;\n    std::cout << \"plus(s1, s2) returns \" << s3 << std::endl;\n\n    // The extra part:\n    std::string s{ plus(\"he\", \"llo\") };\n    std::cout << \"plus(\\\"he\\\", \\\"llo\\\") returns \" << s << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 10/Soln10_04.cpp",
    "content": "// Exercise 10-4.cpp\n// Your very own interpretation of std::size()\n#include <iostream>\n#include <array>\n#include <vector>\n#include <span>\n\n// Look ma, no sizeof()!\ntemplate <typename T, size_t N>\nsize_t my_size(const T (&array)[N]) { return N; }\n\n// Overload with two other templates for std::vector<> and array<> \ntemplate <typename T>\nsize_t my_size(const std::vector<T>& vector) { return vector.size(); }\n\ntemplate <typename T, size_t N>\nsize_t my_size(const std::array<T,N>& array) { return N; }  // or array.size();\n\n/*\nInstead of the latter two templates, you can create one template that would make my_size \naccept any argument and call size() on it. This will make it work\nfor std::array<> and std::vector<>, as well as std::string and many other containers:\n\ntemplate <typename Collection>\nsize_t my_size(const Collection& collection) { return collection.size(); }\n\nPotential downside is that this will instantiate for int and double type arguments\nas well, which may result in somewhat verbose compiler errors.\nThis issue can easily be fixed using a requires clause, though (see Chapter 21).\n\ntemplate <typename Collection> requires requires (const Collection c) { c.size(); }\nsize_t my_size(const Collection& collection) { return collection.size(); }\n*/\n\nint main()\n{\n  int array[] {4, 8, 15, 16, 23, 42};\n  std::cout << \"Size of numbers is \" << my_size(array) << std::endl;\n  \n  // A string literal is also an array:\n  std::cout << \"Size of life lesson is \" \n            << my_size(\"Always wear a smile. One size fits all.\") << std::endl;\n  \n  std::vector<int> vector{4, 8, 15, 16, 23, 42};\n  std::cout << \"Size of vector is \" << my_size(vector) << std::endl;\n  \n  std::array<int, 6> array_object{4, 8, 15, 16, 23, 42};\n  std::cout << \"Size of array_object is \" << my_size(array_object) << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 10/Soln10_05.cpp",
    "content": "// Exercise 10-5.cpp\n// The easiest way to verify this is using a static variable.\n// If indeed each function is only instantiated once, \n// then all calls should share the same static variable...\n// You should see this being reflected in the program's output\n// as main() starts by calling the function for doubles twice.\n#include <iostream>\n#include <format>\n#include <string>\n\ntemplate<typename T> T larger(T a, T b);    // Function template prototype\n\nint main()\n{\n  std::cout << \"Larger of 1.5 and 2.5 is \" << larger(1.5, 2.5) << std::endl;\n  std::cout << \"Larger of 3.5 and 4.5 is \" << larger(3.5, 4.5) << std::endl;\n\n  int big_int {17011983}, small_int {10};\n  std::cout << std::format(\"Larger of {} and {} is {}\\n\", \n                            big_int, small_int, larger(big_int, small_int));\n\n  std::string a_string {\"A\"}, z_string {\"Z\"};\n  std::cout << std::format(R\"(Larger of \"{}\" and \"{}\" is \"{}\")\", \n                           a_string, z_string, larger(a_string, z_string)) << std::endl;\n}\n\n// Template for functions to return the larger of two values\ntemplate <typename T>\nT larger(T a, T b)\n{\n  static size_t counter{};\n  std::cout << \"This instantation has now been called \" << ++counter << \" time(s)\\n\";\n  return a > b? a : b;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 10/Soln10_06.cpp",
    "content": "// Exercise 10-6 A Quicksort function template\n\n#include <iostream>\n#include <format>\n#include <vector>\n\ntemplate <typename T>\nvoid swap(std::vector<T>& data, size_t first, size_t second);\ntemplate <typename T>\nvoid sort(std::vector<T>& data);\ntemplate <typename T>\nvoid sort(std::vector<T>& data, size_t start, size_t end);\ntemplate <typename T>\nvoid show(const std::vector<T>& data, size_t width = 5);\n\nint main()\n{\n  std::vector<int> numbers{ -2, 4, -5, 6, 10, -40, 56, 4, 67, 45 };\n  show(numbers);\n  sort(numbers);\n  std::cout << \"\\nSorted integers:\\n\";\n  show(numbers);\n\n  std::cout << \"\\nCharacters to be sorted:\\n\";\n  std::vector<char> letters{ 'C', 'd', 'a', 'z', 't', 'S', 'p', 'm', 'D', 'f' };\n  show(letters, 2);\n  sort(letters);\n  std::cout << \"\\nSorted characters:\\n\";\n  show(letters, 2);\n\n  std::cout << \"\\nFloating-point values to be sorted:\\n\";\n  std::vector<double> values{ -2.5, 1.4, -2.55, 6.3, 10.1, -40.5, 56.0, 4.7, 67.3, 45.0 };\n  show(values, 10);\n  sort(values);\n  std::cout << \"\\nSorted floaating-point values:\\n\";\n  show(values, 10);\n}\n\ntemplate <typename T>\nvoid swap(std::vector<T>& data, size_t first, size_t second)\n{\n  auto temp{data[first]};\n  data[first] = data[second];\n  data[second] = temp;\n}\n\n// Sort data in ascending sequence\ntemplate <typename T>\nvoid sort(std::vector<T>& data)\n{\n  if (!data.empty())\n    sort(data, 0, data.size() - 1);\n}\n\ntemplate <typename T>\nvoid sort(std::vector<T>& data, size_t start, size_t end)\n{\n  // start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle address to partition set\n  swap(data, start, (start + end) / 2);    // Swap middle element with start element\n\n  // Check data against chosen element\n  size_t current {start};\n  for (size_t i {start + 1}; i <= end; i++)\n  {\n    if (data[i] < data[start])     // Is element less than chosen element?\n      swap(data, ++current, i);    // Yes, so swap to the left\n  }\n\n  swap(data, start, current);      // Swap chosen and last swapped elements\n\n  if (current > start) sort(data, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) sort(data, current + 1, end); // Sort right subset if exists\n}\n\ntemplate <typename T>\nvoid show(const std::vector<T>& data, size_t width)\n{\n  const size_t data_per_line{ 80 / width - 1};\n  std::cout << std::format(\"{:{}}\", data[0], width); // Output first element\n\n  size_t data_in_line {};         // Number of data in current line\n  for (size_t i {1}; i < data.size(); ++i)\n  {\n    if (++data_in_line == data_per_line)\n    {\n      data_in_line = 0;\n      std::cout << std::endl;\n    }\n    std::cout << std::format(\"{:{}}\", data[i], width); // Output an element\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_01/Integer.cpp",
    "content": "#include \"Integer.h\"\n#include <iostream>\n\nInteger::Integer(int value) : m_value{value}\n{\n  std::cout << \"Object created.\" << std::endl;\n}\n\nvoid Integer::show() const\n{\n  std::cout << \"Value is \" << m_value << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_01/Integer.h",
    "content": "#ifndef INTEGER_H\n#define INTEGER_H\n\nclass Integer\n{\npublic:\n  Integer(int value);\n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\n  void show() const;\n\nprivate:\n  int m_value;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_01/Soln12_01.cpp",
    "content": "// Implementing an Integer class\n#include \"Integer.h\"\n#include <iostream>\n\nint main() \n{\n  std::cout << \"Create i with the value 10.\" << std::endl;\n  Integer i {10};\n  i.show();\n  std::cout << \"Change value  of i to 15.\" << std::endl;\n//  i.m_value = 15;\t// Cannot assign directly to m_value\n  i.setValue(15);\n  i.show();\n \n  std::cout << \"Create j with a value that is 150 times that of i.\" << std::endl;\n  const Integer j {150 * i.getValue()};\n  j.show();\n  std::cout << \"Set value of j to .\" << std::endl;\n// j.setValue(5000);  // Cannot call setValue() on const object \n                      // (show() and getValue() work, though)\n\n  std::cout << \"Create k with the value 789.\" << std::endl;\n  Integer k {789};\n  k.show();\n  std::cout << \"Set value of k to sum of i and j values.\" << std::endl;\n  k.setValue(i.getValue() + j.getValue());\n  k.show();\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_02/Integer.cpp",
    "content": "#include \"Integer.h\"\n#include <iostream>\n\n// Constructor\nInteger::Integer(int value)\n  : m_value{ value }\n{\n  std::cout << \"Object created.\" << std::endl;\n}\n\n// Copy constructor\nInteger::Integer(const Integer& obj) \n  : m_value{ obj.m_value }\n{\n  std::cout << \"Object created by copy constructor.\" << std::endl;\n}\n\n// Compare function with reference parameter\nint Integer::compare(const Integer& obj) const\n{\n  if (m_value < obj.m_value)\n    return -1;\n  else if (m_value == obj.m_value)\n    return 0;\n  else\n    return 1;\n}\n\nvoid Integer::show() const\n{\n  std::cout << \"Value is \" << m_value << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_02/Integer.h",
    "content": "/***************************************************************\\\n This header shows two distinct ways of allowing an Integer\n to be constructed without an argument:\n  1) The first is to add a default constructor. \n\t   To make sure m_value is zero, \n     it adds zero initialization to the declaration of m_value.\n  2) The second (at the bottom of the file) is commented out \n     and uses a default parameter value for the existing \n     single-argument constructor.\n\\***************************************************************/\n\n#ifndef INTEGER_H\n#define INTEGER_H\n\n// Option 1: zero-initialize n and add a default constructor\nclass Integer\n{\npublic:\n  Integer() = default;                     // Zero-arg constructor\n  Integer(int value);                      // Contructor with given value\n  Integer(const Integer& obj);             // Copy constructor\n\n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\n\n//  int compare(Integer obj) const;        // Compare function with value parameter\n  int compare(const Integer& obj) const;   // Compare function with reference parameter\n\n  void show() const;\n\nprivate:\n  int m_value{};\n};\n\n// Option 2: use zero a default parameter value\n/*\nclass Integer\n{\npublic:\n  Integer(int value = 0);                  // Contructor with given value\n\n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\n\n//  int compare(Integer obj) const;        // Compare function with value parameter\n  int compare(const Integer& obj) const;   // Compare function with reference parameter\n\n  void show() const;\n\nprivate:\n  int m_value;\n};\n*/\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_02/Soln12_02.cpp",
    "content": "// Using a function with a reference parameter in the Integer class\n#include <iostream>\n#include \"Integer.h\"\n\n/*****************************************************************\\\n Using the version of compare() with the pass-by-value parameter,\n the copy constructor is called because a copy of the argument\n is passed to the function.\n\n Using the version with the reference parameter a reference\n to the object is passed to the function so no constructor call\n is necessary.\n\n You cannot overload a function with a reference parameter with\n a function that has a non-reference parameter because the\n compiler cannot tell which function should be called in any\n particular instance.\n\\*****************************************************************/\n\nint main()\n{\n  std::cout << \"Create i with the value 0.\" << std::endl;\n  Integer i;\n  i.show();\n  std::cout << \"Change value  of i to 15.\" << std::endl;\n  i.setValue(15);\n  i.show();\n \n  std::cout << \"Create j from object i.\" << std::endl;\n  Integer j {i};\n  j.show();\n  std::cout << \"Set value of j to 150 times that of i.\" << std::endl;\n  j.setValue(150 * i.getValue());\n  j.show();\n\n  std::cout << \"Create k with the value 789.\" << std::endl;\n  Integer k {789};\n  k.show();\n  std::cout << \"Set value of k to sum of i and j values.\" << std::endl;\n  k.setValue(i.getValue() + j.getValue());\n  k.show();\n\n  std::cout << \"Result of comparing i and j is \" << i.compare(j) << std::endl;\n  std::cout << \"Result of comparing k and j is \" << k.compare(j) << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_03/Integer.cpp",
    "content": "#include \"Integer.h\"\n#include <iostream>\n\n// Constructor\nInteger::Integer(int value) \n  : m_value{ value }\n{\n}\n\n// Copy constructor\nInteger::Integer(const Integer& obj) \n  : m_value{obj.m_value} \n{\n}\n\nInteger& Integer::add(const Integer& obj)\n{ \n  m_value += obj.m_value;\n  return *this;\n}\n\nInteger& Integer::subtract(const Integer& obj) \n{\n  m_value -= obj.m_value;\n  return *this;\n}\n\nInteger& Integer::multiply(const Integer& obj) \n{\n  m_value *= obj.m_value;\n  return *this;\n}\n\nint Integer::compare(const Integer& obj) const\n{\n  if (m_value < obj.m_value)\n    return -1;\n  else if (m_value == obj.m_value)\n    return 0;\n  else\n  \treturn 1;\n}\n\nvoid Integer::show() const\n{\n  std::cout << \"Value is \" << m_value << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_03/Integer.h",
    "content": "#ifndef INTEGER_H\n#define INTEGER_H\n\nclass Integer\n{\npublic:\n  Integer(int value = 0);\n  Integer(const Integer& obj);\n\n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\n  \n  Integer& add(const Integer& obj);\n  Integer& subtract(const Integer& obj);\n  Integer& multiply(const Integer& obj);\n\n  int compare(const Integer& obj) const;\n  \n  void show() const;\n\nprivate:\n  int m_value;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_03/Soln12_03.cpp",
    "content": "// Implementing add(), subtract() and multiply() \n#include <iostream>\n#include \"Integer.h\"\n\n/***********************************************************\n By returning the dereferenced this pointer in the functions\n we can call the functions successively in a single statement.\n Note the parameter is a reference-to-const;\n const because the argument is not changed by the function\n and a reference to avoid the overhead of copying objects.\n The only other requirement for achieving the calculation\n in a single statement is figuring out how to sequence to\n operations to allow this.\n ***********************************************************/\n\nint main()\n{\n  // Create the even operands as Integers, \n  // and use implicit conversions from int for the odd values\n  const Integer four{4};\n  const Integer six{6};\n  const Integer eight{8};\n  \n  // We can calculate 4*5*5*5+6*5*5+7*5+8 as:\n  //     ((4*5+6)*5+7)*5+8\n  Integer result {four};                       // Set result object as copy of four\n  std::cout << \"Result is \"\n            << result.multiply(5).add(six).multiply(5).add(7).multiply(5).add(eight).getValue()\n            << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_04/Integer.cpp",
    "content": "#include <iostream>\n#include \"Integer.h\"\n\n/****************************************************************\\\n Implementing compare() as a friend is quite simple.\n We must declare the function as a friend in the class definition.\n We now need both objects as arguments and the code in the\n body of the function just compares the n members of the arguments.\n Both parameters are references-to-const.\n\n However, other than the need for you to exercise friend functions,\n there's no real reason for the compare() function to be a friend\n of the Integer class: it can be implemented perfectly fine\n using the public getValue() function as well.\n The nonFriendCompare() function given below is therefore \n preferred over a friend function.\n\\****************************************************************/\n\n\n// Constructor\nInteger::Integer(int value) : m_value{value}\n{\n  std::cout << \"Object created.\" << std::endl;\n}\n\n// Copy constructor\nInteger::Integer(const Integer& obj) : m_value{ obj.m_value }\n{\n  std::cout << \"Object created by copy constructor.\" << std::endl;\n}\n\nvoid Integer::show() const\n{\n  std::cout << \"Value is \" << m_value << std::endl;\n}\n\n// friend compare function\nint compare(const Integer& obj1, const Integer& obj2)\n{\n  if (obj1.m_value < obj2.m_value)\n    return -1;\n  else if (obj1.m_value == obj2.m_value)\n    return 0;\n  else\n\t  return 1;\n}\n\n// non-friend compare function\nint nonFriendCompare(const Integer& obj1, const Integer& obj2)\n{\n  if (obj1.getValue() < obj2.getValue())\n    return -1;\n  else if (obj1.getValue() == obj2.getValue())\n    return 0;\n  else\n  \treturn 1;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_04/Integer.h",
    "content": "#ifndef INTEGER_H\n#define INTEGER_H\n\nclass Integer\n{\npublic:\n  Integer(int value = 0);\n  Integer(const Integer& obj);\n  \n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\n\n  void show() const;\n\n  friend int compare(const Integer& obj1, const Integer& obj2);  // friend compare function\n\nprivate:\n  int m_value;\n};\n\n// A non-friend function that implements the same function\nint nonFriendCompare(const Integer& obj1, const Integer& obj2);\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_04/Soln12_04.cpp",
    "content": "// Using a friend function\n#include <iostream>\n#include \"Integer.h\"\n\nint main()\n{\n  std::cout << \"Create i with the value 10.\" << std::endl;\n  Integer i {10};\n  i.show();\n  std::cout << \"Change value  of i to 15.\" << std::endl;\n  i.setValue(15);\n  i.show();\n \n  std::cout << \"Create j from object i.\" << std::endl;\n  Integer j {i};\n  j.show();\n  std::cout << \"Set value of j to 150 times that of i.\" << std::endl;\n  j.setValue(150 * i.getValue());\n  j.show();\n\n  std::cout << \"Create k with the value 789.\" << std::endl;\n  Integer k {789};\n  k.show();\n  std::cout << \"Set value of k to sum of i and j values.\" << std::endl;\n  k.setValue(i.getValue() + j.getValue());\n  k.show();\n\n  std::cout << \"Result of comparing i and j is \" << compare(i, j) << std::endl;\n  std::cout << \"Result of comparing k and j is \" << compare(k, j) << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_05/Integer.cpp",
    "content": "/*****************************************************************\\\n To implement printCount(), you first need a static member variable\n to store the object count. Every constructor should then increment\n this count, and you need to add a destructor that decrements it. \n\\*****************************************************************/\n#include <iostream>\n#include \"Integer.h\"\n\n// Constructor\nInteger::Integer(int value) : m_value{value}\n{\n  ++s_count;\n  std::cout << \"Object created.\" << std::endl;\n}\n\n// Copy constructor\nInteger::Integer(const Integer& obj) : m_value{obj.m_value}\n{\n  ++s_count;\n  std::cout << \"Object created by copy constructor.\" << std::endl;\n}\n\n// Destructor\nInteger::~Integer()\n{\n  --s_count;\n  std::cout << \"Object deleted.\" << std::endl;\n}\n\nvoid Integer::show() const\n{\n  std::cout << \"Value is \" << m_value << std::endl;\n}\n\nint Integer::compare(const Integer& obj) const\n{\n  if (m_value < obj.m_value)\n    return -1;\n  else if (m_value == obj.m_value)\n    return 0;\n  else\n    return 1;\n}\n\nvoid Integer::printCount()\n{\n  std::cout << \"There are now \" << s_count << \" Integer object(s).\" << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_05/Integer.h",
    "content": "#ifndef INTEGER_H\n#define INTEGER_H\n\nclass Integer\n{\npublic:\n  Integer(int value = 0);                  // Contructor with given value\n  Integer(const Integer& obj);             // Copy constructor\n  ~Integer();                              // Destructor\n\n  int getValue() const { return m_value; }\n  void setValue(int value) { m_value = value; }\n\n  int compare(const Integer& obj) const;   // Compare function with reference parameter\n\n  void show() const;\n  \n  static void printCount();\n\nprivate:\n  int m_value;\n  static inline unsigned int s_count {};\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_05/Soln12_05.cpp",
    "content": "// Using static members and a destructor to keep track of an object count\n#include <iostream>\n#include \"Integer.h\"\n\nvoid showIntegerVal(Integer it)\n{\n  it.show();\n  Integer::printCount();    // passed by value, so object count temporarily increases\n}\nvoid showIntegerRef(const Integer& it)\n{\n  it.show();\n  Integer::printCount();    // passed by reference, so object count did not increase\n}\n\nint main()\n{\n  std::cout << \"Create i with the value 0.\" << std::endl;\n  Integer i;\n  i.show();\n  \n  Integer::printCount();\t// 1 object\n \n  if (i.getValue() == 0)\n  {\n    std::cout << \"Create j from object i.\" << std::endl;\n    Integer j {i};\n    j.show();\n    Integer::printCount();\t// 2 objects\n  }\n  \n  Integer::printCount();\t// 1 object again (Integer j was deleted because its scope ended)\n\n  Integer array[] { 1, 2, 3 };\n  \n  Integer::printCount();   // 4 objects\n  \n  showIntegerRef(array[0]);\n  showIntegerVal(array[1]);\n  \n  Integer::printCount();   // 4 objects again\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_06/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>\n#include <format>\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  void listBox() const\n  {\n    std::cout << std::format(\"Box({:.1f},{:.1f},{:.1f})\", m_length, m_width, m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_06/RandomBoxes.h",
    "content": "#ifndef RANDOM_BOXES_H\n#define RANDOM_BOXES_H\n\n#include \"Box.h\"\n#include <random>        // For random number generation\n#include <functional>    // For std::bind()\n#include <memory>        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\ninline auto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\ninline Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\ninline auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_06/Soln12_06.cpp",
    "content": "// Creating a nested iterator class\n#include \"RandomBoxes.h\"\n#include \"Truckload.h\"\n\n/* \n Turns out moving the getFirstBox() and getLastBox() functions \n to the nested iterator class is easy. We used the same names for\n the member variables, so it is just a matter of changing \"Truckload::\"\n into \"Truckload::Iterator::\".\n \n Makes sense: the logic for iterating the linked lists has not changed.\n The only difference is that now there are m_current and m_head pointers\n per iteration, instead of only the one pair in the Truckload object.\n This allows nested iterations, concurrent iterations, and so on.\n You will encounter this iterator pattern again in Chapters 19 and 20.\n\n Btw: if it strikes you as sub-optimal that our findLargestBox() and\n findSmallestBox() are so similar, do not despair: in Chapter 19 we teach\n you the techniques you need to avoid this so-called code duplication.\n*/\n\nSharedBox findLargestBox(const Truckload& truckload);\nSharedBox findSmallestBox(const Truckload& truckload);\n\nint main()\n{\n  Truckload load1;  // Create an empty list\n\n  // Add 12 random Box objects to the list\n  const size_t boxCount{ 12 };\n  for (size_t i{}; i < boxCount; ++i)\n    load1.addBox(randomSharedBox());\n\n  std::cout << \"The first list:\\n\";\n  load1.listBoxes();\n\n  // Copy the truckload\n  Truckload copy{ load1 };\n  std::cout << \"The copied truckload:\\n\";\n  copy.listBoxes();\n\n  // Find the largest Box in the list\n  const auto largestBox{ findLargestBox(load1) };\n\n  std::cout << \"\\nThe largest box in the first list is \";\n  largestBox->listBox();\n  std::cout << std::endl;\n  load1.removeBox(largestBox);\n  std::cout << \"\\nAfter deleting the largest box, the list contains:\\n\";\n  load1.listBoxes();\n\n  const size_t nBoxes{ 20 };            // Number of vector elements\n  std::vector<SharedBox> boxes;        // Array of Box objects\n\n  for (size_t i{}; i < nBoxes; ++i)\n    boxes.push_back(randomSharedBox());\n\n  Truckload load2{ boxes };\n  std::cout << \"\\nThe second list:\\n\";\n  load2.listBoxes();\n\n  const auto smallestBox{ findSmallestBox(load2) };\n\n  std::cout << \"\\nThe smallest box in the second list is \";\n  smallestBox->listBox();\n  std::cout << std::endl;\n}\n\nSharedBox findLargestBox(const Truckload& truckload)\n{\n  auto iterator{ truckload.getIterator() };  // Type of iterator is Truckload::Iterator\n  SharedBox largestBox{ iterator.getFirstBox() };\n\n  SharedBox nextBox{ iterator.getNextBox() };\n  while (nextBox)\n  {\n    if (nextBox->compare(*largestBox) > 0)\n      largestBox = nextBox;\n    nextBox = iterator.getNextBox();\n  }\n\n  return largestBox;\n}\n\nSharedBox findSmallestBox(const Truckload& truckload)\n{\n  auto iterator{ truckload.getIterator() };  // Type of iterator is Truckload::Iterator\n  SharedBox smallestBox{ iterator.getFirstBox() };\n\n  SharedBox nextBox{ iterator.getNextBox() };\n  while (nextBox)\n  {\n    if (nextBox->compare(*smallestBox) < 0)\n      smallestBox = nextBox;\n    nextBox = iterator.getNextBox();\n  }\n\n  return smallestBox;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_06/Truckload.cpp",
    "content": "#include \"Truckload.h\"\n\n#include <iostream>\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nvoid Truckload::listBoxes() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count {};  \n  for (Package* package{m_head}; package; package = package->m_next)\n  {\n    std::cout << ' ';\n    package->m_box->listBox();\n    if (! (++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n\n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_06/Truckload.h",
    "content": "#ifndef TRUCKLOAD_H\n#define TRUCKLOAD_H\n\n#include \"Box.h\"\n\n#include <memory>\n#include <vector>\n\nusing SharedBox = std::shared_ptr<Box>;\n\nclass Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  void listBoxes() const;           // Output the Boxes\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_07/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>\n#include <format>\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  void listBox() const\n  {\n    std::cout << std::format(\"Box({:.1f},{:.1f},{:.1f})\", m_length, m_width, m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_07/RandomBoxes.h",
    "content": "#ifndef RANDOM_BOXES_H\n#define RANDOM_BOXES_H\n\n#include \"Box.h\"\n#include <random>        // For random number generation\n#include <functional>    // For std::bind()\n#include <memory>        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\ninline auto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\ninline Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\ninline auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_07/Soln12_07.cpp",
    "content": "// Create a doubly-linked list of Packages\n#include \"RandomBoxes.h\"\n#include \"Truckload.h\"\n\n/*\n   To show reverse iteration, we've modified findSmallestBox() to iterate in reverse order\n */\n\nSharedBox findLargestBox(const Truckload& truckload);\nSharedBox findSmallestBox(const Truckload& truckload);\n\nint main()\n{\n  Truckload load;  // Create an empty list\n\n  // Add 12 random Box objects to the list\n  const size_t boxCount{ 12 };\n  for (size_t i{}; i < boxCount; ++i)\n    load.addBox(randomSharedBox());\n\n  std::cout << \"The random truckload:\\n\";\n  load.listBoxes();\n  std::cout << std::endl;\n\n  std::cout << \"The same random truckload in reverse:\\n\";\n  load.listBoxesReversed();\n  std::cout << std::endl;\n\n  std::cout << \"The largest box (found using forward iteration) is \";\n  findLargestBox(load)->listBox();\n  std::cout << std::endl;\n\n  std::cout << \"The smallest box (found using reverse iteration) is \";\n  findSmallestBox(load)->listBox();\n  std::cout << std::endl;\n}\n\nSharedBox findLargestBox(const Truckload& truckload)\n{\n  auto iterator{ truckload.getIterator() };  // Type of iterator is Truckload::Iterator\n  SharedBox largestBox{ iterator.getFirstBox() };\n\n  SharedBox nextBox{ iterator.getNextBox() };\n  while (nextBox)\n  {\n    if (nextBox->compare(*largestBox) > 0)\n      largestBox = nextBox;\n    nextBox = iterator.getNextBox();\n  }\n\n  return largestBox;\n}\n\nSharedBox findSmallestBox(const Truckload& truckload)\n{\n  auto iterator{ truckload.getIterator() };  // Type of iterator is Truckload::Iterator\n  SharedBox smallestBox{ iterator.getLastBox() };\n\n  SharedBox nextBox{ iterator.getPreviousBox() };\n  while (nextBox)\n  {\n    if (nextBox->compare(*smallestBox) < 0)\n      smallestBox = nextBox;\n    nextBox = iterator.getPreviousBox();\n  }\n\n  return smallestBox;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_07/Truckload.cpp",
    "content": "#include \"Truckload.h\"\n\n#include <iostream>\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n  Package* m_previous;  // Pointer to the previous Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{}, m_previous{} {}\n  ~Package() { delete m_next; }\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nvoid Truckload::listBoxes() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count {};  \n  for (Package* package{m_head}; package; package = package->m_next)\n  {\n    std::cout << ' ';\n    package->m_box->listBox();\n    if (! (++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\nvoid Truckload::listBoxesReversed() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count{};\n  for (Package* package{ m_tail }; package; package = package->m_previous)\n  {\n    std::cout << ' ';\n    package->m_box->listBox();\n    if (!(++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\nTruckload::Iterator Truckload::getIterator() const\n{ \n  return Iterator{ m_head, m_tail }; \n}\n\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\nSharedBox Truckload::Iterator::getLastBox()\n{\n  // Return m_tail's box (or nullptr if the list is empty)\n  m_current = m_tail;\n  return m_current ? m_current->m_box : nullptr;\n}\n\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nSharedBox Truckload::Iterator::getPreviousBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getLastBox();                          // ...return the last Box\n\n  m_current = m_current->m_previous;              // Move to the next package\n\n  return m_current ? m_current->m_box : nullptr;  // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n  {\n    package->m_previous = m_tail;  // The package is added after the old tail\n    m_tail->m_next = package;      // Append the new object to the tail\n  }\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n  \n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  // No need for a trailing pointer anymore!\n  // (We can go back one using the m_previous pointer of the doubly-linked list...)\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // Update the doubly-linked list pointers \n      // (make a sketch of this to better see what is going on here!)\n      if (current->m_previous) current->m_previous->m_next = current->m_next;\n      if (current->m_next) current->m_next->m_previous = current->m_previous;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = current->m_previous;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }  \n\n    current = current->m_next;       //  Move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_07/Truckload.h",
    "content": "#ifndef TRUCKLOAD_H\n#define TRUCKLOAD_H\n\n#include \"Box.h\"\n\n#include <memory>\n#include <vector>\n\nusing SharedBox = std::shared_ptr<Box>;\n\nclass Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  void listBoxes() const;           // Output the Boxes\n  void listBoxesReversed() const;   // Output the Boxes in reversed order\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();    // Get the first Box\n  SharedBox getLastBox();     // Get the first Box\n  SharedBox getNextBox();     // Get the next Box\n  SharedBox getPreviousBox(); // Get the previous Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_tail;          // The tail of the linked list (needed for getLastBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head, Package* tail) \n    : m_head{ head }\n    , m_tail{ tail }\n    , m_current{ nullptr } \n  {}\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_08/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <iostream>\n#include <format>\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  void listBox() const\n  {\n    std::cout << std::format(\"Box({:.1f},{:.1f},{:.1f})\", m_length, m_width, m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_08/RandomBoxes.h",
    "content": "#ifndef RANDOM_BOXES_H\n#define RANDOM_BOXES_H\n\n#include \"Box.h\"\n#include <random>        // For random number generation\n#include <functional>    // For std::bind()\n#include <memory>        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\ninline auto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\ninline Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\ninline auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_08/Soln12_08.cpp",
    "content": "// Remove Boxes from a Truckload without searching a second time\n#include \"RandomBoxes.h\"\n#include \"Truckload.h\"\n\n/********************************************************************************\\\n  The key to the solution is that the Iterator object already contains\n  a pointer to the Package that needs to be removed.\n  Of course, external code cannot use a Package, but it can use the Iterator.\n  To exploit the knowledge contained in the Iterator, we add an overload\n  of the removeBox() function with an Iterator parameter instead of a Box.\n\n  To facilitate things, we also added getCurrentBox() to Iterator,\n  which allowed us to remove some duplicated code in the various other getters\n  of that class.\n  \n  Both findLargestBox() and findSmallestBox() are updated to return an Iterator\n  as well. Note that the same technique is used by all Standard Library \n  containers and algorithms (see Chapter 20)!\n\n  Notice also that we created removePackage() to avoid duplicating this code\n  in the two overloads of removeBox().\n\n  An alternative solution that also does not duplicate the removal logic\n  consists of using an Iterator in removeBox(SharedBox), \n  and then invoke removeBox(Iterator) once the box is found. \n  removePackage() is then no longer required. We recommend you give this a try!\n\\**********************************************************************************/\n\nTruckload::Iterator findLargestBox(const Truckload& truckload);\nTruckload::Iterator findSmallestBox(const Truckload& truckload);\n\nint main()\n{\n  Truckload load;  // Create an empty list\n\n  // Add 12 random Box objects to the list\n  const size_t boxCount{ 12 };\n  for (size_t i{}; i < boxCount; ++i)\n    load.addBox(randomSharedBox());\n\n  std::cout << \"The random truckload:\\n\";\n  load.listBoxes();\n  std::cout << std::endl;\n\n  const auto largestIter{ findLargestBox(load) };\n  const auto smallestIter{ findSmallestBox(load) };\n\n  std::cout << \"The largest box (found using forward iteration) is \";\n  largestIter.getCurrentBox()->listBox();\n  std::cout << '\\n' << std::endl;\n\n  load.removeBox(largestIter);\n\n  std::cout << \"The truckload without its largest box:\\n\";\n  load.listBoxes();\n  std::cout << std::endl;\n\n  std::cout << \"The smallest box (found using reverse iteration) is \";\n  smallestIter.getCurrentBox()->listBox();\n  std::cout << '\\n' << std::endl;\n  \n  load.removeBox(smallestIter);\n\n  std::cout << \"The truckload without its smallest box (in reverse order):\\n\";\n  load.listBoxesReversed();\n}\n\nTruckload::Iterator findLargestBox(const Truckload& truckload)\n{\n  auto iterator{ truckload.getIterator() };  // Type of iterator is Truckload::Iterator\n  iterator.getFirstBox();\n  auto largestBoxIterator{ iterator };\n\n  while (iterator.getNextBox())\n  {\n    if (iterator.getCurrentBox()->compare(*largestBoxIterator.getCurrentBox()) > 0)\n    {\n      largestBoxIterator = iterator;\n    }\n  }\n\n  return largestBoxIterator;\n}\n\nTruckload::Iterator findSmallestBox(const Truckload& truckload)\n{\n  auto iterator{ truckload.getIterator() };  // Type of iterator is Truckload::Iterator\n  iterator.getLastBox();\n  auto smallestBoxIterator{ iterator };\n\n  while (iterator.getPreviousBox())\n  {\n    if (iterator.getCurrentBox()->compare(*smallestBoxIterator.getCurrentBox()) < 0)\n    {\n      smallestBoxIterator = iterator;\n    }\n  }\n\n  return smallestBoxIterator;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_08/Truckload.cpp",
    "content": "#include \"Truckload.h\"\n\n#include <iostream>\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n  Package* m_previous;  // Pointer to the previous Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{}, m_previous{} {}\n  ~Package() { delete m_next; }\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nvoid Truckload::listBoxes() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count {};  \n  for (Package* package{m_head}; package; package = package->m_next)\n  {\n    std::cout << ' ';\n    package->m_box->listBox();\n    if (! (++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\nvoid Truckload::listBoxesReversed() const\n{\n  const size_t boxesPerLine{ 4 };\n  size_t count{};\n  for (Package* package{ m_tail }; package; package = package->m_previous)\n  {\n    std::cout << ' ';\n    package->m_box->listBox();\n    if (!(++count % boxesPerLine)) std::cout << std::endl;\n  }\n  if (count % boxesPerLine) std::cout << std::endl;\n}\n\nTruckload::Iterator Truckload::getIterator() const\n{ \n  return Iterator{ m_head, m_tail }; \n}\n\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return getCurrentBox();\n}\n\nSharedBox Truckload::Iterator::getLastBox()\n{\n  // Return m_tail's box (or nullptr if the list is empty)\n  m_current = m_tail;\n  return getCurrentBox();\n}\n\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return getCurrentBox();\n}\n\nSharedBox Truckload::Iterator::getPreviousBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getLastBox();                          // ...return the last Box\n\n  m_current = m_current->m_previous;              // Move to the next package\n\n  return getCurrentBox();\n}\n\nSharedBox Truckload::Iterator::getCurrentBox() const\n{\n  return m_current ? m_current->m_box : nullptr;\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n  {\n    package->m_previous = m_tail;  // The package is added after the old tail\n    m_tail->m_next = package;      // Append the new object to the tail\n  }\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n  \n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  for (auto* current{ m_head }; current != nullptr; current = current->m_next)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      removePackage(current);\n      return true;\n    }  \n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nbool Truckload::removeBox(Iterator iter)\n{\n  if (iter.m_current)\n  {\n    removePackage(iter.m_current);\n    return true;\n  }\n  else\n  {\n    return false;\n  }\n}\n\nvoid Truckload::removePackage(Package* package)\n{\n  // Update the doubly-linked list pointers\n  if (package->m_previous) package->m_previous->m_next = package->m_next;\n  if (package->m_next) package->m_next->m_previous = package->m_previous;\n\n  // Update pointers in member variables where required:\n  if (package == m_head) m_head = package->m_next;\n  if (package == m_tail) m_tail = package->m_previous;\n\n  package->m_next = nullptr;     // Disconnect the current Package from the list\n  delete package;                // and delete it\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 12/Soln12_08/Truckload.h",
    "content": "#ifndef TRUCKLOAD_H\n#define TRUCKLOAD_H\n\n#include \"Box.h\"\n\n#include <memory>\n#include <vector>\n\nusing SharedBox = std::shared_ptr<Box>;\n\nclass Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  Truckload(const Truckload& src);  // Copy constructor\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n  bool removeBox(Iterator iter);    // Remove the Box pointed to by this Iterator\n\n  void listBoxes() const;           // Output the Boxes\n  void listBoxesReversed() const;   // Output the Boxes in reversed order\n\nprivate:\n  class Package;\n\n  void removePackage(Package* package);\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();    // Get the first Box\n  SharedBox getLastBox();     // Get the first Box\n  SharedBox getNextBox();     // Get the next Box\n  SharedBox getPreviousBox(); // Get the previous Box\n  SharedBox getCurrentBox() const;  // Get the current Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_tail;          // The tail of the linked list (needed for getLastBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head, Package* tail) \n    : m_head{ head }\n    , m_tail{ tail }\n    , m_current{ nullptr } \n  {}\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_01/Box.cpp",
    "content": "#include \"Box.h\"\n\n#include <format>\n#include <algorithm>    // For the min() and max() function templates\n\ndouble Box::volume() const\n{\n    return m_length * m_width * m_height;\n}\n\nBox Box::operator+(const Box& aBox) const\n{\n  // New object has larger length and width, and sum of heights\n  return Box{ std::max(m_length, aBox.m_length),\n              std::max(m_width, aBox.m_width),\n              m_height + aBox.m_height };\n}\n\nBox Box::operator*(double factor) const\n{\n  return Box{ m_length * factor, m_width * factor, m_height * factor, };\n}\n\nstd::partial_ordering Box::operator<=>(const Box& aBox) const\n{\n  return volume() <=> aBox.volume();\n}\n\nstd::partial_ordering Box::operator<=>(double value) const\n{\n  return volume() <=> value;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                          box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_01/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n#include <ostream>  // For std::ostream\n\nclass Box\n{\npublic:\n  Box() = default;       // Default constructor\n  Box(double length, double width, double height)\n    : m_length{ std::max(length,width) }\n    , m_width { std::min(length,width) }\n    , m_height{ height } \n  {}\n\n  double volume() const; // Function to calculate the volume\n  \n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions that add full support for comparison operators\n  std::partial_ordering operator<=>(const Box& aBox) const;\n  std::partial_ordering operator<=>(double value) const;\n  bool operator==(const Box& aBox) const = default;\n\n  Box operator+(const Box& aBox) const; // Function to add two Box objects\n  Box operator*(double factor) const;   // Function to multiply a Box with a given factor\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box);\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_01/Soln13_01.cpp",
    "content": "// Exercise 13-1\n// Implementing the * operator for the Box class\n// to post-multiply by an integer\n#include <iostream>\n#include \"Box.h\"\n\nint main()\n{\n  Box box {2, 3, 4};\n  std::cout << \"Box is \" << box << std::endl;\n  unsigned n {3};\n  Box newBox{ box * n };\n  std::cout << \"After multiplying by \" << n << \" box is \" << newBox << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_02/Box.cpp",
    "content": "#include \"Box.h\"\n\n#include <format>\n#include <algorithm>    // For the min() and max() function templates\n\ndouble Box::volume() const\n{\n    return m_length * m_width * m_height;\n}\n\nBox Box::operator+(const Box& aBox) const\n{\n  // New object has larger length and width, and sum of heights\n  return Box{ std::max(m_length, aBox.m_length),\n              std::max(m_width, aBox.m_width),\n              m_height + aBox.m_height };\n}\n\nBox Box::operator*(double factor) const\n{\n  return Box{ m_length * factor, m_width * factor, m_height * factor };\n}\n\nBox operator*(double factor, const Box& box)\n{\n  // Or: return box * factor;\n  return Box{ box.getLength() * factor, box.getWidth() * factor, box.getHeight() * factor };\n}\n\nstd::partial_ordering Box::operator<=>(const Box& aBox) const\n{\n  return volume() <=> aBox.volume();\n}\n\nstd::partial_ordering Box::operator<=>(double value) const\n{\n  return volume() <=> value;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                          box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_02/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n#include <ostream>  // For std::ostream\n\nclass Box\n{\npublic:\n  Box() = default;       // Default constructor\n  Box(double length, double width, double height)\n    : m_length{ std::max(length,width) }\n    , m_width { std::min(length,width) }\n    , m_height{ height } \n  {}\n\n  double volume() const; // Function to calculate the volume\n  \n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions that add full support for comparison operators\n  std::partial_ordering operator<=>(const Box& aBox) const;\n  std::partial_ordering operator<=>(double value) const;\n  bool operator==(const Box& aBox) const = default;\n\n  Box operator+(const Box& aBox) const; // Function to add two Box objects\n  Box operator*(double factor) const;   // Function to multiply a Box with a given factor\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Function to pre-multiply a Box with a given factor\nBox operator*(double factor, const Box& box);\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box);\n\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_02/Soln13_02.cpp",
    "content": "// Exercise 13-2\n// Implementing the * operator for the Box class to pre-multiply by a number\n#include <iostream>\n#include \"Box.h\"\n\nint main()\n{\n  Box box {2, 3, 4};\n  std::cout << \"Box is \" << box << std::endl;\n  unsigned n {3};\n  Box newBox{ n * box };\n  std::cout << \"After pre-multiplying by \" << n << \" box is \" << newBox << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_03/Box.cpp",
    "content": "#include \"Box.h\"\n\n#include <format>\n#include <algorithm>    // For the min() and max() function templates\n\ndouble Box::volume() const\n{\n    return m_length * m_width * m_height;\n}\n\nBox Box::operator+(const Box& aBox) const\n{\n  Box copy{ *this };  // Implement in terms of += operator (avoid duplication)\n  copy += aBox;\n  return copy;        // Return new object (convention)\n}\n\nBox Box::operator*(double factor) const\n{\n  Box copy{ *this };  // Implement in terms of *= operator (avoid duplication)\n  copy *= factor;\n  return copy;        // Return new object (convention)\n}\n\nBox Box::operator/(double divisor) const\n{\n  Box copy{ *this };  // Implement in terms of /= operator (avoid duplication)\n  copy /= divisor;\n  return copy;        // Return new object (convention)\n}\n\nBox& Box::operator+=(const Box& aBox)\n{\n  // New object has larger length and width, and sum of heights\n  m_length = std::max(m_length, aBox.m_length);\n  m_width  = std::max(m_width, aBox.m_width);\n  m_height += aBox.m_height;\n  return *this;   // Return a reference to the left operand (convention)\n}\n\nBox& Box::operator*=(double factor)\n{\n  m_length *= factor;\n  m_width  *= factor;\n  m_height *= factor;\n  return *this;   // Return a reference to the left operand (convention)\n}\n\nBox& Box::operator/=(double divisor)\n{\n  m_length /= divisor;\n  m_width  /= divisor;\n  m_height /= divisor;\n  return *this;   // Return a reference to the left operand (convention)\n}\n\nBox operator*(double factor, const Box& box)\n{\n  return box * factor;\n}\n\nstd::partial_ordering Box::operator<=>(const Box& aBox) const\n{\n  return volume() <=> aBox.volume();\n}\n\nstd::partial_ordering Box::operator<=>(double value) const\n{\n  return volume() <=> value;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                          box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_03/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n#include <ostream>  // For std::ostream\n\nclass Box\n{\npublic:\n  Box() = default;       // Default constructor\n  Box(double length, double width, double height)\n    : m_length{ std::max(length,width) }\n    , m_width { std::min(length,width) }\n    , m_height{ height } \n  {}\n\n  double volume() const; // Function to calculate the volume\n  \n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions that add full support for comparison operators\n  std::partial_ordering operator<=>(const Box& aBox) const;\n  std::partial_ordering operator<=>(double value) const;\n  bool operator==(const Box& aBox) const = default;\n\n  Box operator+(const Box& aBox) const; // Function to add two Box objects\n  Box operator*(double factor) const;   // Function to multiply a Box with a given factor\n  Box operator/(double divisor) const;  // Function to divide a Box by a given divisor\n\n  Box& operator+=(const Box& aBox);\n  Box& operator*=(double factor);\n  Box& operator/=(double divisor);\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n// Function to pre-multiply a Box with a given factor\nBox operator*(double factor, const Box& box); \n\nstd::ostream& operator<<(std::ostream& stream, const Box& box);\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_03/Soln13_03.cpp",
    "content": "// Exercise 13-3\n// Implementing the missing /, *=, +=, and /= operators for the Box class\n#include <iostream>\n#include \"Box.h\"\n\nint main()\n{\n  Box box {2, 3, 4};\n  std::cout << \"Box is \" << box << std::endl;\n  size_t n {3};\n  box *= 3;\n  std::cout << \"After multiplying by \" << n << \" box is \" << box << std::endl;\n  box /= 3;\n  std::cout << \"After dividing by \" << n << \", the box is again \" << box << std::endl;\n  \n  Box newBox {2 * box};\n  std::cout << \"Twice \" << box << \" is \" << newBox << std::endl;\n  \n  std::cout << \"Half that is again \" << (newBox / 2) << std::endl;\n  \n  std::cout << \"Adding both boxes gives \" << (box + newBox) << std::endl;\n  \n  box += newBox;\n  \n  std::cout << \"The same can be obtained by usign += as well: \" << box << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_04/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n#include <ostream>  // For std::ostream\n#include <format>\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\n  bool operator==(double otherVolume) const\n  {\n    return volume() == otherVolume;\n  }\n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                             box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_04/Soln13_04.cpp",
    "content": "// Exercise 13-4\n// Adding support for equality operators that compare Boxes and volumes\n#include <iostream>\n#include \"Box.h\"\n\n/*\n  Because the C++20 compiler automatically rewrites != expression \n  in terms of == and/or even reverses the order of the operands,\n  only one additional operator overload definition is required to make it all work.\n*/\n\nint main()\n{\n  Box box1{ 1, 2, 3 };\n  Box box2{ 3, 2, 1 };\n  Box box3{ 1, 2, 3 };\n\n  // Try out all == and != operators (old and new, the latter in both directions)\n  std::cout << \"box1 and box2 are \" << (box1 == box2 ? \"\" : \"not \") << \"equal\\n\";\n  std::cout << \"box1 and box3 are \" << (box1 != box3 ? \"not \" : \"\") << \"equal\\n\";\n  std::cout << \"box1 is \" << (box1 == 6.0 ? \"\" : \"not \") << \"equal to 6.0\\n\";\n  std::cout << \"10.0 is \" << (10 != box2 ? \"not \" : \"\") << \"equal to box2\\n\";\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_05/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n#include <ostream>  // For std::ostream\n#include <format>\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\n  // Unary negation operator (!box is true if the Box has no volume)\n  bool operator!() const { return volume() == 0; }  \n\n  // Type conversion operator (converts a Box to a Boolean; true if it has volume)\n  operator bool() const  { return volume() != 0; }  \n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                             box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_05/Soln13_05.cpp",
    "content": "// Exercise 13-5\n// Implementing the obvious operators for the Box class \n// to allow it to be used, for instance, in if statements.\n// A Box is \"true\" if and only if its volume is non-zero.\n#include <iostream>\n#include \"Box.h\"\n\nvoid testBox(const Box& box)\n{\n  std::cout << \"The box's volume is \" << box.volume() << \".\\n\";\n  if (box)\n\t  std::cout << \"This volume is non-zero.\";\n  if (!box)\n\t  std::cout << \"This volume is zero.\";\n  std::cout << std::endl;\n}\n\nint main()\n{\n  Box box1{2, 3, 4};\n  std::cout << \"box1 is \" << box1 << std::endl;\n  testBox(box1);\n  \n  std::cout << std::endl;;\n\n  Box box2{0, 0, 0};\n  std::cout << \"box2 is \" << box2 << std::endl;\n  testBox(box2);  \n}\n\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_06/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n#include <ostream>  // For std::ostream\n#include <format>\n\nclass Box\n{\npublic:\n  // Constructors\n  Box() = default;\n  Box(double l, double w, double h) : m_length{ l }, m_width{ w }, m_height{ h } {}\n\n  double volume() const { return m_length * m_width * m_height; }\n\n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth()  const { return m_width; }\n  double getHeight() const { return m_height; }\n\n  std::partial_ordering operator<=>(const Box& otherBox) const \n  { \n    return volume() <=> otherBox.volume();\n  }\n  std::partial_ordering operator<=>(double otherVolume) const \n  { \n    return volume() <=> otherVolume;\n  }\n\n  bool operator==(const Box& otherBox) const = default;\n\n  // Explicit type conversion operator (converts a Box to a Boolean; true if it has volume)\n  explicit operator bool() const  { return volume() != 0; }  \n\nprivate:\n  double m_length{ 1.0 };\n  double m_width{ 1.0 };\n  double m_height{ 1.0 };\n};\n\ninline std::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                             box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_06/Soln13_06.cpp",
    "content": "// Exercise 13-6\n// In canonical C++, you should only implement a single operator to allow \n// objects to be used in if statements, and in Boolean expressions in general:\n// a conversion operator for type bool.\n//\n// This conversion operator, moreover, is normally qualified as explicit.\n// This is far from obvious: despite the explicit qualifier,\n// objects still implicitly convert to bool in, for instance, if statements.\n// As illustrated at the bottom of main(), however, \n// simply assigning a Box to a variable of type bool indeed no longer works\n// without an explicit type conversion (in most cases this is the desired behavior).\n#include <iostream>\n#include \"Box.h\"\n\nvoid testBox(const Box& box)\n{\n  std::cout << \"The box's volume is \" << box.volume() << \".\\n\";\n  if (box)\n\t  std::cout << \"This volume is non-zero.\";\n  if (!box)\n\t  std::cout << \"This volume is zero.\";\n  std::cout << std::endl;\n}\n\nint main()\n{\n  Box box1{2, 3, 4};\n  std::cout << \"box1 is \" << box1 << std::endl;\n  testBox(box1);\n  \n  std::cout << std::endl;;\n\n  Box box2{0, 0, 0};\n  std::cout << \"box2 is \" << box2 << std::endl;\n  testBox(box2);  \n\n  // bool b1{ box1 };    /* Does not compile! */\n  bool b2{ static_cast<bool>(box2) };  // Needs an explicit type conversion\n}\n\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_07/Rational.h",
    "content": "// Rational.h\n\n#ifndef RATIONAL_H\n#define RATIONAL_H\n#include <iostream>\n\nclass Rational\n{\npublic:\n  // Constructor\n  Rational(int numerator = 0, int denominator = 1) \n    : m_numerator {numerator}, m_denominator {denominator}\n  {}\n\n  // Accessors\n  int getNumerator() const { return m_numerator; }\n  int getDenominator() const { return m_denominator; }\n  \n  // Mutators\n  void setNumerator(int numerator) { m_numerator = numerator; }\n  void setDenominator(int denominator) { m_denominator = denominator; }\n  \n  // Casting operators (could be non-explicit as well: is a matter of taste)\n  explicit operator double() const { return static_cast<double>(m_numerator) / m_denominator; }\n  explicit operator float() const { return static_cast<float>(m_numerator) / m_denominator; }\n  \n  // Full support for all comparison operators with both Rational and double\n  // through the magic of the spaceship operator. \n  // The only other operator you need to define here is equality\n  // (because the spaceship operator cannot be defaulted).\n  auto operator<=>(const Rational& other)\n  {\n    return m_numerator * other.m_denominator <=> other.m_numerator * m_denominator;\n  }\n  auto operator<=>(double value)\n  {\n    return static_cast<double>(*this) <=> value;\n  }\n  bool operator==(const Rational& other)\n  {\n    return m_numerator * other.m_denominator == other.m_numerator * m_denominator;\n  }\n  bool operator==(double value)\n  {\n    return static_cast<double>(*this) == value;\n  }\n\n  // Unary arithmetic operator\n  Rational operator-() const { return Rational{-m_numerator, m_denominator}; }   \n  \n  // A Rational is false if and only if its numerator equals zero.\n  // Note: for operator bool(), we used explicit here to sidestep ambiguities with other operators.\n  // We did not add operator!, \n  // because this conversion operator covers all use in Boolean expressions \n  // (see also previous exercise).\n  explicit operator bool() const  { return m_numerator != 0; }         \n  \n  // Compound assignment operators\n  Rational& operator+=(const Rational& other)\n  {\n    m_numerator = m_numerator * other.m_denominator + other.m_numerator * m_denominator;\n    m_denominator = m_denominator * other.m_denominator;\n    return *this;\n  };\n  Rational& operator-=(const Rational& other)\n  { \n    m_numerator = m_numerator * other.m_denominator - other.m_numerator * m_denominator;\n    m_denominator = m_denominator * other.m_denominator;\n    return *this;\n  };\n  Rational& operator*=(const Rational& other)\n  { \n    m_numerator *= other.m_numerator;\n\t  m_denominator *= other.m_denominator;\n\t  return *this;\n  };\n  Rational& operator/=(const Rational& other)\n  { \n    m_numerator *= other.m_denominator;\n    m_denominator *= other.m_numerator;\n    return *this;\n  };\n\n  // Prefix and postfix increment and decrement operators\n  Rational& operator++() \n  { \n    m_numerator += m_denominator;\n    return *this;\n  }\n  const Rational operator++(int)\n  {\n    auto copy(*this);   // Create a copy of the current object\n    ++(*this);          // Increment the current object using the prefix operator...\n    return copy;        // Return the unincremented copy\n  }\n  Rational& operator--() \n  { \n    m_numerator -= m_denominator;\n    return *this;\n  }\n\n  const Rational operator--(int)\n  {\n    auto copy(*this);   // Create a copy of the current object\n    --(*this);          // Increment the current object using the prefix operator...\n    return copy;        // Return the unincremented copy\n  }\n\nprivate:\n  int m_numerator, m_denominator;\n};\n\n// Stream output operator\ninline std::ostream& operator<<(std::ostream& stream, const Rational& r)\n{\n\treturn stream << r.getNumerator() << '/' << r.getDenominator();\n}\n\n// Binary arithmetic operators: non-member functions to allow for implicit conversions\n// This allows expressions such as 2 * (myRationale + 1)\ninline Rational operator+(const Rational& one, const Rational& other) { auto copy{ one }; return copy += other; }\ninline Rational operator-(const Rational& one, const Rational& other) { auto copy{ one }; return copy -= other; }\ninline Rational operator*(const Rational& one, const Rational& other) { auto copy{ one }; return copy *= other; }\ninline Rational operator/(const Rational& one, const Rational& other) { auto copy{ one }; return copy /= other; }\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_07/Soln13_07.cpp",
    "content": "// Exercise 13-7\n// Rational operators\n#include <iostream>\n#include \"Rational.h\"\n\nint main()\n{\n  Rational x{3, 4};\n  Rational y{1, 2};\n  \n  std::cout << \"x = \" << x << std::endl;\n  std::cout << \"y = \" << y << std::endl;\n  \n  std::cout << \"x = \" << static_cast<float>(x) << std::endl;\n  std::cout << \"y = \" << static_cast<double>(y) << std::endl;\n  \n  std::cout << \"-x = \" << -x << std::endl;\n  \n  std::cout << \"x + y = \" << x + y << std::endl;\n  std::cout << \"x - y = \" << x - y << std::endl;\n  std::cout << \"x * y = \" << x * y << std::endl;\n  std::cout << \"x / y = \" << x / y << std::endl;\n  \n  std::cout << \"x + 2 = \" << x + 2 << std::endl;\n  std::cout << \"3 - y = \" << 3 - y << std::endl;\n  std::cout << \"x * 4 = \" << x * 4 << std::endl;\n  std::cout << \"5 / y = \" << 5 / y << std::endl;\n  \n  std::cout << std::boolalpha;  // Print true and false as \"true\" and \"false\" instead of \"1\" and \"0\"\n  std::cout << \"x < y = \" << (x < y) << std::endl;\n  std::cout << \"x > y = \" << (x > y) << std::endl;\n  std::cout << \"x == y = \" << (x == y) << std::endl;\n  std::cout << \"x != y = \" << (x != y) << std::endl;\n  std::cout << \"x >= y = \" << (x >= y) << std::endl;\n  std::cout << \"x >= y = \" << (x <= y) << std::endl;\n  \n  std::cout << \"x < 1 = \" << (x < 1) << std::endl;\n  std::cout << \"2 > y = \" << (2 > y) << std::endl;\n  std::cout << \"x == 3 = \" << (x == 3) << std::endl;\n  std::cout << \"4 != y = \" << (4 != y) << std::endl;\n  std::cout << \"x >= 5 = \" << (x >= 5) << std::endl;\n  std::cout << \"6 >= y = \" << (6 <= y) << std::endl;\n  \n  std::cout << \"x < 1.0 = \" << (x < 1.0) << std::endl;\n  std::cout << \"2 > y = \" << (2.0 > y) << std::endl;\n  std::cout << \"x == 0.75 = \" << (x == 0.75) << std::endl;\n  std::cout << \"1.5 != y = \" << (1.5 != y) << std::endl;\n  std::cout << \"x >= 5 = \" << (x >= 5.0) << std::endl;\n  std::cout << \"6 >= y = \" << (6.0 <= y) << std::endl;\n  \n  x += Rational(1, 4);\n  std::cout << \"x += 1/4 --> x = \" << x << std::endl;\n  x *= 2;\n  std::cout << \"x *= 2 --> x = \" << x << std::endl;\n  \n  y += 1;\n  std::cout << \"y += 1 --> y = \" << y << std::endl;\n  \n  std::cout << \"y++ = \" << y++ << std::endl;\n  std::cout << \"y = \" << y << std::endl;\n  std::cout << \"--y = \" << --y << std::endl;\n}\n\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_08/Box.cpp",
    "content": "#include \"Box.h\"\n\n#include <format>\n#include <cmath>    // For the min() and max() function templates\n\ndouble Box::volume() const\n{\n    return m_length * m_width * m_height;\n}\n\n// Overloaded += operator\nBox& Box::operator+=(const Box& aBox)\n{\n  // New object has larger length and width, and sum of heights\n  m_length = std::max(m_length, aBox.m_length);\n  m_width = std::max(m_width, aBox.m_width);\n  m_height += aBox.m_height;\n  return *this;\n}\n\n// Function to add two Box objects\nBox Box::operator+(const Box& aBox) const\n{\n  Box copy{ *this };\n  copy += aBox;\n  return copy;\n}\n\nstd::partial_ordering Box::operator<=>(const Box& aBox) const\n{\n  return volume() <=> aBox.volume();\n}\n\nstd::partial_ordering Box::operator<=>(double value) const\n{\n  return volume() <=> value;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box)\n{\n  stream << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\",\n                          box.getLength(), box.getWidth(), box.getHeight());\n  return stream;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_08/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <compare>  // For std::partial_ordering (see Chapter 4)\n#include <ostream>  // For std::ostream\n\nclass Box\n{\npublic:\n  Box() = default;       // Default constructor\n  Box(double length, double width, double height)\n    : m_length{ std::max(length,width) }\n    , m_width { std::min(length,width) }\n    , m_height{ height } \n  {}\n\n  double volume() const; // Function to calculate the volume\n  \n  // Accessors\n  double getLength() const { return m_length; }\n  double getWidth() const  { return m_width; }\n  double getHeight() const { return m_height; }\n\n  // Functions that add full support for comparison operators\n  std::partial_ordering operator<=>(const Box& aBox) const;\n  std::partial_ordering operator<=>(double value) const;\n  bool operator==(const Box& aBox) const = default;\n\n  Box& operator+=(const Box& aBox);      // Function to add a Box objects\n  Box operator+(const Box& aBox) const; // Function to add two Box objects\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\nstd::ostream& operator<<(std::ostream& stream, const Box& box);\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_08/PRNG.h",
    "content": "#ifndef PRNG_H\n#define PRNG_H\n\nclass PseudoRandomNumberGenerator\n{\npublic:\n  PseudoRandomNumberGenerator(int n = 0)\n    : m_n{ n }\n  {}\n\n  // A function call operator (no parameters, return type int)\n  // Unlike many function call operators, this one alters the state of the object.\n  int operator()()\n  {\n    const int current{ m_n };\n    m_n = (m_n * 41 + 7) % 100; // See chapter 12\n    return current;\n  }\n\nprivate:\n  int m_n;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_08/Soln13_08.cpp",
    "content": "// Exercise 13-8\n// Creating a simply pseudo-random number generator (PRNG) functor class.\n// Ours is a very limited one that generates numbers between 0 and 100.\n// Seeding and using it requires some type conversions,\n// but other than that our PRNG functor acts as a drop-in replacement to the original one!\n#include <iostream>\n#include <format>\n#include <vector>\n#include <random>       // For random number generation\n#include <functional>   // For std::bind()\n#include \"Box.h\"\n#include \"PRNG.h\"\n\nint main()\n{\n  const double limit {99};       // Upper limit on Box dimensions\n\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  auto random{ PseudoRandomNumberGenerator{ static_cast<int>(seeder()) } };\n\n  const size_t boxCount {20}; // Number of Box object to be created\n  std::vector<Box> boxes;     // Vector of Box objects\n\n  // Create 20 Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    boxes.push_back(Box{ static_cast<double>(random()), static_cast<double>(random()), static_cast<double>(random()) });\n\n  size_t first {};     // Index of first Box object of pair\n  size_t second {1};   // Index of second Box object of pair\n  double minVolume {(boxes[first] + boxes[second]).volume()};\n\n  for (size_t i {}; i < boxCount - 1; ++i)\n  {  \n    for (size_t j {i + 1}; j < boxCount; j++)\n    {\n      if (boxes[i] + boxes[j] < minVolume)\n      {\n        first = i;\n        second = j;\n        minVolume = (boxes[i] + boxes[j]).volume();\n      }\n    }\n  }\n\n  std::cout << \"The two boxes that sum to the smallest volume are \"\n            << boxes[first] << \" and \" << boxes[second] << '\\n';\n  std::cout << std::format(\"The volume of the first box is {:.1f}\\n\",\n                            boxes[first].volume());\n  std::cout << std::format(\"The volume of the second box is {:.1f}\\n\",\n                            boxes[second].volume());\n  std::cout << \"The sum of these boxes is \" << (boxes[first] + boxes[second]) << '\\n';\n  std::cout << std::format(\"The volume of the sum is {:.1f}\", minVolume) << std::endl;\n\n  Box sum{ 0, 0, 0 };            // Start from an empty Box\n  for (const auto& box : boxes)  // And then add all randomly generated Box objects\n    sum += box;\n\n  std::cout << \"The sum of \" << boxCount << \" random boxes is \" << sum << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_09/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <ostream>\n#include <format>\n#include <algorithm>    // For the std::min()/max() function templates\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  int compare(const Box& box) const\n  {\n    if (volume() < box.volume()) return -1;\n    if (volume() == box.volume()) return 0;\n    return +1;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f},{:.1f},{:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\n  Box operator+(const Box& aBox) const   // Function to add two Box objects\n  {\n    return Box{ std::max(m_length, aBox.m_length),\n                std::max(m_width, aBox.m_width),\n                m_height + aBox.m_height }; \n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_09/Soln13_09.cpp",
    "content": "// Exercise 13-9\n// Adding an assignment operator for Truckload\n#include <iostream>\n#include <memory>\n#include <random>       // For random number generation\n#include <functional>   // For std::bind()\n#include \"Truckload.h\"\n\n// See Chapter 12 for an explanation of this function\nauto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 1.0, max }; // Generate in [1, max) interval\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\nint main()\n{\n  const double limit{ 99.0 };    // Upper limit on Box dimensions\n  auto random{ createUniformPseudoRandomNumberGenerator(limit) };\n\n  Truckload load;\n  const size_t boxCount {20};               // Number of Box object to be created\n\n  // Create boxCount Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    load.addBox(std::make_shared<Box>(random(), random(), random()));\n\n  std::cout << \"The boxes in the Truckload are:\\n\";\n  std::cout << load << std::endl;\n\n  Truckload copied;\n  copied = load;\t\t// Use copy assignment\n \n  std::cout << \"The boxes in the copied Truckload are:\\n\";\n  std::cout << copied;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_09/Truckload.cpp",
    "content": "#include \"Truckload.h\"\n\n#include <iostream>\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\nTruckload& Truckload::operator=(const Truckload& other)\n{\n  if (&other != this)   // Do not forget: avoid issues with self-assignment!\n  {\n    delete m_head;              // Delete all current packages\n    m_head = m_tail = nullptr;  // Reset both pointers\n\n    // Same as copy constructor \n    // (see Chapter 17 for the copy-and-swap idiom that allows you to avoid \n    // duplicating logic like this...)\n    for (Package* package{ other.m_head }; package; package = package->m_next)\n    {\n      addBox(package->m_box);\n    }\n  }\n\n  return *this;\n}\n\n// Destructor: clean up the list\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nSharedBox& Truckload::operator[](size_t index) const\n{\n  size_t count{};             // Package count\n  for (Package* package{ m_head }; package; package = package->m_next)\n  {\n    if (count++ == index)      // Up to index yet?\n      return package->m_box;   // If so return the pointer to Box\n  }\n  return nullBox;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 13/Soln13_09/Truckload.h",
    "content": "#ifndef TRUCKLOAD_H\n#define TRUCKLOAD_H\n\n#include \"Box.h\"\n\n#include <memory>\n#include <vector>\n#include <ostream>\n\nusing SharedBox = std::shared_ptr<Box>;\n\nclass Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  \n  Truckload(const Truckload& src);  // Copy constructor\n  Truckload& operator=(const Truckload& other);  // Copy assignment operator\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox& operator[](size_t index) const;   // Overloaded subscript operator\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n\n  static inline SharedBox nullBox{}; // Pointer to nullptr\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load);\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 14/Soln14_01/Animals.cpp",
    "content": "// Implementations of the Animal class and classes derived from Animal\n\n#include <iostream>\n#include \"Animals.h\"\n\n// Constructor\nAnimal::Animal(std::string_view name, int weight) \n\t: m_name{name}, m_weight{weight}\n{}\n\n// Identify the animal\nvoid Animal::who() const\n{\n  std::cout << \"My name is \" << m_name << \" and I weigh \" << m_weight << \"lbs.\" << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 14/Soln14_01/Animals.h",
    "content": "// Animal class and classes derived from Animal\n\n// Note: Animal, Lion, and Aardvark would typically be declared each in their \n// own header files, and then defined in three corresponding source files as well.\n// This example shows that this does not have to be the case; \n// that is:\n//  - file names do not have to match the name of a class; and\n//  - multiple classes may be declared and defined in the same file\n\n#ifndef ANIMALS_H\n#define ANIMALS_H\n\n#include <string>\n#include <string_view>\n\nclass Animal\n{\npublic:\n  Animal(std::string_view name, int weight);    // Constructor\n  \n  void who() const;                 // Display name and weight\n\nprivate:\n  std::string m_name;                    // Name of the animal\n  int m_weight;                        // Weight of the animal\n};\n\nclass Lion : public Animal\n{\npublic:\n  // Define Lion constructor that calls base class constructor\n  Lion(std::string_view name, int weight)  \n\t  : Animal{name, weight} {}\n};\n\nclass Aardvark : public Animal\n{\npublic:\n  using Animal::Animal;  // Inherit constructor instead (preferred)\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 14/Soln14_01/Soln14_01.cpp",
    "content": "// Exercise 14-1 Exercising the Animal classes\n// The solution shows two options, with the second one being the preferred option.\n#include \"Animals.h\"\n\nint main()\n{\n  Lion myLion{\"Leo\", 400};\n  Aardvark myAardvark{\"Algernon\", 50};\n  myLion.who();\n  myAardvark.who();\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 14/Soln14_02/Animals.cpp",
    "content": "// Implementations of the Animal class and classes derived from Animal\n\n#include <iostream>\n#include \"Animals.h\"\n\n// Constructor\nAnimal::Animal(std::string_view name, int weight) \n\t: m_name{name}, m_weight{weight}\n{}\n\n// Identify the animal\nvoid Animal::who() const\n{\n  std::cout << \"My name is \" << m_name << \" and I weigh \" << m_weight << \"lbs.\" << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 14/Soln14_02/Animals.h",
    "content": "// Animal class and classes derived from Animal\n\n#ifndef ANIMALS_H\n#define ANIMALS_H\n\n#include <string>\n#include <string_view>\n\nclass Animal\n{\npublic:\n  Animal(std::string_view name, int weight);    // Constructor\n\nprotected:\n  void who() const;                 // Display name and weight\n\nprivate:\n  std::string m_name;                    // Name of the animal\n  int m_weight;                        // Weight of the animal\n};\n\nclass Lion : public Animal\n{\npublic:\n  // Define Lion constructor that calls base class constructor\n  Lion(std::string_view name, int weight)  \n\t  : Animal{name, weight} {}\n\n  // Create function in derived class that hides and explicitly \n  // invokes the protected function of the base class\n  void who() { return Animal::who(); }\n};\n\nclass Aardvark : public Animal\n{\npublic:\n  using Animal::Animal;   // Inherit constructor instead (preferred)\n  using Animal::who;      // Use using to alter acccess specifier instead (preferred)\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 14/Soln14_02/Soln14_02.cpp",
    "content": "// Exercise 14-2 The who() function for the base class has the protected access specifier,\n// so we ensure the derived classes allow public access to the who() function. \n// The solution shows two alternatives, the second one being the preferred option.\n\n#include \"Animals.h\"\n\nint main()\n{\n  Lion myLion{\"Leo\", 400};\n  Aardvark myAardvark{\"Algernon\", 50};\n  myLion.who();\n  myAardvark.who();\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 14/Soln14_03/Animals.cpp",
    "content": "// Exercise 14-3 - Animals.cpp\n// Implementations of the Animal class and classes derived from Animal\n\n#include <iostream>\n#include \"Animals.h\"\n\n// Constructor\nAnimal::Animal(std::string_view name, int weight) \n\t: m_name{name}, m_weight{weight} {}\n\n// Identify the animal\nvoid Animal::who() const\n{\n  std::cout << \"My name is \" << m_name << \" and I weigh \" << m_weight << \"lbs.\" << std::endl;\n}\n\n// Identify the Lion\nvoid Lion::who() const\n{\n  std::cout << \"Rrroarrrr... I am a lion. \";\n  Animal::who();                       // Call base function\n}\n\n// Identify the Aardvark\nvoid Aardvark::who() const\n{\n  Animal::who();                       // Call base function\n  std::cout << \"Oh. And I'm an aardvark. \" << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 14/Soln14_03/Animals.h",
    "content": "// Animal class and classes derived from Animal\n\n#ifndef ANIMALS_H\n#define ANIMALS_H\n\n#include <string>\n#include <string_view>\n\nclass Animal\n{\npublic:\n  Animal(std::string_view name, int weight);    // Constructor\n  \n  void who() const;                 // Display name and weight\n\nprivate:\n  std::string m_name;                    // Name of the animal\n  int m_weight;                        // Weight of the animal\n};\n\nclass Lion : public Animal\n{\npublic:\n  // Define Lion constructor that calls base class constructor\n  Lion(std::string_view name, int weight)  \n\t: Animal{name, weight} {}\n\n  void who() const;           // Define Lion-specific function\n};\n\nclass Aardvark : public Animal\n{\npublic:\n  using Animal::Animal;                 // Inherit constructor\n  \n  void who() const;       // Define Aardvark-specific function\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 14/Soln14_03/Soln14_03.cpp",
    "content": "// Exercise 14-3 By adding a few lines to the test program, we can see the difference \n// between the calls to the base class and derived class who() functions. \n\n#include <iostream>\n#include \"Animals.h\"\n\nint main()\n{\n  Lion myLion{\"Leo\", 400};\n  Aardvark myAardvark{\"Algernon\", 50};\n  std::cout << \"Calling derived versions of who():\\n\";\n  myLion.who();\n  myAardvark.who();\n\n  std::cout << \"\\nCalling base versions of who():\\n\";\n  myLion.Animal::who();     // By qualifying the base class\n  static_cast<Animal&>(myAardvark).who();     // By casting\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 14/Soln14_04/Person.cpp",
    "content": "// Person class implementation\n\n#include \"Person.h\"\n#include <iostream>\n\nPerson::Person(size_t age, std::string_view name, Gender gender) \n  : m_age {age}, m_name {name}, m_gender {gender}\n{\n  // Instead of just initializing the members with the argument values, \n  // you could validate the arguments by doing reasonableness checks. \n  // e.g. Name mustn't be empty, and age should be less than 130 say.\n  // To handle a failure sensibly we really need exceptions, \n  // but we don't get to those until chapter 16. \n}\n\n// Display details of Person object\nvoid Person::who() const \n{\n  std::cout << \"\\nThis is \" << m_name << \" who is \" << m_age << \" years old.\" << std::endl;\n}\n\nvoid Person::haveBirthday()\n{\n\t++m_age;\n}\n\nstd::string_view Person::getGenderString() const\n{\n  switch (m_gender)\n  {\n  case Gender::male:   return \"a male\";\n  case Gender::female: return \"a female\";\n  case Gender::other:  return \"an other-gendered\";\n  }\n\n  // Unreachable return statement required by some compilers \n  // (switch statement is exhaustive)\n  return {};\n}\n\n// Display details of Employee object\nvoid Employee::who() const\n{\n  std::cout << getName() << \" is \" << getGenderString() << \" employee aged \" << getAge() << \".\" << std::endl;\n}\n\n// Display details of Executive object (execs are particularly sensitive about their age...)\nvoid Executive::who() const\n{\n  std::cout << getName() << \" is \" << getGenderString() << \" executive.\" << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 14/Soln14_04/Person.h",
    "content": "// Person class and classes derived from Person\n#ifndef PERSON_H\n#define PERSON_H\n\n#include <string>\n#include <string_view>\n\n/*\n  We covered the advantages of the principle of data hiding extensively in Chapter 12.\n  In practice, a common convention is to make all data members of a class private. \n  This should thus probably become your default as well. \n  Getter and setter member functions can then be added to either the public \n  or protected interface to control access and/or modifications.\n   \n  Alternatively, you could make the member variables of Person and Employee themselves protected.\n  Often, people take this shortcut because it is somewhat less work:\n  then you wouldn't need the protected getter functions.\n  However, protected data is a bad idea, much for the same reason as public ones are.\n  We refer to the corresponding section in Chapter 14 for a more detailed motivation.\n*/\n\n// Possible alternatives for representing a gender include:\n//  - a Boolean value, but limited, and which is the 'true' gender?\n//  - a char value (say 'm', 'f', 'o'), but then how to enforce that no other values are assigned?\n//  - a string (\"male\", \"female\", etc), but same problem as with chars (and also excessively expensive)\n// The safest, most readable solution is therefore probably an enumeration:\nenum class Gender { male, female, other };\n\nclass Person\n{\npublic:\n  Person() = default;   // Default constructor - necessary to define arrays\n  Person(size_t age, std::string_view name, Gender gender);\n  \n  void who() const;     // Display details\n  \n  void haveBirthday();\n\nprotected:  \n  // Functions to allow derived classes to access to a Person's details\n  size_t getAge() const    { return m_age; } \n  const std::string& getName() const { return m_name; }\n  Gender getGender() const { return m_gender; }\n  \n  // Convenience function:\n  std::string_view getGenderString() const;\n\nprivate:\n  size_t m_age{};      // Age in years\n  std::string m_name;\n  Gender m_gender{ Gender::female };\n};\n\nclass Employee : public Person\n{\npublic:\n  Employee() = default;   // Default constructor - necessary to define arrays\n  Employee(size_t age, std::string_view name, Gender gender, long num)\n    : Person{age, name, gender}, m_personnelNumber {num} {}\n  \n  void who() const;       // Display details\n\nprotected:\n  long getPersonnelNumber() { return m_personnelNumber; }\n\nprivate:\n  long m_personnelNumber{};\n};\n\nclass Executive : public Employee\n{\npublic:\n  using Employee::Employee;   // Inherit all constructors\n  \n  void who() const;           // Display details\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 14/Soln14_04/Soln14_04.cpp",
    "content": "// Exercise 14-4 Working with Employee and Executive objects\n\n#include <iostream>\n#include <vector>\n#include \"Person.h\"\n\nint main()\n{\n  std::vector<Employee> employees\n  {\n    Employee{ 21, \"Randy Marathon\", Gender::male, 34567 },\n    Employee{ 32, \"Anna Pothecary\", Gender::female, 34578 },\n    Employee{ 46, \"Peter Out\", Gender::male, 34589 },\n    Employee{ 37, \"Sheila Rangeit\", Gender::female, 34598 },\n    Employee{ 65, \"Jack Ittin\", Gender::male, 34667 }\n  };\n\n  for (const auto& employee : employees)\n    employee.who();\n\n  std::cout << std::endl;\n\n  // Note: explicitly specifying the type in front of every {...} \n  // in a vector's initializer list, like we did for Employees, \n  // is actually not required...\n  std::vector<Executive> executives\n  {\n    { 44, \"Irwin Pootlemeyer\", Gender::other, 35567 },\n    { 32, \"Alexa Workwell\", Gender::female, 35578 },\n    { 42, \"Steve Stove\", Gender::male, 35589 },\n    { 33, \"Sue Neenuf\", Gender::female, 35598 },\n    { 29, \"Melanie Clair\", Gender::female, 35667 }\n  };\n\n  for (const auto& executive : executives)\n  {\n    executive.who();\n    executive.Employee::who();  // Executive, I shall know thy age!\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_01/Animals.cpp",
    "content": "// Implementations of the Animal class and classes derived from Animal\n\n#include \"Animals.h\"\n\n// Constructor\nAnimal::Animal(std::string_view name, unsigned weight) \n  : m_name{ name }, m_weight{ weight }\n{}\n\n// Return string describing the animal\nstd::string Animal::who() const\n{\n  return \"My name is \" + m_name + \". My weight is \" + std::to_string(m_weight) + \" lbs.\";\n}\n\n// Make like a sheep\nstd::string_view Sheep::sound() const\n{\n  return \"Baaaa!!\";\n}\n\n// Make like a dog\nstd::string_view Dog::sound() const\n{\n  return \"Woof woof!!\";\n}\n\n// Make like a cow\nstd::string_view Cow::sound() const\n{\n  return \"Mooooo!!\";\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_01/Animals.h",
    "content": "// Exercise 15-1 Animals.h \n// Animal classes\n#ifndef ANIMALS_H\n#define ANIMALS_H\n\n#include <string>\n#include <string_view>\n\nclass Animal\n{\npublic:\n  Animal(std::string_view name, unsigned weight);// Constructor\n  virtual ~Animal() = default;                   // Very important: a virtual destructor!\n  virtual std::string who() const;               // Return string containing name and weight\n  virtual std::string_view sound() const = 0;    // Return the sound of an animal\n\nprivate:\n  std::string m_name;                            // Name of the animal\n  unsigned m_weight;                             // Weight of the animal\n};\n\nclass Sheep : public Animal\n{\npublic:\n  using Animal::Animal;                          // Inherit constructor\n  std::string_view sound() const override;       // Return the sound of a sheep\n};\n\nclass Dog : public Animal\n{\npublic:\n  using Animal::Animal;                          // Inherit constructor\n  std::string_view sound() const override;       // Return the sound of a dog\n};\n\nclass Cow : public Animal\n{\npublic:\n  using Animal::Animal;                          // Inherit constructor\n  std::string_view sound() const override;       // Return the sound of a cow\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_01/Soln15_01.cpp",
    "content": "// Exercise 15-1 Exercising Zoo and Animal classes\n#include \"Zoo.h\"\n#include <random>     // For random number generation\n#include <functional> // For std::bind()\n#include <iostream>\n#include <array>\n#include <string_view>\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main() \n{\n  const size_t num_name_options{ 10 };\n  using NameOptions = std::array<std::string_view, num_name_options>;\n\n  const NameOptions dogNames {\n    \"Fido\", \"Rover\"  , \"Lassie\" , \"Lambikins\",  \"Poochy\",\n    \"Spit\", \"Gnasher\", \"Samuel\" , \"Wellington\", \"Patch\"\n  };\n  const NameOptions sheepNames {\n    \"Bozo\",    \"Killer\", \"Tasty\", \"Pete\", \"Chops\",\n    \"Blackie\", \"Whitey\", \"Eric\" , \"Sean\", \"Shep\"\n  };\n  const NameOptions cowNames {\n    \"Dolly\", \"Daisy\",   \"Shakey\", \"Amy\",   \"Dilly\",\n    \"Dizzy\", \"Eleanor\", \"Zippy\" , \"Zappy\", \"Happy\"\n  };\n\n  const unsigned minDogWt{ 1 };     // Minimum weight of a dog in pounds\n  const unsigned maxDogWt{ 120 };   // Maximum weight of a dog in pounds\n  const unsigned minSheepWt{ 80 };  // Minimum weight of a dog in pounds\n  const unsigned maxSheepWt{ 150 }; // Maximum weight of a dog in pounds\n  const unsigned minCowWt{ 800 };   // Minimum weight of a dog in pounds\n  const unsigned maxCowWt{ 1500 };  // Maximum weight of a dog in pounds\n\n  auto randomAnimalType { createUniformPseudoRandomNumberGenerator(0, 2) }; // 0, 1, or 2\n  auto randomNameIndex  { createUniformPseudoRandomNumberGenerator(0, num_name_options - 1) };\n  auto randomDogWeight  { createUniformPseudoRandomNumberGenerator(minDogWt, maxDogWt) };\n  auto randomSheepWeight{ createUniformPseudoRandomNumberGenerator(minSheepWt, maxSheepWt) };\n  auto randomCowWeight  { createUniformPseudoRandomNumberGenerator(minCowWt, maxCowWt) } ;\n\n  std::vector<AnimalPtr> animals;   // Stores smart pointers to animals\n  size_t numAnimals {};             // Number of animals to be created\n  std::cout << \"How many animals in the zoo? \";\n  std::cin >> numAnimals;\n  \n  Zoo zoo;                  // Create an empty Zoo\n  \n  // Create random animals and add them to the Zoo\n  for (size_t i {}; i < numAnimals; ++i)\n  {\n    switch (randomAnimalType())\n    {\n    case 0:                // Create a sheep\n      zoo.addAnimal(std::make_shared<Sheep>(sheepNames[randomNameIndex()], randomSheepWeight()));\n      break;\n    case 1:                // Create a dog\n      zoo.addAnimal(std::make_shared<Dog>(dogNames[randomNameIndex()], randomDogWeight()));\n      break;\n    case 2:                // Create a cow\n      zoo.addAnimal(std::make_shared<Cow>(cowNames[randomNameIndex()], randomCowWeight()));\n      break;\n    }\n  }\n  \n  zoo.showAnimals();                             // Display the animals\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_01/Zoo.cpp",
    "content": "// Implementations of the Zoo class that stores pointers to Animals\n#include \"Zoo.h\"\n#include \"Animals.h\"\n#include <iostream>\n\n// Constructor from a vector of animals\nZoo::Zoo(const std::vector<AnimalPtr>& animals) \n  : m_animals{ animals } \n{}\n\n// Add an animal to the zoo\nvoid Zoo::addAnimal(AnimalPtr animal)\n{\n  m_animals.push_back(animal);\n}\n\n// Output the animals and the sound they make\nvoid Zoo::showAnimals() const\n{\n  for (const auto& animal : m_animals)\n  {\n    std::cout << animal->who() << ' ' << animal->sound() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_01/Zoo.h",
    "content": "// The Zoo class representing a collection of animals \n#ifndef ZOO_H\n#define ZOO_H\n\n#include \"Animals.h\"\n#include <vector>\n#include <memory>\n\nusing AnimalPtr = std::shared_ptr<Animal>;         // Define a type alias for convenience\n\nclass Zoo\n{\npublic:\n  Zoo() = default;                                 // Default constructor for an empty zoo\n  Zoo(const std::vector<AnimalPtr>& new_animals);  // Constructor from a vector of animals\n  virtual ~Zoo() = default;                        // Add a virtual destructor to allow classes to safely derive from Zoo;\n                                                   // possible examples of Zoo specializations include SafariPark, PettingZoo, ...\n  void addAnimal(AnimalPtr animal);                // Add an animal to the zoo\n  void showAnimals() const;                        // Output the animals and the sound they make\n\nprivate:\n  std::vector<AnimalPtr> m_animals;      // Stores pointers to the animals\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_02/Animals.cpp",
    "content": "// Implementations of the Animal class and classes derived from Animal\n\n#include \"Animals.h\"\n\n// Constructor\nAnimal::Animal(std::string_view name, unsigned weight) \n  : m_name{ name }, m_weight{ weight }\n{}\n\n// Return string describing the animal\nstd::string Animal::who() const\n{\n  return \"My name is \" + m_name + \". My weight is \" + std::to_string(m_weight) + \" lbs.\";\n}\n\n// Sheep constructors\nSheep::Sheep(std::string_view name, unsigned weight)\n  : Sheep{name, weight, static_cast<unsigned>(0.1 * weight)}\n{\n}\n\nSheep::Sheep(std::string_view name, unsigned weight, unsigned wool)\n  : Animal{name, weight}\n  , m_wool_weight{wool}\n{\n}\n\n// Override the behaviour of who() for Sheep to prepend \"Woolly \" to their name, \n// and subtract the weight of their wool from weight.\nstd::string Sheep::who() const\n{\n  return \"My name is Woolly \" + getName() + \". My weight is \" + std::to_string(getWeight() - m_wool_weight) + \" lbs.\";\n}\n\n// Make like a sheep\nstd::string_view Sheep::sound() const\n{\n  return \"Baaaa!!\";\n}\n\n// Make like a dog\nstd::string_view Dog::sound() const\n{\n  return \"Woof woof!!\";\n}\n\n// Override the behaviour of who() for Cows to hide their weight\nstd::string Cow::who() const\n{\n  return \"My name is \" + getName() + \".\";\n}\n\n// Make like a cow\nstd::string_view Cow::sound() const\n{\n  return \"Mooooo!!\";\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_02/Animals.h",
    "content": "// Animal classes\n#ifndef ANIMALS_H\n#define ANIMALS_H\n\n#include <string>\n#include <string_view>\n\nclass Animal\n{\npublic:\n  Animal(std::string_view name, unsigned weight);  // Constructor\n  virtual ~Animal() = default;                     // Very important: a virtual destructor!\n  \n  virtual std::string who() const;                 // Return string containing name and weight\n  virtual std::string_view sound() const = 0;      // Return the sound of an animal\n\nprotected:              // Protected getters for use in derived classes\n  const std::string& getName() const { return m_name; }\n  unsigned getWeight() const { return m_weight; }\n\nprivate:\n  std::string m_name;   // Name of the animal\n  unsigned m_weight;    // Weight of the animal\n};\n\nclass Sheep : public Animal\n{\npublic:\n  Sheep(std::string_view name, unsigned weight);\n  Sheep(std::string_view name, unsigned weight, unsigned wool);\n  \n  std::string who() const override;         // Override the behaviour of who() for Sheep\n  std::string_view sound() const override;  // Return the sound of a sheep\n\nprivate:\n  unsigned m_wool_weight;\n};\n\nclass Dog : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string_view sound() const override;  // Return the sound of a dog\n};\n\nclass Cow : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string who() const override;         // Override the behaviour of who() for Cows\n  std::string_view sound() const override;  // Return the sound of a cow\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_02/Soln15_02.cpp",
    "content": "// Exercise 15-2 Exercising Zoo and Animal classes\n#include \"Zoo.h\"\n#include <random>     // For random number generation\n#include <functional> // For std::bind()\n#include <iostream>\n#include <array>\n#include <string_view>\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main() \n{\n  const size_t num_name_options{ 10 };\n  using NameOptions = std::array<std::string_view, num_name_options>;\n\n  const NameOptions dogNames {\n    \"Fido\", \"Rover\"  , \"Lassie\" , \"Lambikins\",  \"Poochy\",\n    \"Spit\", \"Gnasher\", \"Samuel\" , \"Wellington\", \"Patch\"\n  };\n  const NameOptions sheepNames {\n    \"Bozo\",    \"Killer\", \"Tasty\", \"Pete\", \"Chops\",\n    \"Blackie\", \"Whitey\", \"Eric\" , \"Sean\", \"Shep\"\n  };\n  const NameOptions cowNames {\n    \"Dolly\", \"Daisy\",   \"Shakey\", \"Amy\",   \"Dilly\",\n    \"Dizzy\", \"Eleanor\", \"Zippy\" , \"Zappy\", \"Happy\"\n  };\n\n  const unsigned minDogWt{ 1 };     // Minimum weight of a dog in pounds\n  const unsigned maxDogWt{ 120 };   // Maximum weight of a dog in pounds\n  const unsigned minSheepWt{ 80 };  // Minimum weight of a dog in pounds\n  const unsigned maxSheepWt{ 150 }; // Maximum weight of a dog in pounds\n  const unsigned minCowWt{ 800 };   // Minimum weight of a dog in pounds\n  const unsigned maxCowWt{ 1500 };  // Maximum weight of a dog in pounds\n\n  auto randomAnimalType { createUniformPseudoRandomNumberGenerator(0, 2) }; // 0, 1, or 2\n  auto randomNameIndex  { createUniformPseudoRandomNumberGenerator(0, num_name_options - 1) };\n  auto randomDogWeight  { createUniformPseudoRandomNumberGenerator(minDogWt, maxDogWt) };\n  auto randomSheepWeight{ createUniformPseudoRandomNumberGenerator(minSheepWt, maxSheepWt) };\n  auto randomCowWeight  { createUniformPseudoRandomNumberGenerator(minCowWt, maxCowWt) };\n\n  std::vector<AnimalPtr> animals;   // Stores smart pointers to animals\n  size_t numAnimals {};             // Number of animals to be created\n  std::cout << \"How many animals in the zoo? \";\n  std::cin >> numAnimals;\n  \n  Zoo zoo;                  // Create an empty Zoo\n  \n  // Create random animals and add them to the Zoo\n  for (size_t i {}; i < numAnimals; ++i)\n  {\n    switch (randomAnimalType())\n    {\n    case 0:                // Create a sheep\n      zoo.addAnimal(std::make_shared<Sheep>(sheepNames[randomNameIndex()], randomSheepWeight()));\n      break;\n    case 1:                // Create a dog\n      zoo.addAnimal(std::make_shared<Dog>(dogNames[randomNameIndex()], randomDogWeight()));\n      break;\n    case 2:                // Create a cow\n      zoo.addAnimal(std::make_shared<Cow>(cowNames[randomNameIndex()], randomCowWeight()));\n      break;\n    }\n  }\n  \n  zoo.showAnimals();                             // Display the animals\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_02/Zoo.cpp",
    "content": "// Implementations of the Zoo class that stores pointers to Animals\n#include \"Zoo.h\"\n#include \"Animals.h\"\n#include <iostream>\n\n// Constructor from a vector of animals\nZoo::Zoo(const std::vector<AnimalPtr>& animals) \n  : m_animals{ animals } \n{}\n\n// Add an animal to the zoo\nvoid Zoo::addAnimal(AnimalPtr animal)\n{\n  m_animals.push_back(animal);\n}\n\n// Output the animals and the sound they make\nvoid Zoo::showAnimals() const\n{\n  for (const auto& animal : m_animals)\n  {\n    std::cout << animal->who() << ' ' << animal->sound() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_02/Zoo.h",
    "content": "// The Zoo class representing a collection of animals \n#ifndef ZOO_H\n#define ZOO_H\n\n#include \"Animals.h\"\n#include <vector>\n#include <memory>\n\nusing AnimalPtr = std::shared_ptr<Animal>;         // Define a type alias for convenience\n\nclass Zoo\n{\npublic:\n  Zoo() = default;                                 // Default constructor for an empty zoo\n  Zoo(const std::vector<AnimalPtr>& new_animals);  // Constructor from a vector of animals\n  virtual ~Zoo() = default;                        // Add a virtual destructor to allow classes to safely derive from Zoo;\n                                                   // possible examples of Zoo specializations include SafariPark, PettingZoo, ...\n  void addAnimal(AnimalPtr animal);                // Add an animal to the zoo\n  void showAnimals() const;                        // Output the animals and the sound they make\n\nprivate:\n  std::vector<AnimalPtr> m_animals;      // Stores pointers to the animals\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_03/Animals.cpp",
    "content": "// Implementations of the Animal class and classes derived from Animal\n\n#include \"Animals.h\"\n\n// Constructor\nAnimal::Animal(std::string_view name, unsigned weight) \n  : m_name{ name }, m_weight{ weight }\n{}\n\n// Return string describing the animal\nstd::string Animal::who() const\n{\n  return \"My name is \" + m_name + \". My weight is \" + std::to_string(m_weight) + \" lbs.\";\n}\n\n// Sheep constructors\nSheep::Sheep(std::string_view name, unsigned weight)\n  : Sheep{name, weight, static_cast<unsigned>(0.1 * weight)}\n{\n}\n\nSheep::Sheep(std::string_view name, unsigned weight, unsigned wool)\n  : Animal{name, weight}\n  , m_wool_weight{wool}\n{\n}\n\n// Override the behaviour of getName() for Sheep to prepend \"Woolly \"\nstd::string Sheep::getName() const\n{\n  return \"Woolly \" + Animal::getName();\n}\n\n// Override getWeight() to subtract the weight of their wool from weight.\nunsigned Sheep::getWeight() const\n{\n  return Animal::getWeight() - m_wool_weight;\n}\n\n// Make like a sheep\nstd::string_view Sheep::sound() const\n{\n  return \"Baaaa!!\";\n}\n\n// Make like a dog\nstd::string_view Dog::sound() const\n{\n  return \"Woof woof!!\";\n}\n\n// Override the behaviour of who() for Cows to hide their weight\nstd::string Cow::who() const\n{\n  return \"My name is \" + getName() + \".\";\n}\n\n// Make like a cow\nstd::string_view Cow::sound() const\n{\n  return \"Mooooo!!\";\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_03/Animals.h",
    "content": "// Animal classes\n#ifndef ANIMALS_H\n#define ANIMALS_H\n\n#include <string>\n#include <string_view>\n\nclass Animal\n{\npublic:\n  Animal(std::string_view name, unsigned weight);  // Constructor\n  virtual ~Animal() = default;                     // Very important: a virtual destructor!\n  \n  virtual std::string who() const;                 // Return string containing name and weight\n  virtual std::string_view sound() const = 0;      // Return the sound of an animal\n\nprotected:              // Protected getters for use in derived classes\n  virtual std::string getName() const { return m_name; }\n  virtual unsigned getWeight() const { return m_weight; }\n\nprivate:\n  std::string m_name;   // Name of the animal\n  unsigned m_weight;    // Weight of the animal\n};\n\nclass Sheep : public Animal\n{\npublic:\n  Sheep(std::string_view name, unsigned weight);\n  Sheep(std::string_view name, unsigned weight, unsigned wool);\n  \n  std::string_view sound() const override;  // Return the sound of a sheep\n\nprotected:\n  std::string getName() const override;\n  unsigned getWeight() const override;\n\nprivate:\n  unsigned m_wool_weight;\n};\n\nclass Dog : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string_view sound() const override;  // Return the sound of a dog\n};\n\nclass Cow : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string who() const override;         // Override the behaviour of who() for Cows\n  std::string_view sound() const override;  // Return the sound of a cow\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_03/Soln15_03.cpp",
    "content": "// Exercise 15-3 Exercising Zoo and Animal classes\n#include \"Zoo.h\"\n#include <random>     // For random number generation\n#include <functional> // For std::bind()\n#include <iostream>\n#include <array>\n#include <string_view>\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main() \n{\n  const size_t num_name_options{ 10 };\n  using NameOptions = std::array<std::string_view, num_name_options>;\n\n  const NameOptions dogNames {\n    \"Fido\", \"Rover\"  , \"Lassie\" , \"Lambikins\",  \"Poochy\",\n    \"Spit\", \"Gnasher\", \"Samuel\" , \"Wellington\", \"Patch\"\n  };\n  const NameOptions sheepNames {\n    \"Bozo\",    \"Killer\", \"Tasty\", \"Pete\", \"Chops\",\n    \"Blackie\", \"Whitey\", \"Eric\" , \"Sean\", \"Shep\"\n  };\n  const NameOptions cowNames {\n    \"Dolly\", \"Daisy\",   \"Shakey\", \"Amy\",   \"Dilly\",\n    \"Dizzy\", \"Eleanor\", \"Zippy\" , \"Zappy\", \"Happy\"\n  };\n\n  const unsigned minDogWt{ 1 };     // Minimum weight of a dog in pounds\n  const unsigned maxDogWt{ 120 };   // Maximum weight of a dog in pounds\n  const unsigned minSheepWt{ 80 };  // Minimum weight of a dog in pounds\n  const unsigned maxSheepWt{ 150 }; // Maximum weight of a dog in pounds\n  const unsigned minCowWt{ 800 };   // Minimum weight of a dog in pounds\n  const unsigned maxCowWt{ 1500 };  // Maximum weight of a dog in pounds\n\n  auto randomAnimalType { createUniformPseudoRandomNumberGenerator(0, 2) }; // 0, 1, or 2\n  auto randomNameIndex  { createUniformPseudoRandomNumberGenerator(0, num_name_options - 1) };\n  auto randomDogWeight  { createUniformPseudoRandomNumberGenerator(minDogWt, maxDogWt) };\n  auto randomSheepWeight{ createUniformPseudoRandomNumberGenerator(minSheepWt, maxSheepWt) };\n  auto randomCowWeight  { createUniformPseudoRandomNumberGenerator(minCowWt, maxCowWt) };\n\n  std::vector<AnimalPtr> animals;   // Stores smart pointers to animals\n  size_t numAnimals {};             // Number of animals to be created\n  std::cout << \"How many animals in the zoo? \";\n  std::cin >> numAnimals;\n  \n  Zoo zoo;                  // Create an empty Zoo\n  \n  // Create random animals and add them to the Zoo\n  for (size_t i {}; i < numAnimals; ++i)\n  {\n    switch (randomAnimalType())\n    {\n    case 0:                // Create a sheep\n      zoo.addAnimal(std::make_shared<Sheep>(sheepNames[randomNameIndex()], randomSheepWeight()));\n      break;\n    case 1:                // Create a dog\n      zoo.addAnimal(std::make_shared<Dog>(dogNames[randomNameIndex()], randomDogWeight()));\n      break;\n    case 2:                // Create a cow\n      zoo.addAnimal(std::make_shared<Cow>(cowNames[randomNameIndex()], randomCowWeight()));\n      break;\n    }\n  }\n  \n  zoo.showAnimals();                             // Display the animals\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_03/Zoo.cpp",
    "content": "// Implementations of the Zoo class that stores pointers to Animals\n#include \"Zoo.h\"\n#include \"Animals.h\"\n#include <iostream>\n\n// Constructor from a vector of animals\nZoo::Zoo(const std::vector<AnimalPtr>& animals) \n  : m_animals{ animals } \n{}\n\n// Add an animal to the zoo\nvoid Zoo::addAnimal(AnimalPtr animal)\n{\n  m_animals.push_back(animal);\n}\n\n// Output the animals and the sound they make\nvoid Zoo::showAnimals() const\n{\n  for (const auto& animal : m_animals)\n  {\n    std::cout << animal->who() << ' ' << animal->sound() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_03/Zoo.h",
    "content": "// The Zoo class representing a collection of animals \n#ifndef ZOO_H\n#define ZOO_H\n\n#include \"Animals.h\"\n#include <vector>\n#include <memory>\n\nusing AnimalPtr = std::shared_ptr<Animal>;         // Define a type alias for convenience\n\nclass Zoo\n{\npublic:\n  Zoo() = default;                                 // Default constructor for an empty zoo\n  Zoo(const std::vector<AnimalPtr>& new_animals);  // Constructor from a vector of animals\n  virtual ~Zoo() = default;                        // Add a virtual destructor to allow classes to safely derive from Zoo;\n                                                   // possible examples of Zoo specializations include SafariPark, PettingZoo, ...\n  void addAnimal(AnimalPtr animal);                // Add an animal to the zoo\n  void showAnimals() const;                        // Output the animals and the sound they make\n\nprivate:\n  std::vector<AnimalPtr> m_animals;      // Stores pointers to the animals\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_04/Animals.cpp",
    "content": "// Implementations of the Animal class and classes derived from Animal\n\n/*\n  Because the Animal::m_weight member currently represents the total weight of the animal\n  (we kept this from previous versions of these classes),\n  we need to update the Animal's (total) weight during Sheep::shear().\n  \n  In an alternate, arguably more elegant solution:\n    - Animal::m_weight could reprent the \"true\" weight of the animal\n    - Sheep::getWeight() could return Animal::getWeight() + m_wool_weight\n    - Sheep::shear() could simply set m_wool_weight to 0\n */\n\n#include \"Animals.h\"\n\n// Constructor\nAnimal::Animal(std::string_view name, unsigned weight) \n  : m_name{ name }, m_weight{ weight }\n{}\n\n// Return string describing the animal\nstd::string Animal::who() const\n{\n  return \"My name is \" + getName() + \". My weight is \" + std::to_string(getWeight()) + \" lbs.\";\n}\n\nvoid Animal::setWeight(unsigned weight)\n{\n  m_weight = weight;\n}\n\n// Sheep constructors\nSheep::Sheep(std::string_view name, unsigned weight)\n  : Sheep{name, weight, static_cast<unsigned>(0.1 * weight)}\n{\n}\n\nSheep::Sheep(std::string_view name, unsigned weight, unsigned wool)\n  : Animal{name, weight}\n  , m_wool_weight{wool}\n{\n}\n\n// Override the behaviour of getName() for Sheep to prepend \"Woolly \"\nstd::string Sheep::getName() const\n{\n  return \"Woolly \" + Animal::getName();\n}\n\n// Override getWeight() to subtract the weight of their wool from weight.\nunsigned Sheep::getWeight() const\n{\n  return Animal::getWeight() - m_wool_weight;\n}\n\nunsigned Sheep::shear()\n{\n  // Somewhat odd statement that updates the total weight (stored in the Animal subobject)\n  // to the actual weight of the sheep (see Sheep::getWeight()). \n  // Of course, we do this *before* setting the wool's weight to 0.\n  setWeight(getWeight());\n  \n  const unsigned wool_weight{ m_wool_weight };\n  m_wool_weight = 0;\n  return wool_weight;\n\n  // Alternative: use std::exchange() (see Exercise 18-5)\n  //return std::exchange(m_wool_weight, 0);\n}\n\n// Make like a sheep\nstd::string_view Sheep::sound() const\n{\n  return \"Baaaa!!\";\n}\n\n// Make like a dog\nstd::string_view Dog::sound() const\n{\n  return \"Woof woof!!\";\n}\n\n// Override the behaviour of who() for Cows to hide their weight\nstd::string Cow::who() const\n{\n  return \"My name is \" + getName() + \".\";\n}\n\n// Make like a cow\nstd::string_view Cow::sound() const\n{\n  return \"Mooooo!!\";\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_04/Animals.h",
    "content": "// Exercise 14-2 Animals.h \n// Animal classes\n#ifndef ANIMALS_H\n#define ANIMALS_H\n\n#include <string>\n#include <string_view>\n\nclass Animal\n{\npublic:\n  Animal(std::string_view name, unsigned weight);  // Constructor\n  virtual ~Animal() = default;                     // Very important: a virtual destructor!\n  \n  virtual std::string who() const;                 // Return string containing name and weight\n  virtual std::string_view sound() const = 0;      // Return the sound of an animal\n\nprotected:              // Protected getters for use in derived classes\n  virtual std::string getName() const { return m_name; }\n  virtual unsigned getWeight() const { return m_weight; }\n  void setWeight(unsigned weight);\n\nprivate:\n  std::string m_name;   // Name of the animal\n  unsigned m_weight;    // Weight of the animal\n};\n\nclass Sheep : public Animal\n{\npublic:\n  Sheep(std::string_view name, unsigned weight);\n  Sheep(std::string_view name, unsigned weight, unsigned wool);\n  \n  std::string_view sound() const override;  // Return the sound of a sheep\n  unsigned shear();\n\nprotected:\n  std::string getName() const override;\n  unsigned getWeight() const override;\n\nprivate:\n  unsigned m_wool_weight;\n};\n\nclass Dog : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string_view sound() const override;  // Return the sound of a dog\n};\n\nclass Cow : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string who() const override;         // Override the behaviour of who() for Cows\n  std::string_view sound() const override;  // Return the sound of a cow\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_04/Soln15_04.cpp",
    "content": "// Exercise 15-4 Exercising Zoo and Animal classes\n#include \"Zoo.h\"\n#include <random>     // For random number generation\n#include <functional> // For std::bind()\n#include <iostream>\n#include <array>\n#include <string_view>\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main() \n{\n  const size_t num_name_options{ 10 };\n  using NameOptions = std::array<std::string_view, num_name_options>;\n\n  const NameOptions dogNames {\n    \"Fido\", \"Rover\"  , \"Lassie\" , \"Lambikins\",  \"Poochy\",\n    \"Spit\", \"Gnasher\", \"Samuel\" , \"Wellington\", \"Patch\"\n  };\n  const NameOptions sheepNames {\n    \"Bozo\",    \"Killer\", \"Tasty\", \"Pete\", \"Chops\",\n    \"Blackie\", \"Whitey\", \"Eric\" , \"Sean\", \"Shep\"\n  };\n  const NameOptions cowNames {\n    \"Dolly\", \"Daisy\",   \"Shakey\", \"Amy\",   \"Dilly\",\n    \"Dizzy\", \"Eleanor\", \"Zippy\" , \"Zappy\", \"Happy\"\n  };\n\n  const unsigned minDogWt{ 1 };     // Minimum weight of a dog in pounds\n  const unsigned maxDogWt{ 120 };   // Maximum weight of a dog in pounds\n  const unsigned minSheepWt{ 80 };  // Minimum weight of a dog in pounds\n  const unsigned maxSheepWt{ 150 }; // Maximum weight of a dog in pounds\n  const unsigned minCowWt{ 800 };   // Minimum weight of a dog in pounds\n  const unsigned maxCowWt{ 1500 };  // Maximum weight of a dog in pounds\n\n  auto randomAnimalType { createUniformPseudoRandomNumberGenerator(0, 2) }; // 0, 1, or 2\n  auto randomNameIndex  { createUniformPseudoRandomNumberGenerator(0, num_name_options - 1) };\n  auto randomDogWeight  { createUniformPseudoRandomNumberGenerator(minDogWt, maxDogWt) };\n  auto randomSheepWeight{ createUniformPseudoRandomNumberGenerator(minSheepWt, maxSheepWt) };\n  auto randomCowWeight  { createUniformPseudoRandomNumberGenerator(minCowWt, maxCowWt) };\n\n  std::vector<AnimalPtr> animals;   // Stores smart pointers to animals\n  size_t numAnimals {};             // Number of animals to be created\n  std::cout << \"How many animals in the zoo? \";\n  std::cin >> numAnimals;\n  \n  Zoo zoo;                  // Create an empty Zoo\n  \n  // Create random animals and add them to the Zoo\n  for (size_t i {}; i < numAnimals; ++i)\n  {\n    switch (randomAnimalType())\n    {\n    case 0:                // Create a sheep\n      zoo.addAnimal(std::make_shared<Sheep>(sheepNames[randomNameIndex()], randomSheepWeight()));\n      break;\n    case 1:                // Create a dog\n      zoo.addAnimal(std::make_shared<Dog>(dogNames[randomNameIndex()], randomDogWeight()));\n      break;\n    case 2:                // Create a cow\n      zoo.addAnimal(std::make_shared<Cow>(cowNames[randomNameIndex()], randomCowWeight()));\n      break;\n    }\n  }\n  \n  zoo.showAnimals();       // Display the animals\n\n  std::cout << \"\\nHerding and shearing all sheep...\" << std::endl;\n  for (auto* sheep : zoo.herd())\n  {\n    sheep->shear();\n  }\n\n  zoo.showAnimals();       // Display the animals again\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_04/Zoo.cpp",
    "content": "// Implementations of the Zoo class that stores pointers to Animals\n#include \"Zoo.h\"\n#include \"Animals.h\"\n#include <iostream>\n\n// Constructor from a vector of animals\nZoo::Zoo(const std::vector<AnimalPtr>& animals) \n  : m_animals{ animals } \n{}\n\n// Add an animal to the zoo\nvoid Zoo::addAnimal(AnimalPtr animal)\n{\n  m_animals.push_back(animal);\n}\n\n// Output the animals and the sound they make\nvoid Zoo::showAnimals() const\n{\n  for (const auto& animal : m_animals)\n  {\n    std::cout << animal->who() << ' ' << animal->sound() << std::endl;\n  }\n}\n\n// Collect all Sheep in the Zoo using dynamic cast (the recommended way)\nstd::vector<Sheep*> Zoo::herd() const\n{\n  std::vector<Sheep*> sheep;\n  for (auto animal : m_animals)\n  {\n    auto* casted{ dynamic_cast<Sheep*>(animal.get()) };\n    if (casted)\n    {\n      sheep.push_back(casted);\n    }\n  }\n  return sheep;\n}\n\n/*\n// Collect all Sheep in the Zoo using the typeid() operator and a static cast\n// (for the sake of the exercise only)\n#include <typeinfo>       // required when using typeid()\n\nstd::vector<Sheep*> Zoo::herd() const\n{\n  std::vector<Sheep*> sheep;\n  for (auto animal : m_animals)\n  {\n    if (typeid(*animal) == typeid(Sheep))\n    {\n      sheep.push_back(static_cast<Sheep*>(animal.get()));\n    }\n  }\n  return sheep;\n}\n*/"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_04/Zoo.h",
    "content": "// The Zoo class representing a collection of animals \n#ifndef ZOO_H\n#define ZOO_H\n\n#include \"Animals.h\"\n#include <vector>\n#include <memory>\n\nusing AnimalPtr = std::shared_ptr<Animal>;         // Define a type alias for convenience\n\nclass Zoo\n{\npublic:\n  Zoo() = default;                                 // Default constructor for an empty zoo\n  Zoo(const std::vector<AnimalPtr>& new_animals);  // Constructor from a vector of animals\n  virtual ~Zoo() = default;                        // Add a virtual destructor to allow classes to safely derive from Zoo;\n                                                   // possible examples of Zoo specializations include SafariPark, PettingZoo, ...\n  void addAnimal(AnimalPtr animal);                // Add an animal to the zoo\n  void showAnimals() const;                        // Output the animals and the sound they make\n\n  std::vector<Sheep*> herd() const;                // Collect all Sheep in the Zoo\n\nprivate:\n  std::vector<AnimalPtr> m_animals;                // Stores pointers to the animals\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_05/Animals.cpp",
    "content": "// Implementations of the Animal class and classes derived from Animal\n\n/*\n  Because the Animal::m_weight member currently represents the total weight of the animal\n  (we kept this from previous versions of these classes),\n  we need to update the Animal's (total) weight during Sheep::shear().\n  \n  In an alternate, arguably more elegant solution:\n    - Animal::m_weight could reprent the \"true\" weight of the animal\n    - Sheep::getWeight() could return Animal::getWeight() + m_wool_weight\n    - Sheep::shear() could simply set m_wool_weight to 0\n */\n\n#include \"Animals.h\"\n\n// Constructor\nAnimal::Animal(std::string_view name, unsigned weight) \n  : m_name{ name }, m_weight{ weight }\n{}\n\n// Return string describing the animal\nstd::string Animal::who() const\n{\n  return \"My name is \" + getName() + \". My weight is \" + std::to_string(getWeight()) + \" lbs.\";\n}\n\nvoid Animal::setWeight(unsigned weight)\n{\n  m_weight = weight;\n}\n\n// Sheep constructors\nSheep::Sheep(std::string_view name, unsigned weight)\n  : Sheep{name, weight, static_cast<unsigned>(0.1 * weight)}\n{\n}\n\nSheep::Sheep(std::string_view name, unsigned weight, unsigned wool)\n  : Animal{name, weight}\n  , m_wool_weight{wool}\n{\n}\n\n// Override the behaviour of getName() for Sheep to prepend \"Woolly \"\nstd::string Sheep::getName() const\n{\n  return \"Woolly \" + Animal::getName();\n}\n\n// Override getWeight() to subtract the weight of their wool from weight.\nunsigned Sheep::getWeight() const\n{\n  return Animal::getWeight() - m_wool_weight;\n}\n\nunsigned Sheep::shear()\n{\n  // Somewhat odd statement that updates the total weight (stored in the Animal subobject)\n  // to the actual weight of the sheep (see Sheep::getWeight()). \n  // Of course, we do this *before* setting the wool's weight to 0.\n  setWeight(getWeight()); \n\n  const unsigned wool_weight{ m_wool_weight };\n  m_wool_weight = 0;\n  return wool_weight;\n\n  // Alternative: use std::exchange() (see Exercise 18-5)\n  //return std::exchange(m_wool_weight, 0);\n}\n\n// Make like a sheep\nstd::string_view Sheep::sound() const\n{\n  return \"Baaaa!!\";\n}\n\n// Make like a dog\nstd::string_view Dog::sound() const\n{\n  return \"Woof woof!!\";\n}\n\n// Override the behaviour of who() for Cows to hide their weight\nstd::string Cow::who() const\n{\n  return \"My name is \" + getName() + \".\";\n}\n\n// Make like a cow\nstd::string_view Cow::sound() const\n{\n  return \"Mooooo!!\";\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_05/Animals.h",
    "content": "// Exercise 14-2 Animals.h \n// Animal classes\n#ifndef ANIMALS_H\n#define ANIMALS_H\n\n#include <string>\n#include <string_view>\n\nclass Animal\n{\npublic:\n  Animal(std::string_view name, unsigned weight);  // Constructor\n  virtual ~Animal() = default;                     // Very important: a virtual destructor!\n  \n  virtual std::string who() const;                 // Return string containing name and weight\n  virtual std::string_view sound() const = 0;      // Return the sound of an animal\n\nprotected:              // Protected getters for use in derived classes\n  virtual std::string getName() const { return m_name; }\n  virtual unsigned getWeight() const { return m_weight; }\n  void setWeight(unsigned weight);\n\nprivate:\n  std::string m_name;   // Name of the animal\n  unsigned m_weight;    // Weight of the animal\n};\n\nclass Sheep : public Animal\n{\npublic:\n  Sheep(std::string_view name, unsigned weight);\n  Sheep(std::string_view name, unsigned weight, unsigned wool);\n  \n  std::string_view sound() const override;  // Return the sound of a sheep\n  unsigned shear();\n\nprotected:\n  std::string getName() const override;\n  unsigned getWeight() const override;\n\nprivate:\n  unsigned m_wool_weight;\n};\n\nclass Dog : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string_view sound() const override;  // Return the sound of a dog\n};\n\nclass Cow : public Animal\n{\npublic:\n  using Animal::Animal;                     // Inherit constructor\n  \n  std::string who() const override;         // Override the behaviour of who() for Cows\n  std::string_view sound() const override;  // Return the sound of a cow\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_05/Soln15_05.cpp",
    "content": "// Exercise 15-5 Exercising Zoo and Animal classes\n#include \"Zoo.h\"\n#include <random>     // For random number generation\n#include <functional> // For std::bind()\n#include <iostream>\n#include <array>\n#include <string_view>\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main() \n{\n  const size_t num_name_options{ 10 };\n  using NameOptions = std::array<std::string_view, num_name_options>;\n\n  const NameOptions dogNames {\n    \"Fido\", \"Rover\"  , \"Lassie\" , \"Lambikins\",  \"Poochy\",\n    \"Spit\", \"Gnasher\", \"Samuel\" , \"Wellington\", \"Patch\"\n  };\n  const NameOptions sheepNames {\n    \"Bozo\",    \"Killer\", \"Tasty\", \"Pete\", \"Chops\",\n    \"Blackie\", \"Whitey\", \"Eric\" , \"Sean\", \"Shep\"\n  };\n  const NameOptions cowNames {\n    \"Dolly\", \"Daisy\",   \"Shakey\", \"Amy\",   \"Dilly\",\n    \"Dizzy\", \"Eleanor\", \"Zippy\" , \"Zappy\", \"Happy\"\n  };\n\n  const unsigned minDogWt{ 1 };     // Minimum weight of a dog in pounds\n  const unsigned maxDogWt{ 120 };   // Maximum weight of a dog in pounds\n  const unsigned minSheepWt{ 80 };  // Minimum weight of a dog in pounds\n  const unsigned maxSheepWt{ 150 }; // Maximum weight of a dog in pounds\n  const unsigned minCowWt{ 800 };   // Minimum weight of a dog in pounds\n  const unsigned maxCowWt{ 1500 };  // Maximum weight of a dog in pounds\n\n  auto randomAnimalType { createUniformPseudoRandomNumberGenerator(0, 2) }; // 0, 1, or 2\n  auto randomNameIndex  { createUniformPseudoRandomNumberGenerator(0, num_name_options - 1) };\n  auto randomDogWeight  { createUniformPseudoRandomNumberGenerator(minDogWt, maxDogWt) };\n  auto randomSheepWeight{ createUniformPseudoRandomNumberGenerator(minSheepWt, maxSheepWt) };\n  auto randomCowWeight  { createUniformPseudoRandomNumberGenerator(minCowWt, maxCowWt) };\n\n  std::vector<AnimalPtr> animals;   // Stores smart pointers to animals\n  size_t numAnimals {};             // Number of animals to be created\n  std::cout << \"How many animals in the zoo? \";\n  std::cin >> numAnimals;\n  \n  Zoo zoo;                  // Create an empty Zoo\n  \n  // Create random animals and add them to the Zoo\n  for (size_t i {}; i < numAnimals; ++i)\n  {\n    switch (randomAnimalType())\n    {\n    case 0:                // Create a sheep\n      zoo.addAnimal(std::make_shared<Sheep>(sheepNames[randomNameIndex()], randomSheepWeight()));\n      break;\n    case 1:                // Create a dog\n      zoo.addAnimal(std::make_shared<Dog>(dogNames[randomNameIndex()], randomDogWeight()));\n      break;\n    case 2:                // Create a cow\n      zoo.addAnimal(std::make_shared<Cow>(cowNames[randomNameIndex()], randomCowWeight()));\n      break;\n    }\n  }\n  \n  zoo.showAnimals();       // Display the animals\n\n  std::cout << \"\\nHerding and shearing all sheep...\" << std::endl;\n  for (auto sheep : zoo.herd())\n  {\n    sheep->shear();\n  }\n\n  zoo.showAnimals();       // Display the animals again\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_05/Zoo.cpp",
    "content": "// Implementations of the Zoo class that stores pointers to Animals\n#include \"Zoo.h\"\n#include \"Animals.h\"\n#include <iostream>\n\n// Constructor from a vector of animals\nZoo::Zoo(const std::vector<AnimalPtr>& animals) \n  : m_animals{ animals } \n{}\n\n// Add an animal to the zoo\nvoid Zoo::addAnimal(AnimalPtr animal)\n{\n  m_animals.push_back(animal);\n}\n\n// Output the animals and the sound they make\nvoid Zoo::showAnimals() const\n{\n  for (const auto& animal : m_animals)\n  {\n    std::cout << animal->who() << ' ' << animal->sound() << std::endl;\n  }\n}\n\n// Collect all Sheep in the Zoo using dynamic cast (the recommended way)\nstd::vector<SheepPtr> Zoo::herd() const\n{\n  std::vector<SheepPtr> sheep;\n  for (auto animal : m_animals)\n  {\n    auto casted{ std::dynamic_pointer_cast<Sheep>(animal) };\n    if (casted)\n    {\n      sheep.push_back(casted);\n    }\n  }\n  return sheep;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_05/Zoo.h",
    "content": "// The Zoo class representing a collection of animals \n#ifndef ZOO_H\n#define ZOO_H\n\n#include \"Animals.h\"\n#include <vector>\n#include <memory>\n\nusing AnimalPtr = std::shared_ptr<Animal>;         // Define a type alias for convenience\nusing SheepPtr = std::shared_ptr<Sheep>;\n\nclass Zoo\n{\npublic:\n  Zoo() = default;                                 // Default constructor for an empty zoo\n  Zoo(const std::vector<AnimalPtr>& new_animals);  // Constructor from a vector of animals\n  virtual ~Zoo() = default;                        // Add a virtual destructor to allow classes to safely derive from Zoo;\n                                                   // possible examples of Zoo specializations include SafariPark, PettingZoo, ...\n  void addAnimal(AnimalPtr animal);                // Add an animal to the zoo\n  void showAnimals() const;                        // Output the animals and the sound they make\n\n  std::vector<SheepPtr> herd() const;                // Collect all Sheep in the Zoo\n\nprivate:\n  std::vector<AnimalPtr> m_animals;                // Stores pointers to the animals\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_06/Point.h",
    "content": "// A simple class for 2-dimensional points\n#ifndef POINT_H\n#define POINT_H\n\nclass Point final\n{\npublic:\n  Point(double x, double y) : m_x{x}, m_y{y} {}\n  \n  double getX() const { return m_x; }\n  double getY() const { return m_y; }\n  \n  void setX(double x) { m_x = x; }\n  void setY(double y) { m_y = y; }\n  \nprivate:\n  double m_x;\n  double m_y;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_06/Shapes.h",
    "content": "// Shape classes\n#ifndef SHAPE_H\n#define SHAPE_H\n\n#include \"Point.h\"\n#include <numbers>\n\n// Generic base class for shapes\nclass Shape\n{\npublic:\n  Shape(const Point& position) : m_position {position} {}\n  virtual ~Shape() = default; // Remember: always use virtual destructors for base classes!\n\n  virtual double area() const = 0;       // Pure virtual function to compute a shape's area\n  virtual double perimeter() const = 0;  // Pure virtual function to compute a shape's perimeter\n  virtual void scale(double factor) = 0; // Pure virtual function to scale a shape\n\n  // Regular virtual function to move a shape\n  virtual void move(const Point& position) { m_position = position; };  \n\nprivate:\n  Point m_position;          // Position of a shape\n};\n\n// Class defining a circle\nclass Circle : public Shape\n{\npublic:\n  Circle(const Point& center, double radius) : Shape{center}, m_radius{radius} {}\n\n  double area() const override\n  { \n    return m_radius * m_radius * std::numbers::pi;\n  }\n  double perimeter() const override\n  {\n    return 2 * std::numbers::pi * m_radius;\n  }\n\n  void scale(double factor) override { m_radius *= factor; }\n\nprivate:\n  double m_radius;   // Radius of a circle\n};\n\n// Class defining a rectangle\nclass Rectangle : public Shape\n{\n\npublic:\n  Rectangle(const Point& center, double rectWidth, double rectHeight) \n    : Shape{center}, m_width{rectWidth}, m_height{rectHeight} \n  {}\n\n  double area() const override { return m_width * m_height; }\n  double perimeter() const override { return 2 * (m_width + m_height); }\n \n  void scale(double factor) override\n  { \n    m_width *= factor; \n    m_height *= factor; \n  }\n\nprivate:\n  double m_width;        // Width of a rectangle\n  double m_height;       // Height of a rectangle\n};\n\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 15/Soln15_06/Soln15_06.cpp",
    "content": "// Exercise 15-6 Exercising Shape classes\n#include \"Shapes.h\"\n#include <iostream>\n#include <vector>\n\ndouble calculateSumAreas(const std::vector<Shape*>& shapes);\ndouble calculateSumPerimeters(const std::vector<Shape*>& shapes);\nvoid printSums(const std::vector<Shape*>& shapes);\n\nint main() \n{\n  Circle c1{ Point{1, 1}, 1 };\n  Circle c2{ Point{2, 2}, 2 };\n  Circle c3{ Point{3, 3}, 3 };\n  Rectangle r1{ {4, 5}, 4, 5 }; // Shorter notation (omitted Point type) could of course be used for Circles as well!\n  Rectangle r2{ {6, 7}, 6, 7 };\n  Rectangle r3{ {8, 9}, 8, 9 };\n  \n  std::vector<Shape*> shapes{ &c1, &r1, &r2, &c2, &c3, &r3 };\n  \n  printSums(shapes);\n  \n  for (auto* shape : shapes) shape->scale(1.5);\n  \n  std::cout << std::endl;\n  printSums(shapes);\n}\n\ndouble calculateSumAreas(const std::vector<Shape*>& shapes)\n{\n  double sum {};\n  for (auto* shape : shapes)\n  {\n    sum += shape->area();\n  }\n  return sum;\n}\n\ndouble calculateSumPerimeters(const std::vector<Shape*>& shapes)\n{\n  double sum {};\n  for (auto* shape : shapes)\n  {\n    sum += shape->perimeter();\n  }\n  return sum;\n}\n\nvoid printSums(const std::vector<Shape*>& shapes)\n{\n  std::cout << \"Sum of areas: \" << calculateSumAreas(shapes) << std::endl;\n  std::cout << \"Sum of perimeters: \" << calculateSumPerimeters(shapes) << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Exer16_06/Customer.cpp",
    "content": "// A simple C++ customer class\n\n#include \"Customer.h\"\n\nCustomer::Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city)\n  : m_surname{ surname }\n  , m_name{ name }\n  , m_street{ street }\n  , m_streetNumber{ streetNumber }\n  , m_city{ city }\n{}\n\nstd::string Customer::toString() const\n{\n  std::string result;\n  result += m_surname;\n  result += ' ';\n  result += m_name;\n  result += \", \";\n  result += m_street;\n  result += ' ';\n  result += std::to_string(m_streetNumber);\n  result += \", \";\n  result += m_city;\n  return result;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Exer16_06/Customer.h",
    "content": "// A simple C++ customer class\n\n#ifndef CUSTOMER_H\n#define CUSTOMER_H\n\n#include <string>\n#include <string_view>\n\nclass Customer\n{\npublic:\n  Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city\n  );\n\n  std::string toString() const;\n  \nprivate:\n  std::string m_surname;\n  std::string m_name;\n  std::string m_street;\n  int m_streetNumber;\n  std::string m_city;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Exer16_06/DB.cpp",
    "content": "// A mocked database\n\n#include \"DB.h\"\n#include <cstring>    // For std::strcmp()\n#include <memory>\n#include <vector>\n\nnamespace\n{\n  struct QueryResult\n  {\n    std::vector<std::vector<const char*>> data;\n    size_t index {};\n  };\n\n  class Database\n  {\n  public:\n    Database() = default;\n    \n\t  bool hasConnection() const { return m_connected; }\n    void connect() { m_connected = true; }\n    void disconnect() { m_connected = false; }\n    \n    QueryResult* query(const char* query);\n    \n  private:  \n    bool m_connected{};\n  };\n}\n\nDB_CONNECTION* db_connect()\n{\n  // We only have one single database, which allows only one single connection:\n  static Database theDatabase;\n  if (theDatabase.hasConnection())\n  {\n    return nullptr;\n  }\n  else\n  {\n    theDatabase.connect();\n    return &theDatabase;\n  }\n}\n\nvoid db_disconnect(DB_CONNECTION* connection)\n{\n  // reinterpret_cast<> is used to cast between pointers/references of \n  // unrelated types (such as void* and Database*)\n  reinterpret_cast<Database*>(connection)->disconnect();\n}\n\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query)\n{\n  return reinterpret_cast<Database*>(connection)->query(query);\n}\n\nQueryResult* Database::query(const char* query)\n{\n  if (!hasConnection())\n  {\n    return nullptr;\n  }\n  \n  // Our database only understands one single query!\n  if (std::strcmp(query, \"SELECT * FROM CUSTOMER_TABEL\") != 0)\n  {\n    return nullptr;\n  }\n  \n  auto result{ std::make_unique<QueryResult>() };\n  result->data = std::vector<std::vector<const char*>>{\n    { \"Sherlock\", \"Holmes\", \"Baker Street\", \"221\", \"London\" },\n    { \"Joe\", \"Biden\", \"Pennsylvania Avenue\", \"1600\", \"Washington DC\" },\n    { \"Donald\", \"Duck\", \"Webfoot Walk\", \"1313\", \"Duckville\" },\n    { \"Sirius\", \"Black\", \"Grimmauld Place\", \"12\", \"London\" },\n    { \"Nemo\", \"Clownfish\", \"Wallaby Way\", \"42\", \"Sydney\" },\n    { \"Sam\", \"Malone\", \"Beacon Street\", \"112\", \"Boston\" }\n  };\n  return result.release();\n}\n\nint db_num_fields(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->data.empty())\n  {\n    return -1;\n  }\n  else\n  {\n    return static_cast<int>(theResult->data.front().size());\n  }\n}\n\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->index >= theResult->data.size())\n  {\n    return nullptr;\n  }\n  else\n  {\n     return theResult->data[theResult->index++].data();\n  }\n}\n\nvoid db_free_result(DB_QUERY_RESULT* result)\n{\n  delete reinterpret_cast<QueryResult*>(result);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Exer16_06/DB.h",
    "content": "// A C-style interface to a mock database\n// (a simplified subset of the MySQL C interface)\n\n#ifndef DB_INCLUDES\n#define DB_INCLUDES\n\nusing DB_CONNECTION = void;\nusing DB_QUERY_RESULT = void;\nusing DB_ROW = const char**;\n\n/*! Make a connection to the database\n * Do not forget to close the database connection (db_disconnect()) once done with it.\n * \\return a DB_CONNECTION handle; nullptr upon failure\n */\nDB_CONNECTION* db_connect();\n\n/*! Query the database\n * \\param[in] connection A database connection handle returned by db_connect()\n * \\param[in] query      A SQL query\n * \\return A handle to the result of the query (memory to be freed using db_free_result()!)\n */\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query);\n\n/*! Retrieve the number of fields per row stored by the given query result\n * \\param[in] result A handle returned by db_query \n * \\return The number of fields per row stored by the result; -1 upon failure\n */\nint db_num_fields(DB_QUERY_RESULT* result);\n\n/*! Fetch a single row from the result.\n * \\param[in] result A handle returned by db_query\n * \\return An array of strings. Each field is represented as a string (zero-terminated char array). \n * \tLet row be the result, then the first field is accessed using result[0]. \n */\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result);\n\n/*! Release the memory allocated for the result.\n * \\param[in] result A handle returned by db_query()\n */\nvoid db_free_result(DB_QUERY_RESULT* result);\n\n/*! Disconnect from the database\n * \\param[in] connection   A connection handle returned by db_connect()\n */\nvoid db_disconnect(DB_CONNECTION* connection);\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Exer16_06/DBException.h",
    "content": "// A simple C++ exception type\n\n#ifndef DB_EXCEPTION_H\n#define DB_EXCEPTION_H\n\n#include <stdexcept>\n\nclass DatabaseException : public std::runtime_error\n{\npublic:\n  using std::runtime_error::runtime_error;  // Inherit constructor\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Exer16_06/Exer16_06.cpp",
    "content": "/* \n  Creating RAII classes to manage resource handles returned by a C interface\n  Remember: RAII is not just for dynamic memory: every resource should be managed by an object!\n */\n\n#include <iostream>\n#include <vector>\n\n#include \"DB.h\"\n#include \"DBException.h\"\n#include \"Customer.h\"\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result);           // Sanity check on the number of fields returned by our query\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result); // Convert the DB result to a series of C++ objects\nvoid print(std::ostream& stream, const Customer& customer);   // Print a given customer to a given output stream\n\nint main()\n{\n  auto* connection{ db_connect() };\n  try\n  {\n    auto* result{ db_query(connection, \"SELECT * FROM CUSTOMER_TABEL\") };\n    if (!result)\n    {\n      db_disconnect(connection);\n      throw DatabaseException{\"Query failed\"};\n    }\n  \n    std::vector customers{ readCustomers(result) };\n  \n    if (customers.empty())\n    {\n      std::cerr << \"No customers found?\" << std::endl;\n      return 2;\n    }\n    \n    for (auto& customer : customers)\n    {\n       print(std::cout, customer);\n    }\n  \n    db_free_result(result);\n  }\n  catch (std::exception& caught)\n  {\n    std::cerr << caught.what() << std::endl;\n    return 1;\n  }\n  \n  db_disconnect(connection);\n  return 0;\n}\n\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result)\n{\n  // Sanity check \n  // (if the number of fields does not match 5, \n  // the code below would crash!)\n  verifyCustomerFields(result);\n   \n  std::vector<Customer> customers;\n  \n  auto row{ db_fetch_row(result) };\n  while (row)\n  {\n    customers.push_back(Customer{\n      row[0],            // Surname\n      row[1],            // Name\n      row[2],            // Street\n      std::stoi(row[3]), // Street number\n      row[4]             // City\n    });\n    \n    row = db_fetch_row(result);\n  }\n  \n  return customers;\n}\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result)\n{\n  const int numFields{ db_num_fields(result) };\n  if (numFields < 0)\n  {\n    throw DatabaseException{\"db_num_fields() failed\"};\n  }\n  if (numFields != 5)\n  {\n    throw DatabaseException{\"Unexpected number of fields: \" + std::to_string(numFields)};\n  }\n}\n\nvoid print(std::ostream& stream, const Customer& customer)\n{\n  stream << customer.toString() << std::endl;\n  if (std::cout.fail())\n  {\n    std::cout.clear();\n    throw std::runtime_error(\"Failed to output customer\");\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_01/Curveball.h",
    "content": "// Definition of Curveball exception class\n\n#ifndef CURVEBALL_H\n#define CURVEBALL_H\n#include <exception>\n\nclass Curveball : public std::exception\n{\npublic:\n  const char* what() const noexcept override\n  {\n    return \"Curveball exception\";\n  }\n};\n\n#endif //CURVEBALL_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_01/Soln16_01.cpp",
    "content": "// Throwing and catching Curveballs\n#include \"Curveball.h\"\n#include <iostream>\n\n#include <random>     // For random number generation\n#include <functional> // For std::bind()\n\nvoid throwCurveballSometimes();           // Suggested solution\nvoid throwCurveballSometimesBernouilli(); // Alternate solution\n\nint main() \n{\n  size_t number {1000};                             // Number of loop iterations\n  size_t exceptionCount {};                         // Count of exceptions thrown\n\n  for (size_t i {}; i < number; ++i)\n  {\n    try\n    {\n      throwCurveballSometimes();\n      // throwCurveballSometimesBernouilli();\n    }\n    catch (const Curveball&)\n    {\n      exceptionCount++;\n    }\n  }\n  \n  std::cout << \"Curveball exception thrown \" << exceptionCount << \" times out of \" << number << \".\\n\";\n}\n\n// See Chapter 12 for an explanation of this function principle.\nauto createUniformPseudoRandomNumberGenerator(double min, double max)\n{\n  std::random_device seeder;          // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };      // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ min, max }; // Generate in [min, max) interval\n  return std::bind(distribution, generator);             //... and in the darkness bind them!\n}\n\n// Throw a Curveball exception 25% of the time\nvoid throwCurveballSometimes()\n{\n  static auto random{ createUniformPseudoRandomNumberGenerator(0, 100) };\n  if (random() < 25)\n    throw Curveball{};\n}\n\n/*\n Alternate solution: instead of generating numbers in the interval [0,100)\n using a std::uniform_real_distribution, and comparing against 25,\n you could also generate Boolean values directly using a std::bernoulli_distribution\n (see https://en.cppreference.com/w/cpp/numeric/random/bernoulli_distribution;\n  named after https://en.wikipedia.org/wiki/Bernoulli_distribution):\n*/\nauto createUniformPseudoRandomBooleanGenerator(double probabilityOfTrue)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::bernoulli_distribution distribution{ probabilityOfTrue }; // The name says it all...\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\n// Throw a Curveball exception 25% of the time\nvoid throwCurveballSometimesBernouilli()\n{\n  static auto random{ createUniformPseudoRandomBooleanGenerator(0.25) };\n  if (random())\n    throw Curveball{};\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_02/Curveball.h",
    "content": "// Definition of Curveball exception class\n\n#ifndef CURVEBALL_H\n#define CURVEBALL_H\n#include <exception>\n\nclass Curveball : public std::exception\n{\npublic:\n  const char* what() const noexcept override\n  {\n    return \"Curveball exception\";\n  }\n};\n\n#endif //CURVEBALL_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_02/Soln16_02.cpp",
    "content": "// Throwing and catching Curveballs and throwing TooManyExceptions\n#include \"Curveball.h\"\n#include \"TooManyExceptions.h\"\n\n#include <iostream>\n\n#include <random>     // For random number generation\n#include <functional> // For std::bind()\n\nvoid throwCurveballSometimes();\n\n// This program will terminate abnormally when the TooManyExceptions exception is thrown.\nint main()\n{\n  size_t number{ 1000 };             // Number of loop iterations\n  size_t exceptionCount {};          // Count of exceptions thrown\n  const size_t maxExceptions{ 10 };  // Maximum number of exceptions\n\n  for (size_t i {}; i < number; ++i)\n  {\n    try\n    {\n      throwCurveballSometimes();\n    }\n    catch(Curveball& e)\n    {\n      std::cout << e.what() << std::endl;\n    \n      if (++exceptionCount > maxExceptions)\n        throw TooManyExceptions{ maxExceptions };\n    }\n  }\n}\n\n// See Soln16_01 (to generate Booleans, a bernoulli_distribution is actually most appropriate)\nauto createUniformPseudoRandomBooleanGenerator(double probabilityOfTrue)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::bernoulli_distribution distribution{ probabilityOfTrue }; // The name says it all...\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\n// Throw a Curveball exception 25% of the time\nvoid throwCurveballSometimes()\n{\n  static auto random{ createUniformPseudoRandomBooleanGenerator(0.25) };\n  if (random())\n    throw Curveball{};\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_02/TooManyExceptions.h",
    "content": "// Definition of TooManyExceptions exception class\n// We added an extra \"how many\" members to illustrate derived \n// exceptions can carry extra information regarding their cause.\n// Notice how the constructor is explicit (implicit conversions\n// from size_t to TooManyExceptions are not desired).\n\n#ifndef TOOMANYEXCEPTIONS_H\n#define TOOMANYEXCEPTIONS_H\n\n#include <exception>\n#include <string>     // For std::string / std::to_string()\n\nclass TooManyExceptions : public std::exception\n{\npublic:\n  explicit TooManyExceptions(size_t howMany)\n    : m_how_many{ howMany }\n    , m_message{ \"Too many exceptions occurred: \" + std::to_string(m_how_many) }\n  {}\n\n  const char* what() const noexcept override\n  {\n    return m_message.c_str();\n  }\n\n  size_t howMany() const noexcept\n  {\n    return m_how_many;\n  }\n\nprivate:\n  size_t m_how_many;\n  std::string m_message;\n};\n\n#endif //TOOMANYEXCEPTIONS_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_03/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <ostream>\n#include <format>\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_03/RandomBoxes.h",
    "content": "#ifndef RANDOM_BOXES_H\n#define RANDOM_BOXES_H\n\n#include \"Box.h\"\n#include <random>        // For random number generation\n#include <functional>    // For std::bind()\n#include <memory>        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\ninline auto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\ninline Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\ninline auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_03/Soln16_03.cpp",
    "content": "// Using exceptions to signal index-out-of-bounds errors.\n#include <iostream>\n#include <memory>\n#include \"Truckload.h\"\n#include \"RandomBoxes.h\"\n\nint main()\n{\n  Truckload load;\n  const size_t boxCount {20};               // Number of Box object to be created\n\n  // Create boxCount Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    load.addBox(randomSharedBox());\n\n  try\n  {\n    std::cout << \"The truckload contains the following boxes: \" << std::endl;\n    for (size_t i {}; i < 100; ++i)\n    {\n\t    std::cout << *load[i] << std::endl;\n    }\n  }\n  catch (const std::exception& caughtException)\n  {\n    std::cerr << \"Oops: \" << caughtException.what() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_03/Truckload.cpp",
    "content": "#include \"Truckload.h\"\n\n#include <iostream>\n#include <stdexcept>    // For standard exception type std::out_of_range \n#include <string>       // For std::string and std::to_string()\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\nTruckload& Truckload::operator=(const Truckload& other)\n{\n  if (&other != this)   // Do not forget: avoid issues with self-assignment!\n  {\n    delete m_head;              // Delete all current packages\n    m_head = m_tail = nullptr;  // Reset both pointers\n\n    // Same as copy constructor \n    // (see Chapter 17 for the copy-and-swap idiom that allows you to avoid \n    // duplicating logic like this...)\n    for (Package* package{ other.m_head }; package; package = package->m_next)\n    {\n      addBox(package->m_box);\n    }\n  }\n\n  return *this;\n}\n\n// Destructor: clean up the list\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nSharedBox& Truckload::operator[](size_t index) const\n{\n  size_t count{};             // Package count\n  for (Package* package{ m_head }; package; package = package->m_next)\n  {\n    if (count++ == index)      // Up to index yet?\n      return package->m_box;   // If so return the pointer to Box\n  }\n  throw std::out_of_range{ \"Index too large: \" + std::to_string(index) };\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_03/Truckload.h",
    "content": "#ifndef TRUCKLOAD_H\n#define TRUCKLOAD_H\n\n#include \"Box.h\"\n\n#include <memory>\n#include <vector>\n#include <ostream>\n\nusing SharedBox = std::shared_ptr<Box>;\n\nclass Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  \n  Truckload(const Truckload& src);  // Copy constructor\n  Truckload& operator=(const Truckload& other);  // Copy assignment operator\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox& operator[](size_t index) const;   // Overloaded subscript operator\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load);\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_04/Soln16_04.cpp",
    "content": "// Throwing and catching standard exceptions\n#include <iostream>\n#include <stdexcept>\n#include <vector>\n#include <format>\n#include <typeinfo>\n#include <optional>\n\n/*\n  This solution triggers all exceptions mentioned in the text \n  accompanying the Table with all Standard Library exceptions, in order.\n  To know how to trigger any other type, \n  you will have to consult your Standard Library reference.\n\n  Note: while you'll typically catch exceptions by reference-to-const-std::exception \n  (unless more specific handling for concrete types is required, of course),\n  we specify the concrete exception type instead here for clarity.\n */\n\n// First, some dummy class types...\nclass BaseClass\n{\npublic:\n  virtual ~BaseClass() = default;\n};\n\nclass DerivedClass1 : public BaseClass {};\nclass DerivedClass2 : public BaseClass {};\n\nint main()\n{\n  try\n  {\n    std::vector v{ 1, 2, 3, 4, 5 };\n    std::cout << v.at(10) << std::endl;\n  }\n  catch (const std::out_of_range& exception)\n  {\n    std::cout << \"std::out_of_range: \" << exception.what() << std::endl;\n  }\n\n  try\n  {\n    std::cout << std::format(\"Hello {:g}!\\n\", \"World\");\n  }\n  catch (const std::format_error& exception)\n  {\n    std::cout << \"std::format_error: \" << exception.what() << std::endl;\n  }\n\n  try\n  {\n    // Remember: a polymorphic class is a class with at least one virtual function.\n    BaseClass* polymorphic{ nullptr };\n    std::cout << typeid(*polymorphic).name();\n  }\n  catch (const std::bad_typeid& exception)\n  {\n    std::cout << \"std::bad_typeid: \" << exception.what() << std::endl;\n  }\n\n  try\n  {\n    DerivedClass1 derived;\n    BaseClass& reference_to_base{ derived };\n    dynamic_cast<DerivedClass2&>(reference_to_base);\n  }\n  catch (const std::bad_cast& exception)\n  {\n    std::cout << \"std::bad_cast: \" << exception.what() << std::endl;\n  }\n\n  try\n  {\n    std::optional<int> empty;\n    std::cout << empty.value() << std::endl;\n  }\n  catch (const std::bad_optional_access& exception)\n  {\n    std::cout << \"std::bad_optional_access: \" << exception.what() << std::endl;\n  }\n\n  try\n  {\n    int size{ -1 };\n    new int[size];\n  }\n  catch (const std::bad_alloc& exception)\n  {\n    std::cout << \"std::bad_alloc: \" << exception.what() << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_05/Curveball.h",
    "content": "// Definition of Curveball exception class\n\n#ifndef CURVEBALL_H\n#define CURVEBALL_H\n#include <exception>\n\nclass Curveball : public std::exception\n{\npublic:\n  const char* what() const noexcept override\n  {\n    return \"Curveball exception\";\n  }\n};\n\n#endif //CURVEBALL_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_05/DomainExceptions.h",
    "content": "// Definitions of various domain exception classes\n#ifndef DOMAINEXCEPTIONS_H\n#define DOMAINEXCEPTIONS_H\n\n#include <stdexcept>\n#include <string>\n\n/*\n\tstd::domain_error is one of the exception types defined by\n\tthe Standard Libray. It is intended to be used mostly inside\n\tmathematical functions in case an argument is provided for which\n\tthe function is not defined (for instance, should a regular \n\tsquare root function be called with a negative number)\n*/\n\nclass NotANumber : public std::domain_error\n{\npublic:\n  explicit NotANumber(const std::string& nan) \n    : std::domain_error{\"Not a number: \" + nan} \n  {}\n};\n\nclass NegativeNumber : public std::domain_error\n{\npublic:\n  explicit NegativeNumber(int number)\n    : std::domain_error{\"A negative number was entered: \" + std::to_string(number)}\n  {}\n};\n\nclass OddNumber : public std::domain_error\n{\npublic:\n  explicit OddNumber(int number)\n    : std::domain_error{\"An odd number was entered: \" + std::to_string(number)}\n  {}\n};\n\n#endif //DOMAINEXCEPTIONS_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_05/Soln16_05.cpp",
    "content": "// Exercise 16-5\n/* Somewhat artificial example to practice lists of different, \n * related exception types (mind the order + catch-by-reference!)\n * and rethrowing (catch-by-reference + \"throw;\" !)\n */\n\n#include <iostream>\n#include <random>     // For random number generation\n#include <functional> // For std::bind()\n#include <format>\n#include \"Curveball.h\"\n#include \"DomainExceptions.h\"\n\nvoid askEvenNumber();           // Ask the user to provide an even number\n\nint main()\n{\n  try\n  {\n    askEvenNumber();\n  }\n  catch (const Curveball& /*caught*/)\n  {\n    std::cerr << \"...hit it out of the park!\" << std::endl;\n  }\n}\n\n/* Helper functions for askEvenNumber() */\nvoid throwCurveballSometimes(); // Throw a Curveball exception 25% of the time\nint readEvenNumber();           // Reads an even number from std::cin and verifies the input \n                                // (throws upon failure)\n\n// Option 1: use recursion\nvoid askEvenNumber()\n{\n  try\n  {\n    std::cout << \"Please enter an even number: \";\n    const int read = readEvenNumber();\n    std::cout << std::format(\"Well done. {} is a beautiful even number. Thank you!\\n\", read);\n  }\n  catch (const NotANumber& nan)\n  {\n    std::cerr << nan.what() << std::endl;\n    return;\n  }\n  catch (const std::domain_error& domainException)\n  {\n    std::cerr << domainException.what() << std::endl;\n    askEvenNumber();  // Recursive call\n  }\n  catch (const std::exception& exception)\n  {\n    std::cerr << exception.what() << std::endl;\n    throw;\n  }\n}\n\n/*\n// Option 2: use a loop\nvoid askEvenNumber()\n{\n  while (true)\n  {\n    try\n    {\n      std::cout << \"Please enter an even number: \";\n      const int read = readEvenNumber();\n      std::cout << std::format(\"Well done. {} is a beautiful even number. Thank you!\\n\", read);\n      break;\n    }\n    catch (const NotANumber& nan)\n    {\n      std::cerr << nan.what() << std::endl;\n      return;\n    }\n    catch (const std::out_of_range& range)\n    {\n      std::cerr << range.what() << std::endl;\n    }\n    catch (const std::exception& exception)\n    {\n      std::cerr << exception.what() << std::endl;\n      throw;\n    }\n  }\n}\n*/\n\nint readEvenNumber()\n{\n  int number;\n  std::cin >> number;\n  if (std::cin.fail()) // Check whether the user has effectively entered a number\n  {\n    std::cin.clear();  // Reset the stream's failure state\n    std::string line;  // Read the erroneous input and discard it\n    std::getline(std::cin, line);\n    throw NotANumber{line};\n  }\n  \n  throwCurveballSometimes();\n  \n  if (number < 0)\n    throw NegativeNumber{number};\n  if (number % 2)\n    throw OddNumber{number};\n\n  return number;\n}\n\n// See Soln16_01 for an explanation of this function\nauto createUniformPseudoRandomBooleanGenerator(double probabilityOfTrue)\n{\n  std::random_device seeder;        // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::bernoulli_distribution distribution{ probabilityOfTrue }; // The name says it all...\n  return std::bind(distribution, generator);           //... and in the darkness bind them!\n}\n\n// Throw a Curveball exception 25% of the time\nvoid throwCurveballSometimes()\n{\n  static auto random{ createUniformPseudoRandomBooleanGenerator(0.25) };\n  if (random())\n    throw Curveball{};\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_06/Customer.cpp",
    "content": "// A simple C++ customer class\n\n#include \"Customer.h\"\n\nCustomer::Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city)\n  : m_surname{ surname }\n  , m_name{ name }\n  , m_street{ street }\n  , m_streetNumber{ streetNumber }\n  , m_city{ city }\n{}\n\nstd::string Customer::toString() const\n{\n  std::string result;\n  result += m_surname;\n  result += ' ';\n  result += m_name;\n  result += \", \";\n  result += m_street;\n  result += ' ';\n  result += std::to_string(m_streetNumber);\n  result += \", \";\n  result += m_city;\n  return result;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_06/Customer.h",
    "content": "// A simple C++ customer class\n\n#ifndef CUSTOMER_H\n#define CUSTOMER_H\n\n#include <string>\n#include <string_view>\n\nclass Customer\n{\npublic:\n  Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city\n  );\n\n  std::string toString() const;\n  \nprivate:\n  std::string m_surname;\n  std::string m_name;\n  std::string m_street;\n  int m_streetNumber;\n  std::string m_city;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_06/DB.cpp",
    "content": "// A mocked database\n\n#include \"DB.h\"\n#include <cstring>    // For std::strcmp()\n#include <memory>\n#include <vector>\n\nnamespace\n{\n  struct QueryResult\n  {\n    std::vector<std::vector<const char*>> data;\n    size_t index {};\n  };\n\n  class Database\n  {\n  public:\n    Database() = default;\n    \n\t  bool hasConnection() const { return m_connected; }\n    void connect() { m_connected = true; }\n    void disconnect() { m_connected = false; }\n    \n    QueryResult* query(const char* query);\n    \n  private:  \n    bool m_connected{};\n  };\n}\n\nDB_CONNECTION* db_connect()\n{\n  // We only have one single database, which allows only one single connection:\n  static Database theDatabase;\n  if (theDatabase.hasConnection())\n  {\n    return nullptr;\n  }\n  else\n  {\n    theDatabase.connect();\n    return &theDatabase;\n  }\n}\n\nvoid db_disconnect(DB_CONNECTION* connection)\n{\n  // reinterpret_cast<> is used to cast between pointers/references of \n  // unrelated types (such as void* and Database*)\n  reinterpret_cast<Database*>(connection)->disconnect();\n}\n\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query)\n{\n  return reinterpret_cast<Database*>(connection)->query(query);\n}\n\nQueryResult* Database::query(const char* query)\n{\n  if (!hasConnection())\n  {\n    return nullptr;\n  }\n  \n  // Our database only understands one single query!\n  if (std::strcmp(query, \"SELECT * FROM CUSTOMER_TABEL\") != 0)\n  {\n    return nullptr;\n  }\n  \n  auto result{ std::make_unique<QueryResult>() };\n  result->data = std::vector<std::vector<const char*>>{\n    { \"Sherlock\", \"Holmes\", \"Baker Street\", \"221\", \"London\" },\n    { \"Joe\", \"Biden\", \"Pennsylvania Avenue\", \"1600\", \"Washington DC\" },\n    { \"Donald\", \"Duck\", \"Webfoot Walk\", \"1313\", \"Duckville\" },\n    { \"Sirius\", \"Black\", \"Grimmauld Place\", \"12\", \"London\" },\n    { \"Nemo\", \"Clownfish\", \"Wallaby Way\", \"42\", \"Sydney\" },\n    { \"Sam\", \"Malone\", \"Beacon Street\", \"112\", \"Boston\" }\n  };\n  return result.release();\n}\n\nint db_num_fields(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->data.empty())\n  {\n    return -1;\n  }\n  else\n  {\n    return static_cast<int>(theResult->data.front().size());\n  }\n}\n\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->index >= theResult->data.size())\n  {\n    return nullptr;\n  }\n  else\n  {\n     return theResult->data[theResult->index++].data();\n  }\n}\n\nvoid db_free_result(DB_QUERY_RESULT* result)\n{\n  delete reinterpret_cast<QueryResult*>(result);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_06/DB.h",
    "content": "// A C-style interface to a mock database\n// (a simplified subset of the MySQL C interface)\n\n#ifndef DB_INCLUDES\n#define DB_INCLUDES\n\nusing DB_CONNECTION = void;\nusing DB_QUERY_RESULT = void;\nusing DB_ROW = const char**;\n\n/*! Make a connection to the database\n * Do not forget to close the database connection (db_disconnect()) once done with it.\n * \\return a DB_CONNECTION handle; nullptr upon failure\n */\nDB_CONNECTION* db_connect();\n\n/*! Query the database\n * \\param[in] connection A database connection handle returned by db_connect()\n * \\param[in] query      A SQL query\n * \\return A handle to the result of the query (memory to be freed using db_free_result()!)\n */\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query);\n\n/*! Retrieve the number of fields per row stored by the given query result\n * \\param[in] result A handle returned by db_query \n * \\return The number of fields per row stored by the result; -1 upon failure\n */\nint db_num_fields(DB_QUERY_RESULT* result);\n\n/*! Fetch a single row from the result.\n * \\param[in] result A handle returned by db_query\n * \\return An array of strings. Each field is represented as a string (zero-terminated char array). \n * \tLet row be the result, then the first field is accessed using result[0]. \n */\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result);\n\n/*! Release the memory allocated for the result.\n * \\param[in] result A handle returned by db_query()\n */\nvoid db_free_result(DB_QUERY_RESULT* result);\n\n/*! Disconnect from the database\n * \\param[in] connection   A connection handle returned by db_connect()\n */\nvoid db_disconnect(DB_CONNECTION* connection);\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_06/DBException.h",
    "content": "// A simple C++ exception type\n\n#ifndef DB_EXCEPTION_H\n#define DB_EXCEPTION_H\n\n#include <stdexcept>\n\nclass DatabaseException : public std::runtime_error\n{\npublic:\n  using std::runtime_error::runtime_error;  // Inherit constructor\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_06/DB_RAII.h",
    "content": "// RAII classes for handles returned by DB.h C interface functions\n\n/*\n  In this solution we have the RAII classes accept the resource handle in their constructor.\n  Alternatively, you could also acquire the resources inside the constructors of the RAII class.\n  For instance: you could call db_connect() from within the DBConnectionRAII() contructor.\n*/\n\n#ifndef DB_RAII_H\n#define DB_RAII_H\n\n#include \"DB.h\"\n\n/**\n * RAII object that ensures that a given database connection is closed\n * once the RAII object goes out of scope.\n */ \nclass DBConnectionRAII\n{\npublic:\n  DBConnectionRAII(DB_CONNECTION* connection) noexcept\n    : m_connection{ connection }\n  {\n  }  \n  ~DBConnectionRAII() // implicitly noexcept\n  {\n    if (m_connection)\n    {\n      db_disconnect(m_connection);\n    }\n  }\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_CONNECTION*() const noexcept { return m_connection; }\n  \nprivate:\n  DB_CONNECTION* m_connection;\n};\n\n/* RAII object that takes a DB_QUERY_RESULT and ensures it is closed */\nclass DBQueryResultRAII\n{\npublic:\n  DBQueryResultRAII(DB_QUERY_RESULT* result) noexcept \n    : m_result{ result }\n  {\n  }\n  \n  ~DBQueryResultRAII() // implicitly noexcept\n  {\n    if (m_result)\n    {\n      db_free_result(m_result);\n    }\n  }\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_QUERY_RESULT* () const noexcept { return m_result; }\n\nprivate:\n  DB_QUERY_RESULT* m_result;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 16/Soln16_06/Soln16_06.cpp",
    "content": "// Exercise 16-6\n/* Creating RAII classes to manage resource handles returned by a C interface\n   Remember: RAII is not just for dynamic memory: every resource should be managed by an object!\n   \n   Leaks in the original code:\n   - The database connection was not disconnected if an exception occurred indirectly \n     in the main try-catch block. For the DatabaseException thrown in the block of db_query()\n     the connection was correctly disconnected. Possible other exceptions, though, include:\n      a) verifyCustomerFields() discovers a problem. This verification step \n         may've been added later by someone trying to make the program more robuust, \n         but not familiar enough with the surrounding program...\n      b) std::stoi() throws std::invalid_argument because an empty string was passed, \n         or a string that does not start with a number\n      c) Customer::toString() throws std::bad_alloc because memory allocation failed for the new string\n\t    d) If the output stream used fails for whatever reason, a std::runtime_exception occurs.\n         While for std::cout this is less likely, perhaps the program is changed later to output\n         to some other stream that writes to a GUI element or a file. These might fail...\n   - The memory leaks for the query result are analogous\n   - If no customers are found, someone decided to add an extra return statement. \n     This again leaks all resources...\n   \n   Bottom line: the larger the program becomes, the more resources there are to keep track of,\n   and at the same time the more exceptions and return statements there appear.\n   Moreover, in real life often many different people collaborate on the same code,\n   often less familiar with the original program and the resources it uses.\n   It is just too easy to forget one case, and introduce a leak. \n   Even the most disciplined developer will make mistakes this way---believe us!\n   Hence: always use some form of RAII to manage a resource!\n*/\n\n#include <iostream>\n#include <vector>\n\n#include \"DB.h\"\n#include \"DBException.h\"\n#include \"Customer.h\"\n#include \"DB_RAII.h\"\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result);           // Sanity check on the number of fields returned by our query\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result); // Convert the DB result to a series of C++ objects\nvoid print(std::ostream& stream, const Customer& customer);   // Print a given customer to a given output stream\n\nint main()\n{\n  DBConnectionRAII connection{ db_connect() };\n  try\n  {\n    DBQueryResultRAII result{ db_query(connection, \"SELECT * FROM CUSTOMER_TABEL\") };\n    if (!result)\n    {\n      throw DatabaseException{\"Query failed\"};\n    }\n  \n    std::vector customers{ readCustomers(result) };\n  \n    if (customers.empty())\n    {\n      std::cerr << \"No customers found?\" << std::endl;\n      return 2;\n    }\n    \n    for (auto& customer : customers)\n    {\n        print(std::cout, customer);\n    }\n  }\n  catch (const std::exception& caught)\n  {\n    std::cerr << caught.what() << std::endl;\n    return 1;\n  }\n}\n\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result)\n{\n  // Sanity check \n  // (if the number of fields does not match 5, \n  // the code below would crash!)\n  verifyCustomerFields(result);\n   \n  std::vector<Customer> customers;\n  \n  auto row{ db_fetch_row(result) };\n  while (row)\n  {\n    customers.push_back(Customer{\n      row[0],            // Surname\n      row[1],            // Name\n      row[2],            // Street\n      std::stoi(row[3]), // Street number\n      row[4]             // City\n    });\n    \n    row = db_fetch_row(result);\n  }\n  \n  return customers;\n}\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result)\n{\n  const int numFields{ db_num_fields(result) };\n  if (numFields < 0)\n  {\n    throw DatabaseException{\"db_num_fields() failed\"};\n  }\n  if (numFields != 5)\n  {\n    throw DatabaseException{\"Unexpected number of fields: \" + std::to_string(numFields)};\n  }\n}\n\nvoid print(std::ostream& stream, const Customer& customer)\n{\n  stream << customer.toString() << std::endl;\n  if (std::cout.fail())\n  {\n    std::cout.clear();\n    throw std::runtime_error(\"Failed to output customer\");\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_01/Array.h",
    "content": "// Same as Ex17_01B, but with a push_back() member and a default constructor\n#ifndef ARRAY_H\n#define ARRAY_H\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  Array();                                  // Default constructor\n  Array(size_t size);                       // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  void push_back(const T& element);         // Function to add new element to the end\n  size_t getSize() const { return m_size; } // Accessor for m_size\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T>\nArray<T>::Array() : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Template for functions that add new element to the end of the array\n// Uses the 'copy-and-swap' idiom.\n// If either the Array<> constructor throws\n// (std::bad_alloc or some exception from T's default constructor) \n// or any of the copy assignments of a T element throw,\n// then the original Array<> remains untouched.\ntemplate <typename T>\nvoid Array<T>::push_back(const T& newElement)\n{\n  Array<T> copy{ m_size + 1 };        // Copy...\n  for (size_t i {}; i < m_size; ++i)\n    copy[i] = m_elements[i];\n\n  copy[m_size] = newElement;          // ... modify ...\n\n  swap(copy);                         // ... and swap!  (noexcept)\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_01/Soln17_01.cpp",
    "content": "// Adding a push_back() member function and a default constructor to the Array<> \n// class template. Using copy-and-swap for a memory-safe push_back().\n#include \"Array.h\"\n#include <iostream>\n\nint main()\n{\n  const unsigned numElements{ 100 };\n\n  Array<unsigned> squares;       // default construction\n  for (unsigned i {}; i < numElements; ++i)\n\t  squares.push_back(i * i);    // push_back()\n\n  std::cout << squares.getSize() << \" squares were added.\" << std::endl;\n  std::cout << \"For instance: 13 squared equals \" << squares[13] << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_02/Pair.h",
    "content": "#ifndef PAIR_H\n#define PAIR_H\n\n#include <compare>\n\ntemplate <typename First, typename Second>\nclass Pair\n{\npublic:\n  // Public members + no m_ prefix analogous to std::pair<> (see <utility> module)\n  First first;    \n  Second second;\n\n  Pair() = default;\n  Pair(const First& f, const Second& s);\n  \n  // In retrospect, this is no longer such an interesting exercise on writing\n  // member function templates now that the compiler generates all lexicographical \n  // comparison operators for you.\n  //\n  // Note: not all compiler may fully support this generation yet (C++20)...\n  // (replacing auto with std::strong_ordering may make Soln17_02.cpp compile then,\n  // but in general auto is better because First and/or Second could be types \n  // that are not strongly ordered, such as a floating-point types)\n  auto operator<=>(const Pair& other) const = default;\n};\n\n// Constructor\ntemplate <typename First, typename Second>\nPair<First, Second>::Pair(const First& f, const Second& s)\n  : first{f}, second{s}\n{}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_02/Soln17_02.cpp",
    "content": "// Exercise 16-2\n// Create a basic Pair template\n#include \"Pair.h\"\n#include <iostream>\n#include <string>\n\nint main()\n{\n  auto my_pair{ Pair<int, std::string>{122, \"abc\"} };\n  ++my_pair.first;\n  std::cout << \"my_pair equals (\" << my_pair.first \n            << \", \" << my_pair.second << ')' << std::endl;\n\n  auto pair1{ Pair<int, std::string>{0, \"def\"} };\n\n  using namespace std::string_literals; // To make s suffix work (see below)\n  \n  // CTAD works as well. The deduced type for both pair2 and pair3 is Pair<int, std::string>:\n  auto pair2{ Pair{123, std::string{\"abc\"}} }; // Option 1: specify std::string yourself (otherwise the type is const char[])\n  auto pair3{ Pair{123, \"def\"s} };             // Option 2: use string literals: s suffix creates a std::string object\n\n  std::cout << (pair1 < pair2 && pair2 < pair3? \"operator< seems to be working\" : \"oops\") << std::endl;\n  std::cout << (pair1 == pair2? \"oops\" : \"operator== works as well\") << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_03/Pair.h",
    "content": "#ifndef PAIR_H\n#define PAIR_H\n\n#include <compare>\n#include <iostream>\n\ntemplate <typename First, typename Second>\nclass Pair\n{\npublic:\n  // Public members + no m_ prefix analogous to std::pair<> (see <utility> module)\n  First first;    \n  Second second;\n\n  Pair() = default;\n  Pair(const First& f, const Second& s);\n  \n  // Note: not all compiler may fully support this generation yet (C++20)...\n  // (replacing auto with std::strong_ordering may make Soln17_02.cpp compile then,\n  // but in general auto is better because First and/or Second could be types \n  // that are not strongly ordered, such as a floating-point types)\n  auto operator<=>(const Pair& other) const = default;\n};\n\n// Constructor\ntemplate <typename First, typename Second>\nPair<First, Second>::Pair(const First& f, const Second& s)\n  : first{f}, second{s}\n{}\n\ntemplate <typename First, typename Second>\nstd::ostream& operator<<(std::ostream& out, const Pair<First, Second>& pair)\n{\n  return out << '(' << pair.first << \", \" << pair.second << ')';\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_03/Soln17_03.cpp",
    "content": "// Create a << operator template for Pairs\n#include \"Pair.h\"\n#include <iostream>\n#include <string>\n\nint main()\n{\n  // To make the s string literal suffix work \n  // (facilitates creation of Pairs using CTAD, or Constructor Template Argument Deduction).\n  // This syntactic sugar for creating std::string objects is not really covered in the book.\n  using namespace std::string_literals;\n\n  auto my_pair{ Pair{122, \"abc\"s} };\n  ++my_pair.first;\n  std::cout << \"my_pair equals \" << my_pair << std::endl;\n\n  auto pair1{ Pair{  0, \"def\"s} };\n  auto pair2{ Pair{123, \"abc\"s} };\n  auto pair3{ Pair{123, \"def\"s} };\n\n  std::cout << (pair1 < pair2 && pair2 < pair3? \"operator< seems to be working\" : \"oops\") << std::endl;\n  std::cout << (pair1 == pair2? \"oops\" : \"operator== works as well\") << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_04/Pair.h",
    "content": "#ifndef PAIR_H\n#define PAIR_H\n\n#include <compare>\n#include <iostream>\n\ntemplate <typename First, typename Second>\nclass Pair\n{\npublic:\n  // Public members + no m_ prefix analogous to std::pair<> (see <utility> module)\n  First first;    \n  Second second;\n\n  Pair() = default;\n  Pair(const First& f, const Second& s);\n  \n  // Note: not all compiler may fully support this generation yet (C++20)...\n  // (replacing auto with std::strong_ordering may make Soln17_02.cpp compile then,\n  // but in general auto is better because First and/or Second could be types \n  // that are not strongly ordered, such as a floating-point types)\n  auto operator<=>(const Pair& other) const = default;\n};\n\n// Constructor\ntemplate <typename First, typename Second>\nPair<First, Second>::Pair(const First& f, const Second& s)\n  : first{f}, second{s}\n{}\n\ntemplate <typename First, typename Second>\nstd::ostream& operator<<(std::ostream& out, const Pair<First, Second>& pair)\n{\n  return out << '(' << pair.first << \", \" << pair.second << ')';\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_04/Soln17_04.cpp",
    "content": "// Exercising the SparseArray class template\n// We create a sparse array of integers, populate 20 of its entries \n// (checking for duplicates among the randomly generated indices)\n// and output the resulting index/value pairs.\n\n#include \"SparseArray.h\"\n#include <iostream>\n\n#include <random>     // For random number generation\n#include <functional> // For std::bind()\n#include <memory>     // For std::make_shared<>() and std::shared_ptr<>\n\n// See Chapter 12 for an explanation of this principle.\n// The main difference here is that we need a std::uniform_int_distribution \n// instead of a std::uniform_real_distribution to generate integers instead \n// of float-point (or, \"real\") numbers.\nauto createUniformPseudoRandomNumberGenerator(int min, int max)\n{\n  std::random_device seeder;         // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };     // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max }; // Generate in [min, max) interval\n  return std::bind(distribution, generator);            //... and in the darkness bind them!\n}\n\nint main()\n{\n  const size_t count {20};                 // Number of elements to be created\n  const int min_value{32};\n  const int max_value{212};\n  const size_t max_index{499};\n  \n  // Create the (pseudo)-random number generators \n  // (we use +1 because these generate integers in a half-open interval [min,max)...)\n  auto generate_random_index{ createUniformPseudoRandomNumberGenerator(0, max_index + 1) };\n  auto generate_random_value{ createUniformPseudoRandomNumberGenerator(min_value, max_value + 1) };\n\n  SparseArray<int> numbers;               // Create empty sparse array\n  \n  for (size_t i {}; i < count; ++i)       // Create count entries in numbers array\n  {\n    size_t index {};                      // Stores new index value\n\n    // Must ensure that indexes after the first are not duplicates\n    do\n    {\n      index = generate_random_index();    // Get a random index 0 to max_index-1\n    }\n    while (numbers.element_exists_at(index));\n\n    numbers[index] = generate_random_value();  // Store value at new index position\n  }\n\n  for (size_t i {}; i <= max_index; ++i)       // Create count entries in numbers array\n  {\n    if (numbers.element_exists_at(i))\n      std::cout << \"Element at index \" << i << \" equals \" << numbers.at(i) << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_04/SparseArray.h",
    "content": "// SparseArray class template definition\n// Note the use of the find() helper function and the const-and-back-again idiom to minimize code duplication\n\n#ifndef SPARSEARRAY_H\n#define SPARSEARRAY_H\n\n#include \"Pair.h\"\n#include <vector>\n#include <string>       // For std::to_string()\n#include <utility>      // For std::as_const()\n#include <stdexcept>\n\ntemplate<typename T>\nclass SparseArray\n{\npublic:\n  T& operator[](size_t index);              // Subscript operator (creates default-constructed value if no value exists for the given index)\n  T& at(size_t index);                      // Access function (throws std::out_of_range if no value exists for the given index)\n  const T& at(size_t index) const;          // const overload of at()\n  bool element_exists_at(size_t index) const;  // Return true iff an element exists at the given index\n\nprivate:\n  T* find(size_t index);                    // Helper function (returns nullptr if no value exists for the given index)\n  const T* find(size_t index) const;\n  \n  std::vector<Pair<size_t, T>> m_values;\n};\n\ntemplate<typename T>\nT& SparseArray<T>::operator[](size_t index)\n{\n  if (auto* found{ find(index) }; found)   // Using C++17 initialization statements for if statement \n  {                                        // (see at() function for common, traditional equivalent)\n\t  return *found;\n  }\n  else\n  {\n    m_values.push_back({ index, T{} });    // Or push_back(Pair{...}), or push_back(Pair<size_t, T>{...})\n    return m_values.back().second;         // Remember: std::vector<>::back() returns a reference to its last element\n  }\n}\n\ntemplate<typename T>\nconst T& SparseArray<T>::at(size_t index) const\n{\n  const auto* found{ find(index) };\n  if (found)\n  {\n\t  return *found;\n  }\n  else\n  {\n    throw std::out_of_range{\"No value exists at index \" + std::to_string(index)};\n  }\n}\n\ntemplate<typename T>\nT& SparseArray<T>::at(size_t index)\n{\n  return const_cast<T&>(std::as_const(*this).at(index));\n}\n\ntemplate<typename T>\nbool SparseArray<T>::element_exists_at(size_t index) const\n{\n  return find(index) != nullptr;\n}\n\ntemplate<typename T>\nconst T* SparseArray<T>::find(size_t index) const\n{\n  for (auto& pair : m_values)\n  {\n    if (pair.first == index)\n      return &pair.second;\n  }\n  return nullptr;\n}\n\ntemplate<typename T>\nT* SparseArray<T>::find(size_t index)\n{\n  return const_cast<T*>(std::as_const(*this).find(index));\n}\n\n#endif //SPARSEARRAY_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_05/LinkedList.h",
    "content": "#ifndef LINKEDLIST_H\n#define LINKEDLIST_H\n\n/*\nThis LinkedList template follows some (not all) conventions of Standard Library containers:\nsome member function names are analogous,\nas is the choice not to work with exceptions in case you do something wrong\n(such as calling back() or pop_front() on an empty list).\nThe latter has the implication that if you mis-use the container,\nyour program will likely crash...\n*/\n\n#include <cstddef>        // for the size_t typedef\n#include <utility>        // for std::swap()\n\ntemplate<typename T>\nclass LinkedList\n{\npublic:\n\tLinkedList() = default;                      // Default constructor (all pointers are initialised to nullptr)\n\t~LinkedList();\n\n\tLinkedList(const LinkedList& list);          // Copy constructor\n\tLinkedList& operator=(LinkedList list);      // Assignment operator\n\n\tvoid push_front(const T& value);             // Add an object to the head\n\tvoid push_back(const T& value);              // Add an object to the tail\n\n\tvoid pop_back();                             // Removes the last element from the list (undefined behavior for empty lists)\n\tvoid pop_front();                            // Removes the first element from the list (undefined behavior for empty lists)\n\n\tT& front();                                  // Get the object at the head (undefined behavior for empty lists)\n\tT& back();                                   // Get the object at the tail (undefined behavior for empty lists)\n\tconst T& front() const;                      // Get the object at the head (undefined behavior for empty lists)\n\tconst T& back() const;                       // Get the object at the tail (undefined behavior for empty lists)\n\n\tbool empty() const;                          // Checks whether the list is empty or not\n\tvoid clear();                                // Function to remove all elements from the list\n\tsize_t size() const;                         // Get the number of elements from the list\n\n\tclass Iterator;                              // Nested Iterator class declaration (definition below)\n\tIterator front_iterator() const;             // Get an Iterator that starts at the head\n\tIterator back_iterator() const;              // Get an Iterator that starts at the tail\n\n\tvoid swap(LinkedList& other) noexcept;       // Swap function\n\nprivate:\n\tclass Node                                   // Node class definition\n\t{\n\tpublic:\n\t\tNode(const T& theValue)\n\t\t\t: m_value{ theValue }, m_next{}, m_previous{}\n\t\t{}\n\n\t\tT m_value;\n\t\tNode* m_next;\n\t\tNode* m_previous;\n\t};\n\n\tNode* m_head{};    // Pointer to first node\n\tNode* m_tail{};    // Pointer to last node\n\tsize_t m_size{};\n};\n\n// Non-member swap function.\n// Convention dictates swap is present as non-member function.\n// For class types it is often easiest (and recommended) \n// to implement it using a member swap function.\ntemplate<typename T>\nvoid swap(LinkedList<T>& one, LinkedList<T>& other)\n{\n\tone.swap(other);\n}\n\n// ---------------------------------------------\n// Member definitions\n// ---------------------------------------------\n\n// Destructor template\ntemplate<typename T>\nLinkedList<T>::~LinkedList()\n{\n\tclear();\n}\n\n// Copy constructor template\ntemplate<typename T>\nLinkedList<T>::LinkedList(const LinkedList& list)\n{\n  // Use existing members (iteration, push_back()) to implement the copying\n  // This avoids duplicating any code that manipulates the list's pointers / size members.\n  for (auto iterator{ list.front_iterator() }; iterator; iterator.next())\n    push_back(iterator.value());\n}\n\n// Assignment operator template (uses copy-and-swap idiom)\ntemplate<typename T>\nLinkedList<T>& LinkedList<T>::operator=(LinkedList copy)\n{\n\tswap(*this, copy);\n\treturn *this;\n}\n\n// Template for member functions that add an object to the head of the list\ntemplate<typename T> \nvoid LinkedList<T>::push_front(const T& value)\n{\n\t// Note: this function is strongly exception-safe because\n\t// any and all change occur after the line annotated with (*),\n\t// which is the only line that may throw.\n\n\tNode* oldHead{ m_head };\n\tm_head = new Node{ value };  // (*)\n\t++m_size;\n\n\tif (oldHead)\n\t{\n\t\toldHead->m_previous = m_head;\n\t\tm_head->m_next = oldHead;\n\t}\n\telse  // list was empty before, and now has one element\n\t{\n\t\tm_tail = m_head;\n\t}\n}\n\n// Template for member functions that add an object to the tail of the list\ntemplate<typename T>\nvoid LinkedList<T>::push_back(const T& value)\n{\n\t// Note: this function is strongly exception-safe because\n\t// any and all change occur after the line annotated with (*),\n\t// which is the only line that may throw.\n\n\tNode* oldTail{ m_tail };\n\tm_tail = new Node{value};\t // (*)\n\t++m_size;                 \n\n\tif (oldTail)\n\t{\n\t\toldTail->m_next = m_tail;\n\t\tm_tail->m_previous = oldTail;\n\t}\n\telse  // list was empty before, and now has one element\n\t{\n\t\tm_head = m_tail;\n\t}\n}\n\n// Template for member functions that remove an object from the head of the list\ntemplate<typename T> \nvoid LinkedList<T>::pop_front()\n{\n\tNode* oldHead{ m_head };\n\tif (oldHead == m_tail)\n\t{\n\t\tm_head = m_tail = nullptr;\n\t}\n\telse\n\t{\n\t\tm_head = oldHead->m_next;\n\t\tm_head->m_previous = nullptr;\n\t}\n\t\n\t--m_size;\n\tdelete oldHead;\n}\n\n// Template function member to remove an object from the tail of the list\ntemplate<typename T>\nvoid LinkedList<T>::pop_back()\n{\n\tNode* oldTail{ m_tail };\n\tif (oldTail == m_head)\n\t{\n\t\tm_head = m_tail = nullptr;\n\t}\n\telse\n\t{\n\t\tm_tail = oldTail->m_previous;\n\t\tm_tail->next = nullptr;\n\t}\n\n\t--m_size;\n\tdelete oldTail;\n}\n\n// Template function members to get the object at the head of the list\ntemplate<typename T>\nT& LinkedList<T>::front()\n{\n\treturn m_head->value;\n}\ntemplate<typename T>\nconst T& LinkedList<T>::front() const\n{\n\treturn m_head->value;\n}\n\n// Template function members to get the object at the tail of the list\ntemplate<typename T>\nT& LinkedList<T>::back()\n{\n\treturn m_tail->value;\n}\ntemplate<typename T>\nconst T& LinkedList<T>::back() const\n{\n\treturn m_tail->value;\n}\n\n// Check whether list is empty or not\ntemplate<typename T>\nbool LinkedList<T>::empty() const\n{\n\treturn m_size == 0;  // (or m_head == nullptr, or m_tail == nullptr)\n}\n\n// Template to get the size of a list\ntemplate<typename T> \nsize_t LinkedList<T>::size() const\n{\n\treturn m_size;\n}\n\n// Template to clear a list\ntemplate<typename T>\nvoid LinkedList<T>::clear()\n{\n\t// Use existing functions (avoid code duplication!)\n\twhile (!empty()) pop_front();\n}\n\n// Member function template to swap two lists\ntemplate<typename T>\nvoid LinkedList<T>::swap(LinkedList& other) noexcept\n{\n\tstd::swap(m_head, other.m_head);\n\tstd::swap(m_tail, other.m_tail);\n\tstd::swap(m_size, other.m_size);\n}\n\n// Definition of the nested Iterator class\ntemplate<typename T>\nclass LinkedList<T>::Iterator\n{\npublic:\n\texplicit Iterator(Node* node) \n\t\t: m_current{ node }\n\t{}\n\n\tconst T& value() const { return m_current->m_value; }\n\n\tbool hasValue() const { return m_current != nullptr; }\n\toperator bool() const { return m_current != nullptr; }\n\n\tvoid next() { m_current = m_current->m_next; }\n\tvoid previous() { m_current = m_current->m_previous; }\n\nprivate:\n\tNode* m_current;\n};\n\n// Get an Iterator that starts at the head\ntemplate<typename T>\ntypename LinkedList<T>::Iterator LinkedList<T>::front_iterator() const\n{\n  return Iterator{ m_head };\n}\n\n// Get an Iterator that starts at the tail\ntemplate<typename T>\ntypename LinkedList<T>::Iterator LinkedList<T>::back_iterator() const\n{\n  return Iterator{ m_tail };\n}\n\n#endif //LINKEDLIST_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_05/Soln17_05.cpp",
    "content": "// Exercise 17-5 Exercising the LinkedList template class\n// This program reverses the text that is entered\n#include \"LinkedList.h\"\n#include <string>\n#include <string_view>\n#include <iostream>\n\nint main()\n{\n  std::string text;                              // Stores input prose or poem\n  std::cout << \"\\nEnter a poem or prose over one or more lines.\\n\"\n            << \"Terminate the input with #:\\n\";\n  getline(std::cin, text, '#');\n\n  LinkedList<std::string> words;                 // List to store words\n\n  // Extract words and store in the list\n  std::string_view separators{ \" ,.\\\"?!;:\\n\" };  // Separators between words\n  size_t start {};                               // Start of a word\n  size_t end {};                                 // separator position after a word\n  while (std::string::npos != (start = text.find_first_not_of(separators, start)))\n  {\n    end = text.find_first_of(separators, start+1);\n    words.push_back(text.substr(start,end-start));\n    start = end;\n  }\n\n  // List the words 5 to a line\n  std::cout << \"\\nThe words are:\\n\\n\";\n  auto iterator{ words.front_iterator() };\n  size_t count {};                               // Word counter\n  const size_t perline {5};                      // Worde per line\n  while (iterator.hasValue())\n  {\n    std::cout << iterator.value() << ' ';\n    if (!(++count % perline))\n      std::cout << std::endl;\n    iterator.next();\n  }\n  std::cout << std::endl;\n\n  // List the words in reverse order 5 to a line\n  std::cout << \"\\nIn reverse order, the words are:\\n\\n\";\n  iterator = words.back_iterator();\n  count = 0;\n  while (iterator.hasValue())\n  {\n    std::cout << iterator.value() << ' ';\n    if(!(++count % perline))\n      std::cout << std::endl;\n    iterator.previous();\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_06/LinkedList.h",
    "content": "#ifndef LINKEDLIST_H\n#define LINKEDLIST_H\n\n/*\nThis LinkedList template follows some (not all) conventions of Standard Library containers:\nsome member function names are analogous,\nas is the choice not to work with exceptions in case you do something wrong\n(such as calling back() or pop_front() on an empty list).\nThe latter has the implication that if you mis-use the container,\nyour program will likely crash...\n*/\n\n#include <cstddef>        // for the size_t typedef\n#include <utility>        // for std::swap()\n\ntemplate<typename T>\nclass LinkedList\n{\npublic:\n\tLinkedList() = default;                      // Default constructor (all pointers are initialised to nullptr)\n\t~LinkedList();\n\n\tLinkedList(const LinkedList& list);          // Copy constructor\n\tLinkedList& operator=(LinkedList list);      // Assignment operator\n\n\tvoid push_front(const T& value);             // Add an object to the head\n\tvoid push_back(const T& value);              // Add an object to the tail\n\n\tvoid pop_back();                             // Removes the last element from the list (undefined behavior for empty lists)\n\tvoid pop_front();                            // Removes the first element from the list (undefined behavior for empty lists)\n\n\tT& front();                                  // Get the object at the head (undefined behavior for empty lists)\n\tT& back();                                   // Get the object at the tail (undefined behavior for empty lists)\n\tconst T& front() const;                      // Get the object at the head (undefined behavior for empty lists)\n\tconst T& back() const;                       // Get the object at the tail (undefined behavior for empty lists)\n\n\tbool empty() const;                          // Checks whether the list is empty or not\n\tvoid clear();                                // Function to remove all elements from the list\n\tsize_t size() const;                         // Get the number of elements from the list\n\n\tclass Iterator;                              // Nested Iterator class declaration (definition below)\n\tIterator front_iterator() const;             // Get an Iterator that starts at the head\n\tIterator back_iterator() const;              // Get an Iterator that starts at the tail\n\n\tvoid swap(LinkedList& other) noexcept;       // Swap function\n\nprivate:\n\tclass Node                                   // Node class definition\n\t{\n\tpublic:\n\t\tNode(const T& theValue)\n\t\t\t: m_value{ theValue }, m_next{}, m_previous{}\n\t\t{}\n\n\t\tT m_value;\n\t\tNode* m_next;\n\t\tNode* m_previous;\n\t};\n\n\tNode* m_head{};    // Pointer to first node\n\tNode* m_tail{};    // Pointer to last node\n\tsize_t m_size{};\n};\n\n// Non-member swap function.\n// Convention dictates swap is present as non-member function.\n// For class types it is often easiest (and recommended) \n// to implement it using a member swap function.\ntemplate<typename T>\nvoid swap(LinkedList<T>& one, LinkedList<T>& other)\n{\n\tone.swap(other);\n}\n\n// ---------------------------------------------\n// Member definitions\n// ---------------------------------------------\n\n// Destructor template\ntemplate<typename T>\nLinkedList<T>::~LinkedList()\n{\n\tclear();\n}\n\n// Copy constructor template\ntemplate<typename T>\nLinkedList<T>::LinkedList(const LinkedList& list)\n{\n  // Use existing members (iteration, push_back()) to implement the copying\n  // This avoids duplicating any code that manipulates the list's pointers / size members.\n  for (auto iterator{ list.front_iterator() }; iterator; iterator.next())\n    push_back(iterator.value());\n}\n\n// Assignment operator template (uses copy-and-swap idiom)\ntemplate<typename T>\nLinkedList<T>& LinkedList<T>::operator=(LinkedList copy)\n{\n\tswap(*this, copy);\n\treturn *this;\n}\n\n// Template for member functions that add an object to the head of the list\ntemplate<typename T> \nvoid LinkedList<T>::push_front(const T& value)\n{\n\t// Note: this function is strongly exception-safe because\n\t// any and all change occur after the line annotated with (*),\n\t// which is the only line that may throw.\n\n\tNode* oldHead{ m_head };\n\tm_head = new Node{ value };  // (*)\n\t++m_size;\n\n\tif (oldHead)\n\t{\n\t\toldHead->m_previous = m_head;\n\t\tm_head->m_next = oldHead;\n\t}\n\telse  // list was empty before, and now has one element\n\t{\n\t\tm_tail = m_head;\n\t}\n}\n\n// Template for member functions that add an object to the tail of the list\ntemplate<typename T>\nvoid LinkedList<T>::push_back(const T& value)\n{\n\t// Note: this function is strongly exception-safe because\n\t// any and all change occur after the line annotated with (*),\n\t// which is the only line that may throw.\n\n\tNode* oldTail{ m_tail };\n\tm_tail = new Node{value};\t // (*)\n\t++m_size;                 \n\n\tif (oldTail)\n\t{\n\t\toldTail->m_next = m_tail;\n\t\tm_tail->m_previous = oldTail;\n\t}\n\telse  // list was empty before, and now has one element\n\t{\n\t\tm_head = m_tail;\n\t}\n}\n\n// Template for member functions that remove an object from the head of the list\ntemplate<typename T> \nvoid LinkedList<T>::pop_front()\n{\n\tNode* oldHead{ m_head };\n\tif (oldHead == m_tail)\n\t{\n\t\tm_head = m_tail = nullptr;\n\t}\n\telse\n\t{\n\t\tm_head = oldHead->m_next;\n\t\tm_head->m_previous = nullptr;\n\t}\n\t\n\t--m_size;\n\tdelete oldHead;\n}\n\n// Template function member to remove an object from the tail of the list\ntemplate<typename T>\nvoid LinkedList<T>::pop_back()\n{\n\tNode* oldTail{ m_tail };\n\tif (oldTail == m_head)\n\t{\n\t\tm_head = m_tail = nullptr;\n\t}\n\telse\n\t{\n\t\tm_tail = oldTail->m_previous;\n\t\tm_tail->next = nullptr;\n\t}\n\n\t--m_size;\n\tdelete oldTail;\n}\n\n// Template function members to get the object at the head of the list\ntemplate<typename T>\nT& LinkedList<T>::front()\n{\n\treturn m_head->value;\n}\ntemplate<typename T>\nconst T& LinkedList<T>::front() const\n{\n\treturn m_head->value;\n}\n\n// Template function members to get the object at the tail of the list\ntemplate<typename T>\nT& LinkedList<T>::back()\n{\n\treturn m_tail->value;\n}\ntemplate<typename T>\nconst T& LinkedList<T>::back() const\n{\n\treturn m_tail->value;\n}\n\n// Check whether list is empty or not\ntemplate<typename T>\nbool LinkedList<T>::empty() const\n{\n\treturn m_size == 0;  // (or m_head == nullptr, or m_tail == nullptr)\n}\n\n// Template to get the size of a list\ntemplate<typename T> \nsize_t LinkedList<T>::size() const\n{\n\treturn m_size;\n}\n\n// Template to clear a list\ntemplate<typename T>\nvoid LinkedList<T>::clear()\n{\n\t// Use existing functions (avoid code duplication!)\n\twhile (!empty()) pop_front();\n}\n\n// Member function template to swap two lists\ntemplate<typename T>\nvoid LinkedList<T>::swap(LinkedList& other) noexcept\n{\n\tstd::swap(m_head, other.m_head);\n\tstd::swap(m_tail, other.m_tail);\n\tstd::swap(m_size, other.m_size);\n}\n\n// Definition of the nested Iterator class\ntemplate<typename T>\nclass LinkedList<T>::Iterator\n{\npublic:\n\texplicit Iterator(Node* node) \n\t\t: m_current{ node }\n\t{}\n\n\tconst T& value() const { return m_current->m_value; }\n\n\tbool hasValue() const { return m_current != nullptr; }\n\toperator bool() const { return m_current != nullptr; }\n\n\tvoid next() { m_current = m_current->m_next; }\n\tvoid previous() { m_current = m_current->m_previous; }\n\nprivate:\n\tNode* m_current;\n};\n\n// Get an Iterator that starts at the head\ntemplate<typename T>\ntypename LinkedList<T>::Iterator LinkedList<T>::front_iterator() const\n{\n  return Iterator{ m_head };\n}\n\n// Get an Iterator that starts at the tail\ntemplate<typename T>\ntypename LinkedList<T>::Iterator LinkedList<T>::back_iterator() const\n{\n  return Iterator{ m_tail };\n}\n\n#endif //LINKEDLIST_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_06/Pair.h",
    "content": "#ifndef PAIR_H\n#define PAIR_H\n\n#include <compare>\n#include <iostream>\n\ntemplate <typename First, typename Second>\nclass Pair\n{\npublic:\n  // Public members + no m_ prefix analogous to std::pair<> (see <utility> module)\n  First first;    \n  Second second;\n\n  Pair() = default;\n  Pair(const First& f, const Second& s);\n  \n  // Note: not all compiler may fully support this generation yet (C++20)...\n  // (replacing auto with std::strong_ordering may make Soln17_02.cpp compile then,\n  // but in general auto is better because First and/or Second could be types \n  // that are not strongly ordered, such as a floating-point types)\n  auto operator<=>(const Pair& other) const = default;\n};\n\n// Constructor\ntemplate <typename First, typename Second>\nPair<First, Second>::Pair(const First& f, const Second& s)\n  : first{f}, second{s}\n{}\n\ntemplate <typename First, typename Second>\nstd::ostream& operator<<(std::ostream& out, const Pair<First, Second>& pair)\n{\n  return out << '(' << pair.first << \", \" << pair.second << ')';\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_06/Soln17_06.cpp",
    "content": "// Exercising the SparseArray class template in combination with the LinkedList class template\n#include \"SparseArray.h\"\n#include \"LinkedList.h\"\n#include <string>\n#include <string_view>\n#include <iostream>\n#include <cctype>\n#include <utility>\n\nint main()\n{\n  std::string text;                                // Stores input prose or poem\n  std::cout << \"Enter a poem or prose over one or more lines.\\n\"\n            << \"Terminate the input with #:\\n\";\n  getline(std::cin, text, '#');\n\n  SparseArray<LinkedList<std::string>> lists;      // Sparse array of linked lists\n  const std::string_view letters {\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"};\n\n  // Extract words and store in the appropriate list\n  // A list in the SparseArray is selected by the index in letters of the first letter in a word.\n  const std::string_view separators {\" \\n\\t,.\\\"?!;:\"};  // Separators between words\n  size_t start {};                                 // Start of a word\n  size_t end {};                                   // separator position after a word\n  while (std::string::npos != (start = text.find_first_not_of(separators, start)))\n  {\n    end = text.find_first_of(separators, start+1);\n    const auto word{ text.substr(start, end - start) };\n    const auto letter{ static_cast<char>(std::toupper(word[0])) };\n    lists[letters.find(letter)].push_back(word);\n    start = end;\n  }\n\n  // List the words in order 5 to a line\n  const size_t perline {5};\n  \n  for (size_t i {}; i < std::size(letters); ++i)\n  {\n    if (!lists.element_exists_at(i))\n      continue;\n  \n    size_t count {};                               // Word counter\n    for (auto iterator { lists[i].front_iterator() }; iterator; iterator.next())\n    {\n      std::cout << iterator.value() << ' ';\n      if (!(++count % perline))\n        std::cout << std::endl;\n    }\n    std::cout << std::endl;\n  }\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_06/SparseArray.h",
    "content": "// SparseArray class template definition\n// Note the use of the find() helper function and the const-and-back-again idiom to minimize code duplication\n\n#ifndef SPARSEARRAY_H\n#define SPARSEARRAY_H\n\n#include \"Pair.h\"\n#include <vector>\n#include <string>       // For std::to_string()\n#include <utility>      // For std::as_const()\n#include <stdexcept>\n\ntemplate<typename T>\nclass SparseArray\n{\npublic:\n  T& operator[](size_t index);              // Subscript operator (creates default-constructed value if no value exists for the given index)\n  T& at(size_t index);                      // Access function (throws std::out_of_range if no value exists for the given index)\n  const T& at(size_t index) const;          // const overload of at()\n  bool element_exists_at(size_t index) const;  // Return true iff an element exists at the given index\n\nprivate:\n  T* find(size_t index);                    // Helper function (returns nullptr if no value exists for the given index)\n  const T* find(size_t index) const;\n  \n  std::vector<Pair<size_t, T>> m_values;\n};\n\ntemplate<typename T>\nT& SparseArray<T>::operator[](size_t index)\n{\n  if (auto* found{ find(index) }; found)   // Using C++17 initialization statements for if statement \n  {                                        // (see at() function for common, traditional equivalent)\n\t  return *found;\n  }\n  else\n  {\n    m_values.push_back({ index, T{} });    // Or push_back(Pair{...}), or push_back(Pair<size_t, T>{...})\n    return m_values.back().second;         // Remember: std::vector<>::back() returns a reference to its last element\n  }\n}\n\ntemplate<typename T>\nconst T& SparseArray<T>::at(size_t index) const\n{\n  const auto* found{ find(index) };\n  if (found)\n  {\n\t  return *found;\n  }\n  else\n  {\n    throw std::out_of_range{\"No value exists at index \" + std::to_string(index)};\n  }\n}\n\ntemplate<typename T>\nT& SparseArray<T>::at(size_t index)\n{\n  return const_cast<T&>(std::as_const(*this).at(index));\n}\n\ntemplate<typename T>\nbool SparseArray<T>::element_exists_at(size_t index) const\n{\n  return find(index) != nullptr;\n}\n\ntemplate<typename T>\nconst T* SparseArray<T>::find(size_t index) const\n{\n  for (auto& pair : m_values)\n  {\n    if (pair.first == index)\n      return &pair.second;\n  }\n  return nullptr;\n}\n\ntemplate<typename T>\nT* SparseArray<T>::find(size_t index)\n{\n  return const_cast<T*>(std::as_const(*this).find(index));\n}\n\n#endif //SPARSEARRAY_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_07/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  double getLength() const { return m_length; }\n  double getWidth() const { return m_width; }\n  double getHeight() const { return m_height; }\n  \nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_07/BoxFormatter.h",
    "content": "#ifndef BOX_FORMATTER_H\n#define BOX_FORMATTER_H\n\n#include \"Box.h\"\n#include <format>\n\n// Adding specific specializations to the std namespace is allowed\ntemplate <>\nclass std::formatter<Box> : public std::formatter<double>\n{\npublic:\n  \n  /* This was no easy exercise. Fixes required compared to the outline in the exercise:\n      - the member is called advance_to() and not advance() \n        (we actually used advance() by mistake in the book, but hey, \n         it did force you to practice consulting a Standard Library reference?)\n      - you need to specify std::formatter<double> to access the base class format() function\n      - of course you still needed to add \"Box(., ., .)\" as well.\n        One way to do this is repeatedly call std::format_to(),\n        a function similar to std::format() except that it outputs not to a stream but an output iterator.\n        You can also manipulate the iterator directly, as we show in for outputting \n        the second \", \" and the \")\".\n        (Iterator manipulation is explained in more detail in Chapter 20...)\n   */\n  auto format(const Box& box, auto& context)\n  {\n    auto iter{ std::format_to(context.out(), \"Box(\") };\n    context.advance_to(iter);\n    iter = std::formatter<double>::format(box.getLength(), context);\n    iter = std::format_to(iter, \", \");\n    context.advance_to(iter);\n    iter = std::formatter<double>::format(box.getWidth(), context);\n    *iter++ = ',';\n    *iter++ = ' ';\n    context.advance_to(iter);\n    std::formatter<double>::format(box.getHeight(), context);\n    *iter++ = ')';\n    context.advance_to(iter);\n    return iter;\n  }\n};\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_07/Soln17_07.cpp",
    "content": "// Implementing a custom std::formatter<> specialization to format Box objects\n#include \"Box.h\"\n#include \"BoxFormatter.h\"\n#include <iostream>\n\nint main()\n{\n  Box box{ 1, 2, 3 };\n  std::cout << std::format(\"My new box, {:.2}, is fabulous!\", box);\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_07A/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  double getLength() const { return m_length; }\n  double getWidth() const { return m_width; }\n  double getHeight() const { return m_height; }\n  \nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_07A/BoxFormatter.h",
    "content": "#ifndef BOX_FORMATTER_H\n#define BOX_FORMATTER_H\n\n#include \"Box.h\"\n#include <format>\n#include <string>\n\n// Adding specific specializations to the std namespace is allowed\ntemplate <>\nclass std::formatter<Box>\n{\npublic:\n  auto parse(auto& context)\n  {\n    // [context.begin(), context.end()) is a character range that contains a part of\n    // the format string starting from the format specifications to be parsed,\n    // e.g. in\n    //\n    //   std::format(\"My new box, {:.2}, is fabulous!\", box)\n    //\n    // the range will contain \".2}, is fabulous!\". The formatter should\n    // parse specifiers until '}' or the end of the range.\n    //\n    // Our goal for this same example is to store \"Box({:.2}, {:.2}, {:.2})\" in m_format.\n    // We first find the range where for instance \".2\" is present,\n    // and then inject that three times into a format string of the correct form.\n\n    auto iter{ context.begin() };\n    if (iter == context.end())  // May happen for empty {} format specifiers\n    {\n      m_format = \"Box({}, {}, {})\";\n      return iter;\n    }\n\n    // Search for the closing '}'\n    while (iter != context.end() && *iter != '}') ++iter;\n\n    if (*iter != '}') // If not found, fail\n    {\n      throw std::format_error{ \"missing closing braces, }\" };\n    }\n    \n    // Main trick in this format expression is that to get { or } \n    // in the output you have to write {{ or }}. \n    // Otherwise std::format() will see these characters as the begin or end of a replacement field.\n    m_format = std::format(\"Box({{:{0}}}, {{:{0}}}, {{:{0}}})\", std::string(context.begin(), iter));\n\n    return iter;\n  }\n\n  auto format(const Box& box, auto& context)\n  {\n    return std::format_to(\n      context.out(), \n      m_format, \n      box.getLength(), box.getWidth(), box.getHeight()\n    );\n  }\n\nprivate:\n  std::string m_format;\n};\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 17/Soln17_07A/Soln17_07A.cpp",
    "content": "// Implementing a custom std::formatter<> specialization to format Box objects\n// (Alternate solution)\n#include \"Box.h\"\n#include \"BoxFormatter.h\"\n#include <iostream>\n\nint main()\n{\n  Box box{ 1, 2, 3 };\n  std::cout << std::format(\"My new box, {:.2}, is fabulous!\", box);\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_01/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <ostream>\n#include <format>\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_01/RandomBoxes.h",
    "content": "#ifndef RANDOM_BOXES_H\n#define RANDOM_BOXES_H\n\n#include \"Box.h\"\n#include <random>        // For random number generation\n#include <functional>    // For std::bind()\n#include <memory>        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\ninline auto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\ninline Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\ninline auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_01/Soln18_01.cpp",
    "content": "// Exercise 18-1 Define move operators for the Truckload class\n#include <iostream>\n#include <memory>\n#include \"Truckload.h\"\n#include \"RandomBoxes.h\"\n\n/*\n  Things to watch out for:\n    - use of copy-and-swap / move-and-swap function\n    - noexcept move and swap members\n    - dislodge the linked list from the moved load in the move constructor\n*/\n\nint main()\n{\n  const double dimLimit {99.0};             // Upper limit on Box dimensions\n  Truckload load;\n  const size_t boxCount {20};               // Number of Box object to be created\n\n  // Create boxCount Box objects\n  for (size_t i {}; i < boxCount; ++i)\n    load.addBox(randomSharedBox());\n\n  std::cout << \"The boxes in the Truckload are:\\n\";\n  std::cout << load << std::endl;\n\n  Truckload moveConstructedLoad{ std::move(load) };\n\n  std::cout << \"The boxes in the move constructed Truckload are:\\n\";\n  std::cout << moveConstructedLoad << std::endl;\n\n  Truckload moveAssignedLoad;\n  moveAssignedLoad = std::move(moveConstructedLoad);\n  \n  std::cout << \"The boxes in the move assigned Truckload are:\\n\";\n  std::cout << moveAssignedLoad << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_01/Truckload.cpp",
    "content": "#include \"Truckload.h\"\n\n#include <iostream>\n#include <stdexcept>    // For standard exception type std::out_of_range \n#include <string>       // For std::string and std::to_string()\n#include <utility>      // For std::swap()\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Destructor: clean up the list (moved to source file to gain access to definition of Package)\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\n// Copy assignment operator (updated to use copy-and-swap of course!)\nTruckload& Truckload::operator=(const Truckload& src)\n{\n  auto copy{src};\n  swap(copy);\n  return *this;\n}\n\n// Move constructor (noexcept!)\nTruckload::Truckload(Truckload&& src) noexcept\n  : m_head{ src.m_head }\n  , m_tail{ src.m_tail }\n{\n  // Do not forget to dislodge the linked list from the moved src Truckload\n  src.m_head = src.m_tail = nullptr;\n}\n\n// Move assignment operator (noexcept + move-and-swap of course!)\nTruckload& Truckload::operator=(Truckload&& src) noexcept\n{\n  auto moved{std::move(src)};\n  swap(moved);\n  return *this;\n}\n\n// Swap assignment operator (noexcept + move-and-swap of course!)\nvoid Truckload::swap(Truckload& other) noexcept\n{\n  std::swap(m_head, other.m_head);\n  std::swap(m_tail, other.m_tail);\n}\n\n// Optional yet conventional non-member function (forwards to member function)\nvoid swap(Truckload& one, Truckload& other) noexcept\n{\n  one.swap(other);\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n                \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nSharedBox& Truckload::operator[](size_t index) const\n{\n  size_t count{};             // Package count\n  for (Package* package{ m_head }; package; package = package->m_next)\n  {\n    if (count++ == index)      // Up to index yet?\n      return package->m_box;   // If so return the pointer to Box\n  }\n  throw std::out_of_range{ \"Index too large: \" + std::to_string(index) };\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_01/Truckload.h",
    "content": "#ifndef TRUCKLOAD_H\n#define TRUCKLOAD_H\n\n#include \"Box.h\"\n\n#include <memory>\n#include <vector>\n#include <ostream>\n\nusing SharedBox = std::shared_ptr<Box>;\n\nclass Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n  ~Truckload();                     // Destructor\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n\n  Truckload(const Truckload& src);  // Copy constructor\n  Truckload& operator=(const Truckload& src);  // Copy assignment operator\n\n  Truckload(Truckload&& src) noexcept;  // Move constructor\n  Truckload& operator=(Truckload&& src) noexcept;  // Move assignment operator\n\n  void swap(Truckload& other) noexcept;\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox& operator[](size_t index) const;   // Overloaded subscript operator\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load);\n\n// Optional yet conventional non-member function (forwards to member function)\nvoid swap(Truckload& one, Truckload& other) noexcept;\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_02/LinkedList.h",
    "content": "#ifndef LINKEDLIST_H\n#define LINKEDLIST_H\n\n/*\nThe LinkedList template below follows some (not all) conventions of Standard Library containers:\nsome member function names are analogous,\nas is the choice not to work with exceptions in case you do something wrong\n(such as calling back() or pop_front() on an empty list).\nThe latter has the implication that if you mis-use the container,\nyour program will likely crash...\n\nNew in this version are the move constructor / assignment operators \n(mind the noexcepts, as always), and the fact that the push_back() and push_front() \nmembers have been updated to allow new T values to be moved in as well.\nDo not forget to add a move constructor for the nested Node class as well\nto prevent any unnecessary copies there!\n\nNote that if you are not defining a generic container template, \nyou'd usually not add multiple overloads for copying and moving anymore.\nEven here, you could consider simply defining these two pass-by-value members:\n\n  void push_front(T value);       // Copy or move an object to the head\n  void push_back(T value);        // Copy or move an object to the tail\n\nAnd then apply the same simplification to the constructor of the nested Node class.\nThe only downside then is that this is not optimal for objects without support for move semantics, \nbit given that move semantics has been around for almost a decade should be increasingly unlikely.\nWe invite you to give it a try, and simplify the code along these lines.\n*/\n\n#include <cstddef>        // for the size_t typedef\n#include <utility>        // for std::swap()\n\ntemplate<typename T>\nclass LinkedList\n{\npublic:\n  LinkedList() = default;                  // Default constructor (all pointers are initialised to nullptr)\n  ~LinkedList();\n\n  LinkedList(const LinkedList& list);      // Copy constructor\n  LinkedList& operator=(const LinkedList& list); // Copy assignment operator\n\n  LinkedList(LinkedList&& list) noexcept;  // Move constructor\n  LinkedList& operator=(LinkedList&& list) noexcept; // Move assignment operator\n\n  void push_front(const T& value);         // Add an object to the head\n  void push_back(const T& value);          // Add an object to the tail\n  void push_front(T&& value);              // Move an object to the head\n  void push_back(T&& value);               // Move an object to the tail\n\n  void pop_back();                         // Removes the last element from the list (undefined behavior for empty lists)\n  void pop_front();                        // Removes the first element from the list (undefined behavior for empty lists)\n\n  T& front();                              // Get the object at the head (undefined behavior for empty lists)\n  T& back();                               // Get the object at the tail (undefined behavior for empty lists)\n  const T& front() const;                  // Get the object at the head (undefined behavior for empty lists)\n  const T& back() const;                   // Get the object at the tail (undefined behavior for empty lists)\n\n  bool empty() const;                      // Checks whether the list is empty or not\n  void clear();                            // Function to remove all elements from the list\n  size_t size() const;                     // Get the number of elements from the list\n\n  class Iterator;                          // Nested Iterator class declaration (definition below)\n  Iterator front_iterator() const;         // Get an Iterator that starts at the head\n  Iterator back_iterator() const;          // Get an Iterator that starts at the tail\n\n  void swap(LinkedList& other) noexcept;   // Swap function\n\nprivate:\n  class Node                               // Node class definition\n  {\n  public:\n    Node(const T& value)\n      : m_value{ value }\n    {}\n    Node(T&& value)\n      : m_value{ std::move(value) }\n    {}\n\n    T m_value;\n    Node* m_next{};\n    Node* m_previous{};\n  };\n\n  void push_front(Node* node) noexcept;\n  void push_back(Node* node) noexcept;\n\n  Node* m_head{};    // Pointer to first node\n  Node* m_tail{};    // Pointer to last node\n  size_t m_size{};\n};\n\n// Non-member swap function.\n// Convention dictates swap is present as non-member function.\n// For class types it is often easiest (and recommended) \n// to implement it using a member swap function.\ntemplate<typename T>\nvoid swap(LinkedList<T>& one, LinkedList<T>& other)\n{\n  one.swap(other);\n}\n\n// ---------------------------------------------\n// Member definitions\n// ---------------------------------------------\n\n// Destructor template\ntemplate<typename T>\nLinkedList<T>::~LinkedList()\n{\n  clear();\n}\n\n// Copy constructor template\ntemplate<typename T>\nLinkedList<T>::LinkedList(const LinkedList& list)\n{\n  // Use existing members (iteration, push_back()) to implement the copying\n  // This avoids duplicating any code that manipulates the list's pointers / size members.\n  for (auto iterator{ list.front_iterator() }; iterator; iterator.next())\n    push_back(iterator.value());\n}\n\n// Move constructor template\ntemplate<typename T>\nLinkedList<T>::LinkedList(LinkedList&& list) noexcept\n  : m_head{ list.m_head }\n  , m_tail{ list.m_tail }\n  , m_size{ list.m_size }\n{\n  // Make sure list no longer deletes the nodes when destructed\n  list.m_size = 0;\n  list.m_head = list.m_tail = nullptr;  // <-- optional\n}\n\n// Copy assignment operator template (uses copy-and-swap idiom)\ntemplate<typename T>\nLinkedList<T>& LinkedList<T>::operator=(const LinkedList& other)\n{\n  auto copy{ other };\n  swap(copy);\n  return *this;\n}\n\n// Move assignment operator template (uses move-and-swap idiom)\ntemplate<typename T>\nLinkedList<T>& LinkedList<T>::operator=(LinkedList&& other) noexcept\n{\n  auto moved{ std::move(other) };\n  swap(moved);\n  return *this;\n}\n\n// Template for member functions that adds a node to the head of the list\ntemplate<typename T> \nvoid LinkedList<T>::push_front(Node* node) noexcept\n{\n  Node* oldHead{ m_head };\n  m_head = node;\n  ++m_size;\n\n  if (oldHead)\n  {\n    oldHead->m_previous = m_head;\n    m_head->m_next = oldHead;\n  }\n  else  // list was empty before, and now has one element\n  {\n    m_tail = m_head;\n  }\n}\n\n// Template for member functions that copy a value to the head of the list\n// Use push_front(Node*) to avoid any duplication!\ntemplate<typename T>\nvoid LinkedList<T>::push_front(const T& value)\n{\n  push_front(new Node{value});\n}\n\n// Template for member functions that moves a value to the head of the list\n// Use push_front(Node*) to avoid any duplication!\ntemplate<typename T>\nvoid LinkedList<T>::push_front(T&& value)\n{\n  push_front(new Node{std::move(value)});\n}\n\n// Template for member functions that add a node to the tail of the list\ntemplate<typename T>\nvoid LinkedList<T>::push_back(Node* node) noexcept\n{\n  Node* oldTail{ m_tail };\n  m_tail = node;\n  ++m_size;                 \n\n  if (oldTail)\n  {\n    oldTail->m_next = m_tail;\n    m_tail->m_previous = oldTail;\n  }\n  else  // list was empty before, and now has one element\n  {\n    m_head = m_tail;\n  }\n}\n\n// Template for member functions that copy a value to the tail of the list\n// Use push_back(Node*) to avoid any duplication!\ntemplate<typename T>\nvoid LinkedList<T>::push_back(const T& value)\n{\n  push_back(new Node{value});\n}\n\n// Template for member functions that moves a value to the tail of the list\n// Use push_back(Node*) to avoid any duplication!\ntemplate<typename T>\nvoid LinkedList<T>::push_back(T&& value)\n{\n  push_back(new Node{std::move(value)});\n}\n\n// Template for member functions that remove an object from the head of the list\ntemplate<typename T> \nvoid LinkedList<T>::pop_front()\n{\n  Node* oldHead{ m_head };\n  if (oldHead == m_tail)\n  {\n    m_head = m_tail = nullptr;\n  }\n  else\n  {\n    m_head = oldHead->m_next;\n    m_head->m_previous = nullptr;\n  }\n  \n  --m_size;\n  delete oldHead;\n}\n\n// Template function member to remove an object from the tail of the list\ntemplate<typename T>\nvoid LinkedList<T>::pop_back()\n{\n  Node* oldTail{ m_tail };\n  if (oldTail == m_head)\n  {\n    m_head = m_tail = nullptr;\n  }\n  else\n  {\n    m_tail = oldTail->m_previous;\n    m_tail->next = nullptr;\n  }\n\n  --m_size;\n  delete oldTail;\n}\n\n// Template function members to get the object at the head of the list\ntemplate<typename T>\nT& LinkedList<T>::front()\n{\n  return m_head->value;\n}\ntemplate<typename T>\nconst T& LinkedList<T>::front() const\n{\n  return m_head->value;\n}\n\n// Template function members to get the object at the tail of the list\ntemplate<typename T>\nT& LinkedList<T>::back()\n{\n  return m_tail->value;\n}\ntemplate<typename T>\nconst T& LinkedList<T>::back() const\n{\n  return m_tail->value;\n}\n\n// Check whether list is empty or not\ntemplate<typename T>\nbool LinkedList<T>::empty() const\n{\n  return m_size == 0;  // (or m_head == nullptr, or m_tail == nullptr)\n}\n\n// Template to get the size of a list\ntemplate<typename T> \nsize_t LinkedList<T>::size() const\n{\n  return m_size;\n}\n\n// Template to clear a list\ntemplate<typename T>\nvoid LinkedList<T>::clear()\n{\n  // Use existing functions (avoid code duplication!)\n  while (!empty()) pop_front();\n}\n\n// Member function template to swap two lists\ntemplate<typename T>\nvoid LinkedList<T>::swap(LinkedList& other) noexcept\n{\n  std::swap(m_head, other.m_head);\n  std::swap(m_tail, other.m_tail);\n  std::swap(m_size, other.m_size);\n}\n\n// Definition of the nested Iterator class\ntemplate<typename T>\nclass LinkedList<T>::Iterator\n{\npublic:\n  explicit Iterator(Node* node) \n    : m_current{ node }\n  {}\n\n  const T& value() const { return m_current->m_value; }\n\n  bool hasValue() const { return m_current != nullptr; }\n  operator bool() const { return m_current != nullptr; }\n\n  void next() { m_current = m_current->m_next; }\n  void previous() { m_current = m_current->m_previous; }\n\nprivate:\n  Node* m_current;\n};\n\n// Get an Iterator that starts at the head\ntemplate<typename T>\ntypename LinkedList<T>::Iterator LinkedList<T>::front_iterator() const\n{\n  return Iterator{ m_head };\n}\n\n// Get an Iterator that starts at the tail\ntemplate<typename T>\ntypename LinkedList<T>::Iterator LinkedList<T>::back_iterator() const\n{\n  return Iterator{ m_tail };\n}\n\n#endif //LINKEDLIST_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_02/Soln18_02.cpp",
    "content": "// Exercise 18-2 Exercising the LinkedList's move capabilities\n// We do so by creating a linked list of std::unique_ptr<> elements: \n// a perfect example of an element type that cannot be copied!\n#include \"LinkedList.h\"\n#include <memory>     // for std::unique_ptr<>\n#include <iostream>\n#include <string_view>\n\nvoid printList(std::string_view message, const LinkedList<std::unique_ptr<int>>& list)\n{\n  std::cout << message << \": \";\n  for (auto iterator{ list.front_iterator() }; iterator; iterator.next())\n  {\n    std::cout << *iterator.value() << ' ';\n  }\n  std::cout << std::endl;\n}\n\nint main()\n{\n  // In real life, you'd rarely use std::unique_ptr<int>. \n  // A more realistic use would be std::unique_ptr<ClassType>, \n  // where ClassType is a (potentially polymorphic) class type.\n  // For our example here, std::unique_ptr<int> will do just fine:\n  // the idea is simply to use an uncopyable type as template type argument for LinkedList.\n  \n  LinkedList<std::unique_ptr<int>> number_pointers;\n  \n  auto one{ std::make_unique<int>(1) };\n  number_pointers.push_back(std::move(one));\n  number_pointers.push_back(std::make_unique<int>(2));\n  \n  printList(\"Elements in the original list\", number_pointers);\n  \n  LinkedList<std::unique_ptr<int>> move_constructed{std::move(number_pointers)};\n  \n  printList(\"Elements in the move constructed list\", move_constructed);\n  \n  LinkedList<std::unique_ptr<int>> move_assigned;\n  move_assigned = std::move(move_constructed);\n  \n  printList(\"Elements in the move assigned list\", move_assigned);\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_03/Customer.cpp",
    "content": "// A simple C++ customer class\n\n#include \"Customer.h\"\n\nCustomer::Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city)\n  : m_surname{ surname }\n  , m_name{ name }\n  , m_street{ street }\n  , m_streetNumber{ streetNumber }\n  , m_city{ city }\n{}\n\nstd::string Customer::toString() const\n{\n  std::string result;\n  result += m_surname;\n  result += ' ';\n  result += m_name;\n  result += \", \";\n  result += m_street;\n  result += ' ';\n  result += std::to_string(m_streetNumber);\n  result += \", \";\n  result += m_city;\n  return result;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_03/Customer.h",
    "content": "// A simple C++ customer class\n\n#ifndef CUSTOMER_H\n#define CUSTOMER_H\n\n#include <string>\n#include <string_view>\n\nclass Customer\n{\npublic:\n  Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city\n  );\n\n  std::string toString() const;\n  \nprivate:\n  std::string m_surname;\n  std::string m_name;\n  std::string m_street;\n  int m_streetNumber;\n  std::string m_city;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_03/DB.cpp",
    "content": "// A mocked database\n\n#include \"DB.h\"\n#include <cstring>    // For std::strcmp()\n#include <memory>\n#include <vector>\n\nnamespace\n{\n  struct QueryResult\n  {\n    std::vector<std::vector<const char*>> data;\n    size_t index {};\n  };\n\n  class Database\n  {\n  public:\n    Database() = default;\n    \n\t  bool hasConnection() const { return m_connected; }\n    void connect() { m_connected = true; }\n    void disconnect() { m_connected = false; }\n    \n    QueryResult* query(const char* query);\n    \n  private:  \n    bool m_connected{};\n  };\n}\n\nDB_CONNECTION* db_connect()\n{\n  // We only have one single database, which allows only one single connection:\n  static Database theDatabase;\n  if (theDatabase.hasConnection())\n  {\n    return nullptr;\n  }\n  else\n  {\n    theDatabase.connect();\n    return &theDatabase;\n  }\n}\n\nvoid db_disconnect(DB_CONNECTION* connection)\n{\n  // reinterpret_cast<> is used to cast between pointers/references of \n  // unrelated types (such as void* and Database*)\n  reinterpret_cast<Database*>(connection)->disconnect();\n}\n\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query)\n{\n  return reinterpret_cast<Database*>(connection)->query(query);\n}\n\nQueryResult* Database::query(const char* query)\n{\n  if (!hasConnection())\n  {\n    return nullptr;\n  }\n  \n  // Our database only understands one single query!\n  if (std::strcmp(query, \"SELECT * FROM CUSTOMER_TABEL\") != 0)\n  {\n    return nullptr;\n  }\n  \n  auto result{ std::make_unique<QueryResult>() };\n  result->data = std::vector<std::vector<const char*>>{\n    { \"Sherlock\", \"Holmes\", \"Baker Street\", \"221\", \"London\" },\n    { \"Joe\", \"Biden\", \"Pennsylvania Avenue\", \"1600\", \"Washington DC\" },\n    { \"Donald\", \"Duck\", \"Webfoot Walk\", \"1313\", \"Duckville\" },\n    { \"Sirius\", \"Black\", \"Grimmauld Place\", \"12\", \"London\" },\n    { \"Nemo\", \"Clownfish\", \"Wallaby Way\", \"42\", \"Sydney\" },\n    { \"Sam\", \"Malone\", \"Beacon Street\", \"112\", \"Boston\" }\n  };\n  return result.release();\n}\n\nint db_num_fields(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->data.empty())\n  {\n    return -1;\n  }\n  else\n  {\n    return static_cast<int>(theResult->data.front().size());\n  }\n}\n\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->index >= theResult->data.size())\n  {\n    return nullptr;\n  }\n  else\n  {\n     return theResult->data[theResult->index++].data();\n  }\n}\n\nvoid db_free_result(DB_QUERY_RESULT* result)\n{\n  delete reinterpret_cast<QueryResult*>(result);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_03/DB.h",
    "content": "// A C-style interface to a mock database\n// (a simplified subset of the MySQL C interface)\n\n#ifndef DB_INCLUDES\n#define DB_INCLUDES\n\nusing DB_CONNECTION = void;\nusing DB_QUERY_RESULT = void;\nusing DB_ROW = const char**;\n\n/*! Make a connection to the database\n * Do not forget to close the database connection (db_disconnect()) once done with it.\n * \\return a DB_CONNECTION handle; nullptr upon failure\n */\nDB_CONNECTION* db_connect();\n\n/*! Query the database\n * \\param[in] connection A database connection handle returned by db_connect()\n * \\param[in] query      A SQL query\n * \\return A handle to the result of the query (memory to be freed using db_free_result()!)\n */\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query);\n\n/*! Retrieve the number of fields per row stored by the given query result\n * \\param[in] result A handle returned by db_query \n * \\return The number of fields per row stored by the result; -1 upon failure\n */\nint db_num_fields(DB_QUERY_RESULT* result);\n\n/*! Fetch a single row from the result.\n * \\param[in] result A handle returned by db_query\n * \\return An array of strings. Each field is represented as a string (zero-terminated char array). \n * \tLet row be the result, then the first field is accessed using result[0]. \n */\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result);\n\n/*! Release the memory allocated for the result.\n * \\param[in] result A handle returned by db_query()\n */\nvoid db_free_result(DB_QUERY_RESULT* result);\n\n/*! Disconnect from the database\n * \\param[in] connection   A connection handle returned by db_connect()\n */\nvoid db_disconnect(DB_CONNECTION* connection);\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_03/DBException.h",
    "content": "// A simple C++ exception type\n\n#ifndef DB_EXCEPTION_H\n#define DB_EXCEPTION_H\n\n#include <stdexcept>\n\nclass DatabaseException : public std::runtime_error\n{\npublic:\n  using std::runtime_error::runtime_error;  // Inherit constructor\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_03/DB_RAII.h",
    "content": "// RAII classes for handles returned by DB.h C interface functions\n\n/*\n  In this solution we have the RAII classes accept the resource handle in their constructor.\n  Alternatively, you could also acquire the resources inside the constructors of the RAII class.\n  For instance: you could call db_connect() from within the DBConnectionRAII() contructor.\n\n  When creating RAII classes, it is typically crucial they cannot be copied\n  (otherwise multiple objects would be releasing the same resource, \n   which is typically not allowed). To accomplish this, you delete both copy members.\n*/\n\n#ifndef DB_RAII_H\n#define DB_RAII_H\n\n#include \"DB.h\"\n\n/**\n * RAII object that ensures that a given database connection is closed\n * once the RAII object goes out of scope.\n */ \nclass DBConnectionRAII\n{\npublic:\n  DBConnectionRAII(DB_CONNECTION* connection) noexcept\n    : m_connection(connection)\n  {\n  }  \n  ~DBConnectionRAII() // implicitly noexcept\n  {\n    if (m_connection)\n    {\n      db_disconnect(m_connection);\n    }\n  }\n\n  // Prevent copying by deleting both copy members\n  DBConnectionRAII(const DBConnectionRAII& other) = delete;\n  DBConnectionRAII& operator=(const DBConnectionRAII& other) = delete;\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_CONNECTION*() const noexcept { return m_connection; }\n  \nprivate:\n  DB_CONNECTION* m_connection;\n};\n\n/* RAII object that takes a DB_QUERY_RESULT and ensures it is freed */\nclass DBQueryResultRAII\n{\npublic:\n  DBQueryResultRAII(DB_QUERY_RESULT* result) noexcept \n    : m_result(result)\n  {\n  }\n  \n  ~DBQueryResultRAII() // implicitly noexcept\n  {\n    if (m_result)\n    {\n      db_free_result(m_result);\n    }\n  }\n\n  // Prevent copying by deleting both copy members\n  DBQueryResultRAII(const DBQueryResultRAII& other) = delete;\n  DBQueryResultRAII& operator=(const DBQueryResultRAII& other) = delete;\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_QUERY_RESULT* () const noexcept { return m_result; }\n\nprivate:\n  DB_QUERY_RESULT* m_result;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_03/Soln18_03.cpp",
    "content": "// Exercise 18-3\n/*\n  Below is the same test program as used in Exercise 16-6, \n  with some additional commented lines to show that the RAII objects cannot be copied.\n*/\n\n#include <iostream>\n#include <vector>\n\n#include \"DB.h\"\n#include \"DBException.h\"\n#include \"Customer.h\"\n#include \"DB_RAII.h\"\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result);           // Sanity check on the number of fields returned by our query\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result); // Convert the DB result to a series of C++ objects\nvoid print(std::ostream& stream, const Customer& customer);   // Print a given customer to a given output stream\n\nint main()\n{\n  DBConnectionRAII connection{ db_connect() };\n  /*\n    DBConnectionRAII copy{ connection };  // Will not compile (copy constructor is deleted)\n  \n    DBConnectionRAII otherConnection{ db_connect() };\n    otherConnection = connection;         // Will not compile (copy assignment operator is deleted)\n  */\n  try\n  {\n    DBQueryResultRAII result{ db_query(connection, \"SELECT * FROM CUSTOMER_TABEL\") };\n    if (!result)\n    {\n      throw DatabaseException{\"Query failed\"};\n    }\n  \n  /*\n    DBQueryResultRAII copy{ result };    // Will not compile (copy constructor is deleted)\n  \n    DBQueryResultRAII otherResult{ db_query(connection, \"SELECT * FROM CUSTOMER_TABEL\") };\n    otherResult = result;                // Will not compile (copy assignment operator is deleted)\n  */\n  \n    std::vector<Customer> customers{ readCustomers(result) };\n  \n  if (customers.empty())\n  {\n    std::cerr << \"No customers found?\" << std::endl;\n    return 2;\n  }\n    \n  for (auto& customer : customers)\n  {\n     print(std::cout, customer);\n  }\n  }\n  catch (std::exception& caught)\n  {\n    std::cerr << caught.what() << std::endl;\n    return 1;\n  }\n}\n\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result)\n{\n  // Sanity check \n  // (if the number of fields does not match 5, \n  // the code below would crash!)\n  verifyCustomerFields(result);\n   \n  std::vector<Customer> customers;\n  \n  auto row{ db_fetch_row(result) };\n  while (row)\n  {\n    customers.push_back(Customer{\n      row[0],            // Surname\n      row[1],            // Name\n      row[2],            // Street\n      std::stoi(row[3]), // Street number\n      row[4]             // City\n    });\n    \n    row = db_fetch_row(result);\n  }\n  \n  return customers;\n}\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result)\n{\n  int numFields{ db_num_fields(result) };\n  if (numFields < 0)\n  {\n    throw DatabaseException{\"db_num_fields() failed\"};\n  }\n  if (numFields != 5)\n  {\n    throw DatabaseException{\"Unexpected number of fields: \" + std::to_string(numFields)};\n  }\n}\n\nvoid print(std::ostream& stream, const Customer& customer)\n{\n  stream << customer.toString() << std::endl;\n  if (std::cout.fail())\n  {\n    std::cout.clear();\n    throw std::runtime_error(\"Failed to output customer\");\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_04/Customer.cpp",
    "content": "// A simple C++ customer class\n\n#include \"Customer.h\"\n\nCustomer::Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city)\n  : m_surname{ surname }\n  , m_name{ name }\n  , m_street{ street }\n  , m_streetNumber{ streetNumber }\n  , m_city{ city }\n{}\n\nstd::string Customer::toString() const\n{\n  std::string result;\n  result += m_surname;\n  result += ' ';\n  result += m_name;\n  result += \", \";\n  result += m_street;\n  result += ' ';\n  result += std::to_string(m_streetNumber);\n  result += \", \";\n  result += m_city;\n  return result;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_04/Customer.h",
    "content": "// A simple C++ customer class\n\n#ifndef CUSTOMER_H\n#define CUSTOMER_H\n\n#include <string>\n#include <string_view>\n\nclass Customer\n{\npublic:\n  Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city\n  );\n\n  std::string toString() const;\n  \nprivate:\n  std::string m_surname;\n  std::string m_name;\n  std::string m_street;\n  int m_streetNumber;\n  std::string m_city;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_04/DB.cpp",
    "content": "// A mocked database\n\n#include \"DB.h\"\n#include <cstring>    // For std::strcmp()\n#include <memory>\n#include <vector>\n\nnamespace\n{\n  struct QueryResult\n  {\n    std::vector<std::vector<const char*>> data;\n    size_t index {};\n  };\n\n  class Database\n  {\n  public:\n    Database() = default;\n    \n\t  bool hasConnection() const { return m_connected; }\n    void connect() { m_connected = true; }\n    void disconnect() { m_connected = false; }\n    \n    QueryResult* query(const char* query);\n    \n  private:  \n    bool m_connected{};\n  };\n}\n\nDB_CONNECTION* db_connect()\n{\n  // We only have one single database, which allows only one single connection:\n  static Database theDatabase;\n  if (theDatabase.hasConnection())\n  {\n    return nullptr;\n  }\n  else\n  {\n    theDatabase.connect();\n    return &theDatabase;\n  }\n}\n\nvoid db_disconnect(DB_CONNECTION* connection)\n{\n  // reinterpret_cast<> is used to cast between pointers/references of \n  // unrelated types (such as void* and Database*)\n  reinterpret_cast<Database*>(connection)->disconnect();\n}\n\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query)\n{\n  return reinterpret_cast<Database*>(connection)->query(query);\n}\n\nQueryResult* Database::query(const char* query)\n{\n  if (!hasConnection())\n  {\n    return nullptr;\n  }\n  \n  // Our database only understands one single query!\n  if (std::strcmp(query, \"SELECT * FROM CUSTOMER_TABEL\") != 0)\n  {\n    return nullptr;\n  }\n  \n  auto result{ std::make_unique<QueryResult>() };\n  result->data = std::vector<std::vector<const char*>>{\n    { \"Sherlock\", \"Holmes\", \"Baker Street\", \"221\", \"London\" },\n    { \"Joe\", \"Biden\", \"Pennsylvania Avenue\", \"1600\", \"Washington DC\" },\n    { \"Donald\", \"Duck\", \"Webfoot Walk\", \"1313\", \"Duckville\" },\n    { \"Sirius\", \"Black\", \"Grimmauld Place\", \"12\", \"London\" },\n    { \"Nemo\", \"Clownfish\", \"Wallaby Way\", \"42\", \"Sydney\" },\n    { \"Sam\", \"Malone\", \"Beacon Street\", \"112\", \"Boston\" }\n  };\n  return result.release();\n}\n\nint db_num_fields(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->data.empty())\n  {\n    return -1;\n  }\n  else\n  {\n    return static_cast<int>(theResult->data.front().size());\n  }\n}\n\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->index >= theResult->data.size())\n  {\n    return nullptr;\n  }\n  else\n  {\n     return theResult->data[theResult->index++].data();\n  }\n}\n\nvoid db_free_result(DB_QUERY_RESULT* result)\n{\n  delete reinterpret_cast<QueryResult*>(result);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_04/DB.h",
    "content": "// A C-style interface to a mock database\n// (a simplified subset of the MySQL C interface)\n\n#ifndef DB_INCLUDES\n#define DB_INCLUDES\n\nusing DB_CONNECTION = void;\nusing DB_QUERY_RESULT = void;\nusing DB_ROW = const char**;\n\n/*! Make a connection to the database\n * Do not forget to close the database connection (db_disconnect()) once done with it.\n * \\return a DB_CONNECTION handle; nullptr upon failure\n */\nDB_CONNECTION* db_connect();\n\n/*! Query the database\n * \\param[in] connection A database connection handle returned by db_connect()\n * \\param[in] query      A SQL query\n * \\return A handle to the result of the query (memory to be freed using db_free_result()!)\n */\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query);\n\n/*! Retrieve the number of fields per row stored by the given query result\n * \\param[in] result A handle returned by db_query \n * \\return The number of fields per row stored by the result; -1 upon failure\n */\nint db_num_fields(DB_QUERY_RESULT* result);\n\n/*! Fetch a single row from the result.\n * \\param[in] result A handle returned by db_query\n * \\return An array of strings. Each field is represented as a string (zero-terminated char array). \n * \tLet row be the result, then the first field is accessed using result[0]. \n */\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result);\n\n/*! Release the memory allocated for the result.\n * \\param[in] result A handle returned by db_query()\n */\nvoid db_free_result(DB_QUERY_RESULT* result);\n\n/*! Disconnect from the database\n * \\param[in] connection   A connection handle returned by db_connect()\n */\nvoid db_disconnect(DB_CONNECTION* connection);\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_04/DBException.h",
    "content": "// A simple C++ exception type\n\n#ifndef DB_EXCEPTION_H\n#define DB_EXCEPTION_H\n\n#include <stdexcept>\n\nclass DatabaseException : public std::runtime_error\n{\npublic:\n  using std::runtime_error::runtime_error;  // Inherit constructor\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_04/DB_RAII.h",
    "content": "// RAII classes for handles returned by DB.h C interface functions\n\n/*\n  In this solution we have the RAII classes accept the resource handle in their constructor.\n  Alternatively, you could also acquire the resources inside the constructors of the RAII class.\n  For instance: you could call db_connect() from within the DBConnectionRAII() contructor.\n\n  When creating RAII classes, it is typically crucial they cannot be copied\n  (otherwise multiple objects would be releasing the same resource, \n  which is typically not allowed). To accomplish this, you delete both copy members.\n  Moving RAII objects, on the other hand, is usually possible.\n*/\n\n#ifndef DB_RAII_H\n#define DB_RAII_H\n\n#include \"DB.h\"\n\n/**\n * RAII object that ensures that a given database connection is closed\n * once the RAII object goes out of scope.\n */ \nclass DBConnectionRAII\n{\npublic:\n  DBConnectionRAII(DB_CONNECTION* connection = nullptr) noexcept\n    : m_connection(connection)\n  {\n  }  \n  ~DBConnectionRAII() // implicitly noexcept\n  {\n    if (m_connection)\n    {\n      db_disconnect(m_connection);\n    }\n  }\n\n  // Prevent copying by deleting both copy members\n  DBConnectionRAII(const DBConnectionRAII& other) = delete;\n  DBConnectionRAII& operator=(const DBConnectionRAII& other) = delete;\n\n  // Allow moving by adding the appropriate members\n  DBConnectionRAII(DBConnectionRAII&& other) noexcept\n    : m_connection{ other.m_connection }\n  {\n    other.m_connection = nullptr; // Make sure other no longer closes the connection\n  }\n  DBConnectionRAII& operator=(DBConnectionRAII&& other) noexcept\n  {\n    // You could consider move-and-swap here, but it's so trivial we decided against it here.\n    m_connection = other.m_connection;\n    other.m_connection = nullptr;\n    return *this;\n  }\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_CONNECTION*() const noexcept { return m_connection; }\n  \nprivate:\n  DB_CONNECTION* m_connection;\n};\n\n/* RAII object that takes a DB_QUERY_RESULT and ensures it is freed */\nclass DBQueryResultRAII\n{\npublic:\n  DBQueryResultRAII(DB_QUERY_RESULT* result = nullptr) noexcept\n    : m_result{ result }\n  {\n  }\n  \n  ~DBQueryResultRAII() // implicitly noexcept\n  {\n    if (m_result)\n    {\n      db_free_result(m_result);\n    }\n  }\n\n  // Prevent copying by deleting both copy members\n  DBQueryResultRAII(const DBQueryResultRAII& other) = delete;\n  DBQueryResultRAII& operator=(const DBQueryResultRAII& other) = delete;\n\n  // Allow moving by adding the appropriate members\n  DBQueryResultRAII(DBQueryResultRAII&& other) noexcept\n    : m_result{ other.m_result }\n  {\n    other.m_result = nullptr; // Make sure other no longer closes the connection\n  }\n  DBQueryResultRAII& operator=(DBQueryResultRAII&& other) noexcept\n  {\n    // You could consider move-and-swap here, but it's so trivial we decided against it here.\n    m_result = other.m_result;\n    other.m_result = nullptr;\n    return *this;\n  }\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_QUERY_RESULT* () const noexcept { return m_result; }\n\nprivate:\n  DB_QUERY_RESULT* m_result;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_04/Soln18_04.cpp",
    "content": "// Exercise 18-4\n/* \n  Below is the same test program as used in Exercise 16-6, \n  with some additional lines to show that the RAII objects can be moved.\n*/\n\n#include <iostream>\n#include <vector>\n\n#include \"DB.h\"\n#include \"DBException.h\"\n#include \"Customer.h\"\n#include \"DB_RAII.h\"\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result);           // Sanity check on the number of fields returned by our query\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result); // Convert the DB result to a series of C++ objects\nvoid print(std::ostream& stream, const Customer& customer);   // Print a given customer to a given output stream\n\nint main()\n{\n  DBConnectionRAII connection{ db_connect() };\n  DBConnectionRAII moved_connection{ std::move(connection) };\n  \n  try\n  {\n    DBQueryResultRAII result{ db_query(moved_connection, \"SELECT * FROM CUSTOMER_TABEL\") };\n    if (!result)\n    {\n      throw DatabaseException{\"Query failed\"};\n    }\n\t\n\tDBQueryResultRAII moved_result;\n\tmoved_result = std::move(result);\n\t\n    std::vector<Customer> customers{ readCustomers(moved_result) };\n  \n  if (customers.empty())\n  {\n    std::cerr << \"No customers found?\" << std::endl;\n    return 2;\n  }\n    \n  for (auto& customer : customers)\n  {\n     print(std::cout, customer);\n  }\n  }\n  catch (std::exception& caught)\n  {\n    std::cerr << caught.what() << std::endl;\n    return 1;\n  }\n}\n\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result)\n{\n  // Sanity check \n  // (if the number of fields does not match 5, \n  // the code below would crash!)\n  verifyCustomerFields(result);\n   \n  std::vector<Customer> customers;\n  \n  auto row{ db_fetch_row(result) };\n  while (row)\n  {\n    customers.push_back(Customer{\n      row[0],            // Surname\n      row[1],            // Name\n      row[2],            // Street\n      std::stoi(row[3]), // Street number\n      row[4]             // City\n    });\n    \n    row = db_fetch_row(result);\n  }\n  \n  return customers;\n}\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result)\n{\n  int numFields{ db_num_fields(result) };\n  if (numFields < 0)\n  {\n    throw DatabaseException{\"db_num_fields() failed\"};\n  }\n  if (numFields != 5)\n  {\n    throw DatabaseException{\"Unexpected number of fields: \" + std::to_string(numFields)};\n  }\n}\n\nvoid print(std::ostream& stream, const Customer& customer)\n{\n  stream << customer.toString() << std::endl;\n  if (std::cout.fail())\n  {\n    std::cout.clear();\n    throw std::runtime_error(\"Failed to output customer\");\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_05/Customer.cpp",
    "content": "// A simple C++ customer class\n\n#include \"Customer.h\"\n\nCustomer::Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city)\n  : m_surname{ surname }\n  , m_name{ name }\n  , m_street{ street }\n  , m_streetNumber{ streetNumber }\n  , m_city{ city }\n{}\n\nstd::string Customer::toString() const\n{\n  std::string result;\n  result += m_surname;\n  result += ' ';\n  result += m_name;\n  result += \", \";\n  result += m_street;\n  result += ' ';\n  result += std::to_string(m_streetNumber);\n  result += \", \";\n  result += m_city;\n  return result;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_05/Customer.h",
    "content": "// A simple C++ customer class\n\n#ifndef CUSTOMER_H\n#define CUSTOMER_H\n\n#include <string>\n#include <string_view>\n\nclass Customer\n{\npublic:\n  Customer(\n      std::string_view surname,\n      std::string_view name,\n      std::string_view street,\n      int streetNumber,\n      std::string_view city\n  );\n\n  std::string toString() const;\n  \nprivate:\n  std::string m_surname;\n  std::string m_name;\n  std::string m_street;\n  int m_streetNumber;\n  std::string m_city;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_05/DB.cpp",
    "content": "// A mocked database\n\n#include \"DB.h\"\n#include <cstring>    // For std::strcmp()\n#include <memory>\n#include <vector>\n\nnamespace\n{\n  struct QueryResult\n  {\n    std::vector<std::vector<const char*>> data;\n    size_t index {};\n  };\n\n  class Database\n  {\n  public:\n    Database() = default;\n    \n\t  bool hasConnection() const { return m_connected; }\n    void connect() { m_connected = true; }\n    void disconnect() { m_connected = false; }\n    \n    QueryResult* query(const char* query);\n    \n  private:  \n    bool m_connected{};\n  };\n}\n\nDB_CONNECTION* db_connect()\n{\n  // We only have one single database, which allows only one single connection:\n  static Database theDatabase;\n  if (theDatabase.hasConnection())\n  {\n    return nullptr;\n  }\n  else\n  {\n    theDatabase.connect();\n    return &theDatabase;\n  }\n}\n\nvoid db_disconnect(DB_CONNECTION* connection)\n{\n  // reinterpret_cast<> is used to cast between pointers/references of \n  // unrelated types (such as void* and Database*)\n  reinterpret_cast<Database*>(connection)->disconnect();\n}\n\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query)\n{\n  return reinterpret_cast<Database*>(connection)->query(query);\n}\n\nQueryResult* Database::query(const char* query)\n{\n  if (!hasConnection())\n  {\n    return nullptr;\n  }\n  \n  // Our database only understands one single query!\n  if (std::strcmp(query, \"SELECT * FROM CUSTOMER_TABEL\") != 0)\n  {\n    return nullptr;\n  }\n  \n  auto result{ std::make_unique<QueryResult>() };\n  result->data = std::vector<std::vector<const char*>>{\n    { \"Sherlock\", \"Holmes\", \"Baker Street\", \"221\", \"London\" },\n    { \"Joe\", \"Biden\", \"Pennsylvania Avenue\", \"1600\", \"Washington DC\" },\n    { \"Donald\", \"Duck\", \"Webfoot Walk\", \"1313\", \"Duckville\" },\n    { \"Sirius\", \"Black\", \"Grimmauld Place\", \"12\", \"London\" },\n    { \"Nemo\", \"Clownfish\", \"Wallaby Way\", \"42\", \"Sydney\" },\n    { \"Sam\", \"Malone\", \"Beacon Street\", \"112\", \"Boston\" }\n  };\n  return result.release();\n}\n\nint db_num_fields(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->data.empty())\n  {\n    return -1;\n  }\n  else\n  {\n    return static_cast<int>(theResult->data.front().size());\n  }\n}\n\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result)\n{\n  auto* theResult{ reinterpret_cast<QueryResult*>(result) };\n  if (!theResult || theResult->index >= theResult->data.size())\n  {\n    return nullptr;\n  }\n  else\n  {\n     return theResult->data[theResult->index++].data();\n  }\n}\n\nvoid db_free_result(DB_QUERY_RESULT* result)\n{\n  delete reinterpret_cast<QueryResult*>(result);\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_05/DB.h",
    "content": "// A C-style interface to a mock database\n// (a simplified subset of the MySQL C interface)\n\n#ifndef DB_INCLUDES\n#define DB_INCLUDES\n\nusing DB_CONNECTION = void;\nusing DB_QUERY_RESULT = void;\nusing DB_ROW = const char**;\n\n/*! Make a connection to the database\n * Do not forget to close the database connection (db_disconnect()) once done with it.\n * \\return a DB_CONNECTION handle; nullptr upon failure\n */\nDB_CONNECTION* db_connect();\n\n/*! Query the database\n * \\param[in] connection A database connection handle returned by db_connect()\n * \\param[in] query      A SQL query\n * \\return A handle to the result of the query (memory to be freed using db_free_result()!)\n */\nDB_QUERY_RESULT* db_query(DB_CONNECTION* connection, const char* query);\n\n/*! Retrieve the number of fields per row stored by the given query result\n * \\param[in] result A handle returned by db_query \n * \\return The number of fields per row stored by the result; -1 upon failure\n */\nint db_num_fields(DB_QUERY_RESULT* result);\n\n/*! Fetch a single row from the result.\n * \\param[in] result A handle returned by db_query\n * \\return An array of strings. Each field is represented as a string (zero-terminated char array). \n * \tLet row be the result, then the first field is accessed using result[0]. \n */\nDB_ROW db_fetch_row(DB_QUERY_RESULT* result);\n\n/*! Release the memory allocated for the result.\n * \\param[in] result A handle returned by db_query()\n */\nvoid db_free_result(DB_QUERY_RESULT* result);\n\n/*! Disconnect from the database\n * \\param[in] connection   A connection handle returned by db_connect()\n */\nvoid db_disconnect(DB_CONNECTION* connection);\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_05/DBException.h",
    "content": "// A simple C++ exception type\n\n#ifndef DB_EXCEPTION_H\n#define DB_EXCEPTION_H\n\n#include <stdexcept>\n\nclass DatabaseException : public std::runtime_error\n{\npublic:\n  using std::runtime_error::runtime_error;  // Inherit constructor\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_05/DB_RAII.h",
    "content": "// RAII classes for handles returned by DB.h C interface functions\n\n/*\n  In this solution we have the RAII classes accept the resource handle in their constructor.\n  Alternatively, you could also acquire the resources inside the constructors of the RAII class.\n  For instance: you could call db_connect() from within the DBConnectionRAII() contructor.\n\n  When creating RAII classes, it is typically crucial they cannot be copied\n  (otherwise multiple objects would be releasing the same resource, \n  which is typically not allowed). To accomplish this, you delete both copy members.\n  Moving RAII objects, on the other hand, is usually possible.\n*/\n\n#ifndef DB_RAII_H\n#define DB_RAII_H\n\n#include \"DB.h\"\n#include <utility>    // For std::exchange<>()\n\n/**\n * RAII object that ensures that a given database connection is closed\n * once the RAII object goes out of scope.\n */ \nclass DBConnectionRAII\n{\npublic:\n  DBConnectionRAII(DB_CONNECTION* connection = nullptr) noexcept\n    : m_connection(connection)\n  {\n  }  \n  ~DBConnectionRAII() // implicitly noexcept\n  {\n    if (m_connection)\n    {\n      db_disconnect(m_connection);\n    }\n  }\n\n  // Prevent copying by deleting both copy members\n  DBConnectionRAII(const DBConnectionRAII& other) = delete;\n  DBConnectionRAII& operator=(const DBConnectionRAII& other) = delete;\n\n  // Allow moving by adding the appropriate members\n  DBConnectionRAII(DBConnectionRAII&& other) noexcept\n    : m_connection{ std::exchange(other.m_connection, nullptr) }\n  {\n  }\n  DBConnectionRAII& operator=(DBConnectionRAII&& other) noexcept\n  {\n    // You could consider move-and-swap here, but it's so trivial (especially now)\n    // that we decided against it here.\n    m_connection = std::exchange(other.m_connection, nullptr);\n    return *this;\n  }\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_CONNECTION*() const noexcept { return m_connection; }\n  \nprivate:\n  DB_CONNECTION* m_connection;\n};\n\n/* RAII object that takes a DB_QUERY_RESULT and ensures it is freed */\nclass DBQueryResultRAII\n{\npublic:\n  DBQueryResultRAII(DB_QUERY_RESULT* result = nullptr) noexcept\n    : m_result{ result }\n  {\n  }\n  \n  ~DBQueryResultRAII() // implicitly noexcept\n  {\n    if (m_result)\n    {\n      db_free_result(m_result);\n    }\n  }\n\n  // Prevent copying by deleting both copy members\n  DBQueryResultRAII(const DBQueryResultRAII& other) = delete;\n  DBQueryResultRAII& operator=(const DBQueryResultRAII& other) = delete;\n\n  // Allow moving by adding the appropriate members\n  DBQueryResultRAII(DBQueryResultRAII&& other) noexcept\n    : m_result{ std::exchange(other.m_result, nullptr) }\n  {\n  }\n  DBQueryResultRAII& operator=(DBQueryResultRAII&& other) noexcept\n  {\n    // You could consider move-and-swap here, but it's so trivial (especially now)\n    // that we decided against it here.\n    m_result = std::exchange(other.m_result, nullptr);\n    return *this;\n  }\n\n  // Implicit type conversion to the underlying resource handle.\n  // Note: many RAII types will use a get() function instead \n  // (unique_ptr / shared_ptr, for instance, do this)\n  operator DB_QUERY_RESULT* () const noexcept { return m_result; }\n\nprivate:\n  DB_QUERY_RESULT* m_result;\n};\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 18/Soln18_05/Soln18_05.cpp",
    "content": "// Exercise 18-5\n// Only difference is the use of std::exchange() in the RAII classes\n\n#include <iostream>\n#include <vector>\n\n#include \"DB.h\"\n#include \"DBException.h\"\n#include \"Customer.h\"\n#include \"DB_RAII.h\"\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result);           // Sanity check on the number of fields returned by our query\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result); // Convert the DB result to a series of C++ objects\nvoid print(std::ostream& stream, const Customer& customer);   // Print a given customer to a given output stream\n\nint main()\n{\n  DBConnectionRAII connection{ db_connect() };\n  DBConnectionRAII moved_connection{ std::move(connection) };\n  \n  try\n  {\n    DBQueryResultRAII result{ db_query(moved_connection, \"SELECT * FROM CUSTOMER_TABEL\") };\n    if (!result)\n    {\n      throw DatabaseException{\"Query failed\"};\n    }\n\t\n\tDBQueryResultRAII moved_result;\n\tmoved_result = std::move(result);\n\t\n    std::vector<Customer> customers{ readCustomers(moved_result) };\n  \n  if (customers.empty())\n  {\n    std::cerr << \"No customers found?\" << std::endl;\n    return 2;\n  }\n    \n  for (auto& customer : customers)\n  {\n     print(std::cout, customer);\n  }\n  }\n  catch (std::exception& caught)\n  {\n    std::cerr << caught.what() << std::endl;\n    return 1;\n  }\n}\n\nstd::vector<Customer> readCustomers(DB_QUERY_RESULT* result)\n{\n  // Sanity check \n  // (if the number of fields does not match 5, \n  // the code below would crash!)\n  verifyCustomerFields(result);\n   \n  std::vector<Customer> customers;\n  \n  auto row{ db_fetch_row(result) };\n  while (row)\n  {\n    customers.push_back(Customer{\n      row[0],            // Surname\n      row[1],            // Name\n      row[2],            // Street\n      std::stoi(row[3]), // Street number\n      row[4]             // City\n    });\n    \n    row = db_fetch_row(result);\n  }\n  \n  return customers;\n}\n\nvoid verifyCustomerFields(DB_QUERY_RESULT* result)\n{\n  int numFields{ db_num_fields(result) };\n  if (numFields < 0)\n  {\n    throw DatabaseException{\"db_num_fields() failed\"};\n  }\n  if (numFields != 5)\n  {\n    throw DatabaseException{\"Unexpected number of fields: \" + std::to_string(numFields)};\n  }\n}\n\nvoid print(std::ostream& stream, const Customer& customer)\n{\n  stream << customer.toString() << std::endl;\n  if (std::cout.fail())\n  {\n    std::cout.clear();\n    throw std::runtime_error(\"Failed to output customer\");\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_01/Soln19_01.cpp",
    "content": "// Exercise 19-1. \n// A lambda expression returning the number of vector elements that begin with a given letter.\n\n#include <iostream>\n#include <format>\n#include <string>\n#include <vector>\n\nint main()\n{\n  std::vector<std::string> words{\"apple\", \"pear\", \"plum\", \"orange\", \"peach\", \"grape\", \"greengage\"};\n  std::cout << \"Words are:\\n\";\n  for (const auto& word : words)\n    std::cout << std::format(\"{:10}\", word);\n  std::cout << std::endl;\n\n  const auto count {\n    [&words](char letter)\n    {\n      size_t n {};\n      for (auto& word : words)\n        if (letter == word[0]) ++n;\n      return n;\n    }\n  };\n  \n  char ch {'p'};\n  std::cout << std::format(\"There are {} words that begin with {}.\\n\", count(ch), ch);\n  ch = 'g';\n  std::cout << std::format(\"There are {} words that begin with {}.\\n\", count(ch), ch);\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_02/Soln19_02.cpp",
    "content": "// Exercise 19-2. \n// Sorting in various ways using higher-order functions, functors, and lambda expressions.\n\n#include <iostream>\n#include <format>\n#include <functional>\n#include <cctype>         // For std::tolower()\n#include <cmath>          // For std::abs()\n#include \"Sort.h\"\n\n// Output vector elements\ntemplate<typename T>\nvoid list(const std::vector<T>& values, size_t width = 5)\n{\n  for (auto value : values)\n    std::cout << std::format(\"{:{}}\", value, width);\n  std::cout << std::endl;\n}\n\nint main()\n{\n  std::vector numbers{ -2, 4, -5, 6, 10, -40, 56, 4, 67, 45 };\n  std::cout << \"\\nIntegers to be sorted:\\n\";\n  list(numbers);\n  sort(numbers, std::greater<>{});\n  std::cout << \"\\nSorted integers:\\n\";\n  list(numbers);\n\n  std::cout << \"\\nCharacters to be sorted:\\n\";\n  std::vector letters{ 'C', 'd', 'a', 'z', 't', 'S', 'p', 'm', 'D', 'f' };\n  list(letters, 2);\n  sort(letters, [](char x, char y) { return std::tolower(x) < std::tolower(y); });\n  std::cout << \"\\nSorted characters:\\n\";\n  list(letters, 2);\n\n  std::cout << \"\\nFloating-point values to be sorted:\\n\";\n  std::vector values{ -2.5, 1.4, -2.55, 6.3, 10.1, -40.5, 56.0, 4.7, 67.3, 45.0 };\n  list(values, 10);\n  sort(values, [](double x, double y) { return std::abs(x) < std::abs(y); });\n  std::cout << \"\\nSorted floaating-point values:\\n\";\n  list(values, 10);\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_02/Sort.h",
    "content": "// Sort.h\n\n#ifndef SORT_H\n#define SORT_H\n\n#include <cstddef>    // for size_t\n#include <utility>    // for std::swap()\n#include <vector>\n\n// The primary sort() template with two parameters calls \n// this internal sort() template with four parameters\ntemplate<typename T, typename Compare>\nvoid sort(std::vector<T>& data, Compare compare, size_t start, size_t end);\n\n// Sort all vector elements\ntemplate<typename T, typename Compare>\nvoid sort(std::vector<T>& data, Compare compare)\n{\n  if (!data.empty())\n    sort(data, compare, 0, data.size() - 1);\n}\n\n// Swap two vector elements\ntemplate<typename T>\nvoid swap(std::vector<T>& data, size_t first, size_t second)\n{\n  std::swap(data[first], data[second]);\n}\n\n// Sort a range of vector elements\ntemplate<typename T, typename Compare>\nvoid sort(std::vector<T>& data, Compare compare, size_t start, size_t end)\n{\n  // Start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle value to partition set\n  swap(data, start, (start + end) / 2);       // Swap middle value with start\n \n  // Check data against chosen value\n  size_t current{ start };                    // The index of the last element less than the chosen element (after partitioning)\n  for (size_t i{ start + 1 }; i <= end; ++i)\n  {\n    if (compare(data[i], data[start]))        // Is value less than chosen word?\n      swap(data, ++current, i);               // Yes, so swap to the left\n  }\n\n  swap(data, start, current);                 // Swap the chosen value with last in\n\n  if (current > start) sort(data, compare, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) sort(data, compare, current + 1, end); // Sort right subset if exists\n}\n\n\n#endif // SORT_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_03/Soln19_03.cpp",
    "content": "// Exercise 19-3. Comparing sorting algorithms\n\n#include <iostream>\n#include <format>\n#include <cmath>         // For std::log2()\n#include <random>        // For random number generation\n#include <functional>    // For std::bind() and \n#include <algorithm>     // For std::ranges::sort() (bonus algorithm)\n#include \"Sort.h\"\n\n/*\n  If you look carefully, you will notice that our implementation of quicksort\n  deviates from the theoretical expectations. The larger the input size,\n  the more it deviates (as shown by the ratios in our output).\n  Better implementations of quicksort are no doubt possible:\n  on random data an optimal quicksort algorithm should perform, on average,\n  at a ratio 1.39 of the log-linear best case performance.\n  But better algorithms exist as well. As a reference, we also compared with\n  the Standard Library's sort() algorithm you'll learn about in Chapter 20.\n  This algorithm should perform very close to the theoretical optimum.\n*/\n\n// Function to generate a random integer 1 to 100 (both inclusive)\n// Caution: unlike uniform_real_distribution, uniform_int_distribution \n// generates numbers in a closed interval [min, max].\nauto createUniformPseudoRandomNumberGenerator()\n{\n  std::random_device seeder;       // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };   // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ 1u, 100u }; // Generate in [0, 100] interval\n  return std::bind(distribution, generator);          //... and in the darkness bind them!\n}\n\nauto generateRandomNumbers(unsigned number)\n{\n  static auto random{ createUniformPseudoRandomNumberGenerator() };\n  std::vector<unsigned> random_numbers;\n  for (unsigned i{}; i < number; ++i)\n    random_numbers.push_back(random());\n  return random_numbers;\n}\n\nint main()\n{  \n  unsigned count {};\n  const auto counting_less{ [&count](int x, int y) { ++count; return x < y; } };\n  \n  for (auto size : { 500u, 1'000u, 2'000u, 4'000u })\n  {\n    const auto numbers{ generateRandomNumbers(size) };\n    \n    count = 0;                 // Reset the count\n    auto copy{ numbers };      // Ensure both sorrting algorithms work on exact same random sequence\n    quicksort(copy, counting_less);\n    const auto quicksort_count{ count };\n    \n    count = 0;                 // Repeat for bubble sort algorithm\n    copy = numbers;\n    bubbleSort(copy, counting_less);\n    const auto bubble_sort_count{ count };\n    \n    // Not requested, but it is interesting (see earlier) \n    // to also compare with the sorting algorithm of the C++ Standard Library \n    count = 0;                 // Repeat once more for std::ranges::sort()  (see Chapter 20)\n    copy = numbers;\n    std::ranges::sort(copy, counting_less);\n    const auto std_sort_count{ count };\n\n    const auto quick_sort_theory = static_cast<unsigned>(size * std::log2(size));\n    const auto bubble_sort_theory = size * size;\n    const auto std_sort_theory = static_cast<unsigned>(size * std::log2(size));\n\n    std::cout \n      << std::format(\n          \"Number of comparisons for {} elements:\\n\"\n          \" - quicksort: {} (n*log(n): {}; ratio: {:.2})\\n\"\n          \" - bubble sort: {} (n*n: {}; ratio: {:.2})\\n\"\n          \" - Standard Library sort: {} (n*log(n): {}; ratio: {:.2})\\n\",\n          size,\n          quicksort_count, quick_sort_theory, static_cast<float>(quick_sort_theory) / quicksort_count,\n          bubble_sort_count, bubble_sort_theory, static_cast<float>(bubble_sort_theory) / bubble_sort_count,\n          std_sort_count, std_sort_theory, static_cast<float>(std_sort_theory) / std_sort_count\n        ) \n     << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_03/Sort.h",
    "content": "// Sort.h\n\n#ifndef SORT_H\n#define SORT_H\n\n#include <cstddef>    // for size_t\n#include <utility>    // for std::swap()\n#include <vector>\n\n// The two algorithms that we are comparing:\ntemplate<typename T, typename Compare>\nvoid quicksort(std::vector<T>& values, Compare compare);\ntemplate<typename T, typename Compare>\nvoid bubbleSort(std::vector<T>& data, Compare compare);\n\n// Utility to swap two vector elements\ntemplate<typename T>\nvoid swap(std::vector<T>& data, size_t first, size_t second)\n{\n  std::swap(data[first], data[second]);\n}\n\n// The primary quicksort() template with two parameter calls the quicksort() template with four parameters\n\n// Sort a range of vector elements\ntemplate<typename T, typename Compare>\nvoid quicksort(std::vector<T>& data, Compare compare, size_t start, size_t end)\n{\n  // Start index must be less than end index for 2 or more elements\n  if (!(start < end))\n    return;\n\n  // Choose middle value to partition set\n  swap(data, start, (start + end) / 2);       // Swap middle value with start\n \n  // Check data against chosen value\n  size_t current{ start };                    // The index of the last element less than the chosen element (after partitioning)\n  for (size_t i{ start + 1 }; i <= end; ++i)\n  {\n    if (compare(data[i], data[start]))        // Is value less than chosen word?\n      swap(data, ++current, i);               // Yes, so swap to the left\n  }\n\n  swap(data, start, current);                 // Swap the chosen value with last in\n\n  if (current > start) quicksort(data, compare, start, current - 1); // Sort left subset if exists\n  if (end > current + 1) quicksort(data, compare, current + 1, end); // Sort right subset if exists\n}\n\n// Sort all vector elements using quicksort\ntemplate<typename T, typename Compare>\nvoid quicksort(std::vector<T>& data, Compare compare)\n{\n  if (!data.empty())\n    quicksort(data, compare, 0, data.size() - 1);\n}\n\ntemplate<typename T, typename Compare>\nvoid bubbleSort(std::vector<T>& data, Compare compare)\n{\n  if (data.empty())\n    return;\n\n  while (true)\n  {\n    bool swapped{ false };    // Becomes true when not all values are in order\n    for (size_t i {}; i < data.size() - 1; ++i)\n    {\n      if (compare(data[i+1], data[i]))  // Out of order so swap them\n      {\n        swap(data, i, i+1);\n        swapped = true;\n      }\n    }\n\t\n    if (!swapped)   // If there were no swaps\n      break;        // ...they are in order...\n  }                 // ...otherwise, go round again.\n}\t\n\n#endif // SORT_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_04/Collect.h",
    "content": "#ifndef COLLECT_H\n#define COLLECT_H\n\n#include <vector>\n\ntemplate <typename T, typename Predicate>\nstd::vector<T> collect(const std::vector<T>& values, Predicate predicate)\n{\n  std::vector<T> result;\n  \n  for (auto& value : values)\n    if (predicate(value))\n      result.push_back(value);\n  \n  return result;\n}\n\n#endif // COLLECT_H"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_04/Soln19_04.cpp",
    "content": "// Exercise 19-4. \n// Collecting values using higher-order functions, functors, and lambda expressions.\n\n/*\n\tThere are several ways to check for palindromes. \n\tOne of the more elegant solutions probably though is the recursive one shown here.\n\tWhile recursive lambdas are possible, more or less, recursion is far easier with a regular function.\n\n\tNote that to collect upper case letters, there's no need for a lambda either.\n\tJust use a pointer to the std::isupper() function as the callback!\n*/\n\n#include <iostream>\n#include <format>\n#include <functional>\n#include <cctype>         // For std::isupper()\n#include <string>\n#include \"Collect.h\"\n\n// Output vector elements\ntemplate<typename T>\nvoid list(const std::vector<T>& values, size_t width = 5)\n{\n  for (auto value : values)\n    std::cout << std::format(\"{:{}}\", value, width);\n  std::cout << std::endl;\n}\n\nbool is_palindrome(std::string_view s)\n{\n  return s.length() == 0\n    || (s.front() == s.back() && is_palindrome(s.substr(1, s.length() - 2)));\n}\n\nint main()\n{\n  const std::vector numbers{ -2, 4, -5, 6, 10, -40, 56, 4, 67, 45 };\n  std::cout << \"\\nAll numbers:\\n\";\n  list(numbers);\n  \n  int threshold {};\n  std::cout << \"\\nPlease enter a threshold: \";\n  std::cin >> threshold;\n  \n  const auto greater{ collect(numbers, [threshold](int i) { return i > threshold; }) };\n  std::cout << \"Numbers greater than \" << threshold << \":\\n\";\n  list(greater);\n\n  const std::vector letters{ 'C', 'd', 'a', 'z', 't', 'S', 'p', 'm', 'D', 'f' };\n  std::cout << \"\\nAll characters:\\n\";\n  list(letters, 2);\n  //const auto capitals{ collect(letters, std::isupper) };\t// <-- This should but does not work with all compilers\n  const auto capitals{ collect(letters, isupper) };\n  std::cout << \"\\nCapital letters:\\n\";\n  list(capitals, 2);\n\n  const std::vector<std::string> strings{ \"palindrome\", \"racecar\", \"rubarb\", \"noon\", \"kayak\", \"ananas\", \"madam\", \"backwards\" };\n  std::cout << \"\\nAll strings:\\n\";\n  list(strings, 12);\n  const auto palindromes{ collect(strings, is_palindrome) };\n  std::cout << \"\\nPalindromes:\\n\";\n  list(palindromes, 10);\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_05/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <ostream>\n#include <format>\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_05/DeliveryTruck.cpp",
    "content": "#include \"DeliveryTruck.h\"\n\nDeliveryTruck::DeliveryTruck(Truckload aTruckload)\n  : m_truckload{ std::move(aTruckload) }   // Do not copy!\n{}\n\nvoid DeliveryTruck::deliverBox(SharedBox box)\n{\n  m_truckload.removeBox(box);\n  \n  // Notify all interested parties (aka \"observers\") that the Box was delivered\n  for (auto& callback : m_callbacks)\n    callback(box);\n}\n\nvoid DeliveryTruck::registerOnDelivered(Callback callback)\n{\n  m_callbacks.push_back(std::move(callback));   // Do not copy!\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_05/DeliveryTruck.h",
    "content": "#ifndef DELIVERY_TRUCK_H\n#define DELIVERY_TRUCK_H\n\n#include \"Truckload.h\"\n\n#include <functional>      // For std::function<>\n#include <vector>          // For std::vector<>\n\nclass DeliveryTruck\n{\npublic:\n  using Callback = std::function<void(SharedBox)>;  // Type alias for the type of the delivery callback functions\n\t\n  DeliveryTruck(Truckload truckload);   // Create a delivery truck (pass-by-value to allow a Truckload to be either copied or moved!)\n  \n  void deliverBox(SharedBox box);\n  \n  void registerOnDelivered(Callback callback);\n  \nprivate:\n  Truckload m_truckload;\n  \n  std::vector<Callback> m_callbacks;\n};\n\n#endif\n\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_05/RandomBoxes.h",
    "content": "#ifndef RANDOM_BOXES_H\n#define RANDOM_BOXES_H\n\n#include \"Box.h\"\n#include <random>        // For random number generation\n#include <functional>    // For std::bind()\n#include <memory>        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\ninline auto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\ninline Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\ninline auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_05/Soln19_05.cpp",
    "content": "// Exercise 19-5. \n// Using callback functions to implement the so-called observer pattern,\n// where a callback function is called whenever a certain event occurs \n// (in this case: when a Box is delivered).\n\n#include <iostream>\n#include \"DeliveryTruck.h\"\n#include \"RandomBoxes.h\"\n\nvoid logDelivary(SharedBox box)\n{\n  std::cout << \"The box \" << *box << \" was delivered. On time, as always!\" << std::endl;\n}\n\nint main()\n{\n  const size_t boxCount {20};               // Number of Box object to be created\n\n  // Create boxCount Box objects\n  Truckload load;\n  for (size_t i {}; i < boxCount; ++i)\n    load.addBox(randomSharedBox());\n\n  DeliveryTruck truck{ load };  // Copy the load, because we still need it below. \n                                // Note that all Boxes are shared, so the they themselves are not copied.\n  \n  // Register two callback functions:\n  truck.registerOnDelivered(logDelivary);\n  \n  unsigned count {};\n  truck.registerOnDelivered([&count](SharedBox) { ++count; });\n  \n  // Deliver some boxes:\n  for (size_t i : { 5u, 8u, 11u })\n    truck.deliverBox(load[i]);\n\n  std::cout << count << \" boxes were delivered. On time, as always!\" << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_05/Truckload.cpp",
    "content": "#include \"Truckload.h\"\n\n#include <iostream>\n#include <stdexcept>    // For standard exception type std::out_of_range \n#include <string>       // For std::string and std::to_string()\n\n// Definition of the nested class member\n// Since this member is private, \n// its definition can be moved to the source file.\nclass Truckload::Package\n{\npublic:\n  SharedBox m_box;      // Pointer to the Box object contained in this Package\n  Package* m_next;      // Pointer to the next Package in the list\n\n  Package(SharedBox box) : m_box{ box }, m_next{ nullptr } {} // Constructor\n  ~Package() { delete m_next; }                           // Destructor\n};\n\n// Constructor - one Box (moved to source file to gain access to definition of Package)\nTruckload::Truckload(SharedBox box)          \n{\n  m_head = m_tail = new Package{ box };\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(const std::vector<SharedBox>& boxes)\n{\n  for (const auto& box : boxes)\n  {\n    addBox(box);\n  }\n}\n\n// Copy constructor\nTruckload::Truckload(const Truckload& src)\n{\n  for (Package* package{ src.m_head }; package; package = package->m_next)\n  {\n    addBox(package->m_box);\n  }\n}\n\nTruckload& Truckload::operator=(const Truckload& other)\n{\n  if (&other != this)   // Do not forget: avoid issues with self-assignment!\n  {\n    delete m_head;              // Delete all current packages\n    m_head = m_tail = nullptr;  // Reset both pointers\n\n    // Same as copy constructor \n    // (see Chapter 17 for the copy-and-swap idiom that allows you to avoid \n    // duplicating logic like this...)\n    for (Package* package{ other.m_head }; package; package = package->m_next)\n    {\n      addBox(package->m_box);\n    }\n  }\n\n  return *this;\n}\n\n// Destructor: clean up the list\nTruckload::~Truckload()\n{\n  delete m_head;\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_head }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_head;\n  return m_current? m_current->m_box : nullptr;\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (!m_current)                                 // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  m_current = m_current->m_next;                  // Move to the next package\n\n  return m_current? m_current->m_box : nullptr;   // Return its box (or nullptr...).\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  auto package{ new Package{box} }; // Create a new Package\n\n  if (m_tail)                      // Check list is not empty\n    m_tail->m_next = package;      // Append the new object to the tail\n  else                             // List is empty\n    m_head = package;              // so new object is the head\n\n  m_tail = package;                // Either way: the latest object is the (new) tail\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  Package* previous {nullptr};       // no previous yet\n  Package* current {m_head};         // initialize current to the head of the list\n  while (current)\n  {\n    if (current->m_box == boxToRemove)      // We found the Box!\n    {\n      // If there is a previous Package make it point to the next one (Figure 12.10)\n      if (previous) previous->m_next = current->m_next;\n\n      // Update pointers in member variables where required:\n      if (current == m_head) m_head = current->m_next;\n      if (current == m_tail) m_tail = previous;\n                                     \n      current->m_next = nullptr;     // Disconnect the current Package from the list\n      delete current;                // and delete it\n                                     \n      return true;                   // Return true: we found and removed the box\n    }                                \n                                     // Move both pointers along (mind the order!)\n    previous = current;              //  - first current becomes the new previous\n    current = current->m_next;       //  - then move current along to the next Package\n  }\n\n  return false;     // Return false: boxToRemove was not found\n}\n\nSharedBox& Truckload::operator[](size_t index) const\n{\n  size_t count{};             // Package count\n  for (Package* package{ m_head }; package; package = package->m_next)\n  {\n    if (count++ == index)      // Up to index yet?\n      return package->m_box;   // If so return the pointer to Box\n  }\n  throw std::out_of_range{ \"Index too large: \" + std::to_string(index) };\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 19/Soln19_05/Truckload.h",
    "content": "#ifndef TRUCKLOAD_H\n#define TRUCKLOAD_H\n\n#include \"Box.h\"\n\n#include <memory>\n#include <vector>\n#include <ostream>\n\nusing SharedBox = std::shared_ptr<Box>;\n\nclass Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(const std::vector<SharedBox>& boxes);  // Constructor - vector of Boxes\n  \n  Truckload(const Truckload& src);  // Copy constructor\n  Truckload& operator=(const Truckload& other);  // Copy assignment operator\n\n  ~Truckload();                     // Destructor\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox& operator[](size_t index) const;   // Overloaded subscript operator\n\nprivate:\n  class Package;\n\n  Package* m_head {};               // First in the list\n  Package* m_tail {};               // Last in the list\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  Package* m_head;          // The head of the linked list (needed for getFirstBox())\n  Package* m_current;       // The package whose Box was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(Package* head) : m_head{ head }, m_current{ nullptr } {}\n};\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load);\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_01/Box.h",
    "content": "#ifndef BOX_H\n#define BOX_H\n\n#include <ostream>\n#include <format>\n\nclass Box\n{\npublic:\n  Box() = default;\n  Box(double length, double width, double height) \n    : m_length{length}, m_width{width}, m_height{height} {};\n\n  double volume() const \n  {\n    return m_length * m_width * m_height;\n  }\n\n  friend std::ostream& operator<<(std::ostream& out, const Box& box)\n  {\n    return out << std::format(\"Box({:.1f}, {:.1f}, {:.1f})\", box.m_length, box.m_width, box.m_height);\n  }\n\nprivate:\n  double m_length {1.0};\n  double m_width {1.0};\n  double m_height {1.0};\n};\n\n\n\n#endif\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_01/RandomBoxes.h",
    "content": "#ifndef RANDOM_BOXES_H\n#define RANDOM_BOXES_H\n\n#include \"Box.h\"\n#include <random>        // For random number generation\n#include <functional>    // For std::bind()\n#include <memory>        // For std::make_shared<>() and std::shared_ptr<>\n\n// Creates a pseudorandom number generator (PRNG) for random doubles between 0 and max\ninline auto createUniformPseudoRandomNumberGenerator(double max)\n{\n  std::random_device seeder;      // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() };    // Efficient pseudo-random generator\n  std::uniform_real_distribution distribution{ 0.0, max }; // Generate in [0, max) interval\n  return std::bind(distribution, generator);         //... and in the darkness bind them!\n}\n\ninline Box randomBox()\n{\n  const int dimLimit{ 100 };          // Upper limit on Box dimensions\n  static auto random{ createUniformPseudoRandomNumberGenerator(dimLimit) };\n  return Box{ random(), random(), random() };\n}\n\ninline auto randomSharedBox()\n{\n  return std::make_shared<Box>(randomBox());   // Uses copy constructor\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_01/Soln20_01.cpp",
    "content": "// Exercise 20-1 Rework the Truckload class using std::vector<>\n#include <iostream>\n#include <memory>\n#include \"Truckload.h\"\n#include \"RandomBoxes.h\"\n\n/*\n  In this solution we preserved the interface of the nested Iterator class.\n  An alternative, of course, would be to define Iterator as an alias \n  for std::vector<Box>::iterator, and introduce begin() and end() members.\n  But then all code using the iterators would have to be updated as well.\n*/\n\nint main()\n{\n  const double dimLimit{ 99.0 };             // Upper limit on Box dimensions\n  Truckload load;\n  const size_t boxCount{ 20 };               // Number of Box object to be created\n\n  // Create boxCount Box objects\n  for (size_t i{}; i < boxCount; ++i)\n    load.addBox(randomSharedBox());\n\n  std::cout << \"The boxes in the Truckload are:\\n\";\n  std::cout << load << std::endl;\n\n  Truckload moveConstructedLoad{ std::move(load) };\n\n  std::cout << \"The boxes in the move constructed Truckload are:\\n\";\n  std::cout << moveConstructedLoad << std::endl;\n\n  Truckload moveAssignedLoad;\n  moveAssignedLoad = std::move(moveConstructedLoad);\n\n  std::cout << \"The boxes in the move assigned Truckload are:\\n\";\n  std::cout << moveAssignedLoad << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_01/Truckload.cpp",
    "content": "#include \"Truckload.h\"\n\n#include <iostream>\n#include <algorithm>\n\n// Constructor - one Box\nTruckload::Truckload(SharedBox box)\n  : m_boxes{ 1, box }\n{\n}\n\n// Constructor - vector of Boxes\nTruckload::Truckload(std::vector<SharedBox> boxes)\n  : m_boxes{ std::move(boxes) }\n{\n}\n\n// Swap assignment operator (noexcept)\nvoid Truckload::swap(Truckload& other) noexcept\n{\n  m_boxes.swap(other.m_boxes);\n}\n\n// Optional yet conventional non-member function (forwards to member function)\nvoid swap(Truckload& one, Truckload& other) noexcept\n{\n  one.swap(other);\n}\n\nTruckload::Iterator Truckload::getIterator() const { return Iterator{ m_boxes }; }\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getFirstBox()\n{\n  // Return m_head's box (or nullptr if the list is empty)\n  m_current = m_boxes->begin();\n  return m_current != m_boxes->end() ? *m_current : SharedBox{};\n}\n\n// Only thing we changed was adding \"Iterator::\" to the member's qualification\nSharedBox Truckload::Iterator::getNextBox()\n{\n  if (m_current == m_boxes->end())                // If there's no current...\n    return getFirstBox();                         // ...return the 1st Box\n\n  ++m_current;                                    // Move to the next package\n\n  return m_current != m_boxes->end() ? *m_current : SharedBox{};\n}\n\nvoid Truckload::addBox(SharedBox box)\n{\n  m_boxes.push_back(std::move(box));\n}\n\nbool Truckload::removeBox(SharedBox boxToRemove)\n{\n  // Unlike the original implementation, \n  // std::erase() removes all occurrences of boxToRemove.\n  // If that is not acceptable, you can use find() as shown below...\n  return std::erase(m_boxes, boxToRemove) > 0;\n\n// Remove only the first occurrence of boxToRemove\n/*\n  if (auto found{ std::ranges::find(m_boxes, boxToRemove) }; found != end(m_boxes))\n  {\n    m_boxes.erase(found);\n    return true;\n  }\n  else\n  {\n    return false;\n  }\n*/\n}\n\nSharedBox& Truckload::operator[](size_t index)\n{\n  // Original implementation performed bounds checking, so use at() instead of []\n  return m_boxes.at(index);\n}\n\nSharedBox Truckload::operator[](size_t index) const\n{\n  // Original implementation performed bounds checking, so use at() instead of []\n  return m_boxes.at(index);\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load)\n{\n  size_t count{};\n  auto iterator{ load.getIterator() };\n  for (auto box{ iterator.getFirstBox() }; box; box = iterator.getNextBox())\n  {\n    std::cout << *box << ' ';\n    if (!(++count % 4)) std::cout << std::endl;\n  }\n  if (count % 4) std::cout << std::endl;\n  return stream;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_01/Truckload.h",
    "content": "#ifndef TRUCKLOAD_H\n#define TRUCKLOAD_H\n\n#include \"Box.h\"\n\n#include <memory>\n#include <vector>\n#include <ostream>\n\nusing SharedBox = std::shared_ptr<Box>;\n\nclass Truckload\n{\npublic:\n  Truckload() = default;            // Default constructor - empty truckload\n  Truckload(SharedBox box);         // Constructor - one Box\n  Truckload(std::vector<SharedBox> boxes);  // Constructor - vector of Boxes (accept by value!)\n\n  void swap(Truckload& other) noexcept;\n\n  class Iterator;      // Declaration of a public nested class, Truckload::Iterator\n\n  Iterator getIterator() const;\n\n  void addBox(SharedBox box);       // Add a new SharedBox\n  bool removeBox(SharedBox box);    // Remove a Box from the Truckload\n\n  SharedBox& operator[](size_t index);      // Overloaded subscript operator (can no longer be const!)\n  SharedBox operator[](size_t index) const; // Overloaded subscript operator (new const version returns by value)\n\nprivate:\n  std::vector<SharedBox> m_boxes;\n};\n\n// Out-of-class definition of the nested Iterator class \n// (class itself is part of the public interface, so belongs in the header)\n// Note that this is effectively a const iterator...\nclass Truckload::Iterator\n{\npublic:\n  SharedBox getFirstBox();  // Get the first Box\n  SharedBox getNextBox();   // Get the next Box\n\nprivate:\n  const std::vector<SharedBox>* m_boxes;            // Pointer to the underlying vector\n  std::vector<SharedBox>::const_iterator m_current; // Iterator pointing to the Box that was last retrieved\n\n  friend class Truckload;   // Only a Truckload can create an Iterator\n  explicit Iterator(const std::vector<SharedBox>& boxes) \n    : m_boxes{ &boxes }, m_current{ boxes.end() } {}\n};\n\nstd::ostream& operator<<(std::ostream& stream, const Truckload& load);\n\n// Optional yet conventional non-member function (forwards to member function)\nvoid swap(Truckload& one, Truckload& other) noexcept;\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_02/Soln20_02.cpp",
    "content": "// Exercise 20-2\n// Replace a custom stack container by the standard stack container adapter\n#include <stack>\n#include <iostream>\n#include <string>\n\n/*\n  Two challenges:\n  - std::stack<>::pop() is a void function. \n    To access the top of the stack, you use std::stack<>::top().\n  - std::stack<const T> is not allowed\n*/\n\nint main()\n{\n  std::string words[]{ \"The\", \"quick\", \"brown\", \"fox\", \"jumps\" };\n  std::stack<std::string> wordStack;              // A stack of strings\n\n  for (const auto& word : words)\n    wordStack.push(word);\n\n  std::stack<std::string> newStack{ wordStack };  // Create a copy of the stack\n\n  // Display the words in reverse order\n  while (!newStack.empty())\n  {\n    std::cout << newStack.top() << ' ';\n    newStack.pop();\n  }\n    \n  std::cout << std::endl;\n\n  // Reverse wordStack onto newStack\n  while (!wordStack.empty())\n  {\n    newStack.push(wordStack.top());\n    wordStack.pop();\n  }\n\n  // Display the words in original order\n  while (!newStack.empty())\n  {\n    std::cout << newStack.top() << ' ';\n    newStack.pop();\n  }\n    \n  std::cout << std::endl;\n\n  std::cout << std::endl << \"Enter a line of text:\" << std::endl;\n  std::string text;\n  std::getline(std::cin, text);    // Read a line into the string object\n\n  std::stack<char> characters;     // A stack for characters\n\n  for (size_t i{}; i < text.length(); ++i)\n    characters.push(text[i]);      // Push the string characters onto the stack\n\n  std::cout << std::endl;\n  while (!characters.empty())\n  {\n    std::cout << characters.top(); // Pop the characters off the stack\n    characters.pop();\n  }\n\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_03/Soln20_03.cpp",
    "content": "// Exercise 20-3 Replacing custom container types with standard ones\n/*\n\tThe following replacements were made compared to Soln17_06.cpp:\n\t\t- LinkedList<T> --> std::vector<T> (not std::list<>, because vector<> should\n\t\t\tbe your go-to container; there's rarely a good reason to use linked lists)\n\t\t- SparseArray<T> --> std::map<char, T> (no need to use a size_t as the key!)\n\t\n  Notice how much more elegant inserting and retrieving values from the map is.\n  All loops at the end of the solution can now also be replaced with elegant range-based for loops.\n\n  At the bottom, there's two alternative loops: one close to the original one,\n  and one even more elegant one that takes advantage of the fact that the keys \n  in the map are already sorted.\n\n\tSoln20_03A contains alternative solutions based on std::multimap<>\n*/\n#include <vector>\n#include <map>\n#include <string>\n#include <iostream>\n#include <cctype>\n#include <utility>\n\nint main()\n{\n  std::string text;                                // Stores input prose or poem\n  std::cout << \"Enter a poem or prose over one or more lines.\\n\"\n            << \"Terminate the input with #:\\n\";\n  getline(std::cin, text, '#');\n\n  std::map<char, std::vector<std::string>> lists;\n  \n  // Extract words and store in the appropriate list\n  const std::string_view separators {\" \\n\\t,.\\\"?!;:\"}; // Separators between words\n  size_t start {};                                 // Start of a word\n  size_t end {};                                   // separator position after a word\n  while (std::string::npos != (start = text.find_first_not_of(separators, start)))\n  {\n    end = text.find_first_of(separators, start+1);\n    const auto word{ text.substr(start, end - start) };\n    const auto letter{ static_cast<char>(std::toupper(word[0])) };\n    lists[letter].push_back(word);\n    start = end;\n  }\n\n  // List the words in order 5 to a line\n  const size_t perline {5};\n  \n  /* Option 1: use a loop similar to the original one */\n  const std::string_view letters{ \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" };\n  for (char letter : letters)\n  {\n    if (!lists.contains(letter))\n      continue;\n  \n    size_t count {};                               // Word counter\n    for (const auto& word : lists[letter])\n    {\n      if (count++ % perline == 0 && count != 1)\n        std::cout << std::endl;\n      std::cout << word << ' ';\n    }\n    std::cout << std::endl;\n  }\n\n  std::cout << std::endl;\n\n  /* Option 2: take advantage of the fact that the keys are already sorted in the map */\n  for (const auto& [letter, list] : lists)\n  {\n    size_t count{};                               // Word counter\n    for (const auto& word : list)\n    {\n      if (count++ % perline == 0 && count != 1)\n        std::cout << std::endl;\n      std::cout << word << ' ';\n    }\n    std::cout << std::endl;\n  }\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_03A/Soln20_03A.cpp",
    "content": "// Exercise 20-3 Replacing custom container types with standard ones\n/*\n\tThe following replacements were made compared to Soln17_06.cpp:\n\t\t- SparseArray<LinkedList<T>> --> std::multimap<size_t, T>\n\t\n\tThis means that compared to Soln20_03, we replaced std::map<Key, std::vector<Value>>\n\twith the more compact (and efficient) std::multimap<Key, Value>. \n  This data structure was less discussed in the main text (as it is less used in practice), \n  but is actually more appropriate here.\n\n  At the bottom, there's two alternative loops: one close to the original one,\n  and one that takes advantage of the fact that the keys in the multimap are sorted.\n*/\n#include <vector>\n#include <map>\n#include <string>\n#include <iostream>\n#include <cctype>\n#include <utility>\n\nint main()\n{\n  std::string text;                                // Stores input prose or poem\n  std::cout << \"Enter a poem or prose over one or more lines.\\n\"\n    << \"Terminate the input with #:\\n\";\n  getline(std::cin, text, '#');\n\n  std::multimap<char, std::string> words;\n  const std::string_view letters{ \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" };\n\n  // Extract words and store in the appropriate list\n  // A list in the SparseArray is selected by the index in letters of the first letter in a word.\n  const std::string_view separators{ \" \\n\\t,.\\\"?!;:\" }; // Separators between words\n  size_t start{};                                 // Start of a word\n  size_t end{};                                   // separator position after a word\n  while (std::string::npos != (start = text.find_first_not_of(separators, start)))\n  {\n    end = text.find_first_of(separators, start + 1);\n    const auto word{ text.substr(start, end - start) };\n    const auto letter{ static_cast<char>(std::toupper(word[0])) };\n    words.insert({ letter, word });\n    start = end;\n  }\n\n  // List the words in order 5 to a line\n  const size_t perline{ 5 };\n\n  /* Option 1: use a loop similar to the original one */\n  for (char letter : letters)\n  {\n    if (!words.contains(letter))\n      continue;\n\n    size_t count{};                               // Word counter\n    // Retrieve the range of all words that begin with letter\n    const auto [begin, end] { words.equal_range(letter) };\n    for (auto iter{ begin }; iter != end; ++iter)\n    {\n      if (count++ % perline == 0 && count != 1)\n        std::cout << std::endl;\n      std::cout << iter->second << ' ';\n      \n    }\n    std::cout << std::endl;\n  }\n\n  std::cout << std::endl;\n\n  /* Option 2: take advantage of the fact that the keys are already sorted in the multimap */\n  size_t count{};          // Word counter\n  char previous_letter{};\n  for (const auto& [letter, word] : words)\n  {\n    // Add extra enter after each new letter (but not the first time)\n    if (count && letter != previous_letter)\n    {\n      std::cout << std::endl;\n      count = 0;\n    }\n\n    if (count++ % perline == 0 && count != 1)\n      std::cout << std::endl;\n    std::cout << word << ' ';\n\n    previous_letter = letter;\n  }\n\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_04/Soln20_04.cpp",
    "content": "// Removing all elements that satisfy a certain condition using std::partition() / stable_partition().\n\n/*\n  Notes:\n   - Normally one would use std::remove() (as this is slightly faster and more to the point),\n     though std::partition() can be used for this as well.\n   - You may notice that std::partition() reorders the elements that it keeps.\n     It is implementation-defined whether this partition() preserves the original order or not.\n     If you want to make sure the original order of the numbers is preserved,\n     you need to use std::stable_partition()\n*/\n#include <vector>\n#include <string_view>\n#include <iostream>\n#include <algorithm>\n\nstd::vector<int> fillVector_1toN(size_t N);  // Fill a vector with 1, 2, ..., N\nvoid printVector(std::string_view message, const std::vector<int>& numbers);\n\nvoid removeEvenNumbers(std::vector<int>& numbers)\n{\n  const auto first_even_number\n    { std::stable_partition(begin(numbers), end(numbers), [](auto num) { return num % 2 == 1; }) };\n  /*       ^^^^^^^^^^^^^^^^ if you use partition(), the order of the odd elements may become scrambled */ \n  \n  numbers.erase(first_even_number, end(numbers));\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ fillVector_1toN(num_numbers) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  removeEvenNumbers(numbers);\n\n  printVector(\"The numbers that were kept\", numbers);\n}\n\nstd::vector<int> fillVector_1toN(size_t N)\n{\n  std::vector<int> numbers;\n  for (int i{ 1 }; i <= N; ++i)\n    numbers.push_back(i);\n  return numbers;\n}\n\nvoid printVector(std::string_view message, const std::vector<int>& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_05/Soln20_05.cpp",
    "content": "// Exercise 20-5 Create a generic average() algorithm using std::accumulate()\n#include <iostream>\n#include <numeric>\n#include <utility>     // for std::pair<> (only required for Solution 2 below)\n#include <optional>\n#include <vector>\n\n// Solution 1: simply use accumulate to sum, and determine the count using std::distance() \n// (the latter is more general than using iterator arithmetic, end - begin, \n// which only works for random-access iterators)\ntemplate <typename T, typename IterType>\nstd::optional<T> average(IterType begin, IterType end)\n{\n\tconst auto count{ std::distance(begin, end) };\n\tconst auto sum{ std::accumulate(begin, end, T{}) };\n\n\treturn count ? std::optional<T>{ sum / count } : std::nullopt;\n}\n\n// Solution 2: accumulate a pair<> that counts both the number of elements and the sum\n//template <typename T, typename IterType>\n//std::optional<T> average(IterType begin, IterType end)\n//{\n//  const auto accumulated { \n//    std::accumulate(begin, end, std::make_pair(0u, T{}), [](const auto& accumulated, const auto& element)\n//    { \n//      return std::make_pair(accumulated.first + 1, accumulated.second + element); \n//    })\n//\t};\n//\n//  return accumulated.first ? std::optional<T>{ accumulated.second / accumulated.first } : std::nullopt;\n//}\n\n\nint main()\n{\n  std::vector<double> numbers{ 1, 2, 4, 8, 16, 32, 64, 128, 256 };\n  std::cout << *average<double>(begin(numbers), end(numbers)) << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_06/Soln20_06.cpp",
    "content": "// Removing all elements that satisfy a certain condition \n// while iterating over a container\n#include <vector>\n#include <string_view>\n#include <iostream>\n#include <algorithm>   // for std::remove_if()\n#include <numeric>     // for std::iota()\n\n/*\n  Note: std::ranges::iota() does not exist. No doubt because \n  the <ranges> module defines a std::ranges::views::iota range factory.\n  Maybe you can alter this solution to use that view instead to fill the vector?\n  (Note: in the next exercise you are asked to not use a vector at all,\n   but operate directly with views...)\n*/\n\nstd::vector<int> fillVector_1toN(size_t N);       // Fill a vector with 1, 2, ..., N\nvoid printVector(std::string_view message, const std::vector<int>& numbers);\n\ntemplate <typename Auto>\nvoid removeEvenNumbers(Auto& numbers)    /* Using more elegant std::erase_if() */\n{\n  std::erase_if(numbers, [](auto number) { return number % 2 == 0; });\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ fillVector_1toN(num_numbers) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  removeEvenNumbers(numbers);\n\n  printVector(\"The numbers that were kept\", numbers);\n}\n\nstd::vector<int> fillVector_1toN(size_t N)\n{\n  std::vector<int> numbers(N);\n  std::iota(begin(numbers), end(numbers), 1);\n  return numbers;\n}\n\nvoid printVector(std::string_view message, const std::vector<int>& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_07/Soln20_07.cpp",
    "content": "// Removing all elements that satisfy a certain condition \n// while iterating over a container\n#include <vector>\n#include <string_view>\n#include <iostream>\n#include <ranges>\n\nusing namespace std::ranges::views;\n\ntemplate <typename Auto>\nvoid printVector(std::string_view message, Auto& numbers)\n{\n  std::cout << message << \": \";\n  for (int number : numbers) std::cout << number << ' ';\n  std::cout << std::endl;\n}\n\nint main()\n{\n  const size_t num_numbers{ 20 };\n\n  auto numbers{ iota(1, 20) };\n\n  printVector(\"The original set of numbers\", numbers);\n\n  auto odd_numbers{ numbers | filter([](int i) { return i % 2 != 0; }) };\n\n  printVector(\"The numbers that were kept\", odd_numbers);\n}\n\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_08/Soln20_08.cpp",
    "content": "// Exercise 20-8 Apply remove-erase idiom to remove duplicate elements\n#include <iostream>\n#include <random>     // For random number generation\n#include <functional> // For std::bind() and std::ref()\n#include <algorithm>\n#include <vector>\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main()\n{\n  const size_t num_numbers{ 25'000 };\n  std::vector<int> numbers(num_numbers);\n\n  // Why not use an algorithm as well to generate the random numbers!!\n  // (Note: technically generate() is allowed to copy a function object \n  //  as often as it wants. std::ref() ensures that the algorithm \n  //  at all times operates on a reference to our random-number generator)\n  auto generator{ createUniformPseudoRandomNumberGenerator(0, 10'000) };\n  std::ranges::generate(numbers, std::ref(generator));\n\n  // Algorithm number two\n  std::ranges::sort(numbers);\n\n  // And number three; this time combined with the remove-erase idiom (or unique-erase, if you will)\n  /* Option 1: iterator-based */\n  numbers.erase(std::unique(begin(numbers), end(numbers)), end(numbers));\n  /* Option 2: range-based (sadly requires two statements...) */\n  //const auto [to_erase_begin, to_erase_end] { std::ranges::unique(numbers) };\n  //numbers.erase(to_erase_begin, to_erase_end);\n\n  std::cout << \"Number of unique numbers: \" << numbers.size() << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_09/Soln20_09.cpp",
    "content": "// Exercise 20-9 Parallel version of 20-8\n#include <iostream>\n#include <random>     // For random number generation\n#include <functional> // For std::bind() and std::ref()\n#include <algorithm>\n#include <vector>\n#include <execution>\n\n// Creates a preudo-random number generator (PRNG) that generates unsigned integers \n// in a closed interval [min, max].\n// Caution: unlike std::uniform_real_distribution (see Chapter 12), \n// uniform_int_distribution generates values in a *closed* interval.\nauto createUniformPseudoRandomNumberGenerator(unsigned min, unsigned max)\n{\n  std::random_device seeder;     // True random number generator to obtain a seed (slow)\n  std::default_random_engine generator{ seeder() }; // Efficient pseudo-random generator\n  std::uniform_int_distribution distribution{ min, max };      // Generate in [min, max]\n  return std::bind(distribution, generator);        //... and in the darkness bind them!\n}\n\nint main()\n{\n  const size_t num_numbers{ 25'000 };\n  std::vector<int> numbers(num_numbers);\n\n  /* Caution: a pseudo-random number generator cannot safely be accessed concurrently! */\n  auto generator{ createUniformPseudoRandomNumberGenerator(0, 10'000) };\n  std::ranges::generate(numbers, std::ref(generator));\n\n  // Algorithm number two\n  std::sort(std::execution::par, begin(numbers), end(numbers));\n\n  // And number three; this time combined with the remove-erase idiom (or unique-erase, if you will)\n  numbers.erase(std::unique(std::execution::par, begin(numbers), end(numbers)), end(numbers));\n\n  std::cout << \"Number of unique numbers: \" << numbers.size() << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_10/Soln20_10.cpp",
    "content": "// Exercise 20-10: exercising projection with range-based algorithms\n#include <iostream>\n#include <string>\n#include <vector>\n#include <algorithm>\n\nint main()\n{\n  std::vector<std::string> names{\"Frodo Baggins\", \"Gandalf the Gray\", \n    \"Aragon\", \"Samwise Gamgee\", \"Peregrin Took\", \"Meriadoc Brandybuck\", \n    \"Gimli\", \"Legolas Greenleaf\", \"Boromir\"};\n\n  // Sort the names lexicographically\n  std::ranges::sort(names);\n  std::cout << \"Names sorted lexicographically:\" << std::endl;\n  for (const auto& name : names) std::cout << name << \", \";\n  std::cout << std::endl << std::endl;  \n\n  // Sort the names by length\n  /* Option 1: projection using member function pointer */\n  std::ranges::sort(names, std::less<>{}, &std::string::length);\n  /* Option 2: projection using lambda expression */\n//  std::ranges::sort(names, std::less<>{}, [](const auto& name) { return name.length(); });\n  std::cout << \"Names sorted by length:\" << std::endl;\n  for (const auto& name : names) std::cout << name << \", \";\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_11/Soln20_11.cpp",
    "content": "// Exercise 20-11: exercising range factories and range adaptors\n#include <iostream>\n#include <algorithm>\n#include <ranges>\n#include <cmath>\n\nusing namespace std::ranges::views;\n\nbool isPrime(unsigned number)   \n{\n  // Of course we use an algorithm and a range factory here as well!\n  // Caution: mind the corner cases where number is 0, 1, or 2!\n  return number >= 2 \n    && std::ranges::none_of(\n          iota(2u, static_cast<unsigned>(std::sqrt(number) + 1)),\n          [number](unsigned divisor) { return number % divisor == 0; }\n       );\n}\n\nint main()\n{\n  const unsigned num_primes{ 100 };\n  const unsigned per_line{ 10 };\n\n  unsigned count{};\n  for (auto prime : iota(2) | filter(&isPrime) | take(num_primes) | reverse)\n  {\n    std::cout << prime << ' ';\n    if (++count % per_line == 0)\n      std::cout << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_12/Soln20_12.cpp",
    "content": "// Exercise 20-12: exercising new range adaptors\n#include <iostream>\n#include <algorithm>\n#include <ranges>\n#include <cmath>\n\nusing namespace std::ranges::views;\n\nbool isPrime(unsigned number)   \n{\n  // Of course we use an algorithm and a range factory here as well!\n  // Caution: mind the corner cases where number is 0, 1, or 2!\n  return number >= 2 \n    && std::ranges::none_of(\n          iota(2u, static_cast<unsigned>(std::sqrt(number) + 1)),\n          [number](unsigned divisor) { return number % divisor == 0; }\n       );\n}\n\nint main()\n{\n  const unsigned max{ 1'000 };\n  const unsigned per_line{ 10 };\n\n  // As you no doubt deduced, drop_while() is not really applicable here,\n  // but take_while() fits nicely!\n  unsigned count{};\n  for (auto prime : iota(2u) \n        | filter(&isPrime) \n        | take_while([max](unsigned prime) { return prime < max; }) \n        | reverse)\n  {\n    std::cout << prime << ' ';\n    if (++count % per_line == 0)\n      std::cout << std::endl;\n  }\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_13/Soln20_13.cpp",
    "content": "// Exercise 20-13: more fun with algorithms and ranges\n#include <iostream>\n#include <format>\n#include <map>\n#include <string>\n#include <string_view>\n#include <vector>\n#include <algorithm>\n#include <ranges>\n\nusing namespace std::ranges::views;\n\n// Type aliases\nusing Words = std::vector<std::string_view>;\nusing WordCounts = std::map<std::string_view, size_t>;\n\n// Function prototypes\nWords extractWords(std::string_view text, std::string_view separators = \" ,.!?\\\"\\n\");\nWordCounts countWords(const Words& words);\nvoid showWordCounts(const WordCounts& wordCounts);\n\n/*\n  Below we list a number of possible solutions.\n  We're sure there are plenty more variations possible...\n */\n\nsize_t maxWordLength(const WordCounts& wordCounts)\n{\n  // Filter out words that occur only once + transform to word lengths using lambda expression\n  auto frequentWordLengths {\n    wordCounts\n      | filter([](const auto wordCount) { return wordCount.second >= 2; })\n      | transform([](const auto wordCount) { return wordCount.first.length(); })\n  };\n\n  return std::ranges::empty(frequentWordLengths) ? 0 : *std::ranges::max_element(frequentWordLengths);\n}\n\nsize_t maxWordLength_1(const WordCounts& wordCounts)\n{\n  // Filter out words that occur only once, transform twice in a row with member pointers.\n  auto frequentWordLengths {\n    wordCounts\n      | filter([](const auto wordCount) { return wordCount.second >= 2; })\n      | transform(&WordCounts::value_type::first)  // Or, without alias: transform(&std::pair<const std::string_view, size_t>::first)\n      | transform(&std::string_view::length)\n  };\n\n  return std::ranges::empty(frequentWordLengths) ? 0 : *std::ranges::max_element(frequentWordLengths);\n}\n\nsize_t maxWordLength_2(const WordCounts& wordCounts)\n{\n  // Filter out words that occur only once, transform to words, project to lengths.\n  auto frequentWords {\n    wordCounts\n      | filter([](const auto wordCount) { return wordCount.second >= 2; })\n      | transform([](const auto wordCount) { return wordCount.first; })\n  };\n\n  return std::ranges::empty(frequentWords) \n    ? 0 \n    : (*std::ranges::max_element(frequentWords, std::less<>{}, &std::string_view::length)).length();\n}\n\nsize_t maxWordLength_3(const WordCounts& wordCounts)\n{\n  // Filter out words that occur only once\n  auto frequentWordCounts \n    { wordCounts | filter([](const auto wordCount) { return wordCount.second >= 2; }) };\n  \n  // Project to obtain the words (the first element of the pairs in the map), \n  // and compare their lengths using a lambda expression\n  return std::ranges::empty(frequentWordCounts) \n    ? 0 \n    : std::ranges::max_element(\n        frequentWordCounts,\n        [](auto word1, auto word2) { return word1.length() < word2.length(); },\n        &WordCounts::value_type::first  // Or, without alias: std::pair<const std::string_view, size_t>::first\n      )->first.size();\n}\n\n\nint main()\n{\n  std::string text;    // The string to count words in\n\n  // Read a string from the keyboard\n  std::cout << \"Enter a string terminated by *:\" << std::endl;\n  getline(std::cin, text, '*');\n\n  const Words words{ extractWords(text) };\n  if (words.empty())\n  {\n    std::cout << \"No words in text.\" << std::endl;\n    return 0;\n  }\n\n  const WordCounts wordCounts{ countWords(words) };\n  showWordCounts(wordCounts);\n}\n\nWords extractWords(std::string_view text, std::string_view separators)\n{\n  Words words;\n  size_t start{ text.find_first_not_of(separators) };    // Start 1st word\n  size_t end{};                                          // Index for the end of a word\n                                                         \n  while (start != std::string_view::npos)                \n  {                                                      \n    end = text.find_first_of(separators, start + 1);     // Find end separator\n    if (end == std::string_view::npos)                   // End of text?\n      end = text.length();                               // Yes, so set to last+1\n    words.push_back(text.substr(start, end - start));    \n    start = text.find_first_not_of(separators, end + 1); // Find next word\n  }\n\n  return words;\n}\n\nWordCounts countWords(const Words& words)\n{\n  WordCounts result;\n  for (auto& word : words)\n    ++result[word];\n  return result;\n}\n\nvoid showWordCounts(const WordCounts& wordCounts)\n{\n  const size_t field_width{ maxWordLength(wordCounts) + 1};\n  const size_t words_per_line{5};\n\n  size_t words_in_line{};      // Number of words in the current line\n  char previous_initial{};\n  for (const auto& [word, count] : wordCounts)\n  {\n    if (count < 2) continue;   // Skip words that appear only once\n\n    // Output newline when initial letter changes or after 5 per line\n    if ( (previous_initial && word[0] != previous_initial)\n          || words_in_line++ == words_per_line)\n    {\n      words_in_line = 0;\n      std::cout << std::endl;\n    }\n    // Output \"word (count)\", where word has a dynamic field width\n    std::cout << std::format(\"{:>{}} ({:2})\", word, field_width, count); \n    previous_initial = word[0];\n  }\n  std::cout << std::endl;\n}\n"
  },
  {
    "path": "Exercises/NoModules/Chapter 20/Soln20_14/Soln20_14.cpp",
    "content": "// Exercise 20-14: the hard nut\n#include <iostream>\n#include <algorithm>\n#include <ranges>\n#include <iterator>\n#include <cmath>\n\nusing namespace std::ranges::views;\n\nbool isPrime(unsigned number)\n{\n  return number >= 2 \n      && std::ranges::none_of(\n           iota(2u, static_cast<unsigned>(std::sqrt(number) + 1)),\n           [number](unsigned divisor) { return number % divisor == 0; }\n         );\n}\n\nint main()\n{\n  // This first version is one that compiled (with some help) on at least one compiler.\n  // It uses one thing you have not encountered yet: std::ranges::views::common.\n  // This range adaptor transforms a given range into a view where begin() and end()\n  // return values of the same type, something which in general is not true for ranges. \n  // Legacy algorithms, such as the iterator-pair-based std::copy() algorithm, \n  // often expect iterator pairs to have the same type, though.\n  auto view { \n    std::ranges::istream_view<int>(std::cin)\n      | take_while([](int i) { return i >= 0; })\n      | transform([](int i) { return static_cast<unsigned>(i); })\n      | filter(isPrime)\n      | transform([](unsigned i) { return \"Yes, that is a prime!\"; })\n      | common \n  };\n\n  std::copy(view.begin(), view.end(), std::ostream_iterator<std::string>(std::cout, \"\\n\"));\n\n/*\n  // Same as the previous one, but then without the legacy iterator-pair-based copy()\n  // (and thus without the common range adaptor).\n  // At the time we tried this, this did not compile yet in any compiler.\n  auto view {\n    std::ranges::istream_view<int>(std::cin)\n      | take_while([](int i) { return i >= 0; })\n      | transform([](int i) { return static_cast<unsigned>(i); })\n      | filter(isPrime)\n      | transform([](unsigned i) { return \"Yes, that is a prime!\"; })\n  };\n\n  std::ranges::copy(view, std::ostream_iterator<std::string>(std::cout, \"\\n\"));\n*/\n\n/*\n  // A variation that uses std::ranges::for_each(). \n  // But, like the exercise says, this is cheating though, \n  // as for_each() is just a poorly disguised range-based for loop,\n  // and loops were not allowed!\n  std::ranges::for_each(\n    std::ranges::istream_view<int>(std::cin)\n      | take_while([](int i) { return i >= 0; })\n      | transform([](int i) { return static_cast<unsigned>(i); })\n      | filter(isPrime)\n      | transform([](unsigned i) { return \"Yes, that is a prime!\"; })\n    , [](const auto& s) { std::cout << s << std::endl; }\n  );\n*/\n\n/*\n  // A \"clever\" version where we print during a filter step\n  auto view {\n    std::ranges::istream_view<int>(std::cin)\n      | take_while([](int i) { return i >= 0; })\n      | transform([](int i) { return static_cast<unsigned>(i); })\n      | filter(isPrime)\n      | filter([](unsigned i) { std::cout << \"Yes, that is a prime!\\n\"; return false; })\n  };\n  view.begin(); // Try to find the begin of the view\n                // Since the last step filters out all elements, though,\n                // this will never find a begin, and eventually return view.end()...\n*/\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 21/Soln21_01/Soln21_01.cpp",
    "content": "// Exercise 21-1  Understanding compound and simple requirements\n#include <concepts>    // For the std::same_as<> and std::convertible_to<> concepts\n#include <ranges>      // For std::ranges::range<> concept\n#include <type_traits> // For the std::remove_cv<> type trait\n#include <list>\n#include <vector>\n#include <string>\n\ntemplate <typename Iter>\nconcept BidirectionalIterator = true; // Feel free to further work out all requirements...\n\n// A compound requirement \"{ expr } -> concept<Args>;\" is equivalent to \n// the simple requirement \"expr;\", \n// combined with the nested requirement \"requires concept<decltype(expr),Args>;\"\ntemplate<class Iter>\nconcept RandomAccessIterator = BidirectionalIterator<Iter>\n  && requires(const Iter i, const Iter j, Iter k, const int n)\n     {\n       { i - n }; { i + n }; { n + i };\n       requires std::same_as<decltype(i - n), Iter>;\n       requires std::same_as<decltype(i + n), Iter>;\n       requires std::same_as<decltype(n + i), Iter>;\n       { k += n }; { k -= n };\n       requires std::same_as<decltype(k += n), Iter&>;\n       requires std::same_as<decltype(k -= n), Iter&>;\n       i[n];\n       requires std::same_as<decltype(i[n]), decltype(*i)>;\n       i < j; i > j; i <= j; i >= j;\n       requires std::convertible_to<decltype(i < j), bool>\n             && std::convertible_to<decltype(i > j), bool>\n             && std::convertible_to<decltype(i <= j), bool>\n             && std::convertible_to<decltype(i >= j), bool>;\n     };\n\n// To rewrite a compound requirement with noexcept you should know \n// that noexcept(expr) is a valid constant expression as well...\ntemplate <typename T>\nconcept NoExceptDestructible = requires (T& value) \n{ \n  value.~T();\n  noexcept(value.~T());\n};\n\ntemplate <typename C>\nconcept Character = std::same_as<std::remove_cv_t<C>, char>\n                  || std::same_as<std::remove_cv_t<C>, char8_t>\n                  || std::same_as<std::remove_cv_t<C>, char16_t>\n                  || std::same_as<std::remove_cv_t<C>, char32_t>\n                  || std::same_as<std::remove_cv_t<C>, wchar_t>;\n\n// More of the same...\ntemplate <typename S>\nconcept String = std::ranges::range<S> && requires(S & s, const S & cs)\n{\n  typename S::value_type;\n  requires Character<typename S::value_type>;\n  cs.length();\n  requires std::integral<decltype(cs.length())>;\n  s[0]; cs[0];\n  requires std::same_as<decltype(s[0]), typename S::value_type&>\n        && std::convertible_to<decltype(cs[0]), typename S::value_type>;\n  s.data(); cs.data();\n  requires std::same_as<decltype(s.data()), typename S::value_type*>\n        && std::same_as<decltype(cs.data()), const typename S::value_type*>;\n  // ...\n};\n\nstatic_assert(NoExceptDestructible<std::string>);\nstatic_assert(NoExceptDestructible<int>);\nstatic_assert(String<std::string>);\nstatic_assert(!String<std::vector<char>>);\nstatic_assert(Character<char>);\nstatic_assert(Character<const char>);\nstatic_assert(RandomAccessIterator<std::vector<int>::iterator>);\nstatic_assert(!RandomAccessIterator<std::list<int>::iterator>);\nstatic_assert(RandomAccessIterator<int*>);\n\nint main()\n{\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 21/Soln21_02/Soln21_02.cpp",
    "content": "// Exercise 21-2  Writing a proper, modern algorithm is hard...\n// It involves adding support for projection, member pointers,\n// and iterator pairs where the end iterator (or, sentinel) \n// is of a different type than the begin iterator,\n// all with proper type constraints.\n#include <iostream>\n#include <concepts>    // Standard concepts\n#include <ranges>      // Range factories and adaptors\n#include <functional>  // For the std::identity and std::ranges::less functor classes, and std::invoke()\n#include <iterator>    // Iterator-based concepts, std::sentinel_for, and std::projected\n#include <vector>\n\nusing namespace std::ranges::views;\n\n// The original function template which requires begin and end to be of the same type\n// Similar to the original iterator-pair based algorithms of <algorithm>,\n// only with type constraints.\ntemplate <std::forward_iterator Iterator,\n          std::indirect_strict_weak_order<Iterator> Comparison>\nIterator original_find_optimum(Iterator begin, Iterator end, Comparison compare)\n{\n  if (begin == end) return end;\n\n  Iterator optimum{ begin };\n  for (auto iter{ ++begin }; iter != end; ++iter)\n  {\n    if (compare(*iter, *optimum)) optimum = iter;\n  }\n  return optimum;\n}\n\n// Our improved function template supporting projection and differently-typed sentinels.\n// Appropriate default values were added as well.\ntemplate <std::forward_iterator Iterator,\n          std::sentinel_for<Iterator> Sentinel, \n          typename Projection = std::identity,\n          std::indirect_strict_weak_order<std::projected<Iterator, Projection>> Comparison = std::ranges::less>\nIterator find_optimum(Iterator begin, Sentinel end, Comparison compare = {}, Projection projection = {})\n{\n  if (begin == end) return begin; // Do not return end as before...\n\n  Iterator optimum{ begin };\n  for (auto iter{ ++begin }; iter != end; ++iter)\n  {\n    // Note 1: std::invoke() is required to support comparison and projection through member pointers \n    // Note 2: this re-invokes projection(*optimum) for each comparison, same as std::max_element()\n    if (std::invoke(compare, std::invoke(projection, *iter), std::invoke(projection, *optimum)))\n      optimum = iter;\n  }\n  return optimum;\n}\n\n/* A simple Box class to exercise our member-based comparison and projection facilities.\n  It lacks an operator<(), so with classical algorithms you'd need lambdas to compare these Boxes...\n */\nclass Box\n{\npublic:\n  Box() : Box{ 1, 1, 1 } {};\n  Box(double length, double width, double height)\n    : m_length{ length }, m_width{ width }, m_height{ height }\n  {}\n   \n  double volume() const { return m_length * m_width * m_height; }\n  double isSmallerThan(const Box& other) const { return volume() < other.volume(); }\n\nprivate:\n  double m_length, m_width, m_height;\n};\n\nint main()\n{\n  std::vector<Box> boxes{ {2.0, 2.0, 3.0}, {1.0, 3.0, 2.0}, {1.0, 2.0, 1.0}, {2.0, 3.0, 3.0} };\n\n  // Step 1: create a view where begin() and end() are different.\n  // The result of the take_while() range adapter has this property\n  // (or, at least, it should have as per its specification in the Standard).\n  auto first_boxes{ boxes | take_while([](const Box& box) { return box.volume() < 15; }) };\n  \n  /* This therefore generally does not compile... */\n  //std::cout << \"Volume of smallest box: \" \n  //  << original_find_optimum(first_boxes.begin(), first_boxes.end(),\n  //        [](const Box& box1, const Box& box2) { return box1.isSmallerThan(box2); })->volume()\n  //  << std::endl;\n\n  // Side-note: you can use the std::ranges::views::common to turn a range\n  // where begin and end have a different type into a view where they do.\n  auto common_boxes{ first_boxes | common };\n  std::cout << \"Volume of smallest box: \" \n    << original_find_optimum(common_boxes.begin(), common_boxes.end(),\n          [](const Box& box1, const Box& box2) { return box1.isSmallerThan(box2); })->volume()\n    << std::endl;\n  \n  // Step 2: Show off our shiny new, modernised version of find_optimum()\n  // First off: no need for the common adapter!\n  std::cout << \"Volume of largest box: \"\n    << find_optimum(first_boxes.begin(), first_boxes.end(),\n          [](const Box& box1, const Box& box2) { return !box1.isSmallerThan(box2); })->volume()\n    << std::endl;\n\n  // Other cool features of our modern find_optimum() version include projection \n  // and the support for member function pointers. So no more lambdas required here!\n\n  // Use a member-function pointer for the comparison function\n  std::cout << \"Volume of smallest box: \" \n    << find_optimum(first_boxes.begin(), first_boxes.end(), &Box::isSmallerThan)->volume() \n    << std::endl;\n\n  // Use a member-function pointer for the new projection functionality\n  std::cout << \"Volume of largest box: \" \n    << find_optimum(first_boxes.begin(), first_boxes.end(), std::greater<>{}, &Box::volume)->volume()\n    << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 21/Soln21_03/Soln21_03.cpp",
    "content": "// Exercise 21-3 \n#include <iostream>\n#include <concepts>\n#include <span>\n#include <array>\n#include <string>\n\n/* Not requested, but just for fun, here is a concept that prescribes \n   a complete set of operations one would require to take an average */\ntemplate <typename T>\nconcept Averagable = requires (const T x, const T y, T z, const int i)\n{\n  { x + y }  -> std::same_as<T>;\n  { x - y }  -> std::same_as<T>;\n  { z += y } -> std::same_as<T&>;\n  { z -= y } -> std::same_as<T&>;\n  { x / i }  -> std::same_as<T>;\n  { x * i }  -> std::same_as<T>;\n  { z /= i } -> std::same_as<T&>;\n  { z *= i } -> std::same_as<T&>;\n};\n\n// By default, take the N / 2'th element\n// (Note: this template covers both the case if T would not be Averageble,\n//  and the case where N % 2 == 1).\ntemplate <typename T, size_t N>\nauto& medianOfSorted(std::span<T, N> span)\n{\n  static_assert(N != 0, \"The median of an empty span is not defined\");\n  return span[N / 2];\n}\n\ntemplate <Averagable T, size_t N> requires (N % 2 == 0)\nauto medianOfSorted(std::span<T, N> span)\n{\n  static_assert(N != 0, \"The median of an empty span is not defined\");\n  return (span[N / 2 - 1] + span[N / 2]) / 2;\n}\n\nint main()\n{\n  std::array values_odd{ 1, 2, 3, 4, 5, 6, 7 };\n  std::cout << medianOfSorted(std::span{ values_odd }) << std::endl;\n\n  std::array values_even{ 1., 2., 3., 4., 5., 6. };\n  std::cout << medianOfSorted(std::span{ values_even }) << std::endl;\n\n  std::string strings_odd[] { \"1\", \"2\", \"3\", \"4\", \"5\" };\n  std::cout << medianOfSorted(std::span{ strings_odd }) << std::endl;\n\n  std::string strings_even[] { \"1\", \"2\", \"3\", \"4\", \"5\", \"6\" };\n  std::cout << medianOfSorted(std::span{ strings_even }) << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 21/Soln21_04/Soln21_04.cpp",
    "content": "// Exercise 21-4  Generalising medianOfSorted()\n#include <iostream>\n#include <concepts>\n#include <array>\n#include <string>\n#include <vector>\n#include <list>\n#include <forward_list>\n#include <span>\n#include <ranges>\n#include <iterator>\n\n/*\n  Apologies. When we wrote the exercise, we misread what a std::sized_range() was.\n  std::sized_range() is no concept for statically fixed-size ranges, \n  but for ranges for which std::ranges::size() may be invoked *at runtime*.\n  So this solution presents the next best thing: a medianOfSorted() that works\n  for any range (not just fixed-size ranges), with appropriate type constraints.\n  Key point is that underlying, range-based algorithms still very much work with iterators.\n  Most requirements use Standard Library concepts in the std::ranges namespace,\n  and the function implementations use Standard Library functions in that same namespace.\n */\n\n/* Not requested, but just for fun, here is a concept that prescribes \n   a complete set of operations one would require to take an average */\ntemplate <typename T>\nconcept Averagable = requires (const T x, const T y, T z, const int i)\n{\n  { x + y }  -> std::same_as<T>;\n  { x - y }  -> std::same_as<T>;\n  { z += y } -> std::same_as<T&>;\n  { z -= y } -> std::same_as<T&>;\n  { x / i }  -> std::same_as<T>;\n  { x * i }  -> std::same_as<T>;\n  { z /= i } -> std::same_as<T&>;\n  { z *= i } -> std::same_as<T&>;\n};\n\n// By default, take the N/2'th element\ntemplate <std::ranges::sized_range Range>   // Requires being able to determine the range's size using std::ranges::size()\n  requires std::ranges::input_range<Range>  // Requires being able to dereference an iterator over the range.\nauto& medianOfSorted(Range&& range)\n{\n  auto iter{ std::ranges::begin(range) };   // Supported for every range\n  std::ranges::advance(iter, std::ranges::size(range) / 2);  // Advances in constant time for random-access ranges, linearly otherwise.\n  return *iter;                             // Only possible with input iterators...\n}\n\n// When we can take an average, check the size \n// (dynamically, not statically as was the original intent) \n// to decide whether we need to do so...\ntemplate <std::ranges::sized_range Range> \n  requires std::ranges::forward_range<Range>  // More strict than before: we need the multi-pass guarantee\n        && Averagable<std::ranges::range_value_t<Range>>\nauto medianOfSorted(Range&& range)\n{\n  const auto N{ std::ranges::size(range) };\n  auto iter{ std::ranges::begin(range) };\n  if (N % 2 == 0)\n  {\n    std::ranges::advance(iter, N / 2 - 1);\n    const auto& value1{ *iter };      // Reference remains valid because iter is a forward iterator!\n    std::ranges::advance(iter, 1);\n    return (value1 + *iter) / 2;\n  }\n  else\n  {\n    std::ranges::advance(iter, N / 2);\n    return *iter;\n  }\n}\n\nint main()\n{\n  std::array values_odd{ 1, 2, 3, 4, 5, 6, 7 };\n  std::cout << medianOfSorted(values_odd) << std::endl;\n\n  std::array values_even{ 1., 2., 3., 4., 5., 6. };\n  std::cout << medianOfSorted(values_even) << std::endl;\n\n  std::string strings_odd[] { \"1\", \"2\", \"3\", \"4\", \"5\" };\n  std::cout << medianOfSorted(strings_odd) << std::endl;\n\n  std::string strings_even[] { \"1\", \"2\", \"3\", \"4\", \"5\", \"6\" };\n  std::cout << medianOfSorted(std::span{ strings_even }) << std::endl;\n\n  std::vector dynamically_sized{ 1.f, 2.f, 3.f, 4.f };\n  std::cout << medianOfSorted(dynamically_sized) << std::endl;\n\n  std::list non_random_access{ 4.f, 3.f, 2.f, 1.f, 0.f };\n  std::cout << medianOfSorted(non_random_access) << std::endl;\n\n  std::forward_list non_sized_ranged{ 123, 456, 789 };\n  //std::cout << medianOfSorted(non_sized_ranged) << std::endl; /* Error: not sized! */\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 21/Soln21_05/Soln21_05.cpp",
    "content": "// Exercise 21-5  Recreating std::advance() using constraint-based specialisation\n#include <iostream>\n#include <iterator>\n\n#include <vector>\n#include <list>\n#include <forward_list>\n\ntemplate <std::random_access_iterator Iter>\nauto my_advance(Iter iter, std::iter_difference_t<Iter> n)\n{\n  return iter + n;\n}\n\ntemplate <std::bidirectional_iterator Iter>\nauto my_advance(Iter iter, std::iter_difference_t<Iter> n)\n{\n  while (n > 0) { ++iter; --n; }\n  while (n < 0) { --iter; ++n; }\n  return iter;\n}\n\ntemplate <std::input_or_output_iterator Iter>\nauto my_advance(Iter iter, std::iter_difference_t<Iter> n)\n{\n  while (n > 0) { ++iter; --n; }\n  return iter;\n}\n\nint main()\n{\n  // Random-access iterators:\n  std::vector v{ 1, 2, 3, 4, 5 };\n  std::cout << *my_advance(v.begin(), 3) << std::endl;\n\n  // Bidirectional iterators:\n  std::list l{ 1, 2, 3, 4, 5 };\n  std::cout << *my_advance(l.end(), -3) << std::endl;\n\n  // Forward iterators:\n  std::forward_list f{ 1, 2, 3, 4, 5 };\n  std::cout << *my_advance(f.begin(), 3) << std::endl;\n}"
  },
  {
    "path": "Exercises/NoModules/Chapter 21/Soln21_06/Array.h",
    "content": "#ifndef ARRAY_H\n#define ARRAY_H\n\n#include <stdexcept>                        // For standard exception types\n#include <string>                           // For std::to_string()\n#include <utility>                          // For std::as_const()\n#include <iostream>\n\n/*\n// Original template based on type traits and some mild template meta-programming\ntemplate<class T>\nstd::conditional_t<std::is_nothrow_move_assignable_v<T>, T&&, const T&>\nmove_assign_if_noexcept(T& x) noexcept\n{\n  return std::move(x);\n}\n*/\n\n// A straightforward concept with a single compound requirement\ntemplate <typename T>\nconcept NoThrowMoveAssignable =\n  requires (T left, T right) { { left = std::move(right) } noexcept -> std::same_as<T&>; };\n\n// By default: return lvalue reference (will result in x being copied)\n// (Note: this default move_assign_if_noexcept() template in itself is noexcept, \n//  the copy assignment that generally follows is not...)\nauto& move_assign_if_noexcept(auto& x) noexcept { return x; }\n\n// Specialization that moves if possible without throwing\n// Uses abbreviated template syntax with a type constraint on auto)\nauto&& move_assign_if_noexcept(NoThrowMoveAssignable auto& x) noexcept { return std::move(x); }\n\n\ntemplate <typename T>\nclass Array\n{\npublic:\n  Array();                                  // Default constructor\n  explicit Array(size_t size);              // Constructor\n  ~Array();                                 // Destructor\n  Array(const Array& array);                // Copy constructor\n  Array(Array&& array) noexcept;            // Move constructor\n  Array& operator=(const Array& rhs);       // Copy assignment operator\n  Array& operator=(Array&& rhs) noexcept;   // Move assignment operator\n  void swap(Array& other) noexcept;         // Swap member function\n  T& operator[](size_t index);              // Subscript operator\n  const T& operator[](size_t index) const;  // Subscript operator-const arrays\n  size_t getSize() const { return m_size; } // Accessor for m_size\n  void push_back(T element);                // Copy or move element to the back of the array\n\nprivate:\n  T* m_elements;    // Array of type T\n  size_t m_size;    // Number of array elements\n};\n\n// Forwarding default constructor template\ntemplate <typename T>\nArray<T>::Array() : Array{0}\n{}\n\n// Constructor template\ntemplate <typename T>\nArray<T>::Array(size_t size) : m_elements {new T[size] {}}, m_size {size}\n{}\n\n// Copy constructor template\ntemplate <typename T>\nArray<T>::Array(const Array& array) : Array{array.m_size}\n{\n  std::cout << \"Array of \" << m_size << \" elements copied\" << std::endl;\n  for (size_t i {}; i < m_size; ++i)\n    m_elements[i] = array.m_elements[i];\n}\n\n// Move constructor template\ntemplate <typename T>\nArray<T>::Array(Array&& moved) noexcept\n  : m_size{moved.m_size}, m_elements{moved.m_elements}\n{\n  std::cout << \"Array of \" << m_size << \" elements moved\" << std::endl;\n  moved.m_elements = nullptr; // Otherwise destructor of moved would delete[] m_elements!\n}\n\n// Destructor template\ntemplate <typename T>\nArray<T>::~Array() { delete[] m_elements; }\n\n// const subscript operator template\ntemplate <typename T>\nconst T& Array<T>::operator[](size_t index) const\n{\n  if (index >= m_size)\n    throw std::out_of_range {\"Index too large: \" + std::to_string(index)};\n  return m_elements[index];\n}\n\n// Non-const subscript operator template in terms of const one\n// Uses the 'const-and-back-again' idiom\ntemplate <typename T>\nT& Array<T>::operator[](size_t index)\n{\n  return const_cast<T&>(std::as_const(*this)[index]);\n}\n\n// Template for exception-safe copy assignment operators\n// (expressed in terms of copy constructor and swap member)\ntemplate <typename T>\nArray<T>& Array<T>::operator=(const Array& rhs)\n{\n  Array<T> copy{ rhs }; // Copy...       (could go wrong and throw an exception)\n  swap(copy);           // ... and swap! (noexcept)\n  return *this;\n}\n\n// Move assignment operator template\ntemplate <typename T>\nArray<T>& Array<T>::operator=(Array&& rhs) noexcept\n{\n  std::cout << \"Array of \" << rhs.m_size << \" elements moved (assignment)\" << std::endl;\n\n  if (&rhs != this)            // prevent trouble with self-assignments\n  {\n    delete[] m_elements;       // delete[] all existing elements\n\n    m_elements = rhs.m_elements; // copy the elements pointer and the size\n    m_size = rhs.m_size;\n\n    rhs.m_elements = nullptr;  // make sure rhs does not delete[] m_elements\n  }\n  return *this;                // return lhs\n}\n\n// Swap member function template\ntemplate <typename T>\nvoid Array<T>::swap(Array& other) noexcept\n{\n  std::swap(m_elements, other.m_elements); // Swap two pointers\n  std::swap(m_size, other.m_size);         // Swap the sizes\n}\n\n// Swap non-member function template (optional)\ntemplate <typename T>\nvoid swap(Array<T>& one, Array<T>& other) noexcept\n{\n  one.swap(other);     // Forward to public member function\n}\n\n// push_back() overload for lvalue references\ntemplate <typename T>\nvoid Array<T>::push_back(T element)  // Pass by value (copy of lvalue, or moved rvalue!)\n{\n  Array<T> newArray{m_size + 1};     // Allocate a larger Array<>\n  for (size_t i {}; i < m_size; ++i) // Move existing elements (copy if not noexcept)...\n    newArray[i] = move_assign_if_noexcept(m_elements[i]);\n\n  newArray[m_size] = move_assign_if_noexcept(element);  // Move (or copy) the new one...\n\n  swap(newArray);                   // ... and swap!\n}\n\n#endif"
  },
  {
    "path": "Exercises/NoModules/Chapter 21/Soln21_06/Soln21_06.cpp",
    "content": "// Exercise 21-6  Simplifying move_assign_if_noexcept using concepts (see Array.h)\n#include \"Array.h\"\n#include <string>\n\n// Construct an Array<> of a given size, filled with some arbitrary string data\nArray<std::string> buildStringArray(const size_t size)\n{\n  Array<std::string> result{ size };\n  for (size_t i {}; i < size; ++i)\n    result[i] = \"You should learn from your competitor, but never copy. Copy and you die.\";\n  return result;\n}\n\nint main()\n{\n  Array<Array<std::string>> array_of_arrays;\n\n  Array<std::string> array{ buildStringArray(1'000) };\n  array_of_arrays.push_back(array);              // Push an lvalue\n\n  array.push_back(\"One more for good measure\");\n  std::cout << std::endl;\n\n  array_of_arrays.push_back(std::move(array));   // Push an rvalue\n}"
  },
  {
    "path": "Exercises/README.md",
    "content": "# Exercise Solutions\n\nThis directory contains the solutions to all exercises of\n[*Beginning C++20*](https://www.apress.com/9781484258835) by Ivor Horton and Peter Van Weert (Apress, 2020).\n\nThe [Modules](Modules) directory contains solutions that use C++20 modules.\nIf your compiler does not support C++20 modules yet, though\n(which at the time of writing is likely),\nyou may be better off looking at the solutions in the [NoModules](NoModules) directory instead.\n\nConsult the [Workarounds](../Workarounds) directory on \nhow to work around compilation issues with other C++20 language and library features \nthat your compiler may not (fully) [support](https://en.cppreference.com/w/cpp/compiler_support) yet.\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "﻿Freeware License, some rights reserved\r\n\r\nCopyright (c) 2020 Ivor Horton and Peter Van Weert\r\n\r\nPermission is hereby granted, free of charge, to anyone obtaining a copy \r\nof this software and associated documentation files (the \"Software\"), \r\nto work with the Software within the limits of freeware distribution and fair use. \r\nThis includes the rights to use, copy, and modify the Software for personal use. \r\nUsers are also allowed and encouraged to submit corrections and modifications \r\nto the Software for the benefit of other users.\r\n\r\nIt is not allowed to reuse,  modify, or redistribute the Software for \r\ncommercial use in any way, or for a user’s educational materials such as books \r\nor blog articles without prior permission from the copyright holder. \r\n\r\nThe above copyright notice and this permission notice need to be included \r\nin all copies or substantial portions of the software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n"
  },
  {
    "path": "README.md",
    "content": "# Apress Source Code\n\nThis repository accompanies [*Beginning C++20*](https://www.apress.com/9781484258835) by Ivor Horton and Peter Van Weert (Apress, 2020).\n\n[comment]: #cover\n![Cover image](9781484258835.jpg)\n\nDownload the files as a zip using the green button, or clone the repository to your machine using Git. \nTo make sure you also clone the 3rd party submodules in the [Workarounds](Workarounds) directory, \nwe recommend using the following Git command:\n\n    git clone --recursive https://github.com/Apress/beginning-cpp20.git\n    \n## C++20 Compiler Support\n\nAt the time the book was completed, \nnot a single compiler [supported](https://en.cppreference.com/w/cpp/compiler_support) all C++20 features yet. \nWe recommend you consult the [Workarounds](Workarounds) section on how to work around any compilation issues you may experience.\n\n## Contributions\n\nSee the file [Contributing.md](Contributing.md) for more information on how you can contribute to this repository.\n"
  },
  {
    "path": "Workarounds/README.md",
    "content": "# Workarounds\n\nAt the time the book was completed, \nnot a single compiler [supported](https://en.cppreference.com/w/cpp/compiler_support) all C++20 features yet. \nFeatures that were used in the book, \nand for which you therefore need a workaround to compile and run the example / exercise code include\n\n- [Modules](#modules)\n- [std::format()](#format)  \n- [Abbreviated Function Template Syntax](#abbreviated)  \n- [Ranges](#ranges)  \n\n<a name=\"modules\"/>\n\n## Modules\n\nMost source code, most notably that in the second half of the book, uses C++20's modules.\nUnfortunately, [support](https://en.cppreference.com/w/cpp/compiler_support) for this feature may still be lacking in your compiler / build system.\nFor the smaller examples it is just a matter of replacing the `import` declarations with `#include` directives \n(see [Appendix A](../Appendix.pdf)), but for examples comprising multiple files working around these limitations can be more work.\nFor all examples and exercises that are not explicitly about modules,\nwe therefore made an equivalent version available that does not use modules.\nYou can find these in the `NoModules` directories of this source repository.\n\n<a name=\"format\"/>\n\n## std::format()\nIt's not until recently that some major compilers started adding [support](https://en.cppreference.com/w/cpp/compiler_support) for the C++20 `<format>` module. \nThis module provides safe, elegant, and efficient text formatting, primeraly in the form of the `std::format()` function,\nand is heavily used throughout the C++20 edition of the book.\n\nIf your compiler is too old to [support](https://en.cppreference.com/w/cpp/compiler_support) `<format>` natively,\nwe recommend the [`{fmt}`](https://fmt.dev/) library as a workaround. \nIt is a free and open source implementation of a superset of the now standardised `<format>` module.\n\nSteps:\n1. Download the `fmt` source code \n   - If you downloaded the book's source code as a zip file, you can download that of `fmt` as well from https://github.com/fmtlib/fmt, \n     and extract it in a `fmt` subdirectory of this `Workarounds` directory\n   - If you cloned using Git, but without specifying `--recursive`, \n     you can execute the following Git commands in the root directory of your local clone:\n   \n         git submodule init\n         git submodule update\n \n 2. Add the `Workarounds` directory to the additional include paths of your compiler\n    - For clang and gcc, you do this using the `-I` / `--include-directory` command line flags\n    - For Visual Studio, you right-click your project, select Properties,\n      and add the `Workarounds` directory under \n      \n          Configuration Properties ► C/C++ ► General ► Additional Include Directories ► Edit...\n          \n      as illustrated in the following image\n      \n      <img src=\"Images/VisualStudioAdditionalIncludeDirectories.png\" width=480/>\n      \n 3. If all went well, `#include <format>` will then use the [`format`](format) header in this directory,\n    which injects `{fmt}`'s functionality into the `std` namespace (technically not allowed, we know...), \n    and all `std::format()` statements will work as expected.\n\nNote: this workaround works for `#include <format>` directives (see [Appendix A](../Appendix.pdf)); \nbut at the time of writing we weren't having much luck getting this to work with C++20's `import` declarations.\nIf you're experiencing similar problems,\nwe therefore recommend you mostly use the `NoModules` versions of the source code.\nIf you do want to experiment with modules and `std::format()` is getting in the way of that,\nyou can, for instance, add the following to your source files\n\n    namespace std\n    {\n        export std::string format(auto&&...) { return {}; }\n    }\n    \nYour formatted output will not work, \nbut then at least you can try your luck getting the remainder of your modules to compile.\n\n<a name=\"abbreviated\"/>\n\n## Abbreviated Function Template Syntax\n\nIf your compiler does not [support](https://en.cppreference.com/w/cpp/compiler_support) \nC++20's abbreviated function template syntax yet, the solution is somewhat obvious: \nuse the non-abbreviated syntax. That is, instead of\n\n    namespace math\n    {\n       auto square(const auto& x) { return x * x; }\n    }\n    \nyou use\n\n    namespace math\n    {\n       template <typename T>\n       auto square(const T& x) { return x * x; }\n    }\n    \n(`auto` return type deduction should work with any recent compiler.)\n\n<a name=\"ranges\"/>\n\n## Ranges\n\nSimilar to `<format>`,\nit took some time for all Standard Library implementations to add [support](https://en.cppreference.com/w/cpp/compiler_support) for C++20 ranges\n(and if they had support, not all range algorithms were working as they should).\nIf you experience issues, you can try the excellent [range-v3](https://github.com/ericniebler/range-v3) library of Eric Niebler instead.\nWe added the [header file](ranges) we used for this to this directory.\nThe steps you need to get this to work are similar to those we detailed for [`std::format()`](#format),\nexcept that library needs to be compiled as well,\nand the corresponding binaries added as input to your linker.\nYou can consult the [range-v3](https://github.com/ericniebler/range-v3#supported-compilers) on how to build this library,\nand your compiler's documentation on how to link with the resulting binaries.\n"
  },
  {
    "path": "Workarounds/format",
    "content": "// Compatibility include for compilers that do not support the <format> module yet\n// (falls back to the reference implementation from https://fmt.dev)\n// See Appendix A for the preprocessing directives and macros we use here.\n#ifdef __cpp_lib_format\n\t#error Remove Workarounds/format from your include directories (use Standard Library header instead)\n#else\n\t#define FMT_HEADER_ONLY\n\t#include \"fmt/include/fmt/format.h\"\n\n\t// Technically you are not allowed to add to the std namespace, \n\t// but necessity knows no law...\n\tnamespace std \n\t{ \n\t\tusing namespace fmt;\n\t}\n#endif"
  },
  {
    "path": "Workarounds/ranges",
    "content": "// Compatibility include for compilers that do not support the <ranges> module yet\n// (falls back to the reference implementation from https://github.com/ericniebler/range-v3)\n// See Appendix A for the preprocessing directives and macros we use here.\n#ifdef __cpp_lib_ranges\n\t#error Remove/rename this compatibility header (use Standard Library header instead)\n#else\n\t#include \"range-v3/include/range/v3/all.hpp\"\n\n\t// Technically you are not allowed to add to the std namespace, \n\t// but necessity knows no law...\n\tnamespace std::ranges\n\t{ \n\t\tusing namespace ::ranges::cpp20;\n\n\t\tusing ::ranges::empty;\n\t\tusing ::ranges::begin;\n\t\tusing ::ranges::end;\n\t\tusing ::ranges::size;\n\n\t\ttemplate <class Val, class CharT, class Traits>\n\t\tauto istream_view(basic_istream<CharT, Traits>& s) { return basic_istream_view<Val>(s); }\n\t}\n\tnamespace std::views\n\t{\n\t\tusing namespace ::ranges::cpp20::views;\n\t}\n#endif"
  },
  {
    "path": "errata.md",
    "content": "# Errata for *Beginning C++20*\r\n\r\nOn **page 21** [technical accuracy]:\r\n\r\n> lowercase letters have the sixth bit as 0, and uppercase letters have the sixth bit as 1\r\n\r\nshould be\r\n\r\n> lowercase letters have the sixth bit as 1, and uppercase letters have the sixth bit as 0\r\n\r\n***\r\n\r\nOn **page 53** [typographic errors]:\r\n\r\nIn the description of underflow for unsigned integers, the numbers are missing superscript needed to show exponentiation. Also, the result of 2<sup>32</sup> - 2 is incorrect; the correct result is 4294967294.\r\n\r\n| Original                                   | Corrected                                             |\r\n| ------------------------------------------ | ------------------------------------------------------|\r\n| -1 becomes 232 - 1 or 4294967295           | -1 becomes 2<sup>32</sup> - 1 or 4294967295           |\r\n| -2 becomes 232 - 2 or 4294967293           | -2 becomes 2<sup>32</sup> - 1 or 4294967294           |\r\n| -10 indeed becomes 232 - 10, or 4294967286 | -10 indeed becomes 2<sup>32</sup> - 10, or 4294967286 |\r\n\r\n***\r\n\r\nOn **page 81** [wrong bitwise xor result]:\r\n\r\n> font ^ bold 0000 0110 0010 1100 \r\n\r\nshould be\r\n\r\n> font ^ bold   0000 0110 0**1**10 1100\r\n\r\nThe 7th bit of the bitwise exclusive or must be **1**, not 0.\r\n\r\n***\r\n\r\nOn **page 100** [wrong sign]:\r\n\r\n> std::cout << std::format(\"The value of the expression {} == {} is {}\\n\", first, second, first < second);\r\n\r\nshould be\r\n\r\n> std::cout << std::format(\"The value of the expression {} == {} is {}\\n\", first, second, first **==** second);\r\n\r\nInstead of the expression first < second it must be **first == second** for the 3rd bracket.\r\n\r\n***\r\n\r\nOn **page 277** in **figure 8-1** [missing start value for result]:\r\n\r\n> double result; \r\n\r\nshould be\r\n\r\n> double result { **1.0** };\r\n\r\nResult must start with **1.0**, otherwise the power function will not work properly.\r\n\r\n***\r\n\r\nOn **page 323** [wrong comment]:\r\n\r\n> // Yes, so set to end of text\r\n\r\nshould be\r\n\r\n> // **No** , so set to end of text\r\n\r\nThis if refers to when you did not find a separator, hence **no** is needed, not yes.\r\n\r\n***\r\n\r\nOn **page xx** [Summary of error]:\r\n\r\nDetails of error here. Highlight key pieces in **bold**.\r\n"
  }
]