WhiZTiM

MathSet Draft...

Nov 25th, 2014
336
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.83 KB | None | 0 0
  1. /*!
  2.  *  Work in Progress....
  3.  *  (C) WhiZTiM, 25Nov, 2014
  4.  *  Based on, http://www.nairaland.com/2011411/open-source-mathematics-c-class
  5.  * RATIONALE:
  6.  *  MathSet can be instantiated with any type; and any container can be easily specialized for it as an underlying container
  7.  *  Currently, only std::vector and std::unordered_set has been explicitly specialized by the author;
  8.  *  Choosing the underlying container can be done manually(supply more arguments) or automatically based on:
  9.  *  *   For small datatypes (sizeof() less than 8 bytes) and aren't heavy to construct, we use
  10.  *      an std::vector because its CPU Cache-local and thus, extremely high perfomant.
  11.  *      With this we can store several thousands of doubles that will fit into L1 cache!! which means
  12.  *      Deletion and Searching will almost always be faster than an unordered_set!
  13.  *
  14.  *  *   For larger datatypes, with more than 8 bytes, an unordered_set is used because the container overhead
  15.  *      with respect to the data is the same (64bit Architecture) or smaller.
  16.  *
  17.  */
  18.  
  19. #include <vector>
  20. #include <algorithm>
  21. #include <type_traits>
  22. #include <unordered_set>
  23.  
  24. namespace detail
  25. {
  26.     //Compile time type_trait function
  27.     template<typename Type>
  28.     constexpr bool is_8bytes_or_less(){
  29.         return sizeof(Type) <= 8;
  30.     }
  31.    
  32.     //Blank Adaptor Class... should trigger an error if used
  33.     template<typename ValueType, typename ContainerType>
  34.     struct ContainerAdaptor {};
  35.    
  36.     //Specialization for std::vector
  37.     template<typename ValueType>
  38.     struct ContainerAdaptor<ValueType, std::vector<ValueType>>
  39.     {
  40.         using ContainerType = std::vector<ValueType>;
  41.        
  42.         bool SortLastElement(){
  43.             std::partial_sort(c.rbegin(), c.rend(), c.rbegin() + 1);
  44.         }
  45.        
  46.         bool AddElement(const ValueType& element){
  47.             if(std::binary_search(c.begin(), c.end(), element))
  48.                 return false;
  49.             c.push_back(element);
  50.             SortLastElement();
  51.             return true;
  52.         }
  53.        
  54.         void RemoveElement(const ValueType& element){
  55.             auto iter = std::find(c.begin(), c.end(), element);
  56.             if(iter != c.end()){
  57.                 c.erase(iter);
  58.                 return true;
  59.             }
  60.             return false;
  61.         }
  62.        
  63.         bool Contains(const ValueType& element){
  64.             return std::binary_search(c.begin(), c.end(), element);
  65.         }
  66.        
  67.         bool IsSuperSetOf(const ContainerType& other){
  68.             return std::includes(c.cbegin(), c.cend(), other.cbegin(), other.cend());
  69.         }
  70.        
  71.         bool IsSubSetOf(const ContainerType& other){
  72.             return std::includes(other.cbegin(), other.cend(), c.cbegin(), c.cend());
  73.         }
  74.        
  75.         void EnsureReservation(int sz){
  76.             c.reserve(sz);
  77.         }
  78.        
  79.         private:
  80.         ContainerType c;
  81.     };
  82.    
  83.     // Not yet implemented
  84.     template<typename ValueType>
  85.     struct ContainerAdaptor<std::unordered_set<ValueType>, ValueType>
  86.     {
  87.    
  88.     };
  89. }
  90.  
  91.  
  92. // The MathSet, just supply T, and the rest is generated...
  93. // ..uses std::vector if sizeof(T) <= 8 bytes, else, it uses std::unordered_set
  94. // ..uses an Adaptor class to access and operate on its underlying container, i.e
  95. // ..std::vector, std::unordered_set or what ever is supplied as second template argument
  96. template<
  97.     typename T,
  98.     typename Container_Type = typename std::conditional<
  99.                                 detail::is_8bytes_or_less<T>() and std::is_trivial<T>::value,
  100.                                 std::unordered_set<T>,
  101.                                 std::vector<T>
  102.                             >::type,
  103.     typename Container_Adaptor = typename detail::ContainerAdaptor<typename ContainerType::value_type, ContainerType>
  104.     >
  105. class MathSet : private Container_Adaptor
  106. {
  107.     public:
  108.     using ContainerType = Container_Type;
  109.     using value_type = T;
  110.    
  111.     MathSet(const std::string& name = std::string());
  112.    
  113.     bool AddElement(const T& element);
  114.     bool RemoveElement(const T& element);
  115.     bool EnsureReservation(int elements);
  116.    
  117.     bool IsEmptySet() const;
  118.     bool Contains(const T& element) const;
  119.     bool IsSubSetOf(const MathSet<T>& mathset) const;
  120.     bool IsSuperSetOf(const MathSet<T>& mathset) const;
  121.    
  122.     static MathSet<T> Difference(const MathSet<T>& first, const MathSet<T>& second);
  123.     static MathSet<T> Union(const MathSet<T>& first, const MathSet<T>& second);
  124.     static MathSet<T> Intersection(const MathSet<T>& first, const MathSet<T>& second);
  125.    
  126.     private:
  127.     ContainerType container;
  128.     std::string name_;
  129. };
  130.  
  131. template<typename T>
  132. class MathSetCollection
  133. {
  134.  
  135. };
  136. //*/
  137.  
  138. //! Intended Usage format
  139. void example()
  140. {
  141.     MathSet<int> s1();
  142.     s1.AddElement(9);
  143.     s1.AddElement(3);
  144.     s1.AddElement(5);
  145.     s1.RemoveElement(3);
  146.    
  147.     MathSet<int> s2();
  148.     s2.AddElement(5);
  149.     s2.AddElement(7);
  150.     s2.AddElement(8);
  151.     s2.AddElement(9);
  152.    
  153.     MathsSet<int> s3 = MathSet<int>::Union(s1, s2);         // 3, 5, 6, 7, 8, 9
  154.     MathsSet<int> s4 = MathSet<int>::Difference(s1, s2);    // 3, 6, 7, 8
  155.     MathsSet<int> s5 = MathSet<int>::Intersection(s1, s2);  // 5, 9
  156.    
  157.     bool b1 = s1.IsSuperSetOf(s5)   // true
  158.     bool b2 = s2.IsSuperSetOf(s5)   // true
  159.     bool b3 = s3.IsSuperSetOf(s1)   // true
  160.     bool b4 = s3.IsSubSetOf(s2)     // false
  161.     bool b5 = s4.IsSubsetOf(s3)     // true
  162.    
  163.     //....etc
  164. }
Add Comment
Please, Sign In to add comment