Skip to content

Instantly share code, notes, and snippets.

@eruffaldi
Created Oct 12, 2020
Embed
What would you like to do?
Named Operators in C++ and Unicode
// Testedt with GCC and CLang
// Not working with ICC due to the UTF-8
// MSVC requires /utf-8 option
#include <iostream>
// from https://riptutorial.com/cplusplus/example/23817/named-operators
// modified to use < > instead of *
// modified for adding unary version
namespace named_operator {
template<class D>struct make_operator{constexpr make_operator(){}};
template<class T, char, class O> struct half_apply { T&& lhs; };
template<class Lhs, class Op>
half_apply<Lhs, '<', Op> operator<( Lhs&& lhs, make_operator<Op> ) {
return {std::forward<Lhs>(lhs)};
}
template<class Lhs, class Op, class Rhs>
auto operator>( half_apply<Lhs, '<', Op>&& lhs, Rhs&& rhs )
-> decltype( named_invoke( std::forward<Lhs>(lhs.lhs), Op{}, std::forward<Rhs>(rhs) ) )
{
return named_invoke( std::forward<Lhs>(lhs.lhs), Op{}, std::forward<Rhs>(rhs) );
}
template<class Op, class Rhs>
auto operator>( make_operator<Op> , Rhs&& rhs )
-> decltype( named_invokeL( Op{}, std::forward<Rhs>(rhs) ) )
{
return named_invokeL( Op{}, std::forward<Rhs>(rhs) );
}
}
// example
namespace my_ns {
struct range_t : named_operator::make_operator<range_t> {};
constexpr range_t α{};
std::pair<int, int> named_invoke( int a, range_t, int b ) {
return std::pair<int, int>(a,b);
}
}
namespace my_sq3 {
struct sqrt3_t : named_operator::make_operator<sqrt3_t> {};
constexpr sqrt3_t sq3{};
double named_invokeL( sqrt3_t, int b ) {
return -b;
}
}
using my_ns::α;
using my_sq3::sq3;
int main()
{
auto r = (2 <α> 3);
auto w = sq3> 3;
std::cout << "r = " << r.first << " " << r.second << std::endl;
std::cout << "w = " << w << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment