pelib  2.0.0
include/pelib/Set.hpp
Go to the documentation of this file.
00001 /*
00002  Copyright 2015 Nicolas Melot
00003 
00004  This file is part of Pelib.
00005 
00006  Pelib is free software: you can redistribute it and/or modify
00007  it under the terms of the GNU General Public License as published by
00008  the Free Software Foundation, either version 3 of the License, or
00009  (at your option) any later version.
00010 
00011  Pelib is distributed in the hope that it will be useful,
00012  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  GNU General Public License for more details.
00015 
00016  You should have received a copy of the GNU General Public License
00017  along with Pelib. If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 
00021 #include <iostream>
00022 #include <cstdlib>
00023 #include <fstream>
00024 #include <sstream>
00025 #include <string>
00026 #include <boost/regex.hpp>
00027 #include <iomanip>
00028 #include <set>
00029 
00030 #include <pelib/AlgebraData.hpp>
00031 #include <pelib/PelibException.hpp>
00032 
00033 #ifndef PELIB_SET
00034 #define PELIB_SET
00035 
00036 namespace pelib
00037 {
00039         template <class Value, class Key = size_t> 
00040         class Set: public AlgebraData
00041         {
00042                 public:
00044                         typedef std::set<Value> SetType;
00045                         typedef std::map<Key, SetType> SetOfSetsType;
00046 
00048                         Set(const std::string name, const SetType values) : AlgebraData(name)
00049                         {
00050                                 oneSet = 1;
00051                                 if(std::string(typeid(Key).name()).compare(std::string(typeid(size_t).name())) == 0)
00052                                 {
00053                                         this->values.insert(std::pair<size_t, SetType>(1, values)); 
00054                                 }
00055                                 else
00056                                 {
00057                                         throw PelibException(std::string("Trying to build a Set of one subset with an invalid subset key (got key type \"") + typeid(Key).name() + "\", expected \"" + typeid(size_t).name() + "\".");
00058                                 }
00059                         }
00060 
00062                         Set(const std::string name, const Key &key, const SetType values) : AlgebraData(name)
00063                         {
00064                                 oneSet = 0;
00065                                 this->values.insert(std::pair<Key, SetType>(key, values)); 
00066                         }
00067 
00069                         Set(const std::string name, const SetOfSetsType values) : AlgebraData(name), values(values)
00070                         {
00071                                 oneSet = 0;
00072                                 // Do nothing
00073                         }
00074 
00076                         Set(const Set<Value, Key>* set): AlgebraData(set->getName()), values(set->getSubsets())
00077                         {
00078                                 oneSet = set->oneSet;
00079                         }
00080 
00082                         virtual
00083                         Set*
00084                         clone() const
00085                         {
00086                                 return new Set<Value, Key>(this);
00087                         }
00088 
00090                         virtual
00091                         const SetType&
00092                         getValues() const
00093                         {
00094                                 if(values.size() == 1)
00095                                 {
00096                                         return values.begin()->second;
00097                                 }
00098                                 else
00099                                 {
00100                                         throw PelibException("Using exists method on Set of several sets where the method is valid on of there is only one subset.");
00101                                 }
00102                         }
00103 
00105                         virtual
00106                         bool
00107                         exists(Value elem) const
00108                         {
00109                                 if(values.size() == 1)
00110                                 {
00111                                         return getValues().find(elem) != getValues().end();
00112                                 }
00113                                 else
00114                                 {
00115                                         throw PelibException("Using exists method on Set of several sets where the method is valid on of there is only one subset.");
00116                                 }
00117                         }
00118 
00120                         virtual
00121                         size_t
00122                         getSize() const
00123                         {
00124                                 return values.size();
00125                         }
00126 
00127                         const SetOfSetsType&
00128                         getSubsets() const
00129                         {
00130                                 return values;
00131                         }
00132                         
00133                         void
00134                         merge(const AlgebraData *ptr)
00135                         {
00136                                 // Only allow merging if both this and ptr are of same name and type
00137                                 if(ptr->getName().compare(this->getName()) == 0 && std::string(typeid(*ptr).name()).compare(typeid(Set<Value, Key>).name()) == 0)
00138                                 {
00139                                         Set<Value, Key> *set = (Set<Value, Key>*)ptr;
00140                                         oneSet = 0;
00141                                         for(typename SetOfSetsType::iterator i = set->values.begin(); i != set->values.end(); i++)
00142                                         {
00143                                                 if(this->values.find(i->first) != this->values.end())
00144                                                 {
00145                                                         this->values.erase(this->values.find(i->first));
00146                                                 }
00147                                                 // Add the new row in this matrix
00148                                                 this->values.insert(std::pair<Key, SetType>(i->first, i->second));
00149                                         }
00150                                 }
00151                                 else
00152                                 {
00153                                         throw PelibException(std::string("Cannot merge data \"") + ptr->getName() + "\" with " + typeid(Value).name() + " set of name \"" + this->getName() + "\".");
00154                                 }
00155                         }
00156 
00158                         bool
00159                         isOneSet() const
00160                         {
00161                                 return oneSet;
00162                         }
00163 
00164                 protected:
00166                         SetOfSetsType values;
00167                         bool oneSet;
00168                 private:                
00169         };
00170 }
00171 
00172 #endif