SHARE
TWEET

Initializer_List Proxy Function Test

ascend4nt Jan 9th, 2013 41 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <utility>
  5. #include <initializer_list>
  6.  
  7. // initializer_list frustrations – Solving the deep-copy issue
  8. // Author: Ascend4nt
  9. // https://ascend4nt.wordpress.com/2013/01/10/initializer_list-frustrations-solving-the-deep-copy-issue/
  10.  
  11. // A simple (incomplete) wrapper for string objects which is used to demonstrate
  12. // how initializer_lists work with objects
  13. class StringHolder{
  14. protected:
  15.     std::string myStr;
  16. public:
  17.     StringHolder() : myStr()
  18.         { std::cout << "StringHolder empty constructor" << std::endl; }
  19.     StringHolder(const char* sInit) : myStr(sInit)
  20.         { std::cout << "StringHolder(const char*) constructor, init string: " << sInit << std::endl; }
  21.     // Copy-construct
  22.     StringHolder(const StringHolder & copyFrom) : myStr(copyFrom.myStr)
  23.         { std::cout << "StringHolder (*COPY*) Constructor called, made COPY of: " << myStr << std::endl; }
  24.     // Move-construct
  25.     StringHolder(StringHolder && moveFrom) noexcept
  26.      : myStr(std::move(moveFrom.myStr))
  27.     {
  28.         // Note we already move-constructed string myStr, which has its own move constructor
  29.         std::cout << "StringHolder (*MOVE*) Constructor called, now owning: " << myStr << std::endl;
  30.     }
  31.     ~StringHolder()
  32.     { std::cout << "~StringHolder ~destructor~, string contents: " << myStr << std::endl; }
  33.    
  34.     // Copy-Assignment
  35.     StringHolder& operator=(const StringHolder& copyFrom)
  36.     {
  37.         // Make sure we are not assigning to ourself
  38.         if (this != &copyFrom)
  39.         {
  40.             /* Clear our values, release resources */
  41.             myStr.clear();
  42.             /* Copy in new values/resources */
  43.             myStr = copyFrom.myStr;
  44.  
  45.             std::cout << "StringHolder operator=(COPY) called, made COPY of: " << myStr << std::endl;
  46.         }
  47.         return *this;
  48.     }
  49.     // Move-Assignment
  50.     StringHolder& operator=(StringHolder&& moveFrom) noexcept
  51.     {
  52.         // Make sure we are not assigning to ourself
  53.         if (this != &moveFrom)
  54.         {
  55.             // Move-assign myStr (we invoke it via operator= just so we're clear on the std::move() definition
  56.             myStr.operator=(std::move(moveFrom.myStr));
  57.  
  58.             std::cout << "StringHolder operator=(MOVE) called, now owning: " << myStr << std::endl;
  59.         }
  60.         return *this;
  61.     }
  62. };
  63.  
  64.  
  65. // Proxy initializer_list functions
  66. template <typename Container, typename Iterator, typename LType>
  67. void insertInitListProxy(Container & Cnt, Iterator pos, std::initializer_list<LType> il)
  68. {
  69.     for (auto it = il.begin(); it < il.end(); ++it)
  70.     {
  71.         pos = Cnt.emplace(pos, *it);
  72.         ++pos;  // move to position *after* what was just inserted
  73.     }
  74. }
  75.  
  76. template <typename VecT, typename Iterator, typename LType>
  77. void insertInitListProxy(std::vector<VecT> & Cnt, Iterator pos, std::initializer_list<LType> il)
  78. {
  79.     // save iterator 'distance' from begin() in case a resize operation happens
  80.     auto diff = pos - Cnt.begin();
  81.     // pre-allocate space
  82.     Cnt.reserve(Cnt.size() + il.size());
  83.     // reset iterator based on any changes that occurred due to a resize
  84.     // from here on out, we don't need to worry about resizes
  85.     pos = Cnt.begin() + diff;
  86.     // construct the items in-place
  87.     for (auto it = il.begin(); it < il.end(); ++it)
  88.     {
  89.         pos = Cnt.emplace(pos, *it);
  90.         ++pos;  // move to position *after* what was just inserted
  91.     }
  92. }
  93.  
  94.  
  95. int main ()
  96. {
  97.     std::vector<StringHolder> myVec;
  98.  
  99.     // Reserve some space so no vector resizing takes place
  100.     myVec.reserve(20);
  101.  
  102.     std::cout << "---------- Pushing data on vector ----------\n" << std::endl;
  103.  
  104.     myVec.push_back("charstr");
  105.  
  106.     std::cout << "\n------ Now invoking initializer_list insertion ------\n" << std::endl;
  107.  
  108.     myVec.insert(myVec.end(), {"str1", "str2"});
  109.  
  110.     std::cout << "\n------ Now invoking initializer_list proxy ------\n" << std::endl;
  111.  
  112.     insertInitListProxy(myVec, myVec.end(), {"str3", "str4", "str5"});
  113.  
  114.     std::cout << "\n---------- Vector Destruction looming ----------\n" << std::endl;
  115.  
  116.     return 0;
  117. }
RAW Paste Data
Top