Skip to content

Instantly share code, notes, and snippets.

@jbandela
Last active December 31, 2015 20:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbandela/8042689 to your computer and use it in GitHub Desktop.
Save jbandela/8042689 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <typeinfo>
// Would go into operator_auto.hpp
namespace operator_auto {
struct operator_auto_imp {
template <class T>
auto operator=(T &&t) -> decltype(operator_auto(std::forward<T>(t))) {
return operator_auto(std::forward<T>(t));
}
};
namespace {
operator_auto_imp _auto;
}
template <class T> auto operator_auto(T &&t) -> decltype(std::forward<T>(t)) {
return std::forward<T>(t);
}
}
// End operator_auto.hpp
// Example
#define _CRT_SECURE_NO_WARNINGS // don't warn about strcpy in VS10
#include <cstring>
#include <iostream>
namespace my {
class string {
size_t len;
char *str;
string(char *buf, size_t buf_len) : len(buf_len), str(buf) {}
public:
explicit string(const char *src) : len(strlen(src)), str(new char[len + 1]) {
std::strcpy(str, src);
}
string(const string &other) : len(other.length()), str(new char[len + 1]) {
other.copy_to(str);
}
string &operator=(const string &other) {
if (this != &other) {
char *tmp = new char[other.len];
other.copy_to(tmp);
delete[] str;
str = tmp;
len = other.len;
}
return *this;
}
~string() { delete[] str; }
size_t length() const { return len; }
private:
void copy_to(char *buff) const { std::strcpy(buff, str); }
friend struct helper; // because you can't befriend a template
struct helper {
static void copy(const string &str, char *buf) { str.copy_to(buf); }
template <class T> static void copy(const T &t, char *buf) {
t.copy_to(buf);
}
static string create(char *buf, size_t len) { return string(buf, len); }
};
public:
template <class T> class concat {
const T &lhs;
const string &rhs;
bool valid;
public:
concat(const T &left, const string &right)
: lhs(left), rhs(right), valid(true) {}
~concat() { valid = false; }
size_t length() const { return lhs.length() + rhs.length(); }
void copy_to(char *dest) const {
if (!valid)
throw "Here there be dragons^H^H^H undefined behaviour";
helper::copy(lhs, dest);
helper::copy(rhs, dest + lhs.length());
}
operator string() const {
char *buf = new char[length() + 1];
copy_to(buf);
return helper::create(buf, length());
}
concat<concat<T> > operator+(const string &str) const {
return concat<concat<T> >(*this, str);
}
};
public:
concat<string> operator+(const string &str) const {
return concat<string>(*this, str);
}
friend std::ostream &operator<<(std::ostream &os, const string &str) {
return os << str.str;
}
};
}
namespace operator_auto {
template <class T> my::string operator_auto(my::string::concat<T> c) {
return c;
}
}
#include <vector>
#include <limits>
std::vector<bool> to_bits(unsigned int n) {
const int bits = std::numeric_limits<unsigned int>::digits;
std::vector<bool> ret(bits);
for (int i = 0, mask = 1; i < bits; ++i, mask *= 2)
ret[i] = (n & mask) != 0;
return ret;
}
namespace operator_auto{
bool operator_auto(std::vector<bool>::reference&& ref){
return ref;
}
}
int main() {
{
using operator_auto::_auto;
my::string a("hello"), b(" "), c("world"), d("!");
auto s = _auto = a + b + c + d;
auto a1 = _auto = a;
std::cout << s << std::endl;
}
{
using operator_auto::_auto;
bool b = _auto = to_bits(42)[3];
auto a = _auto = to_bits(42)[3];
std::cout << std::boolalpha << b << std::endl;
std::cout << std::boolalpha << a << std::endl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment