fork download
  1. #include <iostream>
  2. #include <iterator>
  3. #include <algorithm>
  4. #include <vector>
  5. #include <tr1/memory>
  6. #include <tr1/functional>
  7.  
  8.  
  9. struct Data
  10. {
  11. int A, B, C;
  12. };
  13.  
  14.  
  15. class DataSpecification
  16. {
  17. public:
  18. virtual bool IsSatisfiedBy(Data&) const = 0;
  19. };
  20.  
  21. typedef std::tr1::shared_ptr<DataSpecification> DataSpecificationPtr;
  22.  
  23.  
  24. class Validator
  25. {
  26. public:
  27. void AddSpecification(DataSpecificationPtr spec)
  28. {
  29. specs_.push_back(spec);
  30. }
  31.  
  32. bool IsValid(Data& data)
  33. {
  34. using std::tr1::placeholders::_1;
  35. return specs_.end() != std::find_if(specs_.begin(), specs_.end(),
  36. std::tr1::bind(&DataSpecification::IsSatisfiedBy, _1, data));
  37. }
  38. private:
  39. std::vector<DataSpecificationPtr> specs_;
  40. };
  41.  
  42.  
  43. class DataLoader
  44. {
  45. public:
  46. DataLoader(bool breakIfInvalid, const Validator& validator) :
  47. validator_(validator),
  48. breakIfInvalid_(breakIfInvalid),
  49. a(0), b(1), c(2)
  50. {
  51.  
  52. }
  53.  
  54. template<typename OutIter>
  55. void Load(OutIter out)
  56. {
  57. while(HasNext())
  58. {
  59. Data data = LoadNext();
  60. if (!validator_.IsValid(data))
  61. {
  62. if (breakIfInvalid_)
  63. break;
  64. else
  65. continue;
  66. }
  67. out++ = data;
  68. }
  69. }
  70.  
  71. private:
  72.  
  73. bool HasNext()
  74. {
  75. return a < 10;
  76. }
  77.  
  78. Data LoadNext()
  79. {
  80. Data d;
  81. d.A = a++;
  82. d.B = b++;
  83. d.C = c++;
  84. return d;
  85. }
  86.  
  87. Validator validator_;
  88. bool breakIfInvalid_;
  89. int a, b, c;
  90. };
  91.  
  92.  
  93. class AGreaterMin : public DataSpecification
  94. {
  95. public:
  96. AGreaterMin(int minA) : min_(minA){}
  97.  
  98. bool IsSatisfiedBy(Data& data) const
  99. {
  100. return data.A > min_;
  101. }
  102. int min_;
  103. };
  104.  
  105. class BGreaterMin : public DataSpecification
  106. {
  107. public:
  108. BGreaterMin(int minB) : min_(minB){}
  109.  
  110. bool IsSatisfiedBy(Data& data) const
  111. {
  112. return data.B > min_;
  113. }
  114. int min_;
  115. };
  116.  
  117.  
  118. template<typename DataContainer>
  119. void PrintData(const DataContainer& c)
  120. {
  121. typedef typename DataContainer::const_iterator Iter;
  122. for (Iter it = c.begin(), end = c.end(); it != end; ++it)
  123. std::cout << it->A << " " << it->B << " " << it->C << "\n";
  124. }
  125. int main()
  126. {
  127. std::vector<Data> data;
  128. Validator v;
  129. v.AddSpecification(DataSpecificationPtr(new AGreaterMin(5)));
  130. v.AddSpecification(DataSpecificationPtr(new BGreaterMin(7)));
  131.  
  132.  
  133. DataLoader loader1(false, v);
  134. loader1.Load(std::back_inserter(data));
  135. PrintData(data);
  136.  
  137. data.clear();
  138. std::cout << "Break if invalid:\n";
  139. DataLoader loader2(true, v);
  140. loader2.Load(std::back_inserter(data));
  141. PrintData(data);
  142. }
Success #stdin #stdout 0s 2864KB
stdin
Standard input is empty
stdout
6 7 8
7 8 9
8 9 10
9 10 11
Break if invalid: