Skip to content

Instantly share code, notes, and snippets.

@xaliphostes
Created September 27, 2024 05:04
Show Gist options
  • Save xaliphostes/eb76d3b9bd619a2648496db1dbf4f749 to your computer and use it in GitHub Desktop.
Save xaliphostes/eb76d3b9bd619a2648496db1dbf4f749 to your computer and use it in GitHub Desktop.
C++ functions chaining using the operator overloading
/**
* Show how to chain functions using the overloaded operator |
* Excerpt from ?? (don't remember)
*/
#include <list>
#include <iostream>
#include <stdlib.h>
using namespace std;
#define foreach(item,cont) for (typeof(cont.begin()) item = cont.begin(); item != cont.end(); item++)
template<typename T>
class list_slice_head {
private:
T &head;
list<T> &tail;
public:
list_slice_head(T &h, list<T> &t) : head(h), tail(t) { }
list_slice_head<T> &operator=(const list<T> &o) {
tail = o;
head = tail.front();
tail.pop_front();
return *this;
}
};
template<typename T>
list_slice_head<T> operator,(T &h, list<T> &t) {
return list_slice_head<T>(h, t);
}
template<typename T>
class list_slice_tail {
private:
list<T> &head;
T &tail;
public:
list_slice_tail(list<T> &h, T &t) : head(h), tail(t) { }
list_slice_tail<T> &operator=(const list<T> &o) {
head = o;
tail = head.back();
head.pop_back();
return *this;
}
};
template<typename T>
list_slice_tail<T> operator,(list<T> &h, T &t) {
return list_slice_tail<T>(h, t);
}
template<typename T, typename F>
list<T> operator | (const list<T> &l, F fn) {
list<T> r;
foreach(i, l) {
T x(*i);
if (fn(x)) {
r.push_back(x);
}
}
return r;
}
template<typename T>
list<T> operator<(const list<T> &l, const T &x) {
return l | bind2nd(less<T>(), x);
}
template<typename T>
list<T> operator>=(const list<T> &l, const T &x) {
return l | bind2nd(greater_equal<T>(), x);
}
template<typename T>
list<T> operator+(const list<T> &l, const T &x) {
list<T> r = l;
r.push_back(x);
return r;
}
template<typename T>
list<T> operator+(const list<T> &l, const list<T> &t) {
list<T> r = l;
r.insert(r.end(), t.begin(), t.end());
return r;
}
template<typename T>
list<T> qsortlist(const list<T> &l)
{
if (l.empty())
return l;
T pivot;
list<T> tail;
(pivot, tail) = l;
return qsortlist(tail < pivot) + pivot + qsortlist(tail >= pivot);
}
// ====================================================================
bool even(int x) {
return x % 2 == 0;
}
bool x2(int &x) {
x *= 2;
return true;
}
template <typename T>
void dump(const list<T> &t) {
foreach (i, t) {
cout << *i << " ";
}
cout << endl;
}
int main()
{
// ---------------------------------------------
list<int> l;
list<int> t;
int x, y;
// ---------------------------------------------
for (int i = 0; i < 10; i++) {
l.push_back(i);
}
(x, t) = l | x2;
(t, y) = t;
cout << x << " " << t.front() << "-" << t.back() << " " << y << endl;
cout << l.front() << "-" << l.back() << endl;
// ---------------------------------------------
t = l < 9;
dump(t);
// ---------------------------------------------
t = t < 7 | even | x2;
dump(t);
// ---------------------------------------------
l = list<int>();
for (int i = 0; i < 12; i++) {
l.push_back(rand() % 100);
}
dump(l);
// ---------------------------------------------
l = qsortlist(l);
dump(l);
// ---------------------------------------------
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment