### bogdan_ogorodniy's blog

By bogdan_ogorodniy, history, 6 weeks ago, translation, I wondered for a long time how to make different user-operators. For example write this x minEqual y instead of x = min(x, y)

So recently I've done this, and decided to share it with you.

#include <bits/stdc++.h>

using namespace std;
struct mineq_operator
{
int tempVal=1000;
inline mineq_operator operator<<(int& x)
{
this->tempVal = x;
return *this;
} inline mineq_operator operator>>(int& x)
{
x = min(x, tempVal);
return *this;
}
};
mineq_operator __me;
inline void operator<<(int& x, mineq_operator& b)
{
b.tempVal = x;
}
#define minEqual <<__me;__me>>
signed main()
{
int x = 3, y = 2;
y minEqual x;
cout << x << ' ' << y << endl;
}


For use it like x = min(x, y); just write y minEqual x;

And this in compressed format:

#include <bits/stdc++.h>

using namespace std;
struct mineq_operator {int tempVal=1000;inline mineq_operator operator<<(int& x) {this->tempVal = x;return *this;}inline mineq_operator operator>>(int& x) {x = min(x, tempVal);return *this;}};
mineq_operator __me; inline void operator<<(int& x, mineq_operator& b) {b.tempVal = x;}
#define minEqual <<__me;__me>>
signed main() {
int x = 3, y = 2;
y minEqual x;
cout << x << ' ' << y << endl;
} Comments (9)
 » wow thx, it is very useful!!
 » Auto comment: topic has been translated by bogdan_ogorodniy (original revision, translated revision, compare)
 » very cool!
 » Some time ago I wrote /* /in/ shortcut + 2 in [1,2,3] + "ab" in "bacaba" + 'w' in "cow" + "key" in {"key": 123}_json + 42 in map, set (+unordered) */ namespace ultra { template struct in_prefix_t { T const *pvalue = nullptr; explicit inline in_prefix_t(T const *pvalue) : pvalue(pvalue) { } }; struct in_helper_t { }; } // namespace ultra ultra::in_helper_t in; template inline ultra::in_prefix_t operator / (T const& value, ultra::in_helper_t) { return ultra::in_prefix_t(&value); } template inline bool operator / (ultra::in_prefix_t prefix, Container const& cont) { return std::find(std::begin(cont), std::end(cont), *prefix.pvalue) != std::end(cont); } template inline bool operator / (ultra::in_prefix_t prefix, std::string const& s) { return s.find(*prefix.pvalue) != string::npos; } inline bool operator / (ultra::in_prefix_t prefix, std::string const& s) { return s.find(*prefix.pvalue) != string::npos; } template inline bool operator / (ultra::in_prefix_t prefix, std::map const& m) { return m.find(*prefix.pvalue) != m.end(); } template inline bool operator / (ultra::in_prefix_t prefix, std::set const& s) { return s.find(*prefix.pvalue) != s.end(); } template inline bool operator / (ultra::in_prefix_t prefix, std::unordered_map const& m) { return m.find(*prefix.pvalue) != m.end(); } template inline bool operator / (ultra::in_prefix_t prefix, std::unordered_set const& s) { return s.find(*prefix.pvalue) != s.end(); } template inline bool operator / (ultra::in_prefix_t prefix, json s) { return s.count(*prefix.pvalue) != 0; } Pretty useless although :)
 » Interesting idea, execution leaves much to be desired.1) You shouldn't put int& as the parameter type for operator>>, int will do just fine. In fact, you'll get compilation errors if you try to use an r-value as an operand, as in the example below.2) After replacing int& with int, what does this print? int computeSomething() { int z = 1000; z minEqual 100; return z; } signed main() { int x = 200, y = 300; y minEqual computeSomething(); cout << x << ' ' << y << endl; } 
 » 6 weeks ago, # | ← Rev. 2 →   I made it a bit shorter (and also without bug, which ivan100sic mentioned) Codestruct X { int *t; }; X operator ^ (int &a, X x) { x.t = &a; } void operator ^ (X x, int b) { *(x.t) = min(*(x.t), b); } #define minEqual ^X()^ And this can be improved to work with any type: Codetemplate struct X { T *t; }; template void operator ^ (X x, T b) { *(x.t) = min(*(x.t), b); } struct Y { }; template X operator ^ (T &a, Y y) { X res; res.t = &a; return res; } #define minEqual ^Y()^ Actually, it is better to use operator ,, instead of operator ^ to avoid extra brackets (link)By the way, my code creates structure on each minEqual, so probably it is slower than the original version, but I am not sure. However, if you aim for speed, you shouldn't use any of these options, I think.
•  » » You should return x in the first function ;)With -O2, the compiler will even get rid of all function calls, you can try it on godbolt.org
 » I suppose that I write x minEqual f(1, 2, 3); to minimize x by a result of function call f(1, 2, 3). Obviously it 1) will not compile and 2) might lead to undefined behavior if f(int, int, int) uses minEqual operator as well.So that I just return to simpler alternative: void minimize(int& a, int b) { a = std::min(a, b); } ... minimize(x, f(1, 2, 3)); ... 
 » 6 weeks ago, # | ← Rev. 2 →   And I use normal functions like these /// I use _x_ instead of normal x to prevent from IntelliSense /// a = min(a, b) template void minimize(_A_ &_a_, const _B_ &_b_) { if (_a_ > _b_) _a_ = _b_; } /// return true if (a is minimized to b) template bool ismini(_A_ &_a_, const _B_ &_b_) { if (_a_ > _b_) { _a_ = _b_; return true; } return false; } /// a = min{b, ...} template void minimize(_A_ &_a_, const _B_ &_b_, const _V_&..._v_) { minimize(_a_, _b_); minimize(_a_, _v_...); }