├── .github ├── ISSUE_TEMPLATE │ └── topic-proposal.md └── workflows │ ├── ci.yml │ ├── ci_tool_tests.yml │ └── release.yml ├── .gitignore ├── .mailmap ├── LICENSE.txt ├── Makefile ├── README.md ├── config ├── pandoc_templates │ ├── bootstrap_menu.html │ ├── clean_menu.html │ ├── easy_template.html │ ├── elegant_bootstrap_menu.html │ └── uikit.html └── spellcheck │ ├── ignored_words.txt │ └── wordlist ├── skeleton.md ├── sources ├── Makefile ├── contributing.md ├── css │ ├── default-pandoc.css │ ├── elegant_bootstrap.css │ ├── epub.css │ └── github-pandoc.css ├── glossary.md ├── images │ └── cpp_logo.png ├── index.html ├── introduction.md ├── knowledge_areas.dat ├── main_raw.md ├── modules │ ├── compilation-model │ │ ├── buildsystems.md │ │ ├── linkage.md │ │ └── translation-units.md │ ├── compile-time-programming │ │ ├── concepts.md │ │ ├── function-templates.md │ │ ├── requires-clause.md │ │ └── requires-expressions.md │ ├── debugging-errors │ │ ├── build-errors.md │ │ ├── compiletime-errors.md │ │ └── runtime-errors.md │ ├── error-handling │ │ ├── c-style-error-codes.md │ │ ├── categories-of-errors.md │ │ ├── error-codes.md │ │ ├── exception-handling.md │ │ └── static-assert.md │ ├── functions │ │ ├── calling-functions.md │ │ ├── defaulted-parameters.md │ │ ├── member-functions.md │ │ ├── passing-parameters-by-reference.md │ │ ├── passing-parameters-by-value.md │ │ └── user-defined-literals.md │ ├── meta-error-handling │ │ └── static_assert.md │ ├── object-model │ │ ├── constant-objects.md │ │ ├── constructors.md │ │ ├── copy-semantics.md │ │ ├── declarations.md │ │ ├── definitions.md │ │ ├── move-semantics.md │ │ ├── objects.md │ │ ├── rule-of-five.md │ │ ├── rule-of-zero.md │ │ ├── special-member-functions.md │ │ └── types.md │ ├── program-design │ │ ├── algorithms.md │ │ ├── concepts.md │ │ ├── containers.md │ │ ├── iterators.md │ │ └── ranges.md │ ├── type-system │ │ ├── fundamental-types.md │ │ └── user-defined-types.md │ └── user-defined-types │ │ ├── class-templates.md │ │ └── user-defined-literals.md ├── obtaining_document.md └── references.md └── tools ├── build ├── aspell_frontend ├── build ├── generate_main.py ├── make_markdown ├── prebuild └── preprocessor ├── mgmt_tools ├── gen_readme.py └── topic_updater.py ├── pandoc_filters ├── meta_vars.lua └── spellcheck.lua ├── pytest.ini ├── requirements.txt └── tests ├── TEST_INPUTS ├── fix_wrong_sections.md ├── missing_sections.md ├── test_injectable_main.md ├── test_modules │ ├── test_empty_module.md │ ├── test_placeholder.md │ └── test_wrong_placeholder.md ├── test_skeleton.md └── user_content_heading_topic.md ├── generate_main_test.py └── topic_updater_test.py /.github/ISSUE_TEMPLATE/topic-proposal.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Topic proposal 3 | about: Describes a topic that should be considered by SG20 for education guidelines 4 | title: "[TOPIC-REQUEST]" 5 | labels: Needs triaging 6 | assignees: vulder, jcvw 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # This action is used to perform a test build of the document that includes 2 | # performing spell checking. 3 | 4 | name: ci 5 | 6 | on: 7 | pull_request: 8 | push: 9 | branches: 10 | master 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v2 17 | ############################################################ 18 | - name: Prepare to build the document. 19 | shell: bash 20 | run: tools/build/prebuild 21 | ############################################################ 22 | - name: Build the document. 23 | shell: bash 24 | run: | 25 | tools/build/build \ 26 | -d ${{runner.temp}}/output \ 27 | -v ${GITHUB_REF#refs/*/} \ 28 | -s 29 | ############################################################ 30 | -------------------------------------------------------------------------------- /.github/workflows/ci_tool_tests.yml: -------------------------------------------------------------------------------- 1 | # This action is used to run tests to ensure all tools work like expected. 2 | 3 | name: Tool CI 4 | 5 | on: 6 | pull_request: 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-20.04 11 | strategy: 12 | matrix: 13 | python-version: [3.7, 3.8, 3.9] 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | with: 18 | fetch-depth: 0 19 | 20 | - name: Set up Python ${{ matrix.python-version }} 21 | uses: actions/setup-python@v2 22 | with: 23 | python-version: ${{ matrix.python-version }} 24 | 25 | - name: Install dependencies 26 | run: | 27 | pip install -r tools/requirements.txt 28 | 29 | - name: Run unittests 30 | run: | 31 | cd tools 32 | pytest 33 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # This is an action that builds the document and deploys the build document 2 | # to its associated GitHub pages site. 3 | 4 | name: release 5 | 6 | on: 7 | push: 8 | tags: 9 | - 'v*.*.*' 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | with: 17 | fetch-depth: 0 18 | ############################################################ 19 | - name: Prepare to build the document. 20 | shell: bash 21 | run: tools/build/prebuild 22 | ############################################################ 23 | - name: Collect git metadata 24 | id: git_metadata 25 | run: | 26 | echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT 27 | # The following builds the document in multiple formats for deployment. 28 | - name: Build the document. 29 | shell: bash 30 | run: | 31 | tools/build/build \ 32 | -d ${{runner.temp}}/output \ 33 | -v ${{ steps.git_metadata.outputs.VERSION }} 34 | - name: Deploy generated content to gh-pages 35 | uses: peaceiris/actions-gh-pages@v3 36 | with: 37 | github_token: ${{ secrets.GITHUB_TOKEN }} 38 | publish_dir: ${{runner.temp}}/output 39 | keep_files: true 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | 3 | # Ignore generated files 4 | sources/contributors.md 5 | sources/guidelines.epub 6 | sources/guidelines.html 7 | sources/guidelines.texi 8 | sources/guidelines_html/ 9 | sources/knowledge_areas_summary.md 10 | sources/main.gen.md 11 | sources/main.pre.md 12 | sources/spellcheck_expected_sorted.txt 13 | sources/spellcheck_result.txt 14 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Florian Sattler 2 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Standard C++ Foundation and its contributors 2 | 3 | Standard C++ Foundation grants you a worldwide, nonexclusive, royalty-free, 4 | perpetual license to copy, use, modify, and create derivative works from this 5 | project for your personal or internal business use only. The above copyright 6 | notice and this permission notice shall be included in all copies or 7 | substantial portions of the project. This license does not grant permission 8 | to use the trade names, trademarks, service marks, or product names of the 9 | licensor, except as required for reasonable and customary use in describing 10 | the origin of the project. 11 | 12 | Standard C++ Foundation reserves the right to accept contributions to the 13 | project at its discretion. 14 | 15 | By contributing material to this project, you grant Standard C++ Foundation, 16 | and those who receive the material directly or indirectly from Standard C++ 17 | Foundation, a perpetual, worldwide, non-exclusive, royalty-free, irrevocable, 18 | transferrable license to reproduce, prepare derivative works of, publicly 19 | display, publicly perform, and distribute your contributed material and such 20 | derivative works, and to sublicense any or all of the foregoing rights to third 21 | parties for commercial or non-commercial use. You also grant Standard C++ 22 | Foundation, and those who receive the material directly or indirectly from 23 | Standard C++ Foundation, a perpetual, worldwide, non-exclusive, royalty-free, 24 | irrevocable license under your patent claims that directly read on your 25 | contributed material to make, have made, use, offer to sell, sell and import 26 | or otherwise dispose of the material. You warrant that your material is your 27 | original work, or that you have the right to grant the above licenses. 28 | 29 | THE PROJECT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE PROJECT OR THE USE OR OTHER DEALINGS IN THE 35 | PROJECT. 36 | 37 | If you believe that anything in the project infringes your copyright, please 38 | contact us at admin@isocpp.org with your contact information and a detailed 39 | description of your intellectual property, including a specific URL where you 40 | believe your intellectual property is being infringed. 41 | 42 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS = \ 2 | sources \ 3 | 4 | .PHONY: all world clean install 5 | all world clean install: 6 | for subdir in $(SUBDIRS); do \ 7 | ( cd $$subdir && make -$(MAKEFLAGS) $@ ) || exit 1; \ 8 | done 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Guidelines for Teaching C++ 2 | =========================== 3 | 4 | This repository contains the source for the document: 5 | 6 | - Guidelines for Teaching C++ 7 | 8 | When the repository is tagged, this document is automatically built 9 | and made available via GitHub Pages at: 10 | 11 | - 12 | 13 | # Prerequisites for Building the Document 14 | 15 | The following software is needed to build the document: 16 | 17 | - pandoc 18 | - aspell 19 | - various basic POSIX utilities, including (amongst others): 20 | - make 21 | - awk 22 | - sed 23 | 24 | If one would like to build the document in PDF format, the 25 | following software is also required: 26 | 27 | - LaTex 28 | 29 | # Building the Document 30 | 31 | To build the document, simply type: 32 | 33 | 1. make clean 34 | 2. make all 35 | 3. make install 36 | 37 | (Strictly speaking, step 2 can be skipped, since the install target 38 | has a dependency on the all target.) 39 | 40 | The above commands will build the document in several formats: 41 | 42 | - HTML format as a single HTML document: 43 | install/html/index.html 44 | - EPUB format: 45 | guidelines.epub 46 | - HTML format split across multiple HTML documents: 47 | install/html_split/index.html 48 | 49 | A make target called world is also defined. Building this target (i.e., 50 | "make world") will generate the document in additional formats, including 51 | PDF format, but requires that LaTeX be installed. 52 | 53 | The build process performs spell checking. 54 | The build will fail if any spelling errors are detected. 55 | 56 | # Spell Checking 57 | 58 | Words that are flagged as having spelling errors can be classified 59 | into two categories: 60 | 61 | 1. valid English words (such as technical terms) that are not in 62 | the spell checker's dictionary 63 | 2. words that are not really "proper" English words but are also not 64 | really errors either (e.g., people's names) 65 | 66 | Words in category 1 should be added to the file 67 | config/spellcheck/wordlist. 68 | Words in category 2 should be added to the file 69 | config/spellcheck/ignored_words.txt 70 | 71 | # Repository Organization 72 | 73 | The files in this repository are organized into directories as follows: 74 | 75 | - config: 76 | This directory contains configuration files that control various 77 | aspects of how the guidelines document is built. 78 | - pandoc_templates: 79 | This directory contains document templates used by pandoc during 80 | the document build process. 81 | - spellcheck: 82 | The directory contains lists of additional words and ignorable errors 83 | for spell checking. 84 | - sources: 85 | This directory hierarchy contains the source files for the document. 86 | - css: 87 | This directory contains CSS files used by the document when built 88 | in HTML format. 89 | - images: 90 | This directory contains images used in the document. 91 | - modules: 92 | The directory hierarchy contains the information for individual modules 93 | and topics. There is one directory per module and one file per topic. 94 | - tools: 95 | The directory hierarchy contains various scripts and other tools used for 96 | building and deploying the document to GitHub pages site. 97 | - build: 98 | This directory contains scripts used for building and deploying the 99 | document. 100 | - old: 101 | This directory hierachy needs to be reorganized. This directory 102 | should probably be renamed and its contents possibly reorganized 103 | or relocated elsewhere. 104 | - tools 105 | - tests 106 | - TEST_INPUTS 107 | - pandoc_filters: 108 | This directory contains various filters needed for pandoc. These 109 | filters do things such as allow markdown-aware spell checking. 110 | -------------------------------------------------------------------------------- /config/pandoc_templates/bootstrap_menu.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | $for(author-meta)$ 47 | 48 | $endfor$ 49 | $if(date-meta)$ 50 | 51 | $endif$ 52 | $if(title-prefix)$$title-prefix$ - $endif$$pagetitle$ 53 | 54 | $if(quotes)$ 55 | 56 | $endif$ 57 | $if(highlighting-css)$ 58 | 61 | $endif$ 62 | $for(css)$ 63 | 64 | $endfor$ 65 | $if(math)$ 66 | $math$ 67 | $endif$ 68 | $for(header-includes)$ 69 | $header-includes$ 70 | $endfor$ 71 | 72 | 73 | 74 | 75 | $if(title)$ 76 | 91 | $endif$ 92 |
93 |
94 | $if(toc)$ 95 |
96 |
97 | 98 | $toc$ 99 | 100 |
101 |
102 | $endif$ 103 |
104 | $for(include-before)$ 105 | $include-before$ 106 | $endfor$ 107 | $body$ 108 | $for(include-after)$ 109 | $include-after$ 110 | $endfor$ 111 |
112 |
113 |
114 | $if(analytics)$ 115 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /config/pandoc_templates/clean_menu.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | $for(author-meta)$ 46 | 47 | $endfor$ 48 | $if(date-meta)$ 49 | 50 | $endif$ 51 | $if(title-prefix)$$title-prefix$ - $endif$$pagetitle$ 52 | 53 | 54 | $if(quotes)$ 55 | 56 | $endif$ 57 | $if(highlighting-css)$ 58 | 61 | $endif$ 62 | $for(css)$ 63 | 64 | $endfor$ 65 | $if(math)$ 66 | $math$ 67 | $endif$ 68 | $for(header-includes)$ 69 | $header-includes$ 70 | $endfor$ 71 | 72 | 73 | 74 | 75 | $if(title)$ 76 | 91 |
92 | $else$ 93 |
94 | $endif$ 95 |
96 | $if(toc)$ 97 |
98 |
99 | 100 | $toc$ 101 | 102 |
103 |
104 | $endif$ 105 |
106 | $for(include-before)$ 107 | $include-before$ 108 | $endfor$ 109 | $body$ 110 | $for(include-after)$ 111 | $include-after$ 112 | $endfor$ 113 |
114 |
115 |
116 | $if(analytics)$ 117 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /config/pandoc_templates/easy_template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | $for(author-meta)$ 48 | 49 | $endfor$ 50 | $if(date-meta)$ 51 | 52 | $endif$ 53 | $if(title-prefix)$$title-prefix$ - $endif$$pagetitle$ 54 | 55 | $if(quotes)$ 56 | 57 | $endif$ 58 | $if(highlighting-css)$ 59 | 62 | $endif$ 63 | $for(css)$ 64 | 65 | $endfor$ 66 | $if(math)$ 67 | $math$ 68 | $endif$ 69 | $for(header-includes)$ 70 | $header-includes$ 71 | $endfor$ 72 | 73 | 74 | 75 | 76 | $if(title)$ 77 | 92 | $endif$ 93 |
94 |
95 | $if(toc)$ 96 |
97 |
98 | 99 | $toc$ 100 | 101 |
102 |
103 | $endif$ 104 |
105 | $for(include-before)$ 106 | $include-before$ 107 | $endfor$ 108 | $body$ 109 | $for(include-after)$ 110 | $include-after$ 111 | $endfor$ 112 |
113 |
114 |
115 | $if(analytics)$ 116 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /config/pandoc_templates/elegant_bootstrap_menu.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | $for(author-meta)$ 48 | 49 | $endfor$ 50 | $if(date-meta)$ 51 | 52 | $endif$ 53 | $if(title-prefix)$$title-prefix$ - $endif$$pagetitle$ 54 | 55 | $if(quotes)$ 56 | 57 | $endif$ 58 | $if(highlighting-css)$ 59 | 62 | $endif$ 63 | $for(css)$ 64 | 65 | $endfor$ 66 | $if(math)$ 67 | $math$ 68 | $endif$ 69 | $for(header-includes)$ 70 | $header-includes$ 71 | $endfor$ 72 | 73 | 74 | 75 | 76 | $if(title)$ 77 | 92 | $endif$ 93 |
94 |
95 | $if(toc)$ 96 |
97 |
98 | 99 | $toc$ 100 | 101 |
102 |
103 | $endif$ 104 |
105 | $for(include-before)$ 106 | $include-before$ 107 | $endfor$ 108 | $body$ 109 | $for(include-after)$ 110 | $include-after$ 111 | $endfor$ 112 |
113 |
114 |
115 | $if(analytics)$ 116 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /config/pandoc_templates/uikit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | $if(title)$$title$$endif$ 8 | 9 | 10 | 11 | $if(template_css)$ 12 | 13 | $else$ 14 | 15 | $endif$ 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | $for(author-meta)$ 30 | 31 | $endfor$ 32 | $if(date-meta)$ 33 | 34 | $endif$ 35 | 36 | $if(version-meta)$ 37 | 38 | $endif$ 39 | 40 | $if(title-prefix)$$title-prefix$ - $endif$$pagetitle$ 41 | 42 | $if(quotes)$ 43 | 44 | $endif$ 45 | $if(highlighting-css)$ 46 | 49 | $endif$ 50 | $for(css)$ 51 | 52 | $endfor$ 53 | $if(math)$ 54 | $math$ 55 | $endif$ 56 | $for(header-includes)$ 57 | $header-includes$ 58 | $endfor$ 59 | 60 | 61 | 62 | 63 | 64 |
65 | 66 | $if(title)$ 67 |
68 | 69 | $if(version)$ 70 |
71 | 72 |
73 | $endif$ 74 | 75 |
76 |

$title$

77 | $if(date)$ 78 |

$date$

79 | $endif$ 80 | 81 | $if(version)$ 82 |

Version $version$

83 | $endif$ 84 | 85 | $for(author)$ 86 |

$author$

