Initial Course
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
add_course_exercise(NAME expected MODULE 13_cpp23 STANDARD 23
|
||||
SOURCES src/expected.cpp test/expected_test.cpp)
|
||||
add_course_exercise(NAME print_and_format MODULE 13_cpp23 STANDARD 23
|
||||
SOURCES src/print_and_format.cpp test/print_and_format_test.cpp)
|
||||
add_course_exercise(NAME mdspan MODULE 13_cpp23 STANDARD 23
|
||||
SOURCES src/mdspan.cpp test/mdspan_test.cpp)
|
||||
add_course_exercise(NAME ranges_zip MODULE 13_cpp23 STANDARD 23
|
||||
SOURCES src/ranges_zip.cpp test/ranges_zip_test.cpp)
|
||||
@@ -0,0 +1,17 @@
|
||||
# Module 13: C++23 Library Additions
|
||||
|
||||
## Learning Goals
|
||||
|
||||
- Handle expected success/failure with `std::expected`
|
||||
- Format and print text with `<format>` and `<print>`
|
||||
- Work with multidimensional data using `std::mdspan`
|
||||
- Combine ranges with `views::zip` and `views::chunk`
|
||||
|
||||
## Exercises
|
||||
|
||||
| Exercise | Feature |
|
||||
|----------|---------|
|
||||
| `expected` | std::expected error handling |
|
||||
| `print_and_format` | std::format and std::print |
|
||||
| `mdspan` | Multidimensional spans |
|
||||
| `ranges_zip` | zip, chunk, adjacent views |
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
namespace cpp23 {
|
||||
|
||||
enum class ParseError { EmptyInput, InvalidNumber };
|
||||
|
||||
[[nodiscard]] auto parse_int(const std::string& text) -> std::expected<int, ParseError>;
|
||||
[[nodiscard]] auto safe_sqrt(int value) -> std::expected<double, std::string>;
|
||||
[[nodiscard]] auto chain_parse_and_double(const std::string& text) -> std::expected<int, ParseError>;
|
||||
|
||||
} // namespace cpp23
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <mdspan>
|
||||
#include <span>
|
||||
#include <vector>
|
||||
|
||||
namespace cpp23 {
|
||||
|
||||
[[nodiscard]] auto make_row_major_matrix(int rows, int cols, int fill) -> std::vector<int>;
|
||||
[[nodiscard]] auto matrix_element(std::mdspan<const int, std::extents<int, std::dynamic_extent, std::dynamic_extent>> matrix,
|
||||
int row, int col) -> int;
|
||||
[[nodiscard]] auto row_sums(std::mdspan<const int, std::extents<int, std::dynamic_extent, std::dynamic_extent>> matrix)
|
||||
-> std::vector<int>;
|
||||
|
||||
} // namespace cpp23
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace cpp23 {
|
||||
|
||||
[[nodiscard]] auto format_greeting(const std::string& name, int score) -> std::string;
|
||||
[[nodiscard]] auto format_table_row(const std::vector<std::string>& columns) -> std::string;
|
||||
[[nodiscard]] auto format_hex(std::uint32_t value) -> std::string;
|
||||
|
||||
} // namespace cpp23
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <ranges>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace cpp23 {
|
||||
|
||||
[[nodiscard]] auto zip_sum(const std::vector<int>& a, const std::vector<int>& b) -> std::vector<int>;
|
||||
[[nodiscard]] auto chunk_strings(const std::vector<std::string>& words, std::size_t chunk_size)
|
||||
-> std::vector<std::vector<std::string>>;
|
||||
[[nodiscard]] auto adjacent_differences(const std::vector<int>& data) -> std::vector<int>;
|
||||
|
||||
} // namespace cpp23
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "expected.hpp"
|
||||
|
||||
namespace cpp23 {
|
||||
|
||||
auto parse_int(const std::string& text) -> std::expected<int, ParseError> {
|
||||
(void)text;
|
||||
return std::unexpected(ParseError::EmptyInput);
|
||||
}
|
||||
|
||||
auto safe_sqrt(int value) -> std::expected<double, std::string> {
|
||||
(void)value;
|
||||
return std::unexpected(std::string{"negative"});
|
||||
}
|
||||
|
||||
auto chain_parse_and_double(const std::string& text) -> std::expected<int, ParseError> {
|
||||
(void)text;
|
||||
return std::unexpected(ParseError::InvalidNumber);
|
||||
}
|
||||
|
||||
} // namespace cpp23
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "mdspan.hpp"
|
||||
|
||||
namespace cpp23 {
|
||||
|
||||
auto make_row_major_matrix(int rows, int cols, int fill) -> std::vector<int> {
|
||||
(void)rows; (void)cols; (void)fill;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto matrix_element(
|
||||
std::mdspan<const int, std::extents<int, std::dynamic_extent, std::dynamic_extent>> matrix,
|
||||
int row, int col) -> int {
|
||||
(void)matrix; (void)row; (void)col;
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto row_sums(
|
||||
std::mdspan<const int, std::extents<int, std::dynamic_extent, std::dynamic_extent>> matrix)
|
||||
-> std::vector<int> {
|
||||
(void)matrix;
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace cpp23
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "print_and_format.hpp"
|
||||
|
||||
namespace cpp23 {
|
||||
|
||||
auto format_greeting(const std::string& name, int score) -> std::string {
|
||||
(void)name; (void)score;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto format_table_row(const std::vector<std::string>& columns) -> std::string {
|
||||
(void)columns;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto format_hex(std::uint32_t value) -> std::string {
|
||||
(void)value;
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace cpp23
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "ranges_zip.hpp"
|
||||
|
||||
namespace cpp23 {
|
||||
|
||||
auto zip_sum(const std::vector<int>& a, const std::vector<int>& b) -> std::vector<int> {
|
||||
(void)a; (void)b;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto chunk_strings(const std::vector<std::string>& words, std::size_t chunk_size)
|
||||
-> std::vector<std::vector<std::string>> {
|
||||
(void)words; (void)chunk_size;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto adjacent_differences(const std::vector<int>& data) -> std::vector<int> {
|
||||
(void)data;
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace cpp23
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "expected.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(Expected, ParseInt) {
|
||||
EXPECT_EQ(*cpp23::parse_int("42"), 42);
|
||||
EXPECT_EQ(cpp23::parse_int(""), std::unexpected(cpp23::ParseError::EmptyInput));
|
||||
}
|
||||
|
||||
TEST(Expected, SafeSqrt) {
|
||||
EXPECT_DOUBLE_EQ(*cpp23::safe_sqrt(9), 3.0);
|
||||
EXPECT_FALSE(cpp23::safe_sqrt(-1).has_value());
|
||||
}
|
||||
|
||||
TEST(Expected, ChainParseAndDouble) {
|
||||
EXPECT_EQ(*cpp23::chain_parse_and_double("21"), 42);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "mdspan.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(Mdspan, MatrixElement) {
|
||||
auto storage = cpp23::make_row_major_matrix(2, 3, 1);
|
||||
const auto matrix = std::mdspan<const int, std::extents<int, std::dynamic_extent, std::dynamic_extent>>(
|
||||
storage.data(), 2, 3);
|
||||
EXPECT_EQ(cpp23::matrix_element(matrix, 1, 2), 1);
|
||||
}
|
||||
|
||||
TEST(Mdspan, RowSums) {
|
||||
std::vector<int> storage = {1, 2, 3, 4, 5, 6};
|
||||
const auto matrix = std::mdspan<const int, std::extents<int, std::dynamic_extent, std::dynamic_extent>>(
|
||||
storage.data(), 2, 3);
|
||||
EXPECT_EQ(cpp23::row_sums(matrix), (std::vector<int>{6, 15}));
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "print_and_format.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(PrintAndFormat, FormatGreeting) {
|
||||
EXPECT_EQ(cpp23::format_greeting("Ada", 100), "Ada scored 100 points");
|
||||
}
|
||||
|
||||
TEST(PrintAndFormat, FormatTableRow) {
|
||||
EXPECT_EQ(cpp23::format_table_row({"A", "B", "C"}), "A | B | C");
|
||||
}
|
||||
|
||||
TEST(PrintAndFormat, FormatHex) {
|
||||
EXPECT_EQ(cpp23::format_hex(255), "0xFF");
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "ranges_zip.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(RangesZip, ZipSum) {
|
||||
EXPECT_EQ(cpp23::zip_sum({1, 2, 3}, {4, 5, 6}), (std::vector<int>{5, 7, 9}));
|
||||
}
|
||||
|
||||
TEST(RangesZip, ChunkStrings) {
|
||||
EXPECT_EQ(cpp23::chunk_strings({"a", "b", "c", "d"}, 2),
|
||||
(std::vector<std::vector<std::string>>{{"a", "b"}, {"c", "d"}}));
|
||||
}
|
||||
|
||||
TEST(RangesZip, AdjacentDifferences) {
|
||||
EXPECT_EQ(cpp23::adjacent_differences({1, 4, 9, 16}), (std::vector<int>{3, 5, 7}));
|
||||
}
|
||||
Reference in New Issue
Block a user