Skip to content

Instantly share code, notes, and snippets.

@dreum
Last active June 3, 2022 08:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dreum/3feec54268b6433fcaf514973d7b2b59 to your computer and use it in GitHub Desktop.
Save dreum/3feec54268b6433fcaf514973d7b2b59 to your computer and use it in GitHub Desktop.
#include <vector>
#include <iostream>
#include <numeric>
#include <string>
#include <optional>
void printStringLine(std::string s)
{
std::cout << s << '\n';
}
template<typename T>
concept Magma = requires(T a)
{
{ a + a } -> T; // a binary operator that returns the same Type
// define operator+ for your Type if you get an error here
};
template<Magma T>
std::optional<T> operator+(std::optional<T> first, std::optional<T> second)
{
if(first)
if(second)
return std::make_optional(first.value() + second.value());
else
return first;
else
return second;
}
std::string fizzBuzzOrNumber(int n)
{
// what should this function be called?
auto maybeStringWhenNMatchesDivisor = [n](int divisor, std::string s) {
return (n % divisor) == 0 ? std::make_optional(s) : std::nullopt;
};
auto maybeFizz = maybeStringWhenNMatchesDivisor(3, "Fizz");
auto maybeBuzz = maybeStringWhenNMatchesDivisor(5, "Buzz");
return (maybeFizz + maybeBuzz).value_or(std::to_string(n));
}
int main()
{
std::vector<int> nums(100);
std::iota(begin(nums),
end(nums),
1);
for(auto n : nums)
printStringLine(fizzBuzzOrNumber(n));
return 0;
}
@dreum
Copy link
Author

dreum commented Jul 25, 2019

requires compiler options: -std=c++2a -fconcepts

@bhardwajs
Copy link

Which compilers have you tested this on? I am assuming gcc. clang and/or MSVC? I can test and report.

@bhardwajs
Copy link

https://godbolt.org/z/zm5hPn clang (expermental concepts) works.

@dreum
Copy link
Author

dreum commented Sep 2, 2019

I've tested it on clang and gcc. I've not tried on MSVC.

@Sofahamster
Copy link

Sofahamster commented Jun 3, 2022

The code doesn't compile on MSVC as it is. You get the following error message:
Error C7593: a return type requirement shall not be a trailing return type '-> T'. Consider using '-> std::convertible_to' instead.

If the line:
{ a + a } -> T
is changed to (as the error message suggests):
{ a + a } -> std::convertible_to

It works fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment