-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
788356f
commit cd631a0
Showing
84 changed files
with
6,944 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#pragma feature as // Permit any implicit conversion with "x as _". | ||
void f_short(short x); | ||
void f_int(int x); | ||
void f_unsigned(unsigned x); | ||
void f_long(long x); | ||
void f_float(float x); | ||
void f_double(double x); | ||
void f_bool(bool x); | ||
|
||
int main() { | ||
#pragma feature no_implicit_integral_narrowing | ||
int x_int = 100; | ||
f_short(x_int); // Error | ||
f_short(x_int as _); // OK | ||
#pragma feature_off no_implicit_integral_narrowing | ||
|
||
#pragma feature no_implicit_floating_narrowing | ||
double x_double = 100; | ||
f_float(x_double); // Error | ||
f_float(x_double as _); // Ok | ||
#pragma feature_off no_implicit_floating_narrowing | ||
|
||
#pragma feature no_implicit_signed_to_unsigned | ||
f_unsigned(x_int); // Error | ||
f_unsigned(x_int as _); // OK | ||
f_unsigned(x_double); // Error | ||
f_unsigned(x_double as _); // OK | ||
#pragma feature_off no_implicit_signed_to_unsigned | ||
|
||
#pragma feature no_implicit_widening | ||
char x_char = 'x'; | ||
f_short(x_char); // Error | ||
f_short(x_char as _); // OK | ||
f_long(x_int); // Error | ||
f_long(x_int as _); // OK | ||
float x_float = 1; | ||
f_double(x_float); // Error | ||
f_double(x_float as _); // OK | ||
#pragma feature_off no_implicit_widening | ||
|
||
#pragma feature as no_implicit_enum_to_underlying | ||
enum numbers_t : int { | ||
Zero, One, Two, Three, | ||
}; | ||
|
||
f_int(Zero); // Error | ||
f_int(Zero as _); // OK | ||
|
||
f_int(numbers_t::Zero); // Error | ||
f_int(numbers_t::Zero as _); // OK | ||
#pragma feature_off no_implicit_enum_to_underlying | ||
|
||
// Use as _ to allow implicit narrowing conversions inside | ||
// braced-initializer. | ||
short s1 { x_int }; // Error | ||
short s2 { x_int as _ }; // OK | ||
f_short({ x_int }); // Error | ||
f_short({ x_int as _}); // OK | ||
#pragma feature_off no_implicit_enum_to_underlying | ||
|
||
// Implicit conversions from pointers to bools are permitted by C++. | ||
const char* p = nullptr; | ||
f_bool(p); // OK | ||
#pragma feature no_implicit_pointer_to_bool | ||
// They are disabled by [no_implicit_pointer_to_bool] | ||
f_bool(p); // Error | ||
f_bool(p as bool); // OK | ||
f_bool(p as _); // OK | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#include <string> | ||
#include <iostream> | ||
|
||
struct Data { | ||
// Strings in tickmarks | ||
std::string `First Name`; | ||
std::string `Last Name`; | ||
int single, `double`, triple; | ||
}; | ||
|
||
int main() { | ||
Data data { }; | ||
data.`First Name` = "Abe"; | ||
data.`Last Name` = "Lincoln"; | ||
data.single = 1; | ||
data.`double` = 2; | ||
data.triple = 3; | ||
|
||
// Use reflection to print the name of each member and its value. | ||
std::cout<< Data~member_names + ": "<< data~member_values<< "\n" ...; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
set -x | ||
circle as.cxx | ||
circle ctor_conversions.cxx | ||
circle user_conversions.cxx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#pragma feature edition_carbon_2023 | ||
#include <string> | ||
#include <iostream> | ||
|
||
using String = std::string; | ||
|
||
choice IntResult { | ||
Success(int32_t), | ||
Failure(String), | ||
Cancelled, | ||
} | ||
|
||
fn ParseAsInt(s: String) -> IntResult { | ||
var r : int32_t = 0; | ||
for(var c in s) { | ||
if(not isdigit(c)) { | ||
return .Failure("Invalid character"); | ||
} | ||
|
||
// Accumulate the digits as they come in. | ||
r = 10 * r + c - '0'; | ||
} | ||
|
||
return .Success(r); | ||
} | ||
|
||
fn TryIt(s: String) { | ||
var result := ParseAsInt(s); | ||
match(result) { | ||
.Success(var x) => std::cout<< "Read integer "<< x<< "\n"; | ||
.Failure(var err) => std::cout<< "Failure '"<< err<< "'\n"; | ||
.Cancelled => std::terminate(); | ||
}; | ||
} | ||
|
||
fn main() -> int { | ||
TryIt("12345"); | ||
TryIt("12x45"); | ||
return 0; | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#pragma feature choice | ||
#include <iostream> | ||
|
||
choice IntResult { | ||
Success(int), | ||
Failure(std::string), | ||
Cancelled, | ||
}; | ||
|
||
template<typename T> | ||
void func(T obj) { | ||
match(obj) { | ||
.Success(auto x) => std::cout<< "Success: "<< x<< "\n"; | ||
.Failure(auto x) => std::cout<< "Failure: "<< x<< "\n"; | ||
.Cancelled => std::terminate(); | ||
}; | ||
} | ||
|
||
int main() { | ||
IntResult r1 = .Success(12345); | ||
IntResult r2 = .Failure("Hello"); | ||
IntResult r3 = .Cancelled(); | ||
func(r1); | ||
func(r2); | ||
func(r3); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#pragma feature choice new_decl_syntax | ||
#include <string> | ||
#include <tuple> | ||
#include <iostream> | ||
|
||
choice MyChoice { | ||
MyTuple(int, std::string), // The payload is a tuple. | ||
MyArray(double[3]), // The payload is an array. | ||
MyScalar(short), // The payload is a scalar. | ||
} | ||
|
||
fn test(obj : MyChoice) { | ||
// You can pattern match on tuples and arrays. | ||
match(obj) { | ||
.MyTuple([1, var b]) => std::cout<< "The tuple int is 1\n"; | ||
.MyArray([var a, a, a]) => std::cout<< "All array elements are "<< a<< "\n"; | ||
.MyArray(var [a, b, c]) => std::cout<< "Some other array\n"; | ||
.MyScalar(> 10) => std::cout<< "A scalar greater than 10\n"; | ||
.MyScalar(var x) => std::cout<< "The scalar is "<< x<< "\n"; | ||
_ => std::cout<< "Something else\n"; | ||
}; | ||
} | ||
|
||
fn main() -> int { | ||
test(.MyTuple{1, "Hello choice tuple"}); | ||
test(.MyArray{10, 20, 30}); | ||
test(.MyArray{50, 50, 50}); | ||
test(.MyScalar{100}); | ||
test(.MyScalar{6}); | ||
test(.MyTuple{2, "Foo"}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#pragma feature choice new_decl_syntax | ||
#include <iostream> | ||
#include <concepts> | ||
|
||
fn even(x : std::integral auto) noexcept -> bool { | ||
return 0 == x % 2; | ||
} | ||
|
||
fn func(arg : auto) { | ||
match(arg) { | ||
5 => std::cout<< "The arg is five.\n"; | ||
10 ... 20 => std::cout<< "The arg is between 10 and 20.\n"; | ||
even => std::cout<< "The arg is even.\n"; | ||
1 || 3 || 7 || 9 => std::cout<< "The arg is special.\n"; | ||
_ => std::cout<< "The arg is not special.\n"; | ||
}; | ||
} | ||
|
||
fn main() -> int { | ||
func(5); | ||
func(13); | ||
func(32); | ||
func(7); | ||
func(21); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#pragma feature choice tuple new_decl_syntax | ||
#include <tuple> | ||
#include <iostream> | ||
|
||
struct obj_t { | ||
var a : (int, int); // A 2-tuple. | ||
var b : (std::string, double, int); // A 3-tuple. | ||
} | ||
|
||
fn func(arg : auto) { | ||
match(arg) { | ||
// Destructure the a member and test if it's (10, 20) | ||
[a: (10, 20)] => std::cout<< "The 'a' member is (10, 20).\n"; | ||
|
||
// Check the range of the double tuple element. | ||
[_, [_, 1...100, _] ] => std::cout<< "The double is between 1 and 100\n"; | ||
|
||
// a's 2nd element matches b's third element. | ||
[ [_, var x], [_, _, x] ] => std::cout<< "A magical coincidence.\n"; | ||
|
||
// Everything else goes here. | ||
_ => std::cout<< "A rubbish struct.\n"; | ||
}; | ||
} | ||
|
||
fn main() -> int { | ||
func(obj_t { { 10, 20 }, { "Hello", 3, 4 } }); | ||
func(obj_t { { 2, 4 }, { "Hello", 3, 4 } }); | ||
func(obj_t { { 2, 5 }, { "Hello", 19.0, 4 } }); | ||
func(obj_t { { 2, 5 }, { "Hello", 101.0, 5 } }); | ||
func(obj_t { { 2, 5 }, { "Hello", 101.0, 6 } }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#pragma feature choice | ||
#include <type_traits> | ||
#include <iostream> | ||
|
||
choice Foo { | ||
x(int), | ||
y(double), | ||
z(const char*), | ||
}; | ||
|
||
template<typename T> requires (T~is_enum) | ||
const char* enum_to_string(T e) noexcept { | ||
return T~enum_values == e ...? | ||
T~enum_names : | ||
"unknown enum of type {}".format(T~string); | ||
} | ||
|
||
int main() { | ||
// "alternatives" is an enum member of Foo. | ||
static_assert(Foo::alternatives~is_enum); | ||
|
||
// It has enumerators for each choice alternative. | ||
std::cout<< "alternatives enumerators:\n"; | ||
std::cout<< " {} = {}\n".format(Foo::alternatives~enum_names, | ||
Foo::alternatives~enum_values~to_underlying) ...; | ||
|
||
// Naming a choice alternative gives you back an enumerator. | ||
static_assert(Foo::alternatives == decltype(Foo::x)); | ||
|
||
// Foo::y is an enumerator of type Foo::alternatives. But it's also | ||
// how you construct choice types! The enumerator has been overloaded to | ||
// work as an initializer. | ||
|
||
// Foo::y is type Foo::alternatives. | ||
static_assert(Foo::alternatives == decltype(Foo::y)); | ||
|
||
// Foo::y() is an initializer, so Foo::y() is type Foo. | ||
static_assert(Foo == decltype(Foo::y())); | ||
|
||
// Initialize a Foo object. | ||
Foo obj = .y(3.14); | ||
|
||
// .active is an implicit data member set to the active alternative. | ||
// The type is Foo::alternatives. | ||
std::cout<< "obj.active = "<< enum_to_string(obj.active)<< "\n"; | ||
|
||
// Compare an enumerator with the .active member to see what's active. | ||
if(Foo::x == obj.active) | ||
std::cout<< "x is active\n"; | ||
else if(Foo::y == obj.active) | ||
std::cout<< "y is active\n"; | ||
else if(Foo::z == obj.active) | ||
std::cout<< "z is active\n"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#pragma feature choice | ||
#include <type_traits> | ||
|
||
struct A { | ||
// Declare a non-trivial destructor to keep things interesting. | ||
~A() { } | ||
|
||
// Declare potentially-throwing copy constructor. | ||
A(const A&) noexcept(false); | ||
|
||
// We must define a non-throwing move constructor. | ||
A(A&&) noexcept; | ||
|
||
// Define a move assignment operator, because [class.copy.assign]/4 | ||
// prevents is generation. | ||
A& operator=(A&&) noexcept; | ||
}; | ||
|
||
choice my_choice_t { | ||
// We need a choice type with at least two alternatives to get into | ||
// a code path that calls copy constructors during choice assignment. | ||
value(A), | ||
value2(int), | ||
}; | ||
|
||
// The choice type is *not* copy-assignable, because that could leave it in | ||
// a valueles-by-exception state. | ||
static_assert(!std::is_copy_assignable_v<my_choice_t>); | ||
|
||
// However, it *is* move-assignable. | ||
static_assert(std::is_move_assignable_v<my_choice_t>); | ||
|
||
void copy_assign(my_choice_t& lhs, const my_choice_t& rhs) { | ||
// Simulate copy-assignment in 2 steps: | ||
// 1. Copy-construct the rhs. | ||
// 2. Move-assign that temporary into the lhs. | ||
// lhs = rhs; // ERROR! | ||
lhs = my_choice_t(rhs); // OK! | ||
} |
Oops, something went wrong.