22 ก.ย. 2557

std::vector splice ด้วย initialize_list กับ parameter pack

// testfunc.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

enum class Operation {
 DELETE, INSERT, EQUAL
};


class Diff
{
public:
 Diff()
 {

 }

 Diff(Operation oper, std::string & str)
 {
  operation = oper;
  text = str;
 }

 inline bool operator==(Diff & rhs)
 {
  return rhs.operation == operation && rhs.text == text;
 }

 Operation operation;
 std::string text;
};

template<class T>
std::vector<T> * SpliceIL(std::vector<T> * input, int start, int count, std::initializer_list<T> objects = {})
{
 std::vector<T> * delRange = new std::vector<T>(input->begin() + start, input->begin() + start + count);
 while (count > 0)
 {
  input->erase(input->begin() + start);
  count--;
 }
 for (auto i : objects)
 {
  input->insert(input->begin() + start++, i);
 }

 return delRange;
}

template<class T,typename... Args>
std::vector<T> * SplicePP(std::vector<T> * input, int start, int count, Args...objects)
{
 std::vector<T> * delRange = new std::vector<T>(input->begin() + start, input->begin() + start + count);
 std::vector<T> newVec = { objects... };
 while (count > 0)
 {
  input->erase(input->begin() + start);
  count--;
 }
 for (auto i : newVec)
 {
  input->insert(input->begin() + start++, i);
 }

 return delRange;
}

int _tmain(int argc, _TCHAR* argv[])
{
 std::vector<Diff*> * r1 = new std::vector<Diff*>();
 r1->push_back(new Diff(Operation::EQUAL,std::string("1")));
 r1->push_back(new Diff(Operation::EQUAL, std::string("2")));
 r1->push_back(new Diff(Operation::EQUAL, std::string("3")));
 r1->push_back(new Diff(Operation::EQUAL, std::string("4")));
 r1->push_back(new Diff(Operation::EQUAL, std::string("5")));
 r1->push_back(new Diff(Operation::EQUAL, std::string("6")));
 r1->push_back(new Diff(Operation::EQUAL, std::string("7")));
 r1->push_back(new Diff(Operation::EQUAL, std::string("8")));

 std::vector<Diff*> * r2 = SpliceIL<Diff*>(r1, 1, 2, 
        { new Diff(Operation::EQUAL, std::string("9")), 
         new Diff(Operation::EQUAL, std::string("10")) 
        } ); //!--pass
 std::vector<Diff*> * r4 = SpliceIL<Diff*>(r1, 1, 2, {}); //!--pass
 std::vector<Diff*> * r5 = SpliceIL<Diff*>(r1, 1, 2); //!--pass

 std::vector<Diff*> * r3 = SplicePP<Diff*, Diff*>(r1, 1, 2, 
        new Diff(Operation::EQUAL, std::string("12")), 
        new Diff(Operation::EQUAL, std::string("13")));
 std::vector<Diff*> * r6 = SplicePP<Diff*, Diff*>(r1, 1, 2, nullptr); 
 std::vector<Diff*> * r6 = SplicePP<Diff*, Diff*>(r1, 1, 2); //!--error
 return 0;
}