Advertisement
Guest User

Jack Whitehead

a guest
Nov 8th, 2009
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.88 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. struct X
  5. {
  6.     X() : id(instances++)
  7.     {
  8.         std::cout << "X" << id << ": construct\n";
  9.     }
  10.  
  11.     X(std::vector<int>) : id(instances++)
  12.     {
  13.         std::cout << "X" << id << ": construct (with vector)\n";
  14.     }
  15.    
  16.     X(X const& rhs) : id(instances++)
  17.     {
  18.         std::cout << "X" << id << ": <- " << "X" << rhs.id << ": **copy**\n";
  19.         ++copies;
  20.     }
  21.  
  22.     // This particular test doesn't exercise assignment, but for
  23.     // completeness:
  24.     X& operator=(X const& rhs)
  25.     {
  26.         std::cout << "X" << id << ": <- " << "X" << rhs.id << ": assign\n";
  27.     }
  28.    
  29.     ~X() { std::cout << "X" << id << ": destroy\n"; }
  30.  
  31.     unsigned id;
  32.    
  33.     static unsigned copies;
  34.     static unsigned instances;
  35. };
  36.  
  37. unsigned X::copies = 0;
  38. unsigned X::instances = 0;
  39.  
  40. #define CHECK_COPIES( stmt, min, max, comment )                         \
  41. {                                                                       \
  42.     unsigned const old_copies = X::copies;                              \
  43.                                                                         \
  44.     std::cout << "\n" comment "\n" #stmt "\n===========\n";             \
  45.     {                                                                   \
  46.         stmt;                                                           \
  47.     }                                                                   \
  48.     unsigned const n = X::copies - old_copies;                          \
  49.     if (n > max)                                                        \
  50.         std::cout << "*** max is too low or compiler is buggy ***\n";   \
  51.     if (n < min)                                                        \
  52.         std::cout << "*** min is too high or compiler is buggy ***\n";  \
  53.                                                                         \
  54.     std::cout << "-----------\n"                                        \
  55.               << n << "/" << max                                        \
  56.               << " possible copies made\n"                              \
  57.               << max - n << "/" << max - min                            \
  58.               << " possible elisions performed\n\n";                    \
  59.                                                                         \
  60.     if (n > min)                                                        \
  61.         std::cout << "*** " << n - min                                  \
  62.                   << " possible elisions missed! ***\n";                \
  63. }
  64.  
  65. struct trace
  66. {
  67.     trace(char const* name)
  68.         : name(name)
  69.     {
  70.         std::cout << "->: " << name << "\n";
  71.     }
  72.    
  73.     ~trace()
  74.     {
  75.         std::cout << "<-: " << name << "\n";
  76.     }
  77.    
  78.     char const* name;
  79. };
  80.  
  81. std::vector<int> vector()
  82. {
  83.     std::vector<int> ret;
  84.     return ret;
  85. }
  86.  
  87. void sink(X a)
  88. {
  89.     trace t("sink");
  90. }
  91.  
  92. X nrvo_source()
  93. {
  94.     trace t("nrvo_source");
  95.     X a;
  96.     return a;
  97. }
  98.  
  99. X urvo_source()
  100. {
  101.     trace t("urvo_source");
  102.     return X();
  103. }
  104.  
  105. X nrvo_source_vector()
  106. {
  107.     trace t("nrvo_source_vector");
  108.     X a( vector() );
  109.     return a;
  110. }
  111.  
  112. X urvo_source_vector()
  113. {
  114.     trace t("urvo_source_vector");
  115.     return X( vector() );
  116. }
  117.  
  118. X identity(X a)
  119. {
  120.     trace t("identity");
  121.     return a;
  122. }
  123.  
  124. X lvalue_;
  125. X& lvalue()
  126. {
  127.     return lvalue_;
  128. }
  129. typedef X rvalue;
  130.  
  131. int main()
  132. {
  133.     // Double parens prevent "most vexing parse"
  134.     CHECK_COPIES( X a(( lvalue() )), 1, 1, "Direct initialization from lvalue");
  135.     CHECK_COPIES( X a(( rvalue() )), 0, 1, "Direct initialization from rvalue");
  136.     CHECK_COPIES( X a(( rvalue(vector()) )), 0, 1, "Direct initialization from rvalue, constructed with vector");
  137.    
  138.     CHECK_COPIES( X a = lvalue(), 1, 1, "Copy initialization from lvalue" );
  139.     CHECK_COPIES( X a = rvalue(), 0, 1, "Copy initialization from rvalue" );
  140.     CHECK_COPIES( X a = rvalue(vector()), 0, 1, "Copy initialization from rvalue, constructed with vector" );
  141.    
  142.     CHECK_COPIES( sink( lvalue() ), 1, 1, "Pass lvalue by value" );
  143.     CHECK_COPIES( sink( rvalue() ), 0, 1, "Pass rvalue by value" );
  144.     CHECK_COPIES( sink( rvalue(vector()) ), 0, 1, "Pass rvalue by value, constructed with vector" );
  145.    
  146.     CHECK_COPIES( nrvo_source(), 0, 1, "Named return value optimization (NRVO)" );
  147.     CHECK_COPIES( nrvo_source_vector(), 0, 1, "Named return value optimization (NRVO), constructed with vector" );
  148.    
  149.     CHECK_COPIES( urvo_source(), 0, 1, "Unnamed return value optimization (URVO)" );
  150.     CHECK_COPIES( urvo_source_vector(), 0, 1, "Unnamed return value optimization (URVO), constructed with vector" );
  151.    
  152.     // Just to prove these things compose properly
  153.     CHECK_COPIES( X a(urvo_source()), 0, 2, "Return value used as ctor arg" );
  154.    
  155.     // Expect to miss one possible elision here
  156.     CHECK_COPIES( identity( rvalue() ), 0, 2, "Return rvalue passed by value" );
  157. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement