Created
October 12, 2020 04:19
-
-
Save eruffaldi/3bcdccc6c64f8c69ee3da8838c9f27e0 to your computer and use it in GitHub Desktop.
Named Operators in C++ and Unicode
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
// 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