00001 #include "BankSelection.h"
00002 #include <iostream>
00003 #include <algorithm>
00004 #include <functional>
00005
00006 namespace {
00007 bool unary_iwcc(const BankSelection::SourceID& s)
00008 {return s.isWildCardChannel();}
00009
00010 struct functor_match {
00011 functor_match(const BankSelection::SourceID& sid)
00012 : fS(sid) {}
00013 bool operator() (const BankSelection::SourceID& s2) const
00014 { return fS.matches(s2); }
00015 const BankSelection::SourceID& fS;
00016 };
00017
00018 struct functor_equals {
00019 functor_equals(const BankSelection::SourceID& sid)
00020 : fS(sid) {}
00021 bool operator() (const BankSelection::SourceID& s2) const
00022 {return fS == s2;}
00023 const BankSelection::SourceID& fS;
00024 };
00025 };
00026
00027
00028
00029 BankSelection::BankSelection(bool match_all)
00030 : fWildCards(match_all ? 1 : 0)
00031 {}
00032
00033
00034
00035 BankSelection::BankSelection(const SourceList_t& list)
00036 {
00037 this->MatchOnly(list);
00038 }
00039
00040
00041 BankSelection::BankSelection(const SourceID& sid)
00042 {
00043 this->MatchOnly(sid);
00044 }
00045
00046
00047
00048 BankSelection::~BankSelection()
00049 {}
00050
00051
00052
00053 bool BankSelection::ListMatch(const SourceID& sid,
00054 const SourceList_t& list) const
00055 {
00056 functor_match match(sid);
00057 if (find_if(list.begin(), list.end(), match) != list.end()) return true;
00058 return false;
00059 }
00060
00061
00062
00063 BankSelection& BankSelection::MatchAll()
00064 {
00065 fMatches.clear();
00066 SourceList_t tmp(1);
00067 fWildCards.swap(tmp);
00068 return *this;
00069 }
00070
00071
00072
00073 BankSelection& BankSelection::MatchNone()
00074 {
00075 fMatches.clear();
00076 fWildCards.clear();
00077 return *this;
00078 }
00079
00080
00081
00082 BankSelection& BankSelection::MatchOnly(const SourceList_t& list)
00083 {
00084 int n_wc = std::count_if(list.begin(), list.end(), unary_iwcc);
00085 fWildCards.reserve(n_wc);
00086 fMatches.reserve(list.size() - n_wc);
00087
00088 return this->MatchNone().Add(list);
00089
00090 }
00091
00092
00093
00094 BankSelection& BankSelection::MatchOnly(const SourceID& sid)
00095 {
00096 return this->MatchNone().Add(sid);
00097 }
00098
00099
00100 BankSelection& BankSelection::Add(const SourceList_t& list)
00101 {
00102 for (citer it = list.begin(); it != list.end(); ++it){
00103 this->Add(*it);
00104 }
00105 return *this;
00106 }
00107
00108
00109
00110 BankSelection& BankSelection::Add(const SourceID& sid)
00111 {
00112 if (unary_iwcc(sid)){
00113 fWildCards.push_back(sid);
00114 } else {
00115 fMatches.push_back(sid);
00116 }
00117
00118 return *this;
00119 }
00120
00121
00122
00123 void BankSelection::SortUnique(SourceList_t& list)
00124 {
00125 std::sort(list.begin(), list.end());
00126 iter dupes = std::unique(list.begin(), list.end());
00127 list.erase(dupes, list.end());
00128 }
00129
00130
00131
00132 BankSelection& BankSelection::Compact()
00133 {
00134 SortUnique(fWildCards);
00135 SortUnique(fMatches);
00136 return *this;
00137 }
00138
00139
00140
00141 BankSelection::iter_pair BankSelection::ImpRemove(const SourceList_t& list)
00142 {
00143
00144
00145 this->Compact();
00146 iter_pair back;
00147 back.wildcard = fWildCards.end();
00148 back.match = fMatches.end();
00149 for (citer it = list.begin(); it != list.end() ; ++it) {
00150 if ( unary_iwcc(*it) ){
00151 back.wildcard = std::remove(fWildCards.begin(), back.wildcard, (*it));
00152 } else {
00153 back.match = std::remove(fMatches.begin(), back.match, (*it));
00154 }
00155 }
00156 return back;
00157 }
00158
00159
00160
00161 BankSelection& BankSelection::Remove(const SourceList_t& list,
00162 SourceList_t& removed)
00163 {
00164 const iter_pair back = ImpRemove(list);
00165
00166
00167
00168 SourceList_t tmp;
00169 std::copy(back.wildcard, fWildCards.end(), tmp.end());
00170 std::copy(back.match, fMatches.end(), tmp.end());
00171 removed.swap(tmp);
00172
00173 fWildCards.erase(back.wildcard, fWildCards.end());
00174 fMatches.erase(back.match, fMatches.end());
00175 return *this;
00176 }
00177
00178
00179
00180 BankSelection& BankSelection::Remove(const SourceList_t& list)
00181 {
00182 iter_pair back = ImpRemove(list);
00183 fWildCards.erase(back.wildcard, fWildCards.end());
00184 fMatches.erase(back.match, fMatches.end());
00185 return *this;
00186 }
00187
00188
00189 BankSelection& BankSelection::Remove(const SourceID& sid)
00190 {
00191 return this->Remove(SourceList_t(1, sid));
00192 }