mirror of
https://github.com/AnthonyCalandra/modern-cpp-features.git
synced 2025-12-17 10:04:35 +03:00
Auto generate readme (#100)
* Auto generate readme provided by @KinglittleQ
This commit is contained in:
23
.github/workflows/main.yml
vendored
Normal file
23
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: auto-generate-readme
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
auto-generate-readme:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v2
|
||||
- name: Install Python3
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- name: Update README
|
||||
run: python auto-generate-readme.py
|
||||
- name: Commit
|
||||
run: |
|
||||
git config --global user.name 'Github Action Bot'
|
||||
git config --global user.email 'bot@example.com'
|
||||
git add -u .
|
||||
git commit -m 'Update README' || echo "No changes to commit"
|
||||
git push origin || echo "No changes to push"
|
||||
@@ -9,10 +9,12 @@ I'm not very picky about how you should contribute, but I ask that the following
|
||||
* Proper spelling and grammar.
|
||||
* If it's a language or library feature that you can write code with, please provide an
|
||||
example of its usage. An optimal submission would also include a short real-world use case for the feature.
|
||||
* Make sure the feature is in the correct C++ version.
|
||||
* Keep additions/deletions of content consistent with the cheatsheet's goals (see below).
|
||||
|
||||
#### Instructions
|
||||
* Make sure the feature is in the correct C++ version file (i.e. CPP11.md, etc.).
|
||||
* Make sure you've added the feature to the table of contents.
|
||||
* Make sure you have also added the feature to the separate major C++ readme files (i.e. CPP11.md, CPP14.md, etc.).
|
||||
* Keep additions/deletions of content consistent with the cheatsheet's goals.
|
||||
* Note: Please don't make changes to README.md itself -- the changes in the individual markdown files are all added to the README automatically.
|
||||
|
||||
## Goals
|
||||
My goal for this cheatsheet is to prefer conciseness over absolute completeness. Examples of features should be minimal: if an example is overly complicated, large, or is more of an obscure usage of the feature then it will most likely be rejected in review. The reason for this goal is to teach users what the most popular uses of these features will be, and for a more thorough investigation, to learn about those from external C++ resources.
|
||||
|
||||
8
CPP11.md
8
CPP11.md
@@ -153,7 +153,7 @@ auto sum(const First first, const Args... args) -> decltype(first) {
|
||||
}
|
||||
|
||||
sum(1, 2, 3, 4, 5); // 15
|
||||
sum(1, 2, 3); // 6
|
||||
sum(1, 2, 3); // 6
|
||||
sum(1.5, 2.0, 3.7); // 7.2
|
||||
```
|
||||
|
||||
@@ -270,7 +270,7 @@ auto add(X x, Y y) -> decltype(x + y) {
|
||||
add(1, 2.0); // `decltype(x + y)` => `decltype(3.0)` => `double`
|
||||
```
|
||||
|
||||
See also: `decltype(auto)` (C++14).
|
||||
See also: [`decltype(auto) (C++14)`](README.md#decltypeauto).
|
||||
|
||||
### Type aliases
|
||||
Semantically similar to using a `typedef` however, type aliases with `using` are easier to read and are compatible with templates.
|
||||
@@ -667,7 +667,7 @@ auto add(T a, U b) -> decltype(a + b) {
|
||||
return a + b;
|
||||
}
|
||||
```
|
||||
In C++14, `decltype(auto)` can be used instead.
|
||||
In C++14, [`decltype(auto) (C++14)`](README.md#decltypeauto) can be used instead.
|
||||
|
||||
### Noexcept specifier
|
||||
The `noexcept` specifier specifies whether a function could throw exceptions. It is an improved version of `throw()`.
|
||||
@@ -779,7 +779,7 @@ void foo(bool clause) { /* do something... */ }
|
||||
|
||||
std::vector<std::thread> threadsVector;
|
||||
threadsVector.emplace_back([]() {
|
||||
// Lambda function that will be invoked
|
||||
// Lambda function that will be invoked
|
||||
});
|
||||
threadsVector.emplace_back(foo, true); // thread will run foo(true)
|
||||
for (auto& thread : threadsVector) {
|
||||
|
||||
4
CPP14.md
4
CPP14.md
@@ -122,7 +122,7 @@ static_assert(std::is_same<int, decltype(f(x))>::value == 1);
|
||||
static_assert(std::is_same<const int&, decltype(g(x))>::value == 1);
|
||||
```
|
||||
|
||||
See also: `decltype` (C++11).
|
||||
See also: [`decltype (C++11)`](README.md#decltype).
|
||||
|
||||
### Relaxing constraints on constexpr functions
|
||||
In C++11, `constexpr` function bodies could only contain a very limited set of syntaxes, including (but not limited to): `typedef`s, `using`s, and a single `return` statement. In C++14, the set of allowable syntaxes expands greatly to include the most common syntax such as `if` statements, multiple `return`s, loops, etc.
|
||||
@@ -198,7 +198,7 @@ The compiler is free to call `new T{}`, then `function_that_throws()`, and so on
|
||||
foo(std::make_unique<T>(), function_that_throws(), std::make_unique<T>());
|
||||
```
|
||||
|
||||
See the C++11 section on smart pointers for more information on `std::unique_ptr` and `std::shared_ptr`.
|
||||
See the section on [smart pointers (C++11)](README.md#smart-pointers) for more information on `std::unique_ptr` and `std::shared_ptr`.
|
||||
|
||||
## Acknowledgements
|
||||
* [cppreference](http://en.cppreference.com/w/cpp) - especially useful for finding examples and documentation of new library features.
|
||||
|
||||
2
CPP17.md
2
CPP17.md
@@ -180,7 +180,7 @@ namespace A::B::C {
|
||||
```
|
||||
|
||||
### Structured bindings
|
||||
A proposal for de-structuring initialization, that would allow writing `auto [ x, y, z ] = expr;` where the type of `expr` was a tuple-like object, whose elements would be bound to the variables `x`, `y`, and `z` (which this construct declares). _Tuple-like objects_ include `std::tuple`, `std::pair`, `std::array`, and aggregate structures.
|
||||
A proposal for de-structuring initialization, that would allow writing `auto [ x, y, z ] = expr;` where the type of `expr` was a tuple-like object, whose elements would be bound to the variables `x`, `y`, and `z` (which this construct declares). _Tuple-like objects_ include [`std::tuple`](README.md#tuples), `std::pair`, [`std::array`](README.md#stdarray), and aggregate structures.
|
||||
```c++
|
||||
using Coordinate = std::pair<int, int>;
|
||||
Coordinate origin() {
|
||||
|
||||
32
README.md
32
README.md
@@ -1,7 +1,7 @@
|
||||
# C++20/17/14/11
|
||||
|
||||
## Overview
|
||||
Many of these descriptions and examples are taken from various resources (see [Acknowledgements](#acknowledgements) section) and summarized in my own words.
|
||||
|
||||
|
||||
C++20 includes the following new language features:
|
||||
- [coroutines](#coroutines)
|
||||
@@ -33,6 +33,7 @@ C++20 includes the following new library features:
|
||||
- [std::midpoint](#stdmidpoint)
|
||||
- [std::to_array](#stdto_array)
|
||||
|
||||
|
||||
C++17 includes the following new language features:
|
||||
- [template argument deduction for class templates](#template-argument-deduction-for-class-templates)
|
||||
- [declaring non-type template parameters with auto](#declaring-non-type-template-parameters-with-auto)
|
||||
@@ -61,6 +62,7 @@ C++17 includes the following new library features:
|
||||
- [splicing for maps and sets](#splicing-for-maps-and-sets)
|
||||
- [parallel algorithms](#parallel-algorithms)
|
||||
|
||||
|
||||
C++14 includes the following new language features:
|
||||
- [binary literals](#binary-literals)
|
||||
- [generic lambda expressions](#generic-lambda-expressions)
|
||||
@@ -76,6 +78,7 @@ C++14 includes the following new library features:
|
||||
- [compile-time integer sequences](#compile-time-integer-sequences)
|
||||
- [std::make_unique](#stdmake_unique)
|
||||
|
||||
|
||||
C++11 includes the following new language features:
|
||||
- [move semantics](#move-semantics)
|
||||
- [variadic templates](#variadic-templates)
|
||||
@@ -128,6 +131,8 @@ C++11 includes the following new library features:
|
||||
- [std::async](#stdasync)
|
||||
- [std::begin/end](#stdbeginend)
|
||||
|
||||
|
||||
|
||||
## C++20 Language Features
|
||||
|
||||
### Coroutines
|
||||
@@ -353,7 +358,7 @@ auto f = []<typename T>(std::vector<T> v) {
|
||||
### Range-based for loop with initializer
|
||||
This feature simplifies common code patterns, helps keep scopes tight, and offers an elegant solution to a common lifetime problem.
|
||||
```c++
|
||||
for (std::vector v{1, 2, 3}; auto& e : v) {
|
||||
for (auto v = std::vector{1, 2, 3}; auto& e : v) {
|
||||
std::cout << e;
|
||||
}
|
||||
// prints "123"
|
||||
@@ -960,7 +965,7 @@ void my_callback(std::string msg, [[maybe_unused]] bool error) {
|
||||
### std::variant
|
||||
The class template `std::variant` represents a type-safe `union`. An instance of `std::variant` at any given time holds a value of one of its alternative types (it's also possible for it to be valueless).
|
||||
```c++
|
||||
std::variant<int, double> v {12};
|
||||
std::variant<int, double> v{ 12 };
|
||||
std::get<int>(v); // == 12
|
||||
std::get<0>(v); // == 12
|
||||
v = 12.0;
|
||||
@@ -1228,7 +1233,7 @@ static_assert(std::is_same<int, decltype(f(x))>::value == 1);
|
||||
static_assert(std::is_same<const int&, decltype(g(x))>::value == 1);
|
||||
```
|
||||
|
||||
See also: [`decltype`](#decltype).
|
||||
See also: [`decltype (C++11)`](#decltype).
|
||||
|
||||
### Relaxing constraints on constexpr functions
|
||||
In C++11, `constexpr` function bodies could only contain a very limited set of syntaxes, including (but not limited to): `typedef`s, `using`s, and a single `return` statement. In C++14, the set of allowable syntaxes expands greatly to include the most common syntax such as `if` statements, multiple `return`s, loops, etc.
|
||||
@@ -1258,7 +1263,6 @@ C++14 introduces the `[[deprecated]]` attribute to indicate that a unit (functio
|
||||
```c++
|
||||
[[deprecated]]
|
||||
void old_method();
|
||||
|
||||
[[deprecated("Use new_method instead")]]
|
||||
void legacy_method();
|
||||
```
|
||||
@@ -1305,7 +1309,7 @@ The compiler is free to call `new T{}`, then `function_that_throws()`, and so on
|
||||
foo(std::make_unique<T>(), function_that_throws(), std::make_unique<T>());
|
||||
```
|
||||
|
||||
See the section on [smart pointers](#smart-pointers) for more information on `std::unique_ptr` and `std::shared_ptr`.
|
||||
See the section on [smart pointers (C++11)](#smart-pointers) for more information on `std::unique_ptr` and `std::shared_ptr`.
|
||||
|
||||
## C++11 Language Features
|
||||
|
||||
@@ -1522,7 +1526,7 @@ auto add(X x, Y y) -> decltype(x + y) {
|
||||
add(1, 2.0); // `decltype(x + y)` => `decltype(3.0)` => `double`
|
||||
```
|
||||
|
||||
See also: [`decltype(auto)`](#decltypeauto).
|
||||
See also: [`decltype(auto) (C++14)`](#decltypeauto).
|
||||
|
||||
### Type aliases
|
||||
Semantically similar to using a `typedef` however, type aliases with `using` are easier to read and are compatible with templates.
|
||||
@@ -1873,7 +1877,6 @@ struct Foo {
|
||||
Bar getBar() & { return bar; }
|
||||
Bar getBar() const& { return bar; }
|
||||
Bar getBar() && { return std::move(bar); }
|
||||
Bar getBar() const&& { return std::move(bar); }
|
||||
private:
|
||||
Bar bar;
|
||||
};
|
||||
@@ -1920,7 +1923,7 @@ auto add(T a, U b) -> decltype(a + b) {
|
||||
return a + b;
|
||||
}
|
||||
```
|
||||
In C++14, [decltype(auto)](#decltypeauto) can be used instead.
|
||||
In C++14, [`decltype(auto) (C++14)`](#decltypeauto) can be used instead.
|
||||
|
||||
### Noexcept specifier
|
||||
The `noexcept` specifier specifies whether a function could throw exceptions. It is an improved version of `throw()`.
|
||||
@@ -1986,7 +1989,7 @@ typename remove_reference<T>::type&& move(T&& arg) {
|
||||
|
||||
Transferring `std::unique_ptr`s:
|
||||
```c++
|
||||
std::unique_ptr<int> p1 {new int{0}}; // in practice, use std::make_unique
|
||||
std::unique_ptr<int> p1 {new int{0}}; // in practice, use std::make_unique
|
||||
std::unique_ptr<int> p2 = p1; // error -- cannot copy unique pointers
|
||||
std::unique_ptr<int> p3 = std::move(p1); // move `p1` into `p3`
|
||||
// now unsafe to dereference object held by `p1`
|
||||
@@ -2058,9 +2061,9 @@ static_assert(std::is_same<std::conditional<true, int, double>::type, int>::valu
|
||||
### Smart pointers
|
||||
C++11 introduces new smart pointers: `std::unique_ptr`, `std::shared_ptr`, `std::weak_ptr`. `std::auto_ptr` now becomes deprecated and then eventually removed in C++17.
|
||||
|
||||
`std::unique_ptr` is a non-copyable, movable pointer that manages its own heap-allocated memory. **Note: Prefer using the `std::make_X` helper functions as opposed to using constructors. See the sections for [std::make_unique](#stdmake_unique) and [std::make_shared](#stdmake_shared).**
|
||||
`std::unique_ptr` is a non-copyable, movable pointer that manages its own heap-allocated memory. **Note: Prefer using the `std::make_X` helper functions as opposed to using constructors. See the sections for [std::make_unique](https://github.com/AnthonyCalandra/modern-cpp-features/blob/master/CPP14.md#stdmake_unique) and [std::make_shared](#stdmake_shared).**
|
||||
```c++
|
||||
std::unique_ptr<Foo> p1 {new Foo{}}; // `p1` owns `Foo`
|
||||
std::unique_ptr<Foo> p1 { new Foo{} }; // `p1` owns `Foo`
|
||||
if (p1) {
|
||||
p1->bar();
|
||||
}
|
||||
@@ -2221,16 +2224,17 @@ auto a = CountTwos(vec); // 2
|
||||
auto b = CountTwos(arr); // 1
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Acknowledgements
|
||||
* [cppreference](http://en.cppreference.com/w/cpp) - especially useful for finding examples and documentation of new library features.
|
||||
* [C++ Rvalue References Explained](http://thbecker.net/articles/rvalue_references/section_01.html) - a great introduction I used to understand rvalue references, perfect forwarding, and move semantics.
|
||||
* [clang](http://clang.llvm.org/cxx_status.html) and [gcc](https://gcc.gnu.org/projects/cxx-status.html)'s standards support pages. Also included here are the proposals for language/library features that I used to help find a description of, what it's meant to fix, and some examples.
|
||||
* [Compiler explorer](https://godbolt.org/)
|
||||
* [Scott Meyers' Effective Modern C++](https://www.amazon.com/Effective-Modern-Specific-Ways-Improve/dp/1491903996) - highly recommended book!
|
||||
* [Scott Meyers' Effective Modern C++](https://www.amazon.com/Effective-Modern-Specific-Ways-Improve/dp/1491903996) - highly recommended series of books!
|
||||
* [Jason Turner's C++ Weekly](https://www.youtube.com/channel/UCxHAlbZQNFU2LgEtiqd2Maw) - nice collection of C++-related videos.
|
||||
* [What can I do with a moved-from object?](http://stackoverflow.com/questions/7027523/what-can-i-do-with-a-moved-from-object)
|
||||
* [What are some uses of decltype(auto)?](http://stackoverflow.com/questions/24109737/what-are-some-uses-of-decltypeauto)
|
||||
* And many more SO posts I'm forgetting...
|
||||
|
||||
## Author
|
||||
Anthony Calandra
|
||||
|
||||
89
auto-generate-readme.py
Normal file
89
auto-generate-readme.py
Normal file
@@ -0,0 +1,89 @@
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class MarkdownParser():
|
||||
|
||||
def __init__(self, text):
|
||||
self.text = text
|
||||
self.lines = text.split('\n')
|
||||
|
||||
def title(self):
|
||||
return self.lines[0].split(' ')[1]
|
||||
|
||||
def header(self, name, level, include_header=False):
|
||||
start = False
|
||||
end = False
|
||||
content = []
|
||||
mark = '#' * level
|
||||
for line in self.lines:
|
||||
if start and not end:
|
||||
end |= (f'{mark} ' in line[:(level + 1)]) and (not f'{mark} {name}' in line)
|
||||
if end:
|
||||
start = False
|
||||
else:
|
||||
content.append(line)
|
||||
else:
|
||||
start = (f'{mark} {name}' in line)
|
||||
if start:
|
||||
end = False
|
||||
if include_header:
|
||||
content.append(line)
|
||||
|
||||
content = '\n'.join(content)
|
||||
return content
|
||||
|
||||
def overview(self):
|
||||
overview = self.header('Overview', 2)
|
||||
overview = overview.split('\n')
|
||||
overview = '\n'.join(overview[1:]) # remove the first line
|
||||
return overview
|
||||
|
||||
def features(self):
|
||||
return self.header('C++', 2, True)
|
||||
|
||||
|
||||
def combine(text, parsers):
|
||||
overview = ''
|
||||
features = ''
|
||||
title = ''
|
||||
for p in parsers:
|
||||
title += p.title().replace('C++', '') + '/'
|
||||
overview += p.overview() + '\n'
|
||||
features += p.features() + '\n'
|
||||
|
||||
title = title[:-1]
|
||||
overview = overview.replace('README.md#', '#')
|
||||
features = features.replace('README.md#', '#')
|
||||
|
||||
text = text.replace('# C++\n', f'# C++{title}\n')
|
||||
text = text.replace(f'<!-- overview -->', overview)
|
||||
text = text.replace(f'<!-- features -->', features)
|
||||
|
||||
return text
|
||||
|
||||
|
||||
def main():
|
||||
src_dir = Path(__file__).parent
|
||||
parsers = []
|
||||
|
||||
srcs = list(src_dir.glob('CPP*.md'))
|
||||
srcs.sort(reverse=True)
|
||||
for file in srcs:
|
||||
with open(file, 'r') as fp:
|
||||
text = fp.read()
|
||||
p = MarkdownParser(text)
|
||||
parsers.append(p)
|
||||
|
||||
template_file = src_dir / 'readme-template.md'
|
||||
with open(template_file, 'r') as fp:
|
||||
text = fp.read()
|
||||
|
||||
text = combine(text, parsers)
|
||||
|
||||
readme_file = src_dir / 'README.md'
|
||||
with open(readme_file, 'w') as fp:
|
||||
fp.write(text)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
26
readme-template.md
Normal file
26
readme-template.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# C++
|
||||
|
||||
## Overview
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
<!-- features -->
|
||||
|
||||
## Acknowledgements
|
||||
* [cppreference](http://en.cppreference.com/w/cpp) - especially useful for finding examples and documentation of new library features.
|
||||
* [C++ Rvalue References Explained](http://thbecker.net/articles/rvalue_references/section_01.html) - a great introduction I used to understand rvalue references, perfect forwarding, and move semantics.
|
||||
* [clang](http://clang.llvm.org/cxx_status.html) and [gcc](https://gcc.gnu.org/projects/cxx-status.html)'s standards support pages. Also included here are the proposals for language/library features that I used to help find a description of, what it's meant to fix, and some examples.
|
||||
* [Compiler explorer](https://godbolt.org/)
|
||||
* [Scott Meyers' Effective Modern C++](https://www.amazon.com/Effective-Modern-Specific-Ways-Improve/dp/1491903996) - highly recommended series of books!
|
||||
* [Jason Turner's C++ Weekly](https://www.youtube.com/channel/UCxHAlbZQNFU2LgEtiqd2Maw) - nice collection of C++-related videos.
|
||||
* [What can I do with a moved-from object?](http://stackoverflow.com/questions/7027523/what-can-i-do-with-a-moved-from-object)
|
||||
* [What are some uses of decltype(auto)?](http://stackoverflow.com/questions/24109737/what-are-some-uses-of-decltypeauto)
|
||||
|
||||
## Author
|
||||
Anthony Calandra
|
||||
|
||||
## Content Contributors
|
||||
See: https://github.com/AnthonyCalandra/modern-cpp-features/graphs/contributors
|
||||
|
||||
## License
|
||||
MIT
|
||||
Reference in New Issue
Block a user