Skip to content

Commit 1343f5e

Browse files
authored
Auto generate readme (AnthonyCalandra#100)
* Auto generate readme provided by @KinglittleQ
1 parent c72f279 commit 1343f5e

File tree

8 files changed

+168
-24
lines changed

8 files changed

+168
-24
lines changed

.github/workflows/main.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: auto-generate-readme
2+
on:
3+
push:
4+
5+
jobs:
6+
auto-generate-readme:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- name: Check out repository code
10+
uses: actions/checkout@v2
11+
- name: Install Python3
12+
uses: actions/setup-python@v2
13+
with:
14+
python-version: '3.7'
15+
- name: Update README
16+
run: python auto-generate-readme.py
17+
- name: Commit
18+
run: |
19+
git config --global user.name 'Github Action Bot'
20+
git config --global user.email '[email protected]'
21+
git add -u .
22+
git commit -m 'Update README' || echo "No changes to commit"
23+
git push origin || echo "No changes to push"

CONTRIBUTING.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ I'm not very picky about how you should contribute, but I ask that the following
99
* Proper spelling and grammar.
1010
* If it's a language or library feature that you can write code with, please provide an
1111
example of its usage. An optimal submission would also include a short real-world use case for the feature.
12-
* Make sure the feature is in the correct C++ version.
12+
* Keep additions/deletions of content consistent with the cheatsheet's goals (see below).
13+
14+
#### Instructions
15+
* Make sure the feature is in the correct C++ version file (i.e. CPP11.md, etc.).
1316
* Make sure you've added the feature to the table of contents.
14-
* Make sure you have also added the feature to the separate major C++ readme files (i.e. CPP11.md, CPP14.md, etc.).
15-
* Keep additions/deletions of content consistent with the cheatsheet's goals.
17+
* Note: Please don't make changes to README.md itself -- the changes in the individual markdown files are all added to the README automatically.
1618

1719
## Goals
1820
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.

CPP11.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ auto sum(const First first, const Args... args) -> decltype(first) {
153153
}
154154

155155
sum(1, 2, 3, 4, 5); // 15
156-
sum(1, 2, 3); // 6
156+
sum(1, 2, 3); // 6
157157
sum(1.5, 2.0, 3.7); // 7.2
158158
```
159159
@@ -270,7 +270,7 @@ auto add(X x, Y y) -> decltype(x + y) {
270270
add(1, 2.0); // `decltype(x + y)` => `decltype(3.0)` => `double`
271271
```
272272
273-
See also: `decltype(auto)` (C++14).
273+
See also: [`decltype(auto) (C++14)`](README.md#decltypeauto).
274274
275275
### Type aliases
276276
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) {
667667
return a + b;
668668
}
669669
```
670-
In C++14, `decltype(auto)` can be used instead.
670+
In C++14, [`decltype(auto) (C++14)`](README.md#decltypeauto) can be used instead.
671671
672672
### Noexcept specifier
673673
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... */ }
779779
780780
std::vector<std::thread> threadsVector;
781781
threadsVector.emplace_back([]() {
782-
// Lambda function that will be invoked
782+
// Lambda function that will be invoked
783783
});
784784
threadsVector.emplace_back(foo, true); // thread will run foo(true)
785785
for (auto& thread : threadsVector) {

CPP14.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static_assert(std::is_same<int, decltype(f(x))>::value == 1);
122122
static_assert(std::is_same<const int&, decltype(g(x))>::value == 1);
123123
```
124124

125-
See also: `decltype` (C++11).
125+
See also: [`decltype (C++11)`](README.md#decltype).
126126

127127
### Relaxing constraints on constexpr functions
128128
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
198198
foo(std::make_unique<T>(), function_that_throws(), std::make_unique<T>());
199199
```
200200

201-
See the C++11 section on smart pointers for more information on `std::unique_ptr` and `std::shared_ptr`.
201+
See the section on [smart pointers (C++11)](README.md#smart-pointers) for more information on `std::unique_ptr` and `std::shared_ptr`.
202202

203203
## Acknowledgements
204204
* [cppreference](http://en.cppreference.com/w/cpp) - especially useful for finding examples and documentation of new library features.

CPP17.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ namespace A::B::C {
180180
```
181181
182182
### Structured bindings
183-
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.
183+
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.
184184
```c++
185185
using Coordinate = std::pair<int, int>;
186186
Coordinate origin() {

README.md

+18-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# C++20/17/14/11
22

33
## Overview
4-
Many of these descriptions and examples are taken from various resources (see [Acknowledgements](#acknowledgements) section) and summarized in my own words.
4+
55

66
C++20 includes the following new language features:
77
- [coroutines](#coroutines)
@@ -33,6 +33,7 @@ C++20 includes the following new library features:
3333
- [std::midpoint](#stdmidpoint)
3434
- [std::to_array](#stdto_array)
3535

36+
3637
C++17 includes the following new language features:
3738
- [template argument deduction for class templates](#template-argument-deduction-for-class-templates)
3839
- [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:
6162
- [splicing for maps and sets](#splicing-for-maps-and-sets)
6263
- [parallel algorithms](#parallel-algorithms)
6364

65+
6466
C++14 includes the following new language features:
6567
- [binary literals](#binary-literals)
6668
- [generic lambda expressions](#generic-lambda-expressions)
@@ -76,6 +78,7 @@ C++14 includes the following new library features:
7678
- [compile-time integer sequences](#compile-time-integer-sequences)
7779
- [std::make_unique](#stdmake_unique)
7880

81+
7982
C++11 includes the following new language features:
8083
- [move semantics](#move-semantics)
8184
- [variadic templates](#variadic-templates)
@@ -128,6 +131,8 @@ C++11 includes the following new library features:
128131
- [std::async](#stdasync)
129132
- [std::begin/end](#stdbeginend)
130133

134+
135+
131136
## C++20 Language Features
132137

133138
### Coroutines
@@ -353,7 +358,7 @@ auto f = []<typename T>(std::vector<T> v) {
353358
### Range-based for loop with initializer
354359
This feature simplifies common code patterns, helps keep scopes tight, and offers an elegant solution to a common lifetime problem.
355360
```c++
356-
for (std::vector v{1, 2, 3}; auto& e : v) {
361+
for (auto v = std::vector{1, 2, 3}; auto& e : v) {
357362
std::cout << e;
358363
}
359364
// prints "123"
@@ -960,7 +965,7 @@ void my_callback(std::string msg, [[maybe_unused]] bool error) {
960965
### std::variant
961966
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).
962967
```c++
963-
std::variant<int, double> v {12};
968+
std::variant<int, double> v{ 12 };
964969
std::get<int>(v); // == 12
965970
std::get<0>(v); // == 12
966971
v = 12.0;
@@ -1228,7 +1233,7 @@ static_assert(std::is_same<int, decltype(f(x))>::value == 1);
12281233
static_assert(std::is_same<const int&, decltype(g(x))>::value == 1);
12291234
```
12301235

1231-
See also: [`decltype`](#decltype).
1236+
See also: [`decltype (C++11)`](#decltype).
12321237

12331238
### Relaxing constraints on constexpr functions
12341239
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
12581263
```c++
12591264
[[deprecated]]
12601265
void old_method();
1261-
12621266
[[deprecated("Use new_method instead")]]
12631267
void legacy_method();
12641268
```
@@ -1305,7 +1309,7 @@ The compiler is free to call `new T{}`, then `function_that_throws()`, and so on
13051309
foo(std::make_unique<T>(), function_that_throws(), std::make_unique<T>());
13061310
```
13071311

1308-
See the section on [smart pointers](#smart-pointers) for more information on `std::unique_ptr` and `std::shared_ptr`.
1312+
See the section on [smart pointers (C++11)](#smart-pointers) for more information on `std::unique_ptr` and `std::shared_ptr`.
13091313

13101314
## C++11 Language Features
13111315

@@ -1522,7 +1526,7 @@ auto add(X x, Y y) -> decltype(x + y) {
15221526
add(1, 2.0); // `decltype(x + y)` => `decltype(3.0)` => `double`
15231527
```
15241528
1525-
See also: [`decltype(auto)`](#decltypeauto).
1529+
See also: [`decltype(auto) (C++14)`](#decltypeauto).
15261530
15271531
### Type aliases
15281532
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 {
18731877
Bar getBar() & { return bar; }
18741878
Bar getBar() const& { return bar; }
18751879
Bar getBar() && { return std::move(bar); }
1876-
Bar getBar() const&& { return std::move(bar); }
18771880
private:
18781881
Bar bar;
18791882
};
@@ -1920,7 +1923,7 @@ auto add(T a, U b) -> decltype(a + b) {
19201923
return a + b;
19211924
}
19221925
```
1923-
In C++14, [decltype(auto)](#decltypeauto) can be used instead.
1926+
In C++14, [`decltype(auto) (C++14)`](#decltypeauto) can be used instead.
19241927
19251928
### Noexcept specifier
19261929
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) {
19861989

19871990
Transferring `std::unique_ptr`s:
19881991
```c++
1989-
std::unique_ptr<int> p1 {new int{0}}; // in practice, use std::make_unique
1992+
std::unique_ptr<int> p1 {new int{0}}; // in practice, use std::make_unique
19901993
std::unique_ptr<int> p2 = p1; // error -- cannot copy unique pointers
19911994
std::unique_ptr<int> p3 = std::move(p1); // move `p1` into `p3`
19921995
// 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
20582061
### Smart pointers
20592062
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.
20602063

2061-
`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).**
2064+
`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).**
20622065
```c++
2063-
std::unique_ptr<Foo> p1 {new Foo{}}; // `p1` owns `Foo`
2066+
std::unique_ptr<Foo> p1 { new Foo{} }; // `p1` owns `Foo`
20642067
if (p1) {
20652068
p1->bar();
20662069
}
@@ -2221,16 +2224,17 @@ auto a = CountTwos(vec); // 2
22212224
auto b = CountTwos(arr); // 1
22222225
```
22232226
2227+
2228+
22242229
## Acknowledgements
22252230
* [cppreference](http://en.cppreference.com/w/cpp) - especially useful for finding examples and documentation of new library features.
22262231
* [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.
22272232
* [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.
22282233
* [Compiler explorer](https://godbolt.org/)
2229-
* [Scott Meyers' Effective Modern C++](https://www.amazon.com/Effective-Modern-Specific-Ways-Improve/dp/1491903996) - highly recommended book!
2234+
* [Scott Meyers' Effective Modern C++](https://www.amazon.com/Effective-Modern-Specific-Ways-Improve/dp/1491903996) - highly recommended series of books!
22302235
* [Jason Turner's C++ Weekly](https://www.youtube.com/channel/UCxHAlbZQNFU2LgEtiqd2Maw) - nice collection of C++-related videos.
22312236
* [What can I do with a moved-from object?](http://stackoverflow.com/questions/7027523/what-can-i-do-with-a-moved-from-object)
22322237
* [What are some uses of decltype(auto)?](http://stackoverflow.com/questions/24109737/what-are-some-uses-of-decltypeauto)
2233-
* And many more SO posts I'm forgetting...
22342238
22352239
## Author
22362240
Anthony Calandra

auto-generate-readme.py

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from pathlib import Path
2+
3+
4+
class MarkdownParser():
5+
6+
def __init__(self, text):
7+
self.text = text
8+
self.lines = text.split('\n')
9+
10+
def title(self):
11+
return self.lines[0].split(' ')[1]
12+
13+
def header(self, name, level, include_header=False):
14+
start = False
15+
end = False
16+
content = []
17+
mark = '#' * level
18+
for line in self.lines:
19+
if start and not end:
20+
end |= (f'{mark} ' in line[:(level + 1)]) and (not f'{mark} {name}' in line)
21+
if end:
22+
start = False
23+
else:
24+
content.append(line)
25+
else:
26+
start = (f'{mark} {name}' in line)
27+
if start:
28+
end = False
29+
if include_header:
30+
content.append(line)
31+
32+
content = '\n'.join(content)
33+
return content
34+
35+
def overview(self):
36+
overview = self.header('Overview', 2)
37+
overview = overview.split('\n')
38+
overview = '\n'.join(overview[1:]) # remove the first line
39+
return overview
40+
41+
def features(self):
42+
return self.header('C++', 2, True)
43+
44+
45+
def combine(text, parsers):
46+
overview = ''
47+
features = ''
48+
title = ''
49+
for p in parsers:
50+
title += p.title().replace('C++', '') + '/'
51+
overview += p.overview() + '\n'
52+
features += p.features() + '\n'
53+
54+
title = title[:-1]
55+
overview = overview.replace('README.md#', '#')
56+
features = features.replace('README.md#', '#')
57+
58+
text = text.replace('# C++\n', f'# C++{title}\n')
59+
text = text.replace(f'<!-- overview -->', overview)
60+
text = text.replace(f'<!-- features -->', features)
61+
62+
return text
63+
64+
65+
def main():
66+
src_dir = Path(__file__).parent
67+
parsers = []
68+
69+
srcs = list(src_dir.glob('CPP*.md'))
70+
srcs.sort(reverse=True)
71+
for file in srcs:
72+
with open(file, 'r') as fp:
73+
text = fp.read()
74+
p = MarkdownParser(text)
75+
parsers.append(p)
76+
77+
template_file = src_dir / 'readme-template.md'
78+
with open(template_file, 'r') as fp:
79+
text = fp.read()
80+
81+
text = combine(text, parsers)
82+
83+
readme_file = src_dir / 'README.md'
84+
with open(readme_file, 'w') as fp:
85+
fp.write(text)
86+
87+
88+
if __name__ == '__main__':
89+
main()

readme-template.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# C++
2+
3+
## Overview
4+
5+
<!-- overview -->
6+
7+
<!-- features -->
8+
9+
## Acknowledgements
10+
* [cppreference](http://en.cppreference.com/w/cpp) - especially useful for finding examples and documentation of new library features.
11+
* [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.
12+
* [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.
13+
* [Compiler explorer](https://godbolt.org/)
14+
* [Scott Meyers' Effective Modern C++](https://www.amazon.com/Effective-Modern-Specific-Ways-Improve/dp/1491903996) - highly recommended series of books!
15+
* [Jason Turner's C++ Weekly](https://www.youtube.com/channel/UCxHAlbZQNFU2LgEtiqd2Maw) - nice collection of C++-related videos.
16+
* [What can I do with a moved-from object?](http://stackoverflow.com/questions/7027523/what-can-i-do-with-a-moved-from-object)
17+
* [What are some uses of decltype(auto)?](http://stackoverflow.com/questions/24109737/what-are-some-uses-of-decltypeauto)
18+
19+
## Author
20+
Anthony Calandra
21+
22+
## Content Contributors
23+
See: https://github.com/AnthonyCalandra/modern-cpp-features/graphs/contributors
24+
25+
## License
26+
MIT

0 commit comments

Comments
 (0)