87 | $endfor$ 88 |
89 |
90 | $endif$ 91 | 92 |
93 |
94 |
95 | 102 |
103 |
104 | 105 |
106 | $body$ 107 |
108 |
109 | $if(analytics)$ 110 | 120 |
121 | 122 | 123 | -------------------------------------------------------------------------------- /config/spellcheck/ignored_words.txt: -------------------------------------------------------------------------------- 1 | args 2 | asm 3 | baz 4 | Bjarne 5 | bool 6 | checkmark 7 | coe 8 | constexpr 9 | cppreference 10 | Engelhart 11 | enum 12 | EPUB 13 | errno 14 | expr 15 | explorative 16 | extern 17 | Florian 18 | func 19 | Furst 20 | Hinnant 21 | html 22 | Hyland 23 | JC 24 | Krathwohl 25 | ness 26 | nothrow 27 | NRVO 28 | RAII 29 | req 30 | Rethrowing 31 | RVO 32 | Sattler 33 | SG 34 | Stroustrup 35 | udl 36 | Vandevoorde 37 | ver 38 | Winkel 39 | -------------------------------------------------------------------------------- /config/spellcheck/wordlist: -------------------------------------------------------------------------------- 1 | ABI 2 | API 3 | APIs 4 | boolean 5 | computable 6 | destructors 7 | IDEs 8 | invariants 9 | lawyering 10 | metaprogramming 11 | namespace 12 | namespaces 13 | ODR 14 | personal_ws-1.1 en 18 15 | preprocessor 16 | redeclarations 17 | SFINAE 18 | toolchain 19 | toolchains 20 | UDL 21 | UDLs 22 | -------------------------------------------------------------------------------- /skeleton.md: -------------------------------------------------------------------------------- 1 | ## Module name: topic name 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | ------------------------------------------------------------------------ 12 | Level Objective 13 | ----------------- ------------------------------------------------------ 14 | Foundational --- 15 | 16 | Main --- 17 | 18 | Advanced --- 19 | 20 | ------------------------------------------------------------------------ 21 | 22 | ### Motivation 23 | 24 | _Why is this important?_ 25 | _Why do we want to learn/teach this topic?_ 26 | 27 | ### Topic introduction 28 | 29 | _Very brief introduction to the topic._ 30 | 31 | ### Foundational: Using * 32 | 33 | #### Background/Required Knowledge 34 | 35 | A student: 36 | 37 | 38 | #### Student outcomes 39 | 40 | _A list of things "a student should be able to" after the curriculum._ 41 | _The next word should be an action word and testable in an exam._ 42 | _Max 5 items._ 43 | 44 | A student should be able to: 45 | 46 | 1. 47 | 2. 48 | 3. 49 | 4. 50 | 5. 51 | 52 | #### Caveats 53 | 54 | _This section mentions subtle points to understand, like anything resulting in 55 | implementation-defined, unspecified, or undefined behavior._ 56 | 57 | #### Points to cover 58 | 59 | _This section lists important details for each point._ 60 | 61 | ### Main: implementing * 62 | 63 | #### Background/Required Knowledge 64 | 65 | * All of the above. 66 | 67 | #### Student outcomes 68 | 69 | A student should be able to: 70 | 71 | 1. 72 | 2. 73 | 3. 74 | 4. 75 | 5. 76 | 77 | #### Caveats 78 | 79 | #### Points to cover 80 | 81 | ### Advanced 82 | 83 | _These are important topics that are not expected to be covered but provide 84 | guidance where one can continue to investigate this topic in more depth._ 85 | -------------------------------------------------------------------------------- /sources/Makefile: -------------------------------------------------------------------------------- 1 | #TOP_DIR = $(realpath ..) 2 | TOP_DIR = .. 3 | 4 | # Specify the document version. 5 | # This can be overridden when invoked from the automated build process. 6 | DOC_VERSION = X.Y.Z 7 | 8 | # Specify whether a spelling error is an error (as opposed to a warning). 9 | # This can be overridden when invoked from the automated build process. 10 | # Please resist the temptation to set this variable to zero. ;-) 11 | # DOC_SPELLCHECK_MUST_PASS = 0 12 | DOC_SPELLCHECK_MUST_PASS = 1 13 | 14 | # This can be overridden when invoked from the automated build process. 15 | INSTALL_DIR = $(TOP_DIR)/install 16 | 17 | # All of the Markdown source files (that are not generated during build). 18 | SOURCES = $(shell find . -mindepth 2 -name '*.md') 19 | 20 | # Special top-level markdown files 21 | EXTRA_SOURCES = glossary.md \ 22 | contributing.md \ 23 | introduction.md \ 24 | main_raw.md \ 25 | obtaining_document.md \ 26 | references.md \ 27 | 28 | # The Markdown files that are generated during the build process. 29 | GENERATED_MARKDOWN = \ 30 | knowledge_areas_summary.md \ 31 | main.pre.md \ 32 | main.gen.md \ 33 | contributors.md \ 34 | 35 | # Merge extra sources with detected sources for teaching modules 36 | SOURCES += $(EXTRA_SOURCES) 37 | 38 | ################################################################################ 39 | # Define primary targets. 40 | ################################################################################ 41 | 42 | # The all target builds the document in a minimal set of formats and 43 | # performs a spell check. 44 | .PHONY: all 45 | all: documents spellcheck 46 | 47 | # The world target is similar to the all target except that it builds the 48 | # document in some additional formats. 49 | .PHONY: world 50 | world: all documents_extra 51 | 52 | # The documents target builds the document in a minimal set of formats. 53 | .PHONY: documents 54 | documents: guidelines.html guidelines_html guidelines.epub 55 | 56 | # The documents_extra target builds the document in a few extra formats. 57 | .PHONY: world 58 | documents_extra: guidelines.pdf 59 | 60 | # The spellcheck format performs a spell check on the document. 61 | .PHONY: spellcheck 62 | spellcheck: spellcheck_result.txt 63 | 64 | # The clean target removes all files generated during the build process. 65 | .PHONY: clean 66 | clean: 67 | rm -f $(GENERATED_MARKDOWN) 68 | rm -f guidelines.html guidelines.pdf guidelines.epub guidelines.tex 69 | rm -rf guidelines.texi 70 | rm -rf guidelines_html 71 | rm -f spellcheck_result.txt 72 | rm -f spellcheck_expected_sorted.txt 73 | rm -f missfont.log 74 | 75 | # The install target installs the build document (in various formats) 76 | # in the directory $(INSTALL_DIR). 77 | .PHONY: install 78 | install: all 79 | if [ ! -d "$(INSTALL_DIR)" ]; then \ 80 | mkdir -p "$(INSTALL_DIR)" || exit 1; \ 81 | fi 82 | for dir in html html/images; do \ 83 | if [ ! -d "$(INSTALL_DIR)/$$dir" ]; then \ 84 | mkdir -p "$(INSTALL_DIR)/$$dir" || exit 1; \ 85 | fi; \ 86 | done 87 | cp -f images/cpp_logo.png "$(INSTALL_DIR)/html/images" 88 | cp -f guidelines.html "$(INSTALL_DIR)/html/index.html" 89 | cp -r -f guidelines_html "$(INSTALL_DIR)/html_split" 90 | cp -f guidelines.epub "$(INSTALL_DIR)" 91 | if [ -f guidelines.pdf ]; then \ 92 | cp -f guidelines.pdf "$(INSTALL_DIR)"; \ 93 | fi 94 | 95 | ################################################################################ 96 | # Some additional configuration. 97 | ################################################################################ 98 | 99 | MAIN_GENERATOR= $(TOP_DIR)/tools/build/generate_main.py 100 | MD_PREPROCESSOR = $(TOP_DIR)/tools/build/preprocessor 101 | MAKE_MARKDOWN = $(TOP_DIR)/tools/build/make_markdown 102 | SPELLCHECK_DIR = $(TOP_DIR)/config/spellcheck 103 | 104 | ################################################################################ 105 | # Preprocessing setup. 106 | ################################################################################ 107 | 108 | main.pre.md: $(SOURCES) contributors.md main_raw.md 109 | $(MAIN_GENERATOR) --raw main_raw.md --out main.pre.md --module-folder modules 110 | 111 | main.gen.md: $(SOURCES) contributors.md main.pre.md 112 | $(MD_PREPROCESSOR) -v $(DOC_VERSION) < main.pre.md > main.gen.md 113 | 114 | knowledge_areas_summary.md: $(SOURCES) knowledge_areas.dat 115 | $(MAKE_MARKDOWN) < knowledge_areas.dat > knowledge_areas_summary.md 116 | 117 | contributors.md: 118 | git log --format="%aN%n%(trailers:key=Co-authored-by,valueonly=true)" | sed 's/ <.*>//g' | sort | uniq > contributors.md 119 | 120 | ################################################################################ 121 | # Establish Pandoc settings. 122 | ################################################################################ 123 | 124 | PANDOC_OPTIONS += --verbose 125 | PANDOC_OPTIONS += --toc --toc-depth 3 126 | PANDOC_OPTIONS += --number-sections 127 | PANDOC_OPTIONS += --standalone 128 | PANDOC_OPTIONS += --pdf-engine=xelatex 129 | #PANDOC_OPTIONS += --lua-filter=tools/pandoc_filters/meta_vars.lua 130 | #PANDOC_OPTIONS += --metadata date="`date +%Y-%m-%d`" 131 | PANDOC_OPTIONS += --metadata version=$(DOC_VERSION) 132 | 133 | INPUT_FORMAT = markdown+header_attributes+multiline_tables 134 | 135 | EPUB_CSS_FILE = css/default-pandoc.css 136 | 137 | #HTML_TEMPLATE = templates/bootstrap_menu.html 138 | HTML_TEMPLATE = $(TOP_DIR)/config/pandoc_templates/uikit.html 139 | 140 | #MAKEINFO_OPTIONS += --no-warn 141 | MAKEINFO_OPTIONS += --error-limit 1000000000000 142 | #MAKEINFO_OPTIONS += --verbose 143 | MAKEINFO_OPTIONS += --no-validate 144 | MAKEINFO_OPTIONS += --force 145 | 146 | ################################################################################ 147 | # Rules for generating the document in various formats. 148 | ################################################################################ 149 | 150 | guidelines.html: $(GENERATED_MARKDOWN) 151 | pandoc $(PANDOC_OPTIONS) --template $(HTML_TEMPLATE) --from $(INPUT_FORMAT) -o $@ main.gen.md 152 | 153 | guidelines.epub: $(GENERATED_MARKDOWN) 154 | pandoc $(PANDOC_OPTIONS) -c $(EPUB_CSS_FILE) --from $(INPUT_FORMAT) -o $@ main.gen.md 155 | 156 | guidelines.pdf: $(GENERATED_MARKDOWN) 157 | pandoc $(PANDOC_OPTIONS) --from $(INPUT_FORMAT) -o $@ main.gen.md 158 | 159 | guidelines.texi: $(GENERATED_MARKDOWN) 160 | pandoc $(PANDOC_OPTIONS) --from $(INPUT_FORMAT) -o $@ main.gen.md 161 | 162 | guidelines.docbook: $(GENERATED_MARKDOWN) 163 | pandoc $(PANDOC_OPTIONS) --from $(INPUT_FORMAT) -o $@ main.gen.md 164 | 165 | guidelines_html: guidelines.texi 166 | makeinfo $(MAKEINFO_OPTIONS) --html -o guidelines_html guidelines.texi 167 | 168 | guidelines.tex: 169 | pandoc $(PANDOC_OPTIONS) --from $(INPUT_FORMAT) --to latex -o $@ main.gen.md 170 | 171 | ################################################################################ 172 | # Rule for spellchecking. 173 | ################################################################################ 174 | 175 | spellcheck_result.txt: guidelines.html 176 | rm -f $@ 177 | PATH="$(TOP_DIR)/tools/build:$$PATH" pandoc --from $(INPUT_FORMAT) \ 178 | --lua-filter $(TOP_DIR)/tools/pandoc_filters/spellcheck.lua \ 179 | main.gen.md | sort | uniq > $@ 180 | if [ -s $@ ]; then \ 181 | echo "DETECTED SPELLING ERRORS:"; \ 182 | cat $@ | while read line; do echo "Misspelled '$$line' in:"; \ 183 | grep -R "$$line" -n --color=auto --include='*.md' --exclude='main.gen.md'; done; \ 184 | sync; \ 185 | if [ $(DOC_SPELLCHECK_MUST_PASS) -ne 0 ]; then \ 186 | echo "ERROR: spelling errors detected, cannot proceed!"; \ 187 | exit 1; \ 188 | else \ 189 | echo "WARNING: spelling errors detected"; \ 190 | fi; \ 191 | fi 192 | -------------------------------------------------------------------------------- /sources/contributing.md: -------------------------------------------------------------------------------- 1 | # How To Contribute {#contributing} 2 | 3 | Before attempting to contribute any content for consideration for 4 | inclusion in this document, please read the information below and 5 | and the referenced documents as appropriate. 6 | 7 | All contributions to this project must be made in accordance with the 8 | license in section [License](#license). 9 | This teaching-guidelines document only offers guidance on teaching C++ 10 | as it is specified in the current version of the C++ standard. 11 | So, content should be presented relative to the most-recently 12 | ratified version of the standard. 13 | A detailed explanation of how to present the material for a topic is given in: 14 | 15 | - JC van Winkel, Bjarne Stroustrup, and Florian Sattler. 16 | P2193 --- 17 | How to structure a teaching topic. 18 | . 19 | 20 | Any potential contributors should ensure that they read this document. 21 | The following document may also be helpful in providing some general 22 | background on the modular approach to teaching followed herein: 23 | 24 | - Christopher Di Bella. 25 | P1725R0 --- 26 | Modular Topic Design. 27 | . 28 | 29 | In order to prepare content, it is important to understand what learning 30 | outcomes are, and how to prepare good ones. 31 | Some information on learning outcomes can be found in the 32 | [References](#references) section. 33 | The following document offers a concise introduction to learning outcomes: 34 | 35 | - Effective Use of Performance Objectives for Learning and Assessment 36 | (For Use With Fink’s and Bloom’s Taxonomies), 37 | University of New Mexico, School of Medicine, Teaching and Educational Development, 38 | . 39 | -------------------------------------------------------------------------------- /sources/css/default-pandoc.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 100%; 3 | overflow-y: scroll; 4 | -webkit-text-size-adjust: 100%; 5 | -ms-text-size-adjust: 100%; 6 | } 7 | 8 | body { 9 | color: #444; 10 | font-family: Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman', serif; 11 | font-size: 12px; 12 | line-height: 1.7; 13 | padding: 1em; 14 | margin: auto; 15 | /* 16 | max-width: 42em; 17 | */ 18 | max-width: 50em; 19 | background: #fefefe; 20 | } 21 | 22 | a { 23 | color: #0645ad; 24 | text-decoration: none; 25 | } 26 | 27 | a:visited { 28 | color: #0b0080; 29 | } 30 | 31 | a:hover { 32 | color: #06e; 33 | } 34 | 35 | a:active { 36 | color: #faa700; 37 | } 38 | 39 | a:focus { 40 | outline: thin dotted; 41 | } 42 | 43 | *::-moz-selection { 44 | background: rgba(255, 255, 0, 0.3); 45 | color: #000; 46 | } 47 | 48 | *::selection { 49 | background: rgba(255, 255, 0, 0.3); 50 | color: #000; 51 | } 52 | 53 | a::-moz-selection { 54 | background: rgba(255, 255, 0, 0.3); 55 | color: #0645ad; 56 | } 57 | 58 | a::selection { 59 | background: rgba(255, 255, 0, 0.3); 60 | color: #0645ad; 61 | } 62 | 63 | p { 64 | margin: 1em 0; 65 | } 66 | 67 | img { 68 | max-width: 100%; 69 | } 70 | 71 | h1, h2, h3, h4, h5, h6 { 72 | color: #111; 73 | line-height: 125%; 74 | margin-top: 2em; 75 | font-weight: normal; 76 | } 77 | 78 | h4, h5, h6 { 79 | font-weight: bold; 80 | } 81 | 82 | h1 { 83 | font-size: 2.5em; 84 | } 85 | 86 | h2 { 87 | font-size: 2em; 88 | } 89 | 90 | h3 { 91 | font-size: 1.5em; 92 | } 93 | 94 | h4 { 95 | font-size: 1.2em; 96 | } 97 | 98 | h5 { 99 | font-size: 1em; 100 | } 101 | 102 | h6 { 103 | font-size: 0.9em; 104 | } 105 | 106 | blockquote { 107 | color: #666666; 108 | margin: 0; 109 | padding-left: 3em; 110 | border-left: 0.5em #EEE solid; 111 | } 112 | 113 | hr { 114 | display: block; 115 | height: 2px; 116 | border: 0; 117 | border-top: 1px solid #aaa; 118 | border-bottom: 1px solid #eee; 119 | margin: 1em 0; 120 | padding: 0; 121 | } 122 | 123 | pre, code, kbd, samp { 124 | color: #000; 125 | font-family: monospace, monospace; 126 | _font-family: 'courier new', monospace; 127 | font-size: 0.98em; 128 | } 129 | 130 | pre { 131 | white-space: pre; 132 | white-space: pre-wrap; 133 | word-wrap: break-word; 134 | } 135 | 136 | b, strong { 137 | font-weight: bold; 138 | } 139 | 140 | dfn { 141 | font-style: italic; 142 | } 143 | 144 | ins { 145 | background: #ff9; 146 | color: #000; 147 | text-decoration: none; 148 | } 149 | 150 | mark { 151 | background: #ff0; 152 | color: #000; 153 | font-style: italic; 154 | font-weight: bold; 155 | } 156 | 157 | sub, sup { 158 | font-size: 75%; 159 | line-height: 0; 160 | position: relative; 161 | vertical-align: baseline; 162 | } 163 | 164 | sup { 165 | top: -0.5em; 166 | } 167 | 168 | sub { 169 | bottom: -0.25em; 170 | } 171 | 172 | ul, ol { 173 | margin: 1em 0; 174 | padding: 0 0 0 2em; 175 | } 176 | 177 | li p:last-child { 178 | margin-bottom: 0; 179 | } 180 | 181 | ul ul, ol ol { 182 | margin: .3em 0; 183 | } 184 | 185 | dl { 186 | margin-bottom: 1em; 187 | } 188 | 189 | dt { 190 | font-weight: bold; 191 | margin-bottom: .8em; 192 | } 193 | 194 | dd { 195 | margin: 0 0 .8em 2em; 196 | } 197 | 198 | dd:last-child { 199 | margin-bottom: 0; 200 | } 201 | 202 | img { 203 | border: 0; 204 | -ms-interpolation-mode: bicubic; 205 | vertical-align: middle; 206 | } 207 | 208 | figure { 209 | display: block; 210 | text-align: center; 211 | margin: 1em 0; 212 | } 213 | 214 | figure img { 215 | border: none; 216 | margin: 0 auto; 217 | } 218 | 219 | figcaption { 220 | font-size: 0.8em; 221 | font-style: italic; 222 | margin: 0 0 .8em; 223 | } 224 | 225 | table { 226 | margin-bottom: 2em; 227 | border-bottom: 1px solid #ddd; 228 | border-right: 1px solid #ddd; 229 | border-spacing: 0; 230 | border-collapse: collapse; 231 | } 232 | 233 | table th { 234 | padding: .2em 1em; 235 | background-color: #eee; 236 | border-top: 1px solid #ddd; 237 | border-left: 1px solid #ddd; 238 | } 239 | 240 | table td { 241 | padding: .2em 1em; 242 | border-top: 1px solid #ddd; 243 | border-left: 1px solid #ddd; 244 | vertical-align: top; 245 | } 246 | 247 | .author { 248 | font-size: 1.2em; 249 | text-align: center; 250 | } 251 | 252 | @media only screen and (min-width: 480px) { 253 | body { 254 | font-size: 14px; 255 | } 256 | } 257 | @media only screen and (min-width: 768px) { 258 | body { 259 | font-size: 16px; 260 | } 261 | } 262 | @media print { 263 | * { 264 | background: transparent !important; 265 | color: black !important; 266 | filter: none !important; 267 | -ms-filter: none !important; 268 | } 269 | 270 | body { 271 | font-size: 12pt; 272 | max-width: 100%; 273 | } 274 | 275 | a, a:visited { 276 | text-decoration: underline; 277 | } 278 | 279 | hr { 280 | height: 1px; 281 | border: 0; 282 | border-bottom: 1px solid black; 283 | } 284 | 285 | a[href]:after { 286 | content: " (" attr(href) ")"; 287 | } 288 | 289 | abbr[title]:after { 290 | content: " (" attr(title) ")"; 291 | } 292 | 293 | .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { 294 | content: ""; 295 | } 296 | 297 | pre, blockquote { 298 | border: 1px solid #999; 299 | padding-right: 1em; 300 | page-break-inside: avoid; 301 | } 302 | 303 | tr, img { 304 | page-break-inside: avoid; 305 | } 306 | 307 | img { 308 | max-width: 100% !important; 309 | } 310 | 311 | @page :left { 312 | margin: 15mm 20mm 15mm 10mm; 313 | } 314 | 315 | @page :right { 316 | margin: 15mm 10mm 15mm 20mm; 317 | } 318 | 319 | p, h2, h3 { 320 | orphans: 3; 321 | widows: 3; 322 | } 323 | 324 | h2, h3 { 325 | page-break-after: avoid; 326 | } 327 | } 328 | -------------------------------------------------------------------------------- /sources/css/elegant_bootstrap.css: -------------------------------------------------------------------------------- 1 | /* 2 | * I add this to html files generated with pandoc. 3 | */ 4 | 5 | html { 6 | font-size: 100%; 7 | overflow-y: scroll; 8 | -webkit-text-size-adjust: 100%; 9 | -ms-text-size-adjust: 100%; 10 | } 11 | 12 | body { 13 | color: #444; 14 | font-family: Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman', serif; 15 | font-size: 12px; 16 | line-height: 1.8; 17 | background: #fefefe; 18 | } 19 | 20 | a { 21 | color: #0645ad; 22 | text-decoration: none; 23 | } 24 | 25 | a:visited { 26 | color: #0b0080; 27 | } 28 | 29 | a:hover { 30 | color: #06e; 31 | } 32 | 33 | a:active { 34 | color: #faa700; 35 | } 36 | 37 | a:focus { 38 | outline: thin dotted; 39 | } 40 | 41 | *::-moz-selection { 42 | background: rgba(255, 255, 0, 0.3); 43 | color: #000; 44 | } 45 | 46 | *::selection { 47 | background: rgba(255, 255, 0, 0.3); 48 | color: #000; 49 | } 50 | 51 | a::-moz-selection { 52 | background: rgba(255, 255, 0, 0.3); 53 | color: #0645ad; 54 | } 55 | 56 | a::selection { 57 | background: rgba(255, 255, 0, 0.3); 58 | color: #0645ad; 59 | } 60 | 61 | p { 62 | margin: 1em 0; 63 | } 64 | 65 | img { 66 | max-width: 100%; 67 | } 68 | 69 | h1, h2, h3, h4, h5, h6 { 70 | color: #111; 71 | line-height: 125%; 72 | /* margin-top: 2em; */ 73 | font-weight: normal; 74 | } 75 | 76 | h4, h5, h6 { 77 | font-weight: bold; 78 | } 79 | 80 | h1 { 81 | font-size: 2.5em; 82 | } 83 | 84 | h2 { 85 | font-size: 2em; 86 | } 87 | 88 | h3 { 89 | font-size: 1.5em; 90 | } 91 | 92 | h4 { 93 | font-size: 1.2em; 94 | } 95 | 96 | h5 { 97 | font-size: 1em; 98 | } 99 | 100 | h6 { 101 | font-size: 0.9em; 102 | } 103 | 104 | blockquote { 105 | color: #666666; 106 | margin: 0; 107 | padding-left: 3em; 108 | border-left: 0.5em #EEE solid; 109 | } 110 | 111 | hr { 112 | display: block; 113 | height: 2px; 114 | border: 0; 115 | border-top: 1px solid #aaa; 116 | border-bottom: 1px solid #eee; 117 | margin: 1em 0; 118 | padding: 0; 119 | } 120 | 121 | pre, code, kbd, samp { 122 | color: #000; 123 | font-family: monospace, monospace; 124 | _font-family: 'courier new', monospace; 125 | font-size: 0.98em; 126 | } 127 | 128 | pre { 129 | white-space: pre; 130 | white-space: pre-wrap; 131 | word-wrap: break-word; 132 | } 133 | 134 | b, strong { 135 | font-weight: bold; 136 | } 137 | 138 | dfn { 139 | font-style: italic; 140 | } 141 | 142 | ins { 143 | background: #ff9; 144 | color: #000; 145 | text-decoration: none; 146 | } 147 | 148 | mark { 149 | background: #ff0; 150 | color: #000; 151 | font-style: italic; 152 | font-weight: bold; 153 | } 154 | 155 | sub, sup { 156 | font-size: 75%; 157 | line-height: 0; 158 | position: relative; 159 | vertical-align: baseline; 160 | } 161 | 162 | sup { 163 | top: -0.5em; 164 | } 165 | 166 | sub { 167 | bottom: -0.25em; 168 | } 169 | 170 | ul, ol { 171 | margin: 1em 0; 172 | padding: 0 0 0 2em; 173 | } 174 | 175 | li { 176 | line-height: inherit; 177 | } 178 | 179 | li p:last-child { 180 | margin-bottom: 0; 181 | } 182 | 183 | ul ul, ol ol { 184 | margin: .3em 0; 185 | } 186 | 187 | dl { 188 | margin-bottom: 1em; 189 | } 190 | 191 | dt { 192 | font-weight: bold; 193 | margin-bottom: .8em; 194 | } 195 | 196 | dd { 197 | margin: 0 0 .8em 2em; 198 | } 199 | 200 | dd:last-child { 201 | margin-bottom: 0; 202 | } 203 | 204 | img { 205 | border: 0; 206 | -ms-interpolation-mode: bicubic; 207 | vertical-align: middle; 208 | } 209 | 210 | figure { 211 | display: block; 212 | text-align: center; 213 | margin: 1em 0; 214 | } 215 | 216 | figure img { 217 | border: none; 218 | margin: 0 auto; 219 | } 220 | 221 | figcaption { 222 | font-size: 0.8em; 223 | font-style: italic; 224 | margin: 0 0 .8em; 225 | } 226 | 227 | table { 228 | margin-bottom: 2em; 229 | border-bottom: 1px solid #ddd; 230 | border-right: 1px solid #ddd; 231 | border-spacing: 0; 232 | border-collapse: collapse; 233 | } 234 | 235 | table th { 236 | padding: .2em 1em; 237 | background-color: #eee; 238 | border-top: 1px solid #ddd; 239 | border-left: 1px solid #ddd; 240 | } 241 | 242 | table td { 243 | padding: .2em 1em; 244 | border-top: 1px solid #ddd; 245 | border-left: 1px solid #ddd; 246 | vertical-align: top; 247 | } 248 | 249 | .author { 250 | font-size: 1.2em; 251 | text-align: center; 252 | } 253 | 254 | @media only screen and (min-width: 480px) { 255 | body { 256 | font-size: 14px; 257 | } 258 | } 259 | @media only screen and (min-width: 768px) { 260 | body { 261 | font-size: 16px; 262 | } 263 | } 264 | @media print { 265 | * { 266 | background: transparent !important; 267 | color: black !important; 268 | filter: none !important; 269 | -ms-filter: none !important; 270 | } 271 | 272 | body { 273 | font-size: 12pt; 274 | max-width: 100%; 275 | } 276 | 277 | a, a:visited { 278 | text-decoration: underline; 279 | } 280 | 281 | hr { 282 | height: 1px; 283 | border: 0; 284 | border-bottom: 1px solid black; 285 | } 286 | 287 | a[href]:after { 288 | content: " (" attr(href) ")"; 289 | } 290 | 291 | abbr[title]:after { 292 | content: " (" attr(title) ")"; 293 | } 294 | 295 | .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { 296 | content: ""; 297 | } 298 | 299 | pre, blockquote { 300 | border: 1px solid #999; 301 | padding-right: 1em; 302 | page-break-inside: avoid; 303 | } 304 | 305 | tr, img { 306 | page-break-inside: avoid; 307 | } 308 | 309 | img { 310 | max-width: 100% !important; 311 | } 312 | 313 | @page :left { 314 | margin: 15mm 20mm 15mm 10mm; 315 | } 316 | 317 | @page :right { 318 | margin: 15mm 10mm 15mm 20mm; 319 | } 320 | 321 | p, h2, h3 { 322 | orphans: 3; 323 | widows: 3; 324 | } 325 | 326 | h2, h3 { 327 | page-break-after: avoid; 328 | } 329 | } 330 | -------------------------------------------------------------------------------- /sources/glossary.md: -------------------------------------------------------------------------------- 1 | # Glossary 2 | 3 | Some possible terms to include in the glossary: 4 | 5 | - learning objective 6 | - learning outcome 7 | -------------------------------------------------------------------------------- /sources/images/cpp_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cplusplus/SG20/80780c5c022df14637d00cc1a18fb0b641a0403d/sources/images/cpp_logo.png -------------------------------------------------------------------------------- /sources/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

