# Technical Documentation: hsutter/cppfront

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/hsutter/cppfront)

### Overview (`README.md`)

# cppfront

Copyright (c) Herb Sutter &#x2022; See [License](LICENSE)

<a href="https://hsutter.github.io/cppfront/welcome/hello-world/"><img width="410" src="https://github.com/hsutter/cppfront/assets/1801526/1e160e93-f966-4aee-8377-9f9f3982a95f"></a><br>
[](CODE_OF_CONDUCT.md)
[](https://github.com/hsutter/cppfront/actions/workflows/build-cppfront.yaml)

Cppfront is a compiler from an experimental C++ 'syntax 2' (Cpp2) to today's 'syntax 1' (Cpp1), to prove out some concepts, share some ideas, and prototype features that can also be proposed for evolving today's C++.

You can find the current status summary here: **[Cppfront status summary (summer 2026)](https://github.com/hsutter/cppfront/discussions/1450)**

## Documentation: [available here](https://hsutter.github.io/cppfront/)

 - [Installation](https://hsutter.github.io/cppfront/welcome/overview/#how-do-i-get-and-build-cppfront)

## What's different about this project?

In short, it aims to help evolve C++ itself, not to be a "C++ successor."

**What it isn't.** Cpp2 is not a successor or alternate language with its own divergent or incompatible ecosystem. For example, it does not have its own nonstandard incompatible modules/concepts/etc. that compete with the Standard C++ features; it does not replace your Standard C++ compiler or other tools; and it does not require any changes to your Standard C++ compiler or standard library or other libraries or tools to keep fully using all of them.

**What it is.** Cpp2 aims to be another "skin" for C++ itself, just a simpler and safer way to write ordinary C++ types/functions/objects, and a faster way to experiment with proposals for future new Standard C++ features in a simpler compiler and syntax flavor. It seamlessly uses Standard C++ modules, concept requirements, and other features.

It also works with all existing C++20 (or higher) compilers, libraries, and tools right out of the box with no changes required to use them all seamlessly and directly, with zero overhead.

For more, see [What is Cpp2?](https://hsutter.github.io/cppfront/#what-is-cpp2).

## Acknowledgments

Scores of people have given valuable feedback and many are listed below, but I especially want to thank Joe Duffy, Anders Hejlsberg, Bjarne Stroustrup, Andrew Sutton, Tim Sweeney, and Mads Torgersen for their insights and valuable feedback on this work over the years — especially when they disagreed with me. I'd also like to thank Dave Abrahams, Andrei Alexandrescu, Walter Bright, Lee Howes, Chris McKinsey, Scott Meyers, Gor Nishanov, Andrew Pardoe, Sean Parent, Jared Parsons, David Sankel, Nathan Sidwell, JC van Winkel, and Ville Voutilainen for broad feedback on the design.

Many more people are listed below for their help with specific parts of the design and those proposals/prototypes. I apologize for the names I have forgotten.

## Further information

To learn more, please see:

- [**👀 The documentation 👀**](https://hsutter.github.io/cppfront/)
- [My CppCon 2022 talk, "Can C++ be 10x simpler and safer ...?"](https://www.youtube.com/watch?v=ELeZAKCN4tY)
- [My CppCon 2023 talk, "Cooperative C++ Evolution: Toward a TypeScript for C++"](https://www.youtube.com/watch?v=8U3hl8XMm8c)
- [Update on cppfront at ACCU 2024](https://www.youtube.com/watch?v=EB7yR-1317k&t=3866s)
- [This repo's wiki](https://github.com/hsutter/cppfront/wiki)
- The list of papers and talks below

### Papers and talks derived from this work (presented in current syntax as contributions toward ISO C++'s evolution itself)

Here are the ISO C++ papers and CppCon conference talks I've given since 2015 that have been derived from this work, in the order that I brought each piece forward. Most of the details in the materials below are still current with only incremental updates, apart from the specific syntax of course.

#### 2015: Lifetime safety

- [**CppCon 2015**: "Writing good C++14... _by default_"](https://youtu.be/hEx5DNLWGgA) particularly [from 29:00 onward](https://youtu.be/hEx5DNLWGgA?t=1757) shows the Lifetime analysis with live demos in a Visual Studio prototype.
- [**CppCon 2018**: "Thoughts on a more powerful _and_ simpler C++ (#5 of N)](https://youtu.be/80BZxujhY38):
    - [The section starting at 18:00](https://youtu.be/80BZxujhY38?t=1097) is an update on the Lifetime status with live demos in a Clang prototype.
    - [The final part starting at 1:28:00](https://youtu.be/80BZxujhY38?t=5307) shows the Lifetime and Metaclasses proposals working hand-in-hand. This is one of the few places before cppfront where the same compiler has contained prototypes of multiple 'syntax 2'-derived features so I could show how they build on each other when used together.
- [**C++ Core Guidelines**: Lifetime safety profile](https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetime.pdf) is this static analysis adopted by the C++ Core Guidelines.
- [**P1179**: Lifetime Safety: Preventing common dangling](https://wg21.link/p1179) is the same analysis in the WG 21 paper list.

This is not yet implemented in cppfront. Implementations are shipping in Visual Studio and in CLion, and initial parts have been upstreamed in Clang. I want to especially thank Matthias Gehre, Gabor Horvath, Neil MacIntosh, and Kyle Reed for their help in implementing the Lifetime static analysis design in Visual Studio and a Clang fork. Thanks also to the following for their input and feedback on the specification: Andrei Alexandrescu, Steve Carroll, Pavel Curtis, Gabriel Dos Reis, Joe Duffy, Daniel Frampton, Anna Gringauze, Chris Hawblitzel, Nicolai Josuttis, Ellie Kornstaedt, Aaron Lahman, Ryan McDougall, Nathan Myers, Gor Nishanov, Andrew Pardoe, Jared Parsons, Dave Sielaff, Richard Smith, Jim Springfield, and Bjarne Stroustrup.

#### 2016: Garbage-collected memory arena

- [**CppCon 2016**: "Leak-freedom in C++... _by default_"](https://www.youtube.com/watch?v=JfmTagWcqoE) particularly [from 59:00 onward](https://youtu.be/JfmTagWcqoE?t=3558) where I show the strawman prototype I wrote of a tracing garbage-collection memory arena.
- [**Github.com/hsutter/gcpp**: "gcpp: Deferred and unordered destruction"](https://github.com/hsutter/gcpp) is the GitHub prototype I wrote.

This is not yet implemented in cppfront. I welcome a real GC expert to collaborate with on bringing this forward to become a "real" usable tracing GC memory arena that C++ code can opt into, with real C++ zero-overhead costing (don't pay anything if you don't do a `gc.new`, and if you do use it then have the costs be proportional to the number of `gc.new` allocations).

### 2017: Spaceship operator for comparisons, `<=>`

- [**CppCon 2017 (just the intro, first 6 minutes)**: "Meta: Thoughts on generative C++"](https://www.youtube.com/watch?v=4AfRAVcThyA).
- [**P0515**: Consistent comparison](https://wg21.link/p0515) is the proposal in today's syntax that I proposed, and was adopted, for C++20.

This is part of ISO C++20 and C++23, except only for chained comparisons which is implemented in cppfront. Thank you again to everyone who helped land this in the Standard in C++20 and improve it in C++23, including especially Walter Brown, Lawrence Crowl, Cameron DaCamara, Gabriel Dos Reis, Jens Maurer, Barry Revzin, Richard Smith, and David Stone.

#### 2017: Reflection, generation, and metaclasses

- [**ACCU 2017**: "Thoughts on metaclasses"](https://www.youtube.com/watch?v=6nsyX37nsRs) is the first talk I gave about this.
- [**CppCon 2017**: "Meta: Thoughts on generative C++"](https://www.youtube.com/watch?v=4AfRAVcThyA) from after the intro, [from 6:00 onward](https://youtu.be/4AfRAVcThyA?t=393).
- [**CppCon 2018**: "Thoughts on a more powerful _and_ simpler C++ ("Simplifying C++" #5 of N)](https://youtu.be/80BZxujhY38):
    - [The section starting at 51:00](https://youtu.be/80BZxujhY38?t=1097) is an update on the Metaclasses status with live demos in a Clang prototype.
    - (repeating the Lifetime section bullet above) [The final part starting at 1:28](https://youtu.be/80BZxujhY38?t=5307) shows the Lifetime and Metaclasses proposals working hand-in-hand. This is one of the few places before cppfront where the same compiler has contained prototypes of multiple 'syntax 2'-derived features so I could show how they build on each other when used together.
- [**P0707**: Metaclass functions: Generative C++](https://wg21.link/p0707) is the paper I brought to the ISO C++ committee.

This is mostly implemented in cppfront, except for the ability to write your own metafunctions (that's coming). Thanks again to Andrew Sutton and his colleagues Wyatt Childers and Jennifer Yao for their help in implementing the Clang-based prototypes of this proposal, and everyone else who contributed feedback on the design including Louis Brandy, Chandler Carruth, Casey Carter, Matúš Chochlík, Lawrence Crowl, Pavel Curtis, Louis Dionne, Gabriel Dos Reis, Joe Duffy, Kenny Kerr, Nicolai Josuttis, Aaron Lahman, Scott Meyers, Axel Naumann, Gor Nishanov, Stephan T. Lavavej, Andrew Pardoe, Sean Parent, Jared Parsons, David Sankel, Richard Smith, Jeff Snyder, Mike Spertus, Mads Torgersen, Daveed Vandevoorde, Tony Van Eerd, JC van Winkel, Ville Voutilainen, and Titus Winters, and many more WG 21 / SG 7 participants.

#### 2018: Updates to Lifetime and Metaclasses (see above)

#### 2019: Zero-overhead deterministic exceptions: Throwing values

- [**ACCU 2019**: "De-fragmenting C++: Making exceptions more affordable and usable](https://www.youtube.com/watch?v=os7cqJ5qlzo).
- [**CppCon 2019**: "De-fragmenting C++: Making exceptions and RTTI more affordable and usable ("Simplifying C++" #6 of N)](https://www.youtube.com/watch?v=ARYP83yNAWk).
- [**P0709**: Zero-overhead deterministic exceptions: Throwing values](https://wg21.link/p0709).

This is not yet implemented in cppfront.

#### 2020: Parameter passing

- **ACCU autumn 2019**: "Quantifying accidental complexity: An empirical look at teaching and using C++" was my first public talk about this, but a "beta" version that was not recorded; you can find the description [here](https://accu.org/conf-previous/2019_autumn/sessions/#XQuantifyingAccidentalComplexityAnEmpiricalLookatTeachingandUsingC).
- [**CppCon 2020**: "Quantifying accidental complexity: An empirical look at teaching and using C++"](https://www.youtube.com/watch?v=6lurOCdaj0Y):
    - The first half of the talk is about how to be rigorous and actually measure that we're making improvements, including to measure the percentage of today's C++ guidance that is about parameter passing and initialization.
    - The second half of the talk is about `in`, `inout`, `out`, `move`, and `forward`.
- [**d0708**: "Parameter passing -> guaranteed unified initialization and value setting](https://github.com/hsutter/708/blob/main/708.pdf) goes into additional detail I didn't have time for in the talk.
- [**Github.com/hsutter/708**](https://github.com/hsutter/708) is a repo with the paper and demo examples as used in the talk.
- [**P2064**: "Assumptions"](https://wg21.link/p2064) is also related to this 'syntax 2' work, because this work includes a contracts design, and assumptions ought to be separate from that. This paper was making the technical argument why assumptions and assertions (contracts) are different things.

This is implemented in cppfront, including the unified `operator=` for user-defined types. Thanks to Andrew Sutton for an initial Clang-based implementation.

#### 2020: "Bridge to NewThingia"

In 2020 I also started socializing the ideas of:

- _How do you answer "why is your thing different when others that look like it have all failed"?_
- _What does it take to be adoptable, including to enable incremental adoption?_

I had specifically in mind a major C++ evolution's success when many attempts to make C or C++ safer have failed, and the importance of seamless compatibility. The talk was "Bridge to NewThingia," presented at:

- [**DevAroundTheSun**: "Bridge to Newthingia"](https://herbsutter.com/2020/06/14/talk-video-available-bridge-to-newthingia-devaroundthesun/), an initial 26-minute version.
- [**C++ on Sea**: "Bridge to NewThingia"](https://www.youtube.com/watch?v=BF3qw1ObUyo) which especially [at the end starting near 48:00](https://youtu.be/BF3qw1ObUyo?t=2883) had a slide that directly tackled the "C++ major evolution" scenario, and laid out what I think it would take to have credible answers to the key questions.

#### 2021: `is`, `as`, and pattern matching

- [**CppCon 2021**: "Extending and simplifying C++: Thoughts on pattern matching using `is` and `as`"](https://www.youtube.com/watch?v=raB_289NxBk).
- [**P2392**: Pattern matching using `is` and `as`](https://wg21.link/p2392) is the ISO C++ committee paper.

This is mostly implemented in cppfront. There is support for `is`, `as`, and basic `inspect` expressions.

#### 2022: CppCon 2022 talk and cppfront

- [**CppCon 2022: "Can C++ be 10x simpler and safer ...?"**](https://www.youtube.com/watch?v=ELeZAKCN4tY)
- This repo.

# Epilog: 2016 roadmap diagram

Finally, here is a roadmap diagram I made in 2016 that is still recognizably a roadmap of Cpp2's design approach, although a few additions like `<=>` came later. I think this is important to show design decisions are related and support each other, so that they are not a gaggle of point fixes but a coordinated refactoring of C++ into a smaller number of regular and combinable features. As Bjarne Stroustrup put it in the _ACM History of Programming Languages III_ (among other places):

> "**10% the size of C++** in definition and similar in front-end compiler size. ... **Most of the simplification would come from generalization.**" (B. Stroustrup, ACM HOPL-III, 2007; emphasis added)




I haven't updated this roadmap diagram since 2016, but it shows many of the talks and papers that have come since then from this work, and it's still a pretty up-to-date roadmap of the major parts of Cpp2. As of spring 2023, cppfront implements most of this roadmap.

I hope you enjoy reading about this personal experiment, and I hope that it might at least start a conversation about what could be possible _**within C++**_'s own evolution to make C++ 10x simpler, safer, and more toolable.

---

### Overview (`passthrough-tests/readme.md`)

File `all-std.cxx` is an include-all-standard-headers file
intended to be built with

    g++-10 all-std.cxx -std=c++2a -E > gcc-10-libstdc++-e.cpp2

    clang++-12 all-std.cxx -std=c++2a -E > clang-12-libstdc++-e.cpp2

    cl all-std.cxx -std:c++latest /E > msvc-msstl-e.cpp2

each of which generates a single .cpp2 test file representing the
contents of a stdlib implementation.

> **Note**: Not all implementations actually support all standard headers.
> So for each compiler invocation above just manually edit `all-std.cxx`
> to comment out the headers that implementation doesn't understand.

Each such `.cpp2` file is then compiled with `cppfront` and the output `.cpp`
file tested to be diff-identical ith the `.cpp2` input, to ensure
that cppfront correctly passes Cpp1 code through unchanged.

Here's a test script:

    cppfront gcc-10-libstdc++-e.cpp2
    diff -s -Z gcc-10-libstdc++-e.cpp2 gcc-10-libstdc++-e.cpp

    cppfront clang-12-libstdc++-e.cpp2
    diff -s -Z clang-12-libstdc++-e.cpp2 clang-12-libstdc++-e.cpp

    cppfront msvc-msstl-e.cpp2
    diff -s -Z msvc-msstl-e.cpp2 msvc-msstl-e.cpp

Each diff should report "files ... are identical".

---

### Index (`docs/index.md`)

# Cpp2 and cppfront: An experimental 'C++ syntax 2' and its first compiler

## Welcome & getting started

- [Overview: What are Cpp2 and cppfront? How do I get and build cppfront?](welcome/overview.md)
- [Hello, world!](welcome/hello-world.md)
- [Adding cppfront to your existing C++ project](welcome/integration.md)

## Cpp2 reference

- [Common concepts](cpp2/common.md)
- [Expressions](cpp2/expressions.md)
- [Declarations and aliases](cpp2/declarations.md)
- [Objects, initialization, and memory](cpp2/objects.md)
- [Functions, branches, and loops](cpp2/functions.md)
- [Contracts](cpp2/contracts.md)
- [Types and inheritance](cpp2/types.md)
- [Metafunctions and reflection](cpp2/metafunctions.md)
- [Namespaces](cpp2/namespaces.md)
- [Safety and "unchecked"](cpp2/safety.md)

## Cppfront reference

- [Using Cpp1 (today's syntax) and Cpp2 in the same source file](cppfront/mixed.md)
- [Cppfront command line options](cppfront/options.md)

## Notes and supplemental topics

- [`@regex` status: Regular expression features](notes/regex_status.md)

---

### Welcome Overview (`docs/welcome/overview.md`)

# Overview: What are Cpp2 and cppfront? How do I get and build cppfront?

``` cpp title="hello.cpp2"
main: () = {
    std::cout << "Hello, world!\n";
}
```

## <a id="what-is-cpp2"></a> What is Cpp2?

"Cpp2," short for "C++ syntax 2," is my ([Herb Sutter's](https://github.com/hsutter)) personal project to try to make writing ordinary C++ types/functions/objects be much **simpler and safer**, without breaking backward compatibility.

**What it isn't.** Cpp2 is not a successor or alternate language with its own divergent or incompatible ecosystem. For example, it does not have its own nonstandard incompatible modules/concepts/etc. that compete with the Standard C++ features; it does not replace your Standard C++ compiler or other tools; and it does not require any changes to your Standard C++ compiler or standard library or other libraries or tools to keep fully using all of them.

**What it is.** Cpp2 aims to be another "skin" for C++ itself, just a simpler and safer way to write ordinary C++ types/functions/objects, and a faster way to experiment with proposals for future new Standard C++ features in a simpler compiler and syntax flavor. It seamlessly uses Standard C++ modules and concepts requirements and other features, and it works with all existing C++20 or higher compilers and libraries and tools right out of the box with no changes required to use them all seamlessly and directly with zero overhead.

 Bjarne Stroustrup said it best:

 > "Inside C++, there is a much smaller and cleaner language struggling to get out." <br>&emsp;&emsp;— Bjarne Stroustrup, _The Design and Evolution of C++_ (D&E), 1994
>
> "Say 10% of the size of C++ in definition and similar in front-end compiler size. ... most of the simplification would come from generalization." <br>&emsp;&emsp;— Bjarne Stroustrup, _ACM History of Programming Languages III_, 2007

**My goal is to try to prove that Stroustrup is right:** that it's possible and desirable to have true C++ with all its expressive power and control and with full backward compatibility, but in a flavor that's 10x simpler with fewer quirks and special cases to remember, [^simpler] and 50x safer where it's far easier to not write security bugs by accident.

We can't make an improvement that large to C++ via gradual evolution to today's syntax, because some important changes would require changing the meaning of code written in today's syntax. For example, we can never change a language feature default in today's syntax, not even if the default creates a security vulnerability pitfall, because changing a default would break vast swathes of existing code. Having a distinct alternative syntax gives us a "bubble of new code" that doesn't exist today, and have:

- **Freedom to make any desired improvement, without breaking any of today's code.** Cpp2 is designed to take all the consensus C++ best-practices guidance we already teach, and make them the default when using "syntax 2." Examples: Writing type-unsafe casts is just not possible in Cpp2 syntax; and Cpp2 can change language defaults to make them simpler and safer. You can always "break the glass" when needed to violate the guidance, but you have to opt out explicitly to write type-unsafe code (usually using the word `unchecked`), so if the program has a bug you can grep for those places to look at first. For details, see [Design note: unsafe code](https://github.com/hsutter/cppfront/wiki/Design-note%3A-Unsafe-code).

- **Perfect link compatibility always on, perfect source compatibility always available (but you pay for it only if you use it).** Any type/function/object/namespace written in either syntax is always still just a normal C++ type/function/object/namespace, so any code or library written in either Cpp2 or today's C++ syntax ("Cpp1" for short) can seamlessly call each other, with no wrapping/marshaling/thunking. You can write a "mixed" source file that has both Cpp2 and Cpp1 code and get perfect backward C++ source compatibility (even SFINAE and macros), or you can write a "pure" all-Cpp2 source file and write code in a 10x simpler syntax.


## <a id="what-is-cppfront"></a> What is cppfront?

[**Cppfront**](https://github.com/hsutter/cppfront) is a compiler that compiles Cpp2 syntax to today's Cpp1 syntax. This lets you start trying out Cpp2 syntax in any existing C++ project and build system just by renaming a source file from `.cpp` to `.cpp2` and [adding a build step](integration.md), and the result Just Works with every C++20 or higher compiler and all existing C++ tools (debuggers, build systems, sanitizers, etc.).

This deliberately follows Bjarne Stroustrup's wise approach with [**cfront**](https://en.wikipedia.org/wiki/Cfront), the original C++ compiler: In the 1980s and 1990s, Stroustrup created cfront to translate C++ to pure C, and similarly ensured that C++ could be interleaved with C in the same source file, and that C++ could always call any C code with no wrapping/marshaling/thunking. By providing a C++ compiler that emitted pure C, Stroustrup ensured full compatibility with the C ecosystems that already existed, and made it easy for people to start trying out C++ code in any existing C project by adding just another build step to translate the C++ to C first, and the result Just Worked with existing C tools.


## <a id="build-cppfront"></a> How do I get and build cppfront?

The full source code for cppfront is at the [**Cppfront GitHub repo**](https://github.com/hsutter/cppfront).

Cppfront builds with any recent C++ compiler. Go to the `/cppfront/source` directory, and run one of the following:

<image align="right" width="120" src="https://user-images.githubusercontent.com/1801526/188906112-ef377a79-b6a9-4a30-b318-10b51d8ea934.png">

``` bash title="MSVC build instructions (Visual Studio 2019 version 16.11 or higher)"
cl cppfront.cpp -std:c++20 -EHsc
```

``` bash title="GCC build instructions (GCC 10 or higher)"
g++ cppfront.cpp -std=c++20 -o cppfront
```

``` bash title="Clang build instructions (Clang 12 or higher)"
clang++ cppfront.cpp -std=c++20 -o cppfront
```

That's it!

> Note: On Windows (including MinGW), if you get a "too many sections" message, specify the switch `/bigobj` (MSVC) or `/Wa,-mbig-obj` (GCC).


### &#10148; Next: [Hello, world!](hello-world.md)


[^simpler]: I'd ideally love to obsolete ~90% of my own books. I know that Cpp2 can eliminate that much of the C++ guidance I've personally had to write and teach over the past quarter century, by removing inconsistencies and pitfalls and gotchas, so that they're either impossible to write or are compile-time errors (either way, we don't have to teach them). I love writing C++ code... I just want it to be easier and safer by default.

---

### Cpp2 Common (`docs/cpp2/common.md`)

# Common programming concepts

## <a id="main"></a> `main`

As always, `main` is the entry point of the program. For example:

`main` can have either:

- No parameters: &emsp; **`#!cpp main: () /*etc.*/`**

- One parameter of implicit type named `args`: &emsp; **`#!cpp main: (args) /*etc.*/`**

    - The type of `args` cannot be explicitly specified. It is always `cpp2::args_t`, which behaves similarly to a `#!cpp const std::array<std::string_view>`.

    - Using `args` performs zero heap allocations. Every `string_view` is directly bound to the string storage provided by host environment.

    - `args.argc` and `args.argv` additionally provide access to the raw C/C++ `main` parameters.

``` cpp title="main with (args)" hl_lines="5 9"
//  Print out command line arguments, then invoke
//  a Qt event loop for a non-UI Qt application
main: (args) -> int
= {
    for args do (arg) {
        std::cout << arg << "\n";
    }

    app: QCoreApplication = (args.argc, args.argv);
    return app.exec();
}
```

`main` can return:

- `#!cpp void`, the default return value for functions. No `#!cpp return` statement is allowed in the body. In this case, the compiled Cpp1 code behaves as if `main` returned `#!cpp int`.

- `#!cpp int`. If the body has no `#!cpp return` statement, the default is to `#!cpp return 0;` at the end of the function body.

- Some other type that your Cpp1 compiler(s) supports as a nonstandard extension.


## <a id="comments"></a> Comments

The usual `#!cpp // line comments` and `#!cpp /* stream comments */` are supported. For example:

``` cpp title="Writing comments"
//  A line comment: After //, the entire
//  rest of the line is part of the comment

/*
    A stream comment: After /*, everything until the
    next * / (without a space between) is part of the
    comment. Note that stream comments do not nest.
 */
```


## <a id="lists"></a> Lists and commas

All lists use `,` commas between list items, and may be enclosed by

- `(` `)` parentheses, for most lists

- `[` `]` brackets, for calling the subscript operator

- `<` `>` angle brackets, for template parameter/argument lists

For example:

``` cpp title="Lists" hl_lines="1 4 6 7"
print: <T,U> (t: T, u: U) = { std::cout << t << u << "\n"; }

main: () = {
    array: std::array = ('A', 'B', 'C');

    for (0, 1, 2) do (e) {
        print( e, array[e] );
    }
    //  Prints:
    //      0A
    //      1B
    //      2C
}
```


An extra comma at the end of the list, before the closing `)` or `>`, is always allowed but ignored if present (for details, see [Design note: Commas](https://github.com/hsutter/cppfront/wiki/Design-note%3A-Commas)).

For example:

``` cpp title="Lists, using optional trailing commas just because we can" hl_lines="1 4 6 7"
print: <T,U,> (t: T, u: U,) = { std::cout << t << u << "\n"; }

main: () = {
    array: std::array = ('A', 'B', 'C',);

    for (0, 1, 2,) do (e) {
        print( e, array[e,], );
    }
    //  Prints:
    //      0A
    //      1B
    //      2C
}
```


## <a id="keywords"></a> Contextual keywords

Cpp2 has very few globally reserved keywords; nearly all keywords are contextual, where they have their special meaning when they appear in a particular place in the grammar. For example:

- `new` is used as an ordinary function to do allocation (e.g., `shared.new<widget>(1, 2, 3)`).

- `struct` and `enum` are used as function names in the metafunctions library.

- `type` can be used as an ordinary name (e.g., `std::common_type<T1,T2>::type`).

- Unqualified `type_of(x)` is a synonym for Cpp1 `std::remove_cvref_t<decltype(x)>`.

In rare cases, usually when consuming code written in other languages, you may need to write a name that is a reserved keyword. The way to do that is to prefix it with `__identifer__`, which treats it as an ordinary identifier (without the prefix).


## <a id="fundamental-types"></a> Fundamental data types

Cpp2 supports the same fundamental types as today's Cpp1, but additionally provides the following aliases in namespace `cpp2`:

| Fixed-width types | Synonym for |
|---|---|
| `i8`        | `std::int8_t`        |
| `i16`       | `std::int16_t`       |
| `i32`       | `std::int32_t`       |
| `i64`       | `std::int64_t`       |
| `u8`        | `std::uint8_t`       |
| `u16`       | `std::uint16_t`      |
| `u32`       | `std::uint32_t`      |
| `u64`       | `std::uint64_t`      |

| Variable-width types <br> (Cpp2-compatible single-word names) | Synonym for (these multi-word<br> names are not allowed in Cpp2) |
|---|---|
| `ushort`      | `#!cpp unsigned short`       |
| `uint`        | `#!cpp unsigned int`         |
| `ulong`       | `#!cpp unsigned long`        |
| `longlong`    | `#!cpp long long`            |
| `ulonglong`   | `#!cpp unsigned long long`   |
| `longdouble`  | `#!cpp long double`          |

| For compatibility/interop only,<br> so deliberately ugly names | Synonym for (these multi-word<br> names are not allowed in Cpp2) | Notes |
|---|---|---|
| `_schar`     | `#!cpp signed char`   | Normally, prefer `i8` instead |
| `_uchar`     | `#!cpp unsigned char` | Normally, prefer `u8` instead |

## <a id="type-qualifiers"></a> Type qualifiers

Types can be qualified with `#!cpp const` and `#!cpp *`. Types are written left-to-right, so a qualifier always applies to what immediately follows it. For example, to declare a `#!cpp const` pointer to a non-`#!cpp const` pointer to a `#!cpp const i32` object, write:

``` cpp title="Using type qualifiers"
//  A const pointer to a non-const pointer to a const i32 object
p: const * * const i32;
```

## <a id="literals"></a> Literals

Cpp2 supports the same `#!cpp 'c'`haracter, `#!cpp "string"`, binary, integer, and floating point literals as Cpp1, including most Unicode encoding prefixes and raw string literals.

Cpp2 supports using Cpp1 user-defined literals for compatibility, to support seamlessly using existing libraries. However, because Cpp2 has [unified function call syntax (UFCS)](expressions.md#ufcs), the preferred way to author the equivalent in Cpp2 is to just write a function or type name as a `.` call suffix. For example:

- You can create a `u8` value by writing either `u8(123)` or **`123.u8()`**. [^u8using]

- You can write a 'constexpr' function like `#!cpp nm: (value: i64) -> my_nanometer_type == { /*...*/ }` that takes an integer and returns a value of a strongly typed "nanometer" type, and then create a `nm` value by writing either `nm(123)` or **`123.nm()`**.

Both **`123.nm()`** and **`123.u8()`** are very similar to user-defined literal syntax, and more general.


## <a id="operators"></a> Operators

Operators have the same precedence and associativity as in Cpp1, but some unary operators that are prefix (always or sometimes) in Cpp1 are postfix (always) in Cpp2.

### <a id="unary-operators"></a> Unary operators

The operators `!`, `+`, and `-` are prefix, as in Cpp1. For example:

``` cpp title="Using prefix operators"
if !vec.empty() {
    vec.emplace_back( -123.45 );
}
```

| Unary operator | Cpp2 example | Cpp1 equivalent |
|---|---|---|
| `!` | `!vec.empty()` | `!vec.empty()` |
| `+` | `#!cpp +100` | `#!cpp +100` |
| `-` | `#!cpp -100` | `#!cpp -100` |

The operators `.`, `..`, `*`, `&`, `~`, `++`, `--`, `()`, `[]`, `..<`, `..=`, and `$` are postfix. For example:

``` cpp title="Using postfix operators"
//  Cpp1 examples, from cppfront's own source code:
//      address = &(*tokens)[pos + num];
//      is_void = *(*u)->identifier == "void";
//  Cpp2 equivalents:
        address = tokens*[pos + num]&;
        is_void = u**.identifier* == "void";
```

Postfix notation lets the code read fluidly left-to-right, in the same order in which the operators will be applied, and lets declaration syntax be consistent with usage syntax. For more details, see [Design note: Postfix operators](https://github.com/hsutter/cppfront/wiki/Design-note%3A-Postfix-operators).

> Note: The function call syntax `f(x)` calls a namespace-scope function only. The function call syntax `x.f()` is a unified function call syntax (aka UFCS) that calls a type-scope function in the type of `x` if available, otherwise calls the same as `f(x)`. The function call syntax `x..f()` calls a type-scope function only. For details, see [Design note: UFCS](https://github.com/hsutter/cppfront/wiki/Design-note%3A-UFCS).

| Unary operator | Cpp2 example | Cpp1 equivalent |
|---|---|---|
| `#!cpp .` | `#!cpp obj.f()` | `#!cpp obj.f()` |
| `#!cpp *` | `#!cpp pobj*.f()` | `#!cpp (*pobj).f()` or `#!cpp pobj->f()` |
| `#!cpp &` | `#!cpp obj&` | `#!cpp &obj` |
| `#!cpp ~` | `#!cpp val~` | `#!cpp ~val` |
| `#!cpp ++` | `#!cpp iter++` | `#!cpp ++iter` |
| `#!cpp --` | `#!cpp iter--` | `#!cpp --iter` |
| `(` `)` | `#!cpp f( 1, 2, 3)` | `#!cpp f( 1, 2, 3)` |
| `[` `]` | `#!cpp vec[123]` | `#!cpp vec[123]` |
| `..<` | `#!cpp v.begin()..<v.end()` | `#!cpp std::ranges::subrange(v.begin(), v.end())` |
| `..=` | `#!cpp 1..=10` | `#!cpp std::views::iota(1, 11)` |
| `$` | `val$` | _reflection — no Cpp1 equivalent yet_ |

> Note: The `...` pack expansion syntax is also supported.

> Note: The `(` `)`, `[` `]`, `..<`, and `..=` operators are treated as postfix unary operators, though they can take additional arguments.

> Note: Because `++` and `--` always have in-place update semantics, we never need to remember "use prefix `++`/`--` unless you need a copy of the old value." If you do need a copy of the old value, just take the copy before calling `++`/`--`. When you write a copyable type that overloads `operator++` or `operator--`, cppfront generates also the copy-old-value overload of that function to support natural use of the type from Cpp1 code.


### <a id="binary-operators"></a> Binary operators

Binary operators are the same as in Cpp1. From highest to lowest precedence:

| Binary operators grouped by precedence |
|---|
| `*`, `/`, `%` |
| `+`, `-` |
| `<<`, `>>` |
| `<=>` |
| `<`, `>`, `<=`, `>=` |
| `==`, `!=` |
| `&` |
| `^` |
| `|` |
| `&&` |
| `||` |
| `=` and compound assignment |


[^u8using]: Or `123.cpp2::u8()` if you aren't `using` the namespace or that specific name.

---

### Cpp2 Contracts (`docs/cpp2/contracts.md`)

# Contracts

## Overview

Cpp2 currently supports three kinds of contracts:

- **Preconditions and postconditions.** A function declaration can include `pre(condition)` and `post(condition)` before the `= /* function body */`. Before entering the function body, preconditions are fully evaluated and postconditions are captured as function expressions to be evaluated later (and perform their captures of values on entry, if any). Immediately before exiting the function body via a normal return, postconditions are evaluated. If the function exits via an exception, postconditions are not evaluated.

- **Assertions.** A function body can write `assert(condition)` assertion statements. Assertions are evaluated when control flow passes through them.

Notes:

- `condition` is an expression that evaluates to `#!cpp true` or `#!cpp false`. It will not be evaluated unless checking for this contract group is enabled (`group.is_active()` is `true`).

- Optionally, `condition` may be followed by `, "message"`, a message to include if a violation occurs. For example, `pre(condition, "message")`.

- Optionally, a `<group, pred1, pred2>` can be written inside `<` `>` angle brackets immediately before the `(`, to designate that this test is part of the [contract group](#groups) named `group` and (also optionally) [contract predicates](#predicates) `pred1` and `pred2`. If a violation occurs, `Group.report_violation()` will be called. For example, `pre<group>(condition)`. If no contract group is specified, the contract defaults to being part of the `default` group (spelled `cpp2_default` when used from Cpp1 code).

The order of evaluation is:

- First, if the contract group is `unevaluated` then the contract is ignored; `condition` is never evaluated. This special group designates conditions intended for use by static analyzers only, and the only requirement is that the condition be grammatically valid.

- Next, predicates are evaluated in order. If any predicate evaluates to `#!cpp false`, stop.

- Next, `group.is_active()` is evaluated. If that evaluates to `#!cpp false`, stop.

- Next, `condition` is evaluated. If that evaluates to `#!cpp true`, stop.

- Finally, if all the predicates were true and the group is active and the condition was false, `group.report_violation()` is called.

For example:

``` cpp title="Precondition and postcondition examples" hl_lines="2 3"
insert_at: (container, where: int, val: int)
    pre<bounds_safety>( 0 <= where <= container.ssize(), "position (where)$ is outside 'container'" )
    post              ( container.ssize() == container.ssize()$ + 1 )
= {
    _ = container.insert( container.begin()+where, val );
}
```

In this example:

- The `$` captures are performed before entering the function.

- The precondition is part of the `bounds_safety` contract group and is checked before entering the function. If the check fails, say because `where` is `#!cpp -1`, then `#!cpp cpp2::bounds_safety.report_violation("position -1 is outside 'container'")` is called.

- The postcondition is part of the `default` safety contract group.  If the check fails, then `#!cpp cpp2::default.report_violation()` is called.


## <a id="groups"></a> Contract groups

Contract groups are useful to enable or disable or [set custom handlers](#violation-handlers) independently for different groups of contracts. A contract group `grp` is just the name of an object that can be called with:

- `grp.report_violation()` and `grp.report_violation(message)`, where `message` is a `* const char` C-style text string

- `grp.is_active()`, which returns `#!cpp true` if and only if the group is enabled

You can create new contract groups just by creating new objects that have a `.report_violation` function. The object's name is the contract group's name. The object can be at any scope: local, global, or heap.

For example, here are some ways to use contract groups of type [`cpp2::contract_group`](#violation-handlers), which is a convenient group type:

``` cpp title="Using contract groups" hl_lines="1 4 6 10-12"
group_a: cpp2::contract_group = ();          // a global group

func: () = {
    group_b: cpp2::contract_group = ();      // a local group

    group_c := new<cpp2::contract_group>();  // a dynamically allocated group

    // ...

    assert<group_a >( some    && condition );
    assert<group_g >( another || condition );
    assert<group_c*>( another && condition );
}
```

You can make all the objects in a class hierarchy into a contract group by having a `.report_violation` function in a base class, and then writing contracts in that hierarchy using `<this>` as desired. This technique is used in cppfront's own reflection API:

``` cpp title="Example of using 'this' as a contract group, from cppfront 'reflect.h2'" hl_lines="8 9"
function_declaration: @copyable type =
{
    // inherits from a base class that provides '.report_violation'

    // ...

    add_initializer: (inout this, source: std::string_view)
        pre<this> (!has_initializer(), "cannot add an initializer to a function that already has one")
        pre<this> (parent_is_type(),   "cannot add an initializer to a function that isn't in a type scope")
    = { /*...*/ }

    // ...

}
```


## <a id="predicates"></a> Contract predicates

Contract predicates are useful to conditionally check specific contracts as a static or dynamic property. Importantly, if any predicate is `#!cpp false`, the check's conditional expression will not be evaluated.

For example:

``` cpp title="Using contract predicates" hl_lines="1 3 4 7"
is_checked_build: bool == SEE_BUILD_FLAG;   // a static (compile-time) predicate

checking_enabled: bool =  /*...*/ ;         // a dynamic (run-time) predicate,
                                            // could change as the program runs

func: () = {
    assert<audit, is_checked_build, checking_enabled>( condition );
}
```

In this example, the order of evaluation is:

- `is_checked_build` is evaluated. Since it is a compile-time value, the evaluation can happen at compile time. If it evaluates to `#!cpp false`, then stop; the entire contract could be optimized away by the compiler.

- Otherwise, next `checking_enabled` is evaluated at run time. If it evaluates to `#!cpp false`, then stop.

- Otherwise, next `audit.is_active()` is evaluated. If it evaluates to `#!cpp false`, then stop.

- Otherwise, next `condition` is evaluated. If it evaluates to `#!cpp true`, then stop.

- Otherwise, `audit.report_violation()` is called.


## <a id="violation-handlers"></a> `cpp2::contract_group`, and customizable violation handling

The contract group object could also provide additional functionality. For example, Cpp2 comes with the `cpp2::contract_group` type which allows installing a customizable handler for each object. Each object can only have one handler at a time, but the handler can change during the course of the program. `contract_group` supports:

- `.set_handler(pfunc)` accepts a pointer to a handler function with signature `#!cpp * (* const char)`.

- `.get_handler()` returns the current handler function pointer, or null if none is installed.

- `.is_active()` returns whether there is a current handler installed.

- `.enforce(condition, message)` evaluates `condition`, and if it is `false` then calls `.report_violation(message)`.

Cpp2 comes with five predefined `contract group` global objects in namespace `cpp2`:

- `default`, which is used as the default contract group for contracts that don't specify a group.

- `type_safety` for type safety checks.

- `bounds_safety` for bounds safety checks.

- `null_safety` for null safety checks.

- `testing` for general test checks.

For these groups, the default handler is `cpp2::report_and_terminate`, which prints information about the violation to `std::cerr` and then calls `std::terminate()`. But you can customize it to do anything you want, including to integrate with any third-party or in-house error reporting system your project is already using. For example:

``` cpp title="Example of customized contract violation handler" hl_lines="2 8-10 17"
main: () -> int = {
    cpp2::default.set_handler(call_my_framework&);
    assert<default>(false, "this is a test, this is only a test");
    std::cout << "done\n";
}

call_my_framework: (msg: * const char) = {
    //  You can do anything you like here, including arbitrary work
    //  and integration with your current error reporting libraries,
    //  log-and-continue, throw an exception, whatever is wanted...
    std::cout
        << "sending error to my framework... ["
        << msg << "]\n";
    exit(0);
}
//  Prints:
//      sending error to my framework... [this is a test, this is only a test]
```

---

### Cpp2 Declarations (`docs/cpp2/declarations.md`)

# Declarations and aliases

## Unified declarations

All Cpp2 declarations are written as **"_name_ `:` _kind_ `=` _statement_"**.

- The _name_ must be a valid identifier (start with a letter, and consist of letters, digits, or `_`). The name can be variadic (be a name for a list of zero or more things) by writing a `...` suffix at the end of the name.

- The `:` is pronounced **"is a."**

- The _kind_ can start with [template parameters](#template-parameters) and end with [`#!cpp requires` constraints](#requires).

- The `=` is pronounced **"defined as."** For the definition of something that will always have the same value, write `==`, pronounced **"defined as a synonym for"**.

- The _statement_ is typically an expression statement (e.g., `#!cpp a + b();`) or a compound statement (e.g., `#!cpp { /*...*/ return c(d) / e; }`).

Various parts of the syntax allow a `_` "don't care" wildcard or can be omitted entirely to accept a default (e.g., `#!cpp x: int = 0;` can be equivalently written `#!cpp x: _ = 0;` or `#!cpp x := 0;` both of which deduce the type).

> Notes:
>
> - When the type is omitted, whitespace does not matter, and writing `#!cpp x: = 0;` or `#!cpp x : = 0;` or `#!cpp x := 0;` or other whitespace is just a stylistic choice. This documentation's style uses the last one, except when there are multiple adjacent declaration lines this style lines up their `:` and `=`.
>
> - `==` stresses that this name will always have the given value, to express [aliases](#aliases) and side-effect-free 'constexpr' [function aliases](#function-aliases).


### <a id="unnamed-declarations"></a> Unnamed declaration expressions

In an expression, most declarations can be written without a name (just starting with `:`). Such unnamed declaration expressions are useful for single-use temporary variables or 'lambda' functions that don't need a name to be reused elsewhere. For example:

- `#!cpp :widget = 42` is an unnamed expression-local (aka temporary) object of type `widget` defined as having the initial value `#!cpp 42`. It uses the same general syntax, just without declaring a name.

- `#!cpp :(x) = std::cout << x` is an unnamed expression-local generic function expression (aka lambda) defined as having the given one-statement body. The body can include [captures](expressions.md/#captures).

Both just omit the name and make the final `;` optional. Otherwise, they have the identical syntax and meaning as if you declared the same thing with a name outside expression scope (e.g., `w: widget = 42;` or `f: (x) = std::cout << x;`) and then used the name in the expression.

> Note: Throughout Cpp2, every declaration is written with `:`, and every use of `:` is a declaration.



### <a id="function-scope-unification"></a> From functions to local scopes, and back again

The function syntax is deliberately designed to be general, so you can omit parts. This means Cpp2 has no special "lambda function" syntax for unnamed functions; an unnamed function is really an unnamed function, written using the ordinary function just without a name. This scales all the way down to ordinary blocks and statements, which are written the same as functions that have no name or parameters.

We can illustrate this in two directions. First, let's start with a full function, and successively omit optional parts that we aren't currently using:

``` cpp title="Start with a full function, and successively omit optional parts if unused" hl_lines="1 5 9 13"
// Full named function
f:(x: int = init) = { /*...*/ }     // x is a parameter to the function
f:(x: int = init) = statement;      // same, except return type is deduced

// Omit name => anonymous function (aka 'lambda')
 :(x: int = init) = { /*...*/ }     // x is a parameter to the function
 :(x: int = init) = statement;      // same, except return type is deduced

// Omit declaration => local and immediate (aka 'let' in other languages)
  (x: int = init)   { /*...*/ }     // x is a parameter to this
  (x: int = init)   statement;      //  compound or single-statement

// Omit parameters => ordinary block or statement
                    { /*...*/ }     // ordinary compound statement
                    statement;      // ordinary statement
```

Conversely, we can start with an ordinary block or statement, and successively build it up to make it more powerful:

``` cpp title="Start with an ordinary block or statement, and successively add parts" hl_lines="1 5 9 13"
// Ordinary block or statement
                    { /*...*/ }     // ordinary compound statement
                    statement;      // ordinary statement

// Add parameters => more RAII locally-scoped variables
  (x: int = init)   { /*...*/ }     // x is destroyed after this
  (x: int = init)   statement;      //  compound or single-statement

// Add declaration => treat the code as a callable object
 :(x: int = init) = { /*...*/ }     // x is a parameter to the function
 :(x: int = init) = statement;      // same, except return type is deduced

// Add name => full named function
f:(x: int = init) = { /*...*/ }     // x is a parameter to the function
f:(x: int = init) = statement;      // same, except return type is deduced

```


### <a id="template-parameters"></a> Template parameters

A template parameter list is a [list](common.md#lists) enclosed by `<` `>` angle brackets, and the parameters separated by commas. Each parameter is declared using the [same syntax as any type or object](declarations.md). If a parameter's **`:`** ***kind*** is not specified, the default is `: type`.

For example:

``` cpp title="Declaring template parameters" hl_lines="1-3 8-9"
array: <T: type, size: i32> type
    // parameter T is a type
    // parameter size is a 32-bit int
= {
    // ...
}

tuple: <Ts...: type> type
    // parameter Ts is variadic list of zero or more types
= {
    // ...
}
```


### <a id="requires"></a> `#!cpp requires` constraints

A `#!cpp requires` ***condition*** constraint appears at the end of the ***kind*** of a templated declaration. If the condition evaluates to `#!cpp false`, that specialization of the template is ignored as if not declared.

For example:

``` cpp title="A requires constraint on a variadic function" hl_lines="3"
print: <Args...: type>
       (inout out: std::ostream, args...: Args)
       requires sizeof...(Args) >= 1u
= {
    (out << ... << args);
}
```


### Examples

```
/* Detailed source-code truncated for AI context efficiency. */
```

> Note: `@enum` is a metafunction, which provides an easy way to opt into a group of defaults, constraints, and generated functions. For details, see [`@enum`](metafunctions.md#enum).


## <a id="aliases"></a> Aliases

Aliases are pronounced **"synonym for"**, and written using the same **name `:` kind `=` value** [declaration syntax](../cpp2/declarations.md) as everything in Cpp2:

- **name** is declared to be a synonym for **value**.

- **kind** can be any of the kinds: `namespace`, `type`, a function signature, or a type.

- **`==`**, pronounced **"defined as a synonym for"**, always precedes the value. The `==` syntax stresses that during compilation every use of the name could be equivalently replaced with the value.

- **value** is the expression that the **name** is a synonym for.


### <a id="namespace-aliases"></a> Namespace aliases

A namespace alias is written the same way as a [namespace](namespaces.md), but using `==` and with the name of another namespace as its value. For example:

``` cpp title="Namespace aliases" hl_lines="1 2 4 5 8 12 16"
//  'chr' is a namespace defined as a synonym for 'std::chrono'
chr    : namespace == std::chrono;

//  'chrlit' is a namespace defined as a synonym for 'std::chrono_literals'
chrlit : namespace == std::chrono_literals;

main: () = {
    using chrlit::_ ;

    //  The next two lines are equivalent
    std::cout << "1s is (std::chrono::nanoseconds(1s).count())$ns\n";
    std::cout << "1s is (chr::nanoseconds(1s).count())$ns\n";
}
//  Prints:
//      1s is 1000000000ns
//      1s is 1000000000ns
```


### <a id="type-aliases"></a> Type aliases

A type alias is written the same way as a [type](types.md), but using `==` and with the name of another type as its value. For example:

``` cpp title="Type aliases" hl_lines="1 2 7 10"
//  'imap<T>' is a type defined as a synonym for 'std::map<i32, T>'
imap : <T> type == std::map<i32, T>;

main: () = {
    //  The next two lines declare two objects with identical type
    map1: std::map<i32, std::string> = ();
    map2: imap<std::string> = ();

    //  Assertion they are the same type, using the same_as concept
    static_assert( std::same_as< decltype(map1), decltype(map2) > );
}
```


### <a id="function-aliases"></a> Function aliases

A function alias is written the same way as a [function](functions.md), but using `==` and with a side-effect-free body as its value; the body must always return the same value for the same input arguments. For example:

``` cpp title="Function aliases" hl_lines="1 2 6 9 12 15"
//  'square' is a function defined as a synonym for the value of 'i * i'
square: (i: i32) -> _ == i * i;

main: () = {
    //  It can be used at compile time, with compile time values
    ints: std::array<i32, square(4)> = ();

    //  Assertion that the size is the square of 4
    static_assert( ints.size() == 16 );

    //  And it can be used at run time, with run time values
    std::cout << "the square of 4 is (square(4))$\n";
}
//  Prints:
//      the square of 4 is 16
```

> Note: A function alias is compiled to a Cpp1 `#!cpp constexpr` function.


### <a id="object-aliases"></a> Object aliases

An object alias is written the same way as an [object](objects.md), but using `==` and with a side-effect-free value. For example:

``` cpp title="Function aliases" hl_lines="1 2 5 6"
//  'BufferSize' is an object defined as a synonym for the value 1'000'000
BufferSize: i32 == 1'000'000;

main: () = {
    buf: std::array<std::byte, BufferSize> = ();
    static_assert( buf.size() == BufferSize );
}
```

> Note: An object alias is compiled to a Cpp1 `#!cpp constexpr` object.

---

### Cpp2 Expressions (`docs/cpp2/expressions.md`)

# Common expressions

## <a id="ufcs"></a> Calling functions: `f(x)` syntax, `x.f()` UFCS syntax, and `x..f()` members-only syntax

A function argument list is a [list](common.md#lists) of arguments enclosed by `(` `)` parentheses.

A function call like `f(x)` is a normal function call that will call non-member functions only, as usual in C++.

A function call like `x.f()` is a unified function call syntax (aka UFCS) call. It will call a member function if one is available, and otherwise will call `f(x)`. Having UFCS is important for generic code that may want to call a member or a non-member function, whichever is available. It's also important to enable fluid programming styles and natural IDE autocompletion support.

An operator notation call like `#!cpp a + b` will call an overloaded operator function if one is available, as usual in C++.

A function call like `x..f()` will consider member functions only.

For example:

``` cpp title="Function calls" hl_lines="3 7 11 16 19 20"
//  Generic function to log something
//  This calls operator<< using operator notation
log: (x) = { clog << x; }

f: ( v : std::vector<widget> ) = {
    //  This calls log() with the result of std::vector::size()
    log( v.size() );

    //  This calls log() with the result of std::ssize(v), because
    //  v doesn't have a .ssize member function
    log( v.ssize() );
}

//  Generic function to use standard I/O to print any printable types
//  safely using string interpolation (instead of type-unsafe format strings)
hello: (name, height: float) = {
    //  Using UFCS to make direct calls to C functions as if they were members
    stdout.fprintf("%s", ("Hi (name)$, your height is (height:.1f)$\"!\n").c_str());
    //  Equivalent using iostreams:
    //        std::cout << "Hello (name)$, your height is (height:.1f)$ inches!\n";

    //  The C and C++ standard libraries are not only fully available,
    //  but safer (and arguably nicer) when used from Cpp2 syntax code
}

main: () = {
    hello("Flimnap", 6.5);
    hello("Goliath", 115);
    hello("Polyphemus", 180);
}
//  Sample output:
//      Hi Flimnap, your height is 6.5"!
//      Hi Goliath, your height is 115.0"!
//      Hi Polyphemus, your height is 180.0"!
```

To explicitly treat an object name passed as an argument as `move` or `out`, write that keyword before the variable name.

- Explicit `move` is rarely needed. Every definite last use of a local variable will apply `move` by default. Writing `move` from an object before its definite last use means that later uses may see a moved-from state.

- Explicit `out` is needed only when initializing a local variable separately from its declaration using a call to a function with an `out` parameter. For details, see [Guaranteed initialization](../cpp2/objects.md#init).

For example:



## <a id="wildcard"></a> <a id="discard"></a> `_` — the "don't care" wildcard, including explicit discard

`_` is pronounced **"don't care"** and allowed as a wildcard in most contexts. For example:

``` cpp title="Using the _ wildcard" hl_lines="2 5 11"
//  We don't care about the guard variable's name
_ : std::lock_guard = mut;

//  If we don't care to write the variable's type, deduce it
x : _ = 42;
    // in cases like this, _ can be omitted...
    // this is equivalent to "x := 42;"

return inspect v -> std::string {
    is std::vector = "v is a std::vector";
    is _ = "unknown";   // don't care what else, match anything
};
```

Cpp2 treats all function outputs (return values, and results produced via `inout` and `out` parameters) as important, and does not let them be silently discarded by default. To explicitly discard such a value, assign it to `_`. For example:

``` cpp title="Using _ for explicit discard" hl_lines="1 8"
_ = vec.emplace_back(1,2,3);
    // "_ =" is required to explicitly discard emplace_back's
    // return value (which is non-void since C++17)

{
    x := my_vector.begin();
    std::advance(x, 2);
    _ = x;  // required to explicitly discard x's new value,
            // because std::advance modifies x's value
}
```

For details, see [Design note: Explicit discard](https://github.com/hsutter/cppfront/wiki/Design-note%3A-Explicit-discard). In Cpp2, data is always initialized, data is never silently lost, data flow is always visible. Data is precious, and it's always safe.


## Type/value queries and casts

### <a id="is"></a> `is` — safe type/value queries

An `x is C` expression allows safe type and value queries, and evaluates to `#!cpp true` if `x` matches constraint `C`. It supports both static and dynamic queries, including customization, with support for standard library dynamic types like `std::variant`, `std::optional`, `std::expected`, and `std::any` provided out of the box.

There are two kinds of `is`:

- A **type query**, where `C` is a type constraint: a type, a template name, a concept, or a type predicate. Here `x` may be a type, or an object or expression; if it is an object or expression, the query refers to `x`'s type.

| Type constraint kind | Example |
|---|---|
| Static type query | `x is int` |
| Dynamic type query | `ptr* is Shape` |
| Static template type query | `x is std::vector` |
| Static concept query | `x is std::integral` |

- A **value query**, where `C` is a value constraint: a value, or a value predicate. Here `x` must be an object or expression.

| Value constraint kind | Example |
|---|---|
| Value | `#!cpp x is 0` |
| Value predicate | `#!cpp x is (in(10, 20))` |

`is` is useful throughout the language, including in `inspect` pattern matching alternatives. `is` is extensible, and works out of the box with `std::variant`, `std::optional`, `std::expected`, and `std::any`. For examples, see:

- [`mixed-inspect-templates.cpp2`](https://github.com/hsutter/cppfront/tree/main/regression-tests/mixed-inspect-templates.cpp2)
- [`mixed-inspect-values.cpp2`](https://github.com/hsutter/cppfront/tree/main/regression-tests/mixed-inspect-values.cpp2)
- [`mixed-inspect-values-2.cpp2`](https://github.com/hsutter/cppfront/tree/main/regression-tests/mixed-inspect-values-2.cpp2)
- [`mixed-type-safety-1.cpp2`](https://github.com/hsutter/cppfront/tree/main/regression-tests/mixed-type-safety-1.cpp2)
- [`pure2-enum.cpp2`](https://github.com/hsutter/cppfront/tree/main/regression-tests/pure2-enum.cpp2)
- [`pure2-inspect-expression-in-generic-function-multiple-types.cpp2`](https://github.com/hsutter/cppfront/tree/main/regression-tests/pure2-inspect-expression-in-generic-function-multiple-types.cpp2)
- [`pure2-inspect-fallback-with-variant-any-optional.cpp2`](https://github.com/hsutter/cppfront/tree/main/regression-tests/pure2-inspect-fallback-with-variant-any-optional.cpp2)
- [`pure2-type-safety-1.cpp2`](https://github.com/hsutter/cppfront/tree/main/regression-tests/pure2-type-safety-1.cpp2)
- [`pure2-type-safety-2-with-inspect-expression.cpp2`](https://github.com/hsutter/cppfront/tree/main/regression-tests/pure2-type-safety-2-with-inspect-expression.cpp2)

Here are some `is` queries with their Cpp1 equivalents. In this table, uppercase names are type names, lowercase names are objects, `v` is a `std::variant` where one alternative is `T`, `o` is a `std::optional<T>`, and `a` is a `std::any`:

| Some sample `is` queries | Cpp1 equivalent
|---|---|
| `X is Y && Y is X` | `std::is_same_v<X,Y>` |
| `D is B` | `std::is_base_of<B,D>` |
| `#!cpp pb is *D` | `#!cpp dynamic_cast<D*>(pb) != nullptr` |
| `v is T`  | `std::holds_alternative<T>(v)` |
| `a is T`  | `#!cpp a.type() == typeid(T)` |
| `o is T`  | `o.has_value()` |

> Note: `is` unifies a variety of differently-named Cpp1 language and library queries under one syntax, and supports only the type-safe ones.


### <a id="as"></a> `as` — safe casts and conversions

An `x as T` expression allows safe type casts. `x` must be an object or expression, and `T` must be a type. Like `is`, `as` supports both static and dynamic typing, including customization, with support for standard library dynamic types like `std::variant`, `std::optional`, `std::expected`, and `std::any` provided out of the box. For example:

``` cpp title="Using as" hl_lines="4 6 14"
main: () = {
    a: std::any = 0;                // a's type is now int, value 0
    test(a);                        // prints "zero"
    a = "plugh" as std::string;     // a's type is now std::string, value "plugh"
    test(a);                        // prints "plugh"
    test("xyzzy" as std::string);   // prints "xyzzy"
}

//  A generic function that takes an argument 'x' of any type,
//  same as "void test( auto const& x )" in C++20 syntax
test: (x) = {
    std::cout << inspect x -> std::string {
        is 0           = "zero";
        is std::string = x as std::string;
        is _           = "(no match)";
    } << "\n";
}
```

Here are some `as` casts with their Cpp1 equivalents. In this table, uppercase names are type names, lowercase names are objects, `v` is a `std::variant` where one alternative is `T`, `o` is a `std::optional<T>`, and `a` is a `std::any`:

| Some sample `as` casts | Cpp1 equivalent
|---|---|
| `x as Y` | `Y{x}` |
| `#!cpp pb as *D` | `#!cpp dynamic_cast<D*>(pb)` |
| `v as T`  | `std::get<T>(v)` |
| `a as T`  | `std::any_cast<T>(a)` |
| `o as T`  | `o.value()` |

> Note: `as` unifies a variety of differently-named Cpp1 language and library casts and conversions under one syntax, and supports only the type-safe ones.


### <a id="unchecked-casts"></a> Unchecked (explicitly type-unsafe) casts

Casts that are not known to be type-safe at compile time must always be explicit.

To perform a numeric narrowing cast, such as `i32` to `i16` or `u32`, use `unchecked_narrow<To>(from)`. Otherwise, if you must perform any other type-unsafe cast, use `unchecked_cast<To>(from)`. For example:

``` cpp title="Type-unsafe narrowing and casts must be explicit" hl_lines="2 3 6 7"
f: (i: i32, inout s: std::string) = {
    // j := i as i16;                     // error, maybe-lossy narrowing
    j := unchecked_narrow<i16>(i);           // ok, 'unchecked' is explicit

    pv: *void = s&;
    // pi := pv as *std::string;          // error, type-unsafe cast
    pi := unchecked_cast<*std::string>(pv);  // ok, 'unchecked' is explicit
}
```


## <a id="inspect"></a> `inspect` — pattern matching

An `inspect expr -> Type = { /* alternatives */ }` expression allows pattern matching using `is`.

- `expr` is evaluated once.

- Each alternative is spelled `is C = statement;` and are evaluated in order. Each `is C` is evaluated as if called with `expr is C`, and if it evaluates to `#!cpp true`, then its `#!cpp = alternative;` body is used as the value of the entire `inspect` expression, and the meaning is the same as if the entire `inspect` expression had been written as just `#!cpp :Type = alternative;` — i.e., an unnamed object expression (aka 'temporary object') of type `Type` initialized with `alternative`.

- A catchall `is _` is required.

For example:

``` cpp title="Using inspect" hl_lines="6-13"
//  A generic function that takes an argument 'x' of any type
//  and inspects various things about `x`
test: (x) = {
    forty_two := 42;
    std::cout
        << inspect x -> std::string {
            is 0           = "zero";            // == 0
            is (forty_two) = "the answer";      // == 42
            is int         = "integer";         // is type int (and not 0 or 42)
            is std::string = x as std::string;  // is type std::string
            is std::vector = "a std::vector";   // is a vector</*of-some-type*/>
            is _           = "(no match)";      // is something else
        }
        << "\n";
}

//  Sample call site
test(42);
    //  Behaves as if the following function were called:
    //      test: (x) = { std::cout << (:std::string = "the answer") << "\n"; }
    //  (and that's why inspect alternatives are introduced with '=')
```

For more examples, see also the examples in the previous two sections on `is` and `as`, many of which use `inspect`.


## <a id="ranges"></a> `..<` and `..=` — range operators

`..<` and `..=` designate a range of things. Use `begin ..< end` for a half-open range (that does not include `end`) and `first ..= last` for a closed range (that does include `last`, and `last` must be a valid value and must be valid to increment once). These operators work for any type that supports `++`; they start with the `first` value, and use `++` to increment until they reach the `last` value (which is included by `..=`, and not included by `..<`).

> Note: For all numeric ranges, `last`'s value must be reachable by incrementing `first` a finite number of times. For `..=` closed numeric ranges, `last` must not be `std::numeric_limits<size_t>::max()` or `std::numeric_limits<ptrdiff_t>::max()`.

For example:

``` cpp title="Using ..< and ..= for ranges" hl_lines="5 11 16-18"
test: (v: std::vector<std::string>) =
{
    //  Print strings from "Nonesuch" (if present) onward
    i1 := v.std::ranges::find("Nonesuch");
    for i1 ..< v.end() do (e) {
        std::cout << "  (e*)$\n";
    }

    if v.ssize() > 2 {
        //  Print indexes 1 and 2 of v
        for 1 ..= 2 do (e) {
            std::cout << "  (e)$  (v[e])$\n";
        }
    }

    std::cout << "  ((1 ..= 100).sum())$ \n";
    std::cout << "  ((1 ..< 100).contains(99))$ \n";
    std::cout << "  ((1 ..< 100).contains(100))$ \n";
}

main: () = {
    vec: std::vector<std::string> = ("Beholder", "Grue", "Nonesuch", "Wumpus");
    test( vec );
}
//  Prints:
//    Nonesuch
//    Wumpus
//    1  Grue
//    2  Nonesuch
//    5050
//    true
//    false
```


## <a id="captures"></a> `$` — captures, including interpolations

Suffix `$` is pronounced **"paste the value of"** and captures the value of an expression at the point when the expression where the capture is written is evaluated. Depending on the complexity of the capture expression `expr$` and where it is used, parentheses `(expr)$` may be required for precedence or to show the boundaries of the expression.

`x$` always captures `x` by value. To capture by reference, take the address and capture a pointer using `x&$`. If the value is immediately used, dereference again; for example `:(val) total&$* += val` adds to the `total` local variable itself, not a copy.

Captures are evaluated at the point where they are written in function expressions, contract postconditions, and string literals. The stored captured value can then be used later when evaluating its context, such as when the function expression body containing the captured value is actually called later (one or more times), when the postcondition containing the captured value is evaluated later when the function returns, or when the string literal containing the captured value is read later.

The design and syntax are selected so that capture is spelled the same way in all contexts. For details, see [Design note: Capture](https://github.com/hsutter/cppfront/wiki/Design-note%3A-Capture).


### <a id="function-captures"></a> Capture in function expressions (aka lambdas)

Any capture in a function expression body is evaluated at the point where the function expression is written, at the declaration of the function expression. The function expression itself is then evaluated each time the function is invoked, and can reference the captured value.

For example:

``` cpp title="Capture in an unnamed function expression (aka lambda)" hl_lines="7 8 13-18"
main: () = {
    s := "-ish\n";
    vec: std::vector = (1, 2, 3, 5, 8, 13 );

    std::ranges::for_each(
        vec,
        :(i) = std::cout << i << s$
        //  Function capture: Paste the value of 's'
    );
}

//  prints:
//      1-ish
//      2-ish
//      3-ish
//      5-ish
//      8-ish
//      13-ish
```

Another example:

``` cpp title="Capture in a named function expression (aka lambda)" hl_lines="2 4 9 14 15"
main: () = {
    price := 100;
    func := // Note: 'func' is a named variable of deduced type initialized to ...
        :() = { std::cout << "Price = " << price$ << "\n"; }  // ... this lambda
        ;   // This is a way to declare 'local functions', which can also capture
            // (In the future, Cpp2 may directly support local functions)
    func();
    price = 200;
    func();
}

//  prints:
//      Price = 100
//      Price = 100
```


### <a id="postcondition-captures"></a> Capture in contract postconditions

Any capture in a postcondition is evaluated at the point where the postcondition is written, at the beginning (entry) of the function. The postcondition itself is then evaluated when the function returns, and can reference the captured value.

For example:

``` cpp title="Capture in contract postconditions" hl_lines="2"
push_back: (coll, value)
    post(coll.ssize() == coll.ssize()$ + 1)
    //  Paste the value of `coll.ssize()`
= {
    // ...
}
```


### <a id="interpolation"></a> Capture in string interpolation

A string literal can capture the value of an expression `expr` by writing `(expr)$` inside the string literal. The `(` `)` are required, and cannot be nested. A string literal has type `std::string` if it performs any captures, otherwise it is a normal C/C++ string literal (array of characters).

Any capture in a string literal is evaluated at the point where the string literal is written. The string literal can be used repeatedly later, and includes the captured value.

For example:

``` cpp title="Capture for string interpolation" hl_lines="2 5"
x := 0;
std::cout << "x is (x)$\n";
        // Paste the value of `x`
x = 1;
std::cout << "now x+2 is (x+2)$\n";
        // Paste the value of `x+2`

//  prints:
//      x is 0
//      now x+2 is 3
```

A string literal capture can include a `:suffix` where the suffix is a [standard C++ format specification](https://en.cppreference.com/w/cpp/utility/format/spec). For example, `#!cpp (x.price(): <10.2f)$` evaluates `x.price()` and converts the result to a string with 10-character width, 2 digits of precision, and left-justified.

---

### Cpp2 Functions (`docs/cpp2/functions.md`)

# Functions

## Overview

A function is defined by writing a function signature after the `:` and a statement (expression or `{` `}` compound statement) after the `=`. After the optional [template parameters](declarations.md#template-parameters) available for all declarations, a function signature consists of a possibly-empty [parameter list](#parameters), and one or more optional [return values](#return-values).

For example, the minimal function named `func` that takes no parameters and returns nothing (`#!cpp void`) is:

``` cpp title="A minimal function"
func: ( /* no parameters */ ) = { /* empty body */ }
```


## <a id="function-signatures"></a> Function signatures: Parameters, returns, and using function types

### <a id="parameter-kinds"></a> Overview

There are six kinds of function parameters, and two of them are the kinds of functions returns:

| Kind | Parameter | Return |
| -------- | -------- | ------- |
| `in` | ⭐   |  |
| `inout` | ✅    | |
| `out` | ✅  |   |
| `copy` | ✅  | |
| `move` | ✅  | ✅ |
| `forward` | ✅  | ⭐ |

The two cases marked ⭐ can automatically pass/return by value or by reference, and so they can be optionally written with `_ref` to require pass/return by reference and not by value (i.e., `in_ref`, `-> forward_ref`).

That's it. For details, see below.

### <a id="parameters"></a> Parameters

The parameter list is a [list](common.md#lists) enclosed by `(` `)` parentheses. Each parameter is declared using the [same unified syntax](declarations.md) as used for all declarations. For example:

``` cpp title="Declaring parameters" hl_lines="2-4"
func: (
    x: i32,                         // parameter x is a 32-bit int
    y: std::string,                 // parameter y is a std::string
    z: std::map<i32, std::string>   // parameter z is a std::map
    )
= {
    // ...
}
```

The parameter type can be deduced by writing `_` (the default, so it can be omitted). You can use `is` to declare a type constraint (e.g., a concept) that a deduced type must match, in which case `_` is required. For example:

``` cpp title="Declaring a parameter of constrained deduced type" hl_lines="2 3 6"
//  ordinary generic function, x's type is deduced
print: (x: _) = { std::cout << x; }
print: (x)    = { std::cout << x; } // same, using the _ default

//  number's type is deduced, but must match the std::integral concept
calc: (number: _ is std::integral) = { /*...*/ }
```

There are six ways to pass parameters that cover all use cases, that can be written before the parameter name:

| Parameter&nbsp;***kind*** | "Pass an `x` the function ______" | Accepts arguments that are | Special semantics | ***kind*** `x: X` compiles&nbsp;to&nbsp;Cpp1&nbsp;as |
|---|---|---|---|---|
| <big>**`in`**</big> (default) | can read from | anything | always `#!cpp const`<p>automatically passes by value if cheaply copyable<br><br>to guarantee a by-reference passing, use `in_ref` | `X const x` or <br> `X const& x` |
| <big>**`copy`**</big> | gets a copy of | anything | acts like a normal local variable initialized with the argument | `X x` |
| <big>**`inout`**</big> | can read from and write to | lvalues | | `X& x` |
| <big>**`out`**</big> | writes to (including construct) | lvalues (including uninitialized) | must `=` assign/construct before other uses | `cpp2::impl::out<X>` |
| <big>**`move`**</big> | moves from (consume the value of) | rvalues | automatically moves from every definite last use | `X&&` |
| <big>**`forward`**</big> | forwards | anything | automatically forwards from every definite last use | `auto&&`, and if a specific type is named also a `requires`-constraint requiring convertibilty to that type |

> Note: All parameters and other objects in Cpp2 are `#!cpp const` by default, except for local variables. For details, see [Design note: `#!cpp const` objects by default](https://github.com/hsutter/cppfront/wiki/Design-note%3A-const-objects-by-default).

For example:

``` cpp title="Declaring parameter kinds" hl_lines="2 3 10"
append_x_to_y: (
    x       : i32,          // an i32 I can read from (i.e., const)
    inout y : std::string   // a string I can read from and write to
    )
= {
    y = y + to_string(x);   // read x, read and write y
}

wrap_f: (
    forward x               // a generic value of deduced type I can forward
)                           //  (omitting x's  type means the same as ': _')
= {
    global_counter += x;    // ok to read x
    f(x);                   // last use: automatically does 'std::forward<T>(x)'
}
```


### <a id="return-values"></a> Return values

A function can return either a single anonymous return value, or a return parameter list containing named return value(s). The default is `#!cpp -> void`.

#### Single anonymous return values

**`#!cpp ->` _kind_ `X`** to return a single unnamed value of type `X` using the same kinds as in the [parameters](#parameters) syntax, but where the only legal kinds are `move` (the default) or `forward` (with optional `forward_ref`; see below).  The type can be  `#!cpp -> void` to signify the function has no return value. If `X` is not `#!cpp void`, the function body must have a `#!cpp return /*value*/;` statement that returns a value of type `X` on every path that exits the function, or must be a single expression of type `X`.

To deduce the return type, write `_`:

- `-> _` deduces by-value return.
- `-> forward _` deduces by-value return (if the function returns a prvalue or type member object) or by-reference return (everything else), based on the `decltype` of the returned expression.
- `-> forward_ref _` deduces by-reference return only.

A function whose body is a single expression `= expr;` defaults to `-> forward _ = { return expr; }`.

For example:

``` cpp title="Functions with an unnamed return value" hl_lines="2 4 7 9 12 14 15 18 20 22"
//  A function returning no value (void)
increment_in_place: (inout a: i32) -> void = { a++; }
//  Or, using syntactic defaults, the following has identical meaning:
increment_in_place: (inout a: i32) = { a++; }

//  A function returning a single value of type i32
add_one: (a: i32) -> i32 = { return a+1; }
//  Or, using syntactic defaults, the following has identical meaning:
add_one: (a: i32) -> i32 = a+1;

//  A generic function returning a single value of deduced type
add: <T: type, U: type> (a:T, b:U) -> forward _ = { return a+b; }
//  Or, using syntactic defaults, the following have identical meaning:
add: (a, b) -> forward _ = a+b;
add: (a, b) a+b;

//  A generic function expression returning a single value of deduced type
vec.std::ranges::sort( :(x:_, y:_) -> forward _ = { return y<x; } );
//  Or, using syntactic defaults, the following has identical meaning:
vec.std::ranges::sort( :(x,y) = y<x );
//  Both are identical to this, which uses the most verbose possible syntax:
vec.std::ranges::sort( :<X:type, Y:type> (x:X, y:Y) -> forward _ = { return y<x; } );
```

#### Return parameter lists: Nameable return value(s)

**`#!cpp -> ( /* parameter list */ )`** to return a list of named return parameters using the same [parameters](#parameters) syntax, but where the only needed kinds are `out` (the default, which moves where possible) or `forward`. The function body must [initialize](objects.md#init) the value of each return-parameter `ret` in its body the same way as any other local variable. An explicit return statement is written just `#!cpp return;` and returns the named values; the function has an implicit `#!cpp return;` at the end. If only a single return parameter is in the list, it is emitted in the lowered Cpp1 code the same way as a single anonymous return value above, so its name is only available inside the function body.

For example:

``` cpp title="Function with multiple/named return values" hl_lines="1 3-4 7-8 14 16-17"
divide: (dividend: int, divisor: int) -> (quotient: int, remainder: int) = {
    if divisor == 0 {
        quotient  = 0;                      // constructs quotient
        remainder = 0;                      // constructs remainder
    }
    else {
        quotient = dividend / divisor;      // constructs quotient
        remainder = dividend % divisor;     // constructs remainder
    }
}

main: () = {
    div := divide(11, 5);
    std::cout << "(div.quotient)$, (div.remainder)$\n";
}
//  Prints:
//     2, 1
```

This next example declares a [member function](types.md#this-parameter) with multiple return values in a [type](types.md) named `set`:

``` cpp title="Member function with multiple/named return values" hl_lines="7 9 10 22-24"
set: <Key> type = {
    container: std::set<Key>;
    iterator : type == std::set<Key>::iterator;

    //  A std::set::insert-like function using named return values
    //  instead of just a std::pair/tuple
    insert: (inout this, value: Key) -> (where: iterator, inserted: bool) = {
        set_returned := container.insert(value);
        where    = set_returned.first;
        inserted = set_returned.second;
    }

    ssize: (this) -> i64 = std::ssize(container);

    // ...
}

use_inserted_position: (_) = { }

main: () = {
    m: set<std::string> = ();
    ret := m.insert("xyzzy");
    if ret.inserted {
        use_inserted_position( ret.where );
    }
    assert( m.ssize() == 1 );
}
```


#### <a id="nodiscard-outputs"></a> Function outputs are not implicitly discardable

A function's outputs are its return values, and the "out" state of any `out` and `inout` parameters.

Function outputs cannot be silently discarded. To explicitly discard a function output, assign it to `_`. For example:

``` cpp title="No silent discard" hl_lines="9 11 13 17-18 23-24 29-30"
f: ()             -> void = { }
g: ()             -> int  = { return 10; }
h: (inout x: int) -> void = { x = 20; }

main: ()
= {
    f();                    // ok, no return value

    std::cout << g();       // ok, use return value

    _ = g();                // ok, explicitly discard return value

    g();                    // ERROR, return value is ignored

    {
        x := 0;
        h( x );             // ok, x is referred to again...
        std::cout << x;     // ... here, so its new value is used
    }

    {
        x := 0;
        h( x );             // ok, x is referred to again...
        _ = x;              // ... here where its value explicitly discarded
    }

    {
        x := 0;
        h( x );             // ERROR, this is a definite last use of x
    }                       // so x is not referred to again, and its
                            // 'out' value can't be implicitly discarded
}
```

> Cpp2 imbues Cpp1 code with nondiscardable semantics, while staying fully compatible as usual:
>
> - A function written in Cpp2 syntax that returns something other than `#!cpp void` is always compiled to Cpp1 with `[[nodiscard]]`.
>
> - A function call written in Cpp2 `x.f()` member call syntax always treats a non-`#!cpp void` return type as not discardable, even if the function was written in Cpp1 syntax that did not write `[[nodiscard]]`.

For details and rationale, see [Design note: Explicit discard](https://github.com/hsutter/cppfront/wiki/Design-note%3A-Explicit-discard).


### <a id = "function-types"></a> Using function types

The same function parameter/return syntax can be used as a function type, for example to instantiate `std::function` or to declare a pointer to function variable. For example:

``` cpp title="Using function types with std::function and *pfunc" hl_lines="4 7"
decorate_int: (i: i32) -> std::string = "--> (i)$ <--";

main: () = {
    pf1: std::function< (i: i32) -> std::string > = decorate_int&;
    std::cout << "pf1(123) returned \"(pf1(123))$\"\n";

    pf2: * (i: i32) -> std::string = decorate_int&;
    std::cout << "pf2(456) returned \"(pf2(456))$\"\n";
}
//  Prints:
//    pf1 returned "--> 123 <--"
//    pf2 returned "--> 456 <--"
```


## <a id="control flow"></a> Control flow

### <a id="branches"></a> `#!cpp if`, `#!cpp else` — Branches

`if` and `else` are like always in C++, except that `(` `)` parentheses around the condition are not required. Instead, `{` `}` braces around a branch body *are* required. For example:

``` cpp title="Using if and else" hl_lines="1 4"
if vec.ssize() > 100 {
    do_general_algorithm( container );
}
else {
    do_linear_scan( vec );
}
```


### <a id="loops"></a> `#!cpp for`, `#!cpp while`, `#!cpp do` — Loops

**`#!cpp do`** and **`#!cpp while`** are like always in C++, except that `(` `)` parentheses around the condition are not required. Instead, `{` `}` braces around the loop body *are* required.

**`#!cpp for range do (e)`** ***statement*** says "for each element in `range`, call it `e` and perform the statement." The loop parameter `(e)` is an ordinary parameter that can be passed using any [parameter kinds](#parameters); as always, the default is `in`, which is read-only and expresses a read-only loop. The statement is not required to be enclosed in braces.

Every loop can have a `next` clause, that is performed at the end of each loop body execution. This makes it easy to have a counter for any loop, including a range `#!cpp for` loop.

> Note: Whitespace is just a stylistic choice. This documentation's style generally puts each keyword on its own line and lines up what follows.

For example:

``` cpp title="Using loops" hl_lines="4 5 13 16 17 22-24"
words: std::vector<std::string> = ("Adam", "Betty");
i := 0;

while i < words.ssize() // while this condition is true
next  i++               // and increment i after each loop body is run
{                       // do this loop body
    std::cout << "word: (words[i])$\n";
}
//  prints:
//      word: Adam
//      word: Betty

do {                    // do this loop body
    std::cout << "**\n";
}
next  i--               // and decrement i after each loop body is run
while i > 0;            // while this condition is true
//  prints:
//      **
//      **

for  words              // for each element in 'words'
next i++                // and increment i after each loop body is run
do   (inout word)       // declare via 'inout' the loop can change the contents
{                       // do this loop body
    word = "[" + word + "]";
    std::cout << "counter: (i)$, word: (word)$\n";
}
//  prints:
//      counter: 0, word: [Adam]
//      counter: 1, word: [Betty]
```

There is no special "select" or "where" to perform the loop body for only a subset of matches, because this can naturally be expressed with `if`. For example:

``` cpp title="Using loops + if" hl_lines="7"
//  Continuing the previous example
i = 0;

for  words
next i++
do   (word)
if   i % 2 == 1         // if i is odd
{                       // do this loop body
    std::cout << "counter: (i)$, word: (word)$\n";
}
//  prints:
//      counter: 1, word: [Betty]
```

Here is the equivalent of the Cpp1 code `for ( int i = 0; i < 10; ++i ){ std::cout << i; }`:

``` cpp title="Equivalent of Cpp1 'for ( int i = 0; i < 10; ++i ){ std::cout << i; }'"
(copy i := 0)
while i < 10
next  i++ {
    std::cout << i;
}
```

Line by line:

- `(copy i := 0)`: Any statement can have [statement-local parameters](declarations.md#from-functions-to-local-scopes-and-back-again), and this is declaring `i` as an `int` that's local to the loop. Parameters by default are `const`, and for not-cheap-to-copy types they bind to the original value; so because we want to modify `i` we say `copy` to explicitly declare this is the loop's own mutable scratch variable.
- `while i < 10`: The termination condition.
- `next i++`: The end-of-loop-iteration statement. Note `++` is always postfix in Cpp2.


#### Loop names, `#!cpp break`, and `#!cpp continue`

Loops can be named using the usual **name `:`** syntax that introduces all names, and `#!cpp break` and `#!cpp continue` can refer to those names. For example:

``` cpp title="Using named break and continue" hl_lines="1 3 6 10"
outer: while i<M next i++ {      // loop named "outer"
    // ...
    inner: while j<N next j++ {  // loop named "inner"
        // ...
        if something() {
            continue inner;      // continue the inner loop
        }
        // ...
        if something_else() {
            break outer;         // break the outer loop
        }
        // ...
    }
    // ...
}
```


### <a id="catch"></a> `#!cpp throw`, `#!cpp try`, `#!cpp catch` — Exceptions

**`#!cpp throw`**, **`#!cpp try`** and **`#!cpp catch`** are like always in C++, except:

- `#!cpp throw(something)` requires parentheses around the thrown value
- `#!cpp catch` uses Cpp2's usual [parameter syntax](#parameters), so you can write `#!cpp catch(obj: type)` to catch an exception of a specific type, and `#!cpp catch(_)` to catch any thrown exception

For example:

``` cpp title="Throw, try, catch" hl_lines="1 3-5 9-11"
//  This program will print "caught something else"
main: () = {
    try {
        throw( "xyzzy" );
    }
    catch( i: int ) {
        std::cout << "caught int with value " << i;
    }
    catch( _ ) {
        std::cout << "caught something else";
    }
}
```


### <a id="static"></a> `#!cpp static` — Global variables inside functions

**`#!cpp static`** can be specified as the first token of a local variable declaration at function scope, to denote that the variable is a global value initialized thread-safely the first time the line is executed (aka C++ "function local static," aka "magic static").

For example (see also [`@singleton`](metafunctions.md#singleton)):

``` cpp title="static variable (function local scope only)" hl_lines="15"
//  For exposition only - normally, use @singleton for convenience
my_singleton: type = {
    value    : int = 42;

    print    : (this) = std::cout << "(value)$\n";

    //--------------------------------------------------------------------
    //  writing '@singleton type' above would generate these two functions
    //  but this example shows them for exposition of 'static'
    //
    private
    operator=: (out this) = { }
    
    instance : () -> forward my_singleton = { 
        static _instance: my_singleton = ();    // singleton variable
        return _instance; 
    }
    //--------------------------------------------------------------------
}

main: () = {
    my_singleton::instance().print();
}
```


## <a id="definite-last-use"></a> Move/forward from definite last use

In a function body, a **definite last use** of a local name is a single use of that name in a statement that is not in a loop, where no control flow path after that statement mentions the name again.

For each definite last use:

- If the name is a `copy` or `move` parameter or is a local object whose name does not start with `guard`, we know the object will not be used again before being destroyed, and so the object is automatically treated as an rvalue (move candidate). If the expression that contains the last use is able to move from the rvalue, the move will happen automatically.

- If the name is a `forward` parameter, the object is automatically forwarded to preserve its constness and value category (`std::forward`-ed).

> Note: This gives language meaning to a naming convention of `guard` as a name prefix for "guard" stack objects, such as local `std::scoped_lock` objects, whose destructors are always the object's real last use.

For example:

``` cpp title="Definite last uses" linenums="1" hl_lines="13 16 19 21"
f: (
    copy    x: some_type,
    move    y: some_type,
    forward z: some_type
    )
= {
    w: some_type = "y";

    prepare(x);                     // NOT a definite last use

    if something() {
        process(y);
        z.process(x);		        // definite last uses of x and z
    }
    else {
        cout << z;		            // definite last use of z
    }

    transfer(y);                    // definite last use of y

    offload(w);                     // definite last use of w
}
```

In this example:

- `x` has a definite last use on one path, but not another. Line 13 is a definite last use that automatically treats `x` as an rvalue. However, if the `#!cpp else` is taken, `x` gets no special automatic handling. Line 9 is not a definite last use because `x` could be used again where it is mentioned later on line 13.

- `y` has a definite last use on every path, in this case the same on all executions of the function. Line 19 is a definite last use that automatically treats `x` as an rvalue.

- `z` has a definite last use on every path, but unlike `y` it can be a different last use on different executions of the function. That's fine, each of lines 13 and 16 is a definite last use that automatically forwards the constness and value category of `z`.

- `w` has a definite last use on every path, in this case the same on all executions of the function. Line 21 is a definite last use that automatically treats `w` as an rvalue.


## <a id="function-defaults"></a> Generality note: Summary of function defaults

There is a single function syntax, designed so we can just omit the parts we're not currently using.

For example, let's express in full verbose detail that `equals` is a function template that has two type parameters `T` and `U`, two ordinary `in` parameters `a` and `b` of type `T` and `U` respectively, and a deduced return type, and its body returns the result of `a == b`:

``` cpp title="equals: A generic function written in full detail (using no defaults)"
equals: <T: type, U: type> (in a: T, in b: U) -> _ = { return a == b; }
```

We can write all that, but we don't have to.

First, `: type` is the default for template parameters, so we can omit it since that's what we want:

``` cpp title="equals: Identical meaning, now using the :type default for template parameters"
equals: <T, U> (in a: T, in b: U) -> _ = { return a == b; }
```

So far, the return type is already using one common default available throughout Cpp2: the wildcard `_` (pronounced "don't care"). Since this function's body doesn't actually use the parameter type names `T` and `U`, we can just use wildcards for the parameter types too:

``` cpp title="equals: Identical meaning, now using the _ wildcard also for the parameter types"
equals: (in a: _, in b: _) -> _ = { return a == b; }
```

Next, `: _` is also the default parameter type, so we don't need to write even that:

``` cpp title="equals: Identical meaning, now using the :_ default parameter type"
equals: (in a, in b) -> _ = { return a == b; }
```

Next, `in` is the default [parameter kind](#parameters). So we can use that default too:

``` cpp title="equals: Identical meaning, now using the 'in' default parameter kind"
equals: (a, b) -> _ = { return a == b; }
```

We already saw that `{ return` ... `; }` is the default for a single-expression function body that deduces its return type:

``` cpp title="equals: Identical meaning, now using the { return ... } default body decoration"
equals: (a, b) -> _ = a == b;
```

Next, `#!cpp -> forward _` (fully deduced return type) is the default for single-expression functions that return something, and in this case will have the same meaning as `#!cpp -> _` :

``` cpp title="equals: Identical meaning, now using the -> _ = default for functions that return something"
equals: (a, b) = a == b;
```

Finally, at expression scope (aka "lambda/temporary") functions/objects aren't named, and the trailing `;` is optional:

``` cpp title="(not) 'equals': Identical meaning, but without a name as an unnamed function at expression scope"
:(a, b) = a == b
```

Here are some additional examples of unnamed function expressions:

``` cpp title="Some more examples of unnamed function expressions"
std::ranges::for_each( a, :(x) = std::cout << x );

std::ranges::transform( a, std::back_inserter(b), :(x) = x+1 );

where_is = std::ranges::find_if( b, :(x) = x == waldo$ );
```

> Note: Cpp2 doesn't have a separate "lambda" syntax; you just use the regular function syntax at expression scope to write an unnamed function, and the syntactic defaults are chosen to make such function expressions convenient to write. And because in Cpp2 every local variable [capture](expressions.md#captures) (for example, `waldo$` above) is written in the body, it doesn't affect the function syntax.

---

### Cpp2 Metafunctions (`docs/cpp2/metafunctions.md`)

# Metafunctions

## Overview

A metafunction is a compile-time function that can participate in interpreting the meaning of a declaration, and can:

- apply defaults (e.g., `interface` makes functions virtual by default)

- enforce constraints (e.g., `value` enforces that the type has no virtual functions)

- generate additional functions and other code (e.g., `value` generates copy/move/comparison operations for a type if it didn't write them explicitly)

The most important thing about metafunctions is that they are not hardwired language features — they are compile-time library code that uses the reflection and code generation API, that lets the author of an ordinary type easily opt into a named set of defaults, requirements, and generated contents. This approach is essential to making the language simpler, because it lets us avoid hardwiring special "extra" types into the language and compiler.

## <a id="applying-metafunctions"></a> Applying metafunctions using `@`

Metafunctions provide an easy way for a type author to opt into a group of defaults, constraints, and generated functions: Just write `@name` afer the `:` of a declaration, where `name` is the name of the metafunction. This lets the type author declare (and the human reader see) the intent up front: "This isn't just any `type`, this is a `@value type`" which automatically gives the type default/copy/move construction and assignment, `<=>` with `std::strong_ordering` comparisons, and guarantees that it has a public destructor and no protected or virtual functions:

``` cpp title="Using the value metafunction when writing a type" hl_lines="1"
point2d: @value type = {
    x: i32 = 0;
    y: i32 = 0;
    // @value automatically generates default/copy/move
    // construction/assignment and <=> strong_ordering comparison,
    // and emits an error if you try to write a non-public
    // destructor or any protected or virtual function
}
```

## <a id="generating-source"></a>Generating source code at compile time

A metafunction applied to a definition using `@` gets to participate in interpreting the meaning of the definition by inspecting and manipulating the definition's parse tree. For example:

``` cpp title="shape.cpp2: Using @interface @print" hl_lines="1"
shape: @interface @print type = {
    draw   : (this);
    move_by: (this, dx: double, dy: double);
}
```

The above code:

- applies `@interface`, which makes functions pure virtual by default and defines a virtual destructor with a do-nothing body if there isn't already a virtual destructor (among other things), and

- then applies `@print`, which pretty-prints the resulting parse tree as source code to the console so that we can see the results of what the first metafunction did.

The result of compiling this is the following cppfront output, which is the `@interface`-modified Cpp2 source code as printed by `@print`:

``` cpp title="'cppfront shape.cpp2' output to the console, from @print" hl_lines="1"
shape:/* @interface @print */ type =
{
    public draw:(virtual in this);

    public move_by:(
        virtual in this,
        in dx: double,
        in dy: double
    );

    operator=:(virtual move this) =
    {
    }
}
```

Finally, cppfront also emits the following in `shape.cpp`:

``` cpp title="'cppfront shape.cpp' output to 'shape.cpp'"
class shape {
    public: virtual auto draw() const -> void = 0;
    public: virtual auto move_by(cpp2::in<double> dx, cpp2::in<double> dy) const -> void = 0;
    public: virtual ~shape() noexcept;

    public: shape() = default;
    public: shape(shape const&) = delete; /* No 'that' constructor, suppress copy */
    public: auto operator=(shape const&) -> void = delete;

};

shape::~shape() noexcept{}
```


## <a id="built-in-metafunctions"></a>Built-in metafunctions

The following metafunctions are provided in the box with cppfront.


### For regular value-like types (copyable, comparable)


#### <a id="ordered"></a>`ordered`, `weakly_ordered`, `partially_ordered`

An `ordered` (or `weakly_ordered` or `partially_ordered`) type has an `#!cpp operator<=>` three-way comparison operator that returns `std::strong_ordering` (or `std::weak_ordering` or `std::partial_ordering`, respectively). This means objects of this type can be used in all binary comparisons: `<`, `<=`, `==`, `!=`, `>=`, and `>`.

If the user explicitly writes `operator<=>`, its return type must be the same as the one implied by the metafunction they chose.

If the user doesn't explicitly write `operator<=>`, a default memberwise `operator<=>: (this, that) -> /* appropriate _ordering */;` will be generated for the type.

These metafunctions will emit a compile-time error if:

- a user-written `operator<=>` returns a different type than the one implied by the metafunction they chose

> Note: This feature derived from Cpp2 was already adopted into Standard C++ via paper [P0515](https://wg21.link/p0515), so most of the heavy lifting is done by the Cpp1 C++20/23 compiler, including the memberwise default semantics. In contrast, cppfront has to do the work itself for default memberwise semantics for operator= assignment as those aren't yet part of Standard C++.


#### `copyable`

A `copyable` type has (copy and move) x (construction and assignment).

If the user explicitly writes any of the copy/move `operator=` functions, they must also write the most general one that takes `(out this, that)`.

If the user doesn't write any of the copy/move `operator=` functions, a default general memberwise `operator=: (out this, that) = { }` will be generated for the type.

`copyable` will emit a compile-time error if:

- there is a user-written `operator=` but no user-written `operator=: (out this, that)`


#### <a id="value"></a>`basic_value`, `value`, `weakly_ordered_value`, `partially_ordered_value`

A `basic_value` type is a regular type: [`copyable`](#copyable), default constructible, and not polymorphic (no protected or virtual functions).

A `value` (or `weakly_ordered_value` or `partially_ordered_value`) is a `basic_value` that is also [`ordered`](#ordered) (or `weakly_ordered` or `partially_ordered`, respectively).

```mermaid
graph TD;
    value---->basic_value;
    weakly_ordered_value---->basic_value;
    partially_ordered_value---->basic_value;
    basic_value-->copyable;
    value-->ordered;
    partially_ordered_value-->partially_ordered;
    weakly_ordered_value-->weakly_ordered;
```

These metafunctions will emit a compile-time error if:

- any function is protected or virtual

- the type has a destructor that is not public


#### `struct`

A `struct` is a type with only public bases, objects, and functions, with no virtual functions, and with no user-defined constructors (i.e., no invariants) or assignment or destructors.

`struct` is implemented in terms of [`cpp1_rule_of_zero`](#cpp1_rule_of_zero).

`struct` will emit a compile-time error if:

- any member is non-public

- any function is virtual

- there is a user-written `operator=`


#### `hashable`

A `hashable` type provides a `hash: (this) -> size_t` function that performs a memberwise hash of its data members using `std::hash`.


### For polymorphic types (interfaces, base classes)


#### `interface`

An `interface` type is an abstract base class having only pure virtual functions.

Cpp2 has no `interface` feature hardwired into the language, as C# and Java do. Instead you apply the `@interface` metafunction when writing an ordinary `type`. For a detailed example, see [the `shape` example above](#generating-source-code-at-compile-time).

`interface` will emit a compile-time error if:

- the type contains a data object

- the type has a copy or move function (the diagnostic message will suggest a virtual `clone` function instead)

- any function has a body

- any function is nonpublic


#### `polymorphic_base`

A `polymorphic_base` type is a pure polymorphic base type that is not copyable, and whose destructor is either public and virtual or protected and nonvirtual.

Unlike an [interface](#interface), it can have nonpublic and nonvirtual functions.

`polymorphic_base` will emit a compile-time error if:

- the type has a copy or move function (the diagnostic message will suggest a virtual `clone` function instead)

- the type has a destructor that is not public and virtual, and also not protected and nonvirtual


### For enumeration types


#### `enum`

Cpp2 has no `enum` feature hardwired into the language. Instead you apply the `@enum` metafunction when writing an ordinary `type`.

`enum` will emit a compile-time error if:

- any member has the reserved name `operator=` or `operator<=>`, as these will be generated by the metafunction

- an enumerator is not public or does not have a deduced type

For example:

``` cpp title="Using the @enum metafunction when writing a type" hl_lines="14"
// skat_game is declaratively a safe enumeration type: it has
// default/copy/move construction/assignment and <=> with
// std::strong_ordering, a minimal-size signed underlying type
// by default if the user didn't specify a type, no implicit
// conversion to/from the underlying type, in fact no public
// construction except copy construction so that it can never
// have a value different from its listed enumerators, inline
// constexpr enumerators with values that automatically start
// at 1 and increment by 1 if the user didn't write their own
// value, and conveniences like to_string()... the word "enum"
// carries all that meaning as a convenient and readable
// opt-in, without hardwiring "enum" specially into the language
//
skat_game: @enum<i16> type = {
    diamonds := 9;
    hearts;  // 10
    spades;  // 11
    clubs;   // 12
    grand    := 20;
    null     := 23;
}
```

Consider `hearts`: It's a member object declaration, but it doesn't have a type (or a default value) which is normally illegal, but here it's okay because the `@enum<i16>` metafunction fills them in: It iterates over all the data members and gives each one the underlying type (here explicitly specified as `i16`, otherwise it would be computed as the smallest signed type that's big enough), and an initializer (by default one higher than the previous enumerator).

Unlike C `#!cpp enum`, this `@enum` is scoped and strongly typed (does not implicitly convert to the underlying type).

Unlike C++11 `#!cpp enum class`, it's "just a `type`" which means it can naturally also have member functions and other things that a type can have:

``` cpp title="An @enum type with a member function" hl_lines="1"
janus: @enum type = {
    past;
    future;

    flip: (inout this) == {
        if this == past { this = future; }
        else { this = past; }
    }
}
```


#### `flag_enum`

`flag_enum` is a variation on `enum` that has power-of-two default enumerator values, a default signed underlying type that is large enough to hold the values, and supports bitwise operators to combine and test values.

`flag_enum` will emit a compile-time error if:

- any member has the reserved name `operator=`, `operator<=>`, `has`, `set`, `clear`, `to_string`, `get_raw_value`, or `none`, as these will be generated by the metafunction

- an enumerator is not public or does not have a deduced type

- the values are outside the range that can be represented by the largest default underlying type

For example:

``` cpp title="Using the @flag_enum metafunction when writing a type" hl_lines="11"
// file_attributes is declaratively a safe flag enum type:
// same as enum, but with a minimal-size unsigned underlying
// type by default, and values that automatically start at 1
// and rise by powers of two if the user didn't write their
// own value, and bitwise operations plus .has(flags),
// .set(flags), and .clear(flags)... the word "flag_enum"
// carries all that meaning as a convenient and readable
// opt-in without hardwiring "[Flags]" specially into the
// language
//
file_attributes: @flag_enum<u8> type = {
    cached;     // 1
    current;    // 2
    obsolete;   // 4
    cached_and_current := cached | current;
}
```


### For dynamic types


#### `union`

`@union` declaratively opts into writing a safe discriminated union/variant dynamic type.

`union` will emit a compile-time error if:

- any alternative is not public or has an initializer

- any member starts with the reserved name prefix `is_` or `set_`, as these will be generated by the metafunction


For example:

``` cpp title="Using the @union metafunction when writing a type" hl_lines="10 18-20 25 26"
// name_or_number is declaratively a safe union/variant type:
// it has a discriminant that enforces only one alternative
// can be active at a time, members always have a name, and
// each member has .is_member(), .set_member(), and .member()
// accessors using the member name... the word "union"
// carries all that meaning as a convenient and readable
// opt-in without hardwiring "union" specially into the
// language
//
name_or_number: @union type = {
    name: std::string;
    num : i32;
}

main: () = {
    x: name_or_number = ();

    x.set_name("xyzzy");            // now x is a string
    assert( x.is_name() );
    std::cout << x.name();          // prints the string

    // trying to use x.num() here would cause a Type safety
    // contract violation, because x is currently a string

    x.set_num( 120 );               // now x is a number
    std::cout << x.num() + 3;       // prints 123
}
```

Unlike C `#!cpp union`, this `@union` is safe to use because it always ensures only the active type is accessed.

Unlike C++11 `std::variant`, this `@union` is easier to use because its alternatives are anonymous, and safer to use because each union type is a distinct type. [^variant]

Each `@union` type has its own type-safe name, has clear and unambiguous named members, and safely encapsulates a discriminator to rule them all. It uses type-unsafe casts in the implementation, but they are fully encapsulated, where they can be tested once and be safe in all uses.

Because a `@union type` is still a `type`, it can naturally have other things normal types can have, such as template parameter lists and member functions:

``` cpp title="A templated custom safe union type" hl_lines="1"
name_or_other: @union <T:type> type
= {
    name  : std::string;
    other : T;

    // a custom member function
    to_string: (this) -> std::string = {
        if is_name()       { return name(); }
        else if is_other() { return other() as std::string; }
        else               { return "invalid value"; }
    }
}

main: () = {
    x: name_or_other<int> = ();
    x.set_other(42);
    std::cout << x.other() * 3.14 << "\n";
    std::cout << x.to_string(); // prints "42" here, but is legal
                                // whichever alternative is active
}
```


### For other common types

#### `encapsulated`

An `encapsulated` type is one that has no public data members.


#### `noncopyable`

A `noncopyable` type is one that has no user-defined copy or move functions (`operator=` with `this` and `that` parameters).


#### <a id="singleton"></a> `singleton`

A `singleton` type is one that has only one global object (instance) in the whole program. The single object is initialized lazily the first time it is accessed. A singleton type has no constructors other than a generated default constructor (note: therefore all data members must have default values), and provides a generated `instance()` function to create and give access to the global instance.

For example:

``` cpp title="A templated custom safe union type" hl_lines="1 7"
my_singleton: @singleton type = {
    value: int = 42;
    print: (this) = std::cout << "(value)$\n";
}

main: () = {
    my_singleton::instance().print();
}
```


### For computational and functional types

#### `autodiff`

An `autodiff` type is extended so that derivatives can be computed. The metafunction adds for each function and member function a differentiated version. **This is a proof of concept implementation. Expect it to break.**
A simple hello diff example is:

``` cpp
ad: @autodiff type = {
    func: (x: double) -> (r: double) = {
        r = x * x;
    }
}

main: (args) = {
    x := 3.0;
    x_d := 1.0;

    r := ad::func_d(x, x_d);

    std::cout << "Derivative of 'x*x' at (x)$ is (r.r_d)$" << std::endl;
}
```

The `@autodiff` metafunction mostly supports the forward mode of algorithmic differentiation. The reverse mode is only partly implemented and not yet well tested.
See [Supported autodiff features](../notes/autodiff_status.md) for a list of supported language features.

Options can be given by text template arguments, e.g. `@autodiff<"reverse">` enables the reverse mode.
| Option | Description |
| `"reverse"` | Reverse mode algorithmic differentiation. Default suffix `_b`. |
| `"order=<n>"` | Higher order derivatives. `<n>` can be arbitrary. See `regression-tests/pure2-autodiff-higher-order.cpp2` for examples. |
| `"suffix=<s>"` | Change the forward mode suffix. Can be used to apply autodiff multiple times. E.g. `@autodiff @autodiff<"suffix=_d2">`. |
| `"rws_suffix=<s>"` | Change the reverse mode suffix. |

#### `regex`

A `regex` type has data members that are regular expression objects. This metafunction replaces all of the type's data members named `regex` or `regex_*` with regular expression objects of the same type. For example:

``` cpp title="Regular expression example"  hl_lines="1 3 4 16 17 19 27 30 31"
name_matcher: @regex type
= {
    regex         := R"((\w+) (\w+))";  // for example: Margaret Hamilton
    regex_no_case := R"(/(ab)+/i)";     // case insensitive match of "ab"+
}

main: (args) = {
    m: name_matcher = ();

    data: std::string = "Donald Duck";
    if args.ssize() >= 2 {
        data = args[1];
    }

    //  regex.match requires matches to match the entire string, from start to end
    result := m.regex.match(data);
    if result.matched {
        //  We found a match; reverse the order of the substrings
        std::cout << "Hello (result.group(2))$, (result.group(1))$!\n";
    }
    else {
        std::cout << "I only know names of the form: <name> <family name>.\n";
    }

    //  regex.search finds a match anywhere within the target string
    std::cout << "Case insensitive match: "
                 "(m.regex_no_case.search(\"blubabABblah\").group(0))$\n";
}
//  Prints:
//      Hello Duck, Donald!
//      Case insensitive match: abAB
```

The `@regex` metafunction currently supports most of [Perl regex syntax](https://perldoc.perl.org/perlre), except for Unicode characters and the syntax tokens associated with them. See [Supported regular expression features](../notes/regex_status.md) for a list of regex options.

Each regex object has the type `cpp2::regex::regular_expression`, which is defined in `include/cpp2regex.h2`. The member functions are:

``` cpp title="Member functions for regular expressions"
//  .match() requires matches to match the entire string, from start to end
//  .search() finds a match anywhere within the target string

match :        (this, str: std::string_view)                -> search_return;
search:        (this, str: std::string_view)                -> search_return;

match :        (this, str: std::string_view, start)         -> search_return;
search:        (this, str: std::string_view, start)         -> search_return;

match :        (this, str: std::string_view, start, length) -> search_return;
search:        (this, str: std::string_view, start, length) -> search_return;

match : <Iter> (this, start: Iter, end: Iter)               -> search_return;
search: <Iter> (this, start: Iter, end: Iter)               -> search_return;
```

The return type `search_return` is defined in `cpp2::regex::regular_expression`. It has these members:

``` cpp title="Members of a regular expression result"
matched: bool;
pos:     int;

//  Functions to access groups by number
group_number: (this) -> size_t;;
group:        (this, g: int) -> std::string;
group_start:  (this, g: int) -> int;
group_end:    (this, g: int) -> int;

//  Functions to access groups by name
group:        (this, g: bstring<CharT>) -> std::string;
group_start:  (this, g: bstring<CharT>) -> int;
group_end:    (this, g: bstring<CharT>) -> int;
```



### Helpers and utilities


#### `cpp1_rule_of_zero`

A `cpp1_rule_of_zero` type is one that has no user-written copy/move/destructor functions, and for which Cpp2 should generate nothing so that the Cpp1 defaults for generated special member functions are accepted.

> C.20: If you can avoid defining default operations, do.
> Reason: It's the simplest and gives the cleanest semantics.
> This is known as "the rule of zero".
> — Stroustrup, Sutter, et al. (C++ Core Guidelines)


#### `print`

`print` prints a pretty-printed visualization of the type to the console.

This is most useful for debugging metafunctions, and otherwise seeing the results of applying previous metafunctions.

For a detailed example, see [the `shape` example above](#generating-source-code-at-compile-time).


[^variant]: With `variant`, there's no way to distinguish in the type system between a `variant<int,string>` that stores either an employee id or employee name, and a `variant<int,string>` that stores either a lucky number or a pet unicorn's dominant color.

---

### Cpp2 Namespaces (`docs/cpp2/namespaces.md`)

# Namespaces

## Overview

A namespace `N` can contain declarations that are then accessed by writing `N::` or [`using`](#using) the namespace or declaration. For example:

``` cpp title="Declaring some things in a namespace" hl_lines="2 8"
//  A namespace to put all the names provided by a widget library
widgetlib: namespace = {
    widget: type = { /*...*/ }
    // ... more things ...
}

main: () = {
    w: widgetlib::widget = /*...*/;
}
```


## <a id="using"></a> `using`

A `#!cpp using` statement brings names declared in another namespace into the current scope as if they had been declared in the current scope.

`#!cpp using a_namespace::a_name ;` brings the single name `a_name` into scope.

`#!cpp using a_namespace::_ ;` brings all the namespace's names into scope using the `#!cpp _` wildcard.

For example:

``` cpp title="using statements" hl_lines="13 14 20 21"
//  A namespace to put all the names provided by a widget library
widgetlib: namespace = {
    widget: type = { /*...*/ }
    // ... more things ...
}

main: () = {
    //  Explicit name qualification
    w: widgetlib::widget = /*...*/;

    {
        //  Using the specific name, no widgetlib:: qualification needed
        using widgetlib::widget;
        w2: widget = /*...*/;
        // ...
    }

    {
        //  Using the whole namespace, no widgetlib:: qualification needed
        using widgetlib::_;
        w3: widget = /*...*/;
        // ...
    }

    // ...
}
```

---

### Cpp2 Objects (`docs/cpp2/objects.md`)

## Overview

An object can be declared at any scope: in a namespace, in a `type`, in a function, in an expression.

Its declaration is written using the same **name `:` kind `=` value** [declaration syntax](../cpp2/declarations.md) as everything in Cpp2:

- **name** starts with a letter and is followed by other letters, digits, or `_`. Examples: `count`, `skat_game`, `Point2D` are valid names.

- **kind** is the object's type. In most places, except type scopes, you can write the `_` wildcard as the type (or omit the type entirely) to ask for the type to be deduced. When the type is a template, the templated arguments can be inferred from the constructor (via [CTAD](../welcome/hello-world.md#ctad)).

- **value** is the object's initial value. To use the default-constructed value, write `()`.


For example:

``` cpp title="Declaring some objects" hl_lines="3 4 7-9 12 13"
//  numbers is an object of type std::vector<int>,
//  defined as having the initial contents 1, 2, 3
numbers: std::vector<int> = (1, 2, 3);
numbers: std::vector = (1, 2, 3);       // same, deducing the vector's type

//  count is an object of type int, defined as having initial value -1
count: int = -1;
count: _ = -1;      // same, deducing the object's type with the _ wildcard
count := -1;        // same, deducing the object's type by just omitting it

//  pi is a variable template; == signifies the value never changes (constexpr)
pi: <T: type> T == 3.14159'26535'89793'23846L;
pi: _ == 3.14159'26535'89793'23846L;    // same, deducing the object's type
```

The object type can be deduced by writing `_` (the default, so it can be omitted). You can use `is` to declare a type constraint (e.g., a concept) that a deduced type must match, in which case `_` is required. For example:

``` cpp title="Declaring an object of constrained deduced type" hl_lines="2"
//  number's type is deduced, but must match the std::regular concept
number: _ is std::regular = some_factory_function();
```


## <a id="init"></a> Guaranteed initialization

Every object must be initialized using `=` before it is used.

An object in any scope can be initialized at its declaration. For example:

``` cpp title="Initializing objects when they are declared" hl_lines="4 10"
shape: type = {
    //  An object at type scope (data member)
    //  initialized with its type's default value
    points: std::vector<point2d> = ();

    draw: (this, where: canvas) -> bool
    = {
        //  An object at function scope (local variable)
        //  initialized with color::red
        pen := color::red;

        // ...
    }

    //  ...
}
```

Additionally, at function local scope an object `obj` can be initialized separately from its declaration. This can be useful when the object must be declared before a program-meaningful initial value is known (to avoid a dead write of a wrong 'dummy' value), and/or when the object may be initialized in more than one way depending on other logic (e.g., by using different constructors on different paths). The way to do this is:

- Declare `obj` without an `= initializer` value, for example: `obj: some_type;`. This allocates stack space for the object, but does not construct it.

- `obj` must have a definite first use on every `#!cpp if`/`#!cpp else` branch path (and that first use must not be inside any loop), and

- that definite first use must be of the form `obj = value;` which is a constructor call, or else pass `obj` as an `out` argument to an `out` parameter (which is also effectively a constructor call, and performs the construction in the callee).

For example:

``` cpp title="Initializing local objects after they are declared" hl_lines="5 14 17 21"
f: () = {
    buf: std::array<std::byte, 1024>;   // uninitialized
    //  ... calculate some things ...
    //  ...  no uses of buf here  ...
    buf = some_calculated_value;        // constructs (not assigns) buf
    //  ...
    std::cout << buf[0];                // ok, a has been initialized
}

g: () = {
    buf: std::array<std::byte, 1024>;   // uninitialized
    if flip_coin_is_heads() {
        if heads_default_is_available {
            buf = copy_heads_default(); // constructs buf
        }
        else {
            buf = (other, constructor); // constructs buf
        }
    }
    else {
        load_from_disk( out buf );      // constructs buf (*)
    }
    std::cout << buf[0];                // ok, a has been initialized
}

load_from_disk: (out x) = {
    x = /* data read from disk */ ;     // when `buffer` is uninitialized,
}                                       // constructs it; otherwise, assigns
```

In the above example, note the simple rule for branches: The local variable must be initialized on both the `#!cpp if` and `#!cpp else` branches, or neither branch.


## <a id="heap"></a>Heap objects

Objects can also be allocated on the heap using `#!cpp xxx.new <T> (/*initializer, arguments*/)` where `xxx` is any object that acts as a memory allocator and provides a `#!cpp .new` function template. Two memory allocators objects are provided in namespace `cpp2`:

- `#!cpp unique.new<T>` calls `std::make_unique<T>` and returns a `std::unique_ptr<T>`.

- `#!cpp shared.new<T>` calls `std::make_shared<T>` and returns a `std::shared_ptr<T>`.

The default is `#!cpp unique.new` if you don't specify an allocator object.

For example (see [types](types.md) for more details about writing types):

``` cpp title="Heap allocation" hl_lines="3-6 10-11"
f: () -> std::shared_ptr<widget>
= {
    //  Dynamically allocate an object owned by a std::unique_ptr
    //  'vec' is a unique_ptr<vector<i32>> containing three values
    vec := new<std::vector<i32>>(1, 2, 3);
            // shorthand for 'unique.new<...>(...)'
    std::cout << vec*.ssize();  // prints 3
                    // note that * dereference is a suffix operator

    //  Dynamically allocate an object with shared ownership
    wid := cpp2::shared.new<widget>();
    store_a_copy( wid );        // store a copy of 'wid' somewhere
    return wid;                 // and move-return a copy too

} // as always in C++, vec is destroyed here automatically, which
  // destroys the heap vector and deallocates its dynamic memory
```

---

### Cpp2 Safety (`docs/cpp2/safety.md`)

# Safety and unchecked code

Cpp2 aims to be safe by default, usually entirely at compile time, and when needed at run time.

When Cpp2 rejects unsafe code (e.g., signed/unsigned comparison) or ensuring safety can require run-time checks (e.g., subscripts bounds checks), you can opt out as needed in two ways:

- at a specific place in your code, using `unchecked_*` functions (these are in namespace `cpp2::`, but can be used unqualified from Cpp2 code)
- for a whole source file, using `-no-*-checks` switches

Nearly always, you should opt out at a specific place in your code where you are confident the result is okay, and if there is a run-time check you have measured that the performance difference matters such as in a hot loop.


### <a id="mixed-sign-comparison"></a> Integer mixed-sign `<`, `<=`, `>`, and `>=` (compile-time enforced)

Comparing signed and unsigned integer values directly using `<`, `<=`, `>`, or `>=` can give wrong results, and so such comparisons are rejected at compile time.

To disable this check at a specific place in your code, use the appropriate `unchecked_cmp_*` function instead of the operator notation: `unchecked_cmp_less`, `unchecked_cmp_less_eq`,`unchecked_cmp_greater`, or `unchecked_cmp_greater_eq`.

For example:

``` cpp title="Integer comparisons" hl_lines="7"
main: () = {
    x: i32 = 42;
    y: u32 = 43;

    if x < y { }                            // unsafe, therefore error by default

    if unchecked_cmp_less(x,y) { }          // ok, explicit "trust me" opt-out
}
```

To disable these checks for the entire source file, you can use cppfront's `-no-comparison-checks` switch:

``` bash title="Disable prevention of mixed-sign integer comparisons" hl_lines="3"
cppfront myfile.cpp2                        # mixed-sign int comparisons banned

cppfront myfile.cpp2 -no-comparison-checks  # mixed-sign int comparisons allowed
```


### <a id="division-by-zero"></a> Division by zero (run-time checked)

Dividing integers by zero is undefined behavior, and is rejected at run time by checking the denominator is nonzero.

To disable this check at a specific place in your code, use `unchecked_div`. For example:

``` cpp title="Division by zero" hl_lines="7"
main: () = {
    x := 42;
    y := 0;

    z := x/y;                               // unsafe, therefore run-time checked

    w := unchecked_div(x,y)                 // ok, explicit "trust me" opt-out
}
```

To disable these checks for the entire source file, you can use cppfront's `-no-div-zero-checks` switch:

``` bash title="Disable prevention of division by zero" hl_lines="3"
cppfront myfile.cpp2                        # division by zero checked

cppfront myfile.cpp2 -no-div-zero-checks    # division by zero not checked
```


### <a id="null-dereference"></a> Null dereference (run-time checked)

Dereferencing a null pointer is undefined behavior, and is rejected at run time by checking the pointer is not null.

To disable this check at a specific place in your code, use `unchecked_dereference`. For example:

``` cpp title="Null dereference" hl_lines="6"
main: () = {
    p: *int = cpp1_func();                  // could be initialized to null

    p* = 42;                                // unsafe, therefore run-time checked

    unchecked_dereference(p) = 42;          // ok, explicit "trust me" opt-out
}
```

To disable these checks for the entire source file, you can use cppfront's `-no-null-checks` switch:

``` bash title="Disable prevention of null deference" hl_lines="3"
cppfront myfile.cpp2                        # null dereferences checked

cppfront myfile.cpp2 -no-null-checks        # null dereferences not checked
```


### <a id="subscript-bounds"></a> Subscript bounds (run-time checked)

Accessing an out of bounds subscript is undefined behavior, and is rejected at run time by checking the subscript is in bounds. For an expression `a[b]` where

- `a` is contiguous and supports `std::size(a)`, and
- `b` is an integral value

the cppfront compiler injects a check that **`0 <= b < std::size(a)`** before the call to `a[b]`.

To disable this check at a specific place in your code, use `unchecked_subscript`. For example:

``` cpp title="Subscript bounds" hl_lines="12 13"
main: () = {
    v: std::vector = ( 1, 2, 3, 4, 5 );
    s: std::span   = v;

    idx := calc_index(s);

    v[idx] += 42;                           // unsafe, therefore run-time checked
    s[idx] += 84;                           // unsafe, therefore run-time checked

    // manually hoist the check and do it myself
    if (0 ..< v.size()).contains(idx) {
        unchecked_subscript(v,idx) += 42;   // ok, explicit "trust me" opt-out
        unchecked_subscript(s,idx) += 84;   // ok, explicit "trust me" opt-out
    }
}
```

To disable these checks for the entire source file, you can use cppfront's `-no-subscript-checks` switch:

``` bash title="Disable prevention of out-of-bounds subscripts" hl_lines="3"
cppfront myfile.cpp2                        # subscript bounds checked

cppfront myfile.cpp2 -no-subscript-checks   # subscript bounds not checked
```

---

### Cpp2 Types (`docs/cpp2/types.md`)

# Types

## Overview

A user-defined `type` is written using the same **name `:` kind `=` value** [declaration syntax](../cpp2/declarations.md) as everything in Cpp2. The type's "value" is a `{}`-enclosed body containing more declarations.

In a `type`, data members are private by default, and functions and nested types are public by default. To explicitly declare a type scope declaration `#!cpp public`, `#!cpp protected`, or `#!cpp private`, write that keyword at the beginning of the declaration.

``` cpp title="Writing a simple type" hl_lines="1"
mytype: type =
{
    // data members are private by default
    x: std::string;

    // functions are public by default
    protected f: (this) = { do_something_with(x); }

    // ...
}
```

## <a id="this-parameter"></a> `#!cpp this` — The parameter name

**`#!cpp this`** is a synonym for the current object. Inside the scope of a type that has a member named `member`, `member` by default means `#!cpp this.member`.

> Note: In Cpp2, `#!cpp this` is not a pointer.

The name `#!cpp this` may only be used for the first parameter of a type-scope function (aka member function). It is never declared with an explicit `: its_type` because its type is always the current type.

`#!cpp this` can be an `in` (default), `inout`, `out`, or `move` parameter. Which you choose naturally determines what kind of member function is being declared:

- **`#!cpp in this`**: Writing `#!cpp myfunc: (this /*...*/)`, which is shorthand for `#!cpp myfunc: (in this /*...*/)`, defines a Cpp1 `#!cpp const`-qualified member function, because  `in` parameters are `#!cpp const`.

- **`#!cpp inout this`**: Writing `#!cpp myfunc: (inout this /*...*/)` defines a Cpp1 non-`#!cpp const` member function.

- **`#!cpp out this`**: Writing `#!cpp myfunc: (out this /*...*/)` defines a Cpp1 constructor... and more. (See below.)

- **`#!cpp move this`**: Writing `#!cpp myfunc: (move this /*...*/)` defines a Cpp1 `#!cpp &&`-qualified member function, or if there are no additional parameters it defines the destructor.

For example, here is how to write read-only member function named `print` that takes a read-only string value and prints this object's data value and the string message:

``` cpp title="The this parameter" hl_lines="4 6"
mytype: type = {
    data: i32;   // some data member (private by default)

    print: (this, msg: std::string) = {
        std::cout << data << msg;
                 // "data" is shorthand for "this.data"
    }

    // ...
}
```

## <a id="this-inheritance"></a> `#!cpp this` — Inheritance

Base types are written as members named `#!cpp this`. For example, just as a type could write a data member as `#!cpp data: string = "xyzzy";`, which is pronounced "`data` is a `string` defined as having the default value `#!cpp "xyzzy"`, a base type is written as `#!cpp this: Shape = (default, values);`, which is pronounced "`#!cpp this` is a `Shape` defined as having these default values."

> Cpp2 syntax has no separate base list or separate member initializer list.

Because base and member subobjects are all declared in the same place (the type body) and initialized in the same place (an `#!cpp operator=` function body), they can be written in any order, including interleaved, and are still guaranteed to be safely initialized in declared order. This means that in Cpp2 you can declare a data member object before a base subobject, so that it naturally outlives the base subobject.

> Cpp2 code doesn't need workarounds like Boost's `base_from_member`, because all of the motivating examples for that can be written directly. See [this explanation](https://github.com/hsutter/cppfront/issues/334#issuecomment-1500984173) for details.

## <a id="virtual-functions"></a> `#!cpp virtual`, `#!cpp override`, and `#!cpp final` — Virtual functions

A `#!cpp this` parameter can additionally be declared as one of the following:

- **`#!cpp virtual`**: Writing `#!cpp myfunc: (virtual this /*...*/)` defines a new virtual function.

- **`#!cpp override`**: Writing `#!cpp myfunc: (override this /*...*/)` defines an override of an existing base class virtual function.

- **`#!cpp final`**: Writing `#!cpp myfunc: (final this /*...*/)` defines a final override of an existing base class virtual function.

A pure virtual function is a function with a `#!cpp virtual this` or `#!cpp override this` parameter and no body.

For example:

``` cpp title="Virtual functions" hl_lines="3 4 14 15"
abstract_base: type
= {
    //  A pure virtual function: virtual + no body
    print: (virtual this, msg: std::string);

    // ...
}

derived: type
= {
    //  'this' is-an 'abstract_base'
    this: abstract_base;

    //  Explicit override
    print: (override this, msg: std::string) = { /*...*/ }

    // ...
}
```


## <a id="implicit"></a> `implicit` — Controlling conversion functions

A `#!cpp this` parameter of an `#!cpp operator=` function can additionally be declared as:

- **`implicit`**: Writing `#!cpp operator=: (implicit out this, /*...*/)` defines a function that will not be marked as "explicit" when lowered to Cpp1 syntax.

> Note: This reverses the Cpp1 default, where constructors are not "explicit" by default, and you have to write "explicit" to make them explicit.


## <a id="operator-equals"></a> `#!cpp operator=` — Construction, assignment, and destruction

All value operations are spelled `#!cpp operator=`, including construction, assignment, and destruction. `#!cpp operator=` sets the value of `#!cpp this` object, so the `#!cpp this` parameter can be passed as anything but `in` (which would imply `#!cpp const`):

- **`#!cpp out this`:** Writing `#!cpp operator=: (out this /*...*/ )` is naturally both a constructor and an assignment operator, because an `out` parameter can take an uninitialized or initialized argument. If you don't also write a more-specialized `#!cpp inout this` assignment operator, Cpp2 will use the `#!cpp out this` function also for assignment.

- **`#!cpp inout this`:** Writing `#!cpp operator=: (inout this /*...*/ )` is an assignment operator (only), because an `inout` parameter requires an initialized modifiable argument.

- **`#!cpp move this`:** Writing `#!cpp operator=: (move this)` is the destructor. No other parameters are allowed, so it connotes "move `#!cpp this` nowhere."

Unifying `#!cpp operator=` enables usable `out` parameters, which is essential for composable guaranteed initialization. We want the expression syntax `#!cpp x = value` to be able to call a constructor or an assignment operator, so naming them both `#!cpp operator=` is consistent.

An assignment operator always returns the same type as `#!cpp this` and automatically performs `#!cpp return this;`.

> Note: Writing `=` always invokes an `#!cpp operator=` (in fact for a Cpp2-authored type, and semantically for a Cpp1-authored type). This avoids the Cpp1 inconsistency that "writing `=` calls `#!cpp operator=`, except when it doesn't" (such as in a Cpp1 variable initialization). Conversely, `#!cpp operator=` is always invoked by `=` in Cpp2.


### <a id="that-parameter"></a> `that` — A source parameter

All type-scope functions can have **`that`** as their second parameter, which is a synonym for the object to be copied/moved from. Like `this`, at type scope it is never declared with an explicit `: its_type` because its type is always the current type.

`that` can be an `in` (default) or `move` parameter. Which you choose naturally determines what kind of member function is being declared:

- **`in that`**: Writing `#!cpp myfunc: (/*...*/ this, that)`, which is shorthand for `#!cpp myfunc: (/*...*/ this, in that)`, is naturally both a copy and move function, because it can accept an lvalue or an rvalue `that` argument. If you don't write a more-specialized `move that` move function, Cpp2 will automatically use the `in that` function also for move.

- **`move that`**: Writing `#!cpp myfunc: (/*...*/ this, move that)` defines a move function.

Putting `this` and `that` together: The most general form of `#!cpp operator=` is **`#!cpp operator=: (out this, that)`**. It works as a unified general {copy, move} x { constructor, assignment } operator, and generates all of four of those in the lowered Cpp1 code if you didn't write a more specific one yourself.


### <a id="generated-operator-equals"></a> `#!cpp operator=` can generalize (A)ssignment from construction, and (M)ove from copy

As mentioned above:
- If you don't write an `#!cpp inout this` function, Cpp2 will use your `#!cpp out this` function in its place (if you wrote one).
- If you don't write a `move that` function, Cpp2 will use your `in that` function in its place (if you wrote one).

> Note: When lowering to Cpp1, this just means generating the applicable special member functions from the appropriate Cpp2 function.

This graphic summarizes these generalizations. For convenience I've numbered the (A)ssignment and (M)ove defaults.



In Cpp1 terms, they can be described as follows:

- **(M)ove, M1, M2:** If you write a copy constructor or assignment operator, but not a corresponding move constructor or assignment operator, the latter is generated.

- **(A)ssignment, A1, A3:** If you write a generalized constructor, but none of the three more-specific copy/move constructor/assignment functions, the latter three get generated. If you write a converting copy constructor, but no converting assignment operator for the same type and this is not a polymorphic type, the latter is generated.

- **The arrows are transitive.** For example, if you write a copy constructor and nothing else, the move constructor, copy assignment operator, and move assignment operator are generated.

The most general `#!cpp operator=` with `that` is `#!cpp (out this, that)`. In Cpp1 terms, it generates all four combinations of { copy, move } x { constructor, assignment }. This is often sufficient, so you can write all these value-setting functions just once. If you do want to write a more specific version that does something else, though, you can always write it too.

> Note: Generating `#!cpp inout this` (assignment) from `#!cpp out this` also generates **converting assignment** from converting construction, which is a new thing. Today in Cpp1, if you write a converting constructor from another type `X`, you may or may not write the corresponding assignment from `X`; in Cpp2 you will get that by default, and it sets the object to the same state as the converting constructor from `X` does.



### <a id="generated-defaults"></a> Minimal functions generated by default

There are only two defaults the language will generate implicitly for a type:

- The only special function every type must have is the destructor. If you don't write it by hand, a public nonvirtual destructor is generated by default.

- If no `#!cpp operator=` functions other than the destructor are written by hand, a public default constructor is generated by default.

All other `#!cpp operator=` functions are explicitly written, either by hand or by opting into applying a metafunction (see below).

> Note: Because generated functions are always opt-in, you can never get a generated function that's wrong for your type, and so Cpp2 doesn’t need to support "=delete" for the purpose of suppressing unwanted generated functions.

### <a id="memberwise-default"></a> Memberwise by default

All copy/move/conversion `#!cpp operator=` functions are memberwise by default in Cpp2. That includes when you write memberwise construction and assignment yourself.

In a hand-written `#!cpp operator=`:

- The body must begin with a series of `member = value;` statements, one for each of the type's data members (including base classes) in declaration order.

- If the body does not mention a member in the appropriate place in the beginning section, by default the member's default initializer is used.

- In an assignment operator (`#!cpp inout this`), you can explicitly skip setting a member by writing `member = _;` where it would normally be set if you know you have a reason to set its value later instead or if the existing value needs to be preserved. (This is rare; for an example, see the generated implementation of the [`union` metafunction](metafunctions.md#union).)

For example:

``` cpp title="Memberwise operator= semantics" hl_lines="9-11 20-22"
mytype: type
= {
    //  data members (private by default)
    name:          std::string;
    social_handle: std::string = "(unknown)";

    //  conversion from string (construction + assignment)
    operator=: (out this, who: std::string) = {
        name = who;
        //  if social_handle is not mentioned, defaults to:
        //      social_handle = "(unknown)";

        //  now that the members have been set,
        //  any other code can follow...
        print();
    }

    //  copy/move constructor/assignment
    operator=: (out this, that) = {
        //  if neither data member is mentioned, defaults to:
        //      name = that.name;
        //      social_handle = that.social_handle;
        print();
    }

    print: (this) = { std::cout << "value is [(name)$] [(social_handle)$]\n"; }
}

//  The above definition of mytype allows all of the following...
main: () = {
    x: mytype = "Jim"; // construct from string
    x = "John";        // assign from string
    y := x;            // copy construct
    y = x;             // copy assign
    z := (move x);     // move construct
    z = (move y);      // move assign
    x.print();         // "value is [] []" - moved from
    y.print();         // "value is [] []" - moved from
}
```

> Note: This makes memberwise semantics symmetric for construction and assignment. In Cpp1, only non-copy/move constructors have a default, which is to initialize a member with its default initializer. In Cpp2, both constructors and assignment operators default to using the default initializer if it's a conversion function (non-`that`, aka non-copy/move), and using memberwise `member = that.member;` for copy/move functions.


## <a id="comparisons"></a> `#!cpp operator<=>` — Unified comparisons

To write comparison functions for your type, usually you just need to write either or both of `operator<=>` and `operator==` with a first parameter of `this` and a second parameter of any type (usually `that` which is of the same type). If you omit the function body, a memberwise comparison will be generated by default.

`operator<=>` must return one of `std::strong_ordering`, `std::partial_ordering`, or `std::weak_ordering`. It makes `<`, `<=`, `>`, and `>=` comparisons available for your type. Prefer a strong ordering unless you have a reason to use a partial or weak ordering. If you write `operator<=>` without a custom function body, `operator==` is generated for you.

`operator==` must return `bool`. It makes `==` and `!=` comparisons available for your type.

For example:

``` cpp title="Writing the <=> operator" hl_lines="5-7 13"
item: type = {
    x: i32         = ();
    y: std::string = ();

    operator<=>: (this, that) -> std::strong_ordering;
        //  memberwise by default: first compares x <=> that.x,
        //  then if those are equal compares y <=> that.y

    // ...
}

test: (x: item, y: item) = {
    if x != y {         //  ok
        //  ...
    }
}
```

The above is the same as in Cpp1 because most of Cpp2's `#!cpp operator<=>` feature has already been merged into ISO C++ (Cpp1). In addition, in Cpp2 comparisons with the same precedence can be safely chained, and always have the mathematically sound transitive meaning or else are rejected at compile time:

- **Valid chains: All `<`/`<=`, all `>`/`>=`, or all `==`.** All mathematically sound and safe chains like `a <= b < c` are supported, with efficient single evaluation of each term. They are "sound" because they are transitive; these chains imply a relationship between `a` and `c` (in this case, the chain implies that `a <= c` is also true).

> Note: These valid chains always give mathematically expected results, even when invoking existing comparison operators authored in Cpp1 syntax.

- **Invalid chains: Everything else.** Nonsense chains like `a >= b < c` and `a != b != c` are compile time errors. They are "nonsense" because they are non-transitive; these chains do not imply any relationship between `a` and `c`.

- **Non-chains: Mixed precedence is not a chain.** Expressions like `a<b == c<d` are not a chain, because `==` has lower precedence than `<`. This simply means what it appears to mean, namely `(a<b) == (c<d)`; the expression evaluates to `#!cpp true` if `a<b` and `c<d` are either both true or both false, otherwise the expression evaluates to `#!cpp false`.

``` cpp title="Chained comparisons" hl_lines="2"
//  If requested is in the range of values [lo, hi)
if lo <= requested < hi {
    // ... do something ...
}

//  Equivalent result to: (lo ..< hi).contains( requested )
```

For more details, see [P0515R0 "Consistent comparison" section 3.3](https://wg21.link/p0515r0) and [P0893 "Chaining comparisons"](https://wg21.link/p0893).

---

### Cppfront Mixed (`docs/cppfront/mixed.md`)

# Mixing Cpp1 (today's C++) and Cpp2 in the same source file

## Compiling a source file that contains both Cpp1 and Cpp2 code

Cppfront compiles a `.cpp2` file and produces a `.cpp` file to be compiled by your favorite C++20 or higher C++ compiler.

The same `.cpp2` file may contain both Cpp2 syntax and today's "Cpp1" C++ syntax, **side by side but not nested**.

When cppfront compiles such a mixed file, it just passes through the Cpp1 code as-is, and translates the Cpp2 code to Cpp1 in-place. This means that when a call site (call this the "caller") uses a type/function/object (call this the "callee") written in the same file:

- **Code written in all Cpp2 is always order-independent by default.** When a caller written in Cpp2 syntax uses a callee written in Cpp2 syntax, they can appear in either order in the file.

- **Code written in Cpp1 is order-dependent as usual.** When either the caller or the callee (or both) are written in Cpp1 syntax, the callee must be declared before the caller.


## Okay: Cpp1 and Cpp2 side by side, interleaved

For example, this source file is fine, where the Cpp2 and Cpp1 code are side by side and seamlessly call each other directly as usual:

``` cpp title="mixed.cpp2 — Mixing Cpp1 and Cpp2 code side by side in the same source file is okay" linenums="1" hl_lines="4-7"
#include <iostream>                             // Cpp1
#include <string_view>                          // Cpp1

N: namespace = {                                        // Cpp2
    hello: (msg: std::string_view) =                    // Cpp2
        std::cout << "Hello, (msg)$!\n";                // Cpp2
}                                                       // Cpp2

int main() {                                    // Cpp1
    auto words = std::vector{ "Alice", "Bob" }; // Cpp1
    N::hello( words[0] );                       // Cpp1
    N::hello( words[1] );                       // Cpp1
    std::cout << "... and goodnight\n";         // Cpp1
}                                               // Cpp1
```

## Not allowed: Nesting Cpp1 inside Cpp2 (and vice versa)

However, the following source file is not valid, because it tries to nest Cpp2 code inside Cpp1 code, and vice versa:

``` cpp title="ERROR.cpp2 — this is NOT allowed" linenums="1" hl_lines="5 6 9 14"
#include <iostream>                             // Cpp1
#include <string_view>                          // Cpp1

namespace N {                                   // Cpp1
    hello: (msg: std::string_view) =                    // Cpp2 (ERROR here)
        std::cout << "Hello, (msg)$!\n";                // Cpp2 (ERROR here)
}                                               // Cpp1

main: () = {                                            // Cpp2
    auto words = std::vector{ "Alice", "Bob" }; // Cpp1 (ERROR here)
    N::hello( words[0] );                           // ?
    N::hello( words[1] );                           // ?
    std::cout << "... and goodnight\n";             // ?
}                                                       // Cpp2
```

The above nesting is not supported because it would create not just parsing problems but also semantic ambiguities. For example, lines 11-13 are syntactically valid as Cpp1 or as Cpp2, but if they are treated as Cpp2 then the `#!cpp words[0]` and `#!cpp words[1]` expressions' `#!cpp std::vector::operator[]` calls are bounds-checked and bounds-safe by default, whereas if they are treated as Cpp1 then they are not bounds-checked. And that's a pretty important difference to be sure about!

---

### Cppfront Options (`docs/cppfront/options.md`)

# Cppfront command line options

Cppfront is invoked using

    cppfront [options] file ...

where

- **options** is optional, and can include options described on this page

- **file ...** is a list of one or more `.cpp2` filenames to be compiled

Command line options are spelled starting with `-` or `/` followed by the option name. For example, `-help` prints help.

For convenience, you can shorten the name to any unique prefix not shared with another option. For example:

- `-help` can be equivalently written as `-hel`, `-he`, or `-h`, because no other option starts with `h`.
- `-import-std` and `-include-std` can be shortened to `-im` and `-in` respectively, but not `-i` which would be ambiguous with each other.


## Basic command line options

### `-help`, `-h`, `-?`

Prints an abbreviated version of this documentation page.

### `-import-std`, `-im`

Makes the entire C++ standard library (namespace `std::`) available via a module `import std.compat;` (which implies `import std;`).

> When you use either `-import-std` or `-include-std`, your `.cpp2` program will not need to explicitly `import` any C++ standard library module or `#include` any C++ standard library header (it can still do that, but it would be redundant).

This option is implicitly set if `-pure-cpp2` is selected.

This option is ignored if `-include-std` is selected. If your Cpp1 compiler does not yet support standard library modules `std` and `std.compat`, this option automatically uses  `-include-std` instead as a fallback.

### `-include-std`, `-in`

Makes the entire C++ standard library (namespace `std::`) available via an '#include" of every standard header.

This option should always work with all standard headers, including draft-standard C++26 headers that are not yet in a published standard, because it tracks new headers as they are added and uses feature tests to not include headers that are not yet available on your Cpp1 implementation.

### `-pure-cpp2`, `-p`

Allow Cpp2 syntax only.

This option also sets `-import-std`.

### `-version`, `-vers`

Print version, build, copyright, and license information.


## Additional dynamic safety check controls

### `-no-comparison-checks`, `-no-c`

Disable mixed-sign comparison safety checks. If not disabled, mixed-sign comparisons are diagnosed by default.

### `-no-div-zero-checks`, `-no-d`

Disable integer division by zero checks. If not disabled, integer division by zero checks are performed by default when both the numerator and denominator are integer types.

### `-no-null-checks`, `-no-n`

Disable null safety checks. If not disabled, null dereference checks are performed by default.

### `-no-subscript-checks`, `-no-s`

Disable subscript bounds safety checks. If not disabled, subscript bounds safety checks are performed by default.


## Support for constrained target environments

### `-fno-exceptions`, `-fno-e`

Disable C++ exception handling. This should be used only if you must run in an environment that bans C++ exception handling, and so you are already using a similar command line option for your Cpp1 compiler.

If this option is selected, a failed `as` for `std::variant` will assert.

### `-fno-rtti`, `-fno-r`

Disable C++ run-time type information (RTTI). This should be used only if you must run in an environment that bans C++ RTTI, and so you are already using a similar command line option for your Cpp1 compiler.

If this option is selected, trying to using `as` for `*` (raw pointers) or `std::any` will assert.


## Cpp1 file content options

### `-clean-cpp1`, `-cl`

Emit clean `.cpp` files without `#line` directives and other extra information that cppfront normally emits in the `.cpp` to light up C++ tools (e.g., to let IDEs integrate cppfront error message output, debuggers step to the right lines in Cpp2 source code, and so forth). In normal use, you won't need `-c`.

### `-emit-cppfront-info`, `-e`

Emit cppfront version and build in the `.cpp` file.

### `-line-paths`, `-l`

Emit absolute paths in `#line` directives.

## Cppfront output options

### `-cwd` _path_, `-cw` _path_

Changes the current working directory to 'path'. Can be useful in build scripts to control where generated Cpp1 files are places; see also `-output`.

### `-debug`, `-d`

Emit compiler debug output. This is only useful when debugging cppfront itself.

### `-format-colon-errors`, `-fo`

Emit cppfront diagnostics using `:line:col:` format for line and column numbers, if that is the format better recognized by your IDE, so that it will pick up cppfront messages and integrate them in its normal error message output location. If not set, by default cppfront diagnostics use `(line,col)` format.

### `-output` _filename_, `-o` _filename_

Output to 'filename' (can be 'stdout'). If not set, the default output filename for is the same as the input filename without the `2` (e.g., compiling `hello.cpp2` by default writes its output to `hello.cpp`, and `header.h2` to `header.h`).

### `-quiet`, `-q`

Print no console output unless there are errors to report.

### `-verbose`, `-verb`

Print verbose statistics and `-debug` output.

---

### Notes Autodiff Status (`docs/notes/autodiff_status.md`)

# Supported algorithmic differentiation (autodiff) features

The listings might be incomplete. If something is missing, it is not supported. Algorithmic differentiation is applied via the [`autodiff` metafunction](../cpp2/metafunctions.md#autodiff). Maybe the planned features are added in 2026. Do not wait for them. The autodif feature is a proof of concept implementation.

** Reverse mode algorithmic differentiation is very experimental. Expect it to break. **

## Currently supported or planned features

| Description | Status forward | Status reverse |
| --- | --- | --- |
| Type definitions (structures) | <span style="color:green">Supported</span> | <span style="color:green">Supported</span> |
| Member values | <span style="color:green">Supported</span> | <span style="color:gray">Planned</span> |
| Member functions | <span style="color:green">Supported</span> | <span style="color:green">Supported</span> |
| Function arguments | <span style="color:green">Supported</span> | <span style="color:green">Supported</span> |
| Function return arguments | <span style="color:green">Supported</span> | <span style="color:green">Supported</span> |
| Addition and multiplication | <span style="color:green">Supported</span> | <span style="color:green">Supported</span> |
| Prefix addition and subtraction | <span style="color:green">Supported</span> | <span style="color:gray">Planned</span> |
| Static member function calls | <span style="color:green">Supported</span> | <span style="color:green">Supported</span> |
| Member function calls | <span style="color:green">Supported</span> | <span style="color:gray">Planned</span> |
| Function calls | <span style="color:green">Supported</span> | <span style="color:green">Supported</span> |
| Math functions (sin, cos, exp, sqrt) | <span style="color:green">Supported</span> | <span style="color:green">Supported</span> |
| If else | <span style="color:green">Supported</span> | <span style="color:gray">Planned</span> |
| Return statement | <span style="color:green">Supported</span> | <span style="color:gray">Planned</span> |
| Intermediate variables | <span style="color:green">Supported</span> | <span style="color:green">Supported</span> |
| Passive variables | <span style="color:green">Supported</span> | <span style="color:green">Supported</span> |
| While loop | <span style="color:green">Supported</span> | <span style="color:gray">Planned</span> |
| Do while loop | <span style="color:green">Supported</span> | <span style="color:gray">Planned</span> |
| For loop | <span style="color:green">Supported</span> | <span style="color:green">Supported</span> |
| Template arguments |  <span style="color:gray">Planned</span> |  <span style="color:gray">Planned</span> |
| Lambda functions |  <span style="color:gray">Planned</span> |  <span style="color:gray">Planned</span> |

---

### Notes Regex Status (`docs/notes/regex_status.md`)

# Supported regular expression features

The listings are taken from the [Perl regex docs](https://perldoc.perl.org/perlre). Regular expressions are applied via the [`regex` metafunction](../cpp2/metafunctions.md#regex).


## Currently supported or planned features


### Modifiers

| Modifier | Notes | Status |
| --- | --- | --- |
| **`i`** | Do case-insensitive pattern matching. For example, "A" will match "a" under `/i`. | <span style="color:green">Supported</span> | 
| **`m`** | Treat the string being matched against as multiple lines. That is, change `^` and `$` from matching the start of the string's first line and the end of its last line to matching the start and end of each line within the string. | <span style="color:green">Supported</span> |
| **`s`** | Treat the string as single line. That is, change `.` to match any character whatsoever, even a newline, which normally it would not match. | <span style="color:green">Supported</span> |
| ***`x` and `xx`** | Extend your pattern's legibility by permitting whitespace and comments. For details see: [Perl regex docs: `/x` and `/xx`](https://perldoc.perl.org/perlre#/x-and-/xx). | <span style="color:green">Supported</span> |
| **`n`** | Prevent the grouping metacharacters `(` and `)` from capturing. This modifier will stop `$1`, `$2`, etc. from being filled in. | <span style="color:green">Supported</span> |
| **`c`** | Keep the current position during repeated matching. | <span style="color:green">Supported</span> |


### Escape sequences __(Complete)__

| Escape sequence  | Notes | Status |
| --- | --- | --- |
| **`\t`** | Tab (HT, TAB)X | <span style="color:green">Supported</span> | 
| **`\n`** | Newline (LF, NL) | <span style="color:green">Supported</span> | 
| **`\r`** | Return (CR) | <span style="color:green">Supported</span> | 
| **`\f`** | Form feed (FF) | <span style="color:green">Supported</span> | 
| **`\a`** | Alarm (bell) (BEL) | <span style="color:green">Supported</span> | 
| **`\e`** | Escape (think troff) (ESC) | <span style="color:green">Supported</span> |
| **`\x{}`, `\x00`** | Character whose ordinal is the given hexadecimal number | <span style="color:green">Supported</span> | 
| **`\o{}`, `\000`** | Character whose ordinal is the given octal number | <span style="color:green">Supported</span> | 


### Quantifiers __(Complete)__

| Quantifier  | Notes | Status |
| --- | --- | --- |
| **`*`** |        Match 0 or more times | <span style="color:green">Supported</span> | 
| **`+`** |        Match 1 or more times | <span style="color:green">Supported</span> | 
| **`?`** |        Match 1 or 0 times | <span style="color:green">Supported</span> | 
| **`{n}`** |      Match exactly n times | <span style="color:green">Supported</span> | 
| **`{n,}`** |     Match at least n times | <span style="color:green">Supported</span> | 
| **`{,n}`** |     Match at most n times | <span style="color:green">Supported</span> | 
| **`{n,m}`** |    Match at least n but not more than m times | <span style="color:green">Supported</span> | 
| |  | |
| **`*?`** |       Match 0 or more times, not greedily | <span style="color:green">Supported</span> | 
| **`+?`** |       Match 1 or more times, not greedily | <span style="color:green">Supported</span> | 
| **`??`** |       Match 0 or 1 time, not greedily | <span style="color:green">Supported</span> | 
| **`{n}?`** |     Match exactly n times, not greedily (redundant) | <span style="color:green">Supported</span> | 
| **`{n,}?`** |    Match at least n times, not greedily | <span style="color:green">Supported</span> | 
| **`{,n}?`** |    Match at most n times, not greedily | <span style="color:green">Supported</span> | 
| **`{n,m}?`** |   Match at least n but not more than m times, not greedily | <span style="color:green">Supported</span> | 
| |  | |
| **`*+`** |       Match 0 or more times and give nothing back | <span style="color:green">Supported</span> | 
| **`++`** |       Match 1 or more times and give nothing back | <span style="color:green">Supported</span> | 
| **`?+`** |       Match 0 or 1 time and give nothing back | <span style="color:green">Supported</span> | 
| **`{n}+`** |     Match exactly n times and give nothing back (redundant) | <span style="color:green">Supported</span> | 
| **`{n,}+`** |    Match at least n times and give nothing back | <span style="color:green">Supported</span> | 
| **`{,n}+`** |    Match at most n times and give nothing back | <span style="color:green">Supported</span> | 
| **`{n,m}+`** |   Match at least n but not more than m times and give nothing back | <span style="color:green">Supported</span> | 


### Character Classes and other Special Escapes __(Complete)__

| Feature  | Notes | Status |
| --- | --- | --- |
| **`[`...`]`** | Match a character according to the rules of the bracketed character class defined by the "...". Example: `[a-z]` matches "a" or "b" or "c" ... or "z" | <span style="color:green">Supported</span> | 
| **`[[:`...`:]]`** |    Match a character according to the rules of the POSIX character class "..." within the outer bracketed character class.  Example: `[[:upper:]]` matches any uppercase character. | <span style="color:green">Supported</span> | 
| **`\g1`** or **`\g{-1}`**  |          Backreference to a specific or previous group. The number may be negative indicating a relative previous group and may optionally be wrapped in curly brackets for safer parsing. | <span style="color:green">Supported</span> | 
| **`\g{name}`** |     Named backreference | <span style="color:green">Supported</span> | 
| **`\k<name>`** |     Named backreference | <span style="color:green">Supported</span> | 
| **`\k'name'`** |     Named backreference | <span style="color:green">Supported</span> | 
| **`\k{name}`** |     Named backreference | <span style="color:green">Supported</span> | 
| **`\w`** |           Match a "word" character (alphanumeric plus "_", plus other connector punctuation chars plus Unicode marks) | <span style="color:green">Supported</span> | 
| **`\W`** |           Match a non-"word" character | <span style="color:green">Supported</span> | 
| **`\s`** |           Match a whitespace character | <span style="color:green">Supported</span> | 
| **`\S`** |           Match a non-whitespace character | <span style="color:green">Supported</span> | 
| **`\d`** |           Match a decimal digit character | <span style="color:green">Supported</span> | 
| **`\D`** |           Match a non-digit character | <span style="color:green">Supported</span> | 
| **`\v`** |           Vertical whitespace | <span style="color:green">Supported</span> | 
| **`\V`** |           Not vertical whitespace | <span style="color:green">Supported</span> | 
| **`\h`** |           Horizontal whitespace | <span style="color:green">Supported</span> | 
| **`\H`** |           Not horizontal whitespace | <span style="color:green">Supported</span> | 
| **`\1`** |           Backreference to a specific capture group or buffer. '1' may actually be any positive integer. | <span style="color:green">Supported</span> | 
| **`\N`** |           Any character but \n.  Not affected by /s modifier | <span style="color:green">Supported</span> | 
| **`\K`** |           Keep the stuff left of the \K, don't include it in $& | <span style="color:green">Supported</span> | 


### Assertions

| Assertion  | Notes | Status |
| --- | --- | --- |
| **`\b`** |     Match a \w\W or \W\w boundary | <span style="color:green">Supported</span> | 
| **`\B`** |     Match except at a \w\W or \W\w boundary | <span style="color:green">Supported</span> | 
| **`\A`** |     Match only at beginning of string | <span style="color:green">Supported</span> | 
| **`\Z`** |     Match only at end of string, or before newline at the end | <span style="color:green">Supported</span> | 
| **`\z`** |     Match only at end of string | <span style="color:green">Supported</span> | 
| **`\G`** |     Match only at pos() (e.g. at the end-of-match position of prior m//g) | <span style="color:green">Supported</span> |


### Capture groups __(Complete)__

| Feature  | Status |
| --- | --- |
| **`(`...`)`** | <span style="color:green">Supported</span> | 


### Quoting metacharacters __(Complete)__

| Feature | Status |
| --- | --- |
| **For `^.[]$()*{}?+|\`** | <span style="color:green">Supported</span> | 


### Extended Patterns

| Extended pattern  | Notes | Status |
| --- | --- | --- |
| **`(?<NAME>pattern)`** |            Named capture group | <span style="color:green">Supported</span> | 
| **`(?#text)`** |                    Comments | <span style="color:green">Supported</span> | 
| **`(?adlupimnsx-imnsx)`** |         Modification for surrounding context | <span style="color:green">Supported</span> | 
| **`(?^alupimnsx)`** |               Modification for surrounding context | <span style="color:green">Supported</span> | 
| **`(?:pattern)`** |                 Clustering, does not generate a group index. | <span style="color:green">Supported</span> | 
| **`(?adluimnsx-imnsx:pattern)`** |  Clustering, does not generate a group index and modifications for the cluster. | <span style="color:green">Supported</span> | 
| **`(?^aluimnsx:pattern)`** |        Clustering, does not generate a group index and modifications for the cluster. | <span style="color:green">Supported</span> | 
| **`(?`<code>&#124;</code>`pattern)`** |                 Branch reset | <span style="color:green">Supported</span> | 
| **`(?'NAME'pattern)`** |            Named capture group | <span style="color:green">Supported</span> | 
| **`(?(condition)yes-pattern`<code>&#124;</code>`no-pattern)`** |  Conditional patterns. | <span style="color:gray">Planned</span> | 
| **`(?(condition)yes-pattern)`** |             Conditional patterns. | <span style="color:gray">Planned</span> | 
| **`(?>pattern)`** |                 Atomic patterns. (Disable backtrack.) | <span style="color:green">Supported</span> |
| **`(*atomic:pattern)`** |           Atomic patterns. (Disable backtrack.) | <span style="color:green">Supported</span> |


### Lookaround Assertions

| Lookaround assertion  | Notes | Status |
| --- | --- | --- |
| **`(?=pattern)`**                     | Positive look ahead. | <span style="color:green">Supported</span> | 
| **`(*pla:pattern)`**                  | Positive look ahead. | <span style="color:green">Supported</span> | 
| **`(*positive_lookahead:pattern)`**   | Positive look ahead. | <span style="color:green">Supported</span> | 
| **`(?!pattern)`**                     | Negative look ahead. | <span style="color:green">Supported</span> | 
| **`(*nla:pattern)`**                  | Negative look ahead. | <span style="color:green">Supported</span> | 
| **`(*negative_lookahead:pattern)`**   | Negative look ahead. | <span style="color:green">Supported</span> | 
| **`(?<=pattern)`**                    | Positive look behind. | <span style="color:green">Supported</span> |
| **`(*plb:pattern)`**                  | Positive look behind. | <span style="color:green">Supported</span> |
| **`(*positive_lookbehind:pattern)`**  | Positive look behind. | <span style="color:green">Supported</span> |
| **`(?<!pattern)`**                    | Negative look behind. | <span style="color:green">Supported</span> |
| **`(*nlb:pattern)`**                  | Negative look behind. | <span style="color:green">Supported</span> |
| **`(*negative_lookbehind:pattern)`**  | Negative look behind. | <span style="color:green">Supported</span> |


### Special Backtracking Control Verbs

| Backtracking control verb  | Notes | Status |
| --- | --- | --- |
| **`(*SKIP) (*SKIP:NAME)`**     | Start next search here. | <span style="color:gray">Planned</span> | 
| **`(*PRUNE) (*PRUNE:NAME)`**   | No backtracking over this point. | <span style="color:gray">Planned</span> | 
| **`(*MARK:NAME) (*:NAME)`**    | Place a named mark. | <span style="color:gray">Planned</span> | 
| **`(*THEN) (*THEN:NAME)`**     | Like PRUNE. | <span style="color:gray">Planned</span> | 
| **`(*COMMIT) (*COMMIT:arg)`**  | Stop searching. | <span style="color:gray">Planned</span> | 
| **`(*FAIL) (*F) (*FAIL:arg)`** | Fail the pattern/branch. | <span style="color:gray">Planned</span> | 
| **`(*ACCEPT) (*ACCEPT:arg)`**  | Accept the pattern/subpattern. | <span style="color:gray">Planned</span> | 


## Not planned (Mainly because of Unicode or perl specifics)

### Modifiers

| Modifier   | Notes | Status |
| --- | --- | --- |
| `p`                | Preserve the string matched such that ${^PREMATCH}, ${^MATCH}, and ${^POSTMATCH} are available for use after matching. | <span style="color:darkred">Not planned</span> | 
| `a`, `d`, `l`, and `u`   | These modifiers affect which character-set rules (Unicode, etc.) are used, as described below in "Character set modifiers". | <span style="color:darkred">Not planned</span> | 
| `g`                | globally match the pattern repeatedly in the string | <span style="color:darkred">Not planned</span> | 
| `e`                | evaluate the right-hand side as an expression | <span style="color:darkred">Not planned</span> | 
| `ee`               | evaluate the right side as a string then eval the result | <span style="color:darkred">Not planned</span> | 
| `o`                | pretend to optimize your code, but actually introduce bugs | <span style="color:darkred">Not planned</span> | 
| `r`                | perform non-destructive substitution and return the new value | <span style="color:darkred">Not planned</span> | 


### Escape sequences

| Escape sequence   | Notes | Status |
| --- | --- | --- |
| `\cK`         | control char          (example: VT) | <span style="color:darkred">Not planned</span> | 
| `\N{name}`    | named Unicode character or character sequence | <span style="color:darkred">Not planned</span> | 
| `\N{U+263D}`  | Unicode character     (example: FIRST QUARTER MOON) | <span style="color:darkred">Not planned</span> | 
| `\l`          | lowercase next char (think vi) | <span style="color:darkred">Not planned</span> | 
| `\u`          | uppercase next char (think vi) | <span style="color:darkred">Not planned</span> | 
| `\L`          | lowercase until \E (think vi) | <span style="color:darkred">Not planned</span> | 
| `\U`          | uppercase until \E (think vi) | <span style="color:darkred">Not planned</span> | 
| `\Q`          | quote (disable) pattern metacharacters until \E | <span style="color:darkred">Not planned</span> | 
| `\E`          | end either case modification or quoted section, think vi | <span style="color:darkred">Not planned</span> | 


### Character Classes and other Special Escapes

| Character class or escape   | Notes | Status |
| --- | --- | --- |
| `(?[...])`  | Extended bracketed character class | <span style="color:darkred">Not planned</span> | 
| `\pP`       | Match P, named property.  Use \p{Prop} for longer names | <span style="color:darkred">Not planned</span> | 
| `\PP`       | Match non-P | <span style="color:darkred">Not planned</span> | 
| `\X`        | Match Unicode "eXtended grapheme cluster" | <span style="color:darkred">Not planned</span> | 
| `\R`        | Linebreak | <span style="color:darkred">Not planned</span> | 


### Assertions

| Assertion   | Notes | Status |
| --- | --- | --- |
| `\b{}`   | Match at Unicode boundary of specified type | <span style="color:darkred">Not planned</span> | 
| `\B{}`   | Match where corresponding \b{} doesn't match | <span style="color:darkred">Not planned</span> | 

### Extended Patterns


| Extended pattern   | Notes | Status |
| --- | --- | --- |
| `(?{ code })`                 | Perl code execution. | <span style="color:darkred">Not planned</span> | 
| `(*{ code })`                 | Perl code execution. | <span style="color:darkred">Not planned</span> | 
| `(??{ code })`                | Perl code execution. | <span style="color:darkred">Not planned</span> | 
| `(?PARNO)` `(?-PARNO)` `(?+PARNO)` `(?R)` `(?0)`       | Recursive subpattern. | <span style="color:darkred">Not planned</span> | 
| `(?&NAME)`                   | Recursive subpattern. | <span style="color:darkred">Not planned</span> | 


### Script runs

| Script runs   | Notes | Status |
| --- | --- | --- |
| `(*script_run:pattern)`         | All chars in pattern need to be of the same script. | <span style="color:darkred">Not planned</span> | 
| `(*sr:pattern)`                 | All chars in pattern need to be of the same script. | <span style="color:darkred">Not planned</span> | 
| `(*atomic_script_run:pattern)`  | Without backtracking. | <span style="color:darkred">Not planned</span> | 
| `(*asr:pattern)`                | Without backtracking. | <span style="color:darkred">Not planned</span> |

---

### Welcome Hello World (`docs/welcome/hello-world.md`)

# **Hello, world!**

``` mermaid
graph LR
  A["` hello.cpp**2** `"] ==> B(["` **cppfront** `"]);
  B ==> C[hello.cpp];
  C ==> D([Your favorite<br> C++ compiler<p>... and IDE / libraries / build<br>system / in-house tools / ...]);
```

## <a id="hello-cpp2"></a> A `hello.cpp2` program

Here is the usual one-line starter program that prints `Hello, world!`. Note that this is a complete program, no `#!cpp #include` required:

``` cpp title="hello.cpp2 — on one line"
main: () = std::cout << "Hello, world!\n";
```

But let's add a little more, just to show a few things:

``` cpp title="hello.cpp2 — slightly more interesting"
main: () = {
    words: std::vector = ( "Alice", "Bob" );
    hello( words[0] );
    hello( words[1] );
}

hello: (msg: std::string_view) = {
    std::cout << "Hello, (msg)$!\n";
}
```

This short program code already illustrates a few Cpp2 essentials.

**Consistent context-free syntax.** Cpp2 is designed so that there is one general way to spell a given thing, that works consistently everywhere. All Cpp2 types/functions/objects/namespaces are written using the unambiguous and context-free [declaration syntax](../cpp2/declarations.md) **"_name_ `:` _kind_ `=` _statement_"**. The `:` is pronounced **"is a,"** and the `=` is pronounced **"defined as."**

- `main` **is a** function that takes no arguments and returns nothing, and is **defined as** the code body shown.

- `words` **is a** `std::vector`, initially **defined as** holding `#!cpp "Alice"` and `#!cpp "Bob"`.

- `hello` **is a** function that takes a `std::string_view` it will only read from and that returns nothing, and is **defined as** code that prints the string to `cout` the usual C++ way.

All grammar is context-free. In particular, we (the human reading the code, and the compiler) never need to do name lookup to figure out how to parse something — there is never a ["vexing parse"](https://en.wikipedia.org/wiki/Most_vexing_parse) in Cpp2. For details, see [Design note: Unambiguous parsing](https://github.com/hsutter/cppfront/wiki/Design-note%3A-Unambiguous-parsing).

**Simple, safe, and efficient by default.** Cpp2 has contracts (tracking draft C++26 contracts), `inspect` pattern matching, string interpolation, automatic move from last use, and more.

- <a id="ctad"></a> Declaring `words` uses **"CTAD"** (C++'s normal [constructor template argument deduction](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction)) to deduce the type of elements in the `vector`.

- Calling `#!cpp words[0]` and `#!cpp words[1]` is **bounds-checked by default**. From Cpp2 code, ordinary `std::vector` subscript accesses are safely bounds-checked by default without requiring any upgrade to your favorite standard library, and that's true for any similar subscript of something whose size can be queried using `std::size()` and `std::ssize()`, and for which `std::begin()` returns a random access iterator, including any in-house integer-indexed container types you already have that can easily provide `std::size()` and `std::ssize()` if they don't already.

- `hello` uses **string interpolation** to be able to write `#!cpp "Hello, (msg)$!\n"` instead of `#!cpp "Hello, " << msg << "!\n"`. String interpolation also supports [standard C++ format specifications](https://en.cppreference.com/w/cpp/utility/format/spec), so you won't need iostream manipulators.

**Simplicity through generality + defaults.** A major way that Cpp2 delivers simplicity is by providing just one powerful general syntax for a given thing (e.g., one function definition syntax), but designing it so you can omit the parts you're not currently using (e.g., where you're happy with the defaults). We're already using some of those defaults above:

- We can omit writing the `#!cpp -> void` return type for a function that doesn't return anything, as both of these functions do.

- We can omit the `{` `}` around single-statement function bodies, as `hello` does.

- We can omit the `in` on the `msg` parameter. Cpp2 has just six ways to pass parameters: The most common ones are `in` for read-only (the default so we can omit it, as `hello` does), and `inout` for read-write.  The others are `copy`, `out`, `move`, and `forward`.

For details, see [Design note: Defaults are one way to say the same thing](https://github.com/hsutter/cppfront/wiki/Design-note%3A-Defaults-are-one-way-to-say-the-same-thing).

**Order-independent by default.** Did you notice that `main` called `hello`, which was defined later? Cpp2 code is order-independent by default — there are no forward declarations.

**Seamless compatibility and interop.** We can just use `std::cout` and `#!cpp std::operator<<` and `std::string_view` directly as usual. Cpp2 code works with any C++ code or library, including the standard library, using ordinary direct calls without any wrapping/marshaling/thunking.

**C++ standard library is always available.** We didn't need `#!cpp #include <iostream>` or `#!cpp import std;`. The full C++ standard library is always available by default if your source file contains only syntax-2 code and you compile using cppfront's `-p` (short for `-pure-cpp2`), or if you use `-im` (short for `-import-std`). Cppfront is regularly updated to be compatible with C++23 and the latest draft C++26 library additions as soon as the ISO C++ committee votes them into the C++26 working draft, so as soon as you have a C++ implementation that has a new standard (or bleeding-edge draft standard!) C++ library feature, you'll be able to fully use it in Cpp2 code.


## <a id="build-hello-cpp2"></a> Building `hello.cpp2`

Now use `cppfront` to compile `hello.cpp2` to a standard C++ file `hello.cpp`:

``` bash title="Call cppfront to produce hello.cpp"
cppfront hello.cpp2 -p
```

The result is an ordinary C++ file that looks like this: [^clean-cpp1]

``` cpp title="hello.cpp — created by cppfront" linenums="1"
#define CPP2_IMPORT_STD          Yes

#include "cpp2util.h"

auto main() -> int;

auto hello(cpp2::in<std::string_view> msg) -> void;
auto main() -> int{
    std::vector words {"Alice", "Bob"};
    hello(CPP2_ASSERT_IN_BOUNDS_LITERAL(words, 0));
    hello(CPP2_ASSERT_IN_BOUNDS_LITERAL(std::move(words), 1));
}

auto hello(cpp2::in<std::string_view> msg) -> void {
    std::cout << ("Hello, " + cpp2::to_string(msg) + "!\n");  }
```

Here we can see more of how Cpp2 makes its features work.

**How: Consistent context-free syntax.**

- **All compiled lines are portable C++20 code** we can build with pretty much any C++ compiler released circa 2019 or later. Cpp2's context-free syntax converts directly to today's Cpp1 syntax. We can write and read our C++ types/functions/objects in simpler Cpp2 syntax without wrestling with context sensitivity and ambiguity, and they're all still just ordinary types/functions/objects.

**How: Simple, safe, and efficient by default.**

- **Line 9: CTAD** just works, because it turns into ordinary C++ code which already supports CTAD.
- **Lines 10-11: Automatic bounds checking** is added to `#!cpp words[0]` and `#!cpp words[1]` nonintrusively at the call site by default. Because it's nonintrusive, it works seamlessly with all existing container types that are `std::size` and `std::ssize`-aware, when you use them from safe Cpp2 code.
- **Line 11: Automatic move from last use** ensures the last use of `words` will automatically avoid a copy if it's being passed to something that's optimized for rvalues.
- **Line 15: String interpolation** performs the string capture of `msg`'s current value via `cpp2::to_string`. That uses `std::to_string` when available, and it also works for additional types (such as `#!cpp bool`, to print `#!cpp false` and `#!cpp true` instead of `0` and `1`, without having to remember to use `std::boolalpha`).

**How: Simplicity through generality + defaults.**

- **Line 7: `in` parameters** are implemented using `#!cpp cpp2::in<>`, which is smart enough to pass by `#!cpp const` value when that's safe and appropriate, otherwise by `#!cpp const&`, so you don't have to choose the right one by hand.

**How: Order-independent by default.**

- **Lines 5 and 7: Order independence** happens because cppfront generates all the type and function forward declarations for you, so you don't have to. That's why `main` can just call `hello`: both are forward-declared, so they can both see each other.

**How: Seamless compatibility and interop.**

- **Lines 9-11 and 15: Ordinary direct calls** to existing C++ code, so there's never a need for wrapping/marshaling/thunking.

**How: C++ standard library always available.**

- **Lines 1 and 3: `std::` is available** because cppfront was invoked with `-p`, which implies either `-im` (short for `-import-std`) or `-in` (short for `-include-std`, for compilers that don't support modules yet). The generated code tells `cpp2util.h` to `#!cpp import` the entire standard library as a module (or do the equivalent via headers if modules are not available).


## <a id="build-hello-cpp"></a> Building and running `hello.cpp` with any recent C++ compiler

Finally, just build `hello.cpp` using your favorite C++20 compiler, where `CPPFRONT_INCLUDE` is the path to `/cppfront/include`:

<image align="right" width="120" src="https://user-images.githubusercontent.com/1801526/188906112-ef377a79-b6a9-4a30-b318-10b51d8ea934.png">

``` title="MSVC (Visual Studio 2019 version 16.11 or higher)"
> cl hello.cpp -std:c++20 -EHsc -I CPPFRONT_INCLUDE
> hello.exe
Hello, world!
```

``` bash title="GCC (GCC 10 or higher)"
$ g++ hello.cpp -std=c++20 -ICPPFRONT_INCLUDE -o hello
$ ./hello.exe
Hello, world!
```

``` bash title="Clang (Clang 12 or higher)"
$ clang++ hello.cpp -std=c++20 -ICPPFRONT_INCLUDE -o hello
$ ./hello.exe
Hello, world!
```


### &#10148; Next: [Adding cppfront to your existing C++ project](integration.md)


[^clean-cpp1]: For presentation purposes, this documentation generally shows the `.cpp` as generated when using cppfront's `-cl` (short for `-clean-cpp1`), which suppresses extra information cppfront normally emits in the `.cpp` to light up C++ tools (e.g., to let IDEs integrate cppfront error message output, debuggers step to the right lines in Cpp2 source code, and so forth). In normal use, you won't need or even want `-cl`.

---

### Welcome Integration (`docs/welcome/integration.md`)

# Adding cppfront in your IDE / build system

To start trying out Cpp2 syntax in any existing C++ project, just add a build step to translate the Cpp2 to Cpp1 syntax:

- Copy the `.cpp` file to the same name with a `.cpp2` extension.
- Add the `.cpp2` file to the project, and ensure the `.cpp` is in C++20 mode.
- Tell the IDE to build that file using a custom build tool to invoke cppfront.

That's it... The result Just Works with every C++20 or higher compiler and all existing C++ tools (debuggers, build systems, sanitizers, etc.). The IDE build should just pick up the `.cpp2` file source locations for any error messages, and the debugger should just step through the `.cpp2` file.

The following uses Visual Studio as an example, but others have done the same in Xcode, Qt Creator, CMake, and other IDEs.

## <a id="add-cpp2"></a> 1. Add the `.cpp2` file to the project, and ensure the `.cpp` is in C++20 mode

For Visual Studio: In the Solution Explorer, right-click on Source Files and pick Add to add the file to the project.

<p align="center"><img width="600" src="https://github.com/hsutter/cppfront/assets/1801526/0be904e4-4222-40bc-85e4-b573d6371d2d"></p>

Also in Solution Explorer, right-click on the `.cpp` file Properties and make sure it's in C++20 (or C++latest) mode.

<p align="center"><img width="600" src="https://github.com/hsutter/cppfront/assets/1801526/f7a25778-5056-41b3-a6e3-3034bf0587fd"></p>


## <a id="add-build-step"></a> 2. Tell the project system to build that file using a custom build tool to invoke cppfront, and add `cppfront/include` to the include path

For Visual Studio: In Solution Explorer, right-click on the `.cpp2` file and select Properties, and add the custom build tool. Remember to also tell it that the custom build tool produces the `.cpp` file, so that it knows about the build dependency:

<p align="center"><img width="600" src="https://github.com/hsutter/cppfront/assets/1801526/1307ac57-6c3b-4c83-b606-f5c626867ebf"></p>

Finally, put the `/cppfront/include` directory on your `INCLUDE` path. In Solution Explorer, right-click the app and select Properties, and add it to the VC++ Directories > Include Directories:

<p align="center"><img width="600" src="https://github.com/hsutter/cppfront/assets/1801526/866fc2b8-bfca-4568-823b-f0fecfae27f5"></p>


## <a id="it-just-works"></a> That's it: Error message outputs, debuggers, visualizers, and other tools should just work

That's enough to enable builds, and the IDE just picks up the rest from the `.cpp` file that cppfront generated:

- **The cppfront error messages in `filename(line, col)` format.** Most C++ IDEs recognize these, and usually automatically merge any diagnostic output wherever compiler error output normally appears. If your IDE prefers `filename:line:col`, just use the cppfront `-format-colon-errors` command line option.

- **The `#line` directives cppfront emits in the generated `.cpp` file.** Most C++ debuggers recognize these and will know to step through the `.cpp2` file. Note that `#line` emission is on by default, but if you choose `-c` (short for `-clean-cpp1`) these will be suppressed and then the debugger will step through the generated C++ code instead.  If your debugger can't find the files, you may need to use `-line-paths` to have absolute paths instead of relative paths in the `#line` directives.

- **Regardless of syntax, every type/function/object/namespace/etc. is still just an ordinary C++ type/function/object/namespace/etc.** Most C++ debugger visualizers will just work and show beautiful output for the types your program uses, including to use any in-the-box visualizers for all the `std::` types (since those are used directly as usual) and any custom visualizers you may have already written for your own types or popular library types.

---

--- METRICS ---
- Files Extracted: 20
- Estimated Token Budget: ~47190 tokens
- Canonical Reference: https://codewiki.google/github.com/hsutter/cppfront
