fork download
  1. #include <iostream>
  2. #include <typeinfo>
  3.  
  4. // Would go into operator_auto.hpp
  5.  
  6. namespace operator_auto {
  7. template <class T> struct operator_auto_type {
  8. using type = T;
  9. };
  10.  
  11. struct operator_auto_imp {
  12. template <class T> typename operator_auto_type<T>::type operator=(T &&t) {
  13. return std::forward<T>(t);
  14. }
  15. };
  16.  
  17. namespace {
  18. operator_auto_imp _auto;
  19. }
  20. }
  21.  
  22. // End operator_auto.hpp
  23.  
  24. // Example adapted from http://l...content-available-to-author-only...s.com/2011/02/21/inferring-too-much/ by Motti Lanzkron
  25.  
  26. #define _CRT_SECURE_NO_WARNINGS // don't warn about strcpy in VS10
  27. #include <cstring>
  28. #include <iostream>
  29.  
  30. namespace my {
  31. class string {
  32. size_t len;
  33. char *str;
  34.  
  35. string(char *buf, size_t buf_len) : len(buf_len), str(buf) {}
  36.  
  37. public:
  38. explicit string(const char *src) : len(strlen(src)), str(new char[len + 1]) {
  39. std::strcpy(str, src);
  40. }
  41.  
  42. string(const string &other) : len(other.length()), str(new char[len + 1]) {
  43. other.copy_to(str);
  44. }
  45.  
  46. string &operator=(const string &other) {
  47. if (this != &other) {
  48. char *tmp = new char[other.len];
  49. other.copy_to(tmp);
  50. delete[] str;
  51. str = tmp;
  52. len = other.len;
  53. }
  54. return *this;
  55. }
  56.  
  57. ~string() { delete[] str; }
  58.  
  59. size_t length() const { return len; }
  60.  
  61. private:
  62. void copy_to(char *buff) const { std::strcpy(buff, str); }
  63.  
  64. friend struct helper; // because you can't befriend a template
  65. struct helper {
  66. static void copy(const string &str, char *buf) { str.copy_to(buf); }
  67.  
  68. template <class T> static void copy(const T &t, char *buf) {
  69. t.copy_to(buf);
  70. }
  71.  
  72. static string create(char *buf, size_t len) { return string(buf, len); }
  73. };
  74.  
  75. public:
  76. template <class T> class concat {
  77. const T &lhs;
  78. const string &rhs;
  79. bool valid;
  80.  
  81. public:
  82. concat(const T &left, const string &right)
  83. : lhs(left), rhs(right), valid(true) {}
  84.  
  85. ~concat() { valid = false; }
  86.  
  87. size_t length() const { return lhs.length() + rhs.length(); }
  88.  
  89. void copy_to(char *dest) const {
  90. if (!valid)
  91. throw "Here there be dragons^H^H^H undefined behaviour";
  92.  
  93. helper::copy(lhs, dest);
  94. helper::copy(rhs, dest + lhs.length());
  95. }
  96.  
  97. operator string() const {
  98. char *buf = new char[length() + 1];
  99. copy_to(buf);
  100. return helper::create(buf, length());
  101. }
  102.  
  103. concat<concat<T> > operator+(const string &str) const {
  104. return concat<concat<T> >(*this, str);
  105. }
  106. };
  107.  
  108. public:
  109. concat<string> operator+(const string &str) const {
  110. return concat<string>(*this, str);
  111. }
  112.  
  113. friend std::ostream &operator<<(std::ostream &os, const string &str) {
  114. return os << str.str;
  115. }
  116. };
  117. }
  118.  
  119. namespace operator_auto {
  120. template <class T> struct operator_auto_type<my::string::concat<T> > {
  121. using type = my::string;
  122. };
  123. }
  124.  
  125. #include <vector>
  126. #include <limits>
  127. std::vector<bool> to_bits(unsigned int n) {
  128. const int bits = std::numeric_limits<unsigned int>::digits;
  129. std::vector<bool> ret(bits);
  130. for (int i = 0, mask = 1; i < bits; ++i, mask *= 2)
  131. ret[i] = (n & mask) != 0;
  132. return ret;
  133. }
  134.  
  135. namespace operator_auto {
  136. template <> struct operator_auto_type<std::vector<bool>::reference> {
  137. using type = bool;
  138. };
  139. }
  140.  
  141. void test_ref(bool &b) { std::cout << "ref\n"; }
  142. void test_ref(const bool &b) { std::cout << "c-ref\n"; }
  143. void test_ref(bool &&b) { std::cout << "rv-ref\n"; }
  144.  
  145. int main() {
  146. {
  147. using operator_auto::_auto;
  148. my::string a("hello"), b(" "), c("world"), d("!");
  149.  
  150. auto s = _auto = a + b + c + d;
  151. auto a1 = _auto = a;
  152. std::cout << s << std::endl;
  153. }
  154.  
  155. {
  156. using operator_auto::_auto;
  157. bool b = _auto = to_bits(42)[3];
  158. auto a = _auto = to_bits(42)[3];
  159. std::cout << std::boolalpha << b << std::endl;
  160. std::cout << std::boolalpha << a << std::endl;
  161.  
  162. // This should be r-value ref
  163. test_ref(_auto = to_bits(42)[3]);
  164.  
  165. // This should be ref
  166. test_ref(_auto = b);
  167. }
  168. }
  169.  
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
hello world!
true
true
rv-ref
ref