If you are not redirected in five seconds, click here.

7 | 8 | -------------------------------------------------------------------------------- /sources/introduction.md: -------------------------------------------------------------------------------- 1 | # Context and Aim of This Guide 2 | 3 | This document is intended to serve as a resource for instructors 4 | to assist in the preparation of courses on C++ in a variety of 5 | settings, including university, college, and industry environments. 6 | The main objectives of this document are as follows: 7 | 8 | - to provide guidelines for content to be covered by courses of various 9 | difficulty levels on C++ (e.g., topics and learning outcomes) 10 | - to note some common misunderstandings and problematic points that may 11 | be encountered when teaching particular topics 12 | - to suggest resources useful for teaching C++ 13 | - to present examples of curriculum for specific courses 14 | 15 | This document does not itself provide a curriculum for a single specific 16 | course, but is rather a set of guidelines that can be used to prepare 17 | curricula for a wide variety of courses that differ in focus and level 18 | of sophistication. 19 | (This said, however, some links to other documents with examples of 20 | curricula for specific courses may be included herein.) 21 | This document only intends to target the teaching of the 22 | most recently ratified version of the C++ standard. 23 | (This said, however, since older versions of this document are also 24 | available, these older versions may be of some use to those who need 25 | guidance in older versions of the standard, at least versions that 26 | do not predate C++20.) 27 | 28 | # Use of This Document 29 | 30 | **[NOTE: This document follows the same license model as the C++ Core 31 | Guidelines. The LICENSE document is taken verbatim from the C++ Core 32 | Guidelines.]** 33 | This document is made available under a MIT-style license. 34 | In simple terms, this license permits copying, use, modification, 35 | and creation of derivative works. 36 | A copy of the license is included in the section [LICENSE](#license). 37 | 38 | # Contributing to This Document 39 | 40 | Contributions to this document are welcome. 41 | If you would like to help with this project as a contributor, 42 | please read the section [How to Contribute](#contributing). 43 | 44 | # Organization of This Document 45 | 46 | The various concepts (i.e., ideas) to potentially be covered 47 | are partitioned into modules. 48 | A module is very broad in scope and consists of numerous topics. 49 | 50 | For each module, topics related to the module are identified. 51 | Then, for each topic, learning outcomes are specified. 52 | In order to address a wide variety of courses on C++, each topic 53 | is addressed at three proficiency levels. 54 | These proficiency levels allow each topic to be covered at more than 55 | one level of detail. 56 | This allows target audiences with different background and learning 57 | objectives to be accommodated. 58 | The three proficiency levels are as follows: 59 | 60 | - foundational: This level gives the learner the idea that a 61 | facility exists, what benefits it offers, and the basic ways of using it. 62 | 63 | - main: This level shows mainstream uses and techniques. 64 | For abstraction and organizational mechanisms it also demonstrates how to 65 | build them. 66 | This level should also give the learner a basic (but not detailed) 67 | understanding of how a 68 | facility might be implemented so that the learner can have a first-order 69 | understanding of any costs involved. 70 | 71 | - advanced: This level gives information suitable for an expert. 72 | For most topics there is an expert level of knowledge that most 73 | programmers rarely need and techniques that require detailed understanding 74 | of language rules or library implementation. 75 | 76 | The remainder of this document is organized as follows. 77 | The various topics are listed grouped by module. 78 | In cases where a topic might be classified into more 79 | than one module, the topic is listed under the module of most direct 80 | relevance. 81 | This is done in order to avoid duplication of content. 82 | (In the case that a topic is equally relevant to multiple modules, 83 | the decision of which to select is made by a proverbial coin toss.) 84 | The order in which modules and topics are presented 85 | is not meant to imply any order of coverage in a course. 86 | The order in which items are listed is essentially arbitrary. 87 | -------------------------------------------------------------------------------- /sources/knowledge_areas.dat: -------------------------------------------------------------------------------- 1 | CM Compilation Model 2 | ? ? ? ? Translation Units 3 | ? ? ? ? Headers 4 | ? ? ? ? Modules 5 | ? ? ? ? Name Mangling 6 | ? ? ? ? Phases of Translation 7 | ? ? ? ? Separate Compilation 8 | ? ? ? ? Linkage 9 | P Preprocessor 10 | ? ? ? ? Preprocessor Metaprogramming 11 | ? ? ? ? Inclusion 12 | ? ? ? ? Macros 13 | B Basics Types, Objects, Values, Expressions, Statements, and Control-Flow Constructs 14 | ? ? ? ? Constant Objects 15 | ? ? ? ? Declarations 16 | def y y y Definitions 17 | ? ? ? ? Selection Constructs (e.g., if, ternary) 18 | ? ? ? ? Looping Constructs (e.g., for, while, etc.) 19 | F Functions 20 | ? ? ? ? Calling Functions 21 | ? ? ? ? Parameter Passing (e.g., Passing By Value and Reference) 22 | func-args y n n Default Arguments 23 | ? ? ? ? Returning Multiple Values 24 | ? ? ? ? Overloading 25 | udl y y n User-Defined Literals 26 | C User-Defined Types (Classes) 27 | ? ? ? ? Special Member Functions 28 | ? ? ? ? Types 29 | ? ? ? ? Conversions 30 | ? ? ? ? Constructors and Destructors 31 | ? ? ? ? Move/Copy Constructors and Assignment Operators 32 | ? ? ? ? Member Functions 33 | ? ? ? ? Sum Types 34 | ? ? ? ? User-Defined Literals 35 | ? ? ? ? Special Member Functions 36 | ? ? ? ? Guidelines for Special Member Functions (e.g., Rule of Five, Rule of Zero) 37 | copy y y n Copy Semantics 38 | ? ? ? ? Moving and Copying 39 | ? ? ? ? Lambdas 40 | I Inheritance and Class Hierarchies 41 | ? ? ? ? Virtual Functions 42 | ? ? ? ? Run-Time Type Information 43 | CT Compile-Time Computation 44 | ? ? ? ? Constant Expressions and Constant Evaluation 45 | static-assert y y n `static_assert` 46 | T Generic Programming (Templates) 47 | ? ? ? ? Concepts 48 | ? ? ? ? SFINAE 49 | ? ? ? ? Template Metaprogramming 50 | ? ? ? ? Function Templates 51 | ? ? ? ? Requires Clauses 52 | req-expr y y n Requires Expressions 53 | EH Error Handling 54 | coe y y n Categories of Errors 55 | ? ? ? ? errno 56 | ? ? ? ? Error Codes 57 | eh y y y Exception Handling 58 | PD Program Design 59 | cont y y y Containers 60 | DE Debugging Errors 61 | compiletimeerr y y y Compile-Time Errors 62 | runtimeerr y y y Run-time Errors 63 | SL Standard Library 64 | ? ? ? ? Input/Output (I/O) 65 | ? ? ? ? Containers, Iterators, and Algorithms 66 | EL External (i.e., Non Standard) Libraries 67 | ? ? ? ? Graphical User Interfaces 68 | BLD Building 69 | ? ? ? ? Software Build Tools 70 | ? ? ? ? Strategies for Handling Build Problems 71 | TD Testing and Debugging 72 | ? ? ? ? Source-Level Debuggers 73 | ? ? ? ? Code Sanitizers 74 | ? ? ? ? Test Frameworks 75 | ? ? ? ? Debugging Strategies 76 | TOOL Tooling 77 | ? ? ? ? Compiler Toolchains 78 | ? ? ? ? IDEs 79 | SD Software Design 80 | ? ? ? ? Design by Contract 81 | 82 | -------------------------------------------------------------------------------- /sources/main_raw.md: -------------------------------------------------------------------------------- 1 | --- 2 | title_logo: images/cpp_logo.png 3 | title: Guidelines for Teaching C++ 4 | author: SG20 (ISO C++ Study Group on Education) 5 | geometry: margin=1in 6 | output: pdf_document 7 | --- 8 | 9 | __INCLUDE__(obtaining_document.md) 10 | 11 | __INCLUDE__(introduction.md) 12 | 13 | # Summary of Modules and Topics 14 | 15 | In the sections that follow, the various modules and topics 16 | are presented. 17 | There is one section per module. 18 | For each module, a table listing the various topics in that module 19 | is provided. 20 | The ID for a topic is linked to the detailed coverage of that 21 | topic that comes later in the document. 22 | If a topic has any learning outcomes at a given proficiency level, this is 23 | indicated by a checkmark ("✔️"). 24 | If a topic has no learning outcomes 25 | (simply because there 26 | are not any, not because the information is missing), 27 | this is indicated by an em dash ("—"). 28 | In the case that the information for a topic is completely 29 | missing, a question mark ("?") symbol is used. 30 | 31 | __INCLUDE__(knowledge_areas_summary.md) 32 | 33 | # Detailed Information for Modules and Topics 34 | 35 | [//]: # ( ********** START OF DETAILED TOPIC DOCUMENTS ********** ) 36 | 37 | INJECT_TEACHING_MODULES_HERE 38 | 39 | [//]: # ( ********** END OF DETAILED TOPIC DOCUMENTS ********** ) 40 | 41 | # License {#license} 42 | 43 | **[NOTE: This license is copied verbatim from the C++ Core Guidelines.]** 44 | ``` 45 | __INCLUDE__(../LICENSE.txt) 46 | ``` 47 | 48 | # Contributors 49 | 50 | ``` 51 | __INCLUDE__(contributors.md) 52 | ``` 53 | 54 | __INCLUDE__(contributing.md) 55 | 56 | __INCLUDE__(glossary.md) 57 | 58 | __INCLUDE__(references.md) 59 | -------------------------------------------------------------------------------- /sources/modules/compilation-model/buildsystems.md: -------------------------------------------------------------------------------- 1 | ## Module name: Build systems 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | ------------------------------------------------------------------------ 12 | Level Objective 13 | ----------------- ------------------------------------------------------ 14 | Foundational --- Knowledge about build systems 15 | 16 | Main --- Usage of build system to compile a executable 17 | 18 | Advanced --- Add external libraries as a dependencies 19 | 20 | ------------------------------------------------------------------------ 21 | 22 | ### Motivation 23 | 24 | _Why is this important?_ 25 | _Why do we want to learn/teach this topic?_ 26 | 27 | * Building complex C++ projects by hand is tricky 28 | * Build systems can help to resolve dependencies 29 | * Build systems can help do distribute C++ code and help other to compile the code 30 | * Build systems can help to find and include libraries as dependencies 31 | * Build systems faciliate project management 32 | * All major C++ projects are distributed with build systems 33 | 34 | ### Topic introduction 35 | 36 | _Very brief introduction to the topic._ 37 | 38 | Build systems are used to configure, build, and install complex C++ projects. 39 | 40 | 41 | ### Foundational: Knowledge about build systems 42 | 43 | #### Background/Required Knowledge 44 | 45 | A student: 46 | * Should know how to compile and link C++ programs 47 | 48 | 49 | #### Student outcomes 50 | 51 | _A list of things "a student should be able to" after the curriculum._ 52 | _The next word should be an action word and testable in an exam._ 53 | _Max 5 items._ 54 | 55 | A student should be able to: 56 | 57 | 1. To explain what a build system is 58 | 2. To explain that a build systems resolves dependencies 59 | 3. To explain that a build system supports compilation for different operating systems and architectures 60 | 61 | #### Caveats 62 | 63 | _This section mentions subtle points to understand, like anything resulting in 64 | implementation-defined, unspecified, or undefined behavior._ 65 | 66 | None 67 | 68 | #### Points to cover 69 | 70 | _This section lists important details for each point._ 71 | 72 | * Mention that many build systems are available for C++ 73 | * Mention benefits and challenges 74 | * Build system help to only compile the C++ files with code changes and not the complete project 75 | 76 | ### Main: Usage of build system to compile a executable 77 | 78 | #### Background/Required Knowledge 79 | 80 | * All of the above. 81 | 82 | #### Student outcomes 83 | 84 | A student should be able to: 85 | 86 | 1. Download a C++ package and build the package 87 | 2. Write a configuration file to compile a C++ executable 88 | 3. Pass compiler options via the build system 89 | 4. Use the build system to generate the executable 90 | 5. Write a configuration file to compile a library and link the library to a C++ executable 91 | 92 | #### Caveats 93 | 94 | The instructions are restricted to the chosen build system and 95 | not easily transferable. 96 | 97 | 98 | #### Points to cover 99 | 100 | * Include paths to header files to the configuration 101 | * Adding compiler flags 102 | * How to build Release and Debug builds 103 | * Linking external libraries to the C++ project 104 | * Support compilation on different operating systems, compilers, and architectures 105 | 106 | 107 | ### Advanced 108 | 109 | _These are important topics that are not expected to be covered but provide 110 | guidance where one can continue to investigate this topic in more depth._ 111 | 112 | * How to build libraries 113 | * How to have external libraries be downloaded during the build process 114 | * Mention that build systems provide support for unit testing 115 | 116 | -------------------------------------------------------------------------------- /sources/modules/compilation-model/linkage.md: -------------------------------------------------------------------------------- 1 | ## C++ compilation model: Linkage {#linkage} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/compilation-model/translation-units.md: -------------------------------------------------------------------------------- 1 | ## C++ compilation model: Translation units {#translunits} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/compile-time-programming/concepts.md: -------------------------------------------------------------------------------- 1 | ## Compile-time programming: concepts 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/compile-time-programming/function-templates.md: -------------------------------------------------------------------------------- 1 | ## Compile-time programming: Function Templates 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/compile-time-programming/requires-clause.md: -------------------------------------------------------------------------------- 1 | ## Compile-time programming: requires-clause 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/compile-time-programming/requires-expressions.md: -------------------------------------------------------------------------------- 1 | ## Module name: Requires Expressions {#req-expr} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | ------------------------------------------------------------------------- 12 | Level Objectives 13 | ------------------ ------------------------------------------------------ 14 | Foundational Define and use requires-expressions to check 15 | satisfaction of expressions by given parameters 16 | 17 | Main Define and use requires-expressions to check 18 | properties of expressions 19 | 20 | Advanced --- 21 | ------------------------------------------------------------------------- 22 | 23 | ### Motivation 24 | 25 | _Why is this important?_ 26 | _Why do we want to learn/teach this topic?_ 27 | 28 | Requires-expressions allow a developer to perform compile-time evaluation 29 | on the validity of other expressions. These are fundamental to the ability 30 | to write concepts. [[Compile-time programming: concepts]][1] 31 | 32 | ## Topic introduction 33 | 34 | _Very brief introduction to the topic._ 35 | 36 | Requires-expressions are compile-time predicates which evaluate to true 37 | when their specified set of expressions are all valid for a given set of 38 | inputs. 39 | 40 | ### Foundational: Writing requires-expressions {#req-expr-basic} 41 | 42 | #### Background/Required Knowledge 43 | 44 | A student is able to: 45 | 46 | * Write and use a function template [[Compile-time programming: function templates]][2] 47 | * Differentiate between expressions and statements 48 | 49 | It is helpful if: 50 | 51 | * The student is aware that attempting to specialize the template with types or values which do not match otherwise unstated assumptions will cause errors within the template. 52 | 53 | #### Student outcomes 54 | 55 | _A list of things "a student should be able to" after the curriculum._ 56 | _The next word should be an action word and testable in an exam._ 57 | _Max 5 items._ 58 | 59 | A student should be able to: 60 | 61 | 1. Write a simple-requirement to assert the validity of an expression 62 | 2. Write a type-requirement to check the existence of a type by its identifier 63 | 3. Write a compound-requirement to test the resulting type of an expression 64 | 4. Write a nested-requirement to test the constexpr value of an operation, as opposed to just the syntactic validity 65 | 5. Use a requires-expression within a concept, requires-clause, or `if constexpr` condition 66 | 67 | #### Caveats 68 | 69 | _This section mentions subtle points to understand, like anything resulting in 70 | implementation-defined, unspecified, or undefined behavior._ 71 | 72 | To require that expressions, which evaluate to a boolean value 73 | like `sizeof(t) == 4`, evaluate to `true` a nested-requirement is needed 74 | (e.g., `requires sizeof(t) == 4;`). Omitting the `requires` results in a 75 | simple-requirement, which is satisfied based purely on syntactic validity, 76 | not on the result of the operation. 77 | 78 | #### Points to cover 79 | 80 | _This section lists important details for each point._ 81 | 82 | * All requires-expression requirements terminate with a semicolon. 83 | * simple-requirements are used to check that an expression is well-formed. 84 | * nested-requirements are introduced with `requires` and primarily used to check the result of an expression computable by the compiler, including concepts or other requires-expressions. 85 | * type-requirements are introduced with `typename` and used to verify the existence of a type with a particular identifier. 86 | * compound-requirements are enclosed in braces and can be used to check the resulting type of an expression. 87 | * Checks are performed by the compiler, not at run time. 88 | * If covering usage of requires-expression with requires-clause, [[Compile-time programming: requires clause]][3] demonstrate `requires requires` and show how to ever avoid writing it by using a concept. [[Compile-time programming: concepts]][1] 89 | 90 | ### Main: Advanced requirements {#req-expr-main} 91 | 92 | #### Background/Required Knowledge 93 | 94 | * All of the above. 95 | * Knowledge of `noexcept` 96 | 97 | A student is able to: 98 | 99 | * Write a concept [[Compile-time programming: concepts]][1] 100 | 101 | #### Student outcomes 102 | 103 | _A list of things "a student should be able to" after the curriculum._ 104 | _The next word should be an action word and testable in an exam._ 105 | _Max 5 items._ 106 | 107 | A student should be able to: 108 | 109 | 1. Write compound-requirements which test the `noexcept`ness of an expression. 110 | 2. Use a concept as the target of a compound-requirement. 111 | 112 | #### Caveats 113 | 114 | _This section mentions subtle points to understand, like anything resulting in 115 | implementation-defined, unspecified, or undefined behavior._ 116 | 117 | #### Points to cover 118 | 119 | _This section lists important details for each point._ 120 | 121 | * Compound-requirements allow the optional ability to test whether an expression is marked as `noexcept`, by using a trailing `noexcept` keyword. 122 | 123 | ```cpp 124 | struct S 125 | { 126 | void foo() noexcept {} 127 | void bar() {} 128 | }; 129 | 130 | static_assert(requires(S s) { { s.foo() } noexcept; } ); // Succeeds. s.foo() is noexcept 131 | static_assert(requires(S s) { { s.bar() } noexcept; } ); // Fails. s.bar() is not noexcept 132 | ``` 133 | 134 | * If the return-type-requirement of a compound-requirement is a concept, that concept is given the resulting type as the first parameter, followed by the specified parameters in the compound-requirement. `{ ++x } -> C` would substitute `C` and check that concept C is satisfied for those parameters. 135 | 136 | ### Advanced {#req-expr-advanced} 137 | 138 | [1]: ../compile-time-programming/concepts.md 139 | [2]: ../compile-time-programming/function-templates.md 140 | [3]: ../compile-time-programming/requires-clause.md 141 | -------------------------------------------------------------------------------- /sources/modules/debugging-errors/build-errors.md: -------------------------------------------------------------------------------- 1 | ## Debugging Errors: Build errors 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/debugging-errors/compiletime-errors.md: -------------------------------------------------------------------------------- 1 | ## Debugging Errors: Compile-time errors {#compiletimeerr} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | ------------------------------------------------------------------------ 12 | Level Objective 13 | ----------------- ------------------------------------------------------ 14 | Foundational Understanding elementary error messages 15 | 16 | Main Dealing with most error messages 17 | 18 | Advanced --- 19 | 20 | ------------------------------------------------------------------------ 21 | 22 | ### Motivation 23 | 24 | _Why is this important?_ 25 | _Why do we want to learn/teach this topic?_ 26 | 27 | Compiler error messages can be hard to read and even compiler specific. 28 | However, they contain valuable information for determining the cause of the compile-time errors. 29 | Oftentimes the error messages are very verbose to give you the most precise information about the error context, so learning how to extract the valuable information from the error message is an important skill that one should acquire. 30 | 31 | ### Topic introduction 32 | 33 | _Very brief introduction to the topic._ 34 | 35 | C++ compilers try to statically determine errors at compile time to shift detection of problems that would occur later on (e.g., at link time or run time) to earlier point in time, where they can be addressed in an earlier stage of the development process. 36 | The error message that the compiler generates directly relates to the C++ language definition and precisely lays out why the code is not valid and where it does not comply with the language rules. 37 | 38 | ### Foundational: Understanding elementary error messages {#compiletimeerr-found} 39 | 40 | #### Background/Required Knowledge 41 | 42 | A student: 43 | 44 | * definitions [[C++ Object Model: Definitions - Foundational]][1] 45 | 46 | #### Student outcomes 47 | 48 | _A list of things "a student should be able to" after the curriculum._ 49 | _The next word should be an action word and testable in an exam._ 50 | _Max 5 items._ 51 | 52 | A student should be able to: 53 | 54 | 1. distill the core of an elementary error message. 55 | 2. act on elementary error messages. 56 | 3. differentiate between different error kinds (e.g., type errors, syntax errors, ...). 57 | 4. give examples for different kinds of errors. 58 | 59 | 60 | #### Caveats 61 | 62 | _This section mentions subtle points to understand, like anything resulting in 63 | implementation-defined, unspecified, or undefined behavior._ 64 | 65 | * names mentioned in error message are presented in full detail and may not look exactly like specified by the programmer (e.g., `std::string` -> `std::basic_string`) 66 | 67 | #### Points to cover 68 | 69 | _This section lists important details for each point._ 70 | 71 | * methodology of reading error messages 72 | * start with the first error 73 | * read top down 74 | * parse error message / pattern matching to error kinds 75 | * linker errors [[Debugging Errors: Build errors - Foundational]][2] 76 | 77 | 78 | ### Main: Dealing with most error messages {#compiletimeerr-main} 79 | 80 | #### Background/Required Knowledge 81 | 82 | * compile-time programming [Soft dependency] 83 | 84 | #### Student outcomes 85 | 86 | A student should be able to: 87 | 88 | 1. locate the principle template involved in a template error message. 89 | 2. determine why a specific overload is chosen, from the compiler’s error message. 90 | 3. apply common debugging techniques in a constexpr context. 91 | 92 | #### Caveats 93 | 94 | * argument dependent lookup 95 | * there is currently no good debugger support for constexpr context 96 | 97 | #### Points to cover 98 | 99 | * templates related error messages 100 | * overload resolution related errors 101 | * reasoning about errors during constexpr execution (consteval) 102 | * reverting to non-constexpr run-time debugging 103 | * employing static_assert 104 | 105 | ### Advanced 106 | 107 | _These are important topics that are not expected to be covered but provide 108 | guidance where one can continue to investigate this topic in more depth._ 109 | 110 | * Full error analysis, there are error messages that are out of the scope for students. 111 | * Complicated SFINAE constructs 112 | 113 | [1]: ../object-model/definitions.md 114 | [2]: ../debugging-errors/build-errors.md 115 | -------------------------------------------------------------------------------- /sources/modules/debugging-errors/runtime-errors.md: -------------------------------------------------------------------------------- 1 | ## Debugging errors: Run-time errors {#runtimeerr} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | ------------------------------------------------------------------------ 12 | Level Objective 13 | ----------------- ------------------------------------------------------ 14 | Foundational Identifying the run-time error cause 15 | 16 | Main Introspection methodologies to trackdown run-time errors 17 | 18 | Advanced --- 19 | 20 | ------------------------------------------------------------------------ 21 | 22 | ### Motivation 23 | 24 | _Why is this important?_ 25 | _Why do we want to learn/teach this topic?_ 26 | 27 | Code correctness is important, as erroneous programs can lead to real-world catastrophes, take for example, medical equipment failures that lead to people being exposed to too much radiation. 28 | Techniques, such as, testing or fuzzing, help developers to identify erroneous states of the program. 29 | However, when these techniques discover a run-time error, it’s up to the programmer to reason about and find the root cause of such run-time errors, so they need a well established process to debug run-time errors. 30 | 31 | ### Topic introduction 32 | 33 | _Very brief introduction to the topic._ 34 | 35 | There exists a wide variety of methodologies, techniques, and tools to debug run-time errors. 36 | In this topic, we give an overview of these and highlight how they can be applied to track down run-time errors in C++ programs. 37 | 38 | ### Foundational: Identifying the run-time error cause {#runtimeerr-found} 39 | 40 | #### Background/Required Knowledge 41 | 42 | A student: 43 | 44 | * should be able to produce a basic running program. 45 | 46 | #### Student outcomes 47 | 48 | _A list of things "a student should be able to" after the curriculum._ 49 | _The next word should be an action word and testable in an exam._ 50 | _Max 5 items._ 51 | 52 | A student should be able to: 53 | 54 | 1. verify the output of the program and identify incorrect outcomes. 55 | 2. phrase hypothesis what could cause the run-time error. 56 | 3. observe and extract program state at specific points of the program, to verify hypotheses. 57 | 4. make their program as observable as possible. 58 | 59 | #### Caveats 60 | 61 | _This section mentions subtle points to understand, like anything resulting in 62 | implementation-defined, unspecified, or undefined behavior._ 63 | 64 | * run-time debugging can be domain specific 65 | * not everything about the program state can be easily observed, students should be aware of that and learn basic techniques to make programs more observable 66 | * students should be aware that the compilation mode (optimized vs debug) affects the debugging experience and also the program state itself 67 | 68 | 69 | #### Points to cover 70 | 71 | _This section lists important details for each point._ 72 | 73 | * the basics of using a debugger 74 | * compiling with debug information 75 | * observability techniques, such as, logging output or even `printf` statements 76 | 77 | ### Main: Introspection methodologies to trackdown run-time errors {#runtimeerr-main} 78 | 79 | #### Background/Required Knowledge 80 | 81 | * All of the above. 82 | 83 | #### Student outcomes 84 | 85 | A student should be able to: 86 | 87 | 1. use a debugger to inspect and manipulate program state 88 | 2. extract crash information using proper libraries 89 | 3. can create a minimal reproducible example 90 | 91 | #### Caveats 92 | 93 | * Different forms of multiprocessing programs can have varying impact on debuggability, such as: 94 | * parallel stl algorithms 95 | * multi threading 96 | * coroutines 97 | * vector parallelism 98 | 99 | 100 | #### Points to cover 101 | 102 | * How to use debuggers and the multitude of features they offer to manipulate and observe program state (e.g., break points, trap points, stack traces, manipulating program state). 103 | * Use (non) standard library support for crash information extraction, e.g., logging libraries, libraries to capture crash reports, and sanitizer libraries (asan/ubsan/tsan). 104 | * Creating minimal reproducible example and regressions tests from the extracted crash information. 105 | 106 | 107 | ### Advanced {#runtimeerr-advanced} 108 | 109 | _These are important topics that are not expected to be covered but provide 110 | guidance where one can continue to investigate this topic in more depth._ 111 | 112 | * ABI incompatibilities can have impact debugging experience where even observability tools, such as, debuggers, cannot correctly show the state of the program. 113 | * Debugging in embedded environments. 114 | -------------------------------------------------------------------------------- /sources/modules/error-handling/c-style-error-codes.md: -------------------------------------------------------------------------------- 1 | ## Error handling: C-style error codes {#cerrcodes} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/error-handling/categories-of-errors.md: -------------------------------------------------------------------------------- 1 | ## Error handling: Categories of errors 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | ------------------------------------------------------------------------ 12 | Level Objective 13 | ----------------- ------------------------------------------------------ 14 | Foundational Categories of errors 15 | 16 | Main Handling different categories of errors 17 | 18 | Advanced --- 19 | 20 | ------------------------------------------------------------------------ 21 | 22 | ### Motivation 23 | 24 | _Why is this important?_ 25 | _Why do we want to learn/teach this topic?_ 26 | 27 | Programs can run in a normal state or erroneous state. Students should be able 28 | to identify different types of erroneous state and how to best handle them. 29 | 30 | ### Topic introduction 31 | 32 | _Very brief introduction to the topic._ 33 | 34 | This topic is an umbrella topic that refers to the different topics for types of errors and error handling. 35 | 36 | ### Foundational: Categories of errors {#coe-found} 37 | 38 | #### Background/Required Knowledge 39 | 40 | A student: 41 | 42 | * should know the basics about linkage [[C++ compilation model: Linkage - Foundational]][1] 43 | 44 | #### Student outcomes 45 | 46 | _A list of things "a student should be able to" after the curriculum._ 47 | _The next word should be an action word and testable in an exam._ 48 | _Max 5 items._ 49 | 50 | A student should be able to: 51 | 52 | 1. Describe different kinds of errors and exceptional situations that require different approaches of error handling. 53 | 2. Provide some examples of the different error categories. 54 | 3. Identify potential erroneous code sections and attribute them to different error categories. 55 | 56 | 57 | #### Caveats 58 | 59 | _This section mentions subtle points to understand, like anything resulting in 60 | implementation-defined, unspecified, or undefined behavior._ 61 | 62 | No caveats at present. 63 | 64 | #### Points to cover 65 | 66 | _This section lists important details for each point._ 67 | 68 | Errors can happen at different times during software lifetime. 69 | 70 | * Compile-time errors 71 | * Link-time errors 72 | * Execution-time errors 73 | 74 | There are different types of errors 75 | 76 | * Logic errors (violations of logical preconditions) 77 | * Run-time errors (errors during code execution due to causes that are external to the program) 78 | 79 | 80 | ### Main: Handling different categories of errors {#coe-main} 81 | 82 | #### Background/Required Knowledge 83 | 84 | #### Student outcomes 85 | 86 | A student should be able to: 87 | 88 | 1. pick the right error handling approach for a given problem. 89 | 2. enumerate different error handling strategies. 90 | 3. make a clear distinction between error-handling code and normal-case handling code 91 | 92 | 93 | #### Caveats 94 | 95 | * The different error handling strategies have different trade-offs (runtime performance, readability, ...) 96 | * The trade-off space depends on the run-time context (embedded, ...) 97 | * There also exist unhandleable errors (e.g., ODR violations, undefined behavior) 98 | 99 | #### Points to cover 100 | 101 | * Exception handling [[Error handling: Exception handling - Foundational]][2] 102 | * Returning a value indication failure [[Error handling: C-style error-codes - Foundational]][3] 103 | * Terminating the program 104 | * Improving error handling by having the error occur at an earlier stage in the software development cycle [[Error handling: Static assert - Foundational]][4] 105 | 106 | ### Advanced {#coe-advanced} 107 | 108 | _These are important topics that are not expected to be covered but provide 109 | guidance where one can continue to investigate this topic in more depth._ 110 | 111 | [1]: ../compilation-model/linkage.md 112 | [2]: ../error-handling/exception-handling.md 113 | [3]: ../error-handling/c-style-error-codes.md 114 | [4]: ../error-handling/static-assert.md 115 | -------------------------------------------------------------------------------- /sources/modules/error-handling/error-codes.md: -------------------------------------------------------------------------------- 1 | ## Error handling: Error codes {#ecodes} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | ------------------------------------------------------------------------ 12 | Level Objective 13 | ----------------- ------------------------------------------------------ 14 | Foundational Handling error codes with `std::error_code` 15 | 16 | Main Designing APIs around `std::error_code` 17 | 18 | Advanced --- 19 | 20 | ------------------------------------------------------------------------ 21 | 22 | ### Motivation 23 | 24 | _Why is this important?_ 25 | _Why do we want to learn/teach this topic?_ 26 | 27 | C++ offers a type safe way of passing around errors, contrary to the C-style of error handling, by this, we prevent bugs when passing error codes. 28 | Furthermore, error handling with error codes is more commonly used than exception handling, which only should be used in exceptional situations and in some environments is not feasible at all, e.g., in embedded or performance critical software. 29 | 30 | ### Topic introduction 31 | 32 | _Very brief introduction to the topic._ 33 | 34 | C++ offers `std::error_code`, which encapsulates error codes in a type safe way. 35 | This topic describes how to use these error codes. 36 | 37 | ### Foundational: Handling error codes with `std::error_code` {#eh-found} 38 | 39 | #### Background/Required Knowledge 40 | 41 | A student: 42 | 43 | * should know that there are different ways of error handling [[Error handling: Categories of errors]][1] 44 | * should know function return values 45 | 46 | #### Student outcomes 47 | 48 | _A list of things "a student should be able to" after the curriculum._ 49 | _The next word should be an action word and testable in an exam._ 50 | _Max 5 items._ 51 | 52 | A student should be able to: 53 | 54 | 1. write code to handle errors with `std::error_code`, e.g., obtain the message of the error code or check if an error occurred. 55 | 2. distinguish between the different categories and make justified decisions when to use which 56 | 57 | #### Caveats 58 | 59 | _This section mentions subtle points to understand, like anything resulting in 60 | implementation-defined, unspecified, or undefined behavior._ 61 | 62 | #### Points to cover 63 | 64 | _This section lists important details for each point._ 65 | 66 | * a brief overview of `std::error_code` and how to use it 67 | 68 | ### Main: Designing APIs around `std::error_code` {#eh-main} 69 | 70 | #### Background/Required Knowledge 71 | 72 | * should know how to use reference parameters as an output parameter 73 | 74 | #### Student outcomes 75 | 76 | A student should be able to: 77 | 78 | 1. create an `error_code` and design API that work with `std:error_code` 79 | 2. write code that utilizes `std::error_category` 80 | 3. explain the difference between C-style error handling with errno and `std::error_code` 81 | 4. make effective use of the interface of `std::error_code` 82 | 83 | #### Caveats 84 | 85 | * reset errno before calling a function that might set errno (better pass an input parameter `std::error_code`) 86 | 87 | #### Points to cover 88 | 89 | * provide a full picture of `std::error_code` and it’s APIs 90 | * `std::error_category` (explorative) 91 | 92 | ### Advanced 93 | 94 | _These are important topics that are not expected to be covered but provide 95 | guidance where one can continue to investigate this topic in more depth._ 96 | 97 | * implementing your own `error_category` 98 | 99 | [1]: error-handling/categories-of-errors.md 100 | -------------------------------------------------------------------------------- /sources/modules/error-handling/exception-handling.md: -------------------------------------------------------------------------------- 1 | ### Overview 2 | 3 | _Provides a short natural language abstract of the module’s contents._ 4 | _Specifies the different levels of teaching._ 5 | 6 | ------------------------------------------------------------------------ 7 | Level Objective 8 | ----------------- ------------------------------------------------------ 9 | Foundational Standards exception hierarchy 10 | 11 | Main Exception guarantees 12 | 13 | Advanced --- 14 | 15 | ------------------------------------------------------------------------ 16 | 17 | ### Motivation 18 | 19 | _Why is this important?_ 20 | _Why do we want to learn/teach this topic?_ 21 | 22 | Exception handling is used to be able to continue the program in case of 23 | exceptional situations (like requesting a ridiculous amount of memory: 24 | `bad_alloc`). 25 | 26 | ### Topic introduction 27 | 28 | _Very brief introduction to the topic._ 29 | 30 | There are other forms of handling difficult situations, but here we concentrate 31 | on exception handling and the peculiarities/characteristics of it. Because 32 | there are different forms, we should know when to use which type of handling 33 | special situations. 34 | 35 | ### Foundational: Standards exception hierarchy {#eh-found} 36 | 37 | #### Background/Required Knowledge 38 | 39 | A student: 40 | 41 | * should know about basic and user-defined types [[Type system: fundamental types]][1] [[Type system: user-defined types]][2] 42 | * should know about flow of control [???] 43 | * should know about blocks and statements [???] 44 | 45 | #### Student outcomes 46 | 47 | _A list of things "a student should be able to" after the curriculum._ 48 | _The next word should be an action word and testable in an exam._ 49 | _Max 5 items._ 50 | 51 | A student should be able to: 52 | 53 | 1. Explain how some `std::` calls may cause an exception 54 | 2. Discern the different standard exception types 55 | 3. Write simple try … except code (e.g., out of memory, vector at indexing) 56 | 4. Explain on a “simplified” conceptual level what happens when an exception is thrown and is bubbled up through the callers until it is caught 57 | 58 | 59 | #### Caveats 60 | 61 | _This section mentions subtle points to understand, like anything resulting in 62 | implementation-defined, unspecified, or undefined behavior._ 63 | 64 | * Exceptions should be used for exceptional situations and should not be used to manage normal control flow. 65 | 66 | #### Points to cover 67 | 68 | _This section lists important details for each point._ 69 | 70 | * Exception hierarchy from the standard library 71 | * Common library functions that may throw exceptions 72 | * Basic handling exceptions: try/catch/throw 73 | * How exceptions bubble up until caught 74 | 75 | 76 | ### Main: Exception guarantees {#eh-main} 77 | 78 | #### Background/Required Knowledge 79 | 80 | * RAII 81 | * Order of construction/destruction of class members 82 | 83 | #### Student outcomes 84 | 85 | A student should be able to: 86 | 87 | 1. Explain the four different exception guarantees 88 | 2. Explain the exception guarantees that the standard library containers offer. 89 | 3. Explain what happens when a exception is thrown in constructor 90 | 91 | 92 | #### Caveats 93 | 94 | * Make sure code is designed with RAII in mind to prevent resources leaking during exception handling, when the stack is unwound. 95 | * Care should be taken in constructor design to make all fully constructed members deleted when the stack unwinding mechanism is activated. 96 | 97 | #### Points to cover 98 | 99 | * Exception guarantees: Nothrow/Strong/Basic/No 100 | * Rethrowing an exception 101 | 102 | ### Advanced: Exception-safe containers and edge cases {#eh-advanced} 103 | 104 | _These are important topics that are not expected to be covered but provide 105 | guidance where one can continue to investigate this topic in more depth._ 106 | 107 | * Rethrowing a modified exception 108 | * Writing exception safe containers 109 | 110 | [1]: ../type-system/fundamental-types.md 111 | [2]: ../type-system/user-defined-types.md -------------------------------------------------------------------------------- /sources/modules/error-handling/static-assert.md: -------------------------------------------------------------------------------- 1 | ## Error handling: Static assert {#staticassert} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/functions/calling-functions.md: -------------------------------------------------------------------------------- 1 | ## C++ functions: calling functions 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/functions/defaulted-parameters.md: -------------------------------------------------------------------------------- 1 | ## Functions: default argument {#func-args} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | Functions in C++ may be overloaded with different numbers and types of 12 | parameters. It may be of value to specify default arguments for some number 13 | of parameters, to allow a caller to avoid specifying arguments that 14 | rarely change, or to enable expanding the set of parameters while 15 | maintaining backward compatibility with existing callers. 16 | 17 | ------------------------------------------------------------------------ 18 | Level Objective 19 | ----------------- ------------------------------------------------------ 20 | Foundational Define and use functions with default arguments 21 | 22 | Main --- 23 | 24 | Advanced refinement of default arguments through multiple 25 | declarations 26 | ------------------------------------------------------------------------ 27 | 28 | ### Motivation 29 | 30 | _Why is this important?_ 31 | _Why do we want to learn/teach this topic?_ 32 | 33 | Default arguments allow the omission of arguments with obvious or common 34 | values. Also may be utilized to extend an existing function signature 35 | without forcing changes to existing calling code. 36 | 37 | ### Topic introduction 38 | 39 | _Very brief introduction to the topic._ 40 | 41 | Explain how default arguments work and how to define them. 42 | 43 | ### Foundational: Using and defining functions with default arguments {#func-args-basic} 44 | 45 | #### Background/Required Knowledge 46 | 47 | A student is able to: 48 | 49 | * Make calls to existing functions, passing arguments [[Functions: calling functions]][1] 50 | * Declare member and non-member functions, separate from definitions 51 | * Define member and non-member functions [[Functions: member functions]][2] 52 | * Explain what a default constructor is and does [[C++ object model: constructors]][3] 53 | 54 | #### Student outcomes 55 | 56 | _A list of things "a student should be able to" after the curriculum._ 57 | _The next word should be an action word and testable in an exam._ 58 | _Max 5 items._ 59 | 60 | A student should be able to: 61 | 62 | 1. Call to a function with a default argument with or without that argument specified 63 | 2. Declare a function with a default argument, and omit the default in the definition's signature 64 | 3. Explain when the lifetime of a default argument begins and ends 65 | 66 | 67 | #### Caveats 68 | 69 | _This section mentions subtle points to understand, like anything resulting in 70 | implementation-defined, unspecified, or undefined behavior._ 71 | 72 | * When no forward-declaration exists, the definition serves as the declaration 73 | * When multiple declarations exist, only one may specify the default for any particular parameter, but multiple declarations may specify the defaults for different parameters. 74 | * Additional default values may be specified for other parameters in repeat declarations 75 | * Calling an overloaded function with fewer arguments may be ambiguous with regard to an overload with default arguments 76 | 77 | #### Points to cover 78 | 79 | _This section lists important details for each point._ 80 | 81 | * Default value may only be specified once for each parameter among all declarations 82 | * Default values must start from the rightmost parameter and continue leftward without gaps 83 | * Considerations of when to use default arguments vs overload set 84 | 85 | ### Main: implementing * {#func-args-main} 86 | 87 | #### Background/Required knowledge 88 | 89 | * All of the above. 90 | 91 | #### Student outcomes 92 | 93 | _A list of things "a student should be able to" after the curriculum._ 94 | _The next word should be an action word and testable in an exam._ 95 | _Max 5 items._ 96 | 97 | A student should be able to: 98 | 99 | #### Caveats 100 | 101 | _This section mentions subtle points to understand, like anything resulting in 102 | implementation-defined, unspecified, or undefined behavior._ 103 | 104 | #### Points to cover 105 | 106 | _This section lists important details for each point._ 107 | 108 | ### Advanced {#func-args-advanced} 109 | 110 | _These are important topics that are not expected to be covered but provide 111 | guidance where one can continue to investigate this topic in more depth._ 112 | 113 | Subsequent redeclarations of the same function may add default argument 114 | values, which are then usable by callers. 115 | Though a single parameter cannot be given a default argument twice in the same 116 | translation unit, it is legal, though ill-advised, to give the same 117 | function different default arguments in different translation units. 118 | 119 | 120 | [1]: ../functions/calling-functions.md 121 | [2]: ../functions/member-functions.md 122 | [3]: ../object-model/constructors.md 123 | -------------------------------------------------------------------------------- /sources/modules/functions/member-functions.md: -------------------------------------------------------------------------------- 1 | ## C++ functions: member functions 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/functions/passing-parameters-by-reference.md: -------------------------------------------------------------------------------- 1 | # Module name: Passing Parameters by Reference 2 | _Skeleton descriptions are typeset in italic text,_ 3 | _so please don't remove these descriptions when editing the topic._ 4 | 5 | ## Overview 6 | 7 | _Provides a short natural language abstract of the module’s contents._ 8 | _Specifies the different levels of teaching._ 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
LevelObjectives
FoundationalAvoiding copies using const-reference modifiers
MainUsing references to modify external data
Advanced
28 | 29 | ## Motivation 30 | 31 | _Why is this important?_ 32 | _Why do we want to learn/teach this topic?_ 33 | 34 | ## Topic introduction 35 | 36 | _Very brief introduction to the topic._ 37 | 38 | Explain what a reference type is and how it constrasts with a value type. 39 | 40 | ## Foundational: Using reference types to avoid copies 41 | 42 | ### Background/Required Knowledge 43 | 44 | A student is able to: 45 | 46 | * Define and call a function with parameters 47 | 48 | ### Student outcomes 49 | 50 | _A list of things "a student should be able to" after the curriculum._ 51 | _The next word should be an action word and testable in an exam._ 52 | _Max 5 items._ 53 | 54 | A student should be able to: 55 | 56 | 1. Use const-refernce types for function arguments 57 | 2. Explain what considerations to take when deciding whether or not to use a const-reference type 58 | 59 | ### Caveats 60 | 61 | _This section mentions subtle points to understand, like anything resulting in 62 | implementation-defined, unspecified, or undefined behavior._ 63 | 64 | ### Points to cover 65 | 66 | _This section lists important details for each point._ 67 | 68 | * No copy of the data is made when taken by constant reference 69 | * A constant reference value cannot be modified 70 | * The lifetime of a constant reference cannot be expected to extend beyond the lifetime of the function, so the reference should not be saved off for future use. 71 | * Taking a reference is not always a time or space savings. Modern machines may use 8-bytes to reference a 4-byte integer, for instance. 72 | 73 | ## Main: Using references to modify external data 74 | 75 | ### Background/Required Knowledge 76 | 77 | * All of the above 78 | 79 | ### Student outcomes 80 | 81 | A student should be able to: 82 | 83 | 1. Define and utilize a non-const reference for passing values out of a function 84 | 85 | ### Caveats 86 | 87 | ### Points to cover 88 | 89 | * If the function does not intend to modify the value, const-references should be preferred 90 | * A reference value may be modified 91 | * The lifetime of a reference cannot be expected to extend beyond the lifetime of the function, so the reference should not be saved off for future use. 92 | * Taking a reference is not always a time or space savings. Modern machines may use 8-bytes to reference a 4-byte integer, for instance. 93 | 94 | ## Advanced 95 | 96 | _These are important topics that are not expected to be covered but provide 97 | guidance where one can continue to investigate this topic in more depth._ 98 | 99 | -------------------------------------------------------------------------------- /sources/modules/functions/passing-parameters-by-value.md: -------------------------------------------------------------------------------- 1 | # Module name: Passing Parameters by Value 2 | _Skeleton descriptions are typeset in italic text,_ 3 | _so please don't remove these descriptions when editing the topic._ 4 | 5 | ## Overview 6 | 7 | _Provides a short natural language abstract of the module’s contents._ 8 | _Specifies the different levels of teaching._ 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
LevelObjectives
FoundationalDefining and calling functions with values
Main
Advanced
28 | 29 | ## Motivation 30 | 31 | _Why is this important?_ 32 | _Why do we want to learn/teach this topic?_ 33 | 34 | The fundamental element for code-reuse is a function. For functions to be 35 | useful, we need to parameterize them. Understanding how to do such is thus 36 | fundamental to programming in any language. 37 | 38 | ## Topic introduction 39 | 40 | _Very brief introduction to the topic._ 41 | 42 | Explain how to define functions with parameters and call them with values. 43 | 44 | ## Foundational: Using reference types to avoid copies 45 | 46 | ### Background/Required Knowledge 47 | 48 | A student is able to: 49 | 50 | * Explain what a function is 51 | 52 | ### Student outcomes 53 | 54 | _A list of things "a student should be able to" after the curriculum._ 55 | _The next word should be an action word and testable in an exam._ 56 | _Max 5 items._ 57 | 58 | A student should be able to: 59 | 60 | 1. Call a function with any number of parameters using the same number of arguments 61 | 2. Define a function with any number of parameters 62 | 63 | ### Caveats 64 | 65 | _This section mentions subtle points to understand, like anything resulting in 66 | implementation-defined, unspecified, or undefined behavior._ 67 | 68 | ### Points to cover 69 | 70 | _This section lists important details for each point._ 71 | 72 | * A function is called by invoking the name of the function, followed by parentheses 73 | * For each parameter in the function signature, a value must be provided, and in the same order 74 | * Multiple values passed to a function are comma-separated 75 | * When defining a function, you must list the parameters with the type first, and parameter name second 76 | 77 | ## Main: Using references to modify external data 78 | 79 | ### Background/Required Knowledge 80 | 81 | ### Student outcomes 82 | 83 | ### Caveats 84 | 85 | ### Points to cover 86 | 87 | ## Advanced 88 | 89 | _These are important topics that are not expected to be covered but provide 90 | guidance where one can continue to investigate this topic in more depth._ 91 | 92 | -------------------------------------------------------------------------------- /sources/modules/functions/user-defined-literals.md: -------------------------------------------------------------------------------- 1 | ## Functions: user-defined literals (UDL) {#udl} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | Literals are a way to write values in the code, such as strings and numbers. 12 | User-defined literals (UDL) allow to add a suffix to a string or number to change the meaning. 13 | The suffix selects a function (an operator) that can alter the value and type of the literal. 14 | The C++ library provides certain operators already and a user can add more by providing such operators. 15 | 16 | ------------------------------------------------------------------------- 17 | Level Objectives 18 | ---------------- -------------------------------------------------------- 19 | Foundational using and understanding UDLs 20 | 21 | Main implementing your own UDLs 22 | 23 | Advanced Advanced use (```"{}, {}!"_fmt("Hello", "World")```) 24 | ------------------------------------------------------------------------- 25 | 26 | ### Motivation 27 | 28 | _Why is this important?_ 29 | _Why do we want to learn/teach this topic?_ 30 | 31 | * Allows clearer expression of intent in C++. 32 | * `std::string`: `"Hello, world!"s` 33 | * `std::chrono`: `3h + 10min + 5s` 34 | 35 | ### Topic introduction 36 | 37 | _Very brief introduction to the topic._ 38 | 39 | * Explain the existence of user defined literals. Example: `12min + 17s` is terse, 40 | expressive and type safe. 41 | 42 | ### Foundational: Using UDLs {#udl-basic} 43 | 44 | 45 | #### Background/Required Knowledge 46 | 47 | 48 | A student: 49 | * knows how to form numeric literals, e.g., `1.5f` means a `float` of value `1.5`. 50 | * is familiar with the major C++ types: 51 | * `bool` (Boolean type) 52 | * `int` (Integer type) 53 | * `double` (Floating-point type) 54 | * `std::string` (Text type) 55 | * `std::vector` (Collection type) 56 | * knows that namespaces exist, and namespace `std`. 57 | * knows what using-declarations and using-directives are. [[C++ object model: declarations]][2] 58 | 59 | #### Student outcomes 60 | 61 | _A list of things "a student should be able to" after the curriculum._ 62 | _The next word should be an action word and testable in an exam._ 63 | _Max 5 items._ 64 | 65 | A student should be able to: 66 | 67 | 1. use `using namespace std::string_literals`\[1]. 68 | 2. recognise UDLs in code that they are reading. 69 | 3. figure out which UDL definitions for a used type exist. 70 | 4. identify parts of the standard library that make use of UDLs. 71 | 5. prevent the dangers of temporaries created with `"blah"s` as well as with 72 | `std::string{"blah"}`. 73 | 6. effectively selects the right set of namespaces in using-directives from the 74 | sub-namespaces `std::literals`. 75 | 76 | \[1]: explain that it's okay to use a using-directive to "activate" UDLs. 77 | 78 | #### Caveats 79 | 80 | _This section mentions subtle points to understand, like anything resulting in 81 | implementation-defined, unspecified, or undefined behavior._ 82 | 83 | * A student gets confused by the similarities and differences between built-in 84 | suffixes and UDLs and between UDLs from different namespaces. 85 | * A student "activates" two suffixes with the same signature from different 86 | namespaces. 87 | 88 | #### Points to cover 89 | 90 | _This section lists important details for each point._ 91 | 92 | ### Main: implementing UDLs {#udl-main} 93 | 94 | 95 | #### Background/Required Knowledge 96 | 97 | 98 | * All of the above. 99 | 100 | #### Student outcomes 101 | 102 | _A list of things "a student should be able to" after the curriculum._ 103 | _The next word should be an action word and testable in an exam._ 104 | _Max 5 items._ 105 | 106 | A student should be able to: 107 | 108 | 1. write a UDL operator of their own. 109 | 2. separate unrelated UDLs into distinct namespaces. 110 | 111 | #### Caveats 112 | 113 | _This section mentions subtle points to understand, like anything resulting in 114 | implementation-defined, unspecified, or undefined behavior._ 115 | 116 | No caveats at present. 117 | #### Points to cover 118 | 119 | _This section lists important details for each point._ 120 | 121 | No caveats at present. 122 | ### Advanced {#udl-advanced} 123 | 124 | _These are important topics that are not expected to be covered but provide 125 | guidance where one can continue to investigate this topic in more depth._ 126 | 127 | [1]: ../object-model/types.md 128 | [2]: ../object-model/declarations.md 129 | -------------------------------------------------------------------------------- /sources/modules/meta-error-handling/static_assert.md: -------------------------------------------------------------------------------- 1 | ## Meta-error handling: `static_assert` {#static-assert} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | ---------------------------------------------------------------------------- 12 | Level Objectives 13 | ---------------- ----------------------------------------------------------- 14 | Foundational Calling ```static_assert``` with a constant expression 15 | 16 | Main Using ```static_assert``` to detect contract violations 17 | and improve error messages 18 | 19 | Advanced --- 20 | ---------------------------------------------------------------------------- 21 | 22 | ### Motivation 23 | 24 | _Why is this important?_ 25 | _Why do we want to learn/teach this topic?_ 26 | 27 | `static_assert` allows the developer to enforce that conditions which can 28 | be checked during compilation will force build errors when violated. 29 | Additionally, they are the best mechanism by which a developer can pass 30 | useful information to other developers regarding what violation occurred or 31 | what must be done, instead. 32 | 33 | ### Topic introduction 34 | 35 | _Very brief introduction to the topic._ 36 | 37 | `static_assert` is a compile-time evaluated function that asserts the 38 | truth of a supplied predicate, issuing an optional user-supplied error 39 | message if the predicate is `false`. 40 | 41 | ### Foundational: Calling `static_assert` with a constant expression {#static-assert-basic} 42 | 43 | #### Background/Required Knowledge 44 | 45 | A student: 46 | 47 | * Should be able to explain the difference between code evaluated at compile-time and run-time 48 | * Should be able to cite some examples of compile-time known information, such as `sizeof(T)` 49 | 50 | #### Student outcomes 51 | 52 | _A list of things "a student should be able to" after the curriculum._ 53 | _The next word should be an action word and testable in an exam._ 54 | _Max 5 items._ 55 | 56 | A student should be able to: 57 | 58 | 1. Assert the expected size of a structure using `static_assert` 59 | 60 | #### Caveats 61 | 62 | _This section mentions subtle points to understand, like anything resulting in 63 | implementation-defined, unspecified, or undefined behavior._ 64 | 65 | #### Points to cover 66 | 67 | _This section lists important details for each point._ 68 | 69 | * X 70 | * In addition to what is wrong, a good error message will inform the user of how to correct it 71 | 72 | ### Main: Contracts and `static_assert` {#static-assert-main} 73 | 74 | #### Background/Required Knowledge 75 | 76 | * All of the above. 77 | * General understanding of compile-time requirements 78 | 79 | #### Student outcomes 80 | 81 | _A list of things "a student should be able to" after the curriculum._ 82 | _The next word should be an action word and testable in an exam._ 83 | _Max 5 items._ 84 | 85 | A student should be able to: 86 | 87 | 1. Utilize `static_assert` to verify preconditions of a meta-function 88 | 2. Utilize `static_assert` to verify the results of meta-functions for known values 89 | 90 | #### Caveats 91 | 92 | _This section mentions subtle points to understand, like anything resulting in 93 | implementation-defined, unspecified, or undefined behavior._ 94 | 95 | #### Points to cover 96 | 97 | _This section lists important details for each point._ 98 | 99 | * When writing a meta-function, use `static_assert` to test the results 100 | * Write `static_assert` calls at the scope of the code they are guarding 101 | ```cpp 102 | template 103 | struct container { 104 | std::map vals; 105 | 106 | // Test location #1 107 | static_assert( 108 | std::is_default_constructible_v, 109 | "container type T must be default constructible");i 110 | 111 | void add(int key, T const& t) { 112 | // Test location #2 113 | static_assert( 114 | std::is_default_constructible_v, 115 | "container type T must be default constructible"); 116 | // std::map::operator[] requires default constructible type for 117 | // the value. This will cause a build failure deep in the 118 | // implementation of std::map, when T is not default constructible 119 | vals[key] = t; 120 | } 121 | }; 122 | 123 | struct NoDefCtor { 124 | NoDefCtor() = delete; 125 | NoDefCtor(double d) {} 126 | }; 127 | 128 | container c; // If Test #1 was omitted, this would succeed 129 | // This is ill-formed. Test #2 would catch this and provide a better 130 | // error message for the user 131 | c.add(42, NoDefCtor(1.0)); 132 | ``` 133 | 134 | ### Advanced {#static-assert-advanced} 135 | 136 | _These are important topics that are not expected to be covered but provide 137 | guidance where one can continue to investigate this topic in more depth._ 138 | -------------------------------------------------------------------------------- /sources/modules/object-model/constant-objects.md: -------------------------------------------------------------------------------- 1 | ## C++ object model: constant objects 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/object-model/constructors.md: -------------------------------------------------------------------------------- 1 | ## C++ object model: constructor 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/object-model/copy-semantics.md: -------------------------------------------------------------------------------- 1 | ## C++ object model: copy semantics {#copy} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | --------------------------------------------------------- 12 | Level Objectives 13 | ------------- ------------------------------------------- 14 | Foundational understanding how and when are copies made 15 | 16 | Main implementing user-defined copy operations 17 | 18 | Advanced special cases: copy elision 19 | --------------------------------------------------------- 20 | 21 | ### Motivation 22 | 23 | _Why is this important?_ 24 | _Why do we want to learn/teach this topic?_ 25 | 26 | Copy semantics allows the user to define how objects of a class get replicated and interact on a value level. 27 | 28 | ### Topic introduction 29 | 30 | _Very brief introduction to the topic._ 31 | 32 | Explains when and how objects are copied. 33 | 34 | ### Foundational: How and when are copies made {#copy-basic} 35 | 36 | #### Background/Required Knowledge 37 | 38 | 39 | A student is able to: 40 | * explain what a C++ type is? [[C++ object model: types]][1] 41 | * explain what an object is? [[C++ object model: objects]][2], [[C++ object model: constant objects]][3] 42 | * define and understand class invariants? 43 | 44 | It helps when a student is able to: 45 | * use move semantics [[C++ object model: move semantics]][4] 46 | * explain special member functions [[C++ object model: special member functions]][5] 47 | 48 | #### Student outcomes 49 | 50 | _A list of things "a student should be able to" after the curriculum._ 51 | _The next word should be an action word and testable in an exam._ 52 | _Max 5 items._ 53 | 54 | A student should be able to: 55 | 56 | 1. explain what copy semantics accomplish 57 | * establishing "equivalent" object state in another object 58 | 2. explain difference between copying a reference and copying a value\* 59 | 3. explain where copies are made 60 | 61 | \* In other languages these differences are sometimes referred to as shallow and deep copy. 62 | 63 | #### Caveats 64 | 65 | _This section mentions subtle points to understand, like anything resulting in 66 | implementation-defined, unspecified, or undefined behavior._ 67 | 68 | * Compiler-provided copy operations may result in ownership problems (e.g., `char*`). These ownership problems can generally be solved by using types whose copy operations have the appropriate semantics, e.g., `std::string` instead of `char*` to hold string values. 69 | 70 | #### Points to cover 71 | 72 | _This section lists important details for each point._ 73 | 74 | * Principle of copying 75 | * Copying of types, which follow the rule of zero 76 | * Copying of types, with user defined copy operations 77 | * Copying an object does not change the original 78 | * Practical applications 79 | * `std::unique_ptr` (has no copy) 80 | * Strings (copies the value) 81 | 82 | 83 | ### Main: Implementing user-defined copy operations {#copy-main} 84 | 85 | 86 | #### Background/Required Knowledge 87 | 88 | 89 | A student is able to: 90 | * identify special member functions [[C++ object model: special member functions]][5] 91 | 92 | It helps when a student is able to: 93 | * use move semantics [[C++ object model: move semantics]][4] 94 | * explain the rule of zero [[C++ object model: rule-of-zero]][7] 95 | * explain the rule of five [[C++ object model: rule-of-five]][6] 96 | 97 | #### Student outcomes 98 | 99 | _A list of things "a student should be able to" after the curriculum._ 100 | _The next word should be an action word and testable in an exam._ 101 | _Max 5 items._ 102 | 103 | A student should be able to: 104 | * explain when they have to implement the copy operations for their own type 105 | * Copy constructor 106 | * Copy assignment operator 107 | * implement copy operations for their own types 108 | * _Optional_: explain when copying with basic and strong exception guarantees is useful 109 | 110 | #### Caveats 111 | 112 | _This section mentions subtle points to understand, like anything resulting in 113 | implementation-defined, unspecified, or undefined behavior._ 114 | 115 | * Intricacies when implementing copy operations: 116 | * Examples of how _not_ to write copy operations (e.g., C++03 `std::auto_ptr`) 117 | 118 | #### Points to cover 119 | 120 | _This section lists important details for each point._ 121 | 122 | * Copy constructors and copy assignment operators 123 | * How compiler generates default copy operations 124 | * =default, =delete (No copy) 125 | * How-to write your own copy operations 126 | * Rule-of-five 127 | * Copy assignment operators can be ref-qualified to avoid assigning into temporary objects. 128 | 129 | ### Advanced {#copy-advanced} 130 | 131 | _These are important topics that are not expected to be covered but provide 132 | guidance where one can continue to investigate this topic in more depth._ 133 | 134 | When can copies be elided and when does the standard guarantee copy elision. 135 | References: 136 | * [Abseil tip of the Week #166](https://abseil.io/tips/166) 137 | * [cppreference - Copy elision](https://en.cppreference.com/w/cpp/language/copy_elision) 138 | 139 | [1]: ../object-model/types.md 140 | [2]: ../object-model/objects.md 141 | [3]: ../object-model/constant-objects.md 142 | [4]: ../object-model/move-semantics.md 143 | [5]: ../object-model/special-member-functions.md 144 | [6]: ../object-model/rule-of-five.md 145 | [7]: ../object-model/rule-of-zero.md 146 | -------------------------------------------------------------------------------- /sources/modules/object-model/declarations.md: -------------------------------------------------------------------------------- 1 | ## C++ object model: Declarations 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | ------------------------------------------------------------------------ 12 | Level Objective 13 | ----------------- ------------------------------------------------------ 14 | Foundational Declaring variables 15 | 16 | Main Declaring for programs 17 | 18 | Advanced Special cases and peculiarities 19 | 20 | ------------------------------------------------------------------------ 21 | 22 | ### Motivation 23 | 24 | _Why is this important?_ 25 | _Why do we want to learn/teach this topic?_ 26 | 27 | * Introduces a name and it’s type 28 | * `int baz;` 29 | * `void bar();` 30 | * `class Foo;` 31 | 32 | ### Topic introduction 33 | 34 | _Very brief introduction to the topic._ 35 | 36 | Introduce names and their associated type in a scope. 37 | 38 | ### Foundational: Declaring variables 39 | 40 | 41 | #### Background/Required Knowledge 42 | 43 | 44 | A student: 45 | 46 | * is familiar with the basic C++ types: 47 | * bool (Boolean type) 48 | * int (Integer type) 49 | * double (Floating-point type) 50 | 51 | #### Student outcomes 52 | 53 | _A list of things "a student should be able to" after the curriculum._ 54 | _The next word should be an action word and testable in an exam._ 55 | _Max 5 items._ 56 | 57 | A student should be able to: 58 | 59 | 1. declare a variable with a specific type ‘int baz;’ 60 | 2. declare a function ‘void bar();’ 61 | 3. declare a class ‘class Foo;’ 62 | 4. forward declare a user-defined type or a function 63 | 5. explain the difference between a definition and a declaration 64 | 65 | #### Caveats 66 | 67 | _This section mentions subtle points to understand, like anything resulting in 68 | implementation-defined, unspecified, or undefined behavior._ 69 | 70 | No caveats at present. 71 | 72 | #### Points to cover 73 | 74 | _This section lists important details for each point._ 75 | 76 | ### Main: Declarations for programs 77 | 78 | 79 | #### Background/Required Knowledge 80 | 81 | 82 | * All of the above. 83 | * Basic template syntax 84 | 85 | #### Student outcomes 86 | 87 | _A list of things "a student should be able to" after the curriculum._ 88 | _The next word should be an action word and testable in an exam._ 89 | _Max 5 items._ 90 | 91 | A student should be able to: 92 | 93 | 1. create header and source files with a declaration in the former and definition of a variable/function in the latter 94 | 2. declare type aliases to introduce a type with an alternative name ‘using std::string;’ 95 | 3. write a forward template declaration 96 | 97 | #### Caveats 98 | 99 | _This section mentions subtle points to understand, like anything resulting in 100 | implementation-defined, unspecified, or undefined behavior._ 101 | 102 | * Declaring aliases can introduce name clashes 103 | * Prefer using declaration’s over using directives in header files [link] 104 | * The order of declarations dictates the order of initialization 105 | 106 | #### Points to cover 107 | 108 | _This section lists important details for each point._ 109 | 110 | ### Advanced 111 | 112 | _These are important topics that are not expected to be covered but provide 113 | guidance where one can continue to investigate this topic in more depth._ 114 | 115 | * asm declaration 116 | * using-enum-declaration 117 | * extern "C" declarations 118 | -------------------------------------------------------------------------------- /sources/modules/object-model/definitions.md: -------------------------------------------------------------------------------- 1 | ## C++ object model: Definitions {#def} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | ------------------------------------------------------------------------ 12 | Level Objective 13 | ----------------- ------------------------------------------------------ 14 | Foundational Defining variables and ODR 15 | 16 | Main Defining for programs 17 | 18 | Advanced Special cases and peculiarities 19 | 20 | ------------------------------------------------------------------------ 21 | 22 | ### Motivation 23 | 24 | _Why is this important?_ 25 | _Why do we want to learn/teach this topic?_ 26 | 27 | * A definition is a declaration that supplies all that is needed for a complete entity 28 | * `int baz = 42;` 29 | * `void bar() { /* implementation */ }` 30 | * `class Foo { /* class body */ };` 31 | 32 | ### Topic introduction 33 | 34 | _Very brief introduction to the topic._ 35 | 36 | A definition extends a declaration, providing all that is needed for a complete 37 | entity, e.g., allocate memory for variables, provide the implementation for 38 | functions, complete definitions of data and function members of a class. 39 | 40 | ### Foundational: Defining variables and ODR {#def-found} 41 | 42 | 43 | #### Background/Required Knowledge 44 | 45 | 46 | A student: 47 | 48 | * is familiar with declarations [[C++ object model: declarations]][1] 49 | 50 | #### Student outcomes 51 | 52 | _A list of things "a student should be able to" after the curriculum._ 53 | _The next word should be an action word and testable in an exam._ 54 | _Max 5 items._ 55 | 56 | A student should be able to: 57 | 58 | 1. define a variable with a specific type `int baz = 42;` 59 | 2. define a function `void bar() {}` 60 | 3. define a class `class Foo {};` 61 | 4. explain the one definition rule 62 | 63 | 64 | #### Caveats 65 | 66 | _This section mentions subtle points to understand, like anything resulting in 67 | implementation-defined, unspecified, or undefined behavior._ 68 | 69 | No caveats at present. 70 | 71 | #### Points to cover 72 | 73 | _This section lists important details for each point._ 74 | 75 | * One definition rule (ODR) 76 | 77 | ### Main: Defining for programs {#def-main} 78 | 79 | 80 | #### Background/Required Knowledge 81 | 82 | 83 | * All of the above. 84 | * is familiar with declarations [[C++ object model: declarations]][1] 85 | 86 | #### Student outcomes 87 | 88 | _A list of things "a student should be able to" after the curriculum._ 89 | _The next word should be an action word and testable in an exam._ 90 | _Max 5 items._ 91 | 92 | A student should be able to: 93 | 94 | 1. organize variables, functions, classes into multiple translation units, describing interface with declarations and providing the implementations with definitions without violating ODR. 95 | 2. distinguish between template declaration and definition 96 | 97 | #### Caveats 98 | 99 | _This section mentions subtle points to understand, like anything resulting in 100 | implementation-defined, unspecified, or undefined behavior._ 101 | 102 | * Putting a definition into a header file that is included more than once leads to ODR violations, possibly resulting in linker errors. 103 | 104 | #### Points to cover 105 | 106 | _This section lists important details for each point._ 107 | 108 | ### Advanced: Special cases and peculiarities {#def-advanced} 109 | 110 | _These are important topics that are not expected to be covered but provide 111 | guidance where one can continue to investigate this topic in more depth._ 112 | 113 | * ABI Incompatibilities: Different definitions of the same type in multiple object files can lead to subtle program errors. 114 | 115 | [1]: ../object-model/declarations.md 116 | -------------------------------------------------------------------------------- /sources/modules/object-model/move-semantics.md: -------------------------------------------------------------------------------- 1 | ## C++ object model: move semantics 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/object-model/objects.md: -------------------------------------------------------------------------------- 1 | ## C++ object model: objects 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/object-model/rule-of-five.md: -------------------------------------------------------------------------------- 1 | ## C++ object model: rule of five 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/object-model/rule-of-zero.md: -------------------------------------------------------------------------------- 1 | ## C++ object model: rule of zero 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/object-model/special-member-functions.md: -------------------------------------------------------------------------------- 1 | ## C++ object model: special member functions 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/object-model/types.md: -------------------------------------------------------------------------------- 1 | ## C++ object model: types 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/program-design/algorithms.md: -------------------------------------------------------------------------------- 1 | ## Program Design: Algorithms 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/program-design/concepts.md: -------------------------------------------------------------------------------- 1 | See [concepts](../compile-time-programmings/concepts.md). 2 | -------------------------------------------------------------------------------- /sources/modules/program-design/containers.md: -------------------------------------------------------------------------------- 1 | ## Program Design: Containers {#cont} 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | ------------------------------------------------------------------------ 12 | Level Objective 13 | ----------------- ------------------------------------------------------ 14 | Foundational Using standard containers 15 | 16 | Main Extending standard containers and day-to-day usages 17 | 18 | Advanced --- 19 | 20 | ------------------------------------------------------------------------ 21 | 22 | ### Motivation 23 | 24 | _Why is this important?_ 25 | _Why do we want to learn/teach this topic?_ 26 | 27 | Storing data is an essential part of computations. 28 | We use abstractions to make it easier to reason about and work with the data. 29 | This leads to grouping related data variables together in data structures to give the grouping a name and to be able to make multiple instances of that data structure. 30 | Data structures are therefore foundational building blocks for program design and are present in almost every program. 31 | 32 | Data structures come in many different forms, but there are special data structures that group objects of related types together. 33 | In C++ these collections of data are called containers. 34 | The C++ standard library provides a wide range of such common containers. 35 | To make algorithms more universally applicable to containers, the standard library defines a common interface. 36 | This way, containers build a bridge between algorithms and how data is organized. 37 | 38 | 39 | ### Topic introduction 40 | 41 | _Very brief introduction to the topic._ 42 | 43 | ### Foundational: Using standard containers {#cont-found} 44 | 45 | #### Background/Required Knowledge 46 | 47 | A student: 48 | 49 | * "for loops" 50 | * "defining variables" 51 | * "main function" 52 | 53 | #### Student outcomes 54 | 55 | _A list of things "a student should be able to" after the curriculum._ 56 | _The next word should be an action word and testable in an exam._ 57 | _Max 5 items._ 58 | 59 | A student should be able to: 60 | 61 | 1. setup and add objects to a container 62 | 2. work with objects that are stored in a container 63 | 64 | #### Caveats 65 | 66 | _This section mentions subtle points to understand, like anything resulting in 67 | implementation-defined, unspecified, or undefined behavior._ 68 | 69 | * On a foundational level, avoid using iterators when teaching containers to prevent problems, such as iterator invalidation or dangling iterators. 70 | * Avoid going deep into the template notation 71 | * Teach people to not use `vector` 72 | 73 | #### Points to cover 74 | 75 | _This section lists important details for each point._ 76 | 77 | * Creating containers, adding objects, iterating over them using range based or index based for loops. 78 | * `vector`, `string`, `unordered_map`, `unordered_set` 79 | * Notation for having container of different value types with angle brackets 80 | 81 | 82 | ### Main: Extending standard containers and day-to-day usages {#cont-main} 83 | 84 | #### Background/Required Knowledge 85 | 86 | * Basic understanding of standard algorithms [[Program Design: Algorithms - Foundational]][1] 87 | * Basic understanding of classes and class templates [[User-defined Types: Class Templates - Foundational]][2] 88 | 89 | #### Student outcomes 90 | 91 | A student should be able to: 92 | 93 | 1. make effective use of the standard containers. 94 | 2. make use of iterators to iterate over a sequence and call algorithms. 95 | 3. make a proper choice what container to use based on its characteristics. 96 | 4. write a container class template for a specific need (based on a standard container). 97 | 5. make use of common container idioms. 98 | 99 | #### Caveats 100 | 101 | * Iterator invalidation 102 | * When extending standard containers, prefer delegation over inheritance 103 | 104 | #### Points to cover 105 | 106 | * Alternative ways of iterating over a container using iterators 107 | * Adapting or extending standard containers (e.g., writing wrapper types with additional semantics) 108 | * Discuss the different characteristics and trade-offs of standard containers 109 | * Common idioms (e.g., find-erase) 110 | * Usage of end-of-sequence iterators [[Program Design: Iterators - Foundational]][3] 111 | * [Optional] Using containers together with ranges [[Program Design: Ranges - Foundational]][4] 112 | 113 | 114 | ### Advanced 115 | 116 | _These are important topics that are not expected to be covered but provide 117 | guidance where one can continue to investigate this topic in more depth._ 118 | 119 | * creating your own STL compatible containers from the ground up 120 | * using containers with non-default allocators 121 | 122 | [1]: ../program-design/algorithms.md 123 | [2]: ../user-defined-types/class-templates.md 124 | [3]: ../program-design/iterators.md 125 | [4]: ../program-design/ranges.md 126 | -------------------------------------------------------------------------------- /sources/modules/program-design/iterators.md: -------------------------------------------------------------------------------- 1 | ## Program Design: Iterators 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/program-design/ranges.md: -------------------------------------------------------------------------------- 1 | ## Program Design: Ranges 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/type-system/fundamental-types.md: -------------------------------------------------------------------------------- 1 | ## Type system: Fundamental types 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/type-system/user-defined-types.md: -------------------------------------------------------------------------------- 1 | ## Types system: User-defined types 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/user-defined-types/class-templates.md: -------------------------------------------------------------------------------- 1 | ## User-defined Types: Class Templates 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /sources/modules/user-defined-types/user-defined-literals.md: -------------------------------------------------------------------------------- 1 | See [user-defined-literals](../functions/user-defined-literals.md). 2 | -------------------------------------------------------------------------------- /sources/obtaining_document.md: -------------------------------------------------------------------------------- 1 | # Obtaining This Document: The Most Recent Version and Alternate Formats 2 | 3 | The most recent version of this document is available as an online 4 | HTML document at: 5 | . 6 | 7 | The version of the document that you are currently reading is available in the 8 | following formats: 9 | 10 | 1. online (HTML) format as a single large HTML document: 11 | 12 | 13 | 2. EPUB format: 14 | 15 | 16 | 3. online (HTML) format, split across multiple HTML documents: 17 | 18 | **[Note: The support for this format needs more work (in order to beautify 19 | and fix linking issues).]** 20 | 21 | Older versions of this document are also available. 22 | In general version _ver_ is available at 23 | https://cplusplus.github.io/SG20/_ver_/html. 24 | For example, version 0.1.0 (assuming that this version exists) would be 25 | available at . 26 | -------------------------------------------------------------------------------- /sources/references.md: -------------------------------------------------------------------------------- 1 | # References 2 | 3 | ## References on Learning Outcomes 4 | 5 | - D. Kennedy, A. Hyland, and N. Ryan. 6 | Writing and Using Learning Outcomes: A Practical Guide, 2007. 7 | . 8 | 9 | - B. S. Bloom, M. D. Engelhart, E. J. Furst, W. H. Hill, and D. R. Krathwohl. 10 | Taxonomy of educational objectives: The classification of educational goals. 11 | Handbook I: Cognitive domain. New York: David McKay Company, 1956. 12 | 13 | - Bloom's Taxonomy. 14 | . 15 | 16 | - Effective Use of Performance Objectives for Learning and Assessment 17 | (For Use With Fink’s and Bloom’s Taxonomies), 18 | University of New Mexico, School of Medicine, Teaching and Educational Development, 19 | . 20 | 21 | ## Working Group Documents Related to C++ Teaching Guidelines 22 | 23 | - Christopher Di Bella, Simon Brand, and Michael Adams. 24 | P1389R0 --- 25 | Standing Document for SG20: Guidelines for Teaching C++ to Beginners. 26 | . 27 | 28 | - Christopher Di Bella. 29 | P1725R0 --- 30 | Modular Topic Design. 31 | . 32 | 33 | - JC van Winkel, Bjarne Stroustrup, and Florian Sattler. 34 | P2193 --- 35 | How to structure a teaching topic. 36 | . 37 | 38 | - JC van Winkel and Christopher Di Bella. 39 | P1231 --- 40 | Proposal for Study Group: C++ Education. 41 | . 42 | 43 | - H. Hinnant, R. Orr, B. Stroustrup, D. Vandevoorde, and M. Wong. 44 | P2000 --- 45 | Direction for ISO C++, Section 5.1. 46 | . 47 | -------------------------------------------------------------------------------- /tools/build/aspell_frontend: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | cmd_dir="$(dirname "$0")" || exit 1 4 | 5 | top_dir="$cmd_dir/../.." 6 | spellcheck_dir="$top_dir/config/spellcheck" 7 | wordlist="wordlist" 8 | if [ ! -f "$spellcheck_dir/$wordlist" ]; then 9 | echo "ERROR" 10 | exit 1 11 | fi 12 | tmp_wordlist=$(mktemp /tmp/wordlist.XXXXXX) 13 | cat $spellcheck_dir/wordlist $spellcheck_dir/ignored_words.txt > $tmp_wordlist 14 | exec aspell --home-dir="$spellcheck_dir" --personal $tmp_wordlist --lang en "$@" 15 | -------------------------------------------------------------------------------- /tools/build/build: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | ################################################################################ 4 | # Some helper functions. 5 | ################################################################################ 6 | 7 | # Terminate with error. 8 | panic() 9 | { 10 | echo "ERROR: $@" 1>&2 11 | exit 1 12 | } 13 | 14 | # Print usage information. 15 | usage() 16 | { 17 | echo "bad usage: $@" 18 | cat << EOF 19 | build - Build the document. 20 | 21 | Usage 22 | ===== 23 | 24 | $0 -d \$install_dir -v \$version 25 | 26 | Options 27 | ======= 28 | 29 | -d \$install_dir 30 | Set the installation directory for the built release to \$install_dir. 31 | 32 | -v \$version 33 | Set the document version $\version. 34 | 35 | Examples 36 | ======== 37 | 38 | $0 -d /tmp/sg20_test/install -v v0.0.1 39 | EOF 40 | exit 2 41 | } 42 | 43 | ################################################################################ 44 | # Perform some basic initialization. 45 | ################################################################################ 46 | 47 | cmd_dir=$(dirname "$0") || panic "cannot determine directory name" 48 | source_dir="$cmd_dir/../.." 49 | 50 | ################################################################################ 51 | # Parse command line. 52 | ################################################################################ 53 | 54 | install_dir= 55 | version= 56 | spellcheck=0 57 | 58 | while getopts d:v:s opt; do 59 | case $opt in 60 | d) 61 | install_dir="$OPTARG";; 62 | v) 63 | version="$OPTARG";; 64 | s) 65 | spellcheck=1;; 66 | \?) 67 | usage 68 | break;; 69 | esac 70 | done 71 | shift $((OPTIND - 1)) 72 | 73 | if [ -z "$install_dir" ]; then 74 | usage "no output directory specified" 75 | fi 76 | if [ -z "$version" ]; then 77 | usage "no document version specified" 78 | fi 79 | 80 | version=PR_${version%/*} 81 | 82 | ################################################################################ 83 | # Build the document. 84 | ################################################################################ 85 | 86 | if [ ! -d "$install_dir" ]; then 87 | mkdir -p "$install_dir" || \ 88 | panic "cannot make installation directory $install_dir" 89 | fi 90 | 91 | (cd "$source_dir" && make clean) || \ 92 | panic "cannot make clean" 93 | 94 | (cd "$source_dir" && \ 95 | make DOC_VERSION="$version" DOC_SPELLCHECK_MUST_PASS="$spellcheck" all) || \ 96 | panic "cannot build document" 97 | 98 | make DOC_VERSION="$version" INSTALL_DIR="$install_dir/$version" install || \ 99 | panic "cannot install release" 100 | 101 | cp $source_dir/sources/index.html $install_dir 102 | 103 | pushd $install_dir 104 | unlink latest 105 | ln -s $version/html latest 106 | popd 107 | -------------------------------------------------------------------------------- /tools/build/generate_main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Generates a complete main file that includes all teaching modules. 4 | """ 5 | import typing as tp 6 | from argparse import ArgumentParser 7 | from pathlib import Path 8 | 9 | 10 | def is_placeholder(module_file: Path) -> bool: 11 | """ 12 | Checks if a given module file is only a placeholder. 13 | 14 | Args: 15 | module_file: that should be checked 16 | """ 17 | with open(module_file, "r", encoding="UTF-8") as module: 18 | for line in module.readlines()[:7]: 19 | if line.startswith("This topic is currently under construction"): 20 | return True 21 | 22 | return False 23 | 24 | 25 | def inject_teaching_modules(main_file: tp.TextIO, module_folder: Path) -> None: 26 | """ 27 | Injects '__INCLUDE__(module/file/path.md)' markers into the main file for 28 | all modules found in the given module folder. 29 | 30 | Args: 31 | main_file: where generated input is written to 32 | module_folder: location of the teaching module folder 33 | """ 34 | for module in module_folder.glob('**/*.md'): 35 | if not is_placeholder(module): 36 | main_file.write(f"__INCLUDE__({module})\n\n") 37 | 38 | 39 | def generate_main(raw_main_filepath: Path, output_filepath: Path, 40 | module_folder: Path) -> None: 41 | """ 42 | Generate a complete main file that includes all teaching modules. 43 | 44 | Args: 45 | raw_main: file that will be processed 46 | output_filename: where generated input should be written 47 | module_folder: location of the teaching module folder 48 | """ 49 | with open(raw_main_filepath, "r", encoding="UTF-8") as raw_main, open( 50 | output_filepath, "w", encoding="UTF-8") as generated_main_file: 51 | 52 | for line in raw_main.readlines(): 53 | if line.startswith("INJECT_TEACHING_MODULES"): 54 | inject_teaching_modules(generated_main_file, module_folder) 55 | else: 56 | generated_main_file.write(line) 57 | 58 | 59 | def main(): 60 | """Parse inputs and kick of main generation.""" 61 | parser = ArgumentParser("topic_updater") 62 | parser.add_argument("--raw", 63 | type=Path, 64 | help="The raw main file to process.") 65 | parser.add_argument("--out", 66 | type=Path, 67 | help="Output filename for the generated main.") 68 | parser.add_argument("--module-folder", 69 | type=Path, 70 | help="Path to the module folder.") 71 | 72 | args = parser.parse_args() 73 | 74 | generate_main(args.raw, args.out, args.module_folder) 75 | 76 | 77 | if __name__ == "__main__": 78 | main() 79 | -------------------------------------------------------------------------------- /tools/build/make_markdown: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | awk ' 4 | function output(level, old_level, label, basic, main, advanced, text) { 5 | bad_char = "?"; 6 | check_char = "✔️"; 7 | emdash = "—"; 8 | 9 | if (level == 1) { 10 | if (label == "?") { 11 | label = bad_char; 12 | } else { 13 | if (basic == "y") { 14 | basic = sprintf("[%s](#%s-basic)", check_char, label); 15 | } else if (basic == "n") { 16 | basic = emdash; 17 | } 18 | if (main == "y") { 19 | main = sprintf("[%s](#%s-main)", check_char, label); 20 | } else if (main == "n") { 21 | main = emdash; 22 | } 23 | if (advanced == "y") { 24 | advanced = sprintf("[%s](#%s-advanced)", check_char, label); 25 | } else if (advanced == "n") { 26 | advanced = emdash; 27 | } 28 | } 29 | label = sprintf("[%s](#%s)", label, label); 30 | } 31 | 32 | if (level == 1 && old_level < 1) { 33 | printf "\n| ID | Unit | Foundational | Main | Advanced |\n"; 34 | printf "|---|----------|---|---|---|\n"; 35 | } 36 | if (level == 1) { 37 | printf "| [%s] | %s | %s | %s | %s |\n", label, text, basic, main, advanced; 38 | } 39 | if ((level == 0 || level == -1) && old_level > 0) { 40 | printf "\n\n"; 41 | } 42 | if (level == 0) { 43 | printf "\n"; 44 | printf "## %s {#%s}\n", text, label; 45 | } 46 | } 47 | 48 | BEGIN { 49 | old_level = -1; 50 | } 51 | 52 | (NF > 0) { 53 | line = $0; 54 | level = 0; 55 | while (substr(line, level + 1, 1) == "\t") { 56 | ++level; 57 | } 58 | 59 | label = ""; 60 | basic = ""; 61 | main = ""; 62 | advanced = ""; 63 | text = ""; 64 | 65 | if (level == 0) { 66 | 67 | label = $1; 68 | text = substr($0, index($0, $2)); 69 | output(level, old_level, label, basic, main, advanced, text); 70 | 71 | } else if (level == 1) { 72 | 73 | label = $1; 74 | basic = $2; 75 | main = $3; 76 | advanced = $4; 77 | text = substr($0, index($0, $5)); 78 | 79 | output(level, old_level, label, basic, main, advanced, text); 80 | 81 | } 82 | 83 | old_level = level; 84 | 85 | } 86 | 87 | END { 88 | 89 | level = -1; 90 | 91 | label = ""; 92 | basic = ""; 93 | main = ""; 94 | advanced = ""; 95 | text = ""; 96 | 97 | output(level, old_level, label, basic, main, advanced, text); 98 | 99 | } 100 | 101 | ' - 102 | -------------------------------------------------------------------------------- /tools/build/prebuild: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | # Terminate with error. 4 | panic() 5 | { 6 | echo "ERROR: $@" 1>&2 7 | exit 1 8 | } 9 | 10 | # Initialize the list of required packages. 11 | packages=() 12 | packages+=(pandoc) 13 | packages+=(texinfo) 14 | packages+=(aspell) 15 | #packages+=(hunspell) 16 | 17 | # Install the packages. 18 | sudo apt-get install -y "${packages[@]}" || \ 19 | panic "unable to install packages" 20 | -------------------------------------------------------------------------------- /tools/build/preprocessor: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | program_dir="$(dirname "$0")" || exit 1 4 | program_pathname="$0" 5 | 6 | panic() 7 | { 8 | echo "ERROR: $@" 9 | exit 1 10 | } 11 | 12 | usage() 13 | { 14 | echo "bad usage: $@" 15 | exit 2 16 | } 17 | 18 | level=0 19 | version= 20 | 21 | while getopts v:l: opt; do 22 | case $opt in 23 | v) 24 | version="$OPTARG";; 25 | l) 26 | level="$OPTARG";; 27 | \?) 28 | usage 29 | break;; 30 | esac 31 | done 32 | shift $((OPTIND - 1)) 33 | 34 | if [ -z "$version" ]; then 35 | usage "no version specified" 36 | fi 37 | if [ "$level" -gt 10 ]; then 38 | panic "recursion too deep" 39 | fi 40 | 41 | awk -v program="$program_pathname" -v level="$level" -v version="$version" ' 42 | /^__INCLUDE__(.*)/ { 43 | i = length("__INCLUDE__("); 44 | start = i + 1; 45 | while (substr($0, i, 1) != ")") { 46 | ++i; 47 | } 48 | end = i; 49 | path = substr($0, start, end - start); 50 | result = system(sprintf("cat %s | %s -l %d -v %s", path, program, level + 1, version)); 51 | if (result) { 52 | printf "error processing %s\n", path > "/dev/stderr"; 53 | exit 1; 54 | } 55 | next; 56 | } 57 | { 58 | print $0; 59 | } 60 | ' - | \ 61 | sed -e 's/__VERSION__/'"$version"'/g' 62 | 63 | status=("${PIPESTATUS[@]}") 64 | for i in "${status[@]}"; do 65 | if [ "$i" -ne 0 ]; then 66 | panic "preprocessor failed" 67 | fi 68 | done 69 | -------------------------------------------------------------------------------- /tools/mgmt_tools/gen_readme.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Small tool to generate a Readme.md file as an overview of all teaching modules 4 | and topics. 5 | 6 | > ./gen_readme.py 7 | """ 8 | from pathlib import Path 9 | from typing import List 10 | import re 11 | 12 | FOLDER_SKIP_LIST = ['.git', '.github', '.mypy_cache', "__pycache__", 'tools'] 13 | README_HEADER = "# SG20: Teaching Topics" 14 | DO_NOT_EDIT_WARNING = """ 20 | """ 21 | 22 | 23 | def create_markdown_anchor(header: str) -> str: 24 | """ 25 | Creates an markdown anchor for a header. 26 | 27 | >>> create_markdown_anchor("C++ compilation model") 28 | '(#c-compilation-model)' 29 | >>> create_markdown_anchor("# C++ compilation model") 30 | '(#c-compilation-model)' 31 | """ 32 | header_anchor = header.lower() 33 | header_anchor = header_anchor.lstrip("# ") 34 | header_anchor = header_anchor.replace(' ', '-') 35 | header_anchor = header_anchor.replace('+', '') 36 | return f"(#{header_anchor})" 37 | 38 | 39 | def create_header_link(header: str) -> str: 40 | """ 41 | Creates a link for the specified header. 42 | 43 | >>> create_header_link("# My header") 44 | '[My header](#my-header)' 45 | """ 46 | return f"[{header.lstrip('# ')}]{create_markdown_anchor(header)}" 47 | 48 | 49 | class TeachingTopic: 50 | """Abstraction for a teaching topic.""" 51 | 52 | LINK_REGEX = re.compile(r".*\((?P.*)\)") 53 | 54 | def __init__(self, name: str, path: Path) -> None: 55 | self.__name = name 56 | self.__path = TeachingTopic.exchange_path_with_orignal_topic_file_path( 57 | path) 58 | 59 | @property 60 | def name(self) -> str: 61 | """Name of the topic.""" 62 | return self.__name 63 | 64 | @property 65 | def path(self) -> Path: 66 | """Path to the topic file.""" 67 | return self.__path 68 | 69 | @staticmethod 70 | def exchange_path_with_orignal_topic_file_path(path: Path) -> Path: 71 | """ 72 | For topics that occure in more than one module, all except for the 73 | original topic file are placeholders that forward the reader to the 74 | original file. To make navigating easier, we automatically exchange the 75 | path of a topic file with the original path, so users can get directly 76 | to the desired file. 77 | """ 78 | with open(path, "r") as topic_file: 79 | first_line = topic_file.readline() 80 | if first_line.lower().startswith("see "): 81 | match = TeachingTopic.LINK_REGEX.search(first_line) 82 | if match: 83 | # Strip leading ../ because we are at the top level dir 84 | return Path(match.group("path").lstrip("./")) 85 | 86 | return path 87 | 88 | 89 | class TeachingModule: 90 | """Abstraction for a teaching module folder.""" 91 | def __init__(self, title: str, path: Path, 92 | topics: List[TeachingTopic]) -> None: 93 | self.__title = title 94 | self.__path = path 95 | self.__topics = topics 96 | 97 | @property 98 | def title(self) -> str: 99 | """Title of the teaching module.""" 100 | return self.__title 101 | 102 | @property 103 | def path(self) -> Path: 104 | """Path to the module folder.""" 105 | return self.__path 106 | 107 | @property 108 | def topics(self) -> List[TeachingTopic]: 109 | """List of teaching topics.""" 110 | return self.__topics 111 | 112 | @staticmethod 113 | def convert_folder_name_to_title(folder_name: str) -> str: 114 | """Converts a module folder name to the corresponding title. 115 | 116 | >>> TeachingModule.convert_folder_name_to_title("user-defined-types") 117 | 'User-defined types' 118 | >>> TeachingModule.convert_folder_name_to_title("functions") 119 | 'Functions' 120 | >>> TeachingModule.convert_folder_name_to_title("error-handling") 121 | 'Error handling' 122 | """ 123 | # Special module names where we need specific name replacements 124 | special_cases = { 125 | "meta-error-handling": "Meta-error handling", 126 | "compile-time-programming": "Compile-time programming", 127 | "user-defined-types": "User-defined types", 128 | "object-model": "C++ object model" 129 | } 130 | title: str = "" 131 | if folder_name in special_cases: 132 | title = special_cases[folder_name] 133 | else: 134 | title = folder_name 135 | title = title.replace("-", " ") 136 | 137 | title = title.capitalize() 138 | return title 139 | 140 | @staticmethod 141 | def parse_module(module_dir: Path) -> 'TeachingModule': 142 | """Parse `TeachingModule` from file path.""" 143 | module_title = TeachingModule.convert_folder_name_to_title( 144 | module_dir.name) 145 | 146 | teaching_topics: List[TeachingTopic] = [] 147 | for topic_path in module_dir.iterdir(): 148 | teaching_topics.append(TeachingTopic(topic_path.stem, topic_path)) 149 | 150 | return TeachingModule(module_title, module_dir, teaching_topics) 151 | 152 | 153 | def create_module_title_with_header_link(module: TeachingModule) -> str: 154 | """ 155 | Creates a module title with string with a link to the corresponding header 156 | anchor. 157 | 158 | >>> create_module_title_with_header_link(TeachingModule(\ 159 | "C++ compilation model", Path("."),["Foo", "Bar"])) 160 | '[C++ compilation model](#c-compilation-model)' 161 | """ 162 | return create_header_link(module.title) 163 | 164 | 165 | def create_topic_path_link(topic: TeachingTopic) -> str: 166 | """ 167 | Creates a link for the specified topic. 168 | 169 | >>> create_topic_path_link(TeachingTopic(\ 170 | "Constant objects",\ 171 | Path("./object-model/constant-objects.md"))) 172 | '[Constant objects](object-model/constant-objects.md)' 173 | """ 174 | return f"[{topic.name}]({str(topic.path)})" 175 | 176 | 177 | def create_topic_list_item(topic: TeachingTopic) -> str: 178 | """Creates a list item for a topic. 179 | 180 | >>> create_topic_list_item(TeachingTopic(\ 181 | "Constant objects",\ 182 | Path("./object-model/constant-objects.md"))) 183 | '* [Constant objects](object-model/constant-objects.md)\\n' 184 | """ 185 | return f"* {create_topic_path_link(topic)}\n" 186 | 187 | 188 | def readme_generator_driver() -> None: 189 | """ 190 | Run the Readme.md generation process. 191 | """ 192 | readme_filename = "Readme.md" 193 | repo_root = Path('sources/modules/') 194 | teaching_modules: List[TeachingModule] = [] 195 | 196 | for directory in filter( 197 | lambda x: (x.is_dir() and x.name not in FOLDER_SKIP_LIST), 198 | repo_root.iterdir()): 199 | teaching_modules.append(TeachingModule.parse_module(directory)) 200 | 201 | with open(readme_filename, 'w') as readme_file: 202 | readme_file.write(DO_NOT_EDIT_WARNING + "\n") 203 | readme_file.write(README_HEADER + "\n\n") 204 | 205 | # Print all module links 206 | readme_file.write("## Modules:\n") 207 | for module in teaching_modules: 208 | readme_file.write( 209 | f"* {create_module_title_with_header_link(module)}\n") 210 | 211 | readme_file.write("\n") 212 | 213 | # Print teaching topics one module at a time 214 | for module in teaching_modules: 215 | readme_file.write(f"### {module.title}\n") 216 | for topic in module.topics: 217 | readme_file.write(create_topic_list_item(topic)) 218 | readme_file.write("\n") 219 | 220 | 221 | if __name__ == "__main__": 222 | readme_generator_driver() 223 | -------------------------------------------------------------------------------- /tools/mgmt_tools/topic_updater.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Small tool for generating and fixing teaching topics. 4 | 5 | Verify if the layout of all topics matches the skeleton. 6 | > ./topic_updater.py --check 7 | 8 | Update all topic files according to the skeleton. 9 | > ./topic_updater.py --update 10 | 11 | Update a specific topic file according to the skeleton. 12 | > ./topic_updater.py --update functions/user-defined-literals.md 13 | """ 14 | 15 | import os 16 | import typing as tp 17 | from argparse import ArgumentParser 18 | from copy import copy 19 | from pathlib import Path 20 | 21 | 22 | def _cli_yn_choice(question: str, default: str = 'y') -> bool: 23 | """Ask the user to make a y/n decision on the cli.""" 24 | choices = 'Y/n' if default.lower() in ('y', 'yes') else 'y/N' 25 | choice: str = str( 26 | input("{message} ({choices}) ".format(message=question, 27 | choices=choices))) 28 | values: tp.Union[tp.Tuple[str, str], 29 | tp.Tuple[str, str, 30 | str]] = ('y', 'yes', 31 | '') if choices == 'Y/n' else ('y', 32 | 'yes') 33 | return choice.strip().lower() in values 34 | 35 | 36 | class SectionHeading: 37 | """ A header of section in the topic document. """ 38 | def __init__(self, title_text: str) -> None: 39 | self.__title_text = title_text 40 | self.__meta_text: tp.List[str] = [] 41 | 42 | @property 43 | def header_text(self) -> str: 44 | """Text of the section header.""" 45 | return self.__title_text 46 | 47 | @property 48 | def meta_text(self) -> tp.List[str]: 49 | """Meta text of the section, represented in italics.""" 50 | return self.__meta_text 51 | 52 | def append_meta_text(self, meta_text_line: str) -> None: 53 | """ 54 | Append a line to the meta text section of this section heading. 55 | 56 | Args: 57 | meta_text_line: new meta text line to append 58 | """ 59 | self.__meta_text.append(meta_text_line) 60 | 61 | def convert_meta_text_to_lines(self) -> tp.List[str]: 62 | """ 63 | Convert the sections meta text into separate lines for the document. 64 | This does not include the header part because some headers contain user 65 | specific text, which is not traced in the Skeleton. 66 | """ 67 | heading_lines = [] 68 | heading_lines.append(os.linesep) 69 | 70 | heading_lines.extend(self.meta_text) 71 | # Guarantee exactly one empty line after meta text 72 | heading_lines[-1] = heading_lines[-1].rstrip() + os.linesep * 2 73 | 74 | return heading_lines 75 | 76 | def __str__(self) -> str: 77 | heading_text = f"{self.header_text}\n{''.join(self.meta_text)}" 78 | return heading_text 79 | 80 | 81 | class Skeleton: 82 | """ 83 | The topic skeleton which defines the layout and meta text of a topic file. 84 | """ 85 | def __init__(self, skeleton_file_path: Path) -> None: 86 | self.__skeleton_file_path = skeleton_file_path 87 | self.__headings: tp.List[SectionHeading] = [] 88 | self.__parse_headings() 89 | 90 | @property 91 | def headings(self) -> tp.List[SectionHeading]: 92 | """All headings in this skeleton.""" 93 | return self.__headings 94 | 95 | def lookup_heading(self, start_heading_line: str) -> SectionHeading: 96 | """ 97 | Looks up a heading from the skeleton. 98 | 99 | Args: 100 | start_heading_line: start of full string of the heading line 101 | 102 | Returns: the section heading that starts like the heading line 103 | """ 104 | for heading in self.headings: 105 | if start_heading_line.lower().startswith( 106 | heading.header_text.split(":")[0].lower()): 107 | return heading 108 | raise LookupError( 109 | f"Could not find heading that starts with: {start_heading_line}") 110 | 111 | def get_title_heading(self) -> SectionHeading: 112 | """ The Title heading of the document. """ 113 | if not self.headings[0].header_text.startswith("## "): 114 | raise AssertionError( 115 | "First heading in the skeleton was not the title.") 116 | return self.headings[0] 117 | 118 | def check_if_topic_file_matches(self, topic_file: tp.TextIO) -> bool: 119 | """ 120 | Checks if the topic file headings and meta text matches the skeleton. 121 | Prints the differences between the topic file and the skeleton, if a 122 | miss mach is detected. 123 | 124 | Args: 125 | topic_file: the topic markdown file to update 126 | 127 | Returns: `True` if the topic matches, otherwise, `False` 128 | """ 129 | current_heading_iter = iter(self.headings) 130 | current_heading = None 131 | processing_meta_text = False 132 | expected_meta_text: tp.List[str] = [] 133 | 134 | for line in topic_file.readlines(): 135 | line = line.rsplit("{#")[0] # ignore anchors 136 | 137 | if line.startswith("This topic is currently under construction"): 138 | return True 139 | if line.startswith("##"): 140 | if current_heading and expected_meta_text: 141 | print("Missing italics detected:") 142 | print(f"Expected: {expected_meta_text[0]}") 143 | return False 144 | 145 | current_heading = next(current_heading_iter) 146 | expected_meta_text = copy( 147 | self.lookup_heading(current_heading.header_text).meta_text) 148 | processing_meta_text = False 149 | 150 | # Check if the required section headings are present 151 | if line.startswith("###") and current_heading: 152 | if current_heading.header_text.split(":")[0] != line.split( 153 | ":")[0].strip(): 154 | print("Found wrong section title:") 155 | print(f"Found:\n{line.strip()}") 156 | print(f"Expected:\n{current_heading.header_text}") 157 | return False 158 | 159 | # Check if the correct meta text is below the section heading 160 | if line.startswith("_") or processing_meta_text: 161 | if not expected_meta_text: 162 | print("Did not expect further italics but found:") 163 | print(line) 164 | return False 165 | 166 | if line == expected_meta_text[0]: 167 | processing_meta_text = not line.strip().endswith("_") 168 | expected_meta_text.pop(0) 169 | else: 170 | print("Found italics text did not match the skeleton:") 171 | print(f"Found:\n{line}") 172 | print(f"Expected:\n{expected_meta_text[0]}") 173 | return False 174 | 175 | return True 176 | 177 | def update_topic_meta_text(self, topic_file: tp.TextIO) -> tp.List[str]: 178 | """ 179 | Create updates of the meta text for a topic file according to this 180 | skeleton. 181 | 182 | Args: 183 | topic_file: the topic markdown file to update 184 | 185 | Returns: updated topic lines 186 | """ 187 | updated_topic_lines = [] 188 | skeleton_headings_iter = iter(self.headings) 189 | 190 | updated_topic_lines.extend( 191 | self.__process_existing_topic_content(topic_file, 192 | skeleton_headings_iter)) 193 | 194 | # Add missing section headings at the end 195 | updated_topic_lines.extend( 196 | self.__get_remaining_section_headings(skeleton_headings_iter)) 197 | 198 | # Remove excessive newlines 199 | updated_topic_lines[-1] = updated_topic_lines[-1].rstrip() + os.linesep 200 | 201 | return updated_topic_lines 202 | 203 | def __process_existing_topic_content( 204 | self, topic_file: tp.TextIO, 205 | skeleton_headings_iter: tp.Iterator[SectionHeading] 206 | ) -> tp.List[str]: 207 | """ 208 | This method checks that all heading related lines in the topic file 209 | correspond correctly to the skeleton. If lines are missing, the user is 210 | asked if the missing heading should be added. 211 | 212 | Args: 213 | topic_file: the topic markdown file to update 214 | skeleton_headings_iter: iterator that points to the next expected 215 | topic heading 216 | 217 | Returns: existing topic lines, where headings were updated according to 218 | the skeleton 219 | """ 220 | updated_topic_lines = [] 221 | emitting_doc_text = True 222 | 223 | for line in topic_file.readlines(): 224 | if line.startswith("###"): 225 | next_heading = next(skeleton_headings_iter) 226 | current_heading = self.lookup_heading(line.split(":")[0]) 227 | 228 | # Add headers that are completely missing 229 | while (current_heading.header_text != 230 | next_heading.header_text): 231 | print(f"Could not find section " 232 | f"({next_heading.header_text}) before section " 233 | f"({current_heading.header_text}).") 234 | if _cli_yn_choice("Should I insert it before?"): 235 | updated_topic_lines.append(next_heading.header_text) 236 | updated_topic_lines.extend( 237 | next_heading.convert_meta_text_to_lines()) 238 | 239 | next_heading = next(skeleton_headings_iter) 240 | 241 | emitting_doc_text = False 242 | 243 | # Write out heading 244 | updated_topic_lines.append(line) 245 | updated_topic_lines.extend( 246 | current_heading.convert_meta_text_to_lines()) 247 | 248 | elif line.startswith("##"): 249 | # Verify that the title heading has correct meta text 250 | emitting_doc_text = False 251 | next_heading = next(skeleton_headings_iter) 252 | updated_topic_lines.append(line) 253 | updated_topic_lines.extend( 254 | self.get_title_heading().convert_meta_text_to_lines()) 255 | elif line.startswith("_") or line.strip().endswith("_"): 256 | # Ignore meta lines 257 | # Meta lines are not allowed to contain modifications by the 258 | # topic writer and are always inserted with the title heading 259 | # from the skeleton. 260 | continue 261 | elif emitting_doc_text or line != "\n": 262 | # Skip new lines if we aren't emitting normal document text 263 | emitting_doc_text = True 264 | updated_topic_lines.append(line) 265 | 266 | return updated_topic_lines 267 | 268 | @staticmethod 269 | def __get_remaining_section_headings( 270 | skeleton_headings_iter: tp.Iterator[SectionHeading] 271 | ) -> tp.List[str]: 272 | """ 273 | Returns a list of all `SectionHeading`s that are still missing and 274 | should be added at the end of the topic. 275 | 276 | Args: 277 | skeleton_headings_iter: iterator that points to the next expected 278 | topic heading 279 | Returns: missing topic lines, which are not present and have not been 280 | added up to now 281 | """ 282 | missing_headings: tp.List[str] = [] 283 | try: 284 | while True: 285 | next_heading = next(skeleton_headings_iter) 286 | missing_headings.append(next_heading.header_text + os.linesep) 287 | missing_headings.extend( 288 | next_heading.convert_meta_text_to_lines()) 289 | except StopIteration: 290 | pass 291 | 292 | return missing_headings 293 | 294 | def __parse_headings(self) -> None: 295 | with open(self.__skeleton_file_path, "r") as skeleton_file: 296 | for line in skeleton_file.readlines(): 297 | if line.startswith("#"): 298 | self.headings.append(SectionHeading(line.strip())) 299 | elif line.startswith("_") or line.strip().endswith("_"): 300 | if not self.headings: 301 | raise AssertionError( 302 | "Found italics skeleton text before first heading." 303 | ) 304 | self.headings[-1].append_meta_text(line) 305 | 306 | def __str__(self) -> str: 307 | skeleton_text = "" 308 | for heading in self.headings: 309 | skeleton_text += str(heading) + "\n" 310 | return skeleton_text 311 | 312 | 313 | def check_skeletons(skeleton: Skeleton, topic_paths: tp.List[Path]) -> bool: 314 | """ 315 | Check of the topics files match the skeleton. 316 | 317 | Args: 318 | skeleton: base skeleton to compare the topics against 319 | topic_paths: list of paths to topic files 320 | 321 | Returns: True, if all topic files matched the skeleton 322 | """ 323 | all_files_matched = True 324 | for topic_path in topic_paths: 325 | with open(topic_path, "r") as topic_file: 326 | print(f"Checking: {topic_path}") 327 | if skeleton.check_if_topic_file_matches(topic_file): 328 | print(" └─> All meta-text matched the skeleton.") 329 | else: 330 | print(" └─> Errors where found!") 331 | all_files_matched = False 332 | 333 | return all_files_matched 334 | 335 | 336 | def update_skeletons(skeleton: Skeleton, topic_paths: tp.List[Path]) -> None: 337 | """ 338 | Update the topics files to match the skeleton. 339 | 340 | Args: 341 | skeleton: base skeleton, used as a ground truth 342 | topic_paths: list of paths to topic files 343 | """ 344 | for path in topic_paths: 345 | updated_topic_content = [] 346 | with open(path, "r") as topic_file: 347 | updated_topic_content = skeleton.update_topic_meta_text(topic_file) 348 | 349 | if updated_topic_content: 350 | # Write update content to topic file 351 | with open(path, "w") as topic_file: 352 | for line in updated_topic_content: 353 | topic_file.write(line) 354 | 355 | 356 | def main() -> None: 357 | """ Driver function for the topic fixer tool. """ 358 | parser = ArgumentParser("topic_updater") 359 | parser.add_argument("--check", 360 | action="store_true", 361 | default=False, 362 | help="Check if the topic files match the skeleton.") 363 | parser.add_argument("--update", 364 | action="store_true", 365 | default=False, 366 | help="Update topic files according to the skeleton.") 367 | parser.add_argument("--skeleton-file", 368 | type=Path, 369 | default=Path("skeleton.md"), 370 | help="Provide alternative skeleton file.") 371 | parser.add_argument("topic_paths", 372 | nargs="*", 373 | default=None, 374 | type=Path, 375 | help="List of paths to topic files, if no paths " 376 | "are provided all topic files are used.") 377 | 378 | args = parser.parse_args() 379 | 380 | if not args.skeleton_file.exists(): 381 | print(f"Could not find skeleton file {args.skeleton_file}") 382 | return 383 | skeleton = Skeleton(args.skeleton_file) 384 | 385 | if not args.topic_paths: 386 | 387 | def exclude_non_topic_files(path: Path) -> bool: 388 | excluded_files = ["skeleton.md", "Readme.md"] 389 | excluded_folders = [".github", "tools"] 390 | for exclude_folder in excluded_folders: 391 | if str(path).startswith(exclude_folder): 392 | return False 393 | return path.name not in excluded_files 394 | 395 | topic_paths = list( 396 | filter(exclude_non_topic_files, 397 | Path("sources/modules/").glob("**/*.md"))) 398 | else: 399 | topic_paths = args.topic_paths 400 | 401 | # Verify that all topic paths exist 402 | for topic_path in topic_paths: 403 | if not topic_path.exists(): 404 | print(f"Could not find topic file {topic_path}") 405 | return 406 | 407 | if args.check: 408 | check_skeletons(skeleton, topic_paths) 409 | elif args.update: 410 | update_skeletons(skeleton, topic_paths) 411 | else: 412 | parser.print_help() 413 | 414 | 415 | if __name__ == "__main__": 416 | main() 417 | -------------------------------------------------------------------------------- /tools/pandoc_filters/meta_vars.lua: -------------------------------------------------------------------------------- 1 | local vars = {} 2 | 3 | function get_vars (meta) 4 | for k, v in pairs(meta) do 5 | if type(v) == 'table' and v.t == 'MetaInlines' then 6 | vars["%" .. k .. "%"] = {table.unpack(v)} 7 | end 8 | end 9 | end 10 | 11 | function replace (el) 12 | if vars[el.text] then 13 | return pandoc.Span(vars[el.text]) 14 | else 15 | return el 16 | end 17 | end 18 | 19 | return {{Meta = get_vars}, {Str = replace}} 20 | -------------------------------------------------------------------------------- /tools/pandoc_filters/spellcheck.lua: -------------------------------------------------------------------------------- 1 | -- lua filter for spell checking: requires 'aspell'. 2 | -- Copyright (C) 2017-2020 John MacFarlane, released under MIT license 3 | 4 | local text = require('text') 5 | local words = {} 6 | local deflang 7 | 8 | local function add_to_dict(lang, t) 9 | if not words[lang] then 10 | words[lang] = {} 11 | end 12 | if not words[lang][t] then 13 | words[lang][t] = (words[lang][t] or 0) + 1 14 | end 15 | end 16 | 17 | local function get_deflang(meta) 18 | deflang = (meta.lang and meta.lang[1] and meta.lang[1].c) or 'en' 19 | -- the following is better but won't work in pandoc 2.0.6. 20 | -- it requires pandoc commit ecc46e229fde934f163d1f646383d24bfe2039e1: 21 | -- deflang = (meta.lang and pandoc.utils.stringify(meta.lang)) or 'en' 22 | return {} -- eliminate meta so it doesn't get spellchecked 23 | end 24 | 25 | local function run_spellcheck(lang) 26 | local keys = {} 27 | local wordlist = words[lang] 28 | for k,_ in pairs(wordlist) do 29 | keys[#keys + 1] = k 30 | end 31 | local inp = table.concat(keys, '\n') 32 | local outp = pandoc.pipe('aspell_frontend', {'list','-l',lang}, inp) 33 | for w in string.gmatch(outp, "([%S]+)\n") do 34 | io.write(w) 35 | if lang ~= deflang then 36 | io.write("\t[" .. lang .. "]") 37 | end 38 | io.write("\n") 39 | end 40 | end 41 | 42 | local function results(el) 43 | pandoc.walk_block(pandoc.Div(el.blocks), {Str = function(e) add_to_dict(deflang, e.text) end}) 44 | for lang,v in pairs(words) do 45 | run_spellcheck(lang) 46 | end 47 | os.exit(0) 48 | end 49 | 50 | local function checkstr(el) 51 | add_to_dict(deflang, el.text) 52 | end 53 | 54 | local function checkspan(el) 55 | local lang = el.attributes.lang 56 | if not lang then return nil end 57 | pandoc.walk_inline(el, {Str = function(e) add_to_dict(lang, e.text) end}) 58 | return {} -- remove span, so it doesn't get checked again 59 | end 60 | 61 | local function checkdiv(el) 62 | local lang = el.attributes.lang 63 | if not lang then return nil end 64 | pandoc.walk_block(el, {Str = function(e) add_to_dict(lang, e.text) end}) 65 | return {} -- remove div, so it doesn't get checked again 66 | end 67 | 68 | return {{Meta = get_deflang}, 69 | {Div = checkdiv, Span = checkspan}, 70 | {Str = function(e) add_to_dict(deflang, e.text) end, Pandoc = results}} 71 | -------------------------------------------------------------------------------- /tools/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | testpaths = tests 3 | addopts = --doctest-modules --doctest-continue-on-failure 4 | pythonpath = . 5 | -------------------------------------------------------------------------------- /tools/requirements.txt: -------------------------------------------------------------------------------- 1 | pytest>=7 2 | mock 3 | -------------------------------------------------------------------------------- /tools/tests/TEST_INPUTS/fix_wrong_sections.md: -------------------------------------------------------------------------------- 1 | ## Main Title 2 | 3 | _Skeleton instructions are typeset in italic text._ 4 | 5 | ### Section with user content: provided by the user 6 | 7 | _ Example section where user text is in the header _ 8 | 9 | ### Missing mid section 10 | 11 | _ This section could be missing in the middle of the topics _ 12 | 13 | ### Italics text should be updated 14 | 15 | _ Wrong old italics text. _ 16 | 17 | ### Meta text with line breaks 18 | 19 | _ Some text here 20 | some after the line break _ 21 | 22 | ### Missing end section 23 | 24 | _ This section could be missing at the end of the document _ 25 | -------------------------------------------------------------------------------- /tools/tests/TEST_INPUTS/missing_sections.md: -------------------------------------------------------------------------------- 1 | ## Main Title 2 | 3 | _Skeleton instructions are typeset in italic text._ 4 | 5 | ### Section with user content: provided by the user 6 | 7 | _ Example section where user text is in the header _ 8 | 9 | ### Italics text should be updated 10 | 11 | _ Updated italics text. _ 12 | 13 | ### Meta text with line breaks 14 | 15 | _ Some text here 16 | some after the line break _ 17 | 18 | -------------------------------------------------------------------------------- /tools/tests/TEST_INPUTS/test_injectable_main.md: -------------------------------------------------------------------------------- 1 | INJECT_TEACHING_MODULES_HERE 2 | -------------------------------------------------------------------------------- /tools/tests/TEST_INPUTS/test_modules/test_empty_module.md: -------------------------------------------------------------------------------- 1 | ## Test: some empty test module 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | ### Overview 7 | 8 | _Provides a short natural language abstract of the module’s contents._ 9 | _Specifies the different levels of teaching._ 10 | 11 | ------------------------------------------------------------------------ 12 | Level Objective 13 | ----------------- ------------------------------------------------------ 14 | Foundational --- 15 | 16 | Main --- 17 | 18 | Advanced --- 19 | 20 | ------------------------------------------------------------------------ 21 | 22 | ### Motivation 23 | 24 | _Why is this important?_ 25 | _Why do we want to learn/teach this topic?_ 26 | 27 | ### Topic introduction 28 | 29 | _Very brief introduction to the topic._ 30 | 31 | ### Foundational: Using * 32 | 33 | #### Background/Required Knowledge 34 | 35 | A student: 36 | 37 | 38 | #### Student outcomes 39 | 40 | _A list of things "a student should be able to" after the curriculum._ 41 | _The next word should be an action word and testable in an exam._ 42 | _Max 5 items._ 43 | 44 | A student should be able to: 45 | 46 | 1. 47 | 2. 48 | 3. 49 | 4. 50 | 5. 51 | 52 | #### Caveats 53 | 54 | _This section mentions subtle points to understand, like anything resulting in 55 | implementation-defined, unspecified, or undefined behavior._ 56 | 57 | #### Points to cover 58 | 59 | _This section lists important details for each point._ 60 | 61 | ### Main: implementing * 62 | 63 | #### Background/Required Knowledge 64 | 65 | * All of the above. 66 | 67 | #### Student outcomes 68 | 69 | A student should be able to: 70 | 71 | 1. 72 | 2. 73 | 3. 74 | 4. 75 | 5. 76 | 77 | #### Caveats 78 | 79 | #### Points to cover 80 | 81 | ### Advanced 82 | 83 | _These are important topics that are not expected to be covered but provide 84 | guidance where one can continue to investigate this topic in more depth._ 85 | -------------------------------------------------------------------------------- /tools/tests/TEST_INPUTS/test_modules/test_placeholder.md: -------------------------------------------------------------------------------- 1 | ## Test: placeholder 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | This topic is currently under construction and will soon be filled with information :) 7 | -------------------------------------------------------------------------------- /tools/tests/TEST_INPUTS/test_modules/test_wrong_placeholder.md: -------------------------------------------------------------------------------- 1 | ## Test: placeholder 2 | 3 | _Skeleton descriptions are typeset in italic text,_ 4 | _so please don't remove these descriptions when editing the topic._ 5 | 6 | Wrong marker text :( 7 | -------------------------------------------------------------------------------- /tools/tests/TEST_INPUTS/test_skeleton.md: -------------------------------------------------------------------------------- 1 | ## Main Title 2 | 3 | _Skeleton instructions are typeset in italic text._ 4 | 5 | ### Section with user content: provided by the user 6 | 7 | _ Example section where user text is in the header _ 8 | 9 | ### Missing mid section 10 | 11 | _ This section could be missing in the middle of the topics _ 12 | 13 | ### Italics text should be updated 14 | 15 | _ Updated italics text. _ 16 | 17 | ### Meta text with line breaks 18 | 19 | _ Some text here 20 | some after the line break _ 21 | 22 | ### Missing end section 23 | 24 | _ This section could be missing at the end of the document _ 25 | -------------------------------------------------------------------------------- /tools/tests/TEST_INPUTS/user_content_heading_topic.md: -------------------------------------------------------------------------------- 1 | ## Main Title 2 | 3 | _Skeleton instructions are typeset in italic text._ 4 | 5 | ### Section with user content: This is provided by the user 6 | 7 | _ Example section where user text is in the header _ 8 | 9 | Users can add different content here. 10 | 11 |
12 | 13 | ### Missing mid section 14 | 15 | _ This section could be missing in the middle of the topics _ 16 | 17 | ### Italics text should be updated 18 | 19 | _ Updated italics text. _ 20 | 21 | ### Meta text with line breaks 22 | 23 | _ Some text here 24 | some after the line break _ 25 | 26 | ### Missing end section 27 | 28 | _ This section could be missing at the end of the document _ 29 | -------------------------------------------------------------------------------- /tools/tests/generate_main_test.py: -------------------------------------------------------------------------------- 1 | """ 2 | """ 3 | 4 | from pathlib import Path 5 | import unittest 6 | import io 7 | 8 | import build.generate_main as gm 9 | 10 | TEST_INPUTS = Path("tests/TEST_INPUTS/") 11 | 12 | 13 | def _trim_include(line: str) -> str: 14 | return line[12:-1] 15 | 16 | 17 | class TestMainGeneration(unittest.TestCase): 18 | """ 19 | Tests the main generator functionallity that is used to automatically 20 | generate a complete main file with all modules. 21 | """ 22 | def test_is_placeholder_actual_placeholder(self): 23 | """Check is_placeholder correctly identifies a placeholder file.""" 24 | self.assertTrue( 25 | gm.is_placeholder(TEST_INPUTS / "test_modules" / 26 | "test_placeholder.md")) 27 | 28 | def test_is_placeholder_does_not_identify_other_files(self): 29 | """Check is_placeholder does not identifies other files as 30 | placeholders.""" 31 | self.assertFalse( 32 | gm.is_placeholder(TEST_INPUTS / "test_modules" / 33 | "test_wrong_placeholder.md")) 34 | 35 | def test_that_inject_modules_correctly_injects_includes(self): 36 | """ 37 | Checks that `inject_teaching_modules` correctly injects all available 38 | teaching modules into the given file. 39 | """ 40 | output_buffer = io.StringIO() 41 | gm.inject_teaching_modules(output_buffer, TEST_INPUTS / "test_modules") 42 | 43 | generated_include_lines = [ 44 | s for s in output_buffer.getvalue().splitlines() if s 45 | ] 46 | 47 | for include_line in generated_include_lines: 48 | self.assertTrue(include_line.startswith("__INCLUDE__(")) 49 | self.assertTrue(include_line.endswith(")")) 50 | 51 | generated_include_lines = sorted( 52 | list(map(_trim_include, generated_include_lines))) 53 | 54 | self.assertEqual( 55 | generated_include_lines[0], 56 | "tests/TEST_INPUTS/test_modules/test_empty_module.md") 57 | self.assertEqual( 58 | generated_include_lines[1], 59 | "tests/TEST_INPUTS/test_modules/test_wrong_placeholder.md") 60 | -------------------------------------------------------------------------------- /tools/tests/topic_updater_test.py: -------------------------------------------------------------------------------- 1 | """ 2 | Testing module for the topic_updater script. This modules tests whether the 3 | abstractions, SectionHeading, Skeleton, which are used in the script correctly 4 | work. 5 | """ 6 | from itertools import dropwhile 7 | from pathlib import Path 8 | import copy 9 | import os 10 | import unittest 11 | 12 | import mock 13 | 14 | import mgmt_tools.topic_updater as tu 15 | 16 | TEST_INPUTS = Path("tests/TEST_INPUTS/") 17 | 18 | 19 | class TestSectionHeading(unittest.TestCase): 20 | """ 21 | Tests the section heading class, which represents a specific secion heading 22 | in a topic markdown. 23 | """ 24 | @classmethod 25 | def setUpClass(cls): 26 | """ Setup example section header. """ 27 | cls.section_title = "## Section Title" 28 | cls.test_meta_text_line0 = "_ Some meta text _" + os.linesep 29 | cls.test_meta_text_line1 = "_ Another line meta text _" + os.linesep 30 | 31 | cls.new_heading = tu.SectionHeading(cls.section_title) 32 | cls.new_heading.append_meta_text(cls.test_meta_text_line0) 33 | 34 | def test_basic_construction(self): 35 | """ Checks if we setup the basic section header correclty. """ 36 | new_heading = copy.deepcopy(self.new_heading) 37 | 38 | self.assertEqual(new_heading.header_text, self.section_title) 39 | self.assertEqual(new_heading.meta_text, [self.test_meta_text_line0]) 40 | 41 | new_heading.append_meta_text(self.test_meta_text_line1) 42 | 43 | self.assertEqual( 44 | new_heading.meta_text, 45 | [self.test_meta_text_line0, self.test_meta_text_line1]) 46 | 47 | def test_meta_text_to_line_conversion(self): 48 | """ Checks if we correctly generate meta text. """ 49 | new_heading = copy.deepcopy(self.new_heading) 50 | new_heading.append_meta_text(self.test_meta_text_line1) 51 | 52 | meta_text_lines = new_heading.convert_meta_text_to_lines() 53 | 54 | self.assertEqual(meta_text_lines[0], os.linesep, 55 | "First line should be only a linesep.") 56 | self.assertEqual(meta_text_lines[1], self.test_meta_text_line0) 57 | self.assertEqual( 58 | meta_text_lines[2], self.test_meta_text_line1 + os.linesep, 59 | "The last meta line should have an additional line separator") 60 | 61 | 62 | class TestSkeleton(unittest.TestCase): 63 | """ 64 | Tests the skeleton class which loads the topic skeleton from a file and 65 | parses it. 66 | """ 67 | @classmethod 68 | def setUpClass(cls): 69 | """ Setup small test skeleton which contains all edge cases. """ 70 | cls.test_skeleton = tu.Skeleton(TEST_INPUTS / "test_skeleton.md") 71 | 72 | def test_actual_skeleton_parse(self): 73 | """ 74 | Checks that we can fully parse the actual skeleton. 75 | """ 76 | offset_to_main_folder = "../../../" 77 | actual_skeleton = tu.Skeleton(TEST_INPUTS / offset_to_main_folder / 78 | "skeleton.md") 79 | 80 | self.assertEqual(actual_skeleton.get_title_heading().header_text, 81 | "## Module name: topic name") 82 | headings = list( 83 | map(lambda heading: heading.header_text, actual_skeleton.headings)) 84 | self.assertEqual(headings[0], "## Module name: topic name") 85 | self.assertEqual(headings[1], "### Overview") 86 | 87 | self.assertEqual(headings[-2], "#### Points to cover") 88 | self.assertEqual(headings[-1], "### Advanced") 89 | 90 | def test_heading_lookup(self): 91 | """ 92 | Checks if we can lookup different section headings in the skeleton. 93 | """ 94 | section_with_user_content = self.test_skeleton.lookup_heading( 95 | "### Section with user content:") 96 | missing_mid = self.test_skeleton.lookup_heading( 97 | "### Missing mid section") 98 | 99 | self.assertEqual( 100 | section_with_user_content.header_text, 101 | "### Section with user content: provided by the user") 102 | self.assertEqual( 103 | section_with_user_content.meta_text[0].rstrip(), 104 | "_ Example section where user text is in the header _") 105 | 106 | self.assertEqual(missing_mid.header_text, "### Missing mid section") 107 | self.assertEqual( 108 | missing_mid.meta_text[0].rstrip(), 109 | "_ This section could be missing in the middle of the topics _") 110 | 111 | def test_heading_lookup_wrong_capitalization(self): 112 | """ 113 | Checks if we can lookup different section headings in the skeleton, 114 | even if the original text is wrongly capitialized. 115 | """ 116 | wrong_upper_case_heading = self.test_skeleton.lookup_heading( 117 | "### Section with User content:") 118 | wrong_lower_case_heading = self.test_skeleton.lookup_heading( 119 | "### missing mid section") 120 | 121 | self.assertEqual( 122 | wrong_upper_case_heading.header_text, 123 | "### Section with user content: provided by the user") 124 | self.assertEqual( 125 | wrong_upper_case_heading.meta_text[0].rstrip(), 126 | "_ Example section where user text is in the header _") 127 | 128 | self.assertEqual(wrong_lower_case_heading.header_text, 129 | "### Missing mid section") 130 | self.assertEqual( 131 | wrong_lower_case_heading.meta_text[0].rstrip(), 132 | "_ This section could be missing in the middle of the topics _") 133 | 134 | def test_title_heading_lookup(self): 135 | """ 136 | Checks if we get the correct title heading from the test skeleton. 137 | """ 138 | self.assertEqual(self.test_skeleton.get_title_heading().header_text, 139 | "## Main Title") 140 | self.assertEqual( 141 | self.test_skeleton.get_title_heading().meta_text[0], 142 | "_Skeleton instructions are typeset in italic text._" + os.linesep) 143 | 144 | def test_that_meta_text_with_linebreaks_inbetween_meta_markers_parse(self): 145 | """ 146 | Checks that we correctly parse meta text that stretches over multiple 147 | lines. 148 | """ 149 | multi_line_meta_heading = self.test_skeleton.lookup_heading( 150 | "### Meta text with line breaks") 151 | 152 | self.assertEqual(multi_line_meta_heading.meta_text[0], 153 | "_ Some text here" + os.linesep) 154 | self.assertEqual(multi_line_meta_heading.meta_text[1], 155 | "some after the line break _" + os.linesep) 156 | 157 | 158 | class TestSkeletonTopicUpdates(unittest.TestCase): 159 | """ 160 | Test skeleton topic update function. This test tries to cover different 161 | scenarios that could occure during topic updates and verifies that we 162 | handle them correctly. 163 | """ 164 | @classmethod 165 | def setUpClass(cls): 166 | """ Setup small test skeleton which contains all edge cases. """ 167 | cls.test_skeleton = tu.Skeleton(TEST_INPUTS / "test_skeleton.md") 168 | 169 | def test_not_to_override_user_provided_heading_text(self): 170 | """ 171 | Checks that the update method does not override user provided text, 172 | which is part of some section headings. 173 | """ 174 | topic_file_path = TEST_INPUTS / "user_content_heading_topic.md" 175 | with open(topic_file_path, "r") as topic_file: 176 | updated_topic_lines = self.test_skeleton.update_topic_meta_text( 177 | topic_file) 178 | 179 | start_test_scope_lines = list( 180 | dropwhile( 181 | lambda line: not line.startswith( 182 | "### Section with user content:"), 183 | updated_topic_lines)) 184 | 185 | self.assertTrue( 186 | start_test_scope_lines[0].endswith( 187 | " This is provided by the user" + os.linesep), 188 | "User provided content was modified") 189 | 190 | def test_that_we_dont_override_user_text_in_sections(self): 191 | """ 192 | Checks that when we don't change user written text in section when 193 | updating the topic. 194 | """ 195 | topic_file_path = TEST_INPUTS / "user_content_heading_topic.md" 196 | with open(topic_file_path, "r") as topic_file: 197 | updated_topic_lines = self.test_skeleton.update_topic_meta_text( 198 | topic_file) 199 | 200 | start_test_scope_lines = list( 201 | dropwhile( 202 | lambda line: not line.startswith( 203 | "Users can add different content here"), 204 | updated_topic_lines)) 205 | 206 | self.assertTrue( 207 | start_test_scope_lines[0].startswith( 208 | "Users can add different content here."), 209 | "User provided content was modified") 210 | self.assertTrue(start_test_scope_lines[1].startswith(""), 211 | "User provided content was modified") 212 | self.assertTrue(start_test_scope_lines[2].startswith("
"), 213 | "User provided content was modified") 214 | 215 | @mock.patch('mgmt_tools.topic_updater._cli_yn_choice') 216 | def test_if_missing_section_gets_added_to_the_end(self, mock_cli_yn): 217 | """ 218 | Checks if a section that is missing at the end of the topic file gets 219 | automatically added. 220 | """ 221 | mock_cli_yn.return_value = True 222 | topic_file_path = TEST_INPUTS / "missing_sections.md" 223 | with open(topic_file_path, "r") as topic_file: 224 | updated_topic_lines = self.test_skeleton.update_topic_meta_text( 225 | topic_file) 226 | 227 | self.assertEqual( 228 | updated_topic_lines[-3].rstrip(), "### Missing end section", 229 | "Missing section was not added to the end of the file.") 230 | self.assertEqual( 231 | updated_topic_lines[-1].rstrip(), 232 | "_ This section could be missing at the end of the document _") 233 | 234 | @mock.patch('mgmt_tools.topic_updater._cli_yn_choice') 235 | def test_if_missing_section_gets_added_in_the_middle(self, mock_cli_yn): 236 | """ 237 | Checks if a section that is missing in the middle of the topic file 238 | gets added if the user wants it. The test assumes the user supplies 239 | yes as an answer. 240 | """ 241 | mock_cli_yn.return_value = True 242 | topic_file_path = TEST_INPUTS / "missing_sections.md" 243 | with open(topic_file_path, "r") as topic_file: 244 | updated_topic_lines = self.test_skeleton.update_topic_meta_text( 245 | topic_file) 246 | 247 | # Reduces the topic lines to only contain sections and removes all 248 | # lines before the test scope, i.e., the section before the missing 249 | # section. 250 | start_test_scope_lines = list( 251 | filter( 252 | lambda line: line.startswith("###"), 253 | dropwhile( 254 | lambda line: not line.startswith( 255 | "### Section with user content"), 256 | iter(updated_topic_lines)))) 257 | 258 | # Verify that the previous section is correct 259 | self.assertTrue( 260 | start_test_scope_lines[0].startswith( 261 | "### Section with user content"), 262 | "The section before the added missing section is wrong.") 263 | 264 | # Verify the section was inserted 265 | self.assertEqual( 266 | start_test_scope_lines[1].rstrip(), "### Missing mid section", 267 | "The missing section was not inserted correctly.") 268 | 269 | # Verify the next section is correct 270 | self.assertTrue( 271 | start_test_scope_lines[2].startswith( 272 | "### Italics text should be updated"), 273 | "The section after the added missing section is wrong.") 274 | 275 | def test_that_meta_text_gets_updated(self): 276 | """ 277 | Checks that meta text in the topic gets updated according to the 278 | skeleton. 279 | """ 280 | topic_file_path = TEST_INPUTS / "fix_wrong_sections.md" 281 | with open(topic_file_path, "r") as topic_file: 282 | updated_topic_lines = self.test_skeleton.update_topic_meta_text( 283 | topic_file) 284 | 285 | topic_lines_starting_from_italics_section = list( 286 | dropwhile( 287 | lambda line: not line.startswith( 288 | "### Italics text should be updated"), 289 | iter(updated_topic_lines))) 290 | self.assertEqual( 291 | topic_lines_starting_from_italics_section[0].rstrip(), 292 | "### Italics text should be updated", 293 | "Could not find italics section.") 294 | self.assertEqual( 295 | topic_lines_starting_from_italics_section[2].rstrip(), 296 | "_ Updated italics text. _") 297 | 298 | def test_topic_does_not_end_in_empty_line(self): 299 | """ 300 | Checks that the update topic lines do not end with and empty line. 301 | """ 302 | topic_file_path = TEST_INPUTS / "user_content_heading_topic.md" 303 | with open(topic_file_path, "r") as topic_file: 304 | updated_topic_lines = self.test_skeleton.update_topic_meta_text( 305 | topic_file) 306 | 307 | self.assertNotEqual(updated_topic_lines[-1], os.linesep) 308 | 309 | def test_newline_between_heading_and_meta_text(self): 310 | """ 311 | Checks that we emit a newline between the heading and the meta text. 312 | """ 313 | topic_file_path = TEST_INPUTS / "user_content_heading_topic.md" 314 | with open(topic_file_path, "r") as topic_file: 315 | updated_topic_lines = self.test_skeleton.update_topic_meta_text( 316 | topic_file) 317 | 318 | start_test_scope_lines = list( 319 | dropwhile( 320 | lambda line: not line.startswith("### Section with user"), 321 | updated_topic_lines)) 322 | self.assertEqual(start_test_scope_lines[1], os.linesep, 323 | "No newline between heading and meta text.") 324 | self.assertTrue( 325 | start_test_scope_lines[2].startswith("_ Example section")) 326 | 327 | 328 | class TestSkeletonTopicChecker(unittest.TestCase): 329 | """ 330 | Test skeleton topic checker function. This test covers different scenarios 331 | that should or should not be detected by the topic checker. 332 | """ 333 | @classmethod 334 | def setUpClass(cls): 335 | """ Setup small test skeleton which contains all edge cases. """ 336 | cls.test_skeleton = tu.Skeleton(TEST_INPUTS / "test_skeleton.md") 337 | 338 | def test_if_good_topic_passes_check(self): 339 | """ 340 | Checks that we do not fail on correct topics and user provided document 341 | content. 342 | """ 343 | topic_file_path = TEST_INPUTS / "user_content_heading_topic.md" 344 | with open(topic_file_path, "r") as topic_file: 345 | self.assertTrue( 346 | self.test_skeleton.check_if_topic_file_matches(topic_file)) 347 | 348 | def test_that_check_detects_missing_sections(self): 349 | """ 350 | Checks that check detects missing sections in topic documents. 351 | """ 352 | topic_file_path = TEST_INPUTS / "missing_sections.md" 353 | with open(topic_file_path, "r") as topic_file: 354 | self.assertFalse( 355 | self.test_skeleton.check_if_topic_file_matches(topic_file)) 356 | 357 | def test_that_check_detects_wrong_sections(self): 358 | """ 359 | Checks that check detects wrong sections in topic documents. 360 | """ 361 | topic_file_path = TEST_INPUTS / "fix_wrong_sections.md" 362 | with open(topic_file_path, "r") as topic_file: 363 | self.assertFalse( 364 | self.test_skeleton.check_if_topic_file_matches(topic_file)) 365 | --------------------------------------------------------------------------------