libept-1.0.12/ 0000755 0000000 0000000 00000000000 12232266500 007736 5 ustar libept-1.0.12/source-tree-root 0000644 0000000 0000000 00000000115 11051022750 013067 0 ustar please do not remove this file, otb uses it to find root of the source tree libept-1.0.12/rep/ 0000755 0000000 0000000 00000000000 11051025210 010511 5 ustar libept-1.0.12/rep/snow.png 0000644 0000000 0000000 00000000215 11051025210 012203 0 ustar PNG IHDR %V tIMEuU pHYs ~ gAMA a PLTE U~ IDATxc` ' IENDB` libept-1.0.12/rep/ruby.png 0000644 0000000 0000000 00000000215 11051025210 012176 0 ustar PNG IHDR %V tIME]W4n pHYs ~ gAMA a PLTE5/ 3 IDATxc` ' IENDB` libept-1.0.12/rep/ept/ 0000755 0000000 0000000 00000000000 11051025211 011302 5 ustar libept-1.0.12/rep/ept/popcon/ 0000755 0000000 0000000 00000000000 11051025210 012577 5 ustar libept-1.0.12/rep/ept/popcon/local.cc.gcov.html 0000644 0000000 0000000 00000046122 11051025210 016105 0 ustar
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** @file 2 : * @author Enrico Zini <enrico@enricozini.org> 3 : * Correlate popcon data with local popcon information 4 : */ 5 : 6 : /* 7 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org> 8 : * 9 : * This program is free software; you can redistribute it and/or modify 10 : * it under the terms of the GNU General Public License as published by 11 : * the Free Software Foundation; either version 2 of the License, or 12 : * (at your option) any later version. 13 : * 14 : * This program is distributed in the hope that it will be useful, 15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : * GNU General Public License for more details. 18 : * 19 : * You should have received a copy of the GNU General Public License 20 : * along with this program; if not, write to the Free Software 21 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 : */ 23 : 24 : #include <ept/popcon/local.h> 25 : #include <ept/popcon/popcon.h> 26 : #include <ept/popcon/maint/path.h> 27 : 28 : #include <wibble/exception.h> 29 : 30 : #include <algorithm> 31 : #include <fstream> 32 : #include <cmath> 33 : 34 : //#include <iostream> 35 : 36 : using namespace std; 37 : 38 : namespace ept { 39 : namespace popcon { 40 : 41 : // Split a string where there are separators 42 1903 : static vector<string> split(const std::string& str, char sep = ' ') 43 : { 44 1903 : vector<string> res; 45 1903 : size_t start = 0; 46 10435 : while (start < str.size()) 47 : { 48 8531 : size_t end = str.find(sep, start); 49 8531 : if (end == string::npos) 50 : { 51 1902 : res.push_back(str.substr(start)); 52 1902 : break; 53 : } 54 : else 55 : { 56 6629 : res.push_back(str.substr(start, end-start)); 57 6629 : start = end + 1; 58 : } 59 : } 60 0 : return res; 61 : } 62 : 63 : // Reverse sort pairs by comparing their second element 64 : struct secondsort 65 : { 66 0 : bool operator()(const pair<string, float>& a, const pair<string, float>& b) const 67 : { 68 0 : if (a.second == b.second) 69 0 : return a.first > b.first; 70 : else 71 0 : return a.second > b.second; 72 : } 73 : }; 74 : 75 1 : Local::Local(const std::string& file) 76 : { 77 1 : m_timestamp = Path::timestamp(file); 78 1 : if (m_timestamp == 0) 79 0 : return; 80 : 81 1 : ifstream in; 82 1 : in.open(file.c_str()); 83 1 : if (!in.good()) 84 0 : throw wibble::exception::File(file, "opening file for reading"); 85 : 86 1907 : while (!in.eof()) 87 : { 88 1905 : std::string line; 89 1905 : getline(in, line); 90 1905 : if (line.substr(0, 10) == "POPULARITY") 91 3 : continue; 92 1904 : if (line.substr(0, 14) == "END-POPULARITY") 93 : continue; 94 1903 : vector<string> data = split(line); 95 1903 : if (data.size() < 4) 96 : continue; 97 1902 : if (data[3] == "<NOFILES>") 98 : // This is an empty / virtual package 99 979 : m_scores.insert(make_pair(data[2], 0.1)); 100 923 : else if (data.size() == 4) 101 : // Package normally in use 102 0 : m_scores.insert(make_pair(data[2], 1.0)); 103 923 : else if (data[4] == "<OLD>") 104 : // Unused packages 105 745 : m_scores.insert(make_pair(data[2], 0.3)); 106 178 : else if (data[4] == "<RECENT-CTIME>") 107 : // Recently installed packages 108 178 : m_scores.insert(make_pair(data[2], 0.5)); 109 1 : } 110 0 : } 111 : 112 2 : float Local::score(const std::string& pkg) const 113 : { 114 2 : std::map<std::string, float>::const_iterator i = m_scores.find(pkg); 115 2 : if (i == m_scores.end()) 116 0 : return 0; 117 : else 118 2 : return i->second; 119 : } 120 : 121 : /** 122 : * Return the TFIDF score of the package computed against the popcon 123 : * information. 124 : */ 125 1 : float Local::tfidf(const Popcon& popcon, const std::string& pkg) const 126 : { 127 1 : float popconScore = popcon.score(pkg); 128 : //cerr << pkg << ": " << score(pkg) << " * log(" << (float)popcon.submissions() << " / " << popconScore << ") = " << score(pkg) * log((float)popcon.submissions() / popconScore) << endl; 129 1 : if (popconScore == 0) 130 0 : return 0; 131 : else 132 1 : return score(pkg) * log((float)popcon.submissions() / popconScore); 133 : 134 : } 135 : 136 0 : std::vector< std::pair<std::string, float> > Local::scores() const 137 : { 138 0 : vector< pair<string, float> > res; 139 : // Copy the scores in res 140 0 : copy(m_scores.begin(), m_scores.end(), back_inserter(res)); 141 : // Sort res by score 142 0 : sort(res.begin(), res.end(), secondsort()); 143 0 : return res; 144 : } 145 : 146 0 : std::vector< std::pair<std::string, float> > Local::tfidf(const Popcon& popcon) const 147 : { 148 0 : vector< pair<string, float> > res; 149 : // Compute the tfidf scores and store them into res 150 0 : for (std::map<std::string, float>::const_iterator i = m_scores.begin(); 151 : i != m_scores.end(); ++i) 152 : { 153 0 : float popconScore = popcon.score(i->first); 154 0 : if (popconScore == 0) 155 0 : res.push_back(make_pair(i->first, 0.0f)); 156 : else 157 : res.push_back(make_pair(i->first, 158 0 : i->second * log((float)popcon.submissions() / popconScore))); 159 : } 160 : // Sort res by score 161 0 : sort(res.begin(), res.end(), secondsort()); 162 0 : return res; 163 : } 164 : 165 : } 166 6 : } 167 : 168 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 2 : #ifndef EPT_POPCON_POPCON_H 3 : #define EPT_POPCON_POPCON_H 4 : 5 : /** @file 6 : * @author Enrico Zini <enrico@enricozini.org> 7 : * Access popcon data 8 : */ 9 : 10 : /* 11 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org> 12 : * 13 : * This program is free software; you can redistribute it and/or modify 14 : * it under the terms of the GNU General Public License as published by 15 : * the Free Software Foundation; either version 2 of the License, or 16 : * (at your option) any later version. 17 : * 18 : * This program is distributed in the hope that it will be useful, 19 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 : * GNU General Public License for more details. 22 : * 23 : * You should have received a copy of the GNU General Public License 24 : * along with this program; if not, write to the Free Software 25 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 : */ 27 : 28 : #include <tagcoll/diskindex/mmap.h> 29 : #include <string> 30 : 31 : namespace ept { 32 : namespace apt { 33 : class Apt; 34 : } 35 : 36 : namespace popcon { 37 : 38 : /** 39 : * Store the score information in the popcon cache. 40 : * 41 : * Currently, this is only one float; more can be added in the future. 42 : */ 43 : class Score 44 : { 45 : protected: 46 : unsigned offset; 47 : 48 : public: 49 : float score; 50 : 51 69910 : Score(float score) : offset(offset), score(score) {} 52 : 53 : friend class Popcon; 54 : friend class PopconIndexer; 55 : friend class PopconGenerator; 56 : }; 57 : 58 : /** 59 : * Maps Packages to IDs and vice-versa. 60 : * 61 : * This is used in building the Debtags fast index, which works representing 62 : * tags and packages as int IDs. 63 : * 64 : * Index building works like this: 65 : * 1. The file all-popcon-results.txt.gz is downloaded from 66 : * http://popcon.debian.org/all-popcon-results.txt.gz 67 : * 2. The file is put in either ~/.popcon/all-popcon-results.txt.gz 68 : * or in /var/lib/popcon/all-popcon-results.txt.gz 69 : * 3. If the file is newer than the index, it will be automatically used to 70 : * recompute the scores and rebuild the index. 71 : */ 72 : class Popcon : public tagcoll::diskindex::MMap 73 7 : { 74 : struct GeneralInfo : public tagcoll::diskindex::MMap 75 7 : { 76 : size_t submissions() const; 77 : }; 78 : 79 : tagcoll::diskindex::MasterMMap mastermmap; 80 : time_t m_timestamp; 81 : 82 : GeneralInfo m_info; 83 : 84 : /// Get the score structure by index 85 102350 : const Score* structByIndex(size_t idx) const 86 : { 87 102350 : if (idx >= 0 && idx < size()) 88 102350 : return (Score*)m_buf + idx; 89 0 : return 0; 90 : } 91 : 92 : public: 93 : Popcon(); 94 : 95 : /// Get the timestamp of when the index was last updated 96 1 : time_t timestamp() const { return m_timestamp; } 97 : 98 : /// Return true if this data source has data, false if it's empty 99 1 : bool hasData() const { return m_timestamp != 0; } 100 : 101 : /// Return the total number of popcon submissions 102 3 : size_t submissions() const { return m_info.submissions(); } 103 : 104 : /// Get the number of packages in the index 105 174055 : size_t size() const 106 : { 107 174055 : if (m_buf) 108 174053 : return ((Score*)m_buf)->offset / sizeof(Score); 109 : else 110 2 : return 0; 111 : } 112 : 113 : /** 114 : * Get a package name by index 115 : * 116 : * If the index is not valid, returns the empty string. 117 : */ 118 30678 : std::string name(size_t idx) const 119 : { 120 30678 : const Score* s = structByIndex(idx); 121 30678 : if (s == 0) return std::string(); 122 30678 : return std::string(m_buf + s->offset); 123 : } 124 : 125 : /// Get the score by index 126 71672 : float scoreByIndex(size_t idx) const 127 : { 128 71672 : const Score* s = structByIndex(idx); 129 71672 : if (!s) return 0; 130 71672 : return s->score; 131 : } 132 : 133 : /// Get the score structure by package name 134 : float scoreByName(const std::string& name) const; 135 : 136 : /// Get the score by index 137 71672 : float score(size_t idx) const { return scoreByIndex(idx); } 138 : 139 : /// Get the score by index 140 : float operator[](int idx) const { return scoreByIndex(idx); } 141 : 142 : /// Get the score by name 143 1790 : float score(const std::string& name) const { return scoreByName(name); } 144 : 145 : /// Get the score structure by package name 146 2 : float operator[](const std::string& name) const { return scoreByName(name); } 147 : }; 148 : 149 : } 150 : } 151 : 152 : // vim:set ts=4 sw=4: 153 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 2 : /* 3 : * popcon/local test 4 : * 5 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org> 6 : * 7 : * This program is free software; you can redistribute it and/or modify 8 : * it under the terms of the GNU General Public License as published by 9 : * the Free Software Foundation; either version 2 of the License, or 10 : * (at your option) any later version. 11 : * 12 : * This program is distributed in the hope that it will be useful, 13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : * GNU General Public License for more details. 16 : * 17 : * You should have received a copy of the GNU General Public License 18 : * along with this program; if not, write to the Free Software 19 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 : */ 21 : 22 : #include <ept/popcon/local.h> 23 : #include <ept/popcon/popcon.h> 24 : #include <ept/popcon/maint/path.h> 25 : 26 : #include <ept/test.h> 27 : 28 : using namespace std; 29 : using namespace ept; 30 : using namespace ept::popcon; 31 : 32 : struct TestPopconLocal 33 1 : { 34 : Path::OverridePopconSourceDir odsd; 35 : Path::OverridePopconIndexDir odid; 36 : Path::OverridePopconUserSourceDir odusd; 37 : Path::OverridePopconUserIndexDir oduid; 38 : 39 : Popcon popcon; 40 : Local local; 41 : 42 1 : TestPopconLocal() 43 : : odsd( TEST_ENV_DIR "popcon" ), 44 : odid( TEST_ENV_DIR "popcon" ), 45 : odusd( TEST_ENV_DIR "popcon" ), 46 : oduid( TEST_ENV_DIR "popcon" ), 47 1 : local( TEST_ENV_DIR "popcon/popularity-contest" ) 48 1 : {} 49 : 50 : // Very basic access 51 1 : Test basicAccess() 52 : { 53 1 : assert(local.score("apt") > 0); 54 2 : assert(local.tfidf(popcon, "apt") > 0); 55 1 : } 56 : 57 : #if 0 // mornfall: apparently left out by enrico, leaving as it is 58 : // Check that every valid index is accessible 59 : template<> template<> 60 : void to::test< 2 >() 61 : { 62 : for (size_t i = 0; i < popcon.size(); ++i) 63 : { 64 : //cerr << popcon.name(i) << " " << popcon.score(i) << endl; 65 : assert(popcon.score(i) > 0); 66 : } 67 : } 68 : 69 : // Check that we can get a score for every package 70 : template<> template<> 71 : void to::test< 3 >() 72 : { 73 : int has = 0; 74 : for (Apt::iterator i = apt.begin(); i != apt.end(); ++i) 75 : { 76 : float score = popcon.score(*i); 77 : if (score > 0) 78 : ++has; 79 : } 80 : // At least 1000 packages should have a score 81 : assert(has > 1000); 82 : } 83 : 84 : // Check that scores are meaningful 85 : template<> template<> 86 : void to::test< 4 >() 87 : { 88 : assert(popcon["apt"] > popcon["libapt-pkg-dev"]); 89 : } 90 : 91 : // If there is no data, Popcon should work as if all scores were 0 92 : template<> template<> 93 : void to::test<5>() 94 : { 95 : Path::OverridePopconSourceDir odsd("./empty"); 96 : Path::OverridePopconIndexDir odid("./empty"); 97 : Path::OverridePopconUserSourceDir odusd("./empty"); 98 : Path::OverridePopconUserIndexDir oduid("./empty"); 99 : Popcon empty; 100 : 101 : assert_eq(empty.timestamp(), 0); 102 : assert(!empty.hasData()); 103 : 104 : assert(empty.size() == 0); 105 : assert(empty.score("apt") == 0.0); 106 : } 107 : #endif 108 : 109 : }; 110 : 111 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 2 : 3 : /** @file 4 : * @author Enrico Zini <enrico@enricozini.org> 5 : * Quick map from package IDs to package names 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org> 10 : * 11 : * This program is free software; you can redistribute it and/or modify 12 : * it under the terms of the GNU General Public License as published by 13 : * the Free Software Foundation; either version 2 of the License, or 14 : * (at your option) any later version. 15 : * 16 : * This program is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 : * GNU General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU General Public License 22 : * along with this program; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <ept/popcon/popcon.h> 27 : #include <ept/popcon/maint/popconindexer.h> 28 : #include <ept/popcon/maint/path.h> 29 : 30 : //#include <iostream> 31 : 32 : using namespace std; 33 : 34 : namespace ept { 35 : namespace popcon { 36 : 37 3 : size_t Popcon::GeneralInfo::submissions() const 38 : { 39 3 : if (!m_buf) return 0; 40 2 : return ((InfoStruct*)m_buf)->submissions; 41 : } 42 : 43 7 : Popcon::Popcon() 44 : { 45 7 : std::string scofname, idxfname; 46 : 47 7 : if (!PopconIndexer::obtainWorkingPopcon(scofname, idxfname)) 48 : { 49 1 : m_timestamp = 0; 50 1 : return; 51 : } 52 : 53 : //cerr << "GOT " << scofname << " " << idxfname << endl; 54 : 55 6 : m_timestamp = Path::timestamp(idxfname); 56 : 57 6 : mastermmap.init(idxfname); 58 6 : tagcoll::diskindex::MMap::init(mastermmap, 0); 59 : 60 6 : m_info.init(mastermmap, 1); 61 : 62 : //cerr << "SIZE " << size() << endl; 63 : //for (size_t i = 0; i < size(); ++i) 64 : //{ 65 : // cerr << "EL " << i << ": " << ((Score*)m_buf)[i].offset << " " << ((Score*)m_buf)[i].score << endl; 66 : //} 67 0 : } 68 : 69 1792 : float Popcon::scoreByName(const std::string& name) const 70 : { 71 : // Binary search the index to find the package ID 72 : int begin, end; 73 : 74 : /* Binary search */ 75 1792 : begin = -1, end = size(); 76 32470 : while (end - begin > 1) 77 : { 78 28886 : int cur = (end + begin) / 2; 79 28886 : if (this->name(cur) > name) 80 14367 : end = cur; 81 : else 82 14519 : begin = cur; 83 : } 84 : 85 1792 : if (begin == -1 || this->name(begin) != name) 86 : //throw NotFoundException(string("looking for the ID of string ") + str); 87 31 : return 0; 88 : else 89 1761 : return score(begin); 90 : } 91 : 92 : } 93 : } 94 : 95 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_POPCON_LOCAL_H 2 : #define EPT_POPCON_LOCAL_H 3 : 4 : /** @file 5 : * @author Enrico Zini <enrico@enricozini.org> 6 : * Correlate popcon data with local popcon information 7 : */ 8 : 9 : /* 10 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org> 11 : * 12 : * This program is free software; you can redistribute it and/or modify 13 : * it under the terms of the GNU General Public License as published by 14 : * the Free Software Foundation; either version 2 of the License, or 15 : * (at your option) any later version. 16 : * 17 : * This program is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 : * GNU General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU General Public License 23 : * along with this program; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : #include <string> 28 : #include <vector> 29 : #include <map> 30 : 31 : namespace ept { 32 : namespace popcon { 33 : 34 : class Popcon; 35 : 36 : /** 37 : * Access the results of the local daily popcon scan. 38 : */ 39 : class Local 40 1 : { 41 : protected: 42 : std::map<std::string, float> m_scores; 43 : time_t m_timestamp; 44 : 45 : public: 46 : Local(const std::string& file = std::string("/var/log/popularity-contest")); 47 : 48 : /// Get the timestamp of the local popcon information 49 : time_t timestamp() const { return m_timestamp; } 50 : 51 : /// Return true if this data source has data, false if it's empty 52 : bool hasData() const { return m_timestamp != 0; } 53 : 54 : /** 55 : * Return the local score of the package 56 : */ 57 : float score(const std::string& pkg) const; 58 : 59 : /** 60 : * Return the TFIDF score of the package computed against the popcon 61 : * information. 62 : * 63 : * The TFIDF score is high when a package is representative of this system, 64 : * that is, it is used in this system and not much used in other systems. 65 : */ 66 : float tfidf(const Popcon& popcon, const std::string& pkg) const; 67 : 68 : /** 69 : * Read the local popcon vote and return the list of packages and their 70 : * local scores, sorted by ascending score. 71 : */ 72 : std::vector< std::pair<std::string, float> > scores() const; 73 : 74 : /** 75 : * Read the local popcon vote and return the list of packages and their 76 : * TFIDF scores computed against the popcon information. 77 : * 78 : * The packages will be sorted by ascending score. 79 : */ 80 : std::vector< std::pair<std::string, float> > tfidf(const Popcon& popcon) const; 81 : }; 82 : 83 : } 84 : } 85 : 86 : // vim:set ts=4 sw=4: 87 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
local.cc |
|
62.1 % | 41 / 66 lines | |
local.h |
|
100.0 % | 1 / 1 lines | |
local.test.h |
|
100.0 % | 8 / 8 lines | |
popcon.cc |
|
95.7 % | 22 / 23 lines | |
popcon.h |
|
96.0 % | 24 / 25 lines | |
popcon.test.h |
|
100.0 % | 38 / 38 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; indent-tabs-mode: t -*- 2 : 3 : /** \file 4 : * popcon paths 5 : */ 6 : 7 : /* 8 : * Copyright (C) 2005,2006,2007 Enrico Zini <enrico@debian.org>, Peter Rockai <me@mornfall.net> 9 : * 10 : * This program is free software; you can redistribute it and/or modify 11 : * it under the terms of the GNU General Public License as published by 12 : * the Free Software Foundation; either version 2 of the License, or 13 : * (at your option) any later version. 14 : * 15 : * This program is distributed in the hope that it will be useful, 16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 : * GNU General Public License for more details. 19 : * 20 : * You should have received a copy of the GNU General Public License 21 : * along with this program; if not, write to the Free Software 22 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 : */ 24 : 25 : #include <ept/config.h> 26 : #include <ept/popcon/maint/path.h> 27 : 28 : #include <wibble/sys/fs.h> 29 : #include <wibble/string.h> 30 : 31 : #include <sys/types.h> // getpwuid, stat, mkdir, getuid 32 : #include <sys/stat.h> // stat, mkdir 33 : #include <pwd.h> // getpwuid 34 : #include <unistd.h> // stat, getuid 35 : 36 : using namespace wibble; 37 : 38 : namespace ept { 39 : namespace popcon { 40 : 41 2 : static std::string userdir() 42 : { 43 2 : std::string rcdir; 44 : 45 2 : struct passwd* udata = getpwuid(getuid()); 46 2 : rcdir = str::joinpath(udata->pw_dir, ".popcon"); 47 : 48 0 : return rcdir; 49 : } 50 : 51 : 52 178 : Path &Path::instance() { 53 178 : if (!s_instance) { 54 1 : s_instance = new Path; 55 1 : instance().m_popconSourceDir = POPCON_DB_DIR; 56 1 : instance().m_popconIndexDir = POPCON_DB_DIR; 57 2 : instance().m_popconUserSourceDir = userdir(); 58 2 : instance().m_popconUserIndexDir = userdir(); 59 : } 60 178 : return *s_instance; 61 : } 62 : 63 2 : int Path::access( const std::string &s, int m ) { 64 2 : return ::access( s.c_str(), m ); 65 : } 66 : 67 49 : time_t Path::timestamp( const std::string& file ) { 68 49 : std::auto_ptr<struct stat> st = wibble::sys::fs::stat(file); 69 90 : return st.get() == NULL ? 0 : st->st_mtime; 70 : } 71 : 72 14 : void Path::setPopconSourceDir( const std::string &s ) 73 : { 74 14 : instance().m_popconSourceDir = s; 75 14 : } 76 14 : void Path::setPopconIndexDir( const std::string &s ) 77 : { 78 14 : instance().m_popconIndexDir = s; 79 14 : } 80 14 : void Path::setPopconUserSourceDir( const std::string &s ) 81 : { 82 14 : instance().m_popconUserSourceDir = s; 83 14 : } 84 14 : void Path::setPopconUserIndexDir( const std::string &s ) 85 : { 86 14 : instance().m_popconUserIndexDir = s; 87 14 : } 88 : 89 14 : std::string Path::popconSourceDir() { return instance().m_popconSourceDir; } 90 43 : std::string Path::popconIndexDir() { return instance().m_popconIndexDir; } 91 14 : std::string Path::popconUserSourceDir() { return instance().m_popconUserSourceDir; } 92 47 : std::string Path::popconUserIndexDir() { return instance().m_popconUserIndexDir; } 93 : 94 17 : std::string Path::scores() { 95 17 : return str::joinpath(popconIndexDir(), "scores"); 96 : } 97 : 98 17 : std::string Path::scoresIndex() { 99 17 : return str::joinpath(popconIndexDir(), "scores.idx"); 100 : } 101 : 102 20 : std::string Path::userScores() { 103 20 : return str::joinpath(popconUserIndexDir(), "scores"); 104 : } 105 : 106 20 : std::string Path::userScoresIndex() { 107 20 : return str::joinpath(popconUserIndexDir(), "scores.idx"); 108 : } 109 : 110 : Path *Path::s_instance = 0; 111 : 112 : } 113 : } 114 : 115 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_DEBTAGS_PKGIDINDEXER_H 2 : #define EPT_DEBTAGS_PKGIDINDEXER_H 3 : 4 : /** @file 5 : * @author Enrico Zini <enrico@enricozini.org> 6 : * Rebuild and maintain the map from package IDs to package names 7 : */ 8 : 9 : /* 10 : * Copyright (C) 2003-2007 Enrico Zini <enrico@debian.org> 11 : * 12 : * This program is free software; you can redistribute it and/or modify 13 : * it under the terms of the GNU General Public License as published by 14 : * the Free Software Foundation; either version 2 of the License, or 15 : * (at your option) any later version. 16 : * 17 : * This program is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 : * GNU General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU General Public License 23 : * along with this program; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : #include <ept/popcon/maint/sourcedir.h> 28 : #include <string> 29 : 30 : namespace ept { 31 : namespace popcon { 32 : 33 : struct InfoStruct 34 : { 35 : size_t submissions; 36 : }; 37 : 38 : struct PopconIndexer 39 7 : { 40 : SourceDir mainSource; 41 : SourceDir userSource; 42 : time_t ts_main_src; 43 : time_t ts_user_src; 44 : time_t ts_main_sco; 45 : time_t ts_user_sco; 46 : time_t ts_main_idx; 47 : time_t ts_user_idx; 48 : 49 28 : time_t sourceTimestamp() const 50 : { 51 28 : time_t res = ts_main_src; 52 28 : if (ts_user_src > res) res = ts_user_src; 53 28 : return res; 54 : 55 : } 56 : bool needsRebuild() const; 57 : bool rebuild(const std::string& scofname, const std::string& idxfname); 58 : bool rebuildIfNeeded(); 59 : bool getUpToDatePopcon(std::string& scofname, std::string& idxfname); 60 : 61 : bool userIndexIsRedundant() const; 62 : bool deleteRedundantUserIndex(); 63 : 64 : void rescan(); 65 : 66 : PopconIndexer(); 67 : 68 : static bool obtainWorkingPopcon(std::string& scofname, std::string& idxfname); 69 : }; 70 : 71 : } 72 : } 73 : 74 : // vim:set ts=4 sw=4: 75 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include <ept/popcon/maint/sourcedir.h> 2 : #include <ept/popcon/maint/path.h> 3 : 4 : #include <wibble/string.h> 5 : 6 : #include <tagcoll/input/zlib.h> 7 : #include <tagcoll/input/stdio.h> 8 : 9 : #include <cstdlib> 10 : 11 : using namespace std; 12 : using namespace wibble; 13 : 14 : namespace ept { 15 : namespace popcon { 16 : 17 93 : SourceDir::FileType SourceDir::fileType(const std::string& name) 18 : { 19 93 : if (name[0] == '.') return SKIP; 20 : 21 59 : if (name == "all-popcon-results.txt") return RAW; 22 59 : if (name == "all-popcon-results.txt.gz") return RAWGZ; 23 : 24 46 : return SKIP; 25 : } 26 : 27 14 : time_t SourceDir::timestamp() 28 : { 29 14 : if (!valid()) return 0; 30 : 31 14 : time_t max = 0; 32 98 : for (const_iterator d = begin(); d != end(); ++d) 33 : { 34 84 : FileType type = fileType(d->d_name); 35 84 : if (type == SKIP) continue; 36 : 37 12 : time_t ts = Path::timestamp(str::joinpath(path(), d->d_name)); 38 24 : if (ts > max) max = ts; 39 14 : } 40 : 41 14 : return max; 42 : } 43 : 44 70200 : bool readLine(tagcoll::input::Input& in, string& str) 45 : { 46 70200 : str.clear(); 47 : int c; 48 4594913 : while ((c = in.nextChar()) != tagcoll::input::Input::Eof && c != '\n') 49 4454513 : str += c; 50 70200 : return c != tagcoll::input::Input::Eof; 51 : } 52 : 53 1 : static void parseScores(tagcoll::input::Input& in, map<std::string, Score>& out, size_t& submissions) 54 : { 55 1 : string line; 56 140349 : while (readLine(in, line)) 57 : { 58 70199 : if (line.size() < 10) 59 0 : continue; 60 70199 : if (line.substr(0, 13) == "Submissions: ") 61 : { 62 1 : submissions = strtoul(line.substr(13).c_str(), 0, 10); 63 1 : continue; 64 : } 65 70198 : if (line.substr(0, 9) != "Package: ") 66 50 : continue; 67 70148 : size_t start = 9; 68 70148 : size_t end = line.find(' ', start); 69 70148 : if (end == string::npos) 70 0 : continue; 71 70148 : string name = line.substr(start, end-start); 72 : // Skip packages not in the apt index 73 : //if (!apt.isValid(name)) 74 : //continue; 75 : 76 70148 : start = line.find_first_not_of(' ', end); 77 70148 : if (start == string::npos) continue; 78 70148 : end = line.find(' ', start); 79 70148 : if (end == string::npos) continue; 80 70148 : string vote = line.substr(start, end-start); 81 : 82 70148 : start = line.find_first_not_of(' ', end); 83 70148 : if (start == string::npos) continue; 84 70148 : end = line.find(' ', start); 85 70148 : if (end == string::npos) continue; 86 70148 : string old = line.substr(start, end-start); 87 : 88 70148 : start = line.find_first_not_of(' ', end); 89 70148 : if (start == string::npos) continue; 90 70148 : end = line.find(' ', start); 91 70148 : if (end == string::npos) continue; 92 70148 : string recent = line.substr(start, end-start); 93 : 94 70148 : start = line.find_first_not_of(' ', end); 95 70148 : if (start == string::npos) continue; 96 70148 : end = line.find(' ', start); 97 70148 : if (end == string::npos) end = line.size(); 98 70148 : string nofiles = line.substr(start, end-start); 99 : 100 : float score = (float)strtoul(vote.c_str(), NULL, 10) 101 : + (float)strtoul(recent.c_str(), NULL, 10) * 0.5f 102 : + (float)strtoul(old.c_str(), NULL, 10) * 0.3f 103 70148 : + (float)strtoul(nofiles.c_str(), NULL, 10) * 0.8f; 104 : 105 70148 : if (score > 0) 106 69910 : out.insert(make_pair(name, Score(score))); 107 1 : } 108 1 : } 109 : 110 3 : bool SourceDir::readScores(map<std::string, Score>& out, size_t& submissions) 111 : { 112 3 : if (!valid()) return false; 113 3 : bool done = false; 114 : 115 12 : for (const_iterator d = begin(); d != end(); ++d) 116 : { 117 9 : FileType type = fileType(d->d_name); 118 9 : if (type == RAW) 119 : { 120 : // Read uncompressed data 121 0 : tagcoll::input::Stdio in(str::joinpath(path(), d->d_name)); 122 : 123 : // Read the scores 124 0 : parseScores(in, out, submissions); 125 0 : done = true; 126 : } 127 9 : else if (type == RAWGZ) 128 : { 129 : // Read compressed data 130 1 : tagcoll::input::Zlib in(str::joinpath(path(), d->d_name)); 131 : 132 : // Read the scores 133 1 : parseScores(in, out, submissions); 134 1 : done = true; 135 : } 136 3 : } 137 3 : return done; 138 : } 139 : 140 : } 141 6 : } 142 : 143 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
path.cc |
|
97.6 % | 41 / 42 lines | |
path.h |
|
100.0 % | 17 / 17 lines | |
popconindexer.cc |
|
79.3 % | 92 / 116 lines | |
popconindexer.h |
|
100.0 % | 5 / 5 lines | |
sourcedir.cc |
|
93.4 % | 71 / 76 lines | |
sourcedir.h |
|
100.0 % | 2 / 2 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_POPCON_SOURCEDIR_H 2 : #define EPT_POPCON_SOURCEDIR_H 3 : 4 : /** @file 5 : * @author Enrico Zini <enrico@enricozini.org> 6 : * Popcon data source directory access 7 : */ 8 : 9 : /* 10 : * Copyright (C) 2003,2004,2005,2006,2007 Enrico Zini <enrico@debian.org> 11 : * 12 : * This program is free software; you can redistribute it and/or modify 13 : * it under the terms of the GNU General Public License as published by 14 : * the Free Software Foundation; either version 2 of the License, or 15 : * (at your option) any later version. 16 : * 17 : * This program is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 : * GNU General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU General Public License 23 : * along with this program; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : #include <ept/popcon/popcon.h> 28 : #include <wibble/sys/fs.h> 29 : #include <string> 30 : #include <map> 31 : 32 : namespace ept { 33 : namespace popcon { 34 : 35 : /** 36 : * Access a directory containing Debtags data files 37 : */ 38 : class SourceDir : public wibble::sys::fs::Directory 39 14 : { 40 : protected: 41 : enum FileType { SKIP, RAW, RAWGZ }; 42 : 43 : // Check if a file name is a tag file, a vocabulary file or a file to skip. 44 : // Please notice that it works on file names, not paths. 45 : FileType fileType(const std::string& name); 46 : 47 : public: 48 14 : SourceDir(const std::string& path) : Directory(path) {} 49 : 50 : /// Return the time of the newest file in the source directory 51 : time_t timestamp(); 52 : 53 : /** 54 : * Read the tag files in the directory and output their content to the map 55 : */ 56 : bool readScores(std::map<std::string, Score>& out, size_t& submissions); 57 : }; 58 : 59 : } 60 : } 61 : 62 : // vim:set ts=4 sw=4: 63 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; indent-tabs-mode: t -*- 2 : /** \file 3 : * popcon paths 4 : */ 5 : 6 : /* 7 : * Copyright (C) 2005,2006,2007 Enrico Zini <enrico@debian.org> 8 : * 9 : * This program is free software; you can redistribute it and/or modify 10 : * it under the terms of the GNU General Public License as published by 11 : * the Free Software Foundation; either version 2 of the License, or 12 : * (at your option) any later version. 13 : * 14 : * This program is distributed in the hope that it will be useful, 15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : * GNU General Public License for more details. 18 : * 19 : * You should have received a copy of the GNU General Public License 20 : * along with this program; if not, write to the Free Software 21 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 : */ 23 : 24 : #ifndef EPT_POPCON_PATH_H 25 : #define EPT_POPCON_PATH_H 26 : 27 : #include <string> 28 : 29 : struct stat; 30 : 31 : namespace ept { 32 : namespace popcon { 33 : 34 : /** 35 : * Singleton class to configure and access the various Popcon paths 36 : */ 37 : class Path 38 1 : { 39 : public: 40 : static std::string scores(); 41 : static std::string scoresIndex(); 42 : static std::string userScores(); 43 : static std::string userScoresIndex(); 44 : 45 : static std::string popconSourceDir(); 46 : static std::string popconIndexDir(); 47 : static std::string popconUserSourceDir(); 48 : static std::string popconUserIndexDir(); 49 : 50 : // Directory where Popcon source data is found 51 : static void setPopconSourceDir( const std::string &s ); 52 : 53 : // Directory where Popcon indexes are kept 54 : static void setPopconIndexDir( const std::string &s ); 55 : 56 : // User-specific directory for Popcon source data 57 : static void setPopconUserSourceDir( const std::string &s ); 58 : 59 : // User-specific directory for Popcon index data 60 : static void setPopconUserIndexDir( const std::string &s ); 61 : 62 : static int access( const std::string &, int ); 63 : static time_t timestamp( const std::string& ); 64 : 65 : // RAII-style classes to temporarily override directories 66 : class OverridePopconSourceDir 67 : { 68 : std::string old; 69 : public: 70 7 : OverridePopconSourceDir(const std::string& path) : old(Path::popconSourceDir()) 71 : { 72 7 : Path::setPopconSourceDir(path); 73 7 : } 74 7 : ~OverridePopconSourceDir() { Path::setPopconSourceDir(old); } 75 : }; 76 : class OverridePopconIndexDir 77 : { 78 : std::string old; 79 : public: 80 7 : OverridePopconIndexDir(const std::string& path) : old(Path::popconIndexDir()) 81 : { 82 7 : Path::setPopconIndexDir(path); 83 7 : } 84 7 : ~OverridePopconIndexDir() { Path::setPopconIndexDir(old); } 85 : }; 86 : class OverridePopconUserSourceDir 87 : { 88 : std::string old; 89 : public: 90 7 : OverridePopconUserSourceDir(const std::string& path) : old(Path::popconUserSourceDir()) 91 : { 92 7 : Path::setPopconUserSourceDir(path); 93 7 : } 94 7 : ~OverridePopconUserSourceDir() { Path::setPopconUserSourceDir(old); } 95 : }; 96 : class OverridePopconUserIndexDir 97 : { 98 : std::string old; 99 : public: 100 7 : OverridePopconUserIndexDir(const std::string& path) : old(Path::popconUserIndexDir()) 101 : { 102 7 : Path::setPopconUserIndexDir(path); 103 7 : } 104 7 : ~OverridePopconUserIndexDir() { Path::setPopconUserIndexDir(old); } 105 : }; 106 : protected: 107 : static Path *s_instance; 108 : static Path &instance(); 109 : 110 : // Directory where Popcon source data is found 111 : std::string m_popconSourceDir; 112 : 113 : // Directory where Popcon indexes are kept 114 : std::string m_popconIndexDir; 115 : 116 : // User-specific directory for Popcon source data 117 : std::string m_popconUserSourceDir; 118 : 119 : // User-specific directory for Popcon index data 120 : std::string m_popconUserIndexDir; 121 : }; 122 : 123 : } 124 : } 125 : 126 : // vim:set ts=4 sw=4: 127 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include <ept/popcon/popcon.h> 2 : #include <ept/popcon/maint/popconindexer.h> 3 : #include <ept/popcon/maint/path.h> 4 : 5 : #include <wibble/exception.h> 6 : #include <wibble/sys/fs.h> 7 : 8 : #include <tagcoll/diskindex/mmap.h> 9 : 10 : #include <set> 11 : #include <string> 12 : #include <cstdio> 13 : #include <cstring> 14 : 15 : using namespace std; 16 : 17 : namespace ept { 18 : namespace popcon { 19 : 20 : template<typename STRUCT> 21 : struct StructIndexer : public tagcoll::diskindex::MMapIndexer 22 1 : { 23 : const STRUCT& data; 24 1 : StructIndexer(const STRUCT& data) : data(data) {} 25 : 26 1 : int encodedSize() const { return sizeof(STRUCT); } 27 1 : void encode(char* buf) const { *(STRUCT*)buf = data; } 28 : }; 29 : 30 : /// MMapIndexer that indexes the package names 31 : struct PopconGenerator : public tagcoll::diskindex::MMapIndexer 32 4 : { 33 : // Sorted set of all available package names and data 34 : std::map<std::string, Score> data; 35 : 36 1 : int encodedSize() const 37 : { 38 1 : int size = data.size() * sizeof(Score); 39 69911 : for (std::map<std::string, Score>::const_iterator i = data.begin(); 40 : i != data.end(); ++i) 41 69910 : size += i->first.size() + 1; 42 1 : return tagcoll::diskindex::MMap::align(size); 43 : } 44 : 45 1 : void encode(char* buf) const 46 : { 47 1 : int pos = data.size() * sizeof(Score); 48 1 : int idx = 0; 49 69911 : for (std::map<std::string, Score>::const_iterator i = data.begin(); 50 : i != data.end(); ++i) 51 : { 52 69910 : ((Score*)buf)[idx] = i->second; 53 69910 : ((Score*)buf)[idx].offset = pos; 54 69910 : memcpy(buf + pos, i->first.c_str(), i->first.size() + 1); 55 69910 : pos += i->first.size() + 1; 56 69910 : ++idx; 57 : } 58 1 : } 59 : }; 60 : 61 : 62 7 : PopconIndexer::PopconIndexer() 63 : : mainSource(Path::popconSourceDir()), 64 7 : userSource(Path::popconUserSourceDir()) 65 : { 66 7 : rescan(); 67 7 : } 68 : 69 7 : void PopconIndexer::rescan() 70 : { 71 7 : ts_main_src = mainSource.timestamp(); 72 7 : ts_user_src = userSource.timestamp(); 73 7 : ts_main_sco = Path::timestamp(Path::scores()); 74 14 : ts_user_sco = Path::timestamp(Path::userScores()); 75 14 : ts_main_idx = Path::timestamp(Path::scoresIndex()); 76 14 : ts_user_idx = Path::timestamp(Path::userScoresIndex()); 77 7 : } 78 : 79 7 : bool PopconIndexer::needsRebuild() const 80 : { 81 : // If there are no indexes of any kind, then we need rebuilding 82 7 : if (ts_user_sco == 0 || ts_main_sco == 0 || ts_user_idx == 0 && ts_main_idx == 0) 83 2 : return true; 84 : 85 : // If the user index is ok, then we are fine 86 5 : if (ts_user_sco >= sourceTimestamp() && ts_user_idx >= sourceTimestamp()) 87 5 : return false; 88 : 89 : // If there are user sources, then we cannot use the system index 90 0 : if (ts_user_src > 0) 91 0 : return true; 92 : 93 : // If there are no user sources, then we can fallback on the system 94 : // indexes in case the user indexes are not up to date 95 0 : if (ts_main_sco >= sourceTimestamp() && ts_main_idx >= sourceTimestamp()) 96 0 : return false; 97 : 98 0 : return true; 99 : } 100 : 101 7 : bool PopconIndexer::userIndexIsRedundant() const 102 : { 103 : // If there is no user index, then it is not redundant 104 7 : if (ts_user_idx == 0) 105 1 : return false; 106 : 107 : // If the system index is not up to date, then the user index is not 108 : // redundant 109 6 : if (ts_main_idx < sourceTimestamp()) 110 0 : return false; 111 : 112 6 : return true; 113 : } 114 : 115 2 : bool PopconIndexer::rebuild(const std::string& scofname, const std::string& idxfname) 116 : { 117 2 : PopconGenerator gen; 118 : InfoStruct is; 119 2 : is.submissions = 0; 120 2 : if (!mainSource.readScores(gen.data, is.submissions)) 121 1 : userSource.readScores(gen.data, is.submissions); 122 2 : if (gen.data.empty()) 123 1 : return false; 124 : 125 1 : StructIndexer<InfoStruct> infoStruct(is); 126 : 127 : // Create the index 128 1 : tagcoll::diskindex::MasterMMapIndexer master(idxfname); 129 1 : master.append(gen); 130 1 : master.append(infoStruct); 131 1 : master.commit(); 132 : 133 : // for (map<string, Score>::const_iterator i = gen.data.begin(); i != gen.data.end(); ++i) 134 : // { 135 : // fprintf(stderr, "%s %d %f\n", i->first.c_str(), i->second.offset, i->second.score); 136 : // } 137 : 138 : // Create the score file 139 1 : FILE* out = fopen(scofname.c_str(), "wt"); 140 1 : if (out == NULL) 141 0 : throw wibble::exception::File(scofname, "opening and truncating file for writing"); 142 69911 : for (map<string, Score>::const_iterator i = gen.data.begin(); 143 : i != gen.data.end(); ++i) 144 : { 145 69910 : fprintf(out, "%s %f\n", i->first.c_str(), i->second.score); 146 : } 147 1 : fclose(out); 148 1 : return true; 149 : } 150 : 151 7 : bool PopconIndexer::rebuildIfNeeded() 152 : { 153 7 : if (needsRebuild()) 154 : { 155 : // Decide if we rebuild the user index or the system index 156 2 : if (Path::access(Path::popconIndexDir(), W_OK) == 0) 157 : { 158 : // Since we can write on the system index directory, we rebuild 159 : // the system index 160 2 : if (!rebuild(Path::scores(), Path::scoresIndex())) 161 1 : return false; 162 1 : ts_main_sco = Path::timestamp(Path::scores()); 163 2 : ts_main_idx = Path::timestamp(Path::scoresIndex()); 164 2 : if (Path::scores() == Path::userScores()) 165 1 : ts_user_sco = ts_main_sco; 166 1 : if (Path::scoresIndex() == Path::userScoresIndex()) 167 1 : ts_user_idx = ts_main_idx; 168 : } else { 169 0 : wibble::sys::fs::mkFilePath(Path::userScores()); 170 0 : wibble::sys::fs::mkFilePath(Path::userScoresIndex()); 171 0 : if (!rebuild(Path::userScores(), Path::userScoresIndex())) 172 0 : return false; 173 0 : ts_user_sco = Path::timestamp(Path::userScores()); 174 0 : ts_user_idx = Path::timestamp(Path::userScoresIndex()); 175 : } 176 1 : return true; 177 : } 178 5 : return false; 179 : } 180 : 181 7 : bool PopconIndexer::deleteRedundantUserIndex() 182 : { 183 7 : if (userIndexIsRedundant()) 184 : { 185 : // Delete the user indexes if they exist 186 6 : if (Path::scores() != Path::userScores()) 187 : { 188 0 : unlink(Path::userScores().c_str()); 189 0 : ts_user_sco = 0; 190 : } 191 6 : if (Path::scoresIndex() != Path::userScoresIndex()) 192 : { 193 0 : unlink(Path::userScoresIndex().c_str()); 194 0 : ts_user_idx = 0; 195 : } 196 6 : return true; 197 : } 198 1 : return false; 199 : } 200 : 201 7 : bool PopconIndexer::getUpToDatePopcon(std::string& scofname, std::string& idxfname) 202 : { 203 : // If there are no indexes of any kind, then we have nothing to return 204 7 : if (ts_user_sco == 0 && ts_main_sco == 0 && ts_user_idx == 0 && ts_main_idx == 0) 205 1 : return false; 206 : 207 : // If the user index is up to date, use it 208 6 : if (ts_user_sco >= sourceTimestamp() && 209 : ts_user_idx >= sourceTimestamp()) 210 : { 211 6 : scofname = Path::userScores(); 212 12 : idxfname = Path::userScoresIndex(); 213 6 : return true; 214 : } 215 : 216 : // If the user index is not up to date and we have user sources, we cannot 217 : // fall back to the system index 218 0 : if (ts_user_src != 0) 219 0 : return false; 220 : 221 : // Fallback to the system index 222 0 : if (ts_main_sco >= sourceTimestamp() && 223 : ts_main_idx >= sourceTimestamp()) 224 : { 225 0 : scofname = Path::scores(); 226 0 : idxfname = Path::scoresIndex(); 227 0 : return true; 228 : } 229 : 230 0 : return false; 231 : } 232 : 233 : 234 7 : bool PopconIndexer::obtainWorkingPopcon(std::string& scofname, std::string& idxfname) 235 : { 236 7 : PopconIndexer indexer; 237 : 238 7 : indexer.rebuildIfNeeded(); 239 7 : indexer.deleteRedundantUserIndex(); 240 7 : return indexer.getUpToDatePopcon(scofname, idxfname); 241 : } 242 : 243 : 244 : } 245 6 : } 246 : 247 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 2 : /* 3 : * popcon test 4 : * 5 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org> 6 : * 7 : * This program is free software; you can redistribute it and/or modify 8 : * it under the terms of the GNU General Public License as published by 9 : * the Free Software Foundation; either version 2 of the License, or 10 : * (at your option) any later version. 11 : * 12 : * This program is distributed in the hope that it will be useful, 13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : * GNU General Public License for more details. 16 : * 17 : * You should have received a copy of the GNU General Public License 18 : * along with this program; if not, write to the Free Software 19 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 : */ 21 : 22 : #include <ept/popcon/popcon.h> 23 : #include <ept/popcon/maint/path.h> 24 : #include <ept/apt/apt.h> 25 : #include <set> 26 : 27 : #include <ept/test.h> 28 : 29 : using namespace std; 30 : using namespace ept; 31 : using namespace ept::popcon; 32 : using namespace ept::apt; 33 : 34 : struct TestPopcon 35 5 : { 36 : popcon::Path::OverridePopconSourceDir odsd; 37 : popcon::Path::OverridePopconIndexDir odid; 38 : popcon::Path::OverridePopconUserSourceDir odusd; 39 : popcon::Path::OverridePopconUserIndexDir oduid; 40 : 41 : Apt apt; 42 : Popcon popcon; 43 : 44 5 : TestPopcon() 45 : : odsd( TEST_ENV_DIR "popcon" ), 46 : odid( TEST_ENV_DIR "popcon" ), 47 : odusd( TEST_ENV_DIR "popcon" ), 48 5 : oduid( TEST_ENV_DIR "popcon" ) 49 5 : {} 50 : 51 1 : Test basicAccess() 52 : { 53 1 : assert_eq(popcon.submissions(), 52024); 54 2 : assert(popcon.size() > 0); 55 2 : assert(popcon.score(0) > 0); 56 2 : assert(!popcon.name(0).empty()); 57 1 : } 58 : 59 : // Check that every valid index is accessible 60 1 : Test accessibility() 61 : { 62 139822 : for (size_t i = 0; i < popcon.size(); ++i) 63 : { 64 : //cerr << popcon.name(i) << " " << popcon.score(i) << endl; 65 69910 : assert(popcon.score(i) > 0); 66 : } 67 1 : } 68 : 69 : // Check that we can get a score for every package 70 1 : Test haveScores() 71 : { 72 1 : int has = 0; 73 1789 : for (Apt::iterator i = apt.begin(); i != apt.end(); ++i) 74 : { 75 1788 : float score = popcon.score(*i); 76 1788 : if (score > 0) 77 1758 : ++has; 78 1 : } 79 : // At least 1000 packages should have a score 80 2 : assert(has > 1000); 81 1 : } 82 : 83 : // Check that scores are meaningful 84 1 : Test validScores() 85 : { 86 1 : assert(popcon["apt"] > popcon["libapt-pkg-dev"]); 87 1 : } 88 : 89 : // If there is no data, Popcon should work as if all scores were 0 90 1 : Test fallbackValues() 91 : { 92 1 : popcon::Path::OverridePopconSourceDir odsd("./empty"); 93 2 : popcon::Path::OverridePopconIndexDir odid("./empty"); 94 2 : popcon::Path::OverridePopconUserSourceDir odusd("./empty"); 95 2 : popcon::Path::OverridePopconUserIndexDir oduid("./empty"); 96 1 : Popcon empty; 97 : 98 1 : assert_eq(empty.timestamp(), 0); 99 2 : assert(!empty.hasData()); 100 : 101 2 : assert_eq(empty.submissions(), 0); 102 2 : assert(empty.size() == 0); 103 2 : assert(empty.score("apt") == 0.0); 104 1 : } 105 : 106 : }; 107 : 108 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** -*- C++ -*- 2 : @file progresscallback.h 3 : @author Michael Vogt <mvo@debian.org> 4 : */ 5 : 6 : #ifndef EPT_PROGRESSCALLBACK_H 7 : #define EPT_PROGRESSCALLBACK_H 8 : 9 : #include <apt-pkg/acquire.h> 10 : 11 : namespace ept { 12 : 13 : class ProgressCallback : public pkgAcquireStatus 14 : { 15 : protected: 16 : virtual bool Pulse(pkgAcquire *Owner); 17 : public: 18 : ProgressCallback() {}; 19 0 : virtual ~ProgressCallback() {}; 20 0 : virtual bool MediaChange( string, string ) { return false; } // bah 21 : 22 : // override this to get periodic updates 23 0 : virtual void UpdatePulse( double, double, unsigned long ) {} 24 : }; 25 : 26 : } 27 : 28 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include <ept/progresscallback.h> 2 : 3 : namespace ept { 4 : 5 0 : bool ProgressCallback::Pulse(pkgAcquire *Owner) 6 : { 7 0 : pkgAcquireStatus::Pulse(Owner); 8 0 : UpdatePulse(FetchedBytes, CurrentCPS, CurrentItems); 9 0 : return true; 10 : } 11 : 12 : } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include <ept/core/apt.h> 2 : #include <ept/config.h> 3 : #include <ept/debtags/maint/path.h> 4 : 5 : #include <wibble/test.h> 6 : 7 : #ifndef EPT_TEST_H 8 : #define EPT_TEST_H 9 : 10 73 : struct AptTestEnvironment { 11 : ept::core::AptDatabase db; 12 73 : AptTestEnvironment() { 13 73 : pkgInitConfig (*_config); 14 73 : _config->Set("Initialized", 1); 15 73 : _config->Set("Dir", TEST_ENV_DIR); 16 146 : _config->Set("Dir::Cache", "cache"); 17 146 : _config->Set("Dir::State", "state"); 18 146 : _config->Set("Dir::Etc", "etc"); 19 146 : _config->Set("Dir::State::status", TEST_ENV_DIR "dpkg-status"); 20 73 : pkgInitSystem (*_config, _system); 21 73 : } 22 : }; 23 : 24 29 : struct DebtagsTestEnvironment : AptTestEnvironment { 25 : ept::debtags::Path::OverrideDebtagsSourceDir odsd; 26 : ept::debtags::Path::OverrideDebtagsIndexDir odid; 27 : ept::debtags::Path::OverrideDebtagsUserSourceDir odusd; 28 : ept::debtags::Path::OverrideDebtagsUserIndexDir oduid; 29 : 30 29 : DebtagsTestEnvironment() 31 : : odsd( TEST_ENV_DIR "debtags/"), 32 : odid( TEST_ENV_DIR "debtags/"), 33 : odusd( TEST_ENV_DIR "debtags/"), 34 29 : oduid( TEST_ENV_DIR "debtags/") 35 29 : {} 36 : }; 37 : 38 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Match tag expressions against sets of Debtags Tags 3 : * 4 : * Copyright (C) 2005,2006,2007 Enrico Zini <enrico@debian.org> 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 2 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, write to the Free Software 18 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : */ 20 : 21 : #include <wibble/test.h> 22 : #include <ept/debtags/maint/path.h> 23 : #include <ept/debtags/expression.h> 24 : #include <ept/debtags/vocabulary.h> 25 : 26 : #include "debtags.test.h" 27 : 28 : using namespace tagcoll; 29 : using namespace std; 30 : using namespace ept::debtags; 31 : 32 2 : struct TestExpression : DebtagsTestEnvironment { 33 : Vocabulary voc; 34 : 35 1 : Test _1() 36 : { 37 1 : set<Tag> test; 38 1 : test.insert(voc.tagByName("use::editing")); 39 2 : test.insert(voc.tagByName("use::viewing")); 40 2 : test.insert(voc.tagByName("works-with::text")); 41 : 42 2 : assert_eq(test.size(), 3u); 43 : 44 2 : Expression e1("use::editing"); 45 2 : assert(e1(test)); 46 : 47 2 : Expression e2("use::editing && use::viewing"); 48 2 : assert(e2(test)); 49 : 50 2 : e1 = Expression("!use::editing"); 51 2 : assert(!e1(test)); 52 : 53 2 : e1 = Expression("use::editing || sugo"); 54 2 : assert(e1(test)); 55 : 56 2 : e1 = Expression("use::editing && !sugo"); 57 2 : assert(e1(test)); 58 : 59 2 : e1 = Expression("use::editing && !use::viewing"); 60 2 : assert(!e1(test)); 61 : 62 2 : e1 = Expression("(use::editing || sugo) && (use::viewing && works-with::text)"); 63 2 : assert(e1(test)); 64 : 65 2 : e1 = Expression("!(use::editinuse::editingra && works-with::text)"); 66 2 : assert(e1(test)); 67 : 68 2 : e1 = Expression("works-with::*"); 69 2 : assert(e1(test)); 70 : 71 2 : e1 = Expression("*::text"); 72 2 : assert(e1(test)); 73 : 74 2 : e1 = Expression("!*::antani"); 75 2 : assert(e1(test)); 76 : 77 2 : e1 = Expression("*::antani"); 78 2 : assert(!e1(test)); 79 1 : } 80 : 81 : }; 82 : 83 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** \file 2 : * Match tag expressions against sets of Debtags Tags 3 : */ 4 : 5 : /* 6 : * Copyright (C) 2003,2004,2005,2006,2007 Enrico Zini <enrico@debian.org> 7 : * 8 : * This program is free software; you can redistribute it and/or modify 9 : * it under the terms of the GNU General Public License as published by 10 : * the Free Software Foundation; either version 2 of the License, or 11 : * (at your option) any later version. 12 : * 13 : * This program is distributed in the hope that it will be useful, 14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : * GNU General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU General Public License 19 : * along with this program; if not, write to the Free Software 20 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 : */ 22 : 23 : #include <ept/debtags/expression.h> 24 : #include <string> 25 : 26 : namespace tagcoll 27 : { 28 : 29 : template<> 30 12 : bool Expression::operator()(const std::set<ept::debtags::Tag>& tags) const 31 : { 32 12 : std::set<std::string> names; 33 48 : for (std::set<ept::debtags::Tag>::const_iterator i = tags.begin(); 34 : i != tags.end(); ++i) 35 36 : names.insert(i->fullname()); 36 12 : return this->m_impl->eval(names); 37 : } 38 : 39 : template<> 40 : bool Expression::operator()(const std::set<ept::debtags::Facet>& tags) const 41 : { 42 : std::set<std::string> names; 43 : for (std::set<ept::debtags::Facet>::const_iterator i = tags.begin(); 44 : i != tags.end(); ++i) 45 : names.insert(i->name()); 46 : return this->m_impl->eval(names); 47 : } 48 : 49 : }; 50 : 51 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Tag vocabulary access 3 : * 4 : * Copyright (C) 2003--2007 Enrico Zini <enrico@debian.org> 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 2 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, write to the Free Software 18 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : */ 20 : 21 : #include <wibble/test.h> 22 : #include <ept/debtags/vocabulary.h> 23 : #include <ept/debtags/maint/vocabularymerger.h> 24 : #include <ept/debtags/maint/path.h> 25 : #include <tagcoll/utils/set.h> 26 : #include <tagcoll/input/stdio.h> 27 : 28 : #include "debtags.test.h" 29 : 30 : // This is not exported by default 31 : namespace ept { 32 : namespace debtags { 33 : int tagcmp(const char* tag1, const char* tag2); 34 : } 35 : } 36 : 37 : using namespace std; 38 : using namespace tagcoll::utils; 39 : using namespace ept::debtags; 40 : 41 : struct TestVocabulary : DebtagsTestEnvironment 42 38 : { 43 : Vocabulary m_tags; 44 1298 : Vocabulary& tags() { return m_tags; } 45 : 46 1 : Test _1() 47 : { 48 1 : tags(); // this will throw if the open above didn't work 49 1 : } 50 : 51 1 : Test _2() 52 : { 53 1 : assert( tags().hasFacet( "works-with" ) ); 54 2 : assert( !tags().hasFacet( "blah" ) ); 55 1 : } 56 : 57 1 : Test _3() 58 : { 59 1 : assert( tags().hasTag( "works-with::people" ) ); 60 2 : assert( !tags().hasTag( "works-with::midgets" ) ); 61 1 : } 62 : 63 1 : Test _4() 64 : { 65 1 : Tag people = tags().tagByName( "works-with::people" ), 66 2 : midgets = tags().tagByName( "works-with::midgets" ), 67 2 : blahg = tags().tagByName( "works-with::blahg" ), 68 2 : text = tags().tagByName( "works-with::text" ), 69 2 : people2 = tags().tagByName( "works-with::people" ); 70 2 : assert( people != midgets ); 71 2 : assert( people != text ); 72 2 : assert( people != blahg ); 73 2 : assert( midgets == blahg ); 74 2 : assert( midgets == midgets ); 75 2 : assert( people == people2 ); 76 2 : assert( people == people ); 77 1 : } 78 : 79 1 : Test _5() 80 : { 81 1 : Tag a = tags().tagByName( "works-with::people" ), 82 2 : b = tags().tagByName( "works-with::midgets" ); 83 2 : std::set< Tag > s = tags().tags(), 84 1 : f = tags().tags( "works-with" ), 85 2 : n = tags().tags( "nonsense" ); 86 2 : assert( set_contains(s, a) ); 87 2 : assert( set_contains(f, a) ); 88 2 : assert( set_contains(s, f) ); 89 2 : assert( !set_contains(s, b) ); 90 2 : assert( !set_contains(f, b) ); 91 2 : assert( n.empty() ); 92 1 : } 93 : 94 1 : Test _6() 95 : { 96 1 : Facet f = tags().facetByName( "works-with" ); 97 2 : Tag t = tags().tagByName( "works-with::people" ); 98 2 : assert_eq(f.name(), "works-with"); 99 1 : assert_eq(t.name(), "people"); 100 1 : assert_eq(t.fullname(), "works-with::people"); 101 1 : } 102 : 103 1 : Test _7() 104 : { 105 1 : Facet f = tags().facetByName( "works-with" ); 106 2 : std::set< Tag > x = tags().tags( "works-with" ); 107 2 : assert( x == f.tags() ); 108 1 : } 109 : 110 1 : Test _8() 111 : { 112 1 : Facet f = tags().facetByName( "does-not-work-with" ); 113 1 : int x = 1; 114 : try { 115 1 : f.tags(); 116 0 : x = 2; 117 2 : } catch (...) { 118 1 : x = 3; 119 : } 120 1 : assert_eq( x, 3 ); 121 1 : } 122 : 123 1 : Test _9() 124 : { 125 1 : Facet f = tags().facetByName( "legacy" ); 126 2 : assert_eq(f.shortDescription(), ""); 127 1 : assert_eq(f.longDescription(), ""); 128 : //assert_eq(f.shortDescription( "weehee" ), "weehee"); 129 1 : } 130 : 131 : Test _10() 132 : { 133 : // assert that one-character tag names are parsed correctly 134 : assert( tags().hasTag( "implemented-in::c" ) ); 135 : } 136 : 137 1 : Test _11() 138 : { 139 : // assert that all tags are somehow working 140 1 : std::set<Facet> facets = tags().facets(); 141 : 142 30 : for (std::set<Facet>::const_iterator i = facets.begin(); 143 : i != facets.end(); i++) 144 : { 145 29 : i->name(string("foo")); 146 58 : i->shortDescription(string("foo")); 147 58 : i->longDescription(string("foo")); 148 58 : i->tags(); 149 1 : } 150 1 : } 151 : 152 1 : Test _12() 153 : { 154 : // assert that all tags are somehow working 155 1 : std::set<Tag> tags = this->tags().tags(); 156 : 157 1242 : for (std::set<Tag>::const_iterator i = tags.begin(); 158 : i != tags.end(); i++) 159 : { 160 620 : i->name(string("foo")); 161 1240 : i->fullname(string("foo")); 162 1240 : i->shortDescription(string("foo")); 163 1240 : i->longDescription(string("foo")); 164 1 : } 165 1 : } 166 : 167 : // Check for correctness of the first and last tag in the vocabulary 168 1 : Test _13() 169 : { 170 1 : Vocabulary& tags = this->tags(); 171 : 172 1 : Tag first = tags.tagByName("accessibility::TODO"); 173 2 : assert(first != Tag()); 174 1 : assert_eq(first.fullname(), string("accessibility::TODO")); 175 2 : assert_eq(first.name(), string("TODO")); 176 2 : assert_eq(first.shortDescription(), string("Need an extra tag")); 177 : 178 2 : Tag last = tags.tagByName("x11::xserver"); 179 2 : assert(last != Tag()); 180 1 : assert_eq(last.fullname(), string("x11::xserver")); 181 2 : assert_eq(last.name(), string("xserver")); 182 2 : assert_eq(last.shortDescription(), string("X Server")); 183 1 : } 184 : 185 1 : Test _14() 186 : { 187 : // assert that it's possible to go from facet to ID and back 188 1 : std::set<Facet> facets = tags().facets(); 189 : 190 30 : for (std::set<Facet>::const_iterator i = facets.begin(); 191 : i != facets.end(); i++) 192 : { 193 29 : Facet f = tags().facetByID(i->id()); 194 29 : assert_eq(*i, f); 195 29 : assert_eq(i->name(), f.name()); 196 29 : assert_eq(i->shortDescription(), f.shortDescription()); 197 29 : assert_eq(i->longDescription(), f.longDescription()); 198 29 : assert_eq(i->tags().size(), f.tags().size()); 199 1 : } 200 1 : } 201 : 202 1 : Test _15() 203 : { 204 : // assert that it's possible to go from tag to ID and back 205 1 : std::set<Tag> tags = this->tags().tags(); 206 : 207 621 : for (std::set<Tag>::const_iterator i = tags.begin(); 208 : i != tags.end(); i++) 209 : { 210 620 : Tag t = this->tags().tagByID(i->id()); 211 620 : assert_eq(*i, t); 212 620 : assert_eq(i->name(), t.name()); 213 620 : assert_eq(i->fullname(), t.fullname()); 214 620 : assert_eq(i->shortDescription(), t.shortDescription()); 215 620 : assert_eq(i->longDescription(), t.longDescription()); 216 1 : } 217 1 : } 218 : 219 1 : Test _16() 220 : { 221 : // assert that facet IDs are distinct 222 1 : std::set<Facet> facets = tags().facets(); 223 1 : std::set<int> ids; 224 30 : for (std::set<Facet>::const_iterator i = facets.begin(); 225 : i != facets.end(); i++) 226 29 : ids.insert(i->id()); 227 : 228 1 : assert_eq(facets.size(), ids.size()); 229 1 : } 230 : 231 1 : Test _17() 232 : { 233 : // assert that tag IDs are distinct 234 1 : std::set<Tag> tags = this->tags().tags(); 235 1 : std::set<int> ids; 236 621 : for (std::set<Tag>::const_iterator i = tags.begin(); 237 : i != tags.end(); i++) 238 620 : ids.insert(i->id()); 239 : 240 1 : assert_eq(tags.size(), ids.size()); 241 1 : } 242 : 243 1 : Test _18() 244 : { 245 : // assert that all the tags are indexed 246 1 : ept::debtags::VocabularyMerger voc; 247 1 : tagcoll::input::Stdio in(ept::debtags::Path::vocabulary()); 248 1 : voc.read(in); 249 1 : std::set<std::string> all = voc.tagNames(); 250 1242 : for (std::set<std::string>::const_iterator i = all.begin(); 251 : i != all.end(); ++i) 252 620 : assert(this->tags().hasTag(*i)); 253 : 254 : // There should be the same amount of tags in both 255 1 : std::set<Tag> allTags = this->tags().tags(); 256 1 : assert_eq(all.size(), allTags.size()); 257 1 : } 258 : 259 1 : Test _19() 260 : { 261 : // test the tagcmp function 262 : 263 : // If unfaceted, same as strcmp 264 1 : assert(ept::debtags::tagcmp("antani", "blinda") < 0); 265 2 : assert(ept::debtags::tagcmp("blinda", "antani") > 0); 266 2 : assert_eq(ept::debtags::tagcmp("antani", "antani"), 0); 267 : 268 : // If the same and faceted, should work 269 2 : assert_eq(ept::debtags::tagcmp("antani::blinda", "antani::blinda"), 0); 270 : 271 : // With different facet names, work just as strcmp 272 2 : assert(ept::debtags::tagcmp("antani::blinda", "blinda::blinda") < 0); 273 2 : assert(ept::debtags::tagcmp("blinda::blinda", "antani::blinda") > 0); 274 2 : assert(ept::debtags::tagcmp("anta::blinda", "antani::blinda") < 0); 275 2 : assert(ept::debtags::tagcmp("antani::blinda", "anta::blinda") > 0); 276 2 : assert(ept::debtags::tagcmp("anta::blinda", "anta-ni::blinda") < 0); 277 2 : assert(ept::debtags::tagcmp("anta-ni::blinda", "anta::blinda") > 0); 278 : 279 : // With same facet names, work just as strcmp on the tags 280 2 : assert(ept::debtags::tagcmp("a::antani", "a::blinda") < 0); 281 2 : assert(ept::debtags::tagcmp("a::blinda", "a::antani") > 0); 282 2 : assert(ept::debtags::tagcmp("a::anta", "a::antani") < 0); 283 2 : assert(ept::debtags::tagcmp("a::antani", "a::anta") > 0); 284 2 : assert(ept::debtags::tagcmp("a::anta", "a::anta-ni") < 0); 285 2 : assert(ept::debtags::tagcmp("a::anta-ni", "a::anta") > 0); 286 1 : } 287 : 288 : Test _20() 289 : { 290 : // check that we're seeing all the tags for a facet 291 : std::set<Tag> t = tags().tags("accessibility"); 292 : assert_eq(t.size(), 10u); 293 : 294 : t = tags().tags("works-with-format"); 295 : assert_eq(t.size(), 33u); 296 : } 297 : 298 : // If there is no data, Vocabulary should work as an empty vocabulary 299 1 : Test _21() 300 : { 301 1 : Path::OverrideDebtagsSourceDir odsd("./empty"); 302 2 : Path::OverrideDebtagsIndexDir odid("./empty"); 303 2 : Path::OverrideDebtagsUserSourceDir odusd("./empty"); 304 2 : Path::OverrideDebtagsUserIndexDir oduid("./empty"); 305 1 : Vocabulary empty; 306 : 307 1 : assert(!empty.hasData()); 308 : 309 1 : set<Facet> facets = empty.facets(); 310 1 : assert_eq(facets.size(), 0u); 311 : 312 1 : set<Tag> tags = empty.tags(); 313 1 : assert_eq(tags.size(), 0u); 314 1 : } 315 : 316 : }; 317 : 318 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : #ifndef EPT_DEBTAGS_TAG_H 3 : #define EPT_DEBTAGS_TAG_H 4 : 5 : /** \file 6 : * Debtags facets and tags 7 : */ 8 : 9 : /* 10 : * Copyright (C) 2005,2006,2007 Enrico Zini <enrico@debian.org> 11 : * 12 : * This program is free software; you can redistribute it and/or modify 13 : * it under the terms of the GNU General Public License as published by 14 : * the Free Software Foundation; either version 2 of the License, or 15 : * (at your option) any later version. 16 : * 17 : * This program is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 : * GNU General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU General Public License 23 : * along with this program; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : #include <set> 28 : #include <string> 29 : 30 : namespace ept { 31 : namespace debtags { 32 : 33 : class Vocabulary; 34 : 35 : class Tag; 36 : 37 : /** 38 : * Representation of a facet. 39 : * 40 : * ept::debtags::Facet represents a Facet with all its informations. 41 : * It is guaranteed to have fast value-copy semantics, so it can be passed 42 : * around freely and efficiently without worrying about memory management 43 : * issues. 44 : * 45 : * The class is normally instantiated using a Vocabulary: 46 : * \code 47 : * Facet facet = vocabulary.faceByName("made-of"); 48 : * \endcode 49 : * 50 : * Facets can contain an "invalid" value, in which case using any of their 51 : * methods will likely produce segfault. The "invalid" facets are useful as 52 : * "none" return values: 53 : * 54 : * \code 55 : * Facet facet = vocabulary.facetByName("made-of"); 56 : * if (!facet) 57 : * throw SomeException("facet \"made-of\" has not been defined"); 58 : * \endcode 59 : */ 60 : class Facet 61 : { 62 : protected: 63 : const Vocabulary* m_tags; 64 : int m_id; 65 : 66 120 : Facet(const Vocabulary* tags, int id) : m_tags(tags), m_id(id) {} 67 : 68 : public: 69 : Facet() : m_tags(0), m_id(-1) {} 70 265 : ~Facet() {} 71 : 72 29 : bool operator==(const Facet& f) const { return m_id == f.m_id; } 73 : bool operator!=(const Facet& f) const { return m_id != f.m_id; } 74 600 : bool operator<(const Facet& f) const { return m_id < f.m_id; } 75 : 76 : /** 77 : * Return true if the facet is valid 78 : */ 79 0 : operator bool() const { return m_id != -1; } 80 353 : bool valid() const { return m_id != -1; } 81 : 82 : /** 83 : * Return the name of the facet 84 : * @throws std::out_of_range if the facet is not valid 85 : */ 86 : std::string name() const; 87 : /** 88 : * Return the name of the facet 89 : * 90 : * Returns d if the facet is not valid. 91 : */ 92 : std::string name(const std::string& d) const; 93 : 94 : /** 95 : * Return the short description of the facet 96 : * @throws std::out_of_range if the facet is not valid 97 : */ 98 : std::string shortDescription() const; 99 : /** 100 : * Return the short description of the facet 101 : * 102 : * Returns d if the facet is not valid. 103 : */ 104 : std::string shortDescription(const std::string& d) const; 105 : 106 : /** 107 : * Return the long description of the facet 108 : * @throws std::out_of_range if the facet is not valid 109 : */ 110 : std::string longDescription() const; 111 : /** 112 : * Return the long description of the facet 113 : * 114 : * Returns d if the facet is not valid. 115 : */ 116 : std::string longDescription(const std::string& d) const; 117 : 118 : /** 119 : * Return true if the facet has a tag with the given name (name, not fullname) 120 : */ 121 : bool hasTag(const std::string& name) const; 122 : 123 : /** 124 : * Return the list of tags in this facet 125 : */ 126 : std::set<Tag> tags() const; 127 : 128 : /** 129 : * Return the ID of this facet 130 : * 131 : * @warning This method is exported to help in writing tests, but it is not 132 : * part of the normal API: do not use it, because future implementations may 133 : * not be based on IDs and therefore not have this method. 134 : */ 135 58 : int id() const { return m_id; } 136 : 137 : friend class Vocabulary; 138 : }; 139 : 140 : /** 141 : * Representation of a tag. 142 : * 143 : * ept::debtags::Tag represents a Tag with all its informations. 144 : * It is guaranteed to have fast value-copy semantics, so it can be passed 145 : * around freely and efficiently without worrying about memory management 146 : * issues. 147 : * 148 : * The class is normally instantiated using a Vocabulary: 149 : * \code 150 : * Tag tag = vocabulary.tagByName("made-of::lang:c++"); 151 : * \endcode 152 : * 153 : * Tags can contain an "invalid" value, in which case using any of their 154 : * methods will likely produce segfault. The "invalid" facets are useful as 155 : * "none" return values: 156 : * 157 : * \code 158 : * Tag tag = vocabulary.tagByName("made-of"); 159 : * if (!tag) 160 : * throw SomeException("tag \"mytag\" has not been defined"); 161 : * \endcode 162 : */ 163 : class Tag 164 : { 165 : protected: 166 : const Vocabulary* m_tags; 167 : int m_id; 168 : 169 745056 : Tag(const Vocabulary* tags, int id) : m_tags(tags), m_id(id) {} 170 : 171 : public: 172 : typedef std::set< Tag > Set; 173 : 174 2 : Tag() : m_tags(0), m_id(-1) {} 175 2229812 : ~Tag() {} 176 : 177 1228 : bool operator==(const Tag& f) const { return m_id == f.m_id; } 178 5 : bool operator!=(const Tag& f) const { return m_id != f.m_id; } 179 2300524 : bool operator<(const Tag& f) const { return m_id < f.m_id; } 180 : 181 1 : operator bool() const { return m_id != -1; } 182 324422 : bool valid() const { return m_id != -1; } 183 : 184 : Facet facet() const; 185 : 186 : /** 187 : * Return the name of the tag, without the facet:: prefix 188 : * @throws std::out_of_range if the tag is not valid 189 : */ 190 : std::string name() const; 191 : /** 192 : * Return the short description of the tag 193 : * 194 : * Returns d if the tag is not valid. 195 : */ 196 : std::string name(const std::string& d) const; 197 : 198 : /** 199 : * Return the name of the tag, with the facet:: prefix 200 : * @throws std::out_of_range if the tag is not valid 201 : */ 202 : std::string fullname() const; 203 : /** 204 : * Return the short description of the tag 205 : * 206 : * Returns d if the tag is not valid. 207 : */ 208 : std::string fullname(const std::string& d) const; 209 : 210 : /** 211 : * Return the short description of the tag 212 : * @throws std::out_of_range if the tag is not valid 213 : */ 214 : std::string shortDescription() const; 215 : /** 216 : * Return the short description of the tag 217 : * 218 : * Returns d if the tag is not valid. 219 : */ 220 : std::string shortDescription(const std::string& d) const; 221 : 222 : /** 223 : * Return the long description of the tag 224 : * 225 : * @throws std::out_of_range if the tag is not valid 226 : */ 227 : std::string longDescription() const; 228 : /** 229 : * Return the long description of the tag 230 : * 231 : * Returns d if the tag is not valid. 232 : */ 233 : std::string longDescription(const std::string& d) const; 234 : 235 : /** 236 : * Return the ID of this tag 237 : * 238 : * @warning This method is exported to help in writing tests, but it is not 239 : * part of the normal API: do not use it, because future implementations may 240 : * not be based on IDs and therefore not have this method. 241 : */ 242 106853 : int id() const { return m_id; } 243 : 244 : friend class Vocabulary; 245 : }; 246 : 247 : } 248 : } 249 : 250 : // vim:set ts=3 sw=3: 251 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* -*- C++ -*- 2 : * Tag vocabulary access 3 : * 4 : * Copyright (C) 2003--2007 Enrico Zini <enrico@debian.org> 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 2 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, write to the Free Software 18 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : */ 20 : 21 : #include <ept/debtags/vocabulary.h> 22 : #include <ept/debtags/maint/vocabularyindexer.h> 23 : #include <ept/debtags/maint/debdbparser.h> 24 : #include <ept/debtags/maint/path.h> 25 : 26 : #include <tagcoll/input/memory.h> 27 : 28 : #include <cstring> 29 : #include <sstream> 30 : 31 : #include <sys/types.h> 32 : #include <sys/stat.h> 33 : #include <fcntl.h> 34 : #include <sys/mman.h> 35 : 36 : using namespace tagcoll; 37 : 38 : namespace ept { 39 : namespace debtags { 40 : 41 9 : int Vocabulary::FacetIndex::id(const char* name) const 42 : { 43 9 : if (size() == 0) return -1; 44 : int begin, end; 45 : 46 : /* Binary search */ 47 9 : begin = -1, end = size(); 48 62 : while (end - begin > 1) 49 : { 50 44 : int cur = (end + begin) / 2; 51 44 : if (strcmp(item(cur)->name, name) > 0) 52 16 : end = cur; 53 : else 54 28 : begin = cur; 55 : } 56 : 57 9 : if (begin == -1 || strcmp(item(begin)->name, name) != 0) 58 : //throw NotFoundException(string("looking for the ID of string ") + str); 59 3 : return -1; 60 : else 61 6 : return begin; 62 : } 63 : 64 1105769 : int tagcmp(const char* tag1, const char* tag2) 65 : { 66 1105769 : const char* tsep1 = strstr(tag1, "::"); 67 1105769 : if (tsep1 == NULL) return strcmp(tag1, tag2); 68 1105766 : const char* tsep2 = strstr(tag2, "::"); 69 1105766 : if (tsep2 == NULL) return strcmp(tag1, tag2); 70 : 71 : // See what is the length of the shortest facet 72 1105766 : int len1 = tsep1 - tag1; 73 1105766 : int len2 = tsep2 - tag2; 74 1105766 : int minlen = len1 < len2 ? len1 : len2; 75 : 76 1105766 : int res = strncmp(tag1, tag2, minlen); 77 1105766 : if (res != 0) 78 : // Different facets 79 454813 : return res; 80 : 81 650953 : if (len1 == len2) 82 : // If the facet is the same, compare the tags 83 639402 : return strcmp(tsep1 + 2, tsep2 + 2); 84 : else 85 : // Two facets with similar prefixes 86 11551 : return len1 < len2 ? -1 : 1; 87 : } 88 : 89 106377 : int Vocabulary::TagIndex::id(const char* name) const 90 : { 91 106377 : if (size() == 0) return -1; 92 : int begin, end; 93 : 94 : /* Binary search */ 95 106377 : begin = -1, end = size(); 96 1212130 : while (end - begin > 1) 97 : { 98 999376 : int cur = (end + begin) / 2; 99 999376 : if (tagcmp(item(cur)->name, name) > 0) 100 432389 : end = cur; 101 : else 102 566987 : begin = cur; 103 : } 104 : 105 106377 : if (begin == -1 || tagcmp(item(begin)->name, name) != 0) 106 : //throw NotFoundException(string("looking for the ID of string ") + str); 107 132 : return -1; 108 : else 109 106245 : return begin; 110 : } 111 : 112 31 : Vocabulary::Vocabulary() 113 31 : : voc_fd(-1), voc_size(0), voc_buf(0) 114 : { 115 31 : std::string vocfname; 116 31 : std::string idxfname; 117 : 118 31 : if (!VocabularyIndexer::obtainWorkingVocabulary(vocfname, idxfname)) 119 : { 120 2 : m_timestamp = 0; 121 2 : return; 122 : } 123 : 124 29 : m_timestamp = Path::timestamp(idxfname); 125 : 126 29 : mastermmap.init(idxfname); 127 : 128 : // Initialize the facet and tag indexes 129 29 : findex.init(mastermmap, 0); 130 29 : tindex.init(mastermmap, 1); 131 : 132 : // MMap the vocabulary 133 : 134 : // Open the file 135 29 : voc_fname = vocfname; 136 29 : if ((voc_fd = open(voc_fname.c_str(), O_RDONLY)) == -1) 137 0 : throw wibble::exception::File(voc_fname, "opening vocabulary file"); 138 : 139 29 : off_t size = lseek(voc_fd, 0, SEEK_END); 140 29 : if (size == (off_t)-1) 141 0 : throw wibble::exception::File(voc_fname, "reading the size of vocabulary file"); 142 29 : voc_size = size; 143 : 144 : // Map the file into memory 145 29 : if ((voc_buf = (const char*)mmap(0, voc_size, PROT_READ, MAP_PRIVATE, voc_fd, 0)) == MAP_FAILED) 146 0 : throw wibble::exception::File(voc_fname, "mmapping vocabulary file"); 147 0 : } 148 : 149 31 : Vocabulary::~Vocabulary() 150 : { 151 : // Unmap and close the file 152 31 : if (voc_buf) 153 29 : munmap((void*)voc_buf, voc_size); 154 31 : if (voc_fd != -1) 155 29 : close(voc_fd); 156 31 : } 157 : 158 120 : Facet Vocabulary::facetByID(int id) const 159 : { 160 120 : return Facet(this, id); 161 : } 162 : 163 745056 : Tag Vocabulary::tagByID(int id) const 164 : { 165 745056 : return Tag(this, id); 166 : } 167 : 168 1301 : void Vocabulary::parseVocBuf(std::map<std::string, std::string>& res, size_t ofs, size_t len) const 169 : { 170 : // Access the right part of the mmapped buffer 171 1301 : std::stringstream name; 172 1301 : name << voc_fname << '+' << ofs << '-' << len; 173 1301 : input::Memory in(name.str(), voc_buf + ofs, len); 174 1301 : DebDBParser parser(in); 175 : // Parse the raw string data and store it in the cache vector 176 1301 : parser.nextRecord(res); 177 : 178 1301 : std::string desc = res["Description"]; 179 2602 : if (!desc.empty()) 180 : { 181 1298 : size_t pos = desc.find('\n'); 182 1298 : if (pos == std::string::npos) 183 849 : res["_SD_"] = desc; 184 : else 185 449 : res["_SD_"] = desc.substr(0, pos); 186 1301 : } 187 1301 : } 188 : 189 1863 : std::string Vocabulary::tagShortName(int id) const 190 : { 191 1863 : const char* fullname = tindex.name(id); 192 1863 : char* sub = strstr(fullname, "::"); 193 1863 : if (sub != NULL) 194 1863 : return sub + 2; 195 : else 196 0 : return fullname; 197 : } 198 : 199 176 : const std::map<std::string, std::string>& Vocabulary::facetData(int id) const 200 : { 201 176 : if (id < 0) return emptyData; 202 : 203 : // Enlarge the cache vector if needed 204 176 : if ((unsigned)id >= m_facetData.size()) 205 59 : m_facetData.resize(id + 1); 206 : 207 176 : if (m_facetData[id].empty()) 208 59 : parseVocBuf(m_facetData[id], findex.offset(id), findex.size(id)); 209 : 210 176 : return m_facetData[id]; 211 : } 212 : 213 3722 : const std::map<std::string, std::string>& Vocabulary::tagData(int id) const 214 : { 215 3722 : if (id < 0) return emptyData; 216 : 217 : // Enlarge the cache vector if needed 218 3722 : if ((unsigned)id >= m_tagData.size()) 219 1242 : m_tagData.resize(id + 1); 220 : 221 3722 : if (m_tagData[id].empty()) 222 1242 : parseVocBuf(m_tagData[id], tindex.offset(id), tindex.size(id)); 223 : 224 3722 : return m_tagData[id]; 225 : } 226 : 227 : } 228 6 : } 229 : 230 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** -*- C++ -*- 2 : * @file 3 : * @author Enrico Zini (enrico) <enrico@enricozini.org> 4 : */ 5 : 6 : /* 7 : * System tag database 8 : * 9 : * Copyright (C) 2003-2008 Enrico Zini <enrico@debian.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <ept/debtags/debtags.h> 27 : #include <ept/debtags/maint/path.h> 28 : #include <ept/debtags/maint/serializer.h> 29 : #include <ept/debtags/maint/debtagsindexer.h> 30 : 31 : #include <tagcoll/input/stdio.h> 32 : #include <tagcoll/TextFormat.h> 33 : 34 : #include <wibble/sys/fs.h> 35 : #include <wibble/string.h> 36 : 37 : #include <iostream> 38 : #include <sstream> 39 : 40 : #include <sys/wait.h> // WIFEXITED WEXITSTATUS 41 : #include <sys/types.h> // getpwuid, stat, mkdir, getuid 42 : #include <sys/stat.h> // stat, mkdir 43 : #include <pwd.h> // getpwuid 44 : #include <unistd.h> // stat, getuid 45 : 46 : 47 : using namespace std; 48 : using namespace tagcoll; 49 : using namespace wibble; 50 : 51 : namespace ept { 52 : namespace debtags { 53 : 54 10 : Debtags::Debtags(bool editable) 55 10 : : m_coll(m_rocoll) 56 : { 57 10 : std::string tagfname; 58 10 : std::string idxfname; 59 : 60 10 : if (!DebtagsIndexer::obtainWorkingDebtags(vocabulary(), tagfname, idxfname)) 61 : { 62 1 : m_timestamp = 0; 63 1 : return; 64 : } else { 65 9 : m_timestamp = Path::timestamp(idxfname); 66 : 67 9 : mastermmap.init(idxfname); 68 : 69 : // Initialize the readonly index 70 9 : m_pkgid.init(mastermmap, 0); 71 9 : m_rocoll.init(mastermmap, 1, 2); 72 : } 73 : 74 : // Initialize the patch collection layer 75 9 : rcdir = Path::debtagsUserSourceDir(); 76 : 77 9 : string patchFile = str::joinpath(rcdir, "patch"); 78 18 : if (Path::access(patchFile, F_OK) == 0) 79 : { 80 0 : input::Stdio in(patchFile); 81 0 : PatchList<int, int> patch; 82 0 : textformat::parsePatch(in, patchStringToInt(m_pkgid, vocabulary(), inserter(patch))); 83 0 : m_coll.setChanges(patch); 84 9 : } 85 0 : } 86 : 87 3 : tagcoll::PatchList<std::string, Tag> Debtags::changes() const 88 : { 89 3 : tagcoll::PatchList<int, int> patches = m_coll.changes(); 90 3 : tagcoll::PatchList<std::string, Tag> res; 91 : 92 5 : for (tagcoll::PatchList<int, int>::const_iterator i = patches.begin(); 93 : i != patches.end(); ++i) 94 : { 95 2 : std::string pkg = packageByID(i->second.item); 96 2 : if (pkg.empty()) 97 0 : continue; 98 : 99 : res.addPatch(tagcoll::Patch<std::string, Tag>(pkg, 100 : vocabulary().tagsByID(i->second.added), 101 2 : vocabulary().tagsByID(i->second.removed))); 102 : } 103 : 104 3 : return res; 105 : } 106 : 107 : 108 : #if 0 109 : bool Debtags::hasTagDatabase() 110 : { 111 : if (Path::access(Path::tagdb(), R_OK) == -1) 112 : { 113 : std::cerr << "Missing tag database " << Path::tagdb() << std::endl; 114 : return false; 115 : } 116 : if (Path::access(Path::tagdbIndex(), R_OK) == -1) 117 : { 118 : std::cerr << "Missing tag database index " << Path::tagdbIndex() << std::endl; 119 : return false; 120 : } 121 : if (Path::access(Path::vocabulary(), R_OK) == -1) 122 : { 123 : std::cerr << "Missing tag vocabulary " << Path::vocabulary() << std::endl; 124 : return false; 125 : } 126 : if (Path::access(Path::vocabularyIndex(), R_OK) == -1) 127 : { 128 : std::cerr << "Missing index for tag vocabulary " << Path::vocabularyIndex() << std::endl; 129 : return false; 130 : } 131 : return true; 132 : } 133 : #endif 134 : 135 : 136 1 : void Debtags::savePatch() 137 : { 138 1 : PatchList<std::string, std::string> spatch; 139 1 : m_coll.changes().output(patchIntToString(m_pkgid, vocabulary(), tagcoll::inserter(spatch))); 140 1 : savePatch(spatch); 141 1 : } 142 : 143 1 : void Debtags::savePatch(const PatchList<std::string, std::string>& patch) 144 : { 145 1 : std::string patchFile = str::joinpath(rcdir, "patch"); 146 1 : std::string backup = patchFile + "~"; 147 : 148 1 : wibble::sys::fs::mkFilePath(patchFile); 149 : 150 1 : if (access(patchFile.c_str(), F_OK) == 0) 151 0 : if (rename(patchFile.c_str(), backup.c_str()) == -1) 152 0 : throw wibble::exception::System("Can't rename " + patchFile + " to " + backup); 153 : 154 : try { 155 1 : FILE* out = fopen(patchFile.c_str(), "w"); 156 1 : if (out == 0) 157 0 : throw wibble::exception::System("Can't write to " + patchFile); 158 : 159 1 : textformat::outputPatch(patch, out); 160 : 161 1 : fclose(out); 162 0 : } catch (std::exception& e) { 163 0 : if (rename(backup.c_str(), patchFile.c_str()) == -1) 164 0 : std::cerr << "Warning: Cannot restore previous backup copy: " << e.what() << std::endl; 165 0 : throw; 166 1 : } 167 1 : } 168 : 169 0 : void Debtags::savePatch(const PatchList<std::string, Tag>& patch) 170 : { 171 0 : PatchList<std::string, std::string> spatch; 172 : // patch.output(patchToString<C>(m_pkgs, m_pkgidx, m_tags, tagcoll::inserter(spatch))); 173 0 : savePatch(spatch); 174 0 : } 175 : 176 0 : void Debtags::sendPatch() 177 : { 178 0 : PatchList<std::string, std::string> spatch; 179 0 : m_coll.changes().output(patchIntToString(m_pkgid, vocabulary(), tagcoll::inserter(spatch))); 180 0 : if (!spatch.empty()) 181 : { 182 0 : sendPatch(spatch); 183 0 : } 184 0 : } 185 : 186 0 : void Debtags::sendPatch(const PatchList<std::string, Tag>& patch) 187 : { 188 0 : PatchList<std::string, std::string> spatch; 189 : // patch.output(patchToString<C>(m_pkgs, m_pkgidx, m_tags, tagcoll::inserter(spatch))); 190 0 : sendPatch(spatch); 191 0 : } 192 : 193 0 : void Debtags::sendPatch(const PatchList<std::string, std::string>& patch) 194 : { 195 : static const char* cmd = "/usr/sbin/sendmail -t"; 196 0 : FILE* out = popen(cmd, "w"); 197 0 : if (out == 0) 198 0 : throw wibble::exception::System(std::string("trying to run `") + cmd + "'"); 199 : 200 0 : struct passwd* udata = getpwuid(getuid()); 201 : 202 : fprintf(out, 203 : "To: enrico-debtags@debian.org\n" 204 : "Bcc: %s\n" 205 : "Subject: Tag patch\n" 206 : "Mime-Version: 1.0\n" 207 : "Content-Type: multipart/mixed; boundary=\"9amGYk9869ThD9tj\"\n" 208 : "Content-Disposition: inline\n" 209 : "X-Mailer: debtags-edit\n\n" 210 : "This mail contains a Debtags patch for the central archive\n\n" 211 : "--9amGYk9869ThD9tj\n" 212 : "Content-Type: text/plain; charset=utf-8\n" 213 : "Content-Disposition: inline\n\n" 214 0 : "-- DEBTAGS DIFF V0.1 --\n", udata->pw_name); 215 : 216 0 : textformat::outputPatch(patch, out); 217 : 218 0 : fprintf(out, "\n--9amGYk9869ThD9tj\n"); 219 : 220 0 : int res = pclose(out); 221 0 : if (!WIFEXITED(res) || WEXITSTATUS(res) != 0) 222 : { 223 0 : std::stringstream str; 224 0 : str << res; 225 0 : throw wibble::exception::Consistency("checking mailer exit status", "sendmail returned nonzero (" + str.str() + "): the mail may have not been sent"); 226 : } 227 0 : } 228 : 229 : 230 : template<typename OUT> 231 : void Debtags::outputSystem(const OUT& cons) 232 : { 233 : m_rocoll.output(intToPkg(m_pkgid, vocabulary(), cons)); 234 : } 235 : 236 : template<typename OUT> 237 : void Debtags::outputPatched(const OUT& cons) 238 : { 239 : m_coll.output(intToPkg(m_pkgid, vocabulary(), cons)); 240 : } 241 : 242 : } 243 : } 244 : 245 : #include <tagcoll/patch.tcc> 246 : #include <tagcoll/coll/patched.tcc> 247 : #include <tagcoll/TextFormat.tcc> 248 : //#include <tagcoll/stream/filters.tcc> 249 : 250 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 2 : /* @file 3 : * @author Enrico Zini (enrico) <enrico@enricozini.org> 4 : */ 5 : 6 : /* 7 : * libpkg Debtags data provider 8 : * 9 : * Copyright (C) 2003-2007 Enrico Zini <enrico@debian.org> 10 : * 11 : * This program is free software; you can redistribute it and/or modify 12 : * it under the terms of the GNU General Public License as published by 13 : * the Free Software Foundation; either version 2 of the License, or 14 : * (at your option) any later version. 15 : * 16 : * This program is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 : * GNU General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU General Public License 22 : * along with this program; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #ifndef EPT_DEBTAGS_DEBTAGS_H 27 : #define EPT_DEBTAGS_DEBTAGS_H 28 : 29 : #include <ept/debtags/tag.h> 30 : #include <ept/debtags/vocabulary.h> 31 : #include <ept/debtags/maint/pkgid.h> 32 : 33 : #include <tagcoll/coll/base.h> 34 : #include <tagcoll/coll/intdiskindex.h> 35 : #include <tagcoll/coll/patched.h> 36 : 37 : namespace ept { 38 : namespace debtags { 39 : class Debtags; 40 : } 41 : } 42 : 43 : namespace tagcoll { 44 : template< typename _, typename _1 > class PatchList; 45 : 46 : namespace coll { 47 : 48 : template<> 49 : struct coll_traits< ept::debtags::Debtags > 50 : { 51 : typedef std::string item_type; 52 : typedef ept::debtags::Tag tag_type; 53 : typedef std::set< ept::debtags::Tag > tagset_type; 54 : typedef std::set< std::string > itemset_type; 55 : }; 56 : 57 : } 58 : } 59 : 60 : namespace ept { 61 : namespace debtags { 62 : 63 : /** 64 : * Access the on-disk Debtags tag database. 65 : * 66 : * The database is normally found in /var/lib/debtags. 67 : * 68 : * Tags and Facets are returned as Tag and Facet objects. The objects follow 69 : * the flyweight pattern and access the data contained in the Vocabulary 70 : * instantiated inside Debtags. 71 : * 72 : * It is possible to get a reference to the Vocabulary object using the 73 : * vocabulary() method. 74 : */ 75 : class Debtags : public tagcoll::coll::Collection<Debtags> 76 : { 77 : protected: 78 : // Master mmap index container 79 : tagcoll::diskindex::MasterMMap mastermmap; 80 : 81 : // Debtags database 82 : tagcoll::coll::IntDiskIndex m_rocoll; 83 : tagcoll::coll::Patched< tagcoll::coll::IntDiskIndex > m_coll; 84 : 85 : // Package name to ID mapping 86 : PkgId m_pkgid; 87 : 88 : // Tag vocabulary 89 : Vocabulary m_voc; 90 : 91 : // User rc directory to store patches 92 : std::string rcdir; 93 : 94 : // Last modification timestamp of the index 95 : time_t m_timestamp; 96 : 97 84710 : std::string packageByID(int id) const 98 : { 99 84710 : return m_pkgid.byID(id); 100 : } 101 : 102 : template<typename IDS> 103 2 : std::set<std::string> packagesById(const IDS& ids) const 104 : { 105 2 : std::set<std::string> pkgs; 106 130 : for (typename IDS::const_iterator i = ids.begin(); 107 : i != ids.end(); ++i) 108 128 : pkgs.insert(packageByID(*i)); 109 0 : return pkgs; 110 : } 111 : 112 8 : int idByPackage(const std::string& pkg) const 113 : { 114 8 : return m_pkgid.byName(pkg); 115 : } 116 : 117 : template<typename PKGS> 118 1 : std::set<int> idsByPackages(const PKGS& pkgs) const 119 : { 120 1 : std::set<int> ids; 121 2 : for (typename PKGS::const_iterator i = pkgs.begin(); 122 : i != pkgs.end(); ++i) 123 1 : ids.insert(idByPackage(*i)); 124 0 : return ids; 125 : } 126 : 127 : public: 128 : typedef tagcoll::coll::Patched< tagcoll::coll::IntDiskIndex > coll_type; 129 : typedef std::pair< std::string, std::set<Tag> > value_type; 130 : 131 : class const_iterator 132 : { 133 : const Debtags& coll; 134 : Debtags::coll_type::const_iterator ci; 135 : mutable const Debtags::value_type* cached_val; 136 : 137 : protected: 138 : const_iterator(const Debtags& coll, 139 63443 : const Debtags::coll_type::const_iterator& ci) 140 63443 : : coll(coll), ci(ci), cached_val(0) {} 141 : 142 : public: 143 63443 : ~const_iterator() 144 : { 145 63443 : if (cached_val) 146 0 : delete cached_val; 147 63443 : } 148 84580 : const Debtags::value_type operator*() const 149 : { 150 84580 : if (cached_val) 151 0 : return *cached_val; 152 : 153 84580 : return make_pair(coll.packageByID(ci->first), coll.vocabulary().tagsByID(ci->second)); 154 : } 155 105725 : const Debtags::value_type* operator->() const 156 : { 157 105725 : if (cached_val) 158 42290 : return cached_val; 159 63435 : return cached_val = new Debtags::value_type(*(*this)); 160 : } 161 63435 : const_iterator& operator++() 162 : { 163 63435 : ++ci; 164 63435 : if (cached_val) 165 : { 166 63435 : delete cached_val; 167 63435 : cached_val = 0; 168 : } 169 63435 : return *this; 170 : } 171 1 : bool operator==(const const_iterator& iter) const 172 : { 173 1 : return ci == iter.ci; 174 : } 175 63438 : bool operator!=(const const_iterator& iter) const 176 : { 177 63438 : return ci != iter.ci; 178 : } 179 : 180 : friend class Debtags; 181 : }; 182 4 : const_iterator begin() const { return const_iterator(*this, m_coll.begin()); } 183 63439 : const_iterator end() const { return const_iterator(*this, m_coll.end()); } 184 : 185 : /** 186 : * Create a new accessor for the on-disk Debtags database 187 : * 188 : * \param editable 189 : * Specifies if recording of modifications should be enabled. If editable 190 : * is true, then the local state directory will be created when the object 191 : * is instantiated. 192 : */ 193 : Debtags(bool editable = false); 194 10 : ~Debtags() {} 195 : 196 : /// Get the timestamp of when the index was last updated 197 1 : time_t timestamp() const { return m_timestamp; } 198 : 199 : /// Return true if this data source has data, false if it's empty 200 1 : bool hasData() const { return m_timestamp != 0; } 201 : 202 : coll_type& tagdb() { return m_coll; } 203 : const coll_type& tagdb() const { return m_coll; } 204 : tagcoll::PatchList<std::string, Tag> changes() const; 205 : 206 : #if 0 207 : template<typename ITEMS, typename TAGS> 208 : void insert(const ITEMS& items, const TAGS& tags) 209 : { 210 : for (typename ITEMS::const_iterator i = items.begin(); 211 : i != items.end(); ++i) 212 : m_changes.addPatch(Patch(*i, tags, TagSet())); 213 : } 214 : 215 : template<typename ITEMS> 216 : void insert(const ITEMS& items, const wibble::Empty<Tag>& tags) 217 : { 218 : // Nothing to do in this case 219 : } 220 : 221 : /** 222 : * Get the changes that have been applied to this collection 223 : */ 224 : const Patches& changes() const { return m_changes; } 225 : 226 : /** 227 : * Throw away all changes previously applied to this collection 228 : */ 229 : void resetChanges() { m_changes.clear(); } 230 : 231 : /** 232 : * Set the changes list to a specific patch list 233 : */ 234 : void setChanges(const Patches& changes); 235 : 236 : /** 237 : * Add a specific patch list to the changes list 238 : */ 239 : void addChanges(const Patches& changes); 240 : #endif 241 : 242 : bool hasTag(const Tag& tag) const { return m_coll.hasTag(tag.id()); } 243 : 244 5 : std::set<Tag> getTagsOfItem(const std::string& item) const 245 : { 246 5 : int id = idByPackage(item); 247 5 : if (id == -1) return std::set<Tag>(); 248 4 : return vocabulary().tagsByID(m_coll.getTagsOfItem(id)); 249 : } 250 : 251 : template<typename ITEMS> 252 1 : std::set<Tag> getTagsOfItems(const ITEMS& items) const 253 : { 254 1 : return vocabulary().tagsByID(m_coll.getTagsOfItems(idsByPackages(items))); 255 : } 256 : 257 : std::set<std::string> getItemsHavingTag(const Tag& tag) const 258 : { 259 : return packagesById(m_coll.getItemsHavingTag(tag.id())); 260 : } 261 : template<typename TAGS> 262 2 : std::set<std::string> getItemsHavingTags(const TAGS& tags) const 263 : { 264 2 : std::set<int> itags; 265 11 : for (typename TAGS::const_iterator i = tags.begin(); 266 : i != tags.end(); ++i) 267 9 : itags.insert(i->id()); 268 2 : return packagesById(m_coll.getItemsHavingTags(itags)); 269 : } 270 : 271 : #if 0 272 : ItemSet getTaggedItems() const; 273 : #endif 274 1 : std::set<Tag> getAllTags() const 275 : { 276 1 : return vocabulary().tagsByID(m_coll.getAllTags()); 277 : } 278 : 279 : /// Access the vocabulary in use 280 27 : Vocabulary& vocabulary() { return m_voc; } 281 : /// Access the vocabulary in use 282 84590 : const Vocabulary& vocabulary() const { return m_voc; } 283 : 284 : /** 285 : * Access the PkgId in use. 286 : * 287 : * \note Future implementations may not rely on a PkgId 288 : */ 289 4 : PkgId& pkgid() { return m_pkgid; } 290 : /** 291 : * Access the PkgId in use. 292 : * 293 : * \note Future implementations may not rely on a PkgId 294 : */ 295 : const PkgId& pkgid() const { return m_pkgid; } 296 : 297 : int getCardinality(const Tag& tag) const 298 : { 299 : return m_coll.getCardinality(tag.id()); 300 : } 301 : 302 2 : void applyChange(const tagcoll::PatchList<std::string, Tag>& change) 303 : { 304 : using namespace tagcoll; 305 2 : PatchList<int, int> intp; 306 4 : for (PatchList<std::string, Tag>::const_iterator i = change.begin(); 307 : i != change.end(); ++i) 308 : { 309 2 : Patch<int, int> p(idByPackage(i->first)); 310 4 : for (std::set<Tag>::const_iterator j = i->second.added.begin(); 311 : j != i->second.added.end(); ++j) 312 2 : p.add(j->id()); 313 2 : for (std::set<Tag>::const_iterator j = i->second.removed.begin(); 314 : j != i->second.removed.end(); ++j) 315 0 : p.remove(j->id()); 316 2 : intp.addPatch(p); 317 : } 318 2 : m_coll.applyChange(intp); 319 2 : } 320 : 321 : #if 0 322 : template<typename OUT> 323 : void output(OUT out) const 324 : { 325 : for (const_iterator i = begin(); i != end(); ++i) 326 : { 327 : *out = *i; 328 : ++out; 329 : } 330 : } 331 : #endif 332 : 333 : 334 : 335 : /** 336 : * Check if the tag database has been created (i.e. if something 337 : * equivalend to debtags update has been run) 338 : */ 339 : //static bool hasTagDatabase(); 340 : 341 : 342 : /** 343 : * Save in the state storage directory a patch that can be used to turn 344 : * the system database into the collection given 345 : */ 346 : void savePatch(); 347 : 348 : /** 349 : * Save in the state storage directory a patch to turn the system database 350 : * into the collection given 351 : */ 352 : void savePatch(const tagcoll::PatchList<std::string, std::string>& patch); 353 : 354 : /** 355 : * Save in the state storage directory a patch to turn the system database 356 : * into the collection given 357 : */ 358 : void savePatch(const tagcoll::PatchList<std::string, Tag>& patch); 359 : 360 : /** 361 : * Send to the central archive a patch that can be used to turn 362 : * the system database into the collection given 363 : */ 364 : void sendPatch(); 365 : 366 : /** 367 : * Send the given patch to the central archive 368 : */ 369 : void sendPatch(const tagcoll::PatchList<std::string, std::string>& patch); 370 : 371 : /** 372 : * Send the given patch to the central archive 373 : */ 374 : void sendPatch(const tagcoll::PatchList<std::string, Tag>& patch); 375 : 376 : 377 : /** 378 : * Output the current Debian tags database to a consumer of <std::string, Tag> 379 : * 380 : * \note The collection is sent to 'cons' without merging repeated items 381 : */ 382 : template<typename OUT> 383 2 : void outputSystem(const OUT& cons); 384 : 385 : /** 386 : * Output the given tag file to a consumer of <std::string, Tag> 387 : * 388 : * \note The collection is sent to 'cons' without merging repeated items 389 : */ 390 : template<typename OUT> 391 : void outputSystem(const std::string& filename, const OUT& out); 392 : 393 : /** 394 : * Output the current Debian tags database, patched with local patch, 395 : * to a Consumer of <std::string, Tag> 396 : * 397 : * \note The collection is sent to 'cons' without merging repeated items 398 : */ 399 : template<typename OUT> 400 2 : void outputPatched(const OUT& cons); 401 : 402 : /** 403 : * Output the given tag file, patched with local patch, 404 : * to a Consumer of <std::string, Tag> 405 : * 406 : * \note The collection is sent to 'cons' without merging repeated items 407 : */ 408 : template<typename OUT> 409 : void outputPatched(const std::string& filename, const OUT& out); 410 : }; 411 : 412 : 413 : } 414 : } 415 : 416 : // vim:set ts=4 sw=4: 417 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** -*- C++ -*- 2 : * @file 3 : * @author Enrico Zini (enrico) <enrico@enricozini.org> 4 : */ 5 : 6 : /* 7 : * libpkg Debtags data provider 8 : * 9 : * Copyright (C) 2003-2007 Enrico Zini <enrico@debian.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #ifndef EPT_DEBTAGS_DEBTAGS_TCC 27 : #define EPT_DEBTAGS_DEBTAGS_TCC 28 : 29 : #include <ept/debtags/debtags.h> 30 : #include <ept/debtags/maint/serializer.h> 31 : 32 : #include <tagcoll/input/stdio.h> 33 : #include <tagcoll/stream/patcher.h> 34 : #include <tagcoll/TextFormat.h> 35 : 36 : namespace ept { 37 : namespace debtags { 38 : 39 : template<typename OUT> 40 : void Debtags::outputSystem(const OUT& cons) 41 : { 42 2 : m_rocoll.output(intToPkg(m_pkgid, vocabulary(), cons)); 43 2 : } 44 : 45 : template<typename OUT> 46 : void Debtags::outputSystem(const std::string& filename, const OUT& out) 47 : { 48 : if (filename == "-") 49 : { 50 : tagcoll::input::Stdio input(stdin, "<stdin>"); 51 : tagcoll::textformat::parse(input, ept::debtags::stringToPkg(m_pkgid, m_voc, out)); 52 : } 53 : else 54 : { 55 : tagcoll::input::Stdio input(filename); 56 : tagcoll::textformat::parse(input, ept::debtags::stringToPkg(m_pkgid, m_voc, out)); 57 : } 58 : } 59 : 60 : template<typename OUT> 61 : void Debtags::outputPatched(const OUT& cons) 62 : { 63 2 : m_coll.output(intToPkg(m_pkgid, vocabulary(), cons)); 64 2 : } 65 : 66 : template<typename OUT> 67 : void Debtags::outputPatched(const std::string& filename, const OUT& out) 68 : { 69 : const tagcoll::PatchList<string, Tag>& patch = m_coll.changes(); 70 : if (filename == "-") 71 : { 72 : tagcoll::input::Stdio input(stdin, "<stdin>"); 73 : tagcoll::textformat::parse(input, ept::debtags::stringToPkg(m_pkgid, m_voc, patcher(patch, out))); 74 : } 75 : else 76 : { 77 : tagcoll::input::Stdio input(filename); 78 : tagcoll::textformat::parse(input, ept::debtags::stringToPkg(m_pkgid, m_voc, patcher(patch, out))); 79 : } 80 : } 81 : 82 : } 83 : } 84 : 85 : #include <tagcoll/coll/patched.tcc> 86 : 87 : #endif 88 : 89 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 2 : /** 3 : * @file 4 : * @author Enrico Zini (enrico) <enrico@enricozini.org> 5 : */ 6 : 7 : /* 8 : * Test for the Debtags data provider 9 : * 10 : * Copyright (C) 2003-2007 Enrico Zini <enrico@debian.org> 11 : * 12 : * This library is free software; you can redistribute it and/or 13 : * modify it under the terms of the GNU Lesser General Public 14 : * License as published by the Free Software Foundation; either 15 : * version 2.1 of the License, or (at your option) any later version. 16 : * 17 : * This library is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 : * Lesser General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU Lesser General Public 23 : * License along with this library; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : 28 : #include <ept/debtags/debtags.h> 29 : #include <ept/core/apt.h> 30 : 31 : #include <tagcoll/coll/simple.h> 32 : #include <tagcoll/stream/sink.h> 33 : 34 : #include <wibble/operators.h> 35 : 36 : #include <ept/test.h> 37 : 38 : #ifndef EPT_DEBTAGS_TESTH 39 : #define EPT_DEBTAGS_TESTH 40 : 41 : using namespace tagcoll; 42 : using namespace std; 43 : using namespace ept; 44 : using namespace ept::debtags; 45 : using namespace wibble::operators; 46 : 47 : struct TestDebtags : DebtagsTestEnvironment 48 5 : { 49 : Debtags debtags; 50 : 51 5 : TestDebtags() {} 52 : 53 10 : Vocabulary& voc() { return debtags.vocabulary(); } 54 : 55 1 : Test _1() { 56 21146 : for (Debtags::const_iterator i = debtags.begin(); i != debtags.end(); ++i) 57 : { 58 21145 : *i; 59 21145 : i->first; 60 21145 : i->second; 61 1 : } 62 1 : int items = 0, tags = 0; 63 1 : debtags.outputSystem(stream::countingSink(items, tags)); 64 : 65 1 : int pitems = 0, ptags = 0; 66 1 : debtags.outputPatched(stream::countingSink(pitems, ptags)); 67 : 68 2 : assert(items > 10); 69 2 : assert(tags > 10); 70 2 : assert(items <= pitems); 71 2 : assert(tags <= ptags); 72 1 : } 73 : 74 1 : Test _2() 75 : { 76 1 : string p("debtags"); 77 1 : std::set<Tag> tags = debtags.getTagsOfItem(p); 78 1 : assert( !tags.empty() ); 79 : 80 : #if 0 81 : for ( std::set< Tag >::iterator i = tags.begin(); i != tags.end(); ++ i ) { 82 : std::cerr << i->id() << ": " << i->fullname() << std::endl; 83 : } 84 : std::cerr << "---" << std::endl; 85 : Tag t = voc().tagByName( "interface::commandline" ); 86 : std::cerr << t.id() << ": " << t.fullname() << std::endl; 87 : #endif 88 : 89 2 : assert_eq( tags.size(), 8u ); 90 2 : assert( voc().tagByName( "devel::buildtools" ) <= tags ); 91 2 : assert( voc().tagByName( "implemented-in::c++" ) <= tags ); 92 2 : assert( voc().tagByName( "interface::commandline" ) <= tags ); 93 2 : assert( voc().tagByName( "role::program" ) <= tags ); 94 2 : assert( voc().tagByName( "scope::application" ) <= tags ); 95 2 : assert( voc().tagByName( "suite::debian" ) <= tags ); 96 2 : assert( voc().tagByName( "use::searching" ) <= tags ); 97 2 : assert( voc().tagByName( "works-with::software:package" ) <= tags ); 98 1 : } 99 : 100 1 : Test _3() 101 : { 102 : using namespace std; 103 : 104 : /* Get the 'debtags' package */ 105 1 : string p("debtags"); 106 : 107 : /* Get its tags */ 108 1 : std::set<Tag> tags = debtags.getTagsOfItem(p); 109 1 : assert(!tags.empty()); 110 : 111 : /* 112 : cerr << "Intersection size: " << endl; 113 : using namespace wibble::operators; 114 : std::set<Tag>::const_iterator dbgi = tags.begin(); 115 : cerr << "* " << dbgi->fullname() << ": " << dbgi->id() << endl; 116 : std::set<int> dbgres = debtags.tagdb().getItemsHavingTag(dbgi->id()); 117 : std::set<Package> dbgpres = debtags.getItemsHavingTag(*dbgi); 118 : cerr << " #pkgs " << dbgres.size() << " == " << dbgpres.size() << endl; 119 : cerr << " #isec " << dbgres.size() << " == " << dbgpres.size() << endl; 120 : cerr << " "; ppset(dbgpres); cerr << endl; 121 : cerr << " "; piset(dbgres); cerr << endl; 122 : for (++dbgi ; dbgi != tags.end(); ++dbgi) 123 : { 124 : cerr << "* " << dbgi->fullname() << ": " << dbgi->id() << endl; 125 : std::set<Package> dbgpkgs = debtags.getItemsHavingTag(*dbgi); 126 : std::set<int> dbgids = debtags.tagdb().getItemsHavingTag(dbgi->id()); 127 : cerr << " "; ppset(dbgpkgs); cerr << endl; 128 : cerr << " "; piset(dbgids); cerr << endl; 129 : cerr << " #pkgs " << dbgpkgs.size() << " == " << dbgids.size() << endl; 130 : dbgres &= dbgids; 131 : dbgpres &= dbgpkgs; 132 : cerr << " #isec " << dbgres.size() << " == " << dbgpres.size() << endl; 133 : } 134 : cerr << " " << dbgres.size() << endl << "Results: " << endl; 135 : for (std::set<int>::const_iterator i = dbgres.begin(); i != dbgres.end(); ++i) 136 : cerr << " " << *i << endl; 137 : */ 138 : 139 : 140 : // cerr << "Tags of debtags: "; 141 : // for (std::set<Tag>::const_iterator i = tags.begin(); i != tags.end(); ++i) 142 : // { 143 : // cerr << " " + i->fullname() << endl; 144 : // std::set<Package> packages = debtags.getItemsHavingTag(*i); 145 : // for (std::set<Package>::const_iterator p = packages.begin(); 146 : // p != packages.end(); ++p) 147 : // cerr << " PKG " << p->name() << endl; 148 : // } 149 : // cerr << endl; 150 : 151 : /* Get the items for the tagset of 'debtags' */ 152 1 : std::set<string> packages = debtags.getItemsHavingTags(tags); 153 : //cerr << packages.size() << endl; 154 1 : assert(!packages.empty()); 155 : /* 156 : for ( std::set< Package >::iterator i = packages.begin(); i != packages.end(); ++ i ) 157 : std::cerr << i->name() << std::endl; 158 : std::cerr << "---" << std::endl; 159 : std::cerr << p.name() << std::endl; 160 : */ 161 : /* They should at least contain 'debtags' */ 162 2 : assert( p <= packages ); 163 : 164 : /* Get one of the tags of 'debtags' */ 165 2 : Tag tag = *tags.begin(); 166 1 : assert(tag); 167 : 168 : /* Get its items */ 169 : { 170 : /* Need this workaround until I figure out how to tell the new GCC 171 : * that TagDB is a TDBReadonlyDiskIndex and should behave as such 172 : */ 173 1 : std::set<Tag> ts; 174 1 : ts.insert(tag); 175 1 : packages = debtags.getItemsHavingTags(ts); 176 : } 177 : //packages = c.debtags().tagdb().getItems(tag); 178 1 : assert(!packages.empty()); 179 : /* They should at least contain 'debtags' */ 180 2 : assert( p <= packages ); 181 : 182 : //c.debtags().getTags(""); // XXX HACK AWW! 183 1 : } 184 : 185 1 : Test _4() 186 : { 187 1 : std::string patchfile = Path::debtagsUserSourceDir() + "patch"; 188 1 : unlink(patchfile.c_str()); 189 : 190 1 : string p("debtags"); 191 : 192 : /* Get its tags */ 193 1 : std::set<Tag> tags = debtags.getTagsOfItem(p); 194 1 : assert(!tags.empty()); 195 : 196 : // Ensure that it's not tagged with gameplaying 197 2 : Tag t = voc().tagByName("use::gameplaying"); 198 2 : assert(! (t <= tags) ); 199 : 200 : // Add the gameplaying tag 201 1 : PatchList<string, Tag> change; 202 1 : change.addPatch(Patch<string, Tag>(p, wibble::singleton(t), wibble::Empty<Tag>())); 203 1 : debtags.applyChange(change); 204 : 205 : // See that the patch is non empty 206 1 : PatchList<string, Tag> tmp = debtags.changes(); 207 1 : assert(tmp.size() > 0); 208 2 : assert_eq(tmp.size(), 1u); 209 : 210 : // Ensure that the tag has been added 211 2 : tags = debtags.getTagsOfItem(p); 212 1 : assert(!tags.empty()); 213 : 214 2 : t = voc().tagByName("use::gameplaying"); 215 2 : assert( t <= tags ); 216 : 217 : // Save the patch 218 1 : debtags.savePatch(); 219 : 220 : // Check that the saved patch is correct 221 1 : FILE* in = fopen(patchfile.c_str(), "r"); 222 1 : string writtenPatch; 223 : int c; 224 29 : while ((c = getc(in)) != EOF) 225 27 : writtenPatch += c; 226 1 : fclose(in); 227 : 228 1 : assert_eq(writtenPatch, string("debtags: +use::gameplaying\n")); 229 : 230 2 : unlink(patchfile.c_str()); 231 : 232 : // Reapply the patch and see that it doesn't disrept things 233 1 : debtags.applyChange(change); 234 : 235 : // The patch should not have changed 236 1 : tmp = debtags.changes(); 237 1 : assert_eq(tmp.size(), 1u); 238 2 : assert_eq(tmp.begin()->first, p); 239 1 : assert_eq(tmp.begin()->second.item, p); 240 1 : } 241 : 242 : // If there is no data, Debtags should work as an empty collection 243 1 : Test _5() 244 : { 245 1 : Path::OverrideDebtagsSourceDir odsd("./empty"); 246 2 : Path::OverrideDebtagsIndexDir odid("./empty"); 247 2 : Path::OverrideDebtagsUserSourceDir odusd("./empty"); 248 2 : Path::OverrideDebtagsUserIndexDir oduid("./empty"); 249 1 : Debtags empty; 250 : 251 1 : assert(empty.begin() == empty.end()); 252 1 : assert_eq(empty.timestamp(), 0); 253 2 : assert(!empty.hasData()); 254 : 255 1 : tagcoll::PatchList<std::string, Tag> patches = empty.changes(); 256 1 : assert(patches.empty()); 257 : 258 2 : set<Tag> res = empty.getTagsOfItem("apt"); 259 2 : assert(res.empty()); 260 2 : res = empty.getTagsOfItems(wibble::singleton(string("apt"))); 261 2 : assert(res.empty()); 262 : 263 2 : res = empty.getAllTags(); 264 1 : assert(res.empty()); 265 : 266 1 : tagcoll::coll::Simple<string, Tag> coll; 267 1 : empty.outputSystem(tagcoll::coll::inserter(coll)); 268 1 : assert_eq(coll.itemCount(), 0u); 269 : 270 1 : coll.clear(); 271 : 272 1 : empty.outputPatched(tagcoll::coll::inserter(coll)); 273 1 : assert_eq(coll.itemCount(), 0u); 274 1 : } 275 : 276 : }; 277 : 278 : #include <ept/debtags/debtags.tcc> 279 : #include <tagcoll/coll/simple.tcc> 280 : 281 : #endif 282 : 283 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_DEBTAGS_VOCABULARY_H 2 : #define EPT_DEBTAGS_VOCABULARY_H 3 : 4 : /** @file 5 : * @author Enrico Zini <enrico@enricozini.org> 6 : * Debtags vocabulary access 7 : */ 8 : 9 : /* 10 : * Copyright (C) 2003,2004,2005,2006,2007 Enrico Zini <enrico@debian.org> 11 : * 12 : * This program is free software; you can redistribute it and/or modify 13 : * it under the terms of the GNU General Public License as published by 14 : * the Free Software Foundation; either version 2 of the License, or 15 : * (at your option) any later version. 16 : * 17 : * This program is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 : * GNU General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU General Public License 23 : * along with this program; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : #include <ept/debtags/tag.h> 28 : #include <tagcoll/diskindex/mmap.h> 29 : 30 : #include <string> 31 : #include <vector> 32 : #include <map> 33 : 34 : namespace ept { 35 : namespace debtags { 36 : 37 : class Vocabulary 38 : { 39 : public: 40 : class FacetIndex : public tagcoll::diskindex::MMap 41 : { 42 : protected: 43 : // Layout of the data in the index 44 : struct Item { 45 : int offset; 46 : int size; 47 : int firsttag; 48 : int lasttag; 49 : const char name[]; 50 : }; 51 2393 : inline Item* item(int id) const 52 : { 53 2393 : if (id >= 0 && (unsigned)id < size()) 54 2392 : return (Item*)(m_buf + ((int*)m_buf)[id]); 55 1 : return NULL; 56 : } 57 : 58 : public: 59 31 : FacetIndex() : tagcoll::diskindex::MMap() {} 60 : FacetIndex(const tagcoll::diskindex::MasterMMap& master, size_t idx) 61 : : tagcoll::diskindex::MMap(master, idx) {} 62 : 63 : /// Get the number of facets in the index 64 2501 : size_t size() const { return m_size == 0 ? 0 : *(int*)m_buf / sizeof(int); } 65 : /// Get the offset of the facet data in the vocabulary for this facet 66 59 : size_t offset(int id) const { Item* i = item(id); return i == NULL ? 0 : i->offset; } 67 : /// Get the size of the facet data in the vocabulary for this facet 68 59 : size_t size(int id) const { Item* i = item(id); return i == NULL ? 0 : i->size; } 69 : /// Get the id of the first tag for this facet 70 91 : int firsttag(int id) const { Item* i = item(id); return i == NULL ? -1 : i->firsttag; } 71 : /// Get the id of the last tag for this facet 72 2043 : int lasttag(int id) const { Item* i = item(id); return i == NULL ? -1 : i->lasttag; } 73 : /// Get the name of this facet 74 88 : const char* name(int id) const { Item* i = item(id); return i == NULL ? "" : i->name; } 75 : /// Get the ID of the facet with this name 76 : int id(const char* name) const; 77 7 : int id(const std::string& name) const { return id(name.c_str()); } 78 : }; 79 : 80 : class TagIndex : public tagcoll::diskindex::MMap 81 : { 82 : protected: 83 : // Layout of the data in the index 84 : struct Item { 85 : int offset; 86 : int size; 87 : int facet; 88 : const char name[]; 89 : }; 90 1112004 : inline Item* item(int id) const 91 : { 92 1112004 : if (id >= 0 && (unsigned)id < size()) 93 1112004 : return (Item*)(m_buf + ((int*)m_buf)[id]); 94 0 : return NULL; 95 : } 96 : 97 : public: 98 31 : TagIndex() : tagcoll::diskindex::MMap() {} 99 : TagIndex(const tagcoll::diskindex::MasterMMap& master, size_t idx) 100 : : tagcoll::diskindex::MMap(master, idx) {} 101 : 102 : /// Get the number of tags in the index 103 1327864 : size_t size() const { return m_size == 0 ? 0 : *(int*)m_buf / sizeof(int); } 104 : /// Get the offset of the facet data in the vocabulary for this tag 105 1242 : size_t offset(int id) const { Item* i = item(id); return i == NULL ? 0 : i->offset; } 106 : /// Get the size of the facet data in the vocabulary for this tag 107 1242 : size_t size(int id) const { Item* i = item(id); return i == NULL ? 0 : i->size; } 108 : /// Get the id of the facet for this tag 109 0 : int facet(int id) const { Item* i = item(id); return i == NULL ? -1 : i->facet; } 110 : /// Get the name of this tag 111 3767 : const char* name(int id) const { Item* i = item(id); return i == NULL ? "" : i->name; } 112 : /// Get the ID of the tag with this name 113 : int id(const char* name) const; 114 105755 : int id(const std::string& name) const { return id(name.c_str()); } 115 : }; 116 : 117 : protected: 118 : // Master MMap index container 119 : tagcoll::diskindex::MasterMMap mastermmap; 120 : 121 : time_t m_timestamp; 122 : 123 : // Mmapped vocabulary file 124 : std::string voc_fname; 125 : int voc_fd; 126 : size_t voc_size; 127 : const char* voc_buf; 128 : 129 : // Facet and tag indexes 130 : FacetIndex findex; 131 : TagIndex tindex; 132 : 133 : // Cached parsed facet and tag records 134 : mutable std::vector< std::map<std::string, std::string> > m_facetData; 135 : mutable std::vector< std::map<std::string, std::string> > m_tagData; 136 : // Empty parsed data to return when data is asked for IDs == -1 137 : std::map<std::string, std::string> emptyData; 138 : 139 : void parseVocBuf(std::map<std::string, std::string>& res, size_t ofs, size_t len) const; 140 : 141 : public: 142 : Vocabulary(); 143 : ~Vocabulary(); 144 : 145 : /// Get the timestamp of when the index was last updated 146 : time_t timestamp() const { return m_timestamp; } 147 : 148 : /// Return true if this data source has data, false if it's empty 149 1 : bool hasData() const { return m_timestamp != 0; } 150 : 151 : const FacetIndex& facetIndex() const { return findex; } 152 : const TagIndex& tagIndex() const { return tindex; } 153 : 154 : /** 155 : * Check if the vocabulary contains the facet `name' 156 : */ 157 2 : bool hasFacet(const std::string& name) const 158 : { 159 2 : return findex.id(name.c_str()) != -1; 160 : } 161 : 162 : /** 163 : * Check if the vocabulary contains the tag `fullname' 164 : */ 165 622 : bool hasTag(const std::string& fullname) const 166 : { 167 622 : return tindex.id(fullname.c_str()) != -1; 168 : } 169 : 170 : /** 171 : * Return the facet with the given name 172 : */ 173 : Facet facetByID(int id) const; 174 : 175 : /** 176 : * Return the tag with the given full name 177 : */ 178 : Tag tagByID(int id) const; 179 : 180 : template<typename IDS> 181 84590 : std::set<Tag> tagsByID(const IDS& ids) const 182 : { 183 84590 : std::set<Tag> res; 184 507017 : for (typename IDS::const_iterator i = ids.begin(); 185 : i != ids.end(); ++i) 186 422427 : res.insert(tagByID(*i)); 187 0 : return res; 188 : } 189 : 190 : /** 191 : * Return the facet for the tag with the given ID 192 : */ 193 0 : Facet facetByTag(int id) const { return facetByID(tindex.facet(id)); } 194 : 195 : /** 196 : * Return the facet with the given name 197 : */ 198 4 : Facet facetByName(const std::string& name) const { return facetByID(findex.id(name)); } 199 : 200 : /** 201 : * Return the tag with the given full name 202 : */ 203 105755 : Tag tagByName(const std::string& fullname) const { return tagByID(tindex.id(fullname)); } 204 : 205 : /** 206 : * Return all the facets in the vocabulary 207 : */ 208 4 : std::set< Facet > facets() const 209 : { 210 4 : std::set< Facet > res; 211 91 : for (size_t i = 0; i < findex.size(); i++) 212 87 : res.insert(facetByID(i)); 213 0 : return res; 214 : } 215 : 216 : /** 217 : * Return all the tags in the vocabulary 218 : */ 219 6 : std::set< Tag > tags() const 220 : { 221 6 : std::set< Tag > res; 222 3106 : for (size_t i = 0; i < tindex.size(); i++) 223 3100 : res.insert(tagByID(i)); 224 0 : return res; 225 : } 226 : 227 : /** 228 : * Return the tags in the given facet 229 : */ 230 91 : std::set< Tag > tags(int facet) const 231 : { 232 91 : std::set< Tag > res; 233 2044 : for (int i = findex.firsttag(facet); i != -1 && i <= findex.lasttag(facet); i++) 234 1953 : res.insert(tagByID(i)); 235 0 : return res; 236 : } 237 : 238 3 : std::set< Tag > tags(const std::string& facetName) const 239 : { 240 3 : return tags(findex.id(facetName)); 241 : } 242 : 243 : std::set< Tag > tags(const Facet& facet) const 244 : { 245 : return tags(facet.id()); 246 : } 247 : 248 : #if 0 249 : /// Get the DerivedTagList with the Equates: expressions read from the vocabulary 250 : const DerivedTagList& getEquations() const throw () { return equations; } 251 : 252 : /// Get a set with all the facets present in the vocabulary that are matched by `filter' 253 : FacetSet facets(const FacetMatcher& filter) const throw () { return getFiltered(filter); } 254 : #endif 255 : 256 : #if 0 257 : // These functions are here just to be used by Facet and Tag. I'm not 258 : // making them private because I don't want Facet and Tag to access other 259 : // Vocabulary member, and other classes can't use these anyway as Facet::Data and 260 : // Tag::Data are protected 261 : const Facet::Data& facetData(int idx) { return m_facets[idx]; } 262 : const Tag::Data& tagData(int idx) { return m_tags[idx]; } 263 : #endif 264 : 265 : /// Get the facet name given the facet id 266 88 : std::string facetName(int id) const { return findex.name(id); } 267 : 268 : /// Get the tag name given the tag id 269 1904 : std::string tagName(int id) const { return tindex.name(id); } 270 : 271 : /// Get the tag name given the tag id 272 : std::string tagShortName(int id) const; 273 : 274 : const std::map<std::string, std::string>& facetData(int id) const; 275 : const std::map<std::string, std::string>& tagData(int id) const; 276 : }; 277 : 278 : } 279 : } 280 : 281 : // vim:set ts=4 sw=4: 282 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
debtags.cc |
|
48.1 % | 39 / 81 lines | |
debtags.h |
|
93.1 % | 67 / 72 lines | |
debtags.tcc |
|
100.0 % | 4 / 4 lines | |
debtags.test.h |
|
100.0 % | 103 / 103 lines | |
expression.cc |
|
100.0 % | 5 / 5 lines | |
expression.test.h |
|
100.0 % | 32 / 32 lines | |
tag.cc |
|
74.6 % | 44 / 59 lines | |
tag.h |
|
93.8 % | 15 / 16 lines | |
vocabulary.cc |
|
95.1 % | 97 / 102 lines | |
vocabulary.h |
|
87.3 % | 48 / 55 lines | |
vocabulary.test.h |
|
99.4 % | 172 / 173 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; indent-tabs-mode: t -*- 2 : 3 : /** \file 4 : * debtags paths 5 : */ 6 : 7 : /* 8 : * Copyright (C) 2005,2006,2007 Enrico Zini <enrico@debian.org>, Peter Rockai <me@mornfall.net> 9 : * 10 : * This program is free software; you can redistribute it and/or modify 11 : * it under the terms of the GNU General Public License as published by 12 : * the Free Software Foundation; either version 2 of the License, or 13 : * (at your option) any later version. 14 : * 15 : * This program is distributed in the hope that it will be useful, 16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 : * GNU General Public License for more details. 19 : * 20 : * You should have received a copy of the GNU General Public License 21 : * along with this program; if not, write to the Free Software 22 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 : */ 24 : 25 : #include <ept/debtags/maint/path.h> 26 : #include <ept/config.h> 27 : 28 : #include <wibble/sys/fs.h> 29 : #include <wibble/string.h> 30 : 31 : #include <sys/types.h> // getpwuid, stat, mkdir, getuid 32 : #include <sys/stat.h> // stat, mkdir 33 : #include <pwd.h> // getpwuid 34 : #include <unistd.h> // stat, getuid 35 : 36 : using namespace wibble; 37 : 38 : namespace ept { 39 : namespace debtags { 40 : 41 2 : static std::string userdir() 42 : { 43 2 : std::string rcdir; 44 : 45 2 : struct passwd* udata = getpwuid(getuid()); 46 2 : rcdir = str::joinpath(udata->pw_dir, ".debtags"); 47 : 48 0 : return rcdir; 49 : } 50 : 51 : 52 732 : Path &Path::instance() { 53 732 : if (!s_instance) { 54 1 : s_instance = new Path; 55 1 : instance().m_debtagsSourceDir = DEBTAGS_DB_DIR; 56 1 : instance().m_debtagsIndexDir = DEBTAGS_DB_DIR; 57 2 : instance().m_debtagsUserSourceDir = userdir(); 58 2 : instance().m_debtagsUserIndexDir = userdir(); 59 : } 60 732 : return *s_instance; 61 : } 62 : 63 12 : int Path::access( const std::string &s, int m ) { 64 12 : return ::access( s.c_str(), m ); 65 : } 66 : 67 300 : time_t Path::timestamp( const std::string& file ) { 68 300 : std::auto_ptr<struct stat> st = wibble::sys::fs::stat(file); 69 580 : return st.get() == NULL ? 0 : st->st_mtime; 70 : } 71 : 72 62 : void Path::setDebtagsSourceDir( const std::string &s ) 73 : { 74 62 : instance().m_debtagsSourceDir = s; 75 62 : } 76 62 : void Path::setDebtagsIndexDir( const std::string &s ) 77 : { 78 62 : instance().m_debtagsIndexDir = s; 79 62 : } 80 62 : void Path::setDebtagsUserSourceDir( const std::string &s ) 81 : { 82 62 : instance().m_debtagsUserSourceDir = s; 83 62 : } 84 62 : void Path::setDebtagsUserIndexDir( const std::string &s ) 85 : { 86 62 : instance().m_debtagsUserIndexDir = s; 87 62 : } 88 : 89 72 : std::string Path::debtagsSourceDir() { return instance().m_debtagsSourceDir; } 90 121 : std::string Path::debtagsIndexDir() { return instance().m_debtagsIndexDir; } 91 82 : std::string Path::debtagsUserSourceDir() { return instance().m_debtagsUserSourceDir; } 92 205 : std::string Path::debtagsUserIndexDir() { return instance().m_debtagsUserIndexDir; } 93 : 94 33 : std::string Path::vocabulary() { 95 33 : return str::joinpath(debtagsIndexDir(), "vocabulary"); 96 : } 97 : 98 32 : std::string Path::vocabularyIndex() { 99 32 : return str::joinpath(debtagsIndexDir(), "vocabulary.idx"); 100 : } 101 : 102 65 : std::string Path::userVocabulary() { 103 65 : return str::joinpath(debtagsUserIndexDir(), "vocabulary"); 104 : } 105 : 106 65 : std::string Path::userVocabularyIndex() { 107 65 : return str::joinpath(debtagsUserIndexDir(), "vocabulary.idx"); 108 : } 109 : 110 11 : std::string Path::tagdb() { 111 11 : return str::joinpath(debtagsIndexDir(), "package-tags"); 112 : } 113 : 114 11 : std::string Path::tagdbIndex() { 115 11 : return str::joinpath(debtagsIndexDir(), "package-tags.idx"); 116 : } 117 : 118 22 : std::string Path::userTagdb() { 119 22 : return str::joinpath(debtagsUserIndexDir(), "package-tags"); 120 : } 121 : 122 22 : std::string Path::userTagdbIndex() { 123 22 : return str::joinpath(debtagsUserIndexDir(), "package-tags.idx"); 124 : } 125 : 126 0 : std::string Path::pkgidx() { 127 0 : return str::joinpath(debtagsIndexDir(), "pkgidx.idx"); 128 : } 129 : 130 0 : std::string Path::userPkgidx() { 131 0 : return str::joinpath(debtagsUserIndexDir(), "pkgidx.idx"); 132 : } 133 : 134 : 135 : Path *Path::s_instance = 0; 136 : 137 : } 138 : } 139 : 140 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Merge different vocabularies together and create the tag and facet indexes 3 : * 4 : * Copyright (C) 2003-2006 Enrico Zini <enrico@debian.org> 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 2 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, write to the Free Software 18 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : */ 20 : 21 : 22 : #include <ept/debtags/maint/vocabularymerger.h> 23 : #include <ept/debtags/maint/debdbparser.h> 24 : 25 : #include <cassert> 26 : #include <cstring> 27 : 28 : using namespace std; 29 : using namespace tagcoll; 30 : 31 : namespace ept { 32 : namespace debtags { 33 : 34 1432 : static void writeDebStyleField(FILE* out, const string& name, const string& val) throw () 35 : { 36 1432 : fprintf(out, "%s: ", name.c_str()); 37 : 38 : // Properly escape newlines 39 1432 : bool was_nl = false; 40 56225 : for (string::const_iterator s = val.begin(); s != val.end(); s++) 41 54793 : if (was_nl) 42 : // \n\n -> \n .\n 43 738 : if (*s == '\n') 44 : { 45 120 : fputc(' ', out); 46 120 : fputc('.', out); 47 120 : fputc(*s, out); 48 : } 49 : // \n([^ \t]) -> \n \1 50 618 : else if (*s != ' ' && *s != '\t') 51 : { 52 618 : fputc(' ', out); 53 618 : fputc(*s, out); 54 618 : was_nl = false; 55 : } 56 : // \n[ \t] goes unchanged 57 : else 58 : { 59 0 : fputc(*s, out); 60 0 : was_nl = false; 61 : } 62 : else 63 54055 : if (*s == '\n') 64 : { 65 618 : fputc(*s, out); 66 618 : was_nl = true; 67 : } 68 : else 69 53437 : fputc(*s, out); 70 : 71 1432 : fputc('\n', out); 72 1432 : } 73 : 74 1865 : VocabularyMerger::TagData& VocabularyMerger::FacetData::obtainTag(const std::string& name) 75 : { 76 1865 : std::map<std::string, TagData>::iterator i = tags.find(name); 77 1865 : if (i == tags.end()) 78 : { 79 : // Create the tag if it's missing 80 1245 : pair<std::map<std::string, TagData>::iterator, bool> res = tags.insert(make_pair<std::string, TagData>(name, TagData())); 81 1245 : i = res.first; 82 1245 : i->second.name = name; 83 : } 84 1865 : return i->second; 85 : } 86 : 87 1953 : VocabularyMerger::FacetData& VocabularyMerger::obtainFacet(const std::string& name) 88 : { 89 1953 : std::map<std::string, FacetData>::iterator i = facets.find(name); 90 1953 : if (i == facets.end()) 91 : { 92 : // Create the facet if it's missing 93 62 : pair<std::map<std::string, FacetData>::iterator, bool> res = facets.insert(make_pair<std::string, FacetData>(name, FacetData())); 94 62 : i = res.first; 95 62 : i->second.name = name; 96 : } 97 1953 : return i->second; 98 : } 99 : 100 1865 : VocabularyMerger::TagData& VocabularyMerger::obtainTag(const std::string& fullname) 101 : { 102 1865 : size_t p = fullname.find("::"); 103 1865 : if (p == string::npos) 104 : { 105 28 : FacetData& facet = obtainFacet("legacy"); 106 28 : return facet.obtainTag(fullname); 107 : } else { 108 1837 : FacetData& facet = obtainFacet(fullname.substr(0, p)); 109 3674 : return facet.obtainTag(fullname.substr(p + 2)); 110 : } 111 : } 112 : 113 : 114 7 : void VocabularyMerger::read(tagcoll::input::Input& input) 115 : { 116 7 : DebDBParser parser(input); 117 7 : DebDBParser::Record record; 118 : 119 1967 : while (parser.nextRecord(record)) 120 : { 121 1953 : DebDBParser::Record::const_iterator fi = record.find("Facet"); 122 3906 : DebDBParser::Record::const_iterator ti = record.find("Tag"); 123 3906 : if (fi != record.end()) 124 : { 125 : // Get the facet record 126 88 : FacetData& facet = obtainFacet(fi->second); 127 : //fprintf(stderr, "Read facet@%d %.*s\n", parser.lineNumber(), PFSTR(facet.name)); 128 88 : assert(facet.name == fi->second); 129 : 130 : // Merge the data 131 416 : for (DebDBParser::Record::const_iterator i = record.begin(); 132 : i != record.end(); i++) 133 328 : if (i->first != "Facet") 134 240 : facet[i->first] = i->second; 135 : } 136 1865 : else if (ti != record.end()) 137 : { 138 : // Get the tag record 139 1865 : TagData& tag = obtainTag(ti->second); 140 : //fprintf(stderr, "Read tag@%d %.*s\n", parser.lineNumber(), PFSTR(tag.name)); 141 : //assert(tag.name == ti->second); 142 : 143 : // Merge the data 144 5796 : for (DebDBParser::Record::const_iterator i = record.begin(); 145 : i != record.end(); i++) 146 3931 : if (i->first != "Tag") 147 2066 : tag[i->first] = i->second; 148 : } 149 : else 150 : { 151 : fprintf(stderr, "%s:%d: Skipping record without Tag or Facet field\n", 152 0 : input.fileName().c_str(), input.lineNumber()); 153 : } 154 7 : } 155 7 : } 156 : 157 0 : bool VocabularyMerger::hasTag(const std::string& fullname) const 158 : { 159 0 : size_t p = fullname.find("::"); 160 0 : std::string facetName; 161 0 : std::string tagName; 162 0 : if (p == string::npos) 163 : { 164 0 : facetName = "legacy"; 165 0 : tagName = fullname; 166 : } else { 167 0 : facetName = fullname.substr(0, p); 168 0 : tagName = fullname.substr(p + 2); 169 : } 170 : 171 0 : std::map<std::string, FacetData>::const_iterator i = facets.find(facetName); 172 0 : if (i == facets.end()) 173 0 : return false; 174 0 : return i->second.tags.find(tagName) != i->second.tags.end(); 175 : } 176 : 177 0 : int VocabularyMerger::tagID(const std::string& fullname) const 178 : { 179 0 : size_t p = fullname.find("::"); 180 0 : std::string facetName; 181 0 : std::string tagName; 182 0 : if (p == string::npos) 183 : { 184 0 : facetName = "legacy"; 185 0 : tagName = fullname; 186 : } else { 187 0 : facetName = fullname.substr(0, p); 188 0 : tagName = fullname.substr(p + 2); 189 : } 190 : 191 0 : std::map<std::string, FacetData>::const_iterator i = facets.find(facetName); 192 0 : if (i == facets.end()) 193 0 : return -1; 194 0 : std::map<std::string, TagData>::const_iterator j = i->second.tags.find(tagName); 195 0 : if (j == i->second.tags.end()) 196 0 : return -1; 197 0 : return j->second.id; 198 : } 199 : 200 1 : std::set<std::string> VocabularyMerger::tagNames() const 201 : { 202 1 : set<string> res; 203 30 : for (std::map<std::string, FacetData>::const_iterator f = facets.begin(); f != facets.end(); f++) 204 649 : for (std::map<std::string, TagData>::const_iterator t = f->second.tags.begin(); 205 : t != f->second.tags.end(); t++) 206 620 : res.insert(f->first + "::" + t->first); 207 0 : return res; 208 : } 209 : 210 4 : void VocabularyMerger::write(const std::string& fname) 211 : { 212 4 : FILE* out = fopen(fname.c_str(), "wt"); 213 4 : if (!out) 214 0 : throw wibble::exception::File(fname, "cept_debtags_vocabularymerger:reating file "); 215 4 : write(out); 216 4 : fclose(out); 217 4 : } 218 : 219 4 : void VocabularyMerger::write(FILE* out) 220 : { 221 4 : long start_ofs = ftell(out); 222 4 : int facetid = 0; 223 4 : int tagid = 0; 224 : 225 : //fprintf(stderr, "Write\n"); 226 37 : for (std::map<std::string, FacetData>::iterator f = facets.begin(); f != facets.end(); f++) 227 : { 228 33 : f->second.id = facetid++; 229 : //fprintf(stderr, "Writing facet %.*s\n", PFSTR(f->first)); 230 33 : f->second.ofs = ftell(out) - start_ofs; 231 33 : writeDebStyleField(out, "Facet", f->first); 232 115 : for (std::map<std::string, std::string>::const_iterator j = f->second.begin(); 233 : j != f->second.end(); j++) 234 82 : writeDebStyleField(out, j->first, j->second); 235 33 : fputc('\n', out); 236 33 : f->second.len = ftell(out) - f->second.ofs; 237 : 238 658 : for (std::map<std::string, TagData>::iterator t = f->second.tags.begin(); 239 : t != f->second.tags.end(); t++) 240 : { 241 625 : t->second.id = tagid++; 242 : //fprintf(stderr, "Writing tag %.*s\n", PFSTR(t->first)); 243 625 : t->second.ofs = ftell(out) - start_ofs; 244 625 : writeDebStyleField(out, "Tag", f->first + "::" + t->first); 245 1317 : for (std::map<std::string, std::string>::const_iterator j = t->second.begin(); 246 : j != t->second.end(); j++) 247 692 : writeDebStyleField(out, j->first, j->second); 248 625 : fputc('\n', out); 249 625 : t->second.len = ftell(out) - t->second.ofs; 250 : } 251 : } 252 : 253 4 : tagCount = tagid; 254 4 : } 255 : 256 : 257 4 : int VocabularyMerger::FacetIndexer::encodedSize() const 258 : { 259 : // First the main offset table 260 4 : int size = vm.facets.size() * sizeof(int); 261 : 262 37 : for (std::map<std::string, FacetData>::const_iterator f = vm.facets.begin(); f != vm.facets.end(); f++) 263 : { 264 : // offset of record in vocabulary 265 : // size of record in vocabulary 266 : // id of first tag 267 : // id of last tag 268 : // name (0-terminated) 269 33 : size += 4 * sizeof(int) + f->first.size() + 1; 270 : 271 : // Align to int boundaries 272 33 : if ((size % sizeof(int)) != 0) 273 25 : size = (size + sizeof(int)) / sizeof(int) * sizeof(int); 274 : } 275 : 276 4 : return tagcoll::diskindex::MMap::align(size); 277 : } 278 : 279 4 : void VocabularyMerger::FacetIndexer::encode(char* buf) const 280 : { 281 4 : int pos = vm.facets.size() * sizeof(int); 282 : 283 37 : for (std::map<std::string, FacetData>::const_iterator f = vm.facets.begin(); f != vm.facets.end(); f++) 284 : { 285 33 : ((int*)buf)[f->second.id] = pos; 286 : 287 : // offset of record in vocabulary 288 33 : *(int*)(buf+pos) = f->second.ofs; 289 33 : pos += sizeof(int); 290 : 291 : // size of record in vocabulary 292 33 : *(int*)(buf+pos) = f->second.len; 293 33 : pos += sizeof(int); 294 : 295 33 : if (f->second.tags.empty()) 296 : { 297 : // id of first tag 298 1 : *(int*)(buf+pos) = -1; 299 1 : pos += sizeof(int); 300 : 301 : // id of last tag 302 1 : *(int*)(buf+pos) = -1; 303 1 : pos += sizeof(int); 304 : } else { 305 : // id of first tag 306 32 : *(int*)(buf+pos) = f->second.tags.begin()->second.id; 307 32 : pos += sizeof(int); 308 : 309 : // id of last tag 310 32 : *(int*)(buf+pos) = f->second.tags.rbegin()->second.id; 311 32 : pos += sizeof(int); 312 : } 313 : 314 : // name (0-terminated) 315 33 : memcpy(buf + pos, f->first.c_str(), f->first.size() + 1); 316 33 : pos += f->first.size() + 1; 317 : 318 : // Align to int boundaries 319 33 : if ((pos % sizeof(int)) != 0) 320 25 : pos = (pos + sizeof(int)) / sizeof(int) * sizeof(int); 321 : } 322 4 : } 323 : 324 4 : int VocabularyMerger::TagIndexer::encodedSize() const 325 : { 326 : // First the main offset table 327 4 : int size = vm.tagCount * sizeof(int); 328 : 329 37 : for (std::map<std::string, FacetData>::const_iterator f = vm.facets.begin(); f != vm.facets.end(); f++) 330 : { 331 658 : for (std::map<std::string, TagData>::const_iterator t = f->second.tags.begin(); 332 : t != f->second.tags.end(); t++) 333 : { 334 : // offset of record in vocabulary 335 : // size of record in vocabulary 336 : // id of facet 337 : // name (0-terminated) 338 625 : size += 3 * sizeof(int) + f->first.size() + t->first.size() + 3; 339 : 340 : // Align to int boundaries 341 625 : if ((size % sizeof(int)) != 0) 342 479 : size = (size + sizeof(int)) / sizeof(int) * sizeof(int); 343 : } 344 : } 345 4 : return tagcoll::diskindex::MMap::align(size); 346 : } 347 : 348 4 : void VocabularyMerger::TagIndexer::encode(char* buf) const 349 : { 350 4 : int pos = vm.tagCount * sizeof(int); 351 : 352 37 : for (std::map<std::string, FacetData>::const_iterator f = vm.facets.begin(); f != vm.facets.end(); f++) 353 : { 354 658 : for (std::map<std::string, TagData>::const_iterator t = f->second.tags.begin(); 355 : t != f->second.tags.end(); t++) 356 : { 357 625 : ((int*)buf)[t->second.id] = pos; 358 : 359 : // offset of record in vocabulary 360 625 : *(int*)(buf+pos) = t->second.ofs; 361 625 : pos += sizeof(int); 362 : 363 : // size of record in vocabulary 364 625 : *(int*)(buf+pos) = t->second.len; 365 625 : pos += sizeof(int); 366 : 367 : // id of facet 368 625 : *(int*)(buf+pos) = f->second.id; 369 625 : pos += sizeof(int); 370 : 371 : // name (0-terminated) 372 625 : string name = f->first + "::" + t->first; 373 625 : memcpy(buf + pos, name.c_str(), name.size() + 1); 374 625 : pos += name.size() + 1; 375 : 376 : // Align to int boundaries 377 625 : if ((pos % sizeof(int)) != 0) 378 479 : pos = (pos + sizeof(int)) / sizeof(int) * sizeof(int); 379 : } 380 : } 381 4 : } 382 : 383 : } 384 6 : } 385 : 386 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include <ept/debtags/maint/sourcedir.h> 2 : #include <ept/debtags/maint/vocabularymerger.h> 3 : #include <ept/debtags/maint/path.h> 4 : 5 : #include <wibble/string.h> 6 : 7 : #include <tagcoll/input/zlib.h> 8 : #include <tagcoll/input/stdio.h> 9 : 10 : using namespace wibble; 11 : 12 : namespace ept { 13 : namespace debtags { 14 : 15 802 : SourceDir::FileType SourceDir::fileType(const std::string& name) 16 : { 17 802 : if (name[0] == '.') return SKIP; 18 : 19 : // Filenames need to be at least 5 characters long (one char plus 20 : // extension) 21 622 : if (name.size() <= 4) return SKIP; 22 : 23 : // Only look at .voc and .tag files 24 542 : std::string ext(name, name.size() - 4); 25 542 : if (ext == ".voc") 26 80 : return VOC; 27 462 : if (ext == ".tag") 28 80 : return TAG; 29 : 30 : // Now look for compressed files, which must have the 4 character extension 31 : // plus the 3 chars of '.gz' 32 382 : if (name.size() <= 7) return SKIP; 33 : 34 302 : ext = name.substr(name.size() - 7); 35 302 : if (ext == ".voc.gz") 36 0 : return VOCGZ; 37 302 : if (ext == ".tag.gz") 38 0 : return TAGGZ; 39 : 40 302 : return SKIP; 41 : } 42 : 43 20 : time_t SourceDir::timestamp() 44 : { 45 20 : if (!valid()) return 0; 46 : 47 20 : time_t max = 0; 48 200 : for (const_iterator d = begin(); d != end(); ++d) 49 : { 50 180 : FileType type = fileType(d->d_name); 51 180 : if (type == SKIP) continue; 52 : 53 36 : time_t ts = Path::timestamp(str::joinpath(path(), d->d_name)); 54 54 : if (ts > max) max = ts; 55 20 : } 56 : 57 20 : return max; 58 : } 59 : 60 62 : time_t SourceDir::vocTimestamp() 61 : { 62 62 : if (!valid()) return 0; 63 : 64 60 : time_t max = 0; 65 632 : for (const_iterator d = begin(); d != end(); ++d) 66 : { 67 572 : FileType type = fileType(d->d_name); 68 1086 : if (type != VOC and type != VOCGZ) continue; 69 : 70 58 : time_t ts = Path::timestamp(str::joinpath(path(), d->d_name)); 71 116 : if (ts > max) max = ts; 72 60 : } 73 : 74 60 : return max; 75 : } 76 : 77 0 : time_t SourceDir::tagTimestamp() 78 : { 79 0 : if (!valid()) return 0; 80 : 81 0 : time_t max = 0; 82 0 : for (const_iterator d = begin(); d != end(); ++d) 83 : { 84 0 : FileType type = fileType(d->d_name); 85 0 : if (type != TAG and type != TAGGZ) continue; 86 : 87 0 : time_t ts = Path::timestamp(str::joinpath(path(), d->d_name)); 88 0 : if (ts > max) max = ts; 89 0 : } 90 : 91 0 : return max; 92 : } 93 : 94 6 : void SourceDir::readVocabularies(VocabularyMerger& out) 95 : { 96 6 : if (!valid()) return; 97 : 98 32 : for (const_iterator d = begin(); d != end(); ++d) 99 : { 100 26 : FileType type = fileType(d->d_name); 101 26 : if (type == VOC) 102 : { 103 : // Read uncompressed data 104 2 : tagcoll::input::Stdio in(str::joinpath(path(), d->d_name)); 105 : 106 : // Read the vocabulary 107 4 : out.read(in); 108 : } 109 24 : else if (type == VOCGZ) 110 : { 111 : // Read compressed data 112 0 : tagcoll::input::Zlib in(str::joinpath(path(), d->d_name)); 113 : 114 : // Read the vocabulary 115 0 : out.read(in); 116 : } 117 6 : } 118 : } 119 : 120 : } 121 6 : } 122 : 123 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Merge different vocabularies together and create the tag and facet indexes 3 : * 4 : * Copyright (C) 2003-2007 Enrico Zini <enrico@debian.org> 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 2 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, write to the Free Software 18 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : */ 20 : 21 : #include <wibble/test.h> 22 : #include <ept/debtags/maint/vocabularymerger.h> 23 : #include <tagcoll/input/string.h> 24 : 25 : using namespace std; 26 : using namespace tagcoll; 27 : 28 : struct TestVocabularyMerger { 29 : 30 14 : inline static const char* indexref(const char* index, int id) 31 : { 32 14 : return index + ((int*)index)[id]; 33 : } 34 : 35 : 36 1 : Test _1() 37 : { 38 : string voc1 = 39 : "Facet: taste\n" 40 : "Description: Taste\n\n" 41 : "Tag: taste::sweet\n" 42 : "Description: Sweet\n\n" 43 : "Tag: taste::salty\n" 44 1 : "Description: Salty\n\n"; 45 : string voc2 = 46 : "Facet: smell\n" 47 : "Description: Smell\n\n" 48 : "Tag: smell::fresh\n" 49 : "Description: Fresh\n\n" 50 : "Tag: smell::mold\n" 51 2 : "Description: Mold\n\n"; 52 1 : tagcoll::input::String in1(voc1); 53 1 : tagcoll::input::String in2(voc2); 54 : 55 1 : ept::debtags::VocabularyMerger vm; 56 : 57 : // Read and merge the two vocabulary samples 58 1 : vm.read(in1); 59 1 : vm.read(in2); 60 : 61 : // Write the merged vocabulary to /dev/null (but generate offsets and indexes in the meantime) 62 1 : vm.write("/dev/null"); 63 : 64 : // Create the facet index 65 2 : char facetIndex[vm.facetIndexer().encodedSize()]; 66 1 : vm.facetIndexer().encode(facetIndex); 67 : 68 : // Create the tag index 69 1 : char tagIndex[vm.tagIndexer().encodedSize()]; 70 1 : vm.tagIndexer().encode(tagIndex); 71 : 72 : // Check that the facet names have been encoded correctly and in order 73 1 : assert_eq(string(indexref(facetIndex, 0) + 4*sizeof(int)), "smell"); 74 2 : assert_eq(string(indexref(facetIndex, 1) + 4*sizeof(int)), "taste"); 75 : 76 : // Check the first and last tag indexes for the facets 77 2 : assert_eq(((int*)indexref(facetIndex, 0))[2], 0); 78 2 : assert_eq(((int*)indexref(facetIndex, 0))[3], 1); 79 2 : assert_eq(((int*)indexref(facetIndex, 1))[2], 2); 80 2 : assert_eq(((int*)indexref(facetIndex, 1))[3], 3); 81 : 82 : // Check that the tag names have been encoded correctly and in order 83 2 : assert_eq(string(indexref(tagIndex, 0) + 3*sizeof(int)), "smell::fresh"); 84 2 : assert_eq(string(indexref(tagIndex, 1) + 3*sizeof(int)), "smell::mold"); 85 2 : assert_eq(string(indexref(tagIndex, 2) + 3*sizeof(int)), "taste::salty"); 86 2 : assert_eq(string(indexref(tagIndex, 3) + 3*sizeof(int)), "taste::sweet"); 87 : 88 : // Check the facet indexes for the tags 89 2 : assert_eq(((int*)indexref(tagIndex, 0))[2], 0); 90 2 : assert_eq(((int*)indexref(tagIndex, 1))[2], 0); 91 2 : assert_eq(((int*)indexref(tagIndex, 2))[2], 1); 92 2 : assert_eq(((int*)indexref(tagIndex, 3))[2], 1); 93 1 : } 94 : 95 : // Test parsing a vocabulary with a tag without a defined facet 96 1 : Test _2() 97 : { 98 : string voc = 99 : "Tag: foo::bar\n" 100 : "Description: Tag without facet\n" 101 1 : " VocabularyMerged should behave fine in this case.\n\n"; 102 1 : tagcoll::input::String in(voc); 103 : 104 1 : ept::debtags::VocabularyMerger vm; 105 1 : vm.read(in); 106 : 107 : // Write the merged vocabulary to /dev/null (but generate offsets and indexes in the meantime) 108 1 : vm.write("/dev/null"); 109 : 110 : // Create the facet index 111 2 : char facetIndex[vm.facetIndexer().encodedSize()]; 112 1 : vm.facetIndexer().encode(facetIndex); 113 : 114 : // Create the tag index 115 1 : char tagIndex[vm.tagIndexer().encodedSize()]; 116 1 : vm.tagIndexer().encode(tagIndex); 117 1 : } 118 : 119 : // Test parsing a vocabulary with a facet without tags 120 1 : Test _3() 121 : { 122 : string voc = 123 : "Facet: empty\n" 124 : "Description: Facet without tags\n" 125 1 : " VocabularyMerged used to segfault in this case.\n\n"; 126 1 : tagcoll::input::String in(voc); 127 : 128 1 : ept::debtags::VocabularyMerger vm; 129 1 : vm.read(in); 130 : 131 : // Write the merged vocabulary to /dev/null (but generate offsets and indexes in the meantime) 132 1 : vm.write("/dev/null"); 133 : 134 : // Create the facet index 135 2 : char facetIndex[vm.facetIndexer().encodedSize()]; 136 1 : vm.facetIndexer().encode(facetIndex); 137 : 138 : // Create the tag index 139 1 : char tagIndex[vm.tagIndexer().encodedSize()]; 140 1 : vm.tagIndexer().encode(tagIndex); 141 1 : } 142 : 143 : }; 144 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 2 : 3 : /** @file 4 : * @author Enrico Zini <enrico@enricozini.org> 5 : * Quick map from package IDs to package names 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2003-2007 Enrico Zini <enrico@debian.org> 10 : * 11 : * This program is free software; you can redistribute it and/or modify 12 : * it under the terms of the GNU General Public License as published by 13 : * the Free Software Foundation; either version 2 of the License, or 14 : * (at your option) any later version. 15 : * 16 : * This program is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 : * GNU General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU General Public License 22 : * along with this program; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <ept/debtags/maint/pkgid.h> 27 : #include <ept/debtags/maint/path.h> 28 : 29 : namespace ept { 30 : namespace debtags { 31 : 32 10 : PkgId::PkgId() {} 33 : 34 1 : PkgId::PkgId(const char* buf, int size) 35 1 : : MMap(buf, size) {} 36 : 37 0 : PkgId::PkgId(const tagcoll::diskindex::MasterMMap& master, size_t idx) 38 0 : : MMap(master, idx) {} 39 : 40 63445 : int PkgId::byName(const std::string& name) const 41 : { 42 : // Binary search the index to find the package ID 43 : int begin, end; 44 : 45 : /* Binary search */ 46 63445 : begin = -1, end = size(); 47 1043664 : while (end - begin > 1) 48 : { 49 916774 : int cur = (end + begin) / 2; 50 916774 : if (byID(cur) > name) 51 443057 : end = cur; 52 : else 53 473717 : begin = cur; 54 : } 55 : 56 63445 : if (begin == -1 || byID(begin) != name) 57 : //throw NotFoundException(string("looking for the ID of string ") + str); 58 2 : return -1; 59 : else 60 63443 : return begin; 61 : } 62 : 63 : } 64 : } 65 : 66 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_DEBTAGS_VOCABULARYINDEXER_H 2 : #define EPT_DEBTAGS_VOCABULARYINDEXER_H 3 : 4 : /** @file 5 : * @author Enrico Zini <enrico@enricozini.org> 6 : * Debtags vocabulary indexer 7 : */ 8 : 9 : /* 10 : * Copyright (C) 2003,2004,2005,2006,2007 Enrico Zini <enrico@debian.org> 11 : * 12 : * This program is free software; you can redistribute it and/or modify 13 : * it under the terms of the GNU General Public License as published by 14 : * the Free Software Foundation; either version 2 of the License, or 15 : * (at your option) any later version. 16 : * 17 : * This program is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 : * GNU General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU General Public License 23 : * along with this program; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : #include <ept/debtags/maint/sourcedir.h> 28 : #include <string> 29 : 30 : namespace ept { 31 : namespace debtags { 32 : 33 : /** 34 : * Infrastructure used to rebuild the vocabulary index when needed 35 : */ 36 : struct VocabularyIndexer 37 31 : { 38 : SourceDir mainSource; 39 : SourceDir userSource; 40 : time_t ts_main_src; 41 : time_t ts_user_src; 42 : time_t ts_main_voc; 43 : time_t ts_main_idx; 44 : time_t ts_user_voc; 45 : time_t ts_user_idx; 46 : 47 : /** 48 : * Get the timestamp of the newest vocabulary data source 49 : */ 50 114 : time_t sourceTimestamp() const { return ts_main_src < ts_user_src ? ts_user_src : ts_main_src; } 51 : /** 52 : * Return true if the vocabulary index needs rebuilding 53 : */ 54 : bool needsRebuild() const; 55 : 56 : /** 57 : * Rebuild the vocabulary index 58 : * @param vocfname 59 : * Full pathname of the merged vocabulary to create 60 : * @param idxfname 61 : * Full pathname of the vocabulary index to create 62 : */ 63 : bool rebuild(const std::string& vocfname, const std::string& idxfname); 64 : 65 : /** 66 : * Rebuild the vocabulary if needed 67 : */ 68 : bool rebuildIfNeeded(); 69 : 70 : /** 71 : * Get the names of the merged vocabulary and vocabulary index that can be 72 : * used to access Debtags vocabulary data. 73 : * 74 : * The system or the user index will be returned according to which one is 75 : * up to date. 76 : */ 77 : bool getUpToDateVocabulary(std::string& vocfname, std::string& idxfname); 78 : 79 : /** 80 : * Returns true if the index in the user home directory is redundant and 81 : * can be deleted. 82 : * 83 : * The user index is redundant if the system index is up to date. 84 : */ 85 : bool userIndexIsRedundant() const; 86 : 87 : /** 88 : * Deletes the user index if it is redundant 89 : */ 90 : bool deleteRedundantUserIndex(); 91 : 92 : /** 93 : * Rescan the various timestamps 94 : */ 95 : void rescan(); 96 : 97 : VocabularyIndexer(); 98 : 99 : /** 100 : * Get the names of the merged vocabulary and vocabulary index that can be 101 : * used to access Debtags vocabulary data. 102 : * 103 : * The system or the user index will be returned according to which one is 104 : * up to date. 105 : * 106 : * The files will be built or rebuilt if they are missing or outdated. 107 : */ 108 : static bool obtainWorkingVocabulary(std::string& vocfname, std::string& idxfname); 109 : }; 110 : 111 : 112 : } 113 : } 114 : 115 : // vim:set ts=4 sw=4: 116 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Parser for debian database files 3 : * 4 : * Copyright (C) 2003--2007 Enrico Zini <enrico@debian.org> 5 : * 6 : * This library is free software; you can redistribute it and/or 7 : * modify it under the terms of the GNU Lesser General Public 8 : * License as published by the Free Software Foundation; either 9 : * version 2.1 of the License, or (at your option) any later version. 10 : * 11 : * This library is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 : * Lesser General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU Lesser General Public 17 : * License along with this library; if not, write to the Free Software 18 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : */ 20 : 21 : #include <ept/debtags/maint/debdbparser.h> 22 : 23 : #include <tagcoll/input/base.h> 24 : 25 : #include <map> 26 : #include <ctype.h> 27 : 28 : // using namespace std; 29 : using namespace tagcoll; 30 : 31 : namespace ept { 32 : namespace debtags { 33 : 34 : // Eat spaces and empty lines 35 : // Returns the number of '\n' encountered 36 12089 : int DebDBParser::eatSpacesAndEmptyLines() 37 : { 38 12089 : int res = 0; 39 : int c; 40 31183 : while ((c = in.nextChar()) != input::Input::Eof && (isblank(c) || c == '\n')) 41 7005 : if (c == '\n') 42 : { 43 3314 : isBOL = true; 44 : //line++; 45 3314 : res++; 46 : } else 47 3691 : isBOL = false; 48 : 49 12089 : if (c == input::Input::Eof) 50 1308 : isEOF = true; 51 : else 52 10781 : in.pushChar(c); 53 : 54 12089 : return res; 55 : } 56 : 57 : // Get the ^([A-Za-z0-9]+) field name 58 7094 : std::string DebDBParser::getFieldName() 59 : { 60 7094 : if (! isBOL) 61 0 : throw exception::Parser(in, "field must start at the beginning of the line"); 62 : 63 7094 : std::string res; 64 : 65 : int c; 66 63954 : while ((c = in.nextChar()) != input::Input::Eof && (isalnum(c) || c == '-')) 67 49766 : res += c; 68 : 69 7094 : if (c == input::Input::Eof) 70 : { 71 0 : isEOF = true; 72 0 : if (!res.empty()) 73 0 : throw exception::Parser(in, "field is truncated at end of file. Last line begins with: \"" + res + "\n"); 74 : } else 75 7094 : in.pushChar(c); 76 : 77 0 : return res; 78 : } 79 : 80 : // Eat the \s*: characters that divide the field name and the field 81 : // data 82 7094 : void DebDBParser::eatFieldSep() 83 : { 84 : int c; 85 : 86 7094 : while ((c = in.nextChar()) != input::Input::Eof && isblank(c)) 87 : ; 88 : 89 7094 : if (c != ':') 90 : { 91 0 : if (c == input::Input::Eof) 92 : { 93 0 : isEOF = true; 94 0 : throw exception::Parser(in, "field is truncated at end of file"); 95 : } else { 96 0 : throw exception::Parser(in, std::string("invalid character `") + (char)c + "' expecting `:'"); 97 : } 98 : } 99 7094 : } 100 : 101 : // Get the \s*(.+?)\s*\n of a body line 102 17875 : void DebDBParser::appendFieldBody(std::string& body) 103 : { 104 : int c; 105 : 106 : // Skip leading spaces 107 17875 : while ((c = in.nextChar()) != input::Input::Eof && isblank(c)) 108 : ; 109 : 110 : // Get the body part 111 280757 : for ( ; c != input::Input::Eof && c != '\n'; c = in.nextChar()) 112 269976 : body += c; 113 : 114 : // Delete trailing spaces 115 10781 : size_t end = body.find_last_not_of(" \t"); 116 10781 : if (end != std::string::npos) 117 10781 : body.resize(end + 1); 118 : 119 10781 : if (c == input::Input::Eof) 120 0 : isEOF = true; 121 : else 122 : { 123 : //line++; 124 10781 : isBOL = true; 125 : } 126 10781 : } 127 : 128 : 129 1308 : DebDBParser::DebDBParser(input::Input& input) : 130 1308 : in(input), isBOL(true), isEOF(false) 131 : { 132 : // Go at the start of the next record 133 1308 : eatSpacesAndEmptyLines(); 134 1308 : } 135 : 136 : 137 : // Read a record and positions itself at the start of the next one 138 : // Returns false when there are no more records available 139 3261 : bool DebDBParser::nextRecord(Record& rec) 140 : { 141 3261 : if (isEOF) 142 7 : return false; 143 : 144 3254 : rec.clear(); 145 : 146 : int n; 147 12880 : do { 148 : // Read the field name 149 7094 : std::string field = getFieldName(); 150 7094 : std::string body; 151 : 152 : //fprintf(stderr, "Got field: %.*s\n", field.size(), field.data()); 153 : 154 : // Read the colon 155 7094 : eatFieldSep(); 156 : 157 : // Read the first line of the field body 158 7094 : appendFieldBody(body); 159 : //fprintf(stderr, "Got body: %.*s\n", body.size(), body.data()); 160 : 161 : // Read the continuation lines of field body 162 17875 : while ((n = eatSpacesAndEmptyLines()) == 0 && ! isBOL) 163 : { 164 3687 : body += '\n'; 165 : 166 3687 : size_t start_size = body.size(); 167 : 168 3687 : appendFieldBody(body); 169 : 170 : // Check for dot-only lines to be changed to empty lines 171 3687 : if (body.size() - start_size == 1 && body[body.size() - 1] == '.') 172 601 : body.resize(body.size() - 1); 173 : 174 : //fprintf(stderr, "Appended body: %.*s\n", body.size(), body.data()); 175 : } 176 : //fprintf(stderr, "Trailing newlines: %d\n", n); 177 : 178 : 179 7094 : rec.insert(std::pair<std::string,std::string>(field, body)); 180 : } while (!isEOF && !n); 181 : 182 3254 : return true; 183 : } 184 : 185 : } 186 6 : } 187 : 188 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include <ept/debtags/maint/vocabularyindexer.h> 2 : #include <ept/debtags/vocabulary.h> 3 : #include <ept/debtags/maint/vocabularymerger.h> 4 : #include <ept/debtags/maint/path.h> 5 : 6 : namespace ept { 7 : namespace debtags { 8 : 9 31 : VocabularyIndexer::VocabularyIndexer() 10 31 : : mainSource(Path::debtagsSourceDir()), userSource(Path::debtagsUserSourceDir()) 11 : { 12 31 : rescan(); 13 31 : } 14 : 15 31 : void VocabularyIndexer::rescan() 16 : { 17 31 : ts_main_src = mainSource.vocTimestamp(); 18 31 : ts_user_src = userSource.vocTimestamp(); 19 31 : ts_main_voc = Path::timestamp(Path::vocabulary()); 20 62 : ts_main_idx = Path::timestamp(Path::vocabularyIndex()); 21 62 : ts_user_voc = Path::timestamp(Path::userVocabulary()); 22 62 : ts_user_idx = Path::timestamp(Path::userVocabularyIndex()); 23 31 : } 24 : 25 31 : bool VocabularyIndexer::needsRebuild() const 26 : { 27 : // If there are no indexes of any kind, then we need rebuilding 28 31 : if (ts_user_voc == 0 && ts_user_idx == 0 && ts_main_voc == 0 && ts_main_idx == 0) 29 3 : return true; 30 : 31 : // If the user index is ok, then we are fine 32 28 : if (ts_user_voc >= sourceTimestamp() && ts_user_idx >= sourceTimestamp()) 33 28 : return false; 34 : 35 : // If there are user sources, then we cannot use the system index 36 0 : if (ts_user_src > 0) 37 0 : return true; 38 : 39 : // If there are no user sources, then we can fallback on the system 40 : // indexes in case the user indexes are not up to date 41 0 : if (ts_main_voc >= sourceTimestamp() && ts_main_idx >= sourceTimestamp()) 42 0 : return false; 43 : 44 0 : return true; 45 : } 46 : 47 31 : bool VocabularyIndexer::userIndexIsRedundant() const 48 : { 49 : // If there is no user index, then it is not redundant 50 31 : if (ts_user_voc == 0 && ts_user_idx == 0) 51 2 : return false; 52 : 53 : // If we have user sources, then the user index is never redundant 54 29 : if (ts_user_src > 0) 55 29 : return false; 56 : 57 : // If the system index is not up to date, then the user index is not 58 : // redundant 59 0 : if (ts_main_voc < sourceTimestamp() || ts_main_idx < sourceTimestamp()) 60 0 : return false; 61 : 62 0 : return true; 63 : } 64 : 65 3 : bool VocabularyIndexer::rebuild(const std::string& vocfname, const std::string& idxfname) 66 : { 67 : using namespace tagcoll; 68 : 69 : // Create the master MMap index 70 3 : diskindex::MasterMMapIndexer master(idxfname); 71 : 72 : // Read and merge vocabulary data 73 3 : VocabularyMerger voc; 74 3 : mainSource.readVocabularies(voc); 75 3 : userSource.readVocabularies(voc); 76 : 77 3 : if (voc.empty()) 78 2 : return false; 79 : //throw wibble::exception::Consistency("Reading debtags sources from " + mainSource.path() + " and " + userSource.path(), "Unable to find any vocabulary data"); 80 : 81 : // Write the merged vocabulary, and generate tag and facet IDs as a side 82 : // effect 83 1 : std::string tmpvocfname = vocfname + ".tmp"; 84 1 : voc.write(tmpvocfname); 85 : 86 : // Add the indexed vocabulary data to the master index 87 : // 0: facets 88 1 : master.append(voc.facetIndexer()); 89 : // 1: tags 90 1 : master.append(voc.tagIndexer()); 91 : 92 1 : if (rename(tmpvocfname.c_str(), vocfname.c_str()) == -1) 93 0 : throw wibble::exception::System("renaming " + tmpvocfname + " to " + vocfname); 94 : 95 1 : master.commit(); 96 1 : return true; 97 : } 98 : 99 31 : bool VocabularyIndexer::rebuildIfNeeded() 100 : { 101 31 : if (needsRebuild()) 102 : { 103 : // Decide if we rebuild the user index or the system index 104 : 105 3 : if (ts_user_src == 0 && Path::access(Path::debtagsIndexDir(), W_OK) == 0) 106 : { 107 : // There are no user sources and we can write to the system index 108 : // directory: rebuild the system index 109 1 : if (!rebuild(Path::vocabulary(), Path::vocabularyIndex())) 110 1 : return false; 111 0 : ts_main_voc = Path::timestamp(Path::vocabulary()); 112 0 : ts_main_idx = Path::timestamp(Path::vocabularyIndex()); 113 0 : if (Path::vocabulary() == Path::userVocabulary()) 114 0 : ts_user_voc = ts_main_voc; 115 0 : if (Path::vocabularyIndex() == Path::userVocabularyIndex()) 116 0 : ts_user_idx = ts_main_idx; 117 : } else { 118 2 : wibble::sys::fs::mkFilePath(Path::userVocabulary()); 119 4 : wibble::sys::fs::mkFilePath(Path::userVocabularyIndex()); 120 4 : if (!rebuild(Path::userVocabulary(), Path::userVocabularyIndex())) 121 1 : return false; 122 1 : ts_user_voc = Path::timestamp(Path::userVocabulary()); 123 2 : ts_user_idx = Path::timestamp(Path::userVocabularyIndex()); 124 : } 125 1 : return true; 126 : } 127 28 : return false; 128 : } 129 : 130 31 : bool VocabularyIndexer::deleteRedundantUserIndex() 131 : { 132 31 : if (userIndexIsRedundant()) 133 : { 134 : // Delete the user indexes if they exist 135 0 : if (Path::vocabulary() != Path::userVocabulary()) 136 : { 137 0 : unlink(Path::userVocabulary().c_str()); 138 0 : ts_user_voc = 0; 139 : } 140 0 : if (Path::vocabularyIndex() != Path::userVocabularyIndex()) 141 : { 142 0 : unlink(Path::userVocabularyIndex().c_str()); 143 0 : ts_user_idx = 0; 144 : } 145 0 : return true; 146 : } 147 31 : return false; 148 : } 149 : 150 31 : bool VocabularyIndexer::getUpToDateVocabulary(std::string& vocfname, std::string& idxfname) 151 : { 152 : // If there are no indexes of any kind, then we have nothing to return 153 31 : if (ts_user_voc == 0 && ts_user_idx == 0 && ts_main_voc == 0 && ts_main_idx == 0) 154 2 : return false; 155 : 156 : // If the user index is up to date, use it 157 29 : if (ts_user_voc >= sourceTimestamp() && 158 : ts_user_idx >= sourceTimestamp()) 159 : { 160 29 : vocfname = Path::userVocabulary(); 161 58 : idxfname = Path::userVocabularyIndex(); 162 29 : return true; 163 : } 164 : 165 : // If the user index is not up to date and we have user sources, we cannot 166 : // fall back to the system index 167 0 : if (ts_user_src != 0) 168 0 : return false; 169 : 170 : // Fallback to the system index 171 0 : if (ts_main_voc >= sourceTimestamp() && 172 : ts_main_idx >= sourceTimestamp()) 173 : { 174 0 : vocfname = Path::vocabulary(); 175 0 : idxfname = Path::vocabularyIndex(); 176 0 : return true; 177 : } 178 : 179 0 : return false; 180 : } 181 : 182 : 183 31 : bool VocabularyIndexer::obtainWorkingVocabulary(std::string& vocfname, std::string& idxfname) 184 : { 185 31 : VocabularyIndexer v; 186 : 187 31 : v.rebuildIfNeeded(); 188 31 : v.deleteRedundantUserIndex(); 189 31 : return v.getUpToDateVocabulary(vocfname, idxfname); 190 : } 191 : 192 : } 193 6 : } 194 : 195 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Merge different vocabularies together and create the tag and facet indexes 3 : * 4 : * Copyright (C) 2003-2007 Enrico Zini <enrico@debian.org> 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 2 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, write to the Free Software 18 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : */ 20 : 21 : #include <tagcoll/diskindex/mmap.h> 22 : #include <tagcoll/input/base.h> 23 : #include <string> 24 : #include <map> 25 : #include <set> 26 : 27 : #ifndef EPT_DEBTAGS_VOCABULARYMERGER_H 28 : #define EPT_DEBTAGS_VOCABULARYMERGER_H 29 : 30 : namespace ept { 31 : namespace debtags { 32 : 33 : class VocabularyMerger 34 7 : { 35 : protected: 36 : class FacetIndexer : public tagcoll::diskindex::MMapIndexer 37 : { 38 : protected: 39 : VocabularyMerger& vm; 40 : public: 41 7 : FacetIndexer(VocabularyMerger& vm) : vm(vm) {} 42 7 : virtual ~FacetIndexer() {} 43 : virtual int encodedSize() const; 44 : virtual void encode(char* buf) const; 45 : }; 46 : class TagIndexer : public tagcoll::diskindex::MMapIndexer 47 : { 48 : protected: 49 : VocabularyMerger& vm; 50 : public: 51 7 : TagIndexer(VocabularyMerger& vm) : vm(vm) {} 52 7 : virtual ~TagIndexer() {} 53 : virtual int encodedSize() const; 54 : virtual void encode(char* buf) const; 55 : }; 56 : class TagData : public std::map<std::string, std::string> 57 8715 : { 58 : public: 59 : std::string name; 60 : // Offset in the last written file (used for indexing) 61 : long ofs; 62 : int len; 63 : int id; 64 : 65 1245 : TagData() : ofs(0), len(0) {} 66 : }; 67 : class FacetData : public std::map<std::string, std::string> 68 434 : { 69 : public: 70 : std::string name; 71 : std::map<std::string, TagData> tags; 72 : // Offset in the last written file (used for indexing) 73 : long ofs; 74 : int len; 75 : int id; 76 : 77 62 : FacetData() : ofs(0), len(0) {} 78 : 79 : TagData& obtainTag(const std::string& fullname); 80 : }; 81 : std::map<std::string, FacetData> facets; 82 : int tagCount; 83 : FacetIndexer findexer; 84 : TagIndexer tindexer; 85 : 86 : FacetData& obtainFacet(const std::string& name); 87 : TagData& obtainTag(const std::string& fullname); 88 : 89 : public: 90 7 : VocabularyMerger() : tagCount(0), findexer(*this), tindexer(*this) {} 91 : 92 : /** 93 : * Check if there is any data in the merged vocabulary 94 : */ 95 3 : bool empty() const { return facets.empty(); } 96 : 97 : /** 98 : * Parse and import the vocabulary from `input', merging the data with the 99 : * previously imported ones 100 : */ 101 : void read(tagcoll::input::Input& input); 102 : 103 : /** 104 : * Write the vocabulary data to the given file 105 : */ 106 : void write(const std::string& fname); 107 : 108 : /** 109 : * Write the vocabulary data to the given output stream 110 : */ 111 : void write(FILE* out); 112 : 113 : /** 114 : * Get the facet indexer. 115 : * 116 : * Note: the indexers will only be functional after one of the write 117 : * methods have been invoked 118 : */ 119 7 : const tagcoll::diskindex::MMapIndexer& facetIndexer() const { return findexer; } 120 : 121 : /** 122 : * Get the tag indexer. 123 : * 124 : * Note: the indexers will only be functional after one of the write 125 : * methods have been invoked 126 : */ 127 7 : const tagcoll::diskindex::MMapIndexer& tagIndexer() const { return tindexer; } 128 : 129 : /** 130 : * Check if the vocabulary contains the facet `name' 131 : */ 132 : bool hasFacet(const std::string& name) const 133 : { 134 : return facets.find(name) != facets.end(); 135 : } 136 : 137 : /** 138 : * Check if the vocabulary contains the tag `fullname' 139 : */ 140 : bool hasTag(const std::string& fullname) const; 141 : 142 : /** 143 : * Return the ID for the given tag (or -1 if not found) 144 : */ 145 : int tagID(const std::string& fullname) const; 146 : 147 : /** 148 : * Return a set with all tag names 149 : */ 150 : std::set<std::string> tagNames() const; 151 : }; 152 : 153 : } 154 : } 155 : 156 : // vim:set ts=4 sw=4: 157 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 2 : /** 3 : * @file cache/component/debtags/serializer.h 4 : * @author Enrico Zini (enrico) <enrico@enricozini.org> 5 : */ 6 : 7 : #ifndef EPT_DEBTAGS_SERIALIZER_H 8 : #define EPT_DEBTAGS_SERIALIZER_H 9 : 10 : #include <ept/debtags/vocabulary.h> 11 : #include <ept/debtags/maint/pkgid.h> 12 : #include <tagcoll/patch.h> 13 : #include <wibble/mixin.h> 14 : #include <string> 15 : 16 : namespace ept { 17 : namespace debtags { 18 : 19 : template<typename OUT> 20 : class IntToPkg : public wibble::mixin::OutputIterator< IntToPkg<OUT> > 21 : { 22 : PkgId& pkgid; 23 : Vocabulary& voc; 24 : OUT out; 25 : 26 : public: 27 5 : IntToPkg(PkgId& pkgid, Vocabulary& voc, const OUT& out) 28 5 : : pkgid(pkgid), voc(voc), out(out) {} 29 : 30 : template<typename ITEMS, typename TAGS> 31 42291 : IntToPkg<OUT>& operator=(const std::pair<ITEMS, TAGS>& data) 32 : { 33 42291 : std::set<std::string> ritems; 34 42291 : std::set<Tag> rtags; 35 : 36 84582 : for (typename ITEMS::const_iterator i = data.first.begin(); 37 : i != data.first.end(); ++i) 38 : { 39 42291 : std::string pkg = pkgid.byID(*i); 40 42291 : if (!pkg.empty()) 41 42291 : ritems.insert(pkg); 42 : } 43 : 44 253489 : for (typename TAGS::const_iterator i = data.second.begin(); 45 : i != data.second.end(); ++i) 46 : { 47 211198 : Tag t = voc.tagByID(*i); 48 211198 : if (t.valid()) 49 211198 : rtags.insert(t); 50 : } 51 : 52 42291 : if (!ritems.empty() && !rtags.empty()) 53 : { 54 42267 : *out = make_pair(ritems, rtags); 55 42267 : ++out; 56 : } 57 42291 : return *this; 58 : } 59 : }; 60 : 61 : template<typename OUT> 62 5 : IntToPkg<OUT> intToPkg(PkgId& pkgid, Vocabulary& voc, const OUT& out) 63 : { 64 5 : return IntToPkg<OUT>(pkgid, voc, out); 65 : } 66 : 67 : template<typename OUT> 68 : class StringToInt : public wibble::mixin::OutputIterator< StringToInt<OUT> > 69 : { 70 : PkgId& pkgid; 71 : Vocabulary& voc; 72 : OUT out; 73 : 74 : public: 75 2 : StringToInt(PkgId& pkgid, Vocabulary& voc, const OUT& out) 76 2 : : pkgid(pkgid), voc(voc), out(out) {} 77 : 78 : template<typename ITEMS, typename TAGS> 79 21146 : StringToInt<OUT>& operator=(const std::pair<ITEMS, TAGS>& data) 80 : { 81 21146 : std::set<int> ritems; 82 21146 : std::set<int> rtags; 83 : 84 42292 : for (typename ITEMS::const_iterator i = data.first.begin(); 85 : i != data.first.end(); ++i) 86 : { 87 21146 : int id = pkgid.byName(*i); 88 21146 : if (id != -1) 89 21146 : ritems.insert(id); 90 : } 91 : 92 126874 : for (typename TAGS::const_iterator i = data.second.begin(); 93 : i != data.second.end(); ++i) 94 : { 95 105728 : Tag t = voc.tagByName(*i); 96 105728 : if (t.valid()) 97 105600 : rtags.insert(t.id()); 98 : } 99 : 100 21146 : if (!ritems.empty() && !rtags.empty()) 101 : { 102 21134 : *out = make_pair(ritems, rtags); 103 21134 : ++out; 104 : } 105 21146 : return *this; 106 : } 107 : 108 : }; 109 : 110 : template<typename OUT> 111 2 : StringToInt<OUT> stringToInt(PkgId& pkgid, Vocabulary& voc, const OUT& out) 112 : { 113 2 : return StringToInt<OUT>(pkgid, voc, out); 114 : } 115 : 116 : template<typename OUT> 117 : class StringToPkg : public wibble::mixin::OutputIterator< StringToPkg<OUT> > 118 : { 119 : PkgId& pkgid; 120 : Vocabulary& voc; 121 : OUT out; 122 : 123 : public: 124 : StringToPkg(PkgId& pkgid, Vocabulary& voc, const OUT& out) 125 : : pkgid(pkgid), voc(voc), out(out) {} 126 : 127 : template<typename ITEMS, typename TAGS> 128 : StringToPkg<OUT>& operator=(const std::pair<ITEMS, TAGS>& data) 129 : { 130 : std::set<std::string> ritems; 131 : std::set<Tag> rtags; 132 : 133 : for (typename ITEMS::const_iterator i = data.first.begin(); 134 : i != data.first.end(); ++i) 135 : { 136 : // Ensure that the package exists in the pkgid database 137 : if (pkgid.byName(*i) == -1) 138 : continue; 139 : ritems.insert(*i); 140 : } 141 : 142 : for (typename TAGS::const_iterator i = data.second.begin(); 143 : i != data.second.end(); ++i) 144 : { 145 : Tag t = voc.tagByName(*i); 146 : if (t.valid()) 147 : rtags.insert(t); 148 : } 149 : 150 : if (!ritems.empty() && !rtags.empty()) 151 : { 152 : *out = make_pair(ritems, rtags); 153 : ++out; 154 : } 155 : return *this; 156 : } 157 : 158 : }; 159 : 160 : template<typename OUT> 161 : StringToPkg<OUT> stringToPkg(PkgId& pkgid, Vocabulary& voc, const OUT& out) 162 : { 163 : return StringToPkg<OUT>(pkgid, voc, out); 164 : } 165 : 166 : template<typename OUT> 167 : class PkgToString : public wibble::mixin::OutputIterator< PkgToString<OUT> > 168 : { 169 : OUT out; 170 : public: 171 1 : PkgToString(const OUT& out) : out(out) {} 172 : 173 : template<typename ITEMS, typename TAGS> 174 1 : PkgToString<OUT>& operator=(const std::pair<ITEMS, TAGS>& data) 175 : { 176 1 : std::set<std::string> stags; 177 3 : for (typename TAGS::const_iterator i = data.second.begin(); 178 : i != data.second.end(); ++i) 179 2 : if (i->valid()) 180 2 : stags.insert(i->fullname()); 181 1 : *out = make_pair(data.first, stags); 182 1 : ++out; 183 1 : return *this; 184 : } 185 : }; 186 : 187 : template<typename OUT> 188 1 : PkgToString<OUT> pkgToString(const OUT& out) 189 : { 190 1 : return PkgToString<OUT>(out); 191 : } 192 : 193 : template<typename OUT> 194 : class PatchStringToInt : public wibble::mixin::OutputIterator< PatchStringToInt<OUT> > 195 : { 196 : PkgId& pkgid; 197 : Vocabulary& voc; 198 : OUT out; 199 : 200 : public: 201 1 : PatchStringToInt(PkgId& pkgid, Vocabulary& voc, const OUT& out) 202 1 : : pkgid(pkgid), voc(voc), out(out) {} 203 : 204 1 : PatchStringToInt<OUT>& operator=(const tagcoll::Patch<std::string, std::string>& patch) 205 : { 206 1 : int id = pkgid.byName(patch.item); 207 1 : if (id == -1) 208 0 : return *this; 209 : 210 1 : tagcoll::Patch<int, int> res(id); 211 2 : for (std::set<std::string>::const_iterator i = patch.added.begin(); 212 : i != patch.added.end(); ++i) 213 : { 214 1 : Tag tag = voc.tagByName(*i); 215 1 : if (tag.valid()) 216 1 : res.add(tag.id()); 217 : } 218 2 : for (std::set<std::string>::const_iterator i = patch.removed.begin(); 219 : i != patch.removed.end(); ++i) 220 : { 221 1 : Tag tag = voc.tagByName(*i); 222 1 : if (tag.valid()) 223 1 : res.remove(tag.id()); 224 : } 225 1 : *out = res; 226 1 : ++out; 227 1 : return *this; 228 : } 229 : }; 230 : 231 : template<typename OUT> 232 1 : PatchStringToInt<OUT> patchStringToInt(PkgId& pkgid, Vocabulary& voc, const OUT& out) 233 : { 234 1 : return PatchStringToInt<OUT>(pkgid, voc, out); 235 : } 236 : 237 : template<typename OUT> 238 : class PatchIntToString : public wibble::mixin::OutputIterator< PatchIntToString<OUT> > 239 : { 240 : PkgId& pkgid; 241 : Vocabulary& voc; 242 : OUT out; 243 : 244 : public: 245 2 : PatchIntToString(PkgId& pkgid, Vocabulary& voc, const OUT& out) 246 2 : : pkgid(pkgid), voc(voc), out(out) {} 247 : 248 2 : PatchIntToString<OUT>& operator=(const tagcoll::Patch<int, int>& patch) 249 : { 250 2 : std::string name = pkgid.byID(patch.item); 251 2 : if (name.empty()) 252 0 : return *this; 253 : 254 2 : tagcoll::Patch<std::string, std::string> res(name); 255 4 : for (std::set<int>::const_iterator i = patch.added.begin(); 256 : i != patch.added.end(); ++i) 257 : { 258 2 : Tag tag = voc.tagByID(*i); 259 2 : if (tag.valid()) 260 2 : res.add(tag.fullname()); 261 : } 262 3 : for (std::set<int>::const_iterator i = patch.removed.begin(); 263 : i != patch.removed.end(); ++i) 264 : { 265 1 : Tag tag = voc.tagByID(*i); 266 1 : if (tag.valid()) 267 1 : res.remove(tag.fullname()); 268 : } 269 2 : *out = res; 270 2 : ++out; 271 2 : return *this; 272 : } 273 : }; 274 : 275 : template<typename OUT> 276 2 : PatchIntToString<OUT> patchIntToString(PkgId& pkgid, Vocabulary& voc, const OUT& out) 277 : { 278 2 : return PatchIntToString<OUT>(pkgid, voc, out); 279 : } 280 : 281 : #if 0 282 : GOOD STUFF 283 : 284 : template<typename OUT> 285 : class ToInt : public wibble::mixin::OutputIterator< ToInt<OUT> > 286 : { 287 : OUT out; 288 : public: 289 : ToInt(const OUT& out) : out(out) {} 290 : 291 : template<typename ITEMS, typename TAGS> 292 : ToInt<OUT>& operator=(const std::pair<ITEMS, TAGS>& data) 293 : { 294 : std::set<int> iitems; 295 : std::set<int> itags; 296 : for (typename ITEMS::const_iterator i = data.first.begin(); 297 : i != data.first.end(); ++i) 298 : if (i->valid()) 299 : iitems.insert(i->ondiskId()); 300 : for (typename TAGS::const_iterator i = data.second.begin(); 301 : i != data.second.end(); ++i) 302 : if (i->valid()) 303 : itags.insert(i->id()); 304 : *out = make_pair(iitems, itags); 305 : ++out; 306 : return *this; 307 : } 308 : }; 309 : 310 : template<typename OUT> 311 : ToInt<OUT> toInt(const OUT& out) 312 : { 313 : return ToInt<OUT>(out); 314 : } 315 : 316 : template<typename ITEMCONV, typename TAGCONV, typename OUT> 317 : class Converter : public wibble::mixin::OutputIterator< Converter<ITEMCONV, TAGCONV, OUT> > 318 : { 319 : ITEMCONV itemconv; 320 : TAGCONV tagconv; 321 : OUT out; 322 : 323 : public: 324 : Converter(const ITEMCONV& itemconv, const TAGCONV& tagconv, const OUT& out) 325 : : itemconv(itemconv), tagconv(tagconv), out(out) {} 326 : 327 : template<typename ITEMS, typename TAGS> 328 : Converter<ITEMCONV, TAGCONV, OUT>& operator=(const std::pair<ITEMS, TAGS>& data) 329 : { 330 : *out = make_pair(itemconv(data.first), tagconv(data.second)); 331 : ++out; 332 : return *this; 333 : } 334 : }; 335 : 336 : template<typename ITEMCONV, typename TAGCONV, typename OUT> 337 : Converter<ITEMCONV, TAGCONV, OUT> converter(const ITEMCONV& itemconv, const TAGCONV& tagconv, const OUT& out) 338 : { 339 : return Converter<ITEMCONV, TAGCONV, OUT>(itemconv, tagconv, out); 340 : } 341 : 342 : 343 : template<typename OUT> 344 : class PatchToString : public wibble::mixin::OutputIterator< PatchToString<OUT> > 345 : { 346 : OUT out; 347 : 348 : public: 349 : PatchToString(const OUT& out) : out(out) {} 350 : 351 : template<typename PKG, typename TAG> 352 : PatchToString<OUT>& operator=(const tagcoll::Patch<PKG, TAG>& patch) 353 : { 354 : if (!patch.item.valid()) 355 : return *this; 356 : 357 : tagcoll::Patch<std::string, std::string> res(patch.item.name()); 358 : for (typename std::set<TAG>::const_iterator i = patch.added.begin(); 359 : i != patch.added.end(); ++i) 360 : if (i->valid()) 361 : res.add(i->fullname()); 362 : for (typename std::set<TAG>::const_iterator i = patch.removed.begin(); 363 : i != patch.removed.end(); ++i) 364 : if (i->valid()) 365 : res.remove(i->fullname()); 366 : *out = res; 367 : ++out; 368 : return *this; 369 : } 370 : }; 371 : 372 : template<typename OUT> 373 : PatchToString<OUT> patchToString(const OUT& out) 374 : { 375 : return PatchToString<OUT>(out); 376 : } 377 : 378 : #endif 379 : 380 : } 381 : } 382 : 383 : #if 0 384 : 385 : namespace tagcoll { 386 : namespace coll { 387 : 388 : template<> 389 : struct coll_traits< ept::cache::debtags::DebtagsIndex > 390 : { 391 : typedef ept::cache::Package<> item_type; 392 : typedef ept::cache::debtags::Tag tag_type; 393 : typedef std::set< ept::cache::Package<> > itemset_type; 394 : typedef std::set<ept::cache::debtags::Tag> tagset_type; 395 : }; 396 : 397 : } 398 : } 399 : 400 : namespace ept { 401 : namespace cache { 402 : namespace debtags { 403 : 404 : #if 0 405 : /** 406 : * Convert Facets to ints 407 : */ 408 : class FacetIntConverter : public Implementation<FacetIntConverter>, 409 : public Tagcoll::Converter<aptFront::cache::entity::Facet, int>, 410 : public Tagcoll::Converter<int, aptFront::cache::entity::Facet> 411 : { 412 : typedef aptFront::cache::entity::Facet Facet; 413 : typedef Tagcoll::OpSet<aptFront::cache::entity::Facet> FacetSet; 414 : typedef Tagcoll::OpSet<int> IntSet; 415 : public: 416 : virtual int operator()(const aptFront::cache::entity::Facet& item) const; 417 : virtual aptFront::cache::entity::Facet operator()(const int& item) const; 418 : 419 : virtual IntSet operator()(const FacetSet& item) const 420 : { return Tagcoll::Converter<Facet, int>::operator()(item); } 421 : virtual FacetSet operator()(const IntSet& item) const 422 : { return Tagcoll::Converter<int, Facet>::operator()(item); } 423 : 424 : static std::string componentName(); 425 : }; 426 : 427 : /** 428 : * Convert Facets to strings 429 : */ 430 : class FacetStringConverter : public Implementation<FacetStringConverter>, 431 : public Tagcoll::Converter<aptFront::cache::entity::Facet, std::string>, 432 : public Tagcoll::Converter<std::string, aptFront::cache::entity::Facet> 433 : { 434 : typedef aptFront::cache::entity::Facet Facet; 435 : typedef Tagcoll::OpSet<aptFront::cache::entity::Facet> FacetSet; 436 : typedef Tagcoll::OpSet<std::string> StringSet; 437 : public: 438 : virtual std::string operator()(const aptFront::cache::entity::Facet& item) const; 439 : virtual aptFront::cache::entity::Facet operator()(const std::string& item) const; 440 : 441 : virtual StringSet operator()(const FacetSet& item) const 442 : { return Tagcoll::Converter<Facet, std::string>::operator()(item); } 443 : virtual FacetSet operator()(const StringSet& item) const 444 : { return Tagcoll::Converter<std::string, Facet>::operator()(item); } 445 : 446 : static std::string componentName(); 447 : }; 448 : 449 : /** 450 : * Convert Vocabulary to ints 451 : */ 452 : class TagIntConverter : public Implementation<TagIntConverter>, 453 : public Tagcoll::Converter<aptFront::cache::entity::Tag, int>, 454 : public Tagcoll::Converter<int, aptFront::cache::entity::Tag> 455 : { 456 : typedef aptFront::cache::entity::Tag Tag; 457 : typedef Tagcoll::OpSet<aptFront::cache::entity::Tag> TagSet; 458 : typedef Tagcoll::OpSet<int> IntSet; 459 : public: 460 : virtual int operator()(const aptFront::cache::entity::Tag& item) const; 461 : virtual aptFront::cache::entity::Tag operator()(const int& item) const; 462 : 463 : virtual IntSet operator()(const TagSet& item) const 464 : { return Tagcoll::Converter<Tag, int>::operator()(item); } 465 : virtual TagSet operator()(const IntSet& item) const 466 : { return Tagcoll::Converter<int, Tag>::operator()(item); } 467 : 468 : static std::string componentName(); 469 : }; 470 : 471 : /** 472 : * Convert Vocabulary to strings 473 : */ 474 : class TagStringConverter : public Implementation<TagStringConverter>, 475 : public Tagcoll::Converter<aptFront::cache::entity::Tag, std::string>, 476 : public Tagcoll::Converter<std::string, aptFront::cache::entity::Tag> 477 : { 478 : typedef aptFront::cache::entity::Tag Tag; 479 : typedef Tagcoll::OpSet<aptFront::cache::entity::Tag> TagSet; 480 : typedef Tagcoll::OpSet<std::string> StringSet; 481 : public: 482 : virtual std::string operator()(const Tag& item) const; 483 : virtual Tag operator()(const std::string& item) const; 484 : 485 : virtual StringSet operator()(const TagSet& item) const 486 : { return Tagcoll::Converter<Tag, std::string>::operator()(item); } 487 : virtual TagSet operator()(const StringSet& item) const 488 : { return Tagcoll::Converter<std::string, Tag>::operator()(item); } 489 : 490 : TagSet parseTagList(const std::string& str) const; 491 : 492 : static std::string componentName(); 493 : }; 494 : 495 : /** 496 : * Convert Aggregator to ints 497 : */ 498 : class PackageIntConverter : public Implementation<PackageIntConverter>, 499 : public Tagcoll::Converter<aptFront::cache::entity::Package, int>, 500 : public Tagcoll::Converter<int, aptFront::cache::entity::Package> 501 : { 502 : typedef aptFront::cache::entity::Package Package; 503 : typedef Tagcoll::OpSet<aptFront::cache::entity::Package> PackageSet; 504 : typedef Tagcoll::OpSet<int> IntSet; 505 : public: 506 : virtual int operator()(const Package& item) const; 507 : virtual Package operator()(const int& item) const; 508 : 509 : virtual IntSet operator()(const PackageSet& item) const 510 : { return Tagcoll::Converter<Package, int>::operator()(item); } 511 : virtual PackageSet operator()(const IntSet& item) const 512 : { return Tagcoll::Converter<int, Package>::operator()(item); } 513 : 514 : static std::string componentName(); 515 : }; 516 : 517 : /** 518 : * Convert Aggregator to strings 519 : */ 520 : class PackageStringConverter : public Implementation<PackageStringConverter>, 521 : public Tagcoll::Converter<aptFront::cache::entity::Package, std::string>, 522 : public Tagcoll::Converter<std::string, aptFront::cache::entity::Package> 523 : { 524 : typedef aptFront::cache::entity::Package Package; 525 : typedef Tagcoll::OpSet<aptFront::cache::entity::Package> PackageSet; 526 : typedef Tagcoll::OpSet<std::string> StringSet; 527 : public: 528 : virtual std::string operator()(const Package& item) const; 529 : virtual Package operator()(const std::string& item) const; 530 : 531 : virtual StringSet operator()(const PackageSet& item) const 532 : { return Tagcoll::Converter<Package, std::string>::operator()(item); } 533 : virtual PackageSet operator()(const StringSet& item) const 534 : { return Tagcoll::Converter<std::string, Package>::operator()(item); } 535 : 536 : static std::string componentName(); 537 : }; 538 : 539 : #endif 540 : 541 : } 542 : } 543 : } 544 : 545 : #endif 546 : 547 : #endif 548 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 549 : 550 : #if 0 551 : /** 552 : * @file cache/debtags/serializer.h 553 : * @author Enrico Zini (enrico) <enrico@enricozini.org> 554 : */ 555 : 556 : #ifndef EPT_CACHE_DEBTAGS_SERIALIZER_TCC 557 : #define EPT_CACHE_DEBTAGS_SERIALIZER_TCC 558 : 559 : #include <ept/cache/debtags/serializer.h> 560 : #if 0 561 : #include <ept/cache/debtags/pkgidx.h> 562 : #include <ept/cache/debtags/vocabulary.h> 563 : #include <ept/cache/package.h> 564 : //#include <ept/cache/cache.h> 565 : #endif 566 : 567 : namespace ept { 568 : namespace t { 569 : namespace cache { 570 : namespace debtags { 571 : 572 : 573 : 574 : #if 0 575 : string FacetIntConverter::componentName() { return "FacetIntConverter"; } 576 : 577 : int FacetIntConverter::operator()(const aptFront::cache::entity::Facet& item) const 578 : { 579 : if (!item.valid()) return -1; 580 : return item.id(); 581 : } 582 : aptFront::cache::entity::Facet FacetIntConverter::operator()(const int& item) const 583 : { 584 : return cache().tags().facetByID(item); 585 : } 586 : 587 : string FacetStringConverter::componentName() { return "FacetStringConverter"; } 588 : 589 : std::string FacetStringConverter::operator()(const aptFront::cache::entity::Facet& item) const 590 : { 591 : if (!item.valid()) return string(); 592 : return item.name(); 593 : } 594 : aptFront::cache::entity::Facet FacetStringConverter::operator()(const std::string& item) const 595 : { 596 : return cache().tags().facetByName(item); 597 : } 598 : 599 : string TagIntConverter::componentName() { return "TagIntConverter"; } 600 : 601 : int TagIntConverter::operator()(const aptFront::cache::entity::Tag& item) const 602 : { 603 : if (!item.valid()) return -1; 604 : return item.id(); 605 : } 606 : aptFront::cache::entity::Tag TagIntConverter::operator()(const int& item) const 607 : { 608 : return cache().tags().tagByID(item); 609 : } 610 : 611 : string TagStringConverter::componentName() { return "TagStringConverter"; } 612 : 613 : std::string TagStringConverter::operator()(const aptFront::cache::entity::Tag& item) const 614 : { 615 : if (!item.valid()) return string(); 616 : return item.fullname(); 617 : } 618 : aptFront::cache::entity::Tag TagStringConverter::operator()(const std::string& item) const 619 : { 620 : return cache().tags().tagByName(item); 621 : } 622 : 623 : Tagcoll::OpSet<entity::Tag> TagStringConverter::parseTagList(const std::string& str) const 624 : { 625 : if (str.empty()) 626 : return Tagcoll::OpSet<entity::Tag>(); 627 : 628 : size_t i = str.find(", "); 629 : if (i == string::npos) 630 : { 631 : // Check if we need curly brace expansion 632 : if (str[str.size() - 1] == '}') 633 : { 634 : using namespace std; 635 : Tagcoll::OpSet<entity::Tag> res; 636 : size_t begin = str.find('{'); 637 : if (begin == string::npos) 638 : return res; 639 : string prefix(str, 0, begin); 640 : ++begin; 641 : size_t end; 642 : while ((end = str.find(',', begin)) != string::npos) 643 : { 644 : res += (*this)(prefix + str.substr(begin, end-begin)); 645 : begin = end + 1; 646 : } 647 : res += (*this)(prefix + str.substr(begin, str.size() - 1 - begin)); 648 : return res; 649 : } else { 650 : entity::Tag t = (*this)(str); 651 : if (t.valid()) 652 : return Tagcoll::OpSet<entity::Tag>() + t; 653 : else 654 : return Tagcoll::OpSet<entity::Tag>(); 655 : } 656 : } else { 657 : return parseTagList(string(str, 0, i)) + parseTagList(string(str, i+2)); 658 : } 659 : } 660 : 661 : string PackageIntConverter::componentName() { return "PackageIntConverter"; } 662 : 663 : int PackageIntConverter::operator()(const aptFront::cache::entity::Package& item) const 664 : { 665 : if (!item.valid()) return -1; 666 : return item.id(); 667 : } 668 : aptFront::cache::entity::Package PackageIntConverter::operator()(const int& item) const 669 : { 670 : PkgIdx& p = cache().pkgidx(); 671 : return cache().packages().packageByName(string(p.name(item), p.size(item))); 672 : } 673 : 674 : string PackageStringConverter::componentName() { return "PackageStringConverter"; } 675 : 676 : std::string PackageStringConverter::operator()(const aptFront::cache::entity::Package& item) const 677 : { 678 : if (!item.valid()) return string(); 679 : return item.name(); 680 : } 681 : aptFront::cache::entity::Package PackageStringConverter::operator()(const std::string& item) const 682 : { 683 : return cache().packages().packageByName(item); 684 : } 685 : #endif 686 : 687 : } 688 : } 689 : 690 : #endif 691 : 692 : #if 0 693 : #ifdef COMPILE_TESTSUITE 694 : //#include <apt-front/cache/component/debtags/update.h> 695 : #include <iostream> 696 : #include "test-utils.h" 697 : 698 : namespace tut { 699 : using namespace aptFront::cache; 700 : using namespace component; 701 : using namespace debtags; 702 : using namespace std; 703 : 704 : struct cache_component_debtags_serializer_shar { 705 : cache_component_debtags_serializer_shar () { 706 : aptInit (); 707 : ok = true; 708 : debtags::fetchNewData(); 709 : c.open( Cache::OpenDefault | 710 : Cache::OpenReadOnly | Cache::OpenDebtags ); 711 : } 712 : void check() { 713 : if (ok) return; 714 : ok = true; 715 : throw warning( "debtags init failed, cancelling" ); 716 : } 717 : ~cache_component_debtags_serializer_shar() { 718 : check(); 719 : } 720 : Cache c; 721 : bool ok; 722 : }; 723 : 724 : TESTGRP( cache_component_debtags_serializer ); 725 : 726 : using namespace Tagcoll; 727 : 728 : template<> template<> 729 : void to::test<1> () 730 : { 731 : check(); 732 : 733 : PackageStringConverter& psc = c.packagestringconverter(); 734 : 735 : ensure(psc("Slartibartsfart") == entity::Package()); 736 : 737 : /* Get the 'debtags' package */ 738 : entity::Package p = c.packages().packageByName( "debtags" ); 739 : ensure(p.valid()); 740 : 741 : /* Get the 'debtags' package using the serializer */ 742 : entity::Package p1 = psc("debtags"); 743 : ensure(p1.valid()); 744 : 745 : /* They must be the same */ 746 : ensure(p == p1); 747 : 748 : ensure_equals(psc(p), "debtags"); 749 : ensure_equals(psc(p1), "debtags"); 750 : ensure_equals(psc(p), psc(p1)); 751 : 752 : /* If there is an invalid package to serialize, it should be discarded */ 753 : { 754 : Tagcoll::OpSet<entity::Package> pkgs; 755 : pkgs += c.packages().packageByName( "debtags" ); 756 : pkgs += c.packages().packageByName( "tagcoll" ); 757 : pkgs += entity::Package(); 758 : 759 : ensure_equals (pkgs.size(), 3u); 760 : ensure_equals (psc(pkgs).size(), 2u); 761 : ensure (psc(pkgs).contains("debtags")); 762 : ensure (psc(pkgs).contains("tagcoll")); 763 : } 764 : 765 : /* If there is an invalid package to serialize, it should be discarded */ 766 : { 767 : Tagcoll::OpSet<std::string> pkgs; 768 : pkgs += "debtags"; 769 : pkgs += "tagcoll"; 770 : pkgs += "Slartibartsfart"; 771 : 772 : ensure_equals (pkgs.size(), 3u); 773 : ensure_equals (psc(pkgs).size(), 2u); 774 : ensure (psc(pkgs).contains(psc("debtags"))); 775 : ensure (psc(pkgs).contains(psc("tagcoll"))); 776 : ensure (!psc(pkgs).contains(entity::Package())); 777 : } 778 : } 779 : 780 : ostream& operator<<(ostream& out, const entity::Package& pkg) 781 : { 782 : if (pkg.valid()) 783 : return out << pkg.name(); 784 : else 785 : return out << "(invalid package)"; 786 : } 787 : 788 : // Check that package conversions work two-way 789 : template<> template<> 790 : void to::test<2> () 791 : { 792 : PackageStringConverter& psc = c.packagestringconverter(); 793 : for (component::Aggregator::iterator i = c.packages().packagesBegin(); 794 : i != c.packages().packagesEnd(); ++i) 795 : { 796 : try { 797 : ensure_equals(*i, psc(psc(*i))); 798 : } catch (...) { 799 : cerr << "Note: exception thrown during processing[string] of package " << i->name(string("(invalid package)")) << endl; 800 : throw; 801 : } 802 : } 803 : 804 : PackageIntConverter& pic = c.packageintconverter(); 805 : for (component::Aggregator::iterator i = c.packages().packagesBegin(); 806 : i != c.packages().packagesEnd(); ++i) 807 : { 808 : try { 809 : ensure_equals(*i, pic(pic(*i))); 810 : } catch (...) { 811 : cerr << "Note: exception thrown during processing[int] of package " << i->name(string("(invalid package)")) << endl; 812 : throw; 813 : } 814 : } 815 : } 816 : 817 : // Check that facet conversions work two-way 818 : template<> template<> 819 : void to::test<3> () 820 : { 821 : typedef Tagcoll::OpSet<entity::Facet> FacetSet; 822 : 823 : FacetStringConverter& fsc = c.facetstringconverter(); 824 : FacetSet allFacets(c.tags().facets()); 825 : for (FacetSet::const_iterator i = allFacets.begin(); i != allFacets.end(); i++) 826 : { 827 : try { 828 : ensure_equals(*i, fsc(fsc(*i))); 829 : } catch (...) { 830 : cerr << "Note: exception thrown during processing[string] of facet " << i->name() << endl; 831 : throw; 832 : } 833 : } 834 : 835 : FacetIntConverter& fic = c.facetintconverter(); 836 : for (FacetSet::const_iterator i = allFacets.begin(); i != allFacets.end(); i++) 837 : { 838 : try { 839 : ensure_equals(*i, fic(fic(*i))); 840 : } catch (...) { 841 : cerr << "Note: exception thrown during processing[int] of facet " << i->name() << endl; 842 : throw; 843 : } 844 : } 845 : } 846 : 847 : // Check that tag conversions work two-way 848 : template<> template<> 849 : void to::test<4> () 850 : { 851 : typedef Tagcoll::OpSet<entity::Tag> TagSet; 852 : 853 : TagStringConverter& tsc = c.tagstringconverter(); 854 : TagSet allTags(c.tags().tags()); 855 : for (TagSet::const_iterator i = allTags.begin(); i != allTags.end(); i++) 856 : { 857 : try { 858 : ensure_equals(*i, tsc(tsc(*i))); 859 : } catch (...) { 860 : cerr << "Note: exception thrown during processing[string] of tag " << i->fullname() << endl; 861 : throw; 862 : } 863 : } 864 : 865 : TagIntConverter& tic = c.tagintconverter(); 866 : for (TagSet::const_iterator i = allTags.begin(); i != allTags.end(); i++) 867 : { 868 : try { 869 : ensure_equals(*i, tic(tic(*i))); 870 : } catch (...) { 871 : cerr << "Note: exception thrown during processing[int] of tag " << i->fullname() << endl; 872 : throw; 873 : } 874 : } 875 : } 876 : 877 : // Check TagStringConverter::parseTagList 878 : template<> template<> 879 : void to::test<5> () 880 : { 881 : TagStringConverter& tsc = c.tagstringconverter(); 882 : OpSet<entity::Tag> ts; 883 : 884 : // First ensure that we're using existing tags as samples 885 : ensure(tsc("accessibility::TODO") != entity::Tag()); 886 : ensure(tsc("role::sw:devel-lib") != entity::Tag()); 887 : ensure(tsc("x11::xserver") != entity::Tag()); 888 : ensure(tsc("antani") == entity::Tag()); 889 : ensure(tsc("blinda") == entity::Tag()); 890 : ensure(tsc("supercazzola") == entity::Tag()); 891 : 892 : ts = tsc.parseTagList("role::sw:devel-lib"); 893 : ensure_equals(ts.size(), 1u); 894 : ensure(ts.contains(tsc("role::sw:devel-lib"))); 895 : 896 : ts = tsc.parseTagList("accessibility::TODO, x11::xserver, role::sw:devel-lib"); 897 : ensure_equals(ts.size(), 3u); 898 : ensure(ts.contains(tsc("accessibility::TODO"))); 899 : ensure(ts.contains(tsc("role::sw:devel-lib"))); 900 : ensure(ts.contains(tsc("x11::xserver"))); 901 : 902 : ts = tsc.parseTagList("antani"); 903 : ensure_equals(ts.size(), 0u); 904 : 905 : ts = tsc.parseTagList("antani, blinda, supercazzola"); 906 : ensure_equals(ts.size(), 0u); 907 : 908 : ts = tsc.parseTagList("antani, x11::xserver, blinda"); 909 : ensure_equals(ts.size(), 1u); 910 : ensure(ts.contains(tsc("x11::xserver"))); 911 : } 912 : 913 : // Check TagStringConverter::parseTagList's handling of curly brace expansion 914 : template<> template<> 915 : void to::test<6> () 916 : { 917 : TagStringConverter& tsc = c.tagstringconverter(); 918 : OpSet<entity::Tag> ts; 919 : 920 : // First ensure that we're using existing tags as samples 921 : ensure(tsc("role::TODO") != entity::Tag()); 922 : ensure(tsc("role::sw:server") != entity::Tag()); 923 : ensure(tsc("role::aux:dummy") != entity::Tag()); 924 : ensure(tsc("role::sw:amusement") != entity::Tag()); 925 : ensure(tsc("role::sw:server{}") == entity::Tag()); 926 : ensure(tsc("role::{}") == entity::Tag()); 927 : ensure(tsc("role::{") == entity::Tag()); 928 : ensure(tsc("role::}") == entity::Tag()); 929 : 930 : ts = tsc.parseTagList("role::{TODO,sw:server,aux:dummy,sw:amusement}"); 931 : ensure_equals(ts.size(), 4u); 932 : ensure(ts.contains(tsc("role::TODO"))); 933 : ensure(ts.contains(tsc("role::sw:server"))); 934 : ensure(ts.contains(tsc("role::aux:dummy"))); 935 : ensure(ts.contains(tsc("role::sw:amusement"))); 936 : 937 : ts = tsc.parseTagList("role::{TODO,aux:dummy}, role::sw:{server,amusement}"); 938 : ensure_equals(ts.size(), 4u); 939 : ensure(ts.contains(tsc("role::TODO"))); 940 : ensure(ts.contains(tsc("role::sw:server"))); 941 : ensure(ts.contains(tsc("role::aux:dummy"))); 942 : ensure(ts.contains(tsc("role::sw:amusement"))); 943 : } 944 : 945 : } 946 : #endif 947 : #endif 948 : #endif 949 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
debdbparser.cc |
|
84.4 % | 54 / 64 lines | |
debtagsindexer.cc |
|
74.8 % | 89 / 119 lines | |
debtagsindexer.h |
|
100.0 % | 5 / 5 lines | |
path.cc |
|
90.7 % | 49 / 54 lines | |
path.h |
|
100.0 % | 17 / 17 lines | |
pkgid.cc |
|
86.7 % | 13 / 15 lines | |
pkgid.h |
|
83.3 % | 5 / 6 lines | |
pkgid.test.h |
|
100.0 % | 18 / 18 lines | |
serializer.h |
|
97.8 % | 87 / 89 lines | |
serializer.test.h |
|
100.0 % | 48 / 48 lines | |
sourcedir.cc |
|
75.4 % | 43 / 57 lines | |
sourcedir.h |
|
100.0 % | 3 / 3 lines | |
sourcedir.tcc |
|
88.9 % | 8 / 9 lines | |
vocabularyindexer.cc |
|
69.1 % | 65 / 94 lines | |
vocabularyindexer.h |
|
100.0 % | 2 / 2 lines | |
vocabularymerger.cc |
|
81.2 % | 147 / 181 lines | |
vocabularymerger.h |
|
100.0 % | 13 / 13 lines | |
vocabularymerger.test.h |
|
100.0 % | 52 / 52 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 2 : /** 3 : * @file 4 : * @author Enrico Zini (enrico) <enrico@enricozini.org> 5 : */ 6 : 7 : /* 8 : * Tests for Debtags serialization filters 9 : * 10 : * Copyright (C) 2003-2007 Enrico Zini <enrico@debian.org> 11 : * 12 : * This library is free software; you can redistribute it and/or 13 : * modify it under the terms of the GNU Lesser General Public 14 : * License as published by the Free Software Foundation; either 15 : * version 2.1 of the License, or (at your option) any later version. 16 : * 17 : * This library is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 : * Lesser General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU Lesser General Public 23 : * License along with this library; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : #include <ept/debtags/maint/serializer.h> 28 : #include <ept/debtags/maint/pkgid.h> 29 : #include <ept/debtags/maint/path.h> 30 : #include <ept/debtags/vocabulary.h> 31 : #include <ept/debtags/debtags.h> 32 : 33 : #include <tagcoll/coll/simple.h> 34 : 35 : #include <wibble/singleton.h> 36 : 37 : #include <ept/test.h> 38 : 39 : using namespace std; 40 : using namespace tagcoll; 41 : using namespace ept; 42 : using namespace ept::debtags; 43 : 44 : struct TestSerializer : DebtagsTestEnvironment 45 2 : { 46 : Debtags debtags; 47 : Vocabulary& voc; 48 : PkgId& pkgid; 49 : 50 2 : TestSerializer() 51 2 : : voc(debtags.vocabulary()), pkgid(debtags.pkgid()) {} 52 : 53 : /* Test going from a stream of tag data <string, string> to a stream of tag 54 : * data <int, int> to a stream of tag data <Package, Tag> and finally back to a 55 : * stream of tag data <string, string> 56 : */ 57 1 : Test _1() 58 : { 59 : // Source data <string, string> 60 1 : coll::Simple<string, string> source; 61 1 : source.insert(wibble::singleton(string("debtags")), wibble::singleton(string("use::editing"))); 62 2 : source.insert(wibble::singleton(string("debtags")), wibble::singleton(string("role::program"))); 63 : 64 : // <string, string> -> <int, int> 65 1 : coll::Simple<int, int> dest; 66 1 : source.output(stringToInt(pkgid, voc, inserter(dest))); 67 : 68 1 : assert_eq(dest.itemCount(), 1u); 69 2 : assert_eq(dest.tagCount(), 2u); 70 : 71 : // <int, int> -> <Package, Tag> 72 1 : coll::Simple<string, Tag> dest1; 73 1 : dest.output(intToPkg(pkgid, voc, inserter(dest1))); 74 : 75 1 : assert_eq(dest1.itemCount(), 1u); 76 2 : assert_eq(dest1.tagCount(), 2u); 77 : 78 2 : std::set<Tag> tags = dest1.getTagsOfItem("debtags"); 79 2 : assert_eq(tags.size(), 2u); 80 : 81 2 : Tag useEditing = voc.tagByName("use::editing"); 82 2 : Tag roleProgram = voc.tagByName("role::program"); 83 : 84 2 : assert(tags.find(useEditing) != tags.end()); 85 2 : assert(tags.find(roleProgram) != tags.end()); 86 : 87 : // <Package, Tag> -> <string, string> 88 1 : coll::Simple<string, string> dest2; 89 1 : dest1.output(pkgToString(inserter(dest2))); 90 : 91 1 : assert_eq(dest2.itemCount(), 1u); 92 2 : assert_eq(dest2.tagCount(), 2u); 93 : 94 2 : std::set<std::string> tags1 = dest2.getTagsOfItem("debtags"); 95 2 : assert_eq(tags1.size(), 2u); 96 : 97 2 : assert(tags1.find("use::editing") != tags1.end()); 98 2 : assert(tags1.find("role::program") != tags1.end()); 99 1 : } 100 : 101 : /* Test going from patch with strings to patch with ints and vice versa */ 102 1 : Test _2() 103 : { 104 1 : PatchList<string, string> change; 105 : change.addPatch(Patch<string, string>("debtags", 106 : wibble::singleton(string("use::gameplaying")), 107 1 : wibble::singleton(string("use::editing")))); 108 : 109 : // Deserialise to ints 110 1 : PatchList<int, int> intChange; 111 1 : change.output(patchStringToInt(pkgid, voc, tagcoll::inserter(intChange))); 112 1 : assert_eq(intChange.size(), 1u); 113 2 : assert_eq(intChange.begin()->second.added.size(), 1u); 114 2 : assert_eq(intChange.begin()->second.removed.size(), 1u); 115 : 116 : // Serialise back to strings 117 1 : PatchList<string, string> change1; 118 1 : intChange.output(patchIntToString(pkgid, voc, tagcoll::inserter(change1))); 119 1 : assert_eq(change1.size(), 1u); 120 2 : assert_eq(change1.begin()->first, string("debtags")); 121 2 : assert_eq(change1.begin()->second.item, string("debtags")); 122 2 : assert_eq(change1.begin()->second.added.size(), 1u); 123 2 : assert_eq(*change1.begin()->second.added.begin(), string("use::gameplaying")); 124 2 : assert_eq(change1.begin()->second.removed.size(), 1u); 125 2 : assert_eq(*change1.begin()->second.removed.begin(), string("use::editing")); 126 1 : } 127 : 128 : }; 129 : 130 : #include <tagcoll/coll/simple.tcc> 131 : #include <tagcoll/patch.tcc> 132 : 133 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 2 : /* 3 : * id->package mapping 4 : * 5 : * Copyright (C) 2006 Enrico Zini <enrico@debian.org> 6 : * 7 : * This program is free software; you can redistribute it and/or modify 8 : * it under the terms of the GNU General Public License as published by 9 : * the Free Software Foundation; either version 2 of the License, or 10 : * (at your option) any later version. 11 : * 12 : * This program is distributed in the hope that it will be useful, 13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : * GNU General Public License for more details. 16 : * 17 : * You should have received a copy of the GNU General Public License 18 : * along with this program; if not, write to the Free Software 19 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 : */ 21 : 22 : #include <ept/debtags/maint/pkgid.h> 23 : #include <ept/debtags/maint/path.h> 24 : #include <ept/debtags/debtags.h> 25 : #include <set> 26 : 27 : #include <ept/test.h> 28 : 29 : using namespace std; 30 : using namespace ept; 31 : using namespace ept::debtags; 32 : 33 : struct TestPkgid : DebtagsTestEnvironment 34 2 : { 35 : Debtags debtags; 36 : PkgId& pkgid; 37 : 38 2 : TestPkgid() 39 2 : : pkgid(debtags.pkgid()) 40 : { 41 2 : } 42 : 43 : // Check that we can go from name to ID and back 44 1 : Test _1() 45 : { 46 : //int x = 0; 47 21146 : for (Debtags::const_iterator i = debtags.begin(); 48 : i != debtags.end(); ++i) 49 : { 50 21145 : int id = pkgid.byName(i->first); 51 21145 : std::string pkg = pkgid.byID(id); 52 21145 : assert(i->first == pkg); 53 : 54 : /* std::cerr << x << ": " << i->id() << ": " 55 : << i->name() << ", " << pkgidx().name( i->id() ) << 56 : std::endl; */ 57 : //++ x; 58 1 : } 59 1 : } 60 : 61 : // Check that IDs are distinct 62 1 : Test _2() 63 : { 64 : using namespace std; 65 : 66 1 : size_t count = 0; 67 1 : set<int> ids; 68 21146 : for (Debtags::const_iterator i = debtags.begin(); i != debtags.end(); ++i, ++count) 69 21146 : ids.insert(pkgid.byName(i->first)); 70 1 : assert_eq(ids.size(), count); 71 1 : } 72 : 73 : }; 74 : 75 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include <ept/debtags/maint/debtagsindexer.h> 2 : #include <ept/debtags/maint/path.h> 3 : #include <ept/debtags/maint/pkgid.h> 4 : #include <ept/debtags/maint/serializer.h> 5 : #include <ept/debtags/vocabulary.h> 6 : 7 : #include <tagcoll/coll/intdiskindex.h> 8 : #include <tagcoll/coll/simple.h> 9 : #include <tagcoll/TextFormat.h> 10 : #include <tagcoll/stream/filters.h> 11 : 12 : #include <wibble/exception.h> 13 : 14 : #include <cstring> 15 : 16 : using namespace std; 17 : 18 : namespace ept { 19 : namespace debtags { 20 : 21 : /// MMapIndexer that indexes the package names 22 : struct PkgIdGenerator : public tagcoll::diskindex::MMapIndexer 23 2 : { 24 : // Sorted set of all available package names 25 : std::set<std::string> pkgs; 26 : 27 3 : int encodedSize() const 28 : { 29 3 : int size = pkgs.size() * sizeof(int); 30 63438 : for (std::set<std::string>::const_iterator i = pkgs.begin(); 31 : i != pkgs.end(); ++i) 32 63435 : size += i->size() + 1; 33 3 : return tagcoll::diskindex::MMap::align(size); 34 : } 35 : 36 2 : void encode(char* buf) const 37 : { 38 2 : int pos = pkgs.size() * sizeof(int); 39 2 : int idx = 0; 40 42292 : for (std::set<std::string>::const_iterator i = pkgs.begin(); 41 : i != pkgs.end(); ++i) 42 : { 43 42290 : ((int*)buf)[idx++] = pos; 44 42290 : memcpy(buf + pos, i->c_str(), i->size() + 1); 45 42290 : pos += i->size() + 1; 46 : } 47 2 : } 48 : }; 49 : 50 : 51 10 : DebtagsIndexer::DebtagsIndexer(Vocabulary& voc) 52 : : voc(voc), 53 : mainSource(Path::debtagsSourceDir()), 54 10 : userSource(Path::debtagsUserSourceDir()) 55 : { 56 10 : rescan(); 57 10 : } 58 : 59 10 : void DebtagsIndexer::rescan() 60 : { 61 10 : ts_main_src = mainSource.timestamp(); 62 10 : ts_user_src = userSource.timestamp(); 63 10 : ts_main_tag = Path::timestamp(Path::tagdb()); 64 20 : ts_main_idx = Path::timestamp(Path::tagdbIndex()); 65 20 : ts_user_tag = Path::timestamp(Path::userTagdb()); 66 20 : ts_user_idx = Path::timestamp(Path::userTagdbIndex()); 67 10 : } 68 : 69 10 : bool DebtagsIndexer::needsRebuild() const 70 : { 71 : // If there are no indexes of any kind, then we need rebuilding 72 10 : if (ts_user_tag == 0 && ts_user_idx == 0 && ts_main_tag == 0 && ts_main_idx == 0) 73 2 : return true; 74 : 75 : // If the user index is ok, then we are fine 76 8 : if (ts_user_tag >= sourceTimestamp() && ts_user_idx >= sourceTimestamp()) 77 8 : return false; 78 : 79 : // If there are user sources, then we cannot use the system index 80 0 : if (ts_user_src > 0) 81 0 : return true; 82 : 83 : // If there are no user sources, then we can fallback on the system 84 : // indexes in case the user indexes are not up to date 85 0 : if (ts_main_tag >= sourceTimestamp() && ts_main_idx >= sourceTimestamp()) 86 0 : return false; 87 : 88 0 : return true; 89 : } 90 : 91 10 : bool DebtagsIndexer::userIndexIsRedundant() const 92 : { 93 : // If there is no user index, then it is not redundant 94 10 : if (ts_user_tag == 0 && ts_user_idx == 0) 95 1 : return false; 96 : 97 : // If we have user sources, then the user index is never redundant 98 9 : if (ts_user_src > 0) 99 9 : return false; 100 : 101 : // If the system index is not up to date, then the user index is not 102 : // redundant 103 0 : if (ts_main_tag < sourceTimestamp() || ts_main_idx < sourceTimestamp()) 104 0 : return false; 105 : 106 0 : return true; 107 : } 108 : 109 2 : bool DebtagsIndexer::rebuild(const std::string& tagfname, const std::string& idxfname) 110 : { 111 : using namespace tagcoll; 112 : 113 2 : diskindex::MasterMMapIndexer master(idxfname); 114 : 115 : // Read and merge tag data 116 2 : coll::Simple<string, string> merged; 117 2 : mainSource.readTags(inserter(merged)); 118 2 : userSource.readTags(inserter(merged)); 119 : 120 2 : if (merged.empty()) 121 : //throw wibble::exception::Consistency("Reading debtags sources from " + Path::debtagsSourceDir() + " and " + Path::debtagsUserSourceDir(), "Unable to find any tag data"); 122 1 : return false; 123 : 124 : // Create the pkgid index 125 1 : PkgIdGenerator pkgidGen; 126 21146 : for (coll::Simple<string, string>::const_iterator i = merged.begin(); 127 : i != merged.end(); ++i) 128 21145 : pkgidGen.pkgs.insert(i->first); 129 : 130 : // Temporary in-memory index to use for converting packages to ints while 131 : // creating the debtags index 132 1 : char buf[pkgidGen.encodedSize()]; 133 1 : pkgidGen.encode(buf); 134 1 : PkgId pkgid(buf, pkgidGen.encodedSize()); 135 : 136 : // Create the Debtags index 137 1 : coll::IntDiskIndexer tagindexer; 138 1 : merged.output(stringToInt(pkgid, voc, inserter(tagindexer))); 139 : 140 : // MMap 0: pkgid 141 1 : master.append(pkgidGen); 142 : // MMap 1: pkg->tag 143 1 : master.append(tagindexer.pkgIndexer()); 144 : // MMap 2: tag->pkg 145 1 : master.append(tagindexer.tagIndexer()); 146 : 147 : // Write the tag database in text format 148 1 : std::string tmpdb = tagfname + ".tmp"; 149 1 : FILE* out = fopen(tmpdb.c_str(), "wt"); 150 1 : if (!out) throw wibble::exception::File(tmpdb, "creating temporary copy of tag index"); 151 1 : merged.output(textformat::StdioWriter(out)); 152 1 : fclose(out); 153 : 154 : // Perform "atomic" update of the tag database 155 : // FIXME: cannot be atomic because race conditions happening between file 156 : // renames 157 1 : if (rename(tmpdb.c_str(), tagfname.c_str()) == -1) 158 0 : throw wibble::exception::System("Renaming " + tmpdb + " to " + tagfname); 159 : 160 1 : master.commit(); 161 1 : return true; 162 : } 163 : 164 10 : bool DebtagsIndexer::rebuildIfNeeded() 165 : { 166 10 : if (needsRebuild()) 167 : { 168 : // Decide if we rebuild the user index or the system index 169 : 170 2 : if (ts_user_src == 0 && Path::access(Path::debtagsIndexDir(), W_OK) == 0) 171 : { 172 : // There are no user sources and we can write to the system index 173 : // directory: rebuild the system index 174 1 : if (!rebuild(Path::tagdb(), Path::tagdbIndex())) 175 1 : return false; 176 0 : ts_main_tag = Path::timestamp(Path::tagdb()); 177 0 : ts_main_idx = Path::timestamp(Path::tagdbIndex()); 178 0 : if (Path::tagdb() == Path::userTagdb()) 179 0 : ts_user_tag = ts_main_tag; 180 0 : if (Path::tagdbIndex() == Path::userTagdbIndex()) 181 0 : ts_user_idx = ts_main_idx; 182 : } else { 183 1 : wibble::sys::fs::mkFilePath(Path::userTagdb()); 184 2 : wibble::sys::fs::mkFilePath(Path::userTagdbIndex()); 185 2 : if (!rebuild(Path::userTagdb(), Path::userTagdbIndex())) 186 0 : return false; 187 1 : ts_user_tag = Path::timestamp(Path::userTagdb()); 188 2 : ts_user_idx = Path::timestamp(Path::userTagdbIndex()); 189 : } 190 1 : return true; 191 : } 192 8 : return false; 193 : } 194 : 195 10 : bool DebtagsIndexer::deleteRedundantUserIndex() 196 : { 197 10 : if (userIndexIsRedundant()) 198 : { 199 : // Delete the user indexes if they exist 200 0 : if (Path::tagdb() != Path::userTagdb()) 201 : { 202 0 : unlink(Path::userTagdb().c_str()); 203 0 : ts_user_tag = 0; 204 : } 205 0 : if (Path::tagdbIndex() != Path::userTagdbIndex()) 206 : { 207 0 : unlink(Path::userTagdbIndex().c_str()); 208 0 : ts_user_idx = 0; 209 : } 210 0 : return true; 211 : } 212 10 : return false; 213 : } 214 : 215 10 : bool DebtagsIndexer::getUpToDateTagdb(std::string& tagfname, std::string& idxfname) 216 : { 217 : // If there are no indexes of any kind, then we have nothing to return 218 10 : if (ts_user_tag == 0 && ts_user_idx == 0 && ts_main_tag == 0 && ts_main_idx == 0) 219 1 : return false; 220 : 221 : // If the user index is up to date, use it 222 9 : if (ts_user_tag >= sourceTimestamp() && 223 : ts_user_idx >= sourceTimestamp()) 224 : { 225 9 : tagfname = Path::userTagdb(); 226 18 : idxfname = Path::userTagdbIndex(); 227 9 : return true; 228 : } 229 : 230 : // If the user index is not up to date and we have user sources, we cannot 231 : // fall back to the system index 232 0 : if (ts_user_src != 0) 233 0 : return false; 234 : 235 : // Fallback to the system index 236 0 : if (ts_main_tag >= sourceTimestamp() && 237 : ts_main_idx >= sourceTimestamp()) 238 : { 239 0 : tagfname = Path::tagdb(); 240 0 : idxfname = Path::tagdbIndex(); 241 0 : return true; 242 : } 243 : 244 0 : return false; 245 : } 246 : 247 : 248 : 249 10 : bool DebtagsIndexer::obtainWorkingDebtags(Vocabulary& voc, std::string& tagfname, std::string& idxfname) 250 : { 251 10 : DebtagsIndexer t(voc); 252 : 253 10 : t.rebuildIfNeeded(); 254 10 : t.deleteRedundantUserIndex(); 255 10 : return t.getUpToDateTagdb(tagfname, idxfname); 256 : } 257 : 258 : } 259 : } 260 : 261 : #include <ept/debtags/maint/sourcedir.tcc> 262 : #include <tagcoll/coll/simple.tcc> 263 : 264 : // vim:set ts=4 sw=4: 265 : // -*- C++ -*- |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_DEBTAGS_SOURCEDIR_H 2 : #define EPT_DEBTAGS_SOURCEDIR_H 3 : 4 : /** @file 5 : * @author Enrico Zini <enrico@enricozini.org> 6 : * Debtags data source directory access 7 : */ 8 : 9 : /* 10 : * Copyright (C) 2003,2004,2005,2006,2007 Enrico Zini <enrico@debian.org> 11 : * 12 : * This program is free software; you can redistribute it and/or modify 13 : * it under the terms of the GNU General Public License as published by 14 : * the Free Software Foundation; either version 2 of the License, or 15 : * (at your option) any later version. 16 : * 17 : * This program is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 : * GNU General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU General Public License 23 : * along with this program; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : #include <wibble/sys/fs.h> 28 : #include <string> 29 : 30 : namespace ept { 31 : namespace debtags { 32 : 33 : class VocabularyMerger; 34 : 35 : /** 36 : * Access a directory containing Debtags data files 37 : */ 38 : class SourceDir : public wibble::sys::fs::Directory 39 82 : { 40 : protected: 41 : enum FileType { SKIP, TAG, VOC, TAGGZ, VOCGZ }; 42 : 43 : // Check if a file name is a tag file, a vocabulary file or a file to skip. 44 : // Please notice that it works on file names, not paths. 45 : FileType fileType(const std::string& name); 46 : 47 : public: 48 82 : SourceDir(const std::string& path) : Directory(path) {} 49 : 50 : /// Return the time of the newest file in the source directory 51 : time_t timestamp(); 52 : 53 : /// Return the time of the newest vocabulary file in the source directory 54 : time_t vocTimestamp(); 55 : 56 : /// Return the time of the newest tag file in the source directory 57 : time_t tagTimestamp(); 58 : 59 : /// Read the tag files in the directory and output their content to out 60 : template<typename OUT> 61 4 : void readTags(OUT out); 62 : 63 : /** 64 : * Read the vocabulary files in the directory and output their content to 65 : * out 66 : */ 67 : void readVocabularies(VocabularyMerger& out); 68 : }; 69 : 70 : } 71 : } 72 : 73 : // vim:set ts=4 sw=4: 74 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; indent-tabs-mode: t -*- 2 : /** \file 3 : * debtags paths 4 : */ 5 : 6 : /* 7 : * Copyright (C) 2005,2006,2007 Enrico Zini <enrico@debian.org> 8 : * 9 : * This program is free software; you can redistribute it and/or modify 10 : * it under the terms of the GNU General Public License as published by 11 : * the Free Software Foundation; either version 2 of the License, or 12 : * (at your option) any later version. 13 : * 14 : * This program is distributed in the hope that it will be useful, 15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : * GNU General Public License for more details. 18 : * 19 : * You should have received a copy of the GNU General Public License 20 : * along with this program; if not, write to the Free Software 21 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 : */ 23 : 24 : #include <string> 25 : 26 : struct stat; 27 : 28 : #ifndef EPT_DEBTAGS_PATH_H 29 : #define EPT_DEBTAGS_PATH_H 30 : 31 : namespace ept { 32 : namespace debtags { 33 : 34 : /** 35 : * Singleton class to configure and access the various Debtags paths 36 : */ 37 : class Path 38 1 : { 39 : public: 40 : static std::string vocabulary(); 41 : static std::string vocabularyIndex(); 42 : static std::string userVocabulary(); 43 : static std::string userVocabularyIndex(); 44 : static std::string tagdb(); 45 : static std::string tagdbIndex(); 46 : static std::string userTagdb(); 47 : static std::string userTagdbIndex(); 48 : static std::string pkgidx(); 49 : static std::string userPkgidx(); 50 : 51 : static std::string debtagsSourceDir(); 52 : static std::string debtagsIndexDir(); 53 : static std::string debtagsUserSourceDir(); 54 : static std::string debtagsUserIndexDir(); 55 : 56 : // Directory where Debtags source data is found 57 : static void setDebtagsSourceDir( const std::string &s ); 58 : 59 : // Directory where Debtags indexes are kept 60 : static void setDebtagsIndexDir( const std::string &s ); 61 : 62 : // User-specific directory for Debtags source data 63 : static void setDebtagsUserSourceDir( const std::string &s ); 64 : 65 : // User-specific directory for Debtags index data 66 : static void setDebtagsUserIndexDir( const std::string &s ); 67 : 68 : static int access( const std::string &, int ); 69 : static time_t timestamp( const std::string& ); 70 : 71 : // RAII-style classes to temporarily override directories 72 : class OverrideDebtagsSourceDir 73 : { 74 : std::string old; 75 : public: 76 31 : OverrideDebtagsSourceDir(const std::string& path) : old(Path::debtagsSourceDir()) 77 : { 78 31 : Path::setDebtagsSourceDir(path); 79 31 : } 80 31 : ~OverrideDebtagsSourceDir() { Path::setDebtagsSourceDir(old); } 81 : }; 82 : class OverrideDebtagsIndexDir 83 : { 84 : std::string old; 85 : public: 86 31 : OverrideDebtagsIndexDir(const std::string& path) : old(Path::debtagsIndexDir()) 87 : { 88 31 : Path::setDebtagsIndexDir(path); 89 31 : } 90 31 : ~OverrideDebtagsIndexDir() { Path::setDebtagsIndexDir(old); } 91 : }; 92 : class OverrideDebtagsUserSourceDir 93 : { 94 : std::string old; 95 : public: 96 31 : OverrideDebtagsUserSourceDir(const std::string& path) : old(Path::debtagsUserSourceDir()) 97 : { 98 31 : Path::setDebtagsUserSourceDir(path); 99 31 : } 100 31 : ~OverrideDebtagsUserSourceDir() { Path::setDebtagsUserSourceDir(old); } 101 : }; 102 : class OverrideDebtagsUserIndexDir 103 : { 104 : std::string old; 105 : public: 106 31 : OverrideDebtagsUserIndexDir(const std::string& path) : old(Path::debtagsUserIndexDir()) 107 : { 108 31 : Path::setDebtagsUserIndexDir(path); 109 31 : } 110 31 : ~OverrideDebtagsUserIndexDir() { Path::setDebtagsUserIndexDir(old); } 111 : }; 112 : protected: 113 : static Path *s_instance; 114 : static Path &instance(); 115 : 116 : // Directory where Debtags source data is found 117 : std::string m_debtagsSourceDir; 118 : 119 : // Directory where Debtags indexes are kept 120 : std::string m_debtagsIndexDir; 121 : 122 : // User-specific directory for Debtags source data 123 : std::string m_debtagsUserSourceDir; 124 : 125 : // User-specific directory for Debtags index data 126 : std::string m_debtagsUserIndexDir; 127 : }; 128 : 129 : } 130 : } 131 : 132 : // vim:set ts=4 sw=4: 133 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 2 : #ifndef EPT_DEBTAGS_PKGID_H 3 : #define EPT_DEBTAGS_PKGID_H 4 : 5 : /** @file 6 : * @author Enrico Zini <enrico@enricozini.org> 7 : * Quick map from package IDs to package names 8 : */ 9 : 10 : /* 11 : * Copyright (C) 2003-2007 Enrico Zini <enrico@debian.org> 12 : * 13 : * This program is free software; you can redistribute it and/or modify 14 : * it under the terms of the GNU General Public License as published by 15 : * the Free Software Foundation; either version 2 of the License, or 16 : * (at your option) any later version. 17 : * 18 : * This program is distributed in the hope that it will be useful, 19 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 : * GNU General Public License for more details. 22 : * 23 : * You should have received a copy of the GNU General Public License 24 : * along with this program; if not, write to the Free Software 25 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 : */ 27 : 28 : #include <tagcoll/diskindex/mmap.h> 29 : #include <string> 30 : 31 : namespace ept { 32 : namespace debtags { 33 : 34 : /** 35 : * Maps Packages to IDs and vice-versa. 36 : * 37 : * This is used in building the Debtags fast index, which works representing 38 : * tags and packages as int IDs 39 : */ 40 : class PkgId : public tagcoll::diskindex::MMap 41 11 : { 42 : tagcoll::diskindex::MasterMMap mastermmap; 43 : time_t m_timestamp; 44 : 45 : public: 46 : PkgId(); 47 : PkgId(const tagcoll::diskindex::MasterMMap& master, size_t idx); 48 : PkgId(const char* buf, int size); 49 : 50 : /// Get the timestamp of when the index was last updated 51 : time_t timestamp() const { return m_timestamp; } 52 : 53 : /// Get the number of packages in the index 54 63445 : size_t size() const { return m_buf ? *(int*)m_buf / sizeof(int) : 0; } 55 : 56 : /** 57 : * Get the ID of a package given its name. 58 : * 59 : * If not found, returns -1. 60 : */ 61 : int byName(const std::string& name) const; 62 : 63 : /** 64 : * Get a package name given its ID. 65 : * 66 : * If not found, returns the empty string. 67 : */ 68 1128365 : std::string byID(int id) const 69 : { 70 1128365 : if (id >= 0 || static_cast<unsigned>(id) < size()) 71 1128365 : return std::string(m_buf + ((int*)m_buf)[id]); 72 0 : return std::string(); 73 : } 74 : 75 : /// Get the number of packages in the index 76 : int size(int id) const 77 : { 78 : if (id < 0 || (unsigned)id >= size()) 79 : return 0; 80 : if ((unsigned)id == size() - 1) 81 : return m_size - ((int*)m_buf)[id] - 1; 82 : else 83 : return ((int*)m_buf)[id + 1] - ((int*)m_buf)[id] - 1; 84 : } 85 : }; 86 : 87 : } 88 : } 89 : 90 : // vim:set ts=4 sw=4: 91 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_DEBTAGS_SOURCEDIR_TCC 2 : #define EPT_DEBTAGS_SOURCEDIR_TCC 3 : 4 : /** @file 5 : * @author Enrico Zini <enrico@enricozini.org> 6 : * Debtags data source directory access 7 : */ 8 : #include <ept/debtags/maint/sourcedir.h> 9 : 10 : #include <tagcoll/input/zlib.h> 11 : #include <tagcoll/input/stdio.h> 12 : 13 : namespace ept { 14 : namespace debtags { 15 : 16 : template<typename OUT> 17 : void SourceDir::readTags(OUT out) 18 : { 19 4 : if (!valid()) return; 20 : 21 28 : for (const_iterator d = begin(); d != end(); ++d) 22 : { 23 24 : FileType type = fileType(d->d_name); 24 24 : if (type == TAG) 25 : { 26 : // Read uncompressed data 27 2 : tagcoll::input::Stdio in(path() + "/" + d->d_name); 28 : 29 : // Read the collection 30 2 : tagcoll::textformat::parse(in, out); 31 : } 32 22 : else if (type == TAGGZ) 33 : { 34 : // Read compressed data 35 0 : tagcoll::input::Zlib in(path() + "/" + d->d_name); 36 : 37 : // Read the collection 38 4 : tagcoll::textformat::parse(in, out); 39 : } 40 : } 41 : } 42 : 43 : } 44 : } 45 : 46 : #include <tagcoll/TextFormat.tcc> 47 : 48 : #endif 49 : 50 : // -*- C++ -*- 51 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_DEBTAGS_DEBTAGSINDEXER_H 2 : #define EPT_DEBTAGS_DEBTAGSINDEXER_H 3 : 4 : #include <ept/debtags/maint/sourcedir.h> 5 : #include <string> 6 : 7 : namespace ept { 8 : namespace debtags { 9 : 10 : class Vocabulary; 11 : 12 : struct DebtagsIndexer 13 10 : { 14 : Vocabulary& voc; 15 : 16 : SourceDir mainSource; 17 : SourceDir userSource; 18 : time_t ts_main_src; 19 : time_t ts_user_src; 20 : time_t ts_main_tag; 21 : time_t ts_main_idx; 22 : time_t ts_user_tag; 23 : time_t ts_user_idx; 24 : 25 34 : time_t sourceTimestamp() const 26 : { 27 34 : time_t res = ts_main_src; 28 34 : if (ts_user_src > res) res = ts_user_src; 29 34 : return res; 30 : } 31 : bool needsRebuild() const; 32 : bool rebuild(const std::string& tagfname, const std::string& idxfname); 33 : bool rebuildIfNeeded(); 34 : bool getUpToDateTagdb(std::string& tagfname, std::string& idxfname); 35 : 36 : bool userIndexIsRedundant() const; 37 : bool deleteRedundantUserIndex(); 38 : 39 : void rescan(); 40 : 41 : DebtagsIndexer(Vocabulary& voc); 42 : 43 : static bool obtainWorkingDebtags(Vocabulary& voc, std::string& tagfname, std::string& idxfname); 44 : }; 45 : 46 : 47 : } 48 : } 49 : 50 : // vim:set ts=4 sw=4: 51 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* -*- C++ -*- 2 : * Copyright (C) 2005,2006 Enrico Zini <enrico@debian.org> 3 : * 4 : * This program is free software; you can redistribute it and/or modify 5 : * it under the terms of the GNU General Public License as published by 6 : * the Free Software Foundation; either version 2 of the License, or 7 : * (at your option) any later version. 8 : * 9 : * This program is distributed in the hope that it will be useful, 10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 : * GNU General Public License for more details. 13 : * 14 : * You should have received a copy of the GNU General Public License 15 : * along with this program; if not, write to the Free Software 16 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : */ 18 : 19 : #include <ept/debtags/tag.h> 20 : #include <ept/debtags/vocabulary.h> 21 : #include <stdexcept> 22 : 23 : namespace ept { 24 : namespace debtags { 25 : 26 : static inline std::string constget(const std::map<std::string, std::string>& m, 27 3898 : const std::string& key) 28 : { 29 3898 : std::map<std::string, std::string>::const_iterator i = m.find(key); 30 3898 : if (i == m.end()) 31 4 : return std::string(); 32 : else 33 3894 : return i->second; 34 : } 35 : 36 59 : std::string Facet::name() const 37 : { 38 59 : if (valid()) 39 59 : return m_tags->facetName(m_id); 40 0 : throw std::out_of_range( "No name for this facet" ); 41 : } 42 29 : std::string Facet::name(const std::string& d) const 43 : { 44 29 : return valid() ? m_tags->facetName(m_id) : d; 45 : } 46 : 47 59 : std::string Facet::shortDescription() const 48 : { 49 59 : if (valid()) 50 59 : return constget(m_tags->facetData(m_id), "_SD_"); 51 0 : throw std::out_of_range( "No short description for this facet" ); 52 : } 53 29 : std::string Facet::shortDescription(const std::string& d) const 54 : { 55 29 : return valid() ? constget(m_tags->facetData(m_id), "_SD_") : d; 56 : } 57 : 58 59 : std::string Facet::longDescription() const 59 : { 60 59 : if (valid()) 61 59 : return constget(m_tags->facetData(m_id), "Description"); 62 0 : throw std::out_of_range( "No long description for this facet" ); 63 : } 64 29 : std::string Facet::longDescription(const std::string& d) const 65 : { 66 29 : return valid() ? constget(m_tags->facetData(m_id), "Description") : d; 67 : } 68 : 69 0 : bool Facet::hasTag(const std::string& name) const 70 : { 71 0 : if (!valid()) 72 0 : throw std::out_of_range( "hasTag() called on an invalid facet" ); 73 0 : return m_tags->hasTag(this->name() + "::" + name); 74 : } 75 : 76 89 : std::set< Tag > Facet::tags() const 77 : { 78 89 : if (!valid()) 79 1 : throw std::out_of_range( "tags() called on an invalid facet" ); 80 88 : return m_tags->tags(m_id); 81 : } 82 : 83 : 84 0 : Facet Tag::facet() const 85 : { 86 0 : if (valid()) 87 0 : return m_tags->facetByTag(m_id); 88 0 : throw std::out_of_range( "No facet for this tag" ); 89 : } 90 : 91 1243 : std::string Tag::name() const 92 : { 93 1243 : if (valid()) 94 1243 : return m_tags->tagShortName(m_id); 95 0 : throw std::out_of_range( "No name for this tag" ); 96 : } 97 620 : std::string Tag::name(const std::string& d) const 98 : { 99 620 : return valid() ? m_tags->tagShortName(m_id) : d; 100 : } 101 : 102 1284 : std::string Tag::fullname() const 103 : { 104 1284 : if (valid()) 105 1284 : return m_tags->tagName(m_id); 106 0 : throw std::out_of_range( "No full name for this tag" ); 107 : } 108 620 : std::string Tag::fullname(const std::string& d) const 109 : { 110 620 : return valid() ? m_tags->tagName(m_id) : d; 111 : } 112 : 113 1242 : std::string Tag::shortDescription() const 114 : { 115 1242 : if (valid()) 116 1242 : return constget(m_tags->tagData(m_id), "_SD_"); 117 0 : throw std::out_of_range( "No short description for this tag" ); 118 : } 119 620 : std::string Tag::shortDescription(const std::string& d) const 120 : { 121 620 : return valid() ? constget(m_tags->tagData(m_id), "_SD_") : d; 122 : } 123 : 124 1240 : std::string Tag::longDescription() const 125 : { 126 1240 : if (valid()) 127 1240 : return constget(m_tags->tagData(m_id), "Description"); 128 0 : throw std::out_of_range( "No long description for this tag" ); 129 : } 130 620 : std::string Tag::longDescription(const std::string& d) const 131 : { 132 620 : return valid() ? constget(m_tags->tagData(m_id), "Description") : d; 133 : } 134 : 135 : } 136 : } 137 : 138 : // vim:set ts=3 sw=3: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
progresscallback.cpp |
|
0.0 % | 0 / 4 lines | |
progresscallback.h |
|
0.0 % | 0 / 3 lines | |
test.h |
|
100.0 % | 15 / 15 lines | |
token.h |
|
81.2 % | 13 / 16 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : #include <wibble/mixin.h> 3 : #include <string> 4 : 5 : #ifndef EPT_TOKEN_H 6 : #define EPT_TOKEN_H 7 : 8 : namespace ept { 9 : 10 9994 : struct Token : wibble::mixin::Comparable< Token > { 11 : std::string _id; // formatted as package[_version] 12 0 : std::string id() const { return _id; } 13 : 14 9755 : Token() : _id( "" ) {} 15 8 : Token( std::string s ) : _id( s ) {} 16 : 17 1831 : std::string version() const { 18 : return _id.find( '_' ) == std::string::npos ? "" : 19 1831 : std::string( _id, _id.find( '_' ) + 1, _id.size() ); 20 : } 21 : 22 7883 : std::string package() const { 23 : return std::string( _id, 0, 24 : _id.find( '_' ) == std::string::npos ? 25 7883 : _id.size() : _id.find( '_' ) ); 26 : } 27 : 28 : bool isDesktop() const { 29 : return std::string( _id, 0, 8 ) == "desktop:"; 30 : } 31 : 32 : std::string desktop() const { 33 : return isDesktop() ? std::string( _id, 8, _id.size() ) : ""; 34 : } 35 : 36 17 : bool hasVersion() const { 37 17 : return version() != ""; 38 : } 39 : 40 1 : bool valid() const { 41 1 : return _id != ""; 42 : } 43 : 44 58 : bool operator<=( const Token &o ) const { 45 58 : return _id <= o._id; 46 : } 47 : }; 48 : 49 : } 50 : 51 0 : inline std::ostream &operator<<( std::ostream &o, const ept::Token &t ) { 52 0 : return o << t.id(); 53 : } 54 : 55 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : #include <ept/config.h> 3 : #include <ept/core/desktop.h> 4 : #include <ept/core/list.h> 5 : #include <ept/test.h> 6 : 7 : using namespace ept::core; 8 : 9 5 : struct TestDesktop { 10 : desktop::Source desk; 11 : ept::Token t; 12 : 13 5 : TestDesktop() : desk( TEST_ENV_DIR "desktop" ) {} 14 : 15 : template< desktop::PropertyId P, typename L > 16 3 : void checkIteration2( int c, const char **check, L l ) { 17 3 : int i = 0; 18 16 : while ( !l.empty() ) { 19 10 : assert_eq( l.head().template get< P >(), check[ i ] ); 20 20 : l = l.tail(); 21 10 : ++ i; 22 : } 23 3 : assert_eq( i, c ); 24 3 : } 25 : 26 : template< desktop::PropertyId P, typename L > 27 3 : void checkIteration( int c, const char **check, L l ) { 28 3 : checkIteration2< P >( c, check, list::sort( l ) ); 29 3 : } 30 : 31 1 : Test iteration() { 32 1 : const char *check[] = { "Kdict", "foo", "XQF", "X-Server" }; 33 : checkIteration< desktop::Name >( 34 1 : 4, check, desk.list< desktop::Name >() ); 35 1 : } 36 : 37 1 : Test groupProperty() { 38 : const char *check[] = { 39 : "{ KDE, Qt, Utility }", 40 : "{ KDE, Qt, Utility }", 41 : "{ Application, Game, X-SuSE-Core-Game }", 42 : "{ KDE, Qt, X-KDE-information }", 43 1 : }; 44 : checkIteration< desktop::Group >( 45 1 : 4, check, desk.list< desktop::Name >() ); 46 1 : } 47 : 48 1 : Test groups() { 49 1 : const char *check[] = { "Kdict", "foo" }; 50 : checkIteration< desktop::Name >( 51 1 : 2, check, desk.group( "{ KDE, Qt, Utility }" ) ); 52 1 : } 53 : 54 1 : Test groupList() { 55 : std::string check[] = { 56 : "{ Application, Game, X-SuSE-Core-Game }", 57 : "{ KDE, Qt, Utility }", 58 : "{ KDE, Qt, X-KDE-information }", 59 1 : }; 60 : 61 2 : assert_list_eq( desk.groupList(), check ); 62 1 : } 63 : 64 1 : Test emptyGroupList() { 65 1 : desktop::InternalList l; 66 1 : assert( l.empty() ); 67 1 : } 68 : }; |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : #include <ept/test.h> 3 : #include <ept/core/list.h> 4 : #include <ept/core/xapian.h> 5 : 6 : // TODO temporary, for building test database 7 : #include <ept/apt/apt.h> 8 : #include <ept/textsearch/textsearch.h> 9 : #include <ept/textsearch/maint/path.h> 10 : 11 : using namespace ept; 12 : using namespace core; 13 : 14 : namespace ept { 15 : namespace textsearch { 16 : extern size_t max_index; 17 : } 18 : } 19 : 20 4 : struct XapianTestEnvironment : AptTestEnvironment { 21 : textsearch::Path::OverrideIndexDir oid; 22 : textsearch::TextSearch textsearch; 23 : apt::Apt apt; 24 4 : XapianTestEnvironment() 25 4 : : oid( TEST_ENV_DIR "xapian" ) 26 : { 27 4 : ept::textsearch::max_index = 1000; 28 4 : textsearch.rebuildIfNeeded(apt); 29 4 : } 30 : }; 31 : 32 4 : struct TestXapian : XapianTestEnvironment { 33 : xapian::Source xap; 34 : xapian::Query query; 35 : 36 4 : TestXapian() : query( xap.db() ) 37 : { 38 4 : query = xap.query( "sgml tool" ); 39 4 : } 40 : 41 1 : Test enquire() { 42 1 : query.updateEnquire(); 43 1 : Xapian::MSet matches = query.m_enq.get_mset(0, 100); 44 1 : assert( matches.size() > 0 ); 45 2 : assert_eq( matches.begin().get_document().get_data(), "psgml" ); 46 1 : } 47 : 48 1 : Test listCount() { 49 1 : xapian::List l( query.results() ); 50 1 : Xapian::MSet matches = query.m_enq.get_mset(0, 6000); 51 1 : assert_eq( list::count( l ), matches.size() ); 52 1 : } 53 : 54 : template< typename List > 55 1 : void checkXapianList( List l, Xapian::MSet m ) { 56 1 : Xapian::MSet::const_iterator i = m.begin(); 57 16 : while (! l.empty() ) { 58 14 : assert_eq( l.token().package(), i.get_document().get_data() ); 59 14 : l = l.tail(); 60 15 : ++ i; 61 : } 62 1 : } 63 : 64 1 : Test list() { 65 1 : xapian::List l( query.results() ); 66 1 : Xapian::MSet matches = query.m_enq.get_mset(0, 6000); 67 1 : checkXapianList( l, matches ); 68 1 : } 69 : 70 1 : Test checkQuery() { 71 1 : assert_eq( xap.query( "sgml tool" ).results().token().package(), "psgml" ); 72 1 : } 73 : 74 : }; |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /// -*- C++ -*- (c) 2006, 2007 Petr Rockai <me@mornfall.net> 2 : 3 : #include <iostream> 4 : #include <string> 5 : #include <map> 6 : 7 : #ifndef EPT_CORE_DESKTOPFILE_H 8 : #define EPT_CORE_DESKTOPFILE_H 9 : 10 : namespace ept { 11 : namespace core { 12 : namespace desktop { 13 : 14 32 : struct File { 15 13540 : struct Entry { 16 : std::string key; 17 : std::string value; 18 : }; 19 : typedef std::map< std::string, Entry > EntryMap; 20 : 21 144 : struct Group { 22 : std::string name; 23 : EntryMap entries; 24 88 : Entry &entry( std::string k ) { return entries[ k ]; } 25 : }; 26 : 27 : typedef std::map< std::string, Group > GroupMap; 28 : GroupMap groups; 29 16 : Group &group( std::string k ) { return groups[ k ]; } 30 : }; 31 : 32 1228 : inline std::istream &operator >>( std::istream &i, File::Entry &e ) 33 : { 34 1228 : std::string spaces = ""; char c; bool started = false; 35 : 36 1228 : e.key = ""; 37 : // read key 38 16056 : while ( i.peek() != EOF ) { 39 14820 : c = i.get(); 40 14820 : if ( !started && c == '\n' ) 41 8 : return i >> e; 42 14812 : if ( isspace( c ) ) { 43 0 : spaces += c; 44 0 : continue; 45 : } 46 14812 : if ( !started && c == '#' ) { 47 0 : while ( i.peek() != EOF && i.get() != '\n' ) 48 : ; // read till eol 49 0 : return i >> e; // restart reading 50 : } 51 14812 : started = true; 52 14812 : if ( c == '=' ) 53 1212 : break; 54 13600 : e.key += spaces; 55 13600 : e.key += c; 56 13600 : spaces = ""; 57 : } 58 : // std::cerr << "read key: " << e.key << std::endl; 59 : 60 1220 : started = false; 61 1220 : bool backslash = false; 62 : // read value 63 37496 : while ( i.peek() != EOF ) { 64 36268 : c = i.get(); 65 36268 : if ( c == '\n' ) { 66 1212 : if ( backslash ) 67 0 : e.value += '\\'; 68 1212 : return i; 69 : } 70 35056 : if ( !started && isspace( c ) ) 71 0 : continue; 72 35056 : started = true; 73 35056 : if ( backslash ) { // interpret escape sequences 74 0 : if ( c == '\\' ) e.value += '\\'; 75 0 : else if ( c == 'n' ) e.value += '\n'; 76 0 : else if ( c == 't' ) e.value += '\t'; 77 0 : else if ( c == 'r' ) e.value += '\r'; 78 0 : else if ( c == 's' ) e.value += ' '; 79 0 : else { e.value += '\\'; e.value += c; } 80 0 : backslash = false; 81 0 : continue; 82 : } 83 35056 : if ( c == '\\' ) { 84 0 : backslash = true; 85 0 : continue; 86 : } 87 35056 : e.value += c; 88 : } 89 8 : return i; 90 : } 91 : 92 16 : inline std::istream &operator >>( std::istream &i, File::Group &g ) 93 : { 94 16 : bool started = false; char c; 95 16 : g.name = ""; 96 256 : while ( i.peek() != EOF ) { 97 240 : c = i.get(); 98 240 : if ( !started && isspace( c ) ) 99 0 : continue; 100 240 : if ( !started && c == '#' ) { 101 0 : while( i.peek() != EOF && i.get() != '\n' ) 102 : ; // read till eol 103 0 : return i >> g; // restart reading 104 : } 105 240 : if ( !started && c == '[' ) { 106 16 : started = true; 107 16 : continue; 108 : } 109 224 : if ( started && c == ']' ) { 110 16 : while( i.peek() != EOF && i.get() != '\n' ) 111 : ; // read till eol 112 16 : break; 113 : } 114 208 : g.name += c; 115 : } 116 1236 : while ( i.peek() != EOF ) { 117 1220 : File::Entry e; 118 1220 : i >> e; 119 1220 : g.entries[ e.key ] = e; 120 : } 121 16 : return i; 122 : } 123 : 124 16 : inline std::istream &operator >>( std::istream &i, File &f ) 125 : { 126 32 : while ( i.peek() != EOF ) { 127 16 : File::Group g; 128 16 : i >> g; 129 16 : f.groups[ g.name ] = g; 130 : } 131 16 : return i; 132 : } 133 : 134 : } 135 : } 136 : } 137 : 138 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : #include <xapian.h> 3 : #include <ept/core/apt.h> 4 : #include <wibble/regexp.h> 5 : #include <wibble/sys/pipe.h> 6 : #include <wibble/sys/exec.h> 7 : 8 : #ifndef EPT_XAPIAN_H 9 : #define EPT_XAPIAN_H 10 : 11 : namespace ept { 12 : namespace core { 13 : namespace xapian { 14 : 15 : // Allocate value indexes for known values 16 : const Xapian::valueno VAL_APT_INSTALLED_SIZE = 1; 17 : const Xapian::valueno VAL_APT_PACKAGE_SIZE = 2; 18 : const Xapian::valueno VAL_POPCON = 10; 19 : const Xapian::valueno VAL_ITERATING_RATING = 20; 20 : const Xapian::valueno VAL_ITERATING_FUNCTIONALITY = 21; 21 : const Xapian::valueno VAL_ITERATING_USABILITY = 22; 22 : const Xapian::valueno VAL_ITERATING_SECURITY = 23; 23 : const Xapian::valueno VAL_ITERATING_PERFORMANCE = 24; 24 : const Xapian::valueno VAL_ITERATING_QUALITY = 25; 25 : const Xapian::valueno VAL_ITERATING_SUPPORT = 26; 26 : const Xapian::valueno VAL_ITERATING_ADOPTION = 27; 27 : 28 : struct TagFilter : public Xapian::ExpandDecider 29 8 : { 30 1760 : virtual bool operator()(const std::string &term) const { 31 1760 : return term[0] == 'X' && term[1] == 'T'; 32 : } 33 : }; 34 : 35 91 : struct List { 36 : char m_enqPlace[sizeof(Xapian::Enquire)]; 37 : mutable Xapian::MSet m_matches; 38 : mutable Xapian::MSet::const_iterator m_iter; 39 : mutable int m_pos; 40 : typedef List Type; 41 : 42 : static const size_t chunkSize = 20; 43 : 44 : List head() const { 45 : seek(); 46 : return *this; 47 : } 48 : 49 15 : Token token() const { 50 15 : Token t; 51 15 : t._id = m_iter.get_document().get_data(); 52 0 : return t; 53 : } 54 : 55 : bool operator<( const List &o ) const { 56 : return token() < o.token(); 57 : } 58 : 59 58 : void seek() const { 60 58 : if ( m_matches.size() == chunkSize && m_iter == m_matches.end() ) { 61 0 : m_matches = enq().get_mset( m_pos, chunkSize ); 62 0 : m_iter = m_matches.begin(); 63 0 : m_pos += chunkSize; 64 : } 65 58 : } 66 : 67 30 : bool empty() const { 68 30 : if ( m_pos == -1 ) 69 0 : return true; 70 30 : seek(); 71 30 : return m_matches.size() < 30 && m_iter == m_matches.end(); 72 : } 73 : 74 28 : List tail() const { 75 28 : List t = *this; 76 28 : t.seek(); 77 28 : t.m_iter ++; 78 0 : return t; 79 : } 80 : 81 6 : Xapian::Enquire const &enq() const { 82 6 : return *reinterpret_cast< Xapian::Enquire const * >( m_enqPlace ); 83 : } 84 : 85 3 : List( Xapian::Enquire _enq ) 86 3 : { 87 3 : Xapian::Enquire *e = new (m_enqPlace) Xapian::Enquire( _enq ); 88 3 : assert_eq( e, &enq() ); 89 6 : m_matches = enq().get_mset( 0, chunkSize ); 90 3 : m_iter = m_matches.begin(); 91 3 : m_pos = chunkSize; 92 3 : } 93 : 94 : List() {} 95 : }; 96 : 97 13 : struct Query { 98 : Xapian::Database *m_db; 99 : Xapian::Enquire m_enq; 100 : Xapian::Stem m_stem; 101 : typedef std::set< std::string > Terms; 102 : Terms m_include, m_exclude; 103 : int m_cutoff; 104 : bool m_expand; 105 : 106 5 : void setQualityCutoff( int c ) { 107 5 : m_cutoff = c; 108 5 : } 109 : 110 5 : void setExpand( bool e ) { m_expand = e; } 111 : 112 9 : Query( Xapian::Database &e ) : m_db( &e ), m_enq( e ) { 113 9 : m_cutoff = 50; 114 9 : m_expand = true; 115 9 : } 116 : 117 5 : wibble::Tokenizer queryTokenizer( std::string q ) const { 118 5 : return wibble::Tokenizer( q, "[A-Za-z0-9_+:-]+", REG_EXTENDED ); 119 : } 120 : 121 : template< typename Out > 122 5 : void tokenizeQuery( std::string q, Out o ) const 123 : { 124 5 : wibble::Tokenizer tok = queryTokenizer( q ); 125 15 : for (wibble::Tokenizer::const_iterator i = tok.begin(); i != tok.end(); ++i ) 126 : { 127 10 : if ( (*i).find( "::" ) != std::string::npos ) { // assume tag 128 0 : *o++ = ("XT" + *i); 129 : } else { 130 10 : std::string t = wibble::str::tolower(*i); 131 10 : std::string s = m_stem(t); 132 10 : *o++ = t; 133 10 : if (s != t) 134 5 : *o++ = ("Z" + s); 135 : } 136 : } 137 5 : } 138 : 139 : template< typename Out > 140 4 : void expand( Out o ) const 141 : { 142 4 : Xapian::RSet rset; 143 : // Get the top 5 results as 'good ones' to compute the search expansion 144 4 : Xapian::MSet mset = m_enq.get_mset(0, 5); 145 24 : for ( Xapian::MSet::iterator i = mset.begin(); i != mset.end(); ++i ) 146 24 : rset.add_document(i); 147 : // Get the expanded set, only expanding the query with tag names 148 4 : TagFilter tagf; 149 4 : Xapian::ESet eset = m_enq.get_eset(5, rset, &tagf); 150 4 : for ( Xapian::ESetIterator i = eset.begin(); i != eset.end(); ++i ) 151 4 : *o++ = *i; 152 4 : } 153 : 154 8 : void updateEnquire() { 155 : // set up query now 156 : Xapian::Query inc( Xapian::Query::OP_OR, 157 : m_include.begin(), 158 8 : m_include.end() ), 159 : exc( Xapian::Query::OP_OR, 160 : m_exclude.begin(), 161 8 : m_exclude.end() ), 162 8 : query( Xapian::Query::OP_AND_NOT, inc, exc ); 163 : 164 8 : m_enq.set_query( query ); 165 : 166 8 : if ( m_expand ) { 167 4 : m_expand = false; 168 4 : expand( std::inserter( m_include, m_include.begin() ) ); 169 4 : updateEnquire(); 170 4 : m_expand = true; 171 4 : return; 172 : } 173 : 174 4 : Xapian::MSet first = m_enq.get_mset(0, 1, 0, 0, 0); 175 4 : Xapian::MSetIterator ifirst = first.begin(); 176 4 : if ( ifirst != first.end() ) { 177 4 : Xapian::percent cutoff = ifirst.get_percent() * m_cutoff / 100; 178 4 : m_enq.set_cutoff(cutoff); 179 4 : } 180 : } 181 : 182 3 : List results() { 183 3 : updateEnquire(); 184 3 : return List( m_enq ); 185 : } 186 : 187 : std::map< std::string, int > relevantTags( int n = 30 ) { 188 : updateEnquire(); 189 : std::map< std::string, int > relev; 190 : Xapian::RSet rset; 191 : Xapian::MSet mset = m_enq.get_mset(0, 100); 192 : for ( Xapian::MSet::iterator i = mset.begin(); i != mset.end(); ++i ) 193 : rset.add_document(i); 194 : // Get the expanded set, only expanding the query with tag names 195 : TagFilter tagf; 196 : Xapian::ESet eset = m_enq.get_eset(n, rset, &tagf); 197 : for ( Xapian::ESetIterator i = eset.begin(); i != eset.end(); ++i ) 198 : relev.insert( relev.begin(), 199 : std::make_pair( 200 : std::string( *i, 2, std::string::npos ), 201 : i.get_weight() ) ); 202 : return relev; 203 : } 204 : 205 5 : void addTerms( std::string t, bool partial = false, bool exclude = false ) { 206 5 : Terms &to = exclude ? m_exclude : m_include; 207 5 : std::vector< std::string > tok; 208 5 : tokenizeQuery( t, std::back_inserter( tok ) ); 209 5 : if ( partial ) { 210 0 : if ( tok.back().size() == 1 ) { 211 0 : tok.pop_back(); 212 : } else { 213 : std::copy( 214 : m_db->allterms_begin( tok.back() ), 215 : m_db->allterms_end( tok.back() ), 216 0 : std::back_inserter( tok ) ); 217 : } 218 : } 219 5 : std::copy( tok.begin(), tok.end(), std::inserter( to, to.begin() ) ); 220 5 : } 221 : 222 : void addTerms( const Terms &t, bool exclude = false ) { 223 : Terms &to = exclude ? m_exclude : m_include; 224 : std::copy( t.begin(), t.end(), std::inserter( to, to.begin() ) ); 225 : } 226 : 227 : }; 228 : 229 : struct Source 230 4 : { 231 : protected: 232 : mutable Xapian::Database m_db; 233 : Xapian::Stem m_stem; 234 : mutable bool m_opened; 235 : 236 : /// Return a lowercased copy of the string 237 : static std::string toLower(const std::string& str); 238 : 239 : /** 240 : * Add normalised tokens computed from the string to the document doc. 241 : * 242 : * pos is used as a sequence generator for entering the token position in 243 : * the document. 244 : */ 245 : void normalize_and_add(Xapian::Document& doc, const std::string& term, 246 : int& pos) const; 247 : 248 : public: 249 : Source(); 250 : 251 : /// Access the Xapian database 252 9 : Xapian::Database& db() { 253 9 : open(); 254 9 : return m_db; 255 : } 256 : 257 : /// Access the Xapian database 258 0 : const Xapian::Database& db() const { 259 0 : open(); 260 0 : return m_db; 261 : } 262 : 263 : void open() const; 264 : void invalidate() { 265 : m_db = Xapian::Database(); 266 : m_opened = false; 267 : } 268 : 269 : /// Timestamp of when the Xapian database was last updated 270 : time_t timestamp() const; 271 : 272 : void updateLeniently( AptDatabase &apt, OpProgress *op = 0 ) { 273 : if (apt.timestamp() - timestamp() > 86400 * 8) // a little over a week 274 : update( op ); 275 : } 276 : 277 : void update( OpProgress *op = 0 ) { 278 : if ( !op ) 279 : op = new OpProgress(); 280 : 281 : wibble::exception::AddContext _ctx( "Rebuilding Xapian database." ); 282 : int outfd; 283 : std::string op_str; 284 : 285 : wibble::sys::Exec ex( "update-apt-xapian-index" ); 286 : ex.args.push_back( "--batch-mode" ); 287 : ex.searchInPath = true; 288 : ex.forkAndRedirect( 0, &outfd, 0 ); 289 : 290 : wibble::sys::Pipe monit( outfd ); 291 : while ( !monit.eof() ) { 292 : std::string line = monit.nextLine(); 293 : if ( line.empty() ) { 294 : usleep( 100000 ); 295 : continue; 296 : } 297 : std::cerr << "got : " << line << std::endl; 298 : if ( wibble::str::startsWith( line, "begin: " ) ) { 299 : op_str = std::string( line, 7, std::string::npos ); 300 : op->OverallProgress( 0, 100, 100, op_str ); 301 : 302 : } else if ( wibble::str::startsWith( line, "done: " ) ) { 303 : op->Done(); 304 : } else if ( wibble::str::startsWith( line, "progress: " ) ) { 305 : wibble::ERegexp re( "progress: ([0-9]+)/([0-9]+)", 3 ); 306 : if ( re.match( line ) ) { 307 : assert_eq( re[2], "100" ); 308 : op->OverallProgress( atoi( re[1].c_str() ), 100, 100, op_str ); 309 : } 310 : } 311 : } 312 : ex.waitForSuccess(); 313 : invalidate(); 314 : } 315 : 316 : /// Returns true if the index has data 317 : bool hasData() const { return timestamp() > 0; } 318 : 319 : Query query( const std::string &s, 320 : bool expand = true, 321 5 : int qualityCutoff = 50 ) 322 : { 323 5 : Query q( db() ); 324 5 : q.setQualityCutoff( qualityCutoff ); 325 5 : q.setExpand( expand ); 326 5 : q.addTerms( s ); 327 0 : return q; 328 : } 329 : 330 : Query partialQuery( const std::string &s ) { 331 : Query q( db() ); 332 : q.addTerms( s, true ); // partial 333 : return q; 334 : } 335 : 336 : /// Returns true if the index is older than the Apt database information 337 : // bool needsRebuild(apt::Apt& apt); 338 : 339 : Xapian::docid docidByName(const std::string& pkgname) const; 340 : 341 : /** 342 : * Tokenize the string and build an OR query with the resulting keywords 343 : */ 344 : Xapian::Query makeORQuery(const std::string& keywords) const; 345 : 346 : /** 347 : * Tokenize the string and build an OR query with the resulting keywords. 348 : * 349 : * The last token in keywords is considered to be typed only partially, to 350 : * implement proper search-as-you-type. 351 : */ 352 : Xapian::Query makePartialORQuery(const std::string& keywords) const; 353 : 354 : /** 355 : * Build a query with the given keywords, specified as iterators of strings 356 : */ 357 : template<typename ITER> 358 : Xapian::Query makeORQuery(const ITER& begin, const ITER& end) const 359 : { 360 : return Xapian::Query(Xapian::Query::OP_OR, begin, end); 361 : } 362 : 363 : /// Return a list of tag-based terms that can be used to expand an OR query 364 : std::vector<std::string> expand(Xapian::Enquire& enq) const; 365 : 366 : // std::vector<std::string> similar(const std::string& pkg); 367 : 368 : /** 369 : * Create a query to look for packages similar to the given one 370 : */ 371 : Xapian::Query makeRelatedQuery(const std::string& pkgname) const; 372 : 373 : /** 374 : * Get the integer value for 375 : */ 376 : double getDoubleValue(const std::string& pkgname, 377 : Xapian::valueno val_id) const; 378 : 379 : /** 380 : * Get the integer value for 381 : */ 382 : int getIntValue(const std::string& pkgname, Xapian::valueno val_id) const; 383 : }; 384 : 385 : } 386 : } 387 : } 388 : 389 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
apt.cpp |
|
100.0 % | 7 / 7 lines | |
apt.h |
|
79.8 % | 138 / 173 lines | |
apt.test.h |
|
100.0 % | 60 / 60 lines | |
desktop.h |
|
94.2 % | 97 / 103 lines | |
desktop.test.h |
|
100.0 % | 33 / 33 lines | |
desktopfile.h |
|
75.3 % | 58 / 77 lines | |
source.h |
|
100.0 % | 34 / 34 lines | |
xapian.cpp |
|
21.4 % | 12 / 56 lines | |
xapian.h |
|
87.2 % | 95 / 109 lines | |
xapian.test.h |
|
100.0 % | 36 / 36 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- (c) 2007 Enrico Zini <enrico@enricozini.org> 2 : // Petr Rockai <me@mornfall.net> 3 : 4 : /* 5 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org> 6 : * 7 : * This program is free software; you can redistribute it and/or modify 8 : * it under the terms of the GNU General Public License as published by 9 : * the Free Software Foundation; either version 2 of the License, or 10 : * (at your option) any later version. 11 : * 12 : * This program is distributed in the hope that it will be useful, 13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : * GNU General Public License for more details. 16 : * 17 : * You should have received a copy of the GNU General Public License 18 : * along with this program; if not, write to the Free Software 19 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 : */ 21 : 22 : #include <ept/core/xapian.h> 23 : #include <ept/core/apt.h> 24 : #include <ept/core/apt/record.h> 25 : 26 : #include <ept/textsearch/maint/path.h> 27 : 28 : #include <wibble/regexp.h> 29 : #include <cctype> 30 : #include <cmath> 31 : 32 : #include <xapian/queryparser.h> 33 : #include <xapian/base.h> 34 : 35 : #include <algorithm> 36 : 37 : #include <iostream> 38 : 39 : using namespace std; 40 : using namespace ept; 41 : // using namespace ept::debtags; 42 : 43 : namespace ept { 44 : namespace core { 45 : namespace xapian { 46 : 47 : size_t max_index = 0; 48 : 49 4 : Source::Source() 50 4 : : m_stem("en"), m_opened( false ) 51 : { 52 4 : } 53 : 54 9 : time_t Source::timestamp() const { 55 9 : return textsearch::Path::indexTimestamp(); 56 : } 57 : 58 9 : void Source::open() const { 59 9 : if (timestamp()) { 60 9 : std::string path = textsearch::Path::index(); 61 9 : m_db = Xapian::Database( path ); 62 9 : m_opened = true; 63 : } 64 9 : } 65 : 66 0 : std::string Source::toLower(const std::string& str) 67 : { 68 0 : std::string res; 69 0 : res.reserve(str.size()); 70 0 : for (std::string::const_iterator i = str.begin(); i != str.end(); ++i) 71 0 : res += tolower(*i); 72 0 : return res; 73 : } 74 : 75 : void Source::normalize_and_add(Xapian::Document& doc, const std::string& term, 76 0 : int& /* pos */) const 77 : { 78 0 : string t = Source::toLower(term); 79 0 : string s = m_stem(t); 80 0 : doc.add_term(t); 81 0 : if (s != t) 82 0 : doc.add_term(s); 83 0 : } 84 : 85 0 : Xapian::docid Source::docidByName(const std::string& pkgname) const 86 : { 87 0 : Xapian::PostingIterator i = m_db.postlist_begin("pkg:"+pkgname); 88 0 : if (i == m_db.postlist_end("pkg:"+pkgname)) 89 0 : return 0; 90 : else 91 0 : return *i; 92 : } 93 : 94 0 : Xapian::Query Source::makeRelatedQuery(const std::string& pkgname) const 95 : { 96 0 : Xapian::Enquire enquire(db()); 97 : 98 : // Retrieve the document for the given package 99 0 : enquire.set_query(Xapian::Query("pkg:"+pkgname)); 100 0 : Xapian::MSet matches = enquire.get_mset(0, 1); 101 0 : Xapian::MSetIterator mi = matches.begin(); 102 0 : if (mi == matches.end()) return Xapian::Query(); 103 0 : Xapian::Document doc = mi.get_document(); 104 : 105 : // Return the query to get the list of similar documents 106 0 : return Xapian::Query(Xapian::Query::OP_OR, doc.termlist_begin(), doc.termlist_end()); 107 : } 108 : 109 : double Source::getDoubleValue(const std::string& pkgname, 110 0 : Xapian::valueno val_id) const 111 : { 112 0 : Xapian::docid id = docidByName(pkgname); 113 0 : if (id == 0) 114 0 : return 0.0; 115 0 : Xapian::Document doc = db().get_document(id); 116 0 : string val = doc.get_value(val_id); 117 0 : if (val.empty()) 118 0 : return 0.0; 119 : else 120 0 : return Xapian::sortable_unserialise(val); 121 : } 122 : 123 : int Source::getIntValue(const std::string& pkgname, 124 0 : Xapian::valueno val_id) const 125 : { 126 0 : Xapian::docid id = docidByName(pkgname); 127 0 : if (id == 0) 128 0 : return 0; 129 0 : Xapian::Document doc = db().get_document(id); 130 0 : string val = doc.get_value(val_id); 131 0 : if (val.empty()) 132 0 : return 0; 133 : else 134 0 : return (int)nearbyint(Xapian::sortable_unserialise(val)); 135 : } 136 : 137 : } 138 : } 139 3 : } 140 : 141 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : #include <ept/core/apt.h> 3 : #include <wibble/sys/fs.h> 4 : 5 : namespace wfs = wibble::sys::fs; 6 : 7 : namespace ept { 8 : namespace core { 9 45 : time_t aptTimestamp() 10 : { 11 : std::auto_ptr<struct stat> st = wfs::stat( 12 45 : _config->FindFile( "Dir::Cache::pkgcache" ) ); 13 45 : time_t t1 = st.get() == NULL ? 0 : st->st_mtime; 14 : 15 : std::auto_ptr<struct stat> st1 = wfs::stat( 16 45 : _config->FindFile( "Dir::State::status" ) ); 17 45 : time_t t2 = st1.get() == NULL ? 0 : st1->st_mtime; 18 : 19 45 : return t1 > t2 ? t1 : t2; 20 : } 21 : 22 : } 23 6 : } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : 3 : #include <ept/core/list.h> 4 : 5 : #ifndef EPT_CORE_SOURCE_H 6 : #define EPT_CORE_SOURCE_H 7 : 8 : namespace ept { 9 : namespace core { 10 : 11 : template< typename Self, typename Setup, 12 : template< typename Setup::PropertyId > class PType > 13 38 : struct Source { 14 : typedef typename Setup::PropertyId PropertyId; 15 : typedef typename Setup::Token Token; 16 : 17 : Token m_cachedToken; 18 : typename Setup::Internal m_cached; 19 : 20 43 : Self &self() { return *static_cast< Self * >( this ); } 21 : 22 : template< PropertyId property > 23 13 : typename PType< property >::T get( Token t ) { 24 13 : if ( m_cachedToken != t ) { 25 10 : m_cachedToken = t; 26 10 : m_cached = self().lookupToken( t ); 27 : } 28 13 : return self().template getInternal< property >( m_cached ); 29 : } 30 : 31 : void invalidate() { 32 : m_cachedToken = ept::Token(); 33 : m_cached = typename Setup::Internal(); 34 : } 35 : 36 : template< PropertyId _property > 37 : struct ComposedList : wibble::mixin::Comparable< ComposedList< _property > > 38 4009 : { 39 : typedef Self Origin; 40 : typedef typename Setup::Token Token; 41 : typedef typename PType< _property >::T Property; 42 : typedef ComposedList Type; 43 : 44 : Origin *origin; 45 : typename Setup::InternalList internal; 46 : 47 12056 : ComposedList tail() const { 48 12056 : return ComposedList< _property >( *origin, internal.tail() ); 49 : } 50 : 51 12078 : bool empty() const { return internal.empty(); } 52 : 53 13 : bool operator<( const ComposedList &o ) const { 54 13 : return token() < o.token(); 55 : } 56 : 57 18 : ComposedList &head() { return *this; } 58 4 : const ComposedList &head() const { return *this; } 59 : 60 6054 : Token token() const { return origin->getToken( internal.head() ); } 61 : 62 7836 : Property property() const { 63 : return origin->template getInternal< _property >( 64 7836 : internal.head() ); 65 : } 66 : 67 : template< PropertyId P > 68 : typename PType< P >::T 69 14 : get() const { 70 14 : return origin->template getInternal< P >( internal.head() ); 71 : } 72 : 73 8 : ComposedList() : origin( 0 ) {} 74 : 75 12066 : ComposedList( Origin &o, typename Setup::InternalList i ) 76 12066 : : origin( &o ), internal( i ) {} 77 : }; 78 : 79 : template< PropertyId property > 80 10 : ComposedList< property > list() 81 : { 82 10 : return ComposedList< property >( self(), self().listInternal() ); 83 : } 84 : 85 : template< PropertyId P, typename F > 86 50 : struct Propertify { 87 : F f; 88 2 : Propertify( F _f = F() ) : f( _f ) {} 89 8 : bool operator()( const ComposedList< P > &x ) const { 90 8 : return f( x.token(), x.property() ); 91 : } 92 : }; 93 : 94 : template< PropertyId P, typename F > 95 : struct PropertyFilter { 96 : typedef typename list::Filtered< 97 : ComposedList< P >, Propertify< P, F > > T; 98 : }; 99 : 100 : template< PropertyId P, typename F > 101 : typename PropertyFilter< P, F >::T 102 1 : propertyFilter( F f ) { 103 1 : return list::filter( list< P >(), Propertify< P, F >( f ) ); 104 : } 105 : 106 38 : Source() 107 38 : { 108 38 : } 109 : }; 110 : 111 : } 112 : } 113 : 114 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : 3 : #include <string> 4 : #include <wibble/test.h> 5 : 6 : #include <ept/token.h> 7 : #include <ept/core/source.h> 8 : 9 : #include <iostream> 10 : #include <wibble/exception.h> 11 : 12 : #include <apt-pkg/pkgcache.h> 13 : #include <apt-pkg/sourcelist.h> 14 : #include <apt-pkg/error.h> 15 : #include <apt-pkg/policy.h> 16 : #include <apt-pkg/cachefile.h> 17 : #include <apt-pkg/progress.h> 18 : #include <apt-pkg/pkgcachegen.h> 19 : #include <apt-pkg/init.h> 20 : 21 : #ifndef EPT_APT_H 22 : #define EPT_APT_H 23 : 24 : namespace ept { 25 : namespace core { 26 : 27 0 : struct AptException : wibble::exception::Generic { 28 0 : std::string desc() const throw () { 29 0 : return "APT Error"; 30 : } 31 : 32 0 : AptException( const std::string &ctx ) : Generic( ctx ) { 33 0 : while ( !_error->empty() ) { 34 0 : std::string err; 35 0 : _error->PopMessage( err ); 36 0 : std::cerr << err << std::endl; 37 0 : addContext( err ); 38 : } 39 0 : } 40 : }; 41 : 42 : struct PackageState { 43 : enum Query { 44 : Install = 1 << 0, 45 : Upgrade = 1 << 1, 46 : Keep = 1 << 2, 47 : Remove = 1 << 3, 48 : Installed = 1 << 4, 49 : Upgradable = 1 << 5, 50 : NowBroken = 1 << 6, 51 : WillBreak = 1 << 7, 52 : ReInstall = 1 << 8, 53 : Purge = 1 << 9, 54 : Hold = 1 << 10, 55 : Valid = 1 << 11 56 : }; 57 : 58 : typedef unsigned state; 59 : 60 3786 : operator unsigned() { return m_state; }; 61 : 62 : PackageState &operator=( unsigned i ) { 63 : m_state = i; 64 : return *this; 65 : } 66 : 67 5218 : PackageState &operator|=( const PackageState &s ) { 68 5218 : m_state |= s.m_state; 69 5218 : return *this; 70 : } 71 : 72 9003 : PackageState( unsigned a ) { 73 9003 : m_state = a; 74 9003 : } 75 : 76 1 : PackageState() : m_state( 0 ) {} 77 : 78 : // FIXME this probably needs to be used consistently in core and out of core 79 2 : bool isValid() const { return m_state & Valid; } 80 : // FIXME compatibility API for non-core apt 81 1 : bool isInstalled() const { return installed(); } 82 : 83 2 : bool install() const { return m_state & Install; } 84 : // reinstall() implies install() 85 : bool reinstall() const { return m_state & ReInstall; } 86 : bool remove() const { return m_state & Remove; } 87 : // purge() implies remove() 88 3775 : bool purge() const { return m_state & Purge; } 89 3780 : bool keep() const { return m_state & Keep; } 90 : bool willBreak() const { return m_state & WillBreak; } 91 : // upgrade() implies install() 92 : bool upgrade() const { return hasNewVersion() && install(); } 93 : // newInsstal() implies install() 94 : bool newInstall() const { return !installed() && install(); } 95 : bool hold() const { return m_state & Hold; } 96 : 97 1 : bool installed() const { return m_state & Installed; } 98 : bool hasNewVersion() const { return m_state & Upgradable; } 99 : bool upgradable() const { return hasNewVersion() && !hold(); } 100 : bool held() const { return hasNewVersion() && hold(); } 101 : bool nowBroken() const { return m_state & NowBroken; } 102 : 103 : bool modify() const { return install() || remove(); } 104 : 105 : protected: 106 : unsigned m_state; 107 : }; 108 : 109 : time_t aptTimestamp(); 110 : 111 : // wrap the apt's database 112 : struct AptDatabase { 113 5093 : pkgCache &cache() { 114 5093 : if ( !m_cache ) 115 20 : openCache(); 116 5093 : return *m_cache; 117 : } 118 : 119 3793 : pkgDepCache &state() { 120 3793 : if ( !m_state ) 121 5 : openState(); 122 3793 : return *m_state; 123 : } 124 : 125 1436 : pkgPolicy &policy() { 126 1436 : if ( !m_policy ) 127 0 : openCache(); 128 1436 : return *m_policy; 129 : } 130 : 131 : OpProgress *m_progress; 132 : bool m_tryWriteable; 133 : bool m_writeable; 134 : 135 : time_t timestamp() { 136 : return aptTimestamp(); 137 : } 138 : 139 73 : AptDatabase() { 140 73 : m_cache = 0; 141 73 : m_state = 0; 142 73 : m_policy = 0; 143 73 : m_progress = new OpProgress(); 144 73 : m_tryWriteable = true; 145 73 : m_writeable = false; 146 73 : } 147 : 148 : void setProgress( OpProgress *p ) { 149 : m_progress = p; 150 : } 151 : 152 : bool writeable() { 153 : if ( !m_cache ) 154 : openCache(); 155 : return m_writeable; 156 : } 157 : 158 5 : void openState() { 159 5 : m_state = new pkgDepCache( &cache(), m_policy ); 160 5 : m_state->Init( m_progress ); 161 5 : m_progress->Done(); 162 5 : } 163 : 164 20 : void openCache() { 165 20 : if ( !_config->FindB("Initialized") ) { 166 0 : pkgInitConfig(*_config); 167 0 : _config->Set("Initialized", 1); 168 0 : pkgInitSystem(*_config, _system); 169 : } 170 : 171 20 : m_writeable = m_tryWriteable; 172 : 173 20 : if ( m_tryWriteable ) { 174 : try { 175 20 : _system->Lock(); 176 0 : } catch ( std::exception e ) { 177 0 : m_tryWriteable = false; 178 0 : openCache(); 179 0 : m_tryWriteable = true; 180 0 : throw; 181 : } 182 : } 183 : 184 20 : pkgSourceList list; 185 20 : if ( list.ReadMainList() == false ) { 186 0 : _error->DumpErrors(); 187 : throw wibble::exception::System( 188 0 : "The list of sources could not be read." ); 189 : } 190 : 191 20 : MMap *m = 0; 192 20 : bool Res = pkgMakeStatusCache( list, *m_progress, &m, !m_writeable ); 193 : 194 20 : if ( !Res ) { 195 : std::cerr << "The package lists or status file " 196 0 : "could not be parsed or opened." << std::endl; 197 : throw AptException( 198 : "The package lists or status file " 199 0 : "could not be parsed or opened." ); 200 : } 201 : 202 20 : m_cache = new pkgCache( m, true ); 203 40 : m_policy = new pkgPolicy( m_cache ); 204 40 : if ( ReadPinFile( *m_policy ) == false ) 205 0 : throw wibble::exception::System( "error reading pin file" ); 206 20 : m_progress->Done(); 207 20 : } 208 : 209 74 : void invalidate() { 210 74 : if ( _config->FindB("Initialized") ) { 211 74 : _system->UnLock(); 212 : } 213 : 214 74 : delete m_state; 215 74 : m_state = 0; 216 74 : delete m_policy; 217 74 : m_policy = 0; 218 74 : delete m_cache; 219 74 : m_cache = 0; 220 74 : } 221 : 222 : pkgCache::VerIterator anyVersion( pkgCache::PkgIterator pi ) { 223 : if ( pi.end() ) return pkgCache::VerIterator(); 224 : return pi.VersionList(); 225 : } 226 : 227 5 : Token candidateVersion( Token p ) { 228 5 : pkgCache::PkgIterator pi = cache().FindPkg( p.package() ); 229 6 : if ( pi.end() ) return Token(); 230 4 : pkgCache::VerIterator vi = policy().GetCandidateVer( pi ); 231 4 : if ( vi.end() ) return Token(); 232 : 233 4 : Token t; t._id = p.package() + "_" + vi.VerStr(); 234 4 : return t; 235 : } 236 : 237 1432 : pkgCache::VerIterator candidateVersion( pkgCache::PkgIterator pi ) { 238 1432 : if ( pi.end() ) return pkgCache::VerIterator(); 239 1432 : pkgCache::VerIterator vi = policy().GetCandidateVer( pi ); 240 1432 : if ( vi.end() ) return pkgCache::VerIterator(); 241 1432 : return vi; 242 : } 243 : 244 1432 : pkgCache::VerIterator installedVersion( pkgCache::PkgIterator pi ) { 245 1432 : if ( pi.end() ) return pkgCache::VerIterator(); 246 : pkgCache::VerIterator vi = pkgCache::VerIterator( cache(), 247 1432 : cache().VerP + pi->CurrentVer ); 248 1432 : if ( vi.end() ) return pkgCache::VerIterator(); 249 1432 : return vi; 250 : } 251 : 252 27 : pkgCache::PkgIterator lookupPackage( Token t ) { 253 27 : return cache().FindPkg( t.package() ); 254 : } 255 : 256 5 : pkgCache::VerIterator lookupVersion( Token t ) { 257 5 : if ( !t.hasVersion() ) 258 5 : t = candidateVersion( t ); 259 5 : pkgCache::PkgIterator pi = lookupPackage( t ); 260 5 : if ( pi.end() ) 261 1 : return pkgCache::VerIterator(); 262 4 : for (pkgCache::VerIterator vi = pi.VersionList(); !vi.end(); ++vi) 263 4 : if ( t.version() == vi.VerStr() ) 264 4 : return vi; 265 0 : return pkgCache::VerIterator(); 266 : } 267 : 268 : static pkgCache::VerFileIterator lookupVersionFile( 269 5 : pkgCache::VerIterator vi ) 270 : { 271 5 : if ( vi.end() ) 272 1 : return pkgCache::VerFileIterator(); 273 4 : pkgCache::VerFileIterator vfi = vi.FileList(); 274 4 : for ( ; !vfi.end(); vfi++ ) 275 4 : if ( ( vfi.File()->Flags & pkgCache::Flag::NotSource ) == 0) 276 4 : break; 277 4 : if ( vfi.end() ) 278 0 : vfi = vi.FileList(); 279 4 : return vfi; 280 : } 281 : 282 0 : PackageState invalidState() { 283 0 : return PackageState( PackageState::NowBroken | PackageState::Keep ); 284 : } 285 : 286 3784 : PackageState packageState( pkgCache::PkgIterator P ) 287 : { 288 3784 : PackageState s = 0; 289 3784 : if ( P.end() ) 290 0 : return invalidState(); 291 3784 : if ( ! ( P->CurrentState == pkgCache::State::ConfigFiles 292 : || P->CurrentState == pkgCache::State::NotInstalled ) ) 293 1432 : s |= PackageState::Installed; 294 3784 : if ( s & PackageState::Installed && 295 : candidateVersion( P ) != installedVersion( P ) ) 296 1 : s |= PackageState::Upgradable; 297 3784 : pkgDepCache::StateCache S = state()[ P ]; 298 3784 : if ( S.Install() ) 299 3 : s |= PackageState::Install; 300 3784 : if ( ( S.iFlags & pkgDepCache::ReInstall ) 301 : == pkgDepCache::ReInstall ) 302 0 : s |= PackageState::ReInstall; 303 3784 : if ( S.Keep() ) 304 3780 : s |= PackageState::Keep; 305 3784 : if ( S.Delete() ) 306 1 : s |= PackageState::Remove; 307 3784 : if ( ( S.iFlags & pkgDepCache::Purge ) == pkgDepCache::Purge ) 308 0 : s |= PackageState::Purge; 309 3784 : if ( S.NowBroken() ) 310 1 : s |= PackageState::NowBroken; 311 3784 : if ( S.InstBroken() ) 312 0 : s |= PackageState::WillBreak; 313 3784 : if ( P->SelectedState == pkgCache::State::Hold ) 314 0 : s |= PackageState::Hold; 315 3784 : return s; 316 : } 317 : 318 1 : PackageState packageState( Token t ) { 319 1 : t = validate( t ); 320 1 : if ( t.valid() ) 321 1 : return packageState( lookupPackage( t ) ); 322 0 : return invalidState(); 323 : } 324 : 325 4 : Token validate( Token t ) { 326 4 : if ( t.hasVersion() ) 327 0 : return lookupVersion( t ).end() ? Token() : t; 328 4 : return lookupPackage( t ).end() ? Token() : t; 329 : } 330 : 331 73 : ~AptDatabase() { 332 73 : invalidate(); 333 73 : } 334 : 335 : protected: 336 : pkgCache *m_cache; 337 : pkgDepCache *m_state; 338 : pkgPolicy *m_policy; 339 : }; 340 : 341 : template< typename Internal > 342 : struct AptInternalList { 343 : Internal m_head; 344 : typedef Internal Type; 345 11331 : AptInternalList tail() const { 346 11331 : AptInternalList t = *this; 347 11331 : t.m_head++; 348 : return t; 349 : } 350 7554 : const Internal &head() const { return m_head; } 351 3781 : Internal &head() { return m_head; } 352 11334 : bool empty() const { return m_head.end(); } 353 3 : AptInternalList( Internal head ) : m_head( head ) {} 354 : AptInternalList() {} 355 : }; 356 : 357 : namespace version { 358 : 359 : typedef enum { Package, VersionString, Section, Architecture, 360 : Depends, Recommends, Record } PropertyId; 361 : 362 : typedef pkgCache::VerIterator Internal; 363 : template< PropertyId > struct PropertyType {}; 364 : 365 : } 366 : 367 : namespace package { 368 : 369 : typedef enum { Name, Versions, AnyVersion, State, CandidateVersion, 370 : InstalledVersion } PropertyId; 371 : typedef pkgCache::PkgIterator Internal; 372 : template< PropertyId > struct PropertyType {}; 373 : 374 : struct VersionList { 375 : version::Internal m_head; 376 : VersionList tail() const; 377 : const version::Internal &head() const { return m_head; } 378 : version::Internal &head() { return m_head; } 379 : }; 380 : 381 : typedef AptInternalList< Internal > InternalList; 382 : 383 : } 384 : 385 : namespace record { 386 : 387 : typedef enum { Record, Name, Priority, Section, InstalledSize, Maintainer, 388 : Architecture, SourcePackage, Version, Description, 389 : ShortDescription, LongDescription, PackageSize } PropertyId; 390 : 391 : extern const char *fields[]; 392 : 393 : typedef pkgCache::VerFileIterator Internal; 394 : 395 : template< PropertyId > struct PropertyType { 396 : typedef std::string T; 397 : }; 398 : 399 : } 400 : } 401 : } 402 : 403 : #include <ept/core/apt/package.h> 404 : #include <ept/core/apt/version.h> 405 : #include <ept/core/apt/record.h> 406 : 407 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /// -*- C++ -*- (c) 2006, 2007 Petr Rockai <me@mornfall.net> 2 : 3 : #include <wibble/string.h> 4 : 5 : #include <ept/token.h> 6 : #include <ept/core/desktopfile.h> 7 : #include <ept/core/source.h> 8 : 9 : #include <set> 10 : #include <vector> 11 : #include <fstream> 12 : #include <sstream> 13 : #include <iterator> 14 : #include <functional> 15 : 16 : #include <dirent.h> 17 : 18 : #ifndef EPT_CORE_DESKTOP_H 19 : #define EPT_CORE_DESKTOP_H 20 : 21 : namespace ept { 22 : namespace core { 23 : namespace desktop { 24 : 25 : typedef enum { Name, Group, ShortDescription, Package, Icon } PropertyId; 26 : 27 : template< PropertyId > struct PropertyType {}; 28 : template<> struct PropertyType< Name > { typedef std::string T; }; 29 : template<> struct PropertyType< Group > { typedef std::string T; }; 30 : template<> struct PropertyType< ShortDescription > { typedef std::string T; }; 31 : template<> struct PropertyType< Package > { typedef ept::Token T; }; 32 : template<> struct PropertyType< Icon > { typedef std::string T; }; 33 : 34 : typedef std::set< std::string > Categories; 35 : 36 64 : struct Category { 37 : std::string name; 38 112 : operator std::string() const { return name; } 39 : }; 40 : 41 80 : inline std::istream &operator >>( std::istream &i, Category &cat ) { 42 : char c; 43 80 : cat.name = ""; 44 468 : while ( i.peek() != EOF ) { 45 356 : c = i.get(); 46 356 : if ( c == ';' ) return i; 47 308 : cat.name += c; 48 : } 49 32 : return i; 50 : } 51 : 52 567 : struct Entry : wibble::mixin::Comparable< Entry > { 53 18 : Entry() {} 54 : Entry( std::string n, std::string g, 55 : std::string p, std::string d , std::string i ) 56 : : m_name( n ), 57 : m_package( p ), 58 : m_description( d ), 59 : m_icon( i ) 60 : { setCategories( g ); } 61 : 62 16 : void load( std::string file ) { 63 16 : m_id = file; 64 16 : std::ifstream i( file.c_str() ); 65 16 : if ( !i.is_open() ) 66 0 : return; // throw? 67 16 : desktop::File e; 68 16 : i >> e; 69 16 : i.close(); 70 16 : desktop::File::Group &g = e.group( "Desktop Entry" ); 71 32 : m_name = g.entry( "Name" ).value; 72 32 : m_description = g.entry( "Comment" ).value; 73 32 : if ( m_description == "" ) 74 8 : m_description = g.entry( "GenericName" ).value; 75 16 : m_package = g.entry( "X-AppInstall-Package" ).value; 76 : // m_group = g.entry( "Categories" ).value; 77 32 : m_icon = g.entry( "Icon" ).value; 78 32 : setCategories( g.entry( "Categories" ).value ); 79 : } 80 : 81 16 : void setCategories( std::string s ) { 82 16 : std::istringstream i( s ); 83 16 : m_categories.clear(); 84 : std::remove_copy_if( 85 : std::istream_iterator< Category >( i ), 86 : std::istream_iterator< Category >(), 87 : std::inserter( m_categories, m_categories.begin() ), 88 16 : std::bind1st( std::equal_to< std::string >(), "" ) ); 89 16 : } 90 : 91 16 : Categories categories() const { return m_categories; } 92 : bool inCategory( std::string c ) const { 93 : return m_categories.find( c ) != m_categories.end(); 94 : } 95 34 : std::string id() const { return m_id; } 96 6 : std::string name() const { return m_name; } 97 : std::string package() const { return m_package; } 98 : std::string description() const { return m_description; } 99 : std::string icon() const { return m_icon; } 100 : bool operator< ( const Entry &o ) const { 101 : if ( m_name < o.m_name ) return true; 102 : if ( m_name == o.m_name ) 103 : if ( m_package < o.m_package ) return true; 104 : return false; 105 : } 106 : protected: 107 : std::string m_name, m_package, m_description, m_icon, m_id; 108 : bool m_supported, m_free; 109 : Categories m_categories; 110 : }; 111 : 112 450 : struct InternalList { 113 : std::string dir; 114 : std::string current; 115 : mutable Entry entry; 116 : off_t offset; 117 : mutable bool loaded; 118 : 119 9 : InternalList() : dir( "" ), offset( -2 ), loaded( false ) {} 120 4 : InternalList( std::string d ) : dir( d ), offset( -1 ), loaded( false ) 121 : { 122 4 : firstFile(); 123 4 : } 124 : 125 56 : Entry head() const { 126 56 : if (!loaded) 127 16 : entry.load( current ); 128 56 : loaded = true; 129 56 : return entry; 130 : } 131 : 132 33 : bool empty() const { 133 33 : return (offset == -2); 134 : } 135 : 136 4 : void firstFile() { 137 4 : offset = -1; 138 4 : nextFile(); 139 4 : } 140 : 141 16 : InternalList tail() const { 142 16 : InternalList r = *this; 143 16 : r.nextFile(); 144 0 : return r; 145 : } 146 : 147 20 : void nextFile() { 148 20 : loaded = false; 149 20 : DIR *d = opendir( dir.c_str() ); 150 20 : if ( !d ) { 151 0 : offset = -2; 152 0 : closedir( d ); 153 0 : return; 154 : } 155 : 156 20 : if ( offset != -1 ) 157 16 : seekdir( d, offset ); 158 : 159 20 : dirent *ent = 0; 160 48 : while ( ( ent = readdir( d ) ) != 0 ) { 161 24 : std::string name( ent->d_name ); 162 48 : if ( name == "." || name == ".." ) 163 8 : continue; 164 16 : if ( !wibble::str::endsWith( name, ".desktop" ) ) 165 : continue; 166 16 : current = dir + "/" + name; 167 16 : offset = telldir( d ); 168 16 : closedir( d ); 169 16 : return; 170 : } 171 4 : closedir( d ); 172 4 : offset = -2; 173 : } 174 : }; 175 : 176 : struct Setup { 177 : typedef ept::Token Token; 178 : typedef Entry Internal; 179 : typedef desktop::PropertyId PropertyId; 180 : typedef desktop::InternalList InternalList; 181 : }; 182 : 183 5 : struct GroupPolicy { 184 16 : virtual std::string group( const Entry &e ) 185 : { 186 16 : return wibble::str::fmt( e.categories() ); 187 : } 188 5 : virtual ~GroupPolicy() {} 189 : }; 190 : 191 : struct Source : core::Source< Source, Setup, PropertyType > 192 5 : { 193 : std::string m_dir; 194 : 195 : GroupPolicy m_defaultPolicy; 196 : GroupPolicy *m_policy; 197 : 198 5 : Source( std::string dir ) : m_dir( dir ), 199 5 : m_policy( &m_defaultPolicy ) {} 200 : 201 4 : InternalList listInternal() { 202 4 : return InternalList( m_dir ); 203 : } 204 : 205 34 : Token getToken( Entry i ) { 206 34 : Token t; 207 34 : t._id = std::string( "desktop:" ) + i.id(); 208 0 : return t; 209 : } 210 : 211 : Entry lookupToken( Token t ) { 212 : Entry e; 213 : e.load( t.desktop() ); 214 : return e; 215 : } 216 : 217 : void setGroupPolicy( GroupPolicy *p ) { 218 : m_policy = p; 219 : } 220 : 221 : template< PropertyId p > 222 : typename PropertyType< p >::T getInternal( Entry ); 223 : 224 56 : struct IsInGroup { 225 : std::string g; 226 2 : IsInGroup( std::string _g = "" ) : g( _g ) {} 227 8 : bool operator()( Token, std::string gr ) const { 228 8 : return gr == g; 229 : } 230 : }; 231 : 232 1 : PropertyFilter< Group, IsInGroup >::T group( std::string id ) 233 : { 234 1 : return propertyFilter< Group >( IsInGroup( id ) ); 235 : } 236 : 237 4 : static std::string projectGroup( ComposedList< Name > t ) { 238 4 : return t.get< Group >(); 239 : } 240 : 241 : list::Unique< list::Sorted< 242 : list::Map< ComposedList< Name >, 243 : __typeof( std::ptr_fun( &projectGroup ) ) > > > 244 1 : groupList() { 245 : return list::unique( 246 : list::sort( list::map( list< Name >(), 247 1 : std::ptr_fun( &projectGroup ) ) ) ); 248 : } 249 : }; 250 : 251 6 : template<> inline std::string Source::getInternal< Name >( Entry e ) { 252 6 : return e.name(); 253 : } 254 : 255 : template<> inline std::string Source::getInternal< Icon >( Entry e ) { 256 : return e.icon(); 257 : } 258 : 259 : template<> inline ept::Token Source::getInternal< Package >( Entry e ) { 260 : ept::Token t; 261 : t._id = e.package(); 262 : return t; 263 : } 264 : 265 16 : template<> inline std::string Source::getInternal< Group >( Entry e ) { 266 16 : return m_policy->group( e ); 267 : } 268 : 269 : template<> inline std::string Source::getInternal< ShortDescription >( Entry e ) { 270 : return e.description(); 271 : } 272 : 273 : } 274 : } 275 : } 276 : 277 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : #include <ept/config.h> 3 : #include <ept/core/apt.h> 4 : #include <ept/core/list.h> 5 : #include <ept/test.h> 6 : 7 : using namespace ept::core; 8 : 9 : struct TestCoreApt : AptTestEnvironment 10 12 : { 11 : package::Source pkgs; 12 : version::Source vers; 13 : ept::Token t; 14 : 15 12 : TestCoreApt() : pkgs( db ), vers( db ) { 16 12 : t._id = "sp"; 17 12 : } 18 : 19 1 : Test token() { 20 1 : assert_eq( t.package(), "sp" ); 21 2 : assert_eq( t.version(), "" ); 22 1 : } 23 : 24 1 : Test tokenVersion() { 25 1 : ept::Token t2; 26 1 : t2._id = "libwibble-dev_0.1.10"; 27 1 : assert_eq( t2.package(), "libwibble-dev" ); 28 1 : assert_eq( t2.version(), "0.1.10" ); 29 1 : } 30 : 31 1 : Test packageName() { 32 1 : assert_eq( t.package(), pkgs.get< package::Name >( t ) ); 33 1 : } 34 : 35 : template< typename List > 36 1 : void checkPackageNameList( List l ) { 37 3779 : while ( !l.empty() ) { 38 3777 : assert_eq( l.token().package(), l.property() ); 39 3777 : l = l.tail(); 40 : } 41 1 : } 42 : 43 : template< typename List > 44 1 : void checkVersionPackageList( List l ) { 45 1810 : while ( !l.empty() ) { 46 1808 : assert_eq( l.property().package(), l.token().package() ); 47 3616 : assert_eq( l.property().version(), "" ); 48 1808 : l = l.tail(); 49 : } 50 1 : } 51 : 52 1 : Test packageCount() { 53 : assert_eq( list::count( pkgs.list< package::Name >() ), 54 1 : 3777 ); 55 1 : } 56 : 57 1 : Test packageNameList() { 58 1 : checkPackageNameList( pkgs.list< package::Name >() ); 59 1 : } 60 : 61 1 : Test versionCount() { 62 : assert_eq( list::count( vers.list< version::Package >() ), 63 1 : 1808 ); 64 1 : } 65 : 66 1 : Test versionPackage() { 67 1 : checkVersionPackageList( vers.list< version::Package >() ); 68 1 : } 69 : 70 1 : Test validate() { 71 1 : assert_eq( t, db.validate( t ) ); 72 : assert_neq( ept::Token( "libfoobar" ), 73 2 : db.validate( ept::Token( "libfooar" ) ) ); 74 2 : assert_eq( ept::Token(), db.validate( ept::Token( "libfoobar" ) ) ); 75 1 : } 76 : 77 1 : Test packageState() { 78 1 : assert( db.packageState( t ) & PackageState::Keep ); 79 1 : } 80 : 81 1 : Test packageState2() { 82 1 : assert( pkgs.get< package::State >( t ) & PackageState::Keep ); 83 1 : } 84 : 85 1 : Test exists() { 86 1 : assert( pkgs.exists( t ) ); 87 2 : assert( !pkgs.exists( ept::Token( "nonexistent-package" ) ) ); 88 1 : } 89 : 90 1 : Test invalidate() { 91 1 : assert( pkgs.exists( t ) ); 92 1 : db.invalidate(); 93 2 : assert( pkgs.exists( t ) ); 94 1 : } 95 : }; |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** \file 2 : * Parser for APT records 3 : */ 4 : 5 : /* 6 : * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org> 7 : * 8 : * This library is free software; you can redistribute it and/or 9 : * modify it under the terms of the GNU Lesser General Public 10 : * License as published by the Free Software Foundation; either 11 : * version 2.1 of the License, or (at your option) any later version. 12 : * 13 : * This library is distributed in the hope that it will be useful, 14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 : * Lesser General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU Lesser General Public 19 : * License along with this library; if not, write to the Free Software 20 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 : */ 22 : 23 : #include <ept/core/apt/recordparser.h> 24 : 25 : #include <algorithm> 26 : #include <cctype> 27 : 28 : //#include <iostream> 29 : 30 : using namespace std; 31 : 32 : namespace ept { 33 : namespace core { 34 : namespace record { 35 : 36 : struct rpcompare 37 : { 38 : const RecordParser& rp; 39 1310 : rpcompare(const RecordParser& rp) : rp(rp) {} 40 89600 : bool operator()(size_t a, size_t b) 41 : { 42 89600 : return rp.name(a) < rp.name(b); 43 : } 44 : }; 45 : 46 1310 : void RecordParser::scan(const std::string& str) 47 : { 48 1310 : buffer = str; 49 1310 : ends.clear(); 50 1310 : sorted.clear(); 51 : 52 : //cerr << "PARSE " << endl << buffer << "*****" << endl; 53 : 54 : // Scan the buffer, taking note of all ending offsets of the various fields 55 1310 : size_t pos = 0; 56 1310 : size_t idx = 0; 57 29815 : while (pos < buffer.size() - 1) 58 : { 59 : //cerr << "PREPOS " << pos << " left: " << buffer.substr(pos, 10) << endl; 60 28505 : pos = buffer.find("\n", pos); 61 : //cerr << "POSTPOS " << pos << " left: " << (pos == string::npos ? "NONE" : buffer.substr(pos, 10)) << endl; 62 : 63 : // The buffer does not end with a newline 64 28505 : if (pos == string::npos) 65 : { 66 : //cerr << "ENDNOTEOL" << endl; 67 1 : pos = buffer.size(); 68 1 : ends.push_back(pos); 69 1 : sorted.push_back(idx++); 70 1 : break; 71 : } 72 : 73 28504 : ++pos; 74 : //cerr << "POSTPOSINC " << pos << " left: " << buffer.substr(pos, 10) << endl; 75 : 76 : // The buffer ends with a newline 77 28504 : if (pos == buffer.size()) 78 : { 79 : //cerr << "ENDEOL" << endl; 80 1309 : ends.push_back(pos); 81 1309 : sorted.push_back(idx++); 82 1309 : break; 83 : } 84 : 85 : // Terminate parsing on double newlines 86 27195 : if (buffer[pos] == '\n') 87 : { 88 : //cerr << "ENDDOUBLENL" << endl; 89 0 : ends.push_back(pos); 90 0 : sorted.push_back(idx++); 91 0 : break; 92 : } 93 : 94 : // Mark the end of the field if it's not a continuation line 95 27195 : if (!isspace(buffer[pos])) 96 : { 97 : //cerr << "INNERFIELD" << endl; 98 17224 : ends.push_back(pos); 99 17224 : sorted.push_back(idx++); 100 : } //else 101 : //cerr << "CONTLINE" << endl; 102 : } 103 : 104 : // Sort the sorted array 105 1310 : sort(sorted.begin(), sorted.end(), rpcompare(*this)); 106 : 107 : //for (size_t i = 0; i < ends.size(); ++i) 108 : // cerr << ends[i] << "\t" << name(i) << "\t" << sorted[i] << "\t" << name(sorted[i]) << endl; 109 1310 : } 110 : 111 187124 : std::string RecordParser::field(size_t idx) const 112 : { 113 187124 : if (idx >= ends.size()) 114 1 : return string(); 115 187123 : if (idx == 0) 116 16577 : return buffer.substr(0, ends[0]); 117 : else 118 170546 : return buffer.substr(ends[idx-1], ends[idx]-ends[idx-1]); 119 : } 120 : 121 185814 : std::string RecordParser::name(size_t idx) const 122 : { 123 185814 : string res = field(idx); 124 185814 : size_t pos = res.find(":"); 125 185814 : if (pos == string::npos) 126 2 : return res; 127 185812 : return res.substr(0, pos); 128 : } 129 : 130 1310 : std::string RecordParser::lookup(size_t idx) const 131 : { 132 1310 : string res = field(idx); 133 1310 : size_t pos = res.find(":"); 134 1310 : if (pos == string::npos) 135 1 : return res; 136 : // Skip initial whitespace after the : 137 1309 : for (++pos; pos < res.size() && isspace(res[pos]); ++pos) 138 : ; 139 1309 : res = res.substr(pos); 140 : // Trim spaces at the end 141 3927 : while (!res.empty() && isspace(res[res.size() - 1])) 142 1309 : res.resize(res.size() - 1); 143 1309 : return res; 144 : } 145 : 146 1310 : size_t RecordParser::index(const std::string& str) const 147 : { 148 : int begin, end; 149 : 150 : /* Binary search */ 151 1310 : begin = -1, end = size(); 152 7924 : while (end - begin > 1) 153 : { 154 5304 : int cur = (end + begin) / 2; 155 : //cerr << "Test " << cur << " " << str << " < " << name(cur) << endl; 156 5304 : if (name(sorted[cur]) > str) 157 1724 : end = cur; 158 : else 159 3580 : begin = cur; 160 : } 161 : 162 1310 : if (begin == -1 || name(sorted[begin]) != str) 163 1 : return size(); 164 : else 165 1309 : return sorted[begin]; 166 : } 167 : 168 : } 169 : } 170 : } 171 : 172 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include <ept/core/apt.h> 2 : 3 : namespace ept { 4 : namespace core { 5 : namespace record { 6 : 7 : // needs to be kept in sync with record::PropertyId, see apt.h 8 : const char *fields[] = { 9 : "", "Package", "Priority", "Section", "Installed-Size", 10 : "Maintainer", "Architecture", "Source", "Version", 11 : "Description", "", "", "Size" 12 : }; 13 : 14 : } 15 : } 16 3 : } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : 3 : #ifndef EPT_APT_PACKAGE_H 4 : #define EPT_APT_PACKAGE_H 5 : 6 : namespace ept { 7 : namespace core { 8 : namespace package { 9 : 10 : struct Setup { 11 : typedef ept::Token Token; 12 : typedef package::Internal Internal; 13 : typedef package::PropertyId PropertyId; 14 : typedef package::InternalList InternalList; 15 : }; 16 : 17 : template<> struct PropertyType< Name > { typedef std::string T; }; 18 : template<> struct PropertyType< Versions > { typedef VersionList T; }; 19 : template<> struct PropertyType< AnyVersion > { typedef Token T; }; 20 : template<> struct PropertyType< State > { typedef PackageState T; }; 21 : template<> struct PropertyType< CandidateVersion > { typedef Token T; }; 22 : template<> struct PropertyType< InstalledVersion > { typedef Token T; }; 23 : 24 : struct Source : core::Source< Source, Setup, PropertyType > 25 15 : { 26 : AptDatabase &m_db; 27 : 28 15 : Source( AptDatabase &db ) : m_db( db ) {} 29 : 30 3 : InternalList listInternal() { 31 3 : return InternalList( m_db.cache().PkgBegin() ); 32 : } 33 : 34 17 : Internal lookupToken( Token t ) { 35 17 : return m_db.lookupPackage( t ); 36 : } 37 : 38 3777 : Token getToken( Internal i ) { 39 3777 : Token t; 40 3777 : t._id = i.Name(); 41 0 : return t; 42 : } 43 : 44 8 : bool exists( Token t ) { 45 8 : if ( t.hasVersion() ) 46 0 : return !m_db.lookupVersion( t ).end(); 47 : else 48 8 : return !lookupToken( t ).end(); 49 : } 50 : 51 : Token versionToken( pkgCache::VerIterator vi ) { 52 : if ( vi.end() ) 53 : return Token(); 54 : return Token( std::string( vi.ParentPkg().Name() ) + "_" + vi.VerStr() ); 55 : } 56 : 57 : template< PropertyId p > 58 : typename PropertyType< p >::T getInternal( Internal ); 59 : 60 : template< typename List > 61 1 : void revertState( List l ) { 62 3779 : while ( !l.empty() ) { 63 3777 : PackageState s = getInternal< State >( l.head() ); 64 3777 : if ( !s.keep() || s.purge() ) { 65 2 : pkgDepCache::StateCache &S = db().state()[ l.head() ]; 66 2 : db().state().MarkKeep( l.head(), false, false ); 67 2 : S.iFlags &= ~pkgDepCache::Purge; 68 2 : S.iFlags &= ~pkgDepCache::ReInstall; 69 : } 70 3777 : l = l.tail(); 71 : } 72 1 : } 73 : 74 1 : void revertStates() { 75 1 : pkgDepCache::ActionGroup group( db().state() ); 76 1 : revertState( listInternal() ); 77 1 : } 78 : 79 : typedef ComposedList< State > ChangeList; 80 : 81 : static bool isChanged( Token t, PackageState s ); 82 : static bool isUpgradable( Token t, PackageState s ); 83 : 84 : PropertyFilter< State, __typeof( &isChanged ) >::T changedList() { 85 : return propertyFilter< State >( isChanged ); 86 : } 87 : 88 : PropertyFilter< State, __typeof( &isUpgradable ) >::T upgradableList() { 89 : return propertyFilter< State >( isUpgradable ); 90 : } 91 : 92 9 : AptDatabase &db() { return m_db; } 93 : }; 94 : 95 3778 : template<> inline std::string Source::getInternal< Name >( Internal i ) { 96 3778 : return i.Name(); 97 : } 98 : 99 3783 : template<> inline PackageState Source::getInternal< State >( Internal i ) { 100 3783 : return m_db.packageState( i ); 101 : } 102 : 103 : template<> inline Token Source::getInternal< CandidateVersion >( Internal i ) { 104 : return versionToken( m_db.candidateVersion( i ) ); 105 : } 106 : 107 : template<> inline Token Source::getInternal< AnyVersion >( Internal i ) { 108 : return versionToken( m_db.candidateVersion( i ) ); 109 : } 110 : 111 : template<> inline Token Source::getInternal< InstalledVersion >( Internal i ) { 112 : return versionToken( m_db.installedVersion( i ) ); 113 : } 114 : 115 : inline bool Source::isChanged( Token, PackageState s ) { 116 : return s.modify(); 117 : } 118 : 119 : inline bool Source::isUpgradable( Token, PackageState s ) { 120 : return s.upgradable(); 121 : } 122 : 123 : } 124 : } 125 : } 126 : 127 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : #ifndef EPT_CORE_APT_RECORDPARSER_H 3 : #define EPT_CORE_APT_RECORDPARSER_H 4 : 5 : /** \file 6 : * Parser for APT records 7 : */ 8 : 9 : /* 10 : * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org> 11 : * 12 : * This library is free software; you can redistribute it and/or 13 : * modify it under the terms of the GNU Lesser General Public 14 : * License as published by the Free Software Foundation; either 15 : * version 2.1 of the License, or (at your option) any later version. 16 : * 17 : * This library is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 : * Lesser General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU Lesser General Public 23 : * License along with this library; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : #include <vector> 28 : #include <string> 29 : 30 : namespace ept { 31 : namespace core { 32 : namespace record { 33 : 34 : /** 35 : * Access the fields of a package record contained inside a std::string. 36 : * 37 : * Implementation note: this implementation should take advantage of 38 : * std::string sharing buffer space among them. 39 : */ 40 : class RecordParser 41 1310 : { 42 : /// Buffer containing the whole record 43 : std::string buffer; 44 : 45 : /// End offsets of the various fields in the record 46 : std::vector<size_t> ends; 47 : 48 : /// Indexes on the ends vector, sorted by field name 49 : std::vector<size_t> sorted; 50 : 51 : public: 52 : RecordParser() {} 53 1310 : RecordParser(const std::string& str) { scan(str); } 54 : 55 : /// Index a new record 56 : void scan(const std::string& str); 57 : 58 : /** 59 : * Get the index of the field with the given name. 60 : * 61 : * size() is returned if not found 62 : */ 63 : size_t index(const std::string& str) const; 64 : 65 : /// Return the field by its index 66 : std::string field(size_t idx) const; 67 : 68 : /// Return the name of a field by its index 69 : std::string name(size_t idx) const; 70 : 71 : /// Return the content of a field by its index 72 : std::string lookup(size_t idx) const; 73 : 74 : /// Return the content of a field by its name 75 1310 : std::string lookup(const std::string& name) const { return lookup(index(name)); } 76 : 77 : /// Return the content of a field by its index 78 : std::string operator[](size_t idx) const { return lookup(idx); } 79 : 80 : /// Return the content of a field by its name 81 : std::string operator[](const std::string& name) const { return lookup(name); } 82 : 83 : /// Return the entire record 84 : const std::string& record() const { return buffer; } 85 : 86 : /// Return the entire record 87 : std::string record() { return buffer; } 88 : 89 : /// Return the number of fields in the record 90 1311 : size_t size() const { return ends.size(); } 91 : }; 92 : 93 : } 94 : } 95 : } 96 : 97 : // vim:set ts=4 sw=4: 98 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : 3 : #include <string> 4 : #include <ept/token.h> 5 : #include <ept/core/apt.h> 6 : #include <apt-pkg/algorithms.h> 7 : 8 : #ifndef EPT_APT_ACTION_H 9 : #define EPT_APT_ACTION_H 10 : 11 : namespace ept { 12 : namespace core { 13 : namespace package { 14 : 15 13 : struct Action { 16 : enum Type { Install, ReInstall, Remove, Keep, Purge, SystemUpgrade }; 17 : Token m_token; 18 : Type m_type; 19 : 20 4 : Token token() { return m_token; } 21 : Type type() { return m_type; } 22 : 23 4 : void apply( package::Source &pkgs ) 24 : { 25 4 : Type a = m_type; 26 4 : pkgDepCache &dc = pkgs.db().state(); 27 : 28 4 : if ( a == SystemUpgrade ) { 29 0 : pkgDistUpgrade( dc ); 30 : } else { 31 4 : if ( !pkgs.exists( m_token ) ) 32 0 : return; 33 4 : pkgCache::PkgIterator p = pkgs.lookupToken( m_token ); 34 : 35 4 : pkgProblemResolver fix( &dc ); 36 8 : if ( a == Install || a == ReInstall ) { 37 2 : fix.Clear( p ); 38 2 : fix.Protect( p ); 39 2 : dc.MarkInstall( p, true ); 40 2 : fix.InstallProtect(); 41 2 : if ( a == ReInstall ) 42 0 : dc.SetReInstall( p, true ); 43 2 : } else if ( a == Remove || a == Purge ) { 44 0 : fix.Clear( p ); 45 0 : fix.Protect( p ); 46 0 : fix.Remove( p ); 47 0 : dc.MarkDelete( p, a == Purge ? true : false ); 48 2 : } else if ( a == Keep ) { 49 2 : fix.Clear( p ); 50 2 : fix.Protect( p ); 51 2 : dc.MarkKeep( p, true ); 52 : } 53 4 : fix.Resolve( true ); 54 : } 55 : } 56 : 57 : bool redundant( package::Source &pkgs ) { 58 : if ( m_type == SystemUpgrade ) { 59 : // check whether we have any upgradable packages 60 : return false; 61 : } 62 : if ( !pkgs.exists( m_token ) ) 63 : return true; 64 : PackageState s = pkgs.db().packageState( m_token ); 65 : Type a = m_type; 66 : // if ( a == Keep && !s.upgradable() ) 67 : // return true; 68 : if ( ( a == Install || a == ReInstall ) 69 : && ( !s.upgradable() && s.installed() ) ) 70 : return true; 71 : if ( ( a == Remove || a == Purge ) && !s.installed() ) 72 : return true; 73 : return false; 74 : } 75 : 76 6 : Action( Token t, Type a ) 77 6 : : m_token( t ), m_type( a ) 78 6 : {} 79 : }; 80 : 81 2 : struct ActionList { 82 : typedef std::vector< Action > List; 83 : List m_list; 84 : 85 : void clear() { 86 : m_list.clear(); 87 : } 88 : 89 1 : bool empty() { 90 1 : return m_list.empty(); 91 : } 92 : 93 3 : void add( Action a ) { 94 3 : List::iterator rm = m_list.end(), i; 95 3 : for ( i = m_list.begin(); i != m_list.end(); ++i ) { 96 2 : if ( i->token() == a.token() ) { 97 2 : rm = i; 98 2 : break; 99 : } 100 : } 101 3 : if ( rm != m_list.end() ) 102 2 : m_list.erase( rm ); 103 : // if ( a.type() != Action::Keep ) 104 3 : m_list.push_back( a ); 105 3 : } 106 : 107 : Action latest() { 108 : return m_list.back(); 109 : } 110 : 111 1 : void replay( package::Source &pkgs ) { 112 2 : for ( List::iterator i = m_list.begin(); i != m_list.end(); ++i ) { 113 1 : i->apply( pkgs ); 114 : } 115 1 : } 116 : 117 : void prune( package::Source &pkgs ) { 118 : List l; 119 : std::swap( l, m_list ); 120 : for ( List::iterator i = m_list.begin(); i != m_list.end(); ++i ) { 121 : if ( !i->redundant( pkgs ) ) 122 : m_list.push_back( *i ); 123 : } 124 : /* We want to do but can't bind reference parameters.... (or 125 : maybe use remove_copy_if or whatever ... ugly 126 : std::remove_if( m_list.begin(), m_list.end(), std::bind2nd( 127 : std::mem_fun_ref( &Action::redundant ), pkgs ) ); */ 128 : } 129 : }; 130 : 131 : } 132 : } 133 : } 134 : 135 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : #ifndef EPT_CORE_APT_VERSION_H 3 : #define EPT_CORE_APT_VERSION_H 4 : 5 : namespace ept { 6 : namespace core { 7 : namespace version { 8 : 9 3616 : struct InternalList { 10 : package::Internal m_pkg; 11 : Internal m_ver; 12 : 13 : typedef Internal Type; 14 : 15 3616 : InternalList tail() const { 16 3616 : InternalList t = *this; 17 3616 : t.m_ver ++; 18 3616 : t.seek(); 19 : return t; 20 : } 21 : 22 5424 : const Internal head() const { 23 5424 : return m_ver; 24 : } 25 : 26 : Internal head() { 27 : return m_ver; 28 : } 29 : 30 3618 : bool empty() const { 31 3618 : return m_pkg.end(); 32 : } 33 : 34 3618 : void seek() 35 : { 36 14790 : while ( m_ver.end() && !m_pkg.end() ) { 37 7554 : m_pkg ++; 38 7554 : m_ver = m_pkg.VersionList(); 39 : } 40 3618 : } 41 : 42 2 : InternalList( package::Internal i ) 43 2 : : m_pkg( i ) 44 : { 45 2 : m_ver = m_pkg.VersionList(); 46 2 : seek(); 47 2 : } 48 : }; 49 : 50 : struct Setup { 51 : typedef ept::Token Token; 52 : typedef version::Internal Internal; 53 : typedef version::PropertyId PropertyId; 54 : typedef version::InternalList InternalList; 55 : }; 56 : 57 : struct Source : core::Source< Source, Setup, PropertyType > 58 12 : { 59 : AptDatabase &m_db; 60 12 : Source( AptDatabase &db ) : m_db( db ) {} 61 : 62 2 : InternalList listInternal() { 63 2 : return InternalList( m_db.cache().PkgBegin() ); 64 : } 65 : 66 1808 : Token getToken( Internal i ) { 67 1808 : Token t; 68 1808 : t._id = std::string( i.ParentPkg().Name() ) + "_" + i.VerStr(); 69 0 : return t; 70 : } 71 : 72 : Internal lookupToken( Token t ) { 73 : return m_db.lookupVersion( t ); 74 : } 75 : 76 : template< PropertyId p > 77 : typename PropertyType< p >::T getInternal( Internal ); 78 : }; 79 : 80 : template<> struct PropertyType< Package > { typedef Token T; }; 81 : 82 3616 : template<> inline Token Source::getInternal< Package >( Internal i ) { 83 3616 : assert( !i.end() ); 84 3616 : Token t; 85 7232 : t._id = i.ParentPkg().Name(); 86 0 : return t; 87 : } 88 : 89 : } 90 : } 91 : } 92 : 93 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
action.h |
|
85.4 % | 41 / 48 lines | |
action.test.h |
|
100.0 % | 29 / 29 lines | |
package.h |
|
93.9 % | 31 / 33 lines | |
record.cpp |
|
100.0 % | 1 / 1 lines | |
record.h |
|
86.5 % | 83 / 96 lines | |
record.test.h |
|
100.0 % | 29 / 29 lines | |
recordparser.cpp |
|
95.2 % | 59 / 62 lines | |
recordparser.h |
|
100.0 % | 4 / 4 lines | |
version.h |
|
93.8 % | 30 / 32 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : #include <ept/core/apt.h> 3 : 4 : #include <ept/test.h> 5 : 6 : using namespace ept::core; 7 : 8 : struct TestAptRecord : AptTestEnvironment 9 6 : { 10 : record::Source recs; 11 : ept::Token t; 12 : 13 6 : TestAptRecord() : recs( db ) { 14 6 : t._id = "sp"; 15 6 : } 16 : 17 1 : Test checkLookup() { 18 1 : recs.get< record::Record >( t ); 19 1 : } 20 : 21 1 : Test checkLookupValue() { 22 1 : assert_eq( recs.get< record::Name >( t ), t.package() ); 23 : assert_eq( recs.get< record::Maintainer >( t ), 24 2 : "Neil Roeth <neil@debian.org>" ); 25 1 : } 26 : 27 1 : Test checkLookupNumeric() { 28 : assert_eq( recs.get< record::InstalledSize >( t ), 29 1 : 600 ); 30 1 : } 31 : 32 1 : Test checkShortDescription() { 33 : assert_eq( recs.get< record::ShortDescription >( t ), 34 1 : "James Clark's SGML parsing tools" ); 35 1 : } 36 : 37 : template< typename List > 38 1 : void checkRecordNameList( List l ) { 39 437 : while ( !l.empty() ) { 40 435 : assert_eq( l.property(), l.token().package() ); 41 435 : l = l.tail(); 42 : } 43 1 : } 44 : 45 1 : Test checkList() { 46 : // there are 435 valid records in the list file 47 : assert_eq( list::count( recs.list< 48 1 : record::Name >() ), 435 ); 49 1 : checkRecordNameList( recs.list< record::Name >() ); 50 1 : } 51 : 52 1 : Test nonexistent() { 53 : assert_eq( recs.get< record::ShortDescription >( 54 1 : ept::Token( "nonexistent-package" ) ), "" ); 55 1 : } 56 : }; |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : #include <ept/core/apt/action.h> 3 : #include <ept/test.h> 4 : 5 : using namespace ept::core; 6 : 7 : struct TestAptAction : AptTestEnvironment 8 3 : { 9 : package::Source pkgs; 10 3 : TestAptAction() : pkgs( db ) {} 11 : 12 1 : Test basic() { 13 1 : ept::Token t( "sp" ); 14 2 : package::Action a( t, package::Action::Install ); 15 1 : a.apply( pkgs ); 16 1 : assert( pkgs.get< package::State >( t ).install() ); 17 1 : a = package::Action( t, package::Action::Keep ); 18 1 : a.apply( pkgs ); 19 1 : assert( pkgs.get< package::State >( t ).keep() ); 20 1 : } 21 : 22 1 : Test revert() { 23 1 : ept::Token t( "sp" ); 24 2 : package::Action a( t, package::Action::Install ); 25 1 : a.apply( pkgs ); 26 1 : assert( pkgs.get< package::State >( t ).install() ); 27 1 : pkgs.revertStates(); 28 1 : assert( pkgs.get< package::State >( t ).keep() ); 29 1 : } 30 : 31 1 : Test keep() { 32 1 : package::ActionList al; 33 1 : ept::Token t( "sp" ); 34 2 : al.add( package::Action( t, package::Action::Install ) ); 35 1 : assert( !al.empty() ); 36 2 : al.add( package::Action( t, package::Action::Remove ) ); 37 1 : al.add( package::Action( t, package::Action::Keep ) ); 38 1 : al.replay( pkgs ); 39 1 : assert( pkgs.get< package::State >( t ).keep() ); 40 1 : } 41 : }; |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : 3 : #include <ept/core/apt/recordparser.h> 4 : 5 : #ifndef EPT_APT_RECORD_H 6 : #define EPT_APT_RECORD_H 7 : 8 : namespace ept { 9 : namespace core { 10 : namespace record { 11 : 12 : struct Source; 13 : 14 : struct InternalList { 15 : Source *m_source; 16 : size_t m_idx; 17 : 18 : Internal head(); 19 : const Internal head() const; 20 : bool empty() const; 21 : 22 870 : InternalList tail() const { 23 870 : InternalList t = *this; 24 870 : ++ t.m_idx; 25 : return t; 26 : } 27 : 28 2 : InternalList( Source &s ) 29 2 : : m_source( &s ), m_idx( 0 ) 30 2 : {} 31 : }; 32 : 33 : struct Setup { 34 : typedef ept::Token Token; 35 : typedef record::Internal Internal; 36 : typedef record::PropertyId PropertyId; 37 : typedef record::InternalList InternalList; 38 : }; 39 : 40 : template<> struct PropertyType< InstalledSize > { typedef int T; }; 41 : template<> struct PropertyType< PackageSize > { typedef int T; }; 42 : 43 : struct Parser: RecordParser 44 1310 : { 45 : bool parseBool(bool& def, const std::string& str) const 46 : { 47 : // Believe it or not, this is what apt does to interpret bool fields 48 : if (str == "no" || str == "false" || str == "without" || 49 : str == "off" || str == "disable") 50 : return false; 51 : 52 : if (str == "yes" || str == "true" || str == "with" || 53 : str == "on" || str == "enable") 54 : return true; 55 : 56 : return def; 57 : } 58 : 59 : public: 60 : Parser() : RecordParser() {} 61 1310 : Parser(const std::string& str) : RecordParser(str) {} 62 : 63 : template< PropertyId p > 64 : typename PropertyType< p >::T parse( typename PropertyType< p >::T def, 65 : std::string data ); 66 : 67 : template< typename T > 68 : struct Default { 69 : static T def; 70 : }; 71 : 72 : template< typename T > T parse( const T &def, 73 : const std::string &field ) const; 74 : 75 : template< PropertyId p > 76 : typename PropertyType< p >::T get( 77 : const typename PropertyType< p >::T &def 78 1308 : = Default< typename PropertyType< p >::T >::def ) const 79 : { 80 : return parse< typename PropertyType< p >::T >( def, 81 1308 : lookup( fields[ p ] ) ); 82 : } 83 : 84 : }; 85 : 86 25 : template< typename T > T Parser::Default< T >::def = T(); 87 : 88 : template<> inline std::string Parser::get< ShortDescription >( 89 2 : const std::string& def ) const 90 : { 91 2 : std::string str = lookup( fields[ Description ] ); 92 4 : if (str == std::string()) 93 1 : return def; 94 1 : size_t pos = str.find("\n"); 95 1 : if (pos == std::string::npos) 96 0 : return str; 97 : else 98 1 : return str.substr(0, pos); 99 : } 100 : 101 : template<> inline std::string Parser::get< LongDescription >( 102 : const std::string& def ) const 103 : { 104 : std::string str = lookup( fields[ Description ] ); 105 : if (str == std::string()) 106 : return def; 107 : size_t pos = str.find("\n"); 108 : if (pos == std::string::npos) 109 : return str; 110 : else 111 : { 112 : // Trim trailing spaces 113 : for (++pos; pos < str.size() && isspace(str[pos]); ++pos) 114 : ; 115 : return str.substr(pos); 116 : } 117 : } 118 : 119 : template<> inline std::string Parser::parse< std::string >( 120 1307 : const std::string& def, const std::string& str) const 121 : { 122 1307 : if (str == std::string()) 123 0 : return def; 124 1307 : return str; 125 : } 126 : 127 : template<> inline int Parser::parse< int >( 128 1 : const int& def, const std::string& str) const 129 : { 130 1 : if (str == string()) 131 0 : return def; 132 1 : return (size_t)strtoul(str.c_str(), NULL, 10); 133 : } 134 : 135 : struct Source : core::Source< Source, Setup, PropertyType > 136 6 : { 137 : AptDatabase &m_db; 138 : 139 : /* caching */ 140 : pkgCache::PkgFileIterator lastFile; 141 : FileFd file; 142 : size_t lastOffset; 143 : 144 : /* in-order retrieval of records, for InternalList */ 145 : typedef vector< pkgCache::VerFile * > VfList; 146 : VfList m_vflist; 147 : 148 1742 : VfList &vfList() { 149 1742 : if ( m_vflist.size() > 0 ) 150 1741 : return m_vflist; 151 : 152 1 : m_vflist.reserve(m_db.cache().HeaderP->PackageCount + 1); 153 : 154 : // Populate the vector of versions to print 155 3778 : for (pkgCache::PkgIterator pi = m_db.cache().PkgBegin(); !pi.end(); ++pi) 156 : { 157 3777 : if (pi->VersionList == 0) 158 1989 : continue; 159 : 160 3596 : for( pkgCache::VerIterator vi = pi.VersionList(); !vi.end(); ++vi ) { 161 : 162 : // Choose a valid file that contains the record for this version 163 1808 : pkgCache::VerFileIterator vfi = vi.FileList(); 164 3181 : for ( ; !vfi.end(); ++vfi ) 165 1808 : if ((vfi.File()->Flags & pkgCache::Flag::NotSource) == 0) 166 435 : break; 167 : 168 1808 : if ( !vfi.end() ) 169 435 : m_vflist.push_back( vfi ); 170 : } 171 : } 172 : 173 1 : sort(m_vflist.begin(), m_vflist.end(), localityCompare); 174 1 : return m_vflist; 175 : } 176 : 177 6 : Source( AptDatabase &db ) : m_db( db ) {} 178 : 179 2 : InternalList listInternal() { 180 2 : return InternalList( *this ); 181 : } 182 : 183 5 : Internal lookupToken( Token t ) { 184 5 : return m_db.lookupVersionFile( m_db.lookupVersion( t ) ); 185 : } 186 : 187 : // Sort a version list by package file locality 188 : static bool localityCompare(const pkgCache::VerFile* a, 189 4371 : const pkgCache::VerFile* b) 190 : { 191 4371 : if (a == 0 && b == 0) 192 0 : return false; 193 4371 : if (a == 0) 194 0 : return true; 195 4371 : if (b == 0) 196 0 : return false; 197 : 198 4371 : if (a->File == b->File) 199 4371 : return a->Offset < b->Offset; 200 0 : return a->File < b->File; 201 : } 202 : 203 : void invalidate() { 204 : core::Source< Source, Setup, PropertyType >::invalidate(); 205 : lastFile = pkgCache::PkgFileIterator(); 206 : } 207 : 208 1311 : std::string getRecord( Internal vfi ) { 209 1311 : if ( vfi.Cache() == 0 || vfi.end() ) 210 1 : return ""; 211 : 212 1310 : if ((lastFile.Cache() == 0) 213 : || vfi->File + m_db.cache().PkgFileP != lastFile) 214 : { 215 : lastFile = pkgCache::PkgFileIterator( 216 5 : m_db.cache(), vfi->File + m_db.cache().PkgFileP); 217 5 : if (!lastFile.IsOk()) 218 : throw wibble::exception::System( 219 : std::string("Reading the" 220 : " data record for a package from file ") 221 0 : + lastFile.FileName() ); 222 5 : if (file.IsOpen()) 223 0 : file.Close(); 224 5 : if (!file.Open(lastFile.FileName(), FileFd::ReadOnly)) 225 : throw wibble::exception::System( std::string("Opening file ") 226 0 : + lastFile.FileName() ); 227 5 : lastOffset = 0; 228 : } 229 : 230 : // If we start near were we ended, avoid a seek 231 : // and enlarge the read a bit 232 1310 : size_t slack = vfi->Offset - lastOffset; 233 1310 : if ( slack > 128 ) // mornfall: was 8, making it 128 234 : { 235 871 : slack = 0; 236 871 : if ( !file.Seek( vfi->Offset ) ) 237 : throw wibble::exception::System( 238 : std::string("Cannot seek to package record in file ") 239 0 : + lastFile.FileName() ); 240 : } 241 : 242 1310 : char buffer[vfi->Size + slack + 1]; 243 1310 : if (!file.Read(buffer, vfi->Size + slack)) 244 : throw wibble::exception::System( 245 : std::string("Cannot read package " 246 0 : "record in file ") + lastFile.FileName() ); 247 : 248 1310 : buffer[vfi->Size + slack] = '\0'; 249 : //cerr << "Data read (slack: " << slack << ")" << endl; 250 : 251 1310 : lastOffset = vfi->Offset + vfi->Size; 252 : 253 1310 : return string(buffer+slack); 254 : } 255 : 256 435 : Token getToken( Internal i ) { 257 435 : Token t; 258 435 : t._id = getInternal< Name >( i ) + "_" + getInternal< Version >( i ); 259 0 : return t; 260 : } 261 : 262 : template< PropertyId p > 263 1310 : typename PropertyType< p >::T getInternal( Internal i ) { 264 1310 : Parser rec( getRecord( i ) ); 265 1310 : return rec.get< p >(); 266 : } 267 : }; 268 : 269 1 : template<> inline std::string Source::getInternal< Record >( Internal i ) { 270 1 : assert( !i.end() ); 271 1 : return getRecord( i ); 272 : } 273 : 274 870 : inline const Internal InternalList::head() const { 275 : return pkgCache::VerFileIterator( m_source->m_db.cache(), 276 870 : m_source->vfList()[ m_idx ] ); 277 : } 278 : 279 872 : inline bool InternalList::empty() const { 280 872 : return m_idx == m_source->vfList().size(); 281 : } 282 : 283 : 284 : } 285 : } 286 : } 287 : 288 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org> 3 : * 4 : * This library is free software; you can redistribute it and/or 5 : * modify it under the terms of the GNU Lesser General Public 6 : * License as published by the Free Software Foundation; either 7 : * version 2.1 of the License, or (at your option) any later version. 8 : * 9 : * This library is distributed in the hope that it will be useful, 10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : * Lesser General Public License for more details. 13 : * 14 : * You should have received a copy of the GNU Lesser General Public 15 : * License along with this library; if not, write to the Free Software 16 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : */ 18 : 19 : #include <ept/test.h> 20 : #include <ept/apt/recordparser.h> 21 : 22 : //#include <iostream> 23 : 24 : using namespace std; 25 : using namespace ept; 26 : using namespace ept::apt; 27 : 28 12 : struct TestAptRecordparser { 29 : std::string record; 30 12 : TestAptRecordparser() 31 12 : { 32 : record = 33 : "A:\n" 34 : "D: da de di do du\n" 35 : "B: b\n" 36 : "C: c \n" 37 : "Desc: this is the beginning\n" 38 : " this is the continuation\n" 39 12 : " this is the end\n"; 40 12 : } 41 : 42 : // Check that the fields are identified and broken up correctly 43 1 : Test parsing() 44 : { 45 1 : RecordParser p(record); 46 : 47 1 : assert_eq(p.record(), record); 48 1 : assert_eq(p.size(), 5u); 49 1 : } 50 : 51 1 : Test fieldTuples() 52 : { 53 1 : RecordParser p(record); 54 1 : assert_eq(p.field(0), "A:\n"); 55 1 : assert_eq(p.field(1), "D: da de di do du\n"); 56 1 : assert_eq(p.field(2), "B: b\n"); 57 1 : assert_eq(p.field(3), "C: c \n"); 58 1 : assert_eq(p.field(4), "Desc: this is the beginning\n this is the continuation\n this is the end\n"); 59 1 : } 60 : 61 1 : Test fieldKeys() 62 : { 63 1 : RecordParser p(record); 64 1 : assert_eq(p.name(0), "A"); 65 1 : assert_eq(p.name(1), "D"); 66 1 : assert_eq(p.name(2), "B"); 67 1 : assert_eq(p.name(3), "C"); 68 1 : assert_eq(p.name(4), "Desc"); 69 1 : } 70 : 71 1 : Test fieldValues() 72 : { 73 1 : RecordParser p(record); 74 1 : assert_eq(p[0], ""); 75 1 : assert_eq(p[1], "da de di do du"); 76 1 : assert_eq(p[2], "b"); 77 1 : assert_eq(p[3], "c"); 78 1 : assert_eq(p[4], "this is the beginning\n this is the continuation\n this is the end"); 79 1 : } 80 : 81 : // Check that the field search by name finds all the fields 82 1 : Test findByName() 83 : { 84 1 : RecordParser p(record); 85 : 86 1 : assert_eq(p.index("A"), 0u); 87 2 : assert_eq(p.index("D"), 1u); 88 2 : assert_eq(p.index("B"), 2u); 89 2 : assert_eq(p.index("C"), 3u); 90 2 : assert_eq(p.index("Desc"), 4u); 91 : 92 2 : assert_eq(p.name(p.index("A")), "A"); 93 2 : assert_eq(p.name(p.index("B")), "B"); 94 2 : assert_eq(p.name(p.index("C")), "C"); 95 2 : assert_eq(p.name(p.index("D")), "D"); 96 2 : assert_eq(p.name(p.index("Desc")), "Desc"); 97 1 : } 98 : 99 1 : Test indexing() 100 : { 101 1 : RecordParser p(record); 102 1 : assert_eq(p["A"], ""); 103 2 : assert_eq(p["B"], "b"); 104 2 : assert_eq(p["C"], "c"); 105 2 : assert_eq(p["D"], "da de di do du"); 106 2 : assert_eq(p["Desc"], "this is the beginning\n this is the continuation\n this is the end"); 107 1 : } 108 : 109 1 : Test missingBehaviour() 110 : { 111 1 : RecordParser p(record); 112 : // Missing fields give empty strings 113 1 : assert_eq(p.field(100), ""); 114 1 : assert_eq(p.name(100), ""); 115 1 : assert_eq(p[100], ""); 116 1 : assert_eq(p["Missing"], ""); 117 1 : } 118 : 119 : // Check that scanning twice replaces the old fields 120 1 : Test rescan() 121 : { 122 : std::string record = 123 : "A: a\n" 124 : "B: b\n" 125 1 : "C: c\n"; 126 : 127 1 : RecordParser p(record); 128 1 : assert_eq(p.size(), 3u); 129 2 : assert_eq(p["A"], "a"); 130 2 : assert_eq(p["B"], "b"); 131 2 : assert_eq(p["C"], "c"); 132 : 133 : std::string record1 = 134 : "Foo: bar\n" 135 2 : "A: different\n"; 136 : 137 1 : p.scan(record1); 138 : 139 : //for (size_t i = 0; i < p.size(); ++i) 140 : // cerr << ">> " << i << "==" << p.index(p.name(i)) << " " << p.name(i) << " " << p[i] << endl; 141 : 142 1 : assert_eq(p.size(), 2u); 143 2 : assert_eq(p["A"], "different"); 144 2 : assert_eq(p["B"], ""); 145 2 : assert_eq(p["C"], ""); 146 2 : assert_eq(p["Foo"], "bar"); 147 1 : } 148 : 149 : // Real-life example 150 1 : Test realLife() 151 : { 152 : string record = 153 : "Package: apt\n" 154 : "Priority: important\n" 155 : "Section: admin\n" 156 : "Installed-Size: 4368\n" 157 : "Maintainer: APT Development Team <deity@lists.debian.org>\n" 158 : "Architecture: amd64\n" 159 : "Version: 0.6.46.4-0.1\n" 160 : "Replaces: libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)\n" 161 : "Provides: libapt-pkg-libc6.3-6-3.11\n" 162 : "Depends: libc6 (>= 2.3.5-1), libgcc1 (>= 1:4.1.1-12), libstdc++6 (>= 4.1.1-12), debian-archive-keyring\n" 163 : "Suggests: aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2\n" 164 : "Filename: pool/main/a/apt/apt_0.6.46.4-0.1_amd64.deb\n" 165 : "Size: 1436478\n" 166 : "MD5sum: 1776421f80d6300c77a608e77a9f4a15\n" 167 : "SHA1: 1bd7337d2df56d267632cf72ac930c0a4895898f\n" 168 : "SHA256: b92442ab60046b4d0728245f39cc932f26e17db9f7933a5ec9aaa63172f51fda\n" 169 : "Description: Advanced front-end for dpkg\n" 170 : " This is Debian's next generation front-end for the dpkg package manager.\n" 171 : " It provides the apt-get utility and APT dselect method that provides a\n" 172 : " simpler, safer way to install and upgrade packages.\n" 173 : " .\n" 174 : " APT features complete installation ordering, multiple source capability\n" 175 : " and several other unique features, see the Users Guide in apt-doc.\n" 176 : "Build-Essential: yes\n" 177 1 : "Tag: admin::package-management, filetransfer::ftp, filetransfer::http, hardware::storage:cd, interface::commandline, network::client, protocol::{ftp,http,ipv6}, role::program, suite::debian, use::downloading, use::searching, works-with::software:package\n"; 178 1 : RecordParser p(record); 179 : 180 1 : assert_eq(p.size(), 19u); 181 : 182 1 : string rec1; 183 20 : for (size_t i = 0; i < p.size(); ++i) 184 19 : rec1 += p.field(i); 185 1 : assert_eq(record, rec1); 186 1 : } 187 : 188 : // Various buffer termination patterns 189 1 : Test bufferTermination() 190 : { 191 : std::string record = 192 : "A: a\n" 193 1 : "B: b"; 194 : 195 1 : RecordParser p(record); 196 1 : assert_eq(p.size(), 2u); 197 2 : assert_eq(p["A"], "a"); 198 2 : assert_eq(p["B"], "b"); 199 1 : } 200 : 201 1 : Test bufferTermination2() 202 : { 203 : std::string record = 204 : "A: a\n" 205 1 : "B: b\n\n"; 206 : 207 1 : RecordParser p(record); 208 1 : assert_eq(p.size(), 2u); 209 2 : assert_eq(p["A"], "a"); 210 2 : assert_eq(p["B"], "b"); 211 1 : } 212 : 213 1 : Test bufferTermination3() 214 : { 215 : std::string record = 216 : "A: a\n" 217 : "B: b\n\n" 218 1 : "C: c\n"; 219 : 220 1 : RecordParser p(record); 221 1 : assert_eq(p.size(), 2u); 222 2 : assert_eq(p["A"], "a"); 223 2 : assert_eq(p["B"], "b"); 224 1 : } 225 : 226 : }; 227 : 228 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** \file 2 : * High-level front-end to libapt-pkg, as a data provider for the ept framework. 3 : */ 4 : 5 : /* 6 : * Copyright (C) 2007,2008 Enrico Zini <enrico@enricozini.org> 7 : * 8 : * This library is free software; you can redistribute it and/or 9 : * modify it under the terms of the GNU Lesser General Public 10 : * License as published by the Free Software Foundation; either 11 : * version 2.1 of the License, or (at your option) any later version. 12 : * 13 : * This library is distributed in the hope that it will be useful, 14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 : * Lesser General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU Lesser General Public 19 : * License along with this library; if not, write to the Free Software 20 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 : */ 22 : 23 : #include <ept/apt/apt.h> 24 : 25 : #include <apt-pkg/error.h> 26 : #include <apt-pkg/init.h> 27 : #include <apt-pkg/progress.h> 28 : #include <apt-pkg/sourcelist.h> 29 : #include <apt-pkg/pkgcachegen.h> 30 : #include <apt-pkg/policy.h> 31 : #include <apt-pkg/cachefile.h> 32 : 33 : #include <wibble/sys/fs.h> 34 : #include <sys/stat.h> 35 : 36 : #include <vector> 37 : #include <algorithm> 38 : 39 : #include <iostream> 40 : 41 : using namespace std; 42 : 43 : namespace ept { 44 : namespace apt { 45 : using core::aptTimestamp; 46 : 47 0 : Exception::Exception(const std::string& context) throw () 48 0 : : Generic(context) 49 : { 50 : // Concatenate all errors and warnings found 51 0 : string err; 52 0 : while (!_error->empty()) 53 : { 54 0 : bool type = _error->PopMessage(err); 55 0 : if (type) 56 0 : m_message += "E: " + err + "\n"; 57 : else 58 0 : m_message += "W: " + err + "\n"; 59 0 : } 60 0 : } 61 : 62 29 : static void aptInit () 63 : { 64 29 : if (_config->FindB("Initialized")) 65 29 : return; 66 : 67 0 : if (!pkgInitConfig (*_config)) 68 0 : throw Exception("initialising apt configuration"); 69 : 70 0 : _config->Set("Initialized", 1); 71 : 72 : /* 73 : _config->Set("Dir", CACHE_DIR); 74 : _config->Set("Dir::Cache", "cache"); 75 : _config->Set("Dir::State", "state"); 76 : _config->Set("Dir::Etc", "etc"); 77 : _config->Set("Dir::State::status", CACHE_DIR "dpkg-status"); 78 : */ 79 0 : if (!pkgInitSystem (*_config, _system)) 80 0 : throw Exception("initialising apt system"); 81 : } 82 : 83 : struct AptImplementation 84 : { 85 : pkgSourceList* m_list; 86 : MMap *m; 87 : OpProgress progress; 88 : pkgCache* m_cache; 89 : pkgPolicy* m_policy; 90 : pkgCacheFile* m_depcache; 91 : time_t m_open_timestamp; 92 : 93 29 : AptImplementation() : m_list(0), m(0), m_cache(0), m_policy(0), m_depcache(0), m_open_timestamp(0) 94 : { 95 : // Init the apt library if needed 96 29 : aptInit(); 97 : 98 29 : m_open_timestamp = aptTimestamp(); 99 : 100 29 : m_list = new pkgSourceList; 101 58 : if (!m_list->ReadMainList()) 102 0 : throw Exception("reading list of sources"); 103 : 104 29 : bool res = pkgMakeStatusCache(*m_list, progress, &m, true); 105 29 : progress.Done(); 106 29 : if (!res) 107 0 : throw Exception("Reading the package lists or status file"); 108 : 109 29 : m_cache = new pkgCache(m); 110 58 : m_policy = new pkgPolicy(m_cache); 111 58 : if (!ReadPinFile(*m_policy)) 112 0 : throw Exception("Reading the policy pin file"); 113 29 : } 114 : 115 29 : ~AptImplementation() 116 : { 117 29 : if (m_depcache) delete m_depcache; 118 29 : if (m_policy) delete m_policy; 119 29 : if (m_cache) delete m_cache; 120 29 : if (m) delete m; 121 29 : if (m_list) delete m_list; 122 29 : } 123 : 124 3980 : pkgCache& cache() 125 : { 126 3980 : return *m_cache; 127 : } 128 : 129 16099 : pkgPolicy& policy() 130 : { 131 16099 : return *m_policy; 132 : } 133 : 134 1 : pkgCacheFile& depcache() 135 : { 136 1 : if (!m_depcache) 137 : { 138 1 : m_depcache = new pkgCacheFile; 139 1 : if (!m_depcache->Open(progress, false)) 140 0 : throw Exception("Opening the cache file"); 141 : } 142 1 : return *m_depcache; 143 : } 144 : }; 145 : 146 : // Sort a version list by package file locality 147 39519 : bool localityCompare(const pkgCache::VerFile* a, const pkgCache::VerFile* b) 148 : { 149 39519 : if (a == 0 && b == 0) 150 0 : return false; 151 39519 : if (a == 0) 152 0 : return true; 153 39519 : if (b == 0) 154 0 : return false; 155 : 156 39519 : if (a->File == b->File) 157 39060 : return a->Offset < b->Offset; 158 459 : return a->File < b->File; 159 : } 160 : 161 : // Iterate records using the algorithm used by apt-cache dumpavail 162 : struct RecordIteratorImpl 163 : { 164 : mutable int _ref; 165 : AptImplementation& apt; 166 : vector<pkgCache::VerFile*> vflist; 167 : pkgCache::PkgFileIterator lastFile; 168 : FileFd file; 169 : size_t lastOffset; 170 : 171 9 : RecordIteratorImpl(AptImplementation& apt) : _ref(0), apt(apt), vflist(0) 172 : { 173 : // We already have an estimate of how many versions we're about to find 174 9 : vflist.reserve(apt.cache().HeaderP->PackageCount + 1); 175 : 176 : // Populate the vector of versions to print 177 34002 : for (pkgCache::PkgIterator pi = apt.cache().PkgBegin(); !pi.end(); ++pi) 178 : { 179 33993 : if (pi->VersionList == 0) 180 17901 : continue; 181 : 182 : /* Get the candidate version or fallback on the installed version, 183 : * as usual */ 184 16092 : pkgCache::VerIterator vi = apt.policy().GetCandidateVer(pi); 185 16092 : if (vi.end() == true) 186 : { 187 1926 : if (pi->CurrentVer == 0) 188 1926 : continue; 189 0 : vi = pi.CurrentVer(); 190 : } 191 : 192 : // Choose a valid file that contains the record for this version 193 14166 : pkgCache::VerFileIterator vfi = vi.FileList(); 194 24507 : for ( ; !vfi.end(); ++vfi) 195 14166 : if ((vfi.File()->Flags & pkgCache::Flag::NotSource) == 0) 196 3825 : break; 197 : 198 : // Handle packages whose candidate version is currently installed 199 : // from outside the archives (like from a locally built .deb 200 14166 : if (vfi.end() == true) 201 : { 202 20682 : for (pkgCache::VerIterator cur = pi.VersionList(); cur.end() != true; cur++) 203 : { 204 20763 : for (vfi = cur.FileList(); vfi.end() == false; vfi++) 205 : { 206 10422 : if ((vfi.File()->Flags & pkgCache::Flag::NotSource) == 0) 207 : { 208 81 : vfi = vi.FileList(); 209 81 : break; 210 : } 211 : } 212 : 213 10422 : if (vfi.end() == false) 214 81 : break; 215 : } 216 : } 217 14166 : if (!vfi.end()) 218 3906 : vflist.push_back(vfi); 219 : } 220 : 221 : //cerr << vflist.size() << " versions found" << endl; 222 : 223 9 : sort(vflist.begin(), vflist.end(), localityCompare); 224 : 225 : //for (size_t i = 0; i < vflist.size(); ++i) 226 : //{ 227 : // pkgCache::PkgFileIterator fi(apt.cache(), vflist[i]->File + apt.cache().PkgFileP); 228 : // cerr << i << ": " << fi.FileName() << ":" << vflist[i]->Offset << "-" << vflist[i]->Size << endl; 229 : //} 230 : //cerr << "Done indexing." << endl; 231 9 : } 232 : 233 9 : ~RecordIteratorImpl() 234 : { 235 9 : if (file.IsOpen()) 236 9 : file.Close(); 237 9 : } 238 : 239 14 : void ref() { ++_ref; } 240 14 : bool unref() { return --_ref == 0; } 241 : 242 3906 : size_t size() { return vflist.size(); } 243 : 244 3906 : string record(size_t idx) 245 : { 246 : //cerr << "Access record " << idx << endl; 247 : //cerr << "lastfile: " << (lastFile.Cache() != 0) << endl; 248 : // We can't reuse the file that was already open: open the new one 249 3906 : if ((lastFile.Cache() == 0) || vflist[idx]->File + apt.cache().PkgFileP != lastFile) 250 : { 251 : //cerr << "Needs open/reopen" << endl; 252 18 : lastFile = pkgCache::PkgFileIterator(apt.cache(), vflist[idx]->File + apt.cache().PkgFileP); 253 18 : if (!lastFile.IsOk()) 254 0 : throw Exception(string("Reading the data record for a package from file ") + lastFile.FileName()); 255 : //cerr << "Ok for " << lastFile.FileName() << endl; 256 18 : if (file.IsOpen()) 257 9 : file.Close(); 258 18 : if (!file.Open(lastFile.FileName(), FileFd::ReadOnly)) 259 0 : throw Exception(string("Opening file ") + lastFile.FileName()); 260 : //cerr << "Opened " << lastFile.FileName() << endl; 261 18 : lastOffset = 0; 262 : } 263 : 264 : //cerr << "Reading from " << lastFile.FileName() << ":" << vflist[idx]->Offset << "-" << vflist[idx]->Size << " (lastOffset: " << lastOffset << ")" << endl; 265 : 266 : // If we start near were we ended, avoid a seek and enlarge the read a bit 267 3906 : size_t slack = vflist[idx]->Offset - lastOffset; 268 : //cerr << "Slack: " << slack << endl; 269 3906 : if (slack > 8) 270 : { 271 : //cerr << "Slack too big: seek to " << vflist[idx]->Offset << endl; 272 171 : slack = 0; 273 171 : if (!file.Seek(vflist[idx]->Offset)) 274 0 : throw Exception(string("Cannot seek to package record in file ") + lastFile.FileName()); 275 : } 276 : 277 3906 : char buffer[vflist[idx]->Size + slack + 1]; 278 3906 : if (!file.Read(buffer, vflist[idx]->Size + slack)) 279 0 : throw Exception(string("Cannot read package record in file ") + lastFile.FileName()); 280 3906 : buffer[vflist[idx]->Size + slack] = '\n'; 281 : //cerr << "Data read (slack: " << slack << ")" << endl; 282 : 283 3906 : lastOffset = vflist[idx]->Offset + vflist[idx]->Size; 284 : 285 3906 : return string(buffer+slack); 286 : } 287 : }; 288 : 289 20 : Apt::Iterator::Iterator(const Iterator& i) 290 : { 291 20 : if (i.cur) 292 : { 293 10 : pkgCache::PkgIterator* p = new pkgCache::PkgIterator; 294 10 : *p = *static_cast<pkgCache::PkgIterator*>(i.cur); 295 10 : cur = p; 296 : } else 297 10 : cur = 0; 298 20 : } 299 : 300 0 : Apt::Iterator& Apt::Iterator::operator=(const Iterator& i) 301 : { 302 0 : if (cur != i.cur) 303 : { 304 0 : if (cur) delete static_cast<pkgCache::PkgIterator*>(cur); 305 0 : if (i.cur) 306 : { 307 0 : pkgCache::PkgIterator* p = new pkgCache::PkgIterator; 308 0 : *p = *static_cast<pkgCache::PkgIterator*>(i.cur); 309 0 : cur = p; 310 : } else 311 0 : cur = 0; 312 : } 313 0 : return *this; 314 : } 315 : 316 3605 : Apt::Iterator::~Iterator() 317 : { 318 3605 : if (cur) delete static_cast<pkgCache::PkgIterator*>(cur); 319 3605 : } 320 5364 : std::string Apt::Iterator::operator*() 321 : { 322 5364 : return static_cast<pkgCache::PkgIterator*>(cur)->Name(); 323 : } 324 7152 : Apt::Iterator& Apt::Iterator::operator++() 325 : { 326 7152 : pkgCache::PkgIterator* iter = static_cast<pkgCache::PkgIterator*>(cur); 327 7152 : ++*iter; 328 22260 : while (!iter->end() && (*iter)->VersionList == 0) 329 7956 : ++*iter; 330 7152 : if (iter->end()) 331 : { 332 4 : delete iter; 333 4 : cur = 0; 334 : } 335 7152 : return *this; 336 : } 337 0 : bool Apt::Iterator::operator==(const Iterator& i) const 338 : { 339 0 : if (cur == 0 && i.cur == 0) 340 0 : return true; 341 0 : if (cur == 0 || i.cur == 0) 342 0 : return false; 343 0 : pkgCache::PkgIterator* iter1 = static_cast<pkgCache::PkgIterator*>(cur); 344 0 : pkgCache::PkgIterator* iter2 = static_cast<pkgCache::PkgIterator*>(i.cur); 345 0 : return *iter1 == *iter2; 346 : } 347 7157 : bool Apt::Iterator::operator!=(const Iterator& i) const 348 : { 349 7157 : if (cur == 0 && i.cur == 0) 350 4 : return false; 351 7153 : if (cur == 0 || i.cur == 0) 352 7153 : return true; 353 0 : pkgCache::PkgIterator* iter1 = static_cast<pkgCache::PkgIterator*>(cur); 354 0 : pkgCache::PkgIterator* iter2 = static_cast<pkgCache::PkgIterator*>(i.cur); 355 0 : return *iter1 != *iter2; 356 : } 357 : 358 : 359 9 : Apt::RecordIterator::RecordIterator(RecordIteratorImpl* impl, size_t pos) 360 9 : : impl(impl), pos(pos), cur_pos(pos) 361 : { 362 9 : if (impl) 363 : { 364 9 : impl->ref(); 365 9 : cur = impl->record(pos); 366 9 : cur_pos = pos; 367 : } 368 9 : } 369 10 : Apt::RecordIterator::RecordIterator(const RecordIterator& r) 370 10 : : impl(r.impl), pos(r.pos), cur(r.cur), cur_pos(r.cur_pos) 371 : { 372 10 : if (impl) 373 5 : impl->ref(); 374 10 : } 375 3500 : Apt::RecordIterator::~RecordIterator() 376 : { 377 3500 : if (impl && impl->unref()) 378 1 : delete impl; 379 3500 : } 380 3906 : std::string Apt::RecordIterator::operator*() 381 : { 382 3906 : if (cur_pos != pos) 383 : { 384 3464 : cur = impl->record(pos); 385 3464 : cur_pos = pos; 386 : } 387 3906 : return cur; 388 : } 389 868 : std::string* Apt::RecordIterator::operator->() 390 : { 391 868 : if (cur_pos != pos) 392 : { 393 433 : cur = impl->record(pos); 394 433 : cur_pos = pos; 395 : } 396 868 : return &cur; 397 : } 398 3906 : Apt::RecordIterator& Apt::RecordIterator::operator++() 399 : { 400 3906 : ++pos; 401 3906 : if (pos >= impl->size()) 402 : { 403 : // If we reach the end, we become an end iterator 404 9 : if (impl && impl->unref()) 405 8 : delete impl; 406 9 : impl = 0; 407 9 : pos = 0; 408 : } 409 3906 : return *this; 410 : } 411 0 : Apt::RecordIterator& Apt::RecordIterator::operator=(const RecordIterator& r) 412 : { 413 : // Increment first, to avoid it reaching zero on assignment to self 414 0 : if (r.impl) r.impl->ref(); 415 0 : if (impl && impl->unref()) 416 0 : delete impl; 417 0 : impl = r.impl; 418 0 : pos = r.pos; 419 0 : cur = r.cur; 420 0 : cur_pos = r.cur_pos; 421 0 : return *this; 422 : } 423 0 : bool Apt::RecordIterator::operator==(const RecordIterator& ri) const 424 : { 425 0 : return impl == ri.impl && pos == ri.pos; 426 : } 427 3915 : bool Apt::RecordIterator::operator!=(const RecordIterator& ri) const 428 : { 429 3915 : return impl != ri.impl || pos != ri.pos; 430 : } 431 : 432 : 433 28 : Apt::Apt() : impl(new AptImplementation()) {} 434 28 : Apt::~Apt() { delete impl; } 435 : 436 4 : Apt::iterator Apt::begin() const 437 : { 438 4 : pkgCache::PkgIterator* p = new pkgCache::PkgIterator; 439 4 : *p = impl->cache().PkgBegin(); 440 4 : return Apt::Iterator(p); 441 : } 442 : 443 3581 : Apt::iterator Apt::end() const 444 : { 445 3581 : return Apt::Iterator(); 446 : } 447 : 448 9 : Apt::record_iterator Apt::recordBegin() const 449 : { 450 9 : return Apt::RecordIterator(new RecordIteratorImpl(*impl)); 451 : } 452 : 453 3481 : Apt::record_iterator Apt::recordEnd() const 454 : { 455 3481 : return Apt::RecordIterator(); 456 : } 457 : 458 0 : size_t Apt::size() const 459 : { 460 0 : return impl->cache().HeaderP->PackageCount; 461 : } 462 : 463 16 : time_t Apt::timestamp() 464 : { 465 16 : return aptTimestamp(); 466 : } 467 : 468 5 : bool Apt::isValid(const std::string& pkg) const 469 : { 470 5 : pkgCache::PkgIterator pi = impl->cache().FindPkg(pkg); 471 5 : return !pi.end(); 472 : } 473 : 474 4 : Version Apt::validate(const Version& ver) const 475 : { 476 4 : pkgCache::PkgIterator pi = impl->cache().FindPkg(ver.name()); 477 5 : if (pi.end()) return Version(); 478 4 : for (pkgCache::VerIterator vi = pi.VersionList(); !vi.end(); vi++) 479 : { 480 3 : const char* v = vi.VerStr(); 481 3 : if (v == 0) continue; 482 3 : if (ver.version() == v) 483 2 : return ver; 484 : } 485 1 : return Version(); 486 : } 487 : 488 4 : Version Apt::candidateVersion(const std::string& pkg) const 489 : { 490 4 : pkgCache::PkgIterator pi = impl->cache().FindPkg(pkg); 491 4 : if (pi.end()) return Version(); 492 3 : pkgCache::VerIterator vi = impl->policy().GetCandidateVer(pi); 493 3 : if (vi.end()) return Version(); 494 3 : return Version(pkg, vi.VerStr()); 495 : } 496 : 497 2 : Version Apt::installedVersion(const std::string& pkg) const 498 : { 499 2 : pkgCache::PkgIterator pi = impl->cache().FindPkg(pkg); 500 2 : if (pi.end()) return Version(); 501 1 : if (pi->CurrentVer == 0) return Version(); 502 1 : pkgCache::VerIterator vi = pi.CurrentVer(); 503 1 : if (vi.end()) return Version(); 504 1 : return Version(pkg, vi.VerStr()); 505 : } 506 : 507 4 : Version Apt::anyVersion(const std::string& pkg) const 508 : { 509 4 : pkgCache::PkgIterator pi = impl->cache().FindPkg(pkg); 510 4 : if (pi.end()) return Version(); 511 : 512 3 : pkgCache::VerIterator vi = impl->policy().GetCandidateVer(pi); 513 3 : if (vi.end()) 514 : { 515 0 : if (pi->CurrentVer == 0) return Version(); 516 0 : vi = pi.CurrentVer(); 517 0 : if (vi.end()) return Version(); 518 : } 519 3 : return Version(pkg, vi.VerStr()); 520 : } 521 : 522 2 : PackageState Apt::state(const std::string& pkg) const 523 : { 524 2 : pkgCache::PkgIterator pi = impl->cache().FindPkg(pkg); 525 2 : if (pi.end()) return PackageState(); 526 1 : pkgDepCache::StateCache sc = impl->depcache()[pi]; 527 : 528 1 : unsigned int flags = PackageState::Valid; 529 : 530 : // Check if the package is installed 531 1 : if (pi->CurrentState != pkgCache::State::ConfigFiles && 532 : pi->CurrentState != pkgCache::State::NotInstalled && 533 : pi->CurrentVer != 0) 534 : { 535 : // Try to get a VerIterator to the installed version 536 1 : pkgCache::VerIterator inst = pi.CurrentVer(); 537 1 : if (!inst.end()) 538 : { 539 : // If we made it so far, it is installed 540 1 : flags |= PackageState::Installed; 541 : 542 : // Now check if it is upgradable 543 1 : pkgCache::VerIterator cand = impl->policy().GetCandidateVer(pi); 544 : 545 : // If the candidate version is different than the installed one, then 546 : // it is installable 547 1 : if (!cand.end() && inst != cand) 548 0 : flags |= PackageState::Upgradable; 549 : } 550 : } 551 1 : if (sc.Install()) 552 0 : flags |= PackageState::Install; 553 1 : if ((sc.iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall) 554 0 : flags |= PackageState::ReInstall; 555 1 : if (sc.Keep()) 556 1 : flags |= PackageState::Keep; 557 1 : if (sc.Delete()) 558 0 : flags |= PackageState::Remove; 559 1 : if ((sc.iFlags & pkgDepCache::Purge) == pkgDepCache::Purge) 560 0 : flags |= PackageState::Purge; 561 1 : if (sc.NowBroken()) 562 0 : flags |= PackageState::NowBroken; 563 1 : if (sc.InstBroken()) 564 0 : flags |= PackageState::WillBreak; 565 : 566 1 : return PackageState(flags); 567 : } 568 : 569 1 : std::string Apt::rawRecord(const std::string& ver) const 570 : { 571 : // TODO: possibly reimplement using a single lump of apt code, to avoid 572 : // repeating lookups 573 1 : return rawRecord(anyVersion(ver)); 574 : } 575 : 576 4 : std::string Apt::rawRecord(const Version& ver) const 577 : { 578 4 : pkgCache::PkgIterator pi = impl->cache().FindPkg(ver.name()); 579 4 : if (pi.end()) return std::string(); 580 5 : for (pkgCache::VerIterator vi = pi.VersionList(); !vi.end(); vi++) 581 : { 582 4 : const char* v = vi.VerStr(); 583 4 : if (v == 0) continue; 584 4 : if (ver.version() == v) 585 : { 586 : // Code taken and adapted from apt-cache's DisplayRecord 587 : 588 : // Find an appropriate file 589 3 : pkgCache::VerFileIterator vfi = vi.FileList(); 590 3 : for (; !vfi.end(); vfi++) 591 3 : if ((vfi.File()->Flags & pkgCache::Flag::NotSource) == 0) 592 3 : break; 593 3 : if (vfi.end()) 594 0 : vfi = vi.FileList(); 595 : 596 : // Check and load the package list file 597 3 : pkgCache::PkgFileIterator pfi = vfi.File(); 598 3 : if (!pfi.IsOk()) 599 0 : throw Exception(string("Reading the data record for a package version from file ") + pfi.FileName()); 600 : 601 3 : FileFd pkgf(pfi.FileName(), FileFd::ReadOnly); 602 6 : if (_error->PendingError() == true) 603 0 : return std::string(); 604 : 605 : // Read the record and then write it out again. 606 3 : char* buffer = new char[vfi->Size+1]; 607 3 : buffer[vfi->Size] = '\n'; 608 3 : if (!pkgf.Seek(vfi->Offset) || !pkgf.Read(buffer, vfi->Size)) 609 : { 610 0 : delete[] buffer; 611 0 : return std::string(); 612 : } 613 : 614 3 : std::string res(buffer, vfi->Size); 615 6 : delete[] buffer; 616 3 : return res; 617 : } 618 : } 619 1 : return std::string(); 620 : } 621 : 622 2 : void Apt::checkCacheUpdates() 623 : { 624 2 : if (impl->m_open_timestamp < timestamp()) 625 : { 626 : // Crudely reopen everything 627 1 : delete impl; 628 1 : impl = new AptImplementation; 629 : } 630 2 : } 631 : 632 1 : void Apt::invalidateTimestamp() 633 : { 634 1 : impl->m_open_timestamp = 0; 635 1 : } 636 : 637 : } 638 6 : } 639 : 640 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_APT_RECORDPARSER_H 2 : #define EPT_APT_RECORDPARSER_H 3 : 4 : /** \file 5 : * Parser for APT records 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <vector> 27 : #include <string> 28 : 29 : namespace ept { 30 : namespace apt { 31 : 32 : /** 33 : * Access the fields of a package record contained inside a std::string. 34 : * 35 : * Implementation note: this implementation should take advantage of 36 : * std::string sharing buffer space among them. 37 : */ 38 : class RecordParser 39 19 : { 40 : /// Buffer containing the whole record 41 : std::string buffer; 42 : 43 : /// End offsets of the various fields in the record 44 : std::vector<size_t> ends; 45 : 46 : /// Indexes on the ends vector, sorted by field name 47 : std::vector<size_t> sorted; 48 : 49 : public: 50 6 : RecordParser() {} 51 13 : RecordParser(const std::string& str) { scan(str); } 52 : 53 : /// Index a new record 54 : void scan(const std::string& str); 55 : 56 : /** 57 : * Get the index of the field with the given name. 58 : * 59 : * size() is returned if not found 60 : */ 61 : size_t index(const std::string& str) const; 62 : 63 : /// Return the field by its index 64 : std::string field(size_t idx) const; 65 : 66 : /// Return the name of a field by its index 67 : std::string name(size_t idx) const; 68 : 69 : /// Return the content of a field by its index 70 : std::string lookup(size_t idx) const; 71 : 72 : /// Return the content of a field by its name 73 18273 : std::string lookup(const std::string& name) const { return lookup(index(name)); } 74 : 75 : /// Return the content of a field by its index 76 6 : std::string operator[](size_t idx) const { return lookup(idx); } 77 : 78 : /// Return the content of a field by its name 79 19 : std::string operator[](const std::string& name) const { return lookup(name); } 80 : 81 : /// Return the entire record 82 : const std::string& record() const { return buffer; } 83 : 84 : /// Return the entire record 85 1 : std::string record() { return buffer; } 86 : 87 : /// Return the number of fields in the record 88 20972 : size_t size() const { return ends.size(); } 89 : }; 90 : 91 : } 92 : } 93 : 94 : // vim:set ts=4 sw=4: 95 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** \file 2 : * Parser for APT records 3 : */ 4 : 5 : /* 6 : * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org> 7 : * 8 : * This library is free software; you can redistribute it and/or 9 : * modify it under the terms of the GNU Lesser General Public 10 : * License as published by the Free Software Foundation; either 11 : * version 2.1 of the License, or (at your option) any later version. 12 : * 13 : * This library is distributed in the hope that it will be useful, 14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 : * Lesser General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU Lesser General Public 19 : * License along with this library; if not, write to the Free Software 20 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 : */ 22 : 23 : #include <ept/apt/recordparser.h> 24 : 25 : #include <algorithm> 26 : #include <cctype> 27 : 28 : //#include <iostream> 29 : 30 : using namespace std; 31 : 32 : namespace ept { 33 : namespace apt { 34 : 35 : struct rpcompare 36 : { 37 : const RecordParser& rp; 38 2618 : rpcompare(const RecordParser& rp) : rp(rp) {} 39 177724 : bool operator()(size_t a, size_t b) 40 : { 41 177724 : return rp.name(a) < rp.name(b); 42 : } 43 : }; 44 : 45 2618 : void RecordParser::scan(const std::string& str) 46 : { 47 2618 : buffer = str; 48 2618 : ends.clear(); 49 2618 : sorted.clear(); 50 : 51 : //cerr << "PARSE " << endl << buffer << "*****" << endl; 52 : 53 : // Scan the buffer, taking note of all ending offsets of the various fields 54 2618 : size_t pos = 0; 55 2618 : size_t idx = 0; 56 59427 : while (pos < buffer.size() - 1) 57 : { 58 : //cerr << "PREPOS " << pos << " left: " << buffer.substr(pos, 10) << endl; 59 56809 : pos = buffer.find("\n", pos); 60 : //cerr << "POSTPOS " << pos << " left: " << (pos == string::npos ? "NONE" : buffer.substr(pos, 10)) << endl; 61 : 62 : // The buffer does not end with a newline 63 56809 : if (pos == string::npos) 64 : { 65 : //cerr << "ENDNOTEOL" << endl; 66 1 : pos = buffer.size(); 67 1 : ends.push_back(pos); 68 1 : sorted.push_back(idx++); 69 1 : break; 70 : } 71 : 72 56808 : ++pos; 73 : //cerr << "POSTPOSINC " << pos << " left: " << buffer.substr(pos, 10) << endl; 74 : 75 : // The buffer ends with a newline 76 56808 : if (pos == buffer.size()) 77 : { 78 : //cerr << "ENDEOL" << endl; 79 11 : ends.push_back(pos); 80 11 : sorted.push_back(idx++); 81 11 : break; 82 : } 83 : 84 : // Terminate parsing on double newlines 85 56797 : if (buffer[pos] == '\n') 86 : { 87 : //cerr << "ENDDOUBLENL" << endl; 88 2606 : ends.push_back(pos); 89 2606 : sorted.push_back(idx++); 90 2606 : break; 91 : } 92 : 93 : // Mark the end of the field if it's not a continuation line 94 54191 : if (!isspace(buffer[pos])) 95 : { 96 : //cerr << "INNERFIELD" << endl; 97 34233 : ends.push_back(pos); 98 34233 : sorted.push_back(idx++); 99 : } //else 100 : //cerr << "CONTLINE" << endl; 101 : } 102 : 103 : // Sort the sorted array 104 2618 : sort(sorted.begin(), sorted.end(), rpcompare(*this)); 105 : 106 : //for (size_t i = 0; i < ends.size(); ++i) 107 : // cerr << ends[i] << "\t" << name(i) << "\t" << sorted[i] << "\t" << name(sorted[i]) << endl; 108 2618 : } 109 : 110 465183 : std::string RecordParser::field(size_t idx) const 111 : { 112 465183 : if (idx >= ends.size()) 113 2664 : return string(); 114 462519 : if (idx == 0) 115 52771 : return buffer.substr(0, ends[0]); 116 : else 117 409748 : return buffer.substr(ends[idx-1], ends[idx]-ends[idx-1]); 118 : } 119 : 120 446879 : std::string RecordParser::name(size_t idx) const 121 : { 122 446879 : string res = field(idx); 123 446879 : size_t pos = res.find(":"); 124 446879 : if (pos == string::npos) 125 1 : return res; 126 446878 : return res.substr(0, pos); 127 : } 128 : 129 18279 : std::string RecordParser::lookup(size_t idx) const 130 : { 131 18279 : string res = field(idx); 132 18279 : size_t pos = res.find(":"); 133 18279 : if (pos == string::npos) 134 2662 : return res; 135 : // Skip initial whitespace after the : 136 15617 : for (++pos; pos < res.size() && isspace(res[pos]); ++pos) 137 : ; 138 15617 : res = res.substr(pos); 139 : // Trim spaces at the end 140 46850 : while (!res.empty() && isspace(res[res.size() - 1])) 141 15616 : res.resize(res.size() - 1); 142 15617 : return res; 143 : } 144 : 145 18283 : size_t RecordParser::index(const std::string& str) const 146 : { 147 : int begin, end; 148 : 149 : /* Binary search */ 150 18283 : begin = -1, end = size(); 151 109703 : while (end - begin > 1) 152 : { 153 73137 : int cur = (end + begin) / 2; 154 : //cerr << "Test " << cur << " " << str << " < " << name(cur) << endl; 155 73137 : if (name(sorted[cur]) > str) 156 32507 : end = cur; 157 : else 158 40630 : begin = cur; 159 : } 160 : 161 18283 : if (begin == -1 || name(sorted[begin]) != str) 162 2661 : return size(); 163 : else 164 15622 : return sorted[begin]; 165 : } 166 : 167 : } 168 : } 169 : 170 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_APT_VERSION_H 2 : #define EPT_APT_VERSION_H 3 : 4 : /** \file 5 : * Representation of a package with a version 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <string> 27 : 28 : namespace ept { 29 : namespace apt { 30 : 31 : /** 32 : * Lightweight Version class that represent a package with a version, with very 33 : * cheap value copy operations. 34 : * 35 : * This class can be used to query package information from various information 36 : * sources. The purpose is create a middle ground that makes sure that all 37 : * sort of different information sources about packages are referring to the 38 : * same package. 39 : */ 40 : class Version 41 55 : { 42 : protected: 43 : std::string m_name; 44 : std::string m_version; 45 : 46 : public: 47 : /** 48 : * Create an invalid Version 49 : */ 50 7 : Version() {} 51 : 52 : /** 53 : * Create a Version from strings 54 : */ 55 34 : Version(const std::string& name, const std::string& version) 56 34 : : m_name(name), m_version(version) {} 57 : 58 : /** 59 : * Return the package name 60 : */ 61 81 : std::string name() const { return m_name; } 62 : 63 : /** 64 : * Return the package version, or the empty string if this is a 65 : * versionless package. 66 : */ 67 38 : std::string version() const { return m_version; } 68 : 69 : /** 70 : * Return the upstream part of the version 71 : */ 72 : std::string upstreamVersion() const; 73 : 74 : /** 75 : * Return true if this package contains a valid value 76 : */ 77 11 : bool isValid() const { return !m_name.empty() && !m_version.empty(); } 78 : 79 : /** 80 : * Comparison operators 81 : */ 82 9 : bool operator==(const Version& pkg) const { return m_name == pkg.m_name && m_version == pkg.m_version; } 83 5 : bool operator!=(const Version& pkg) const { return m_name != pkg.m_name || m_version != pkg.m_version; } 84 : bool operator<=(const Version& pkg) const; 85 : bool operator<(const Version& pkg) const; 86 : bool operator>=(const Version& pkg) const; 87 : bool operator>(const Version& pkg) const; 88 : }; 89 : 90 : } 91 : } 92 : 93 : // vim:set ts=4 sw=4: 94 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_APT_PACKAGERECORD_H 2 : #define EPT_APT_PACKAGERECORD_H 3 : 4 : /** \file 5 : * Parser for APT records, with specialised accessors for package records 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <ept/apt/recordparser.h> 27 : #include <set> 28 : 29 : namespace ept { 30 : namespace apt { 31 : 32 : /** 33 : * RecordParser specialised with access methods for common Debian package 34 : * information. 35 : */ 36 : class PackageRecord : public RecordParser 37 7 : { 38 1 : bool parseBool(bool& def, const std::string& str) const 39 : { 40 : // Believe it or not, this is what apt does to interpret bool fields 41 1 : if (str == "no" || str == "false" || str == "without" || 42 : str == "off" || str == "disable") 43 0 : return false; 44 : 45 1 : if (str == "yes" || str == "true" || str == "with" || 46 : str == "on" || str == "enable") 47 1 : return true; 48 : 49 0 : return def; 50 : } 51 10436 : std::string parseString(const std::string& def, const std::string& str) const 52 : { 53 10436 : if (str == std::string()) 54 0 : return def; 55 10436 : return str; 56 : } 57 : std::string parseShortDescription(const std::string& def, const std::string& str) const; 58 : std::string parseLongDescription(const std::string& def, const std::string& str) const; 59 : size_t parseSize(size_t def, const std::string& str) const; 60 : std::set<std::string> parseTags(const std::set<std::string>& def, const std::string& str) const; 61 : 62 : public: 63 6 : PackageRecord() : RecordParser() {} 64 1 : PackageRecord(const std::string& str) : RecordParser(str) {} 65 : 66 7813 : std::string package(const std::string& def = std::string()) const 67 : { 68 7813 : return parseString(def, lookup("Package")); 69 : } 70 1 : std::string priority(const std::string& def = std::string()) const 71 : { 72 1 : return parseString(def, lookup("Priority")); 73 : } 74 1 : std::string section(const std::string& def = std::string()) const 75 : { 76 1 : return parseString(def, lookup("Section")); 77 : } 78 2605 : size_t installedSize(size_t def = 0) const 79 : { 80 2605 : return parseSize(def, lookup("Installed-Size")); 81 : } 82 1 : std::string maintainer(const std::string& def = std::string()) const 83 : { 84 1 : return parseString(def, lookup("Maintainer")); 85 : } 86 1 : std::string architecture(const std::string& def = std::string()) const 87 : { 88 1 : return parseString(def, lookup("Architecture")); 89 : } 90 1 : std::string source(const std::string& def = std::string()) const 91 : { 92 1 : return parseString(def, lookup("Source")); 93 : } 94 1 : std::string version(const std::string& def = std::string()) const 95 : { 96 1 : return parseString(def, lookup("Version")); 97 : } 98 1 : std::string replaces(const std::string& def = std::string()) const 99 : { 100 1 : return parseString(def, lookup("Replaces")); 101 : } 102 1 : std::string depends(const std::string& def = std::string()) const 103 : { 104 1 : return parseString(def, lookup("Depends")); 105 : } 106 1 : std::string preDepends(const std::string& def = std::string()) const 107 : { 108 1 : return parseString(def, lookup("Pre-Depends")); 109 : } 110 1 : std::string recommends(const std::string& def = std::string()) const 111 : { 112 1 : return parseString(def, lookup("Recommends")); 113 : } 114 1 : std::string suggests(const std::string& def = std::string()) const 115 : { 116 1 : return parseString(def, lookup("Suggests")); 117 : } 118 1 : std::string enhances(const std::string& def = std::string()) const 119 : { 120 1 : return parseString(def, lookup("Enhances")); 121 : } 122 1 : std::string provides(const std::string& def = std::string()) const 123 : { 124 1 : return parseString(def, lookup("Provides")); 125 : } 126 1 : std::string conflicts(const std::string& def = std::string()) const 127 : { 128 1 : return parseString(def, lookup("Conflicts")); 129 : } 130 1 : std::string filename(const std::string& def = std::string()) const 131 : { 132 1 : return parseString(def, lookup("Filename")); 133 : } 134 2605 : size_t packageSize(size_t def = 0) const 135 : { 136 2605 : return parseSize(def, lookup("Size")); 137 : } 138 1 : std::string md5sum(const std::string& def = std::string()) const 139 : { 140 1 : return parseString(def, lookup("MD5sum")); 141 : } 142 1 : std::string sha1(const std::string& def = std::string()) const 143 : { 144 1 : return parseString(def, lookup("SHA1")); 145 : } 146 1 : std::string sha256(const std::string& def = std::string()) const 147 : { 148 1 : return parseString(def, lookup("SHA256")); 149 : } 150 2605 : std::string description(const std::string& def = std::string()) const 151 : { 152 2605 : return parseString(def, lookup("Description")); 153 : } 154 1 : std::string shortDescription(const std::string& def = std::string()) const 155 : { 156 1 : return parseShortDescription(def, lookup("Description")); 157 : } 158 1 : std::string longDescription(const std::string& def = std::string()) const 159 : { 160 1 : return parseLongDescription(def, lookup("Description")); 161 : } 162 1 : bool buildEssential(bool def = false) const 163 : { 164 1 : return parseBool(def, lookup("Build-Essential")); 165 : } 166 2605 : std::set<std::string> tag(const std::set<std::string>& def = std::set<std::string>()) const 167 : { 168 2605 : return parseTags(def, lookup("Tag")); 169 : } 170 : }; 171 : 172 : } 173 : } 174 : 175 : // vim:set ts=4 sw=4: 176 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** \file 2 : * Parser for APT records, with specialised accessors for package records 3 : */ 4 : 5 : /* 6 : * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org> 7 : * 8 : * This library is free software; you can redistribute it and/or 9 : * modify it under the terms of the GNU Lesser General Public 10 : * License as published by the Free Software Foundation; either 11 : * version 2.1 of the License, or (at your option) any later version. 12 : * 13 : * This library is distributed in the hope that it will be useful, 14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 : * Lesser General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU Lesser General Public 19 : * License along with this library; if not, write to the Free Software 20 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 : */ 22 : 23 : #include <ept/apt/packagerecord.h> 24 : 25 : #include <cctype> 26 : #include <cstdlib> 27 : 28 : //#include <iostream> 29 : 30 : using namespace std; 31 : 32 : namespace ept { 33 : namespace apt { 34 : 35 5210 : size_t PackageRecord::parseSize(size_t def, const std::string& str) const 36 : { 37 5210 : if (str == string()) 38 54 : return def; 39 5156 : return (size_t)strtoul(str.c_str(), NULL, 10); 40 : } 41 : 42 1 : std::string PackageRecord::parseShortDescription(const std::string& def, const std::string& str) const 43 : { 44 1 : if (str == std::string()) 45 0 : return def; 46 1 : size_t pos = str.find("\n"); 47 1 : if (pos == std::string::npos) 48 0 : return str; 49 : else 50 1 : return str.substr(0, pos); 51 : } 52 : 53 1 : std::string PackageRecord::parseLongDescription(const std::string& def, const std::string& str) const 54 : { 55 1 : if (str == std::string()) 56 0 : return def; 57 1 : size_t pos = str.find("\n"); 58 1 : if (pos == std::string::npos) 59 0 : return str; 60 : else 61 : { 62 : // Trim trailing spaces 63 1 : for (++pos; pos < str.size() && isspace(str[pos]); ++pos) 64 : ; 65 1 : return str.substr(pos); 66 : } 67 : } 68 : 69 2605 : std::set<std::string> PackageRecord::parseTags(const std::set<std::string>& def, const std::string& str) const 70 : { 71 2605 : if (str == string()) 72 2604 : return def; 73 : 74 1 : set<string> res; 75 : 76 1 : size_t pos = 0; 77 13 : while (pos < str.size()) 78 : { 79 12 : string tag; 80 12 : size_t i = str.find(", ", pos); 81 12 : if (i == string::npos) 82 1 : tag = str.substr(pos); 83 : else 84 11 : tag = str.substr(pos, i-pos); 85 : 86 : // Check if we need curly brace expansion 87 12 : if (tag[tag.size() - 1] == '}') 88 : { 89 1 : size_t begin = tag.find('{'); 90 1 : if (begin != string::npos) 91 : { 92 1 : string prefix(tag, 0, begin); 93 1 : ++begin; 94 : size_t end; 95 4 : while ((end = tag.find(',', begin)) != string::npos) 96 : { 97 2 : res.insert(prefix + tag.substr(begin, end-begin)); 98 2 : begin = end + 1; 99 : } 100 1 : res.insert(prefix + tag.substr(begin, tag.size() - 1 - begin)); 101 : } 102 : } else { 103 11 : res.insert(tag); 104 : } 105 : 106 12 : if (i == string::npos) 107 1 : break; 108 : else 109 11 : pos = i + 2; 110 : } 111 : 112 1 : return res; 113 : } 114 : 115 : } 116 : } 117 : 118 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
apt.cc |
|
76.8 % | 248 / 323 lines | |
apt.h |
|
50.0 % | 3 / 6 lines | |
apt.test.h |
|
100.0 % | 99 / 99 lines | |
packagerecord.cc |
|
90.9 % | 40 / 44 lines | |
packagerecord.h |
|
95.4 % | 62 / 65 lines | |
packagerecord.test.h |
|
88.5 % | 46 / 52 lines | |
recordparser.cc |
|
100.0 % | 62 / 62 lines | |
recordparser.h |
|
100.0 % | 8 / 8 lines | |
recordparser.test.h |
|
100.0 % | 107 / 107 lines | |
version.cc |
|
88.2 % | 30 / 34 lines | |
version.h |
|
100.0 % | 9 / 9 lines | |
version.test.h |
|
100.0 % | 71 / 71 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org> 3 : * 4 : * This library is free software; you can redistribute it and/or 5 : * modify it under the terms of the GNU Lesser General Public 6 : * License as published by the Free Software Foundation; either 7 : * version 2.1 of the License, or (at your option) any later version. 8 : * 9 : * This library is distributed in the hope that it will be useful, 10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : * Lesser General Public License for more details. 13 : * 14 : * You should have received a copy of the GNU Lesser General Public 15 : * License along with this library; if not, write to the Free Software 16 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : */ 18 : 19 : #include <ept/test.h> 20 : #include <ept/apt/packagerecord.h> 21 : 22 : namespace std { 23 0 : ostream& operator<<(ostream& out, const set<string>& s) 24 : { 25 0 : for (set<string>::const_iterator i = s.begin(); 26 : i != s.end(); ++i) 27 0 : if (i == s.begin()) 28 0 : out << *i; 29 : else 30 0 : out << ", " << *i; 31 0 : return out; 32 : } 33 : } 34 : 35 : using namespace std; 36 : using namespace ept; 37 : using namespace ept::apt; 38 : 39 : struct TestAptPackagerecord { 40 : 41 : // Check that the supported fields are understood 42 1 : Test supportedFields() 43 : { 44 : string record = 45 : "Package: apt\n" 46 : "Priority: important\n" 47 : "Section: admin\n" 48 : "Installed-Size: 4368\n" 49 : "Maintainer: APT Development Team <deity@lists.debian.org>\n" 50 : "Architecture: amd64\n" 51 : "Source: apt\n" 52 : "Version: 0.6.46.4-0.1\n" 53 : "Replaces: libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)\n" 54 : "Provides: libapt-pkg-libc6.3-6-3.11\n" 55 : "Depends: libc6 (>= 2.3.5-1), libgcc1 (>= 1:4.1.1-12), libstdc++6 (>= 4.1.1-12), debian-archive-keyring\n" 56 : "Pre-Depends: debtags (maybe)\n" 57 : "Suggests: aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2\n" 58 : "Recommends: debtags (maybe)\n" 59 : "Enhances: debian\n" 60 : "Conflicts: marameo\n" 61 : "Filename: pool/main/a/apt/apt_0.6.46.4-0.1_amd64.deb\n" 62 : "Size: 1436478\n" 63 : "MD5sum: 1776421f80d6300c77a608e77a9f4a15\n" 64 : "SHA1: 1bd7337d2df56d267632cf72ac930c0a4895898f\n" 65 : "SHA256: b92442ab60046b4d0728245f39cc932f26e17db9f7933a5ec9aaa63172f51fda\n" 66 : "Description: Advanced front-end for dpkg\n" 67 : " This is Debian's next generation front-end for the dpkg package manager.\n" 68 : " It provides the apt-get utility and APT dselect method that provides a\n" 69 : " simpler, safer way to install and upgrade packages.\n" 70 : " .\n" 71 : " APT features complete installation ordering, multiple source capability\n" 72 : " and several other unique features, see the Users Guide in apt-doc.\n" 73 : "Build-Essential: yes\n" 74 1 : "Tag: admin::package-management, filetransfer::ftp, filetransfer::http, hardware::storage:cd, interface::commandline, network::client, protocol::{ftp,http,ipv6}, role::program, suite::debian, use::downloading, use::searching, works-with::software:package\n"; 75 : 76 1 : PackageRecord p(record); 77 : 78 1 : assert_eq(p.size(), 24u); 79 : 80 2 : assert_eq(p.package(), "apt"); 81 1 : assert_eq(p.priority(), "important"); 82 1 : assert_eq(p.section(), "admin"); 83 1 : assert_eq(p.installedSize(), 4368u); 84 2 : assert_eq(p.maintainer(), "APT Development Team <deity@lists.debian.org>"); 85 1 : assert_eq(p.architecture(), "amd64"); 86 1 : assert_eq(p.source(), "apt"); 87 1 : assert_eq(p.version(), "0.6.46.4-0.1"); 88 1 : assert_eq(p.replaces(), "libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)"); 89 1 : assert_eq(p.provides(), "libapt-pkg-libc6.3-6-3.11"); 90 1 : assert_eq(p.depends(), "libc6 (>= 2.3.5-1), libgcc1 (>= 1:4.1.1-12), libstdc++6 (>= 4.1.1-12), debian-archive-keyring"); 91 1 : assert_eq(p.preDepends(), "debtags (maybe)"); 92 1 : assert_eq(p.recommends(), "debtags (maybe)"); 93 1 : assert_eq(p.suggests(), "aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2"); 94 1 : assert_eq(p.enhances(), "debian"); 95 1 : assert_eq(p.conflicts(), "marameo"); 96 1 : assert_eq(p.filename(), "pool/main/a/apt/apt_0.6.46.4-0.1_amd64.deb"); 97 1 : assert_eq(p.packageSize(), 1436478u); 98 2 : assert_eq(p.md5sum(), "1776421f80d6300c77a608e77a9f4a15"); 99 1 : assert_eq(p.sha1(), "1bd7337d2df56d267632cf72ac930c0a4895898f"); 100 1 : assert_eq(p.sha256(), "b92442ab60046b4d0728245f39cc932f26e17db9f7933a5ec9aaa63172f51fda"); 101 : assert_eq(p.description(), "Advanced front-end for dpkg\n" 102 : " This is Debian's next generation front-end for the dpkg package manager.\n" 103 : " It provides the apt-get utility and APT dselect method that provides a\n" 104 : " simpler, safer way to install and upgrade packages.\n" 105 : " .\n" 106 : " APT features complete installation ordering, multiple source capability\n" 107 1 : " and several other unique features, see the Users Guide in apt-doc."); 108 1 : assert_eq(p.shortDescription(), "Advanced front-end for dpkg"); 109 : assert_eq(p.longDescription(), 110 : "This is Debian's next generation front-end for the dpkg package manager.\n" 111 : " It provides the apt-get utility and APT dselect method that provides a\n" 112 : " simpler, safer way to install and upgrade packages.\n" 113 : " .\n" 114 : " APT features complete installation ordering, multiple source capability\n" 115 1 : " and several other unique features, see the Users Guide in apt-doc."); 116 1 : assert_eq(p.buildEssential(), true); 117 : 118 1 : std::set<std::string> tags; 119 1 : tags.insert("admin::package-management"); 120 2 : tags.insert("filetransfer::ftp"); 121 2 : tags.insert("filetransfer::http"); 122 2 : tags.insert("hardware::storage:cd"); 123 2 : tags.insert("interface::commandline"); 124 2 : tags.insert("network::client"); 125 2 : tags.insert("protocol::ftp"); 126 2 : tags.insert("protocol::http"); 127 2 : tags.insert("protocol::ipv6"); 128 2 : tags.insert("role::program"); 129 2 : tags.insert("suite::debian"); 130 2 : tags.insert("use::downloading"); 131 2 : tags.insert("use::searching"); 132 2 : tags.insert("works-with::software:package"); 133 2 : assert_eq(p.tag(), tags); 134 1 : } 135 : 136 : }; 137 : 138 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** \file 2 : * Provide a very lightweight Version class that represent a package with a 3 : * version, with very cheap value copy operations. 4 : */ 5 : 6 : /* 7 : * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org> 8 : * 9 : * This library is free software; you can redistribute it and/or 10 : * modify it under the terms of the GNU Lesser General Public 11 : * License as published by the Free Software Foundation; either 12 : * version 2.1 of the License, or (at your option) any later version. 13 : * 14 : * This library is distributed in the hope that it will be useful, 15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 : * Lesser General Public License for more details. 18 : * 19 : * You should have received a copy of the GNU Lesser General Public 20 : * License along with this library; if not, write to the Free Software 21 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 : */ 23 : 24 : #include <ept/apt/version.h> 25 : #include <apt-pkg/debversion.h> 26 : 27 : using namespace std; 28 : 29 : namespace ept { 30 : namespace apt { 31 : 32 4 : std::string Version::upstreamVersion() const 33 : { 34 : // Skip the epoch, if it is there 35 4 : size_t start = m_version.find(':'); 36 4 : if (start == string::npos) 37 3 : start = 0; 38 : else 39 1 : ++start; 40 : 41 : // Skip everything after the trailing '-', if it is there 42 4 : size_t end = m_version.rfind('-'); 43 4 : if (end == string::npos) 44 1 : end = m_version.size(); 45 : 46 4 : return m_version.substr(start, end-start); 47 : } 48 : 49 : /* Version comparison by Debian policy */ 50 : 51 4 : bool Version::operator<=(const Version& pkg) const 52 : { 53 4 : if (name() < pkg.name()) 54 1 : return true; 55 3 : if (name() == pkg.name()) 56 3 : return debVS.CmpVersion(version(), pkg.version()) <= 0; 57 0 : return false; 58 : } 59 5 : bool Version::operator<(const Version& pkg) const 60 : { 61 5 : if (name() < pkg.name()) 62 1 : return true; 63 4 : if (name() == pkg.name()) 64 4 : return debVS.CmpVersion(version(), pkg.version()) < 0; 65 0 : return false; 66 : } 67 4 : bool Version::operator>=(const Version& pkg) const 68 : { 69 4 : if (name() > pkg.name()) 70 0 : return true; 71 4 : if (name() == pkg.name()) 72 3 : return debVS.CmpVersion(version(), pkg.version()) >= 0; 73 1 : return false; 74 : } 75 5 : bool Version::operator>(const Version& pkg) const 76 : { 77 5 : if (name() > pkg.name()) 78 0 : return true; 79 5 : if (name() == pkg.name()) 80 4 : return debVS.CmpVersion(version(), pkg.version()) > 0; 81 1 : return false; 82 : } 83 : 84 : } 85 6 : } 86 : 87 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : #ifndef EPT_APT_APT_H 3 : #define EPT_APT_APT_H 4 : 5 : /** \file 6 : * High-level front-end to libapt-pkg, as a data provider for the ept framework. 7 : */ 8 : 9 : /* 10 : * Copyright (C) 2007,2008 Enrico Zini <enrico@enricozini.org> 11 : * 12 : * This library is free software; you can redistribute it and/or 13 : * modify it under the terms of the GNU Lesser General Public 14 : * License as published by the Free Software Foundation; either 15 : * version 2.1 of the License, or (at your option) any later version. 16 : * 17 : * This library is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 : * Lesser General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU Lesser General Public 23 : * License along with this library; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : #include <wibble/exception.h> 28 : #include <ept/apt/version.h> 29 : #include <ept/core/apt.h> 30 : 31 : #include <iterator> 32 : 33 : namespace ept { 34 : namespace apt { 35 : 36 : class Exception : public wibble::exception::Generic 37 : { 38 : protected: 39 : std::string m_message; 40 : 41 : public: 42 : Exception(const std::string& context) throw (); 43 0 : ~Exception() throw () {} 44 : 45 0 : virtual const char* type() const throw () { return "Apt"; } 46 0 : virtual std::string desc() const throw () { return m_message; } 47 : }; 48 : 49 : class Apt; 50 : class AptImplementation; 51 : class RecordIteratorImpl; 52 : using core::PackageState; 53 : 54 : /** 55 : * High-level access to the Apt cache, as a data provider for the ept 56 : * framework. 57 : * 58 : * This class wraps the Apt cache and allows to query it in various ways. 59 : */ 60 : class Apt 61 : { 62 : protected: 63 : AptImplementation* impl; 64 : 65 : public: 66 : // Iterate Packages in the Apt cache 67 : class Iterator : public std::iterator<std::input_iterator_tag, std::string, void, void, void> 68 : { 69 : void* cur; 70 : 71 : protected: 72 : // Construct a valid iterator 73 4 : Iterator(void* cur) : cur(cur) {} 74 : 75 : // Construct and end iterator 76 3581 : Iterator() : cur(0) {} 77 : 78 : public: 79 : // Copy constructor 80 : Iterator(const Iterator&); 81 : ~Iterator(); 82 : std::string operator*(); 83 : Iterator& operator++(); 84 : Iterator& operator=(const Iterator&); 85 : bool operator==(const Iterator&) const; 86 : bool operator!=(const Iterator&) const; 87 : 88 : // FIXME: Iterator operator++(int); cannot be easily implemented 89 : // because of how Apt's pkgIterator works 90 : 91 : friend class Apt; 92 : }; 93 : 94 : // Iterate Package records in the Apt cache 95 : class RecordIterator : public std::iterator<std::input_iterator_tag, std::string, void, void, void> 96 : { 97 : RecordIteratorImpl* impl; 98 : size_t pos; 99 : std::string cur; 100 : size_t cur_pos; 101 : 102 : protected: 103 : // Construct a valid iterator 104 : RecordIterator(RecordIteratorImpl* cur, size_t pos = 0); 105 : 106 : // Construct and end iterator 107 3481 : RecordIterator() : impl(0), pos(0), cur_pos(0) {} 108 : 109 : public: 110 : // Copy constructor 111 : RecordIterator(const RecordIterator& r); 112 : 113 : ~RecordIterator(); 114 : std::string operator*(); 115 : std::string* operator->(); 116 : RecordIterator& operator++(); 117 : RecordIterator& operator=(const RecordIterator& r); 118 : bool operator==(const RecordIterator&) const; 119 : bool operator!=(const RecordIterator&) const; 120 : 121 : // FIXME: Iterator operator++(int); cannot be easily implemented 122 : // because of how Apt's pkgIterator works 123 : 124 : friend class Apt; 125 : }; 126 : 127 : typedef Iterator iterator; 128 : typedef RecordIterator record_iterator; 129 : 130 : /** 131 : * Create the Apt data provider 132 : */ 133 : Apt(); 134 : ~Apt(); 135 : 136 : iterator begin() const; 137 : iterator end() const; 138 : 139 : record_iterator recordBegin() const; 140 : record_iterator recordEnd() const; 141 : 142 : 143 : /// Return the number of packages in the archive 144 : size_t size() const; 145 : 146 : /** 147 : * Validate a package name, returning trye if it exists in the APT database, 148 : * or false if it does not. 149 : */ 150 : bool isValid(const std::string& pkg) const; 151 : 152 : /// Validate a package name, returning it if it exists in the APT database, 153 : /// or returning the empty string if it does not. 154 : std::string validate(const std::string& pkg) const 155 : { 156 : if (isValid(pkg)) 157 : return pkg; 158 : return std::string(); 159 : } 160 : 161 : /// Validate a Version, returning it if it exists in the APT database, or 162 : /// returning the invalid version if it does not. 163 : Version validate(const Version& ver) const; 164 : 165 : /// Return the installed version for a package 166 : Version installedVersion(const std::string& pkg) const; 167 : 168 : /// Return the candidate version for a package 169 : Version candidateVersion(const std::string& pkg) const; 170 : 171 : /** 172 : * Return the candidate version for a package, if available, or the 173 : * installed version otherwise 174 : */ 175 : Version anyVersion(const std::string& pkg) const; 176 : 177 : /// Return state information on a package 178 : PackageState state(const std::string& pkg) const; 179 : 180 : /** 181 : * Perform a package search. 182 : * 183 : * All packages for which the functor filter returns true, are passed to 184 : * the functor out. 185 : */ 186 : //template<typename FILTER, typename OUT> 187 : //void search(const FILTER& filter, OUT& out); 188 : 189 : /// Get the raw package record for the given Version 190 : std::string rawRecord(const std::string& pkg) const; 191 : 192 : /// Get the raw package record for the given Version 193 : std::string rawRecord(const Version& ver) const; 194 : 195 : /// Timestamp of when the apt index was last modified 196 : time_t timestamp(); 197 : 198 : /** 199 : * Check if the cache has been changed by another process, and reopen it if 200 : * that is the case. 201 : * 202 : * Note that this method can invalidate all existing iterators. 203 : */ 204 : void checkCacheUpdates(); 205 : 206 : /** 207 : * Invalidate the cache timestamp used to track cache updates. 208 : * 209 : * @warning Do not use this method: it is here only to support the test 210 : * cases, and may disappear in any future version. 211 : */ 212 : void invalidateTimestamp(); 213 : }; 214 : 215 : } 216 : } 217 : 218 : // vim:set ts=4 sw=4: 219 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org> 3 : * 4 : * This library is free software; you can redistribute it and/or 5 : * modify it under the terms of the GNU Lesser General Public 6 : * License as published by the Free Software Foundation; either 7 : * version 2.1 of the License, or (at your option) any later version. 8 : * 9 : * This library is distributed in the hope that it will be useful, 10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : * Lesser General Public License for more details. 13 : * 14 : * You should have received a copy of the GNU Lesser General Public 15 : * License along with this library; if not, write to the Free Software 16 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : */ 18 : 19 : #include <ept/test.h> 20 : #include <ept/apt/version.h> 21 : 22 : using namespace std; 23 : using namespace ept::apt; 24 : 25 : struct TestAptVersion { 26 : 27 : // Basic test for invalid version 28 1 : Test invalid() 29 : { 30 1 : Version test; 31 : 32 1 : assert_eq(test.name(), ""); 33 1 : assert_eq(test.version(), ""); 34 1 : assert_eq(test.isValid(), false); 35 : 36 1 : string p = test.name(); 37 : 38 1 : assert_eq(p, string()); 39 1 : } 40 : 41 : // Basic test for version 42 1 : Test basic() 43 : { 44 1 : Version test("test", "1.0"); 45 : 46 2 : assert_eq(test.name(), "test"); 47 1 : assert_eq(test.version(), "1.0"); 48 1 : assert_eq(test.isValid(), true); 49 : 50 1 : string p = test.name(); 51 : 52 1 : assert_eq(p, "test"); 53 : 54 1 : Version v(p, "1.1"); 55 2 : assert_eq(v.name(), "test"); 56 1 : assert_eq(v.version(), "1.1"); 57 1 : assert_eq(v.isValid(), true); 58 1 : } 59 : 60 : // Comparison semanthics 61 1 : Test comparison() 62 : { 63 1 : Version test("test", "1.0"); 64 2 : Version test1("test", "1.0"); 65 : 66 2 : assert(test == test1); 67 2 : assert(! (test != test1)); 68 2 : assert(! (test < test1)); 69 2 : assert(! (test > test1)); 70 2 : assert(test <= test1); 71 2 : assert(test >= test1); 72 : 73 : 74 2 : Version test2("test2", "1.0"); 75 : 76 2 : assert(test != test2); 77 2 : assert(test != test2); 78 2 : assert(test < test2); 79 2 : assert(! (test > test2)); 80 2 : assert(test <= test2); 81 2 : assert(! (test >= test2)); 82 : 83 : 84 2 : Version test3("test", "2.0"); 85 : 86 2 : assert(test != test3); 87 2 : assert(test != test3); 88 2 : assert(test < test3); 89 2 : assert(! (test > test3)); 90 2 : assert(test <= test3); 91 2 : assert(! (test >= test3)); 92 1 : } 93 : 94 : // Value-copy semanthics 95 1 : Test valueCopy() 96 : { 97 1 : Version test("test", "1.0"); 98 1 : Version test1 = test; 99 : 100 1 : assert(test == test1); 101 : 102 1 : Version test2; 103 1 : test2 = test; 104 1 : assert(test == test2); 105 2 : assert(test1 == test2); 106 : 107 2 : Version test3("test", "1.0"); 108 2 : assert(test == test3); 109 2 : assert(test1 == test3); 110 2 : assert(test2 == test3); 111 1 : } 112 : 113 : // Extraction of upstream version 114 1 : Test upstreamVersion() 115 : { 116 1 : assert_eq(Version("a", "10.0").upstreamVersion(), "10.0"); 117 2 : assert_eq(Version("a", "10.0-1").upstreamVersion(), "10.0"); 118 2 : assert_eq(Version("a", "10.0~foo.1-1.0").upstreamVersion(), "10.0~foo.1"); 119 2 : assert_eq(Version("a", "1.0:10.0~foo.1-1.0").upstreamVersion(), "10.0~foo.1"); 120 1 : } 121 : 122 : // Debian policy comparison semanthics 123 1 : Test policyComparison() 124 : { 125 1 : assert(Version("a", "10.0") > Version("a", "2.1")); 126 2 : assert(Version("a", "1:10.0") < Version("a", "2:2.1")); 127 2 : assert(Version("a", "10.0-1") < Version("a", "10.0-2")); 128 2 : assert(Version("a", "10.0-2") > Version("a", "10.0-1")); 129 2 : assert(Version("a", "1:10.0-1") <= Version("a", "1:10.0-1")); 130 2 : assert(Version("a", "1:10.0-1") >= Version("a", "1:10.0-1")); 131 : // TODO: add more 132 1 : } 133 : 134 : }; 135 : 136 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Copyright (C) 2007 Enrico Zini <enrico@enricozini.org> 3 : * 4 : * This library is free software; you can redistribute it and/or 5 : * modify it under the terms of the GNU Lesser General Public 6 : * License as published by the Free Software Foundation; either 7 : * version 2.1 of the License, or (at your option) any later version. 8 : * 9 : * This library is distributed in the hope that it will be useful, 10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : * Lesser General Public License for more details. 13 : * 14 : * You should have received a copy of the GNU Lesser General Public 15 : * License along with this library; if not, write to the Free Software 16 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : */ 18 : 19 : #include <ept/test.h> 20 : #include <ept/apt/apt.h> 21 : #include <set> 22 : #include <algorithm> 23 : 24 : using namespace std; 25 : using namespace ept; 26 : using namespace ept::apt; 27 : 28 26 : struct TestApt : AptTestEnvironment { 29 : Apt apt; 30 : 31 : // Check that iterations iterates among some packages 32 1 : Test iterators() 33 : { 34 1 : Apt::iterator i = apt.begin(); 35 1 : assert(i != apt.end()); 36 : 37 1 : size_t count = 0; 38 1789 : for (; i != apt.end(); ++i) 39 1788 : ++count; 40 : 41 1 : assert(count > 100); 42 1 : } 43 : 44 : // Check that iteration gives some well-known packages 45 1 : Test aptExists() 46 : { 47 1 : set<string> packages; 48 : 49 1 : std::copy(apt.begin(), apt.end(), inserter(packages, packages.begin())); 50 : 51 1 : assert(packages.find("libsp1") != packages.end()); 52 : // TODO this exposes a bug somewhere... sp definitely is among 53 : // the packages 54 : // assert(packages.find("sp") != packages.end()); 55 2 : assert(packages.find("") == packages.end()); 56 1 : } 57 : 58 : // Check that timestamp gives some meaningful timestamp 59 1 : Test timestamp() 60 : { 61 1 : time_t ts = apt.timestamp(); 62 1 : assert(ts > 1000000); 63 1 : } 64 : 65 : // Check the package validator 66 1 : Test validity() 67 : { 68 1 : assert(apt.isValid("apt")); 69 2 : assert(!apt.isValid("this-package-does-not-really-exists")); 70 1 : } 71 : 72 : // Check the version instantiators 73 1 : Test versions() 74 : { 75 1 : std::string pkg("apt"); 76 1 : Version ver = apt.candidateVersion(pkg); 77 1 : assert(ver.isValid()); 78 : 79 2 : ver = apt.installedVersion(pkg); 80 1 : assert(ver.isValid()); 81 : 82 2 : ver = apt.anyVersion(pkg); 83 1 : assert(ver.isValid()); 84 : 85 2 : std::string pkg1("this-package-does-not-really-exists"); 86 2 : ver = apt.candidateVersion(pkg1); 87 1 : assert(!ver.isValid()); 88 : 89 2 : ver = apt.installedVersion(pkg1); 90 1 : assert(!ver.isValid()); 91 : 92 2 : ver = apt.anyVersion(pkg1); 93 1 : assert(!ver.isValid()); 94 1 : } 95 : 96 : // Check the version validator 97 1 : Test versionValidity() 98 : { 99 1 : Version ver = apt.candidateVersion("apt"); 100 2 : assert(apt.validate(ver) == ver); 101 : 102 1 : ver = Version("this-package-does-not-really-exists", "0.1"); 103 2 : assert(!apt.validate(ver).isValid()); 104 : 105 1 : ver = Version("apt", "0.31415"); 106 2 : assert(!apt.validate(ver).isValid()); 107 1 : } 108 : 109 : // Check the raw record accessor 110 1 : Test rawRecord() 111 : { 112 1 : string pkg("sp"); 113 1 : Version ver = apt.candidateVersion(pkg); 114 1 : assert(apt.validate(ver) == ver); 115 : 116 1 : string record = apt.rawRecord(ver); 117 1 : assert(record.find("Package: sp") != string::npos); 118 2 : assert(record.find("Section: text") != string::npos); 119 : 120 2 : record = apt.rawRecord(Version("sp", "0.31415")); 121 2 : assert_eq(record, string()); 122 : 123 1 : assert_eq(apt.rawRecord(pkg), apt.rawRecord(apt.anyVersion(pkg))); 124 1 : } 125 : 126 : // Check the package state accessor 127 1 : Test state() 128 : { 129 1 : PackageState s = apt.state("kdenetwork"); 130 2 : assert(s.isValid()); 131 2 : assert(s.isInstalled()); 132 : 133 2 : s = apt.state("this-package-does-not-really-exists"); 134 2 : assert(!s.isValid()); 135 1 : } 136 : 137 : // Check the record iterator (accessing with *) 138 1 : Test recordIteration() 139 : { 140 1 : size_t count = 0; 141 435 : for (Apt::record_iterator i = apt.recordBegin(); 142 : i != apt.recordEnd(); ++i) 143 : { 144 434 : assert((*i).size() > 8); 145 434 : assert_eq((*i).substr(0, 8), "Package:"); 146 434 : ++count; 147 1 : } 148 2 : assert(count > 200); 149 1 : } 150 : 151 : // Check the record iterator (accessing with ->) 152 1 : Test recordIteration2() 153 : { 154 1 : size_t count = 0; 155 435 : for (Apt::record_iterator i = apt.recordBegin(); 156 : i != apt.recordEnd(); ++i) 157 : { 158 434 : assert(i->size() > 8); 159 868 : assert_eq(i->substr(0, 8), "Package:"); 160 434 : ++count; 161 1 : } 162 2 : assert(count > 200); 163 1 : } 164 : 165 : // Check that the iterators can be used with the algorithms 166 1 : Test stlIteration() 167 : { 168 1 : vector<string> out; 169 1 : std::copy(apt.begin(), apt.end(), back_inserter(out)); 170 1 : } 171 : 172 : // Check that the iterators can be used with the algorithms 173 1 : Test stlRecordIteration() 174 : { 175 1 : vector<string> out; 176 1 : std::copy(apt.recordBegin(), apt.recordEnd(), back_inserter(out)); 177 1 : } 178 : 179 : // Check that checkUpdates will keep a working Apt object 180 1 : Test checkUpdates() 181 : { 182 1 : assert(apt.isValid("apt")); 183 1 : apt.checkCacheUpdates(); 184 2 : assert(apt.isValid("apt")); 185 1 : apt.invalidateTimestamp(); 186 1 : apt.checkCacheUpdates(); 187 2 : assert(apt.isValid("apt")); 188 1 : } 189 : 190 : }; 191 : 192 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*- 2 : /* 3 : * popcon test 4 : * 5 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org> 6 : * 7 : * This program is free software; you can redistribute it and/or modify 8 : * it under the terms of the GNU General Public License as published by 9 : * the Free Software Foundation; either version 2 of the License, or 10 : * (at your option) any later version. 11 : * 12 : * This program is distributed in the hope that it will be useful, 13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : * GNU General Public License for more details. 16 : * 17 : * You should have received a copy of the GNU General Public License 18 : * along with this program; if not, write to the Free Software 19 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 : */ 21 : 22 : #include <ept/test.h> 23 : #include <ept/textsearch/textsearch.h> 24 : #include <ept/textsearch/maint/path.h> 25 : #include <ept/apt/apt.h> 26 : #include <wibble/sys/fs.h> 27 : #include <set> 28 : 29 : namespace ept { 30 : namespace textsearch { 31 : extern size_t max_index; 32 : } 33 : } 34 : 35 : using namespace std; 36 : using namespace ept; 37 : using namespace ept::textsearch; 38 : using namespace ept::apt; 39 : 40 : struct DirMaker 41 : { 42 6 : DirMaker(const std::string& name) 43 : { 44 6 : wibble::sys::fs::mkdirIfMissing(name, 0755); 45 6 : } 46 : }; 47 : 48 : struct TestTextsearch : AptTestEnvironment 49 6 : { 50 : DirMaker md; 51 : Path::OverrideIndexDir oid; 52 : Apt apt; 53 : TextSearch textsearch; 54 : 55 6 : TestTextsearch() 56 6 : : md( TEST_ENV_DIR "xapian"), oid( TEST_ENV_DIR "xapian") 57 : { 58 : try { 59 6 : ept::textsearch::max_index = 1000; 60 6 : textsearch.rebuildIfNeeded(apt); 61 0 : } catch (Xapian::Error& e) { 62 0 : cerr << e.get_type() << " " << e.get_msg() << " " << e.get_context() << endl; 63 0 : throw; 64 : } 65 6 : } 66 : 67 : // Access an empty index 68 1 : Test empty() 69 : { 70 1 : Path::OverrideIndexDir oid("./empty"); 71 1 : TextSearch empty; 72 1 : assert_eq(empty.timestamp(), 0); 73 2 : assert(!empty.hasData()); 74 2 : assert(empty.needsRebuild(apt)); 75 : /* 76 : Xapian::Enquire enq(empty.db()); 77 : empty.search(enq, "apt"); 78 : Xapian::MSet matches = enq.get_mset(0, 100); 79 : assert_eq(matches.size(), 0u); 80 : */ 81 1 : } 82 : 83 : // Very basic access 84 1 : Test basicAccess() 85 : { 86 1 : assert(textsearch.hasData()); 87 2 : assert(textsearch.timestamp() > 0); 88 2 : assert(!textsearch.needsRebuild(apt)); 89 : 90 1 : Xapian::Enquire enq(textsearch.db()); 91 2 : enq.set_query(textsearch.makeORQuery("sgml")); 92 1 : Xapian::MSet matches = enq.get_mset(0, 100); 93 1 : assert(matches.size() > 0); 94 : 95 : // See if the apt package is among the results 96 1 : set<string> results; 97 10 : for (Xapian::MSetIterator i = matches.begin(); i != matches.end(); ++i) 98 10 : results.insert(i.get_document().get_data()); 99 1 : assert(results.find("sp") != results.end()); 100 1 : } 101 : 102 : // Alternate access using intermediate Xapian::Query objects 103 1 : Test queryAccess() 104 : { 105 1 : Xapian::Enquire enq(textsearch.db()); 106 1 : enq.set_query(textsearch.makeORQuery("sgml")); 107 1 : Xapian::MSet matches = enq.get_mset(0, 100); 108 1 : assert(matches.size() > 0); 109 : 110 : // See if the apt package is among the results 111 1 : set<string> results; 112 10 : for (Xapian::MSetIterator i = matches.begin(); i != matches.end(); ++i) 113 10 : results.insert(i.get_document().get_data()); 114 1 : assert(results.find("sp") != results.end()); 115 1 : } 116 : 117 : // Try makePartialORQuery 118 1 : Test partialOrQuery() 119 : { 120 1 : Xapian::Enquire enq(textsearch.db()); 121 1 : enq.set_query(textsearch.makePartialORQuery("sgml")); 122 1 : Xapian::MSet matches = enq.get_mset(0, 100); 123 1 : assert(matches.size() > 0); 124 : 125 : // See if the apt package is among the results 126 1 : set<string> results; 127 10 : for (Xapian::MSetIterator i = matches.begin(); i != matches.end(); ++i) 128 10 : results.insert(i.get_document().get_data()); 129 1 : assert(results.find("sp") != results.end()); 130 1 : } 131 : 132 : // Try docidByName 133 1 : Test docidByName() 134 : { 135 1 : assert(textsearch.docidByName("sp") != 0); 136 2 : assert_eq(textsearch.docidByName("thereisnopackagewiththisname"), 0u); 137 1 : } 138 : 139 : // Access values 140 1 : Test values() 141 : { 142 1 : assert(textsearch.hasData()); 143 2 : assert(textsearch.timestamp() > 0); 144 2 : assert(!textsearch.needsRebuild(apt)); 145 : 146 : double dval; 147 2 : dval = textsearch.getDoubleValue("autoconf", VAL_APT_INSTALLED_SIZE); 148 2 : assert(dval == 2408); 149 2 : dval = textsearch.getDoubleValue("autoconf", VAL_APT_PACKAGE_SIZE); 150 2 : assert(dval == 741486); 151 2 : assert_eq(textsearch.getDoubleValue("thereisnopackagewiththisname", VAL_APT_INSTALLED_SIZE), 0.0); 152 2 : assert_eq(textsearch.getDoubleValue("thereisnopackagewiththisname", VAL_APT_PACKAGE_SIZE), 0.0); 153 : 154 : int val; 155 2 : val = textsearch.getIntValue("autoconf", VAL_APT_INSTALLED_SIZE); 156 2 : assert(val == 2408); 157 2 : val = textsearch.getIntValue("autoconf", VAL_APT_PACKAGE_SIZE); 158 2 : assert(val == 741486); 159 1 : cout << val; 160 2 : assert_eq(textsearch.getIntValue("thereisnopackagewiththisname", VAL_APT_INSTALLED_SIZE), 0); 161 2 : assert_eq(textsearch.getIntValue("thereisnopackagewiththisname", VAL_APT_PACKAGE_SIZE), 0); 162 1 : } 163 : 164 : }; 165 : 166 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
extraindexers.cc |
|
0.0 % | 0 / 10 lines | |
extraindexers.h |
|
0.0 % | 0 / 2 lines | |
textsearch.cc |
|
72.2 % | 83 / 115 lines | |
textsearch.h |
|
86.7 % | 13 / 15 lines | |
textsearch.test.h |
|
95.9 % | 71 / 74 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : 2 : /** @file 3 : * @author Enrico Zini <enrico@enricozini.org> 4 : * Fast full-text search 5 : */ 6 : 7 : /* 8 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org> 9 : * 10 : * This program is free software; you can redistribute it and/or modify 11 : * it under the terms of the GNU General Public License as published by 12 : * the Free Software Foundation; either version 2 of the License, or 13 : * (at your option) any later version. 14 : * 15 : * This program is distributed in the hope that it will be useful, 16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 : * GNU General Public License for more details. 19 : * 20 : * You should have received a copy of the GNU General Public License 21 : * along with this program; if not, write to the Free Software 22 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 : */ 24 : 25 : #include <ept/textsearch/extraindexers.h> 26 : #include <ept/apt/packagerecord.h> 27 : #include <ept/debtags/debtags.h> 28 : 29 : using namespace std; 30 : using namespace ept::debtags; 31 : 32 : namespace ept { 33 : namespace textsearch { 34 : 35 0 : void AptTagsExtraIndexer::operator()(Xapian::Document& doc, const apt::PackageRecord& rec) const 36 : { 37 : // Index tags as well 38 0 : set<string> tags = rec.tag(); 39 0 : for (set<string>::const_iterator ti = tags.begin(); 40 : ti != tags.end(); ++ti) 41 0 : doc.add_term("XT"+*ti); 42 0 : } 43 : 44 0 : void DebtagsExtraIndexer::operator()(Xapian::Document& doc, const apt::PackageRecord& rec) const 45 : { 46 : // Index tags as well 47 0 : set<Tag> tags = debtags.getTagsOfItem(doc.get_data()); 48 0 : for (set<Tag>::const_iterator ti = tags.begin(); 49 : ti != tags.end(); ++ti) 50 0 : doc.add_term("XT"+ti->fullname()); 51 0 : } 52 : 53 : } 54 : } 55 : 56 : #include <ept/debtags/debtags.tcc> 57 : 58 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; indent-tabs-mode: t -*- 2 : 3 : /** \file 4 : * popcon paths 5 : */ 6 : 7 : /* 8 : * Copyright (C) 2005,2006,2007 Enrico Zini <enrico@debian.org>, Peter Rockai <me@mornfall.net> 9 : * 10 : * This program is free software; you can redistribute it and/or modify 11 : * it under the terms of the GNU General Public License as published by 12 : * the Free Software Foundation; either version 2 of the License, or 13 : * (at your option) any later version. 14 : * 15 : * This program is distributed in the hope that it will be useful, 16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 : * GNU General Public License for more details. 19 : * 20 : * You should have received a copy of the GNU General Public License 21 : * along with this program; if not, write to the Free Software 22 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 : */ 24 : 25 : #include <ept/config.h> 26 : #include <ept/textsearch/maint/path.h> 27 : 28 : #include <wibble/exception.h> 29 : #include <wibble/sys/fs.h> 30 : #include <wibble/string.h> 31 : 32 : #include <cstdio> 33 : #include <cerrno> 34 : 35 : #include <sys/types.h> 36 : #include <sys/stat.h> 37 : #include <unistd.h> 38 : 39 : using namespace std; 40 : using namespace wibble; 41 : 42 : namespace ept { 43 : namespace textsearch { 44 : 45 111 : Path &Path::instance() { 46 111 : if (!s_instance) { 47 1 : s_instance = new Path; 48 1 : instance().m_indexDir = TEXTSEARCH_DB_DIR; 49 : } 50 111 : return *s_instance; 51 : } 52 : 53 0 : int Path::access( const std::string &s, int m ) 54 : { 55 0 : return ::access( s.c_str(), m ); 56 : } 57 : 58 20 : time_t Path::indexTimestamp() 59 : { 60 20 : string tsfile = str::joinpath(instance().indexDir(), "update-timestamp"); 61 40 : std::auto_ptr<struct stat> st = wibble::sys::fs::stat(tsfile); 62 20 : if (st.get()) 63 18 : return st->st_mtime; 64 : else 65 2 : return 0; 66 : } 67 : 68 6 : void Path::setTimestamp(time_t ts) 69 : { 70 6 : string tsfile = str::joinpath(instance().indexDir(), "/update-timestamp"); 71 12 : FILE* out = fopen(tsfile.c_str(), "wt"); 72 6 : if (!out) 73 0 : throw wibble::exception::File(tsfile, "opening file for truncate/writing"); 74 6 : if (fprintf(out, "%ld\n", ts) < 0) 75 0 : throw wibble::exception::File(tsfile, "writing the modification time"); 76 6 : if (fclose(out) < 0) 77 0 : throw wibble::exception::File(tsfile, "closing the file"); 78 6 : } 79 : 80 22 : void Path::setIndexDir( const std::string &s ) 81 : { 82 22 : instance().m_indexDir = s; 83 22 : } 84 : 85 37 : std::string Path::indexDir() { return instance().m_indexDir; } 86 25 : std::string Path::index() { return str::joinpath(instance().m_indexDir, "/index"); } 87 : 88 : Path *Path::s_instance = 0; 89 : 90 : } 91 6 : } 92 : 93 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
path.cc |
|
82.8 % | 24 / 29 lines | |
path.h |
|
100.0 % | 5 / 5 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; indent-tabs-mode: t -*- 2 : /** \file 3 : * popcon paths 4 : */ 5 : 6 : /* 7 : * Copyright (C) 2005,2006,2007 Enrico Zini <enrico@debian.org> 8 : * 9 : * This program is free software; you can redistribute it and/or modify 10 : * it under the terms of the GNU General Public License as published by 11 : * the Free Software Foundation; either version 2 of the License, or 12 : * (at your option) any later version. 13 : * 14 : * This program is distributed in the hope that it will be useful, 15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : * GNU General Public License for more details. 18 : * 19 : * You should have received a copy of the GNU General Public License 20 : * along with this program; if not, write to the Free Software 21 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 : */ 23 : 24 : #ifndef EPT_TEXTSEARCH_PATH_H 25 : #define EPT_TEXTSEARCH_PATH_H 26 : 27 : #include <string> 28 : 29 : struct stat; 30 : 31 : namespace ept { 32 : namespace textsearch { 33 : 34 : /** 35 : * Singleton class to configure and access the various Popcon paths 36 : */ 37 : class Path 38 1 : { 39 : public: 40 : static std::string indexDir(); 41 : static std::string index(); 42 : 43 : // Directory where Popcon source data is found 44 : static void setIndexDir( const std::string &s ); 45 : 46 : static int access( const std::string &, int ); 47 : static time_t indexTimestamp(); 48 : static void setTimestamp(time_t ts); 49 : 50 : // RAII-style classes to temporarily override directories 51 : class OverrideIndexDir 52 : { 53 : std::string old; 54 : public: 55 11 : OverrideIndexDir(const std::string& path) : old(Path::indexDir()) 56 : { 57 11 : Path::setIndexDir(path); 58 11 : } 59 11 : ~OverrideIndexDir() { Path::setIndexDir(old); } 60 : }; 61 : 62 : protected: 63 : static Path *s_instance; 64 : static Path &instance(); 65 : 66 : // Directory where Popcon source data is found 67 : std::string m_indexDir; 68 : }; 69 : 70 : } 71 : } 72 : 73 : // vim:set ts=4 sw=4: 74 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_TEXTSEARCH_TEXTSEARCH_H 2 : #define EPT_TEXTSEARCH_TEXTSEARCH_H 3 : 4 : /** @file 5 : * @author Enrico Zini <enrico@enricozini.org> 6 : * Fast full-text search 7 : */ 8 : 9 : /* 10 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org> 11 : * 12 : * This program is free software; you can redistribute it and/or modify 13 : * it under the terms of the GNU General Public License as published by 14 : * the Free Software Foundation; either version 2 of the License, or 15 : * (at your option) any later version. 16 : * 17 : * This program is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 : * GNU General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU General Public License 23 : * along with this program; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : #include <xapian.h> 28 : #include <vector> 29 : #include <string> 30 : 31 : namespace ept { 32 : namespace apt { 33 : class Apt; 34 : class PackageRecord; 35 : } 36 : namespace debtags { 37 : class Debtags; 38 : } 39 : namespace textsearch { 40 : 41 : // Allocate value indexes for known values 42 : const Xapian::valueno VAL_APT_INSTALLED_SIZE = 1; 43 : const Xapian::valueno VAL_APT_PACKAGE_SIZE = 2; 44 : const Xapian::valueno VAL_POPCON = 10; 45 : const Xapian::valueno VAL_ITERATING_RATING = 20; 46 : const Xapian::valueno VAL_ITERATING_FUNCTIONALITY = 21; 47 : const Xapian::valueno VAL_ITERATING_USABILITY = 22; 48 : const Xapian::valueno VAL_ITERATING_SECURITY = 23; 49 : const Xapian::valueno VAL_ITERATING_PERFORMANCE = 24; 50 : const Xapian::valueno VAL_ITERATING_QUALITY = 25; 51 : const Xapian::valueno VAL_ITERATING_SUPPORT = 26; 52 : const Xapian::valueno VAL_ITERATING_ADOPTION = 27; 53 : // If you need to index a value and cannot edit this file, feel free to use any 54 : // value starting from 1000000 55 : 56 : 57 : /* 58 : Fallback on apt scan searches when index is not present 59 : 60 : Explicitly decide at instantiation (or at any other time) if a rebuild should 61 : be performed. Just adding a 'rebuildIfNeeded' method would be enough. 62 : 63 : 17:14 #xapian < enrico> Hello. I'm finally in a position of writing a library to maintain 64 : a xapian index with Debian package descriptions in a Debian system 65 : 17:14 #xapian < enrico> I have a question, though 66 : 17:14 #xapian < enrico> The descriptions change regularly as people run 'apt-get update' 67 : 17:15 #xapian < enrico> I'd need to have a way to update the description index after 68 : apt-get update, without rebuilding it from scratch 69 : 17:15 #xapian < enrico> Is there some documentation on how to do that? I can't exactly 70 : tell Xapian "the new description for package foo is this" because 71 : I'd need the xapian id 72 : 19:11 #xapian < omega> you can add a unique term with a boolean prefix? 73 : 19:11 #xapian < omega> like Qpackage-name 74 : 19:11 #xapian < omega> then you search for it and replace_document 75 : 19:24 #xapian < richardb> Or indeed, you use the "replace_document()" form which takes a 76 : unique_id term. 77 : 19:25 #xapian < richardb> Xapian::docid replace_document(const std::string & 78 : unique_term, 79 : 19:25 #xapian < richardb> const Xapian::Document & 80 : document); 81 : 19:43 #xapian < enrico> unique term 82 : 19:43 #xapian < enrico> nice! 83 : 19:44 #xapian < enrico> can I use a non-alpha prefix, like :package-name ? 84 : 19:45 #xapian < enrico> or pkg:package-name 85 : 19:45 #xapian < enrico> I suppose I can 86 : */ 87 : 88 : /** 89 : * Maintains and accesses a Xapian index of package descriptions. 90 : * 91 : * Contrarily to Debtags and Popcon, TextSearch does not attempt to create the 92 : * index in the home directory if no system index is found and it is not 93 : * running as root: this is to avoid secretly building large indexes (>50Mb) 94 : * in the home directory of users. 95 : * 96 : * The idea then is to have root keep the index up to date, possibly running a 97 : * reindexing tool once a day, or after an apt-get update. 98 : * 99 : * This works because the full text search index is useful even if it is 100 : * slightly out of date. 101 : */ 102 : class TextSearch 103 11 : { 104 : protected: 105 : time_t m_timestamp; 106 : Xapian::Database m_db; 107 : Xapian::Stem m_stem; 108 : 109 : /// Return a lowercased copy of the string 110 : static std::string toLower(const std::string& str); 111 : 112 : /** 113 : * Add normalised tokens computed from the string to the document doc. 114 : * 115 : * pos is used as a sequence generator for entering the token position in 116 : * the document. 117 : */ 118 : void normalize_and_add(Xapian::Document& doc, const std::string& term, int& pos) const; 119 : 120 : public: 121 : struct ExtraIndexer 122 : { 123 0 : virtual ~ExtraIndexer() {} 124 : virtual void operator()(Xapian::Document& doc, const apt::PackageRecord& rec) const = 0; 125 : }; 126 : 127 : TextSearch(); 128 : 129 : /// Access the Xapian database 130 3 : Xapian::Database& db() { return m_db; } 131 : 132 : /// Access the Xapian database 133 4 : const Xapian::Database& db() const { return m_db; } 134 : 135 : /// Timestamp of when the Xapian database was last updated 136 3 : time_t timestamp() const { return m_timestamp; } 137 : 138 : /// Returns true if the index has data 139 3 : bool hasData() const { return m_timestamp > 0; } 140 : 141 : /// Returns true if the index is older than the Apt database information 142 : bool needsRebuild(apt::Apt& apt); 143 : 144 : /** 145 : * Rebuild the index if needed. 146 : * 147 : * Allow to specify functors that contribute to the indexing. 148 : * 149 : * @note This requires write access to the index directory. 150 : * @note This is not the main way to update the index: it is provided here 151 : * only as a way to build a draft index for the library tests 152 : */ 153 : bool rebuildIfNeeded( 154 : apt::Apt& apt, 155 : const std::vector<const ExtraIndexer*>& extraIndexers = std::vector<const ExtraIndexer*>()); 156 : 157 : /** 158 : * Retrieve a Xapian docid by package name 159 : */ 160 : Xapian::docid docidByName(const std::string& pkgname) const; 161 : 162 : /** 163 : * Tokenize the string and build an OR query with the resulting keywords 164 : */ 165 : Xapian::Query makeORQuery(const std::string& keywords) const; 166 : 167 : /** 168 : * Tokenize the string and build an OR query with the resulting keywords. 169 : * 170 : * The last token in keywords is considered to be typed only partially, to 171 : * implement proper search-as-you-type. 172 : */ 173 : Xapian::Query makePartialORQuery(const std::string& keywords) const; 174 : 175 : /** 176 : * Build a query with the given keywords, specified as iterators of strings 177 : */ 178 : template<typename ITER> 179 3 : Xapian::Query makeORQuery(const ITER& begin, const ITER& end) const 180 : { 181 3 : std::vector<std::string> terms; 182 : // Insert both the lowercased and the stemmed lowercased query terms 183 10 : for (ITER i = begin; i != end; ++i) 184 : { 185 7 : std::string t = toLower(*i); 186 7 : std::string s = m_stem(t); 187 7 : terms.push_back(t); 188 7 : if (s != t) 189 0 : terms.push_back("Z" + s); 190 : } 191 3 : return Xapian::Query(Xapian::Query::OP_OR, terms.begin(), terms.end()); 192 : } 193 : 194 : /// Return a list of tag-based terms that can be used to expand an OR query 195 : std::vector<std::string> expand(Xapian::Enquire& enq) const; 196 : 197 : // std::vector<std::string> similar(const std::string& pkg); 198 : 199 : /** 200 : * Create a query to look for packages similar to the given one 201 : */ 202 : Xapian::Query makeRelatedQuery(const std::string& pkgname) const; 203 : 204 : /** 205 : * Get the integer value for 206 : */ 207 : double getDoubleValue(const std::string& pkgname, Xapian::valueno val_id) const; 208 : 209 : /** 210 : * Get the integer value for 211 : */ 212 : int getIntValue(const std::string& pkgname, Xapian::valueno val_id) const; 213 : }; 214 : 215 : } 216 : } 217 : 218 : // vim:set ts=4 sw=4: 219 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef EPT_TEXTSEARCH_EXTRAINDEXERS_H 2 : #define EPT_TEXTSEARCH_EXTRAINDEXERS_H 3 : 4 : /** @file 5 : * @author Enrico Zini <enrico@enricozini.org> 6 : * Fast full-text search 7 : */ 8 : 9 : /* 10 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org> 11 : * 12 : * This program is free software; you can redistribute it and/or modify 13 : * it under the terms of the GNU General Public License as published by 14 : * the Free Software Foundation; either version 2 of the License, or 15 : * (at your option) any later version. 16 : * 17 : * This program is distributed in the hope that it will be useful, 18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 : * GNU General Public License for more details. 21 : * 22 : * You should have received a copy of the GNU General Public License 23 : * along with this program; if not, write to the Free Software 24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 : */ 26 : 27 : #include <ept/textsearch/textsearch.h> 28 : 29 : namespace ept { 30 : namespace debtags { 31 : class Debtags; 32 : } 33 : namespace textsearch { 34 : 35 : struct AptTagsExtraIndexer : public TextSearch::ExtraIndexer 36 0 : { 37 : virtual void operator()(Xapian::Document& doc, const apt::PackageRecord& rec) const; 38 : }; 39 : 40 : struct DebtagsExtraIndexer : public TextSearch::ExtraIndexer 41 0 : { 42 : const debtags::Debtags& debtags; 43 : DebtagsExtraIndexer(const debtags::Debtags& debtags) : debtags(debtags) {} 44 : virtual void operator()(Xapian::Document& doc, const apt::PackageRecord& rec) const; 45 : }; 46 : 47 : } 48 : } 49 : 50 : // vim:set ts=4 sw=4: 51 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : 2 : /** @file 3 : * @author Enrico Zini <enrico@enricozini.org> 4 : * Fast full-text search 5 : */ 6 : 7 : /* 8 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org> 9 : * 10 : * This program is free software; you can redistribute it and/or modify 11 : * it under the terms of the GNU General Public License as published by 12 : * the Free Software Foundation; either version 2 of the License, or 13 : * (at your option) any later version. 14 : * 15 : * This program is distributed in the hope that it will be useful, 16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 : * GNU General Public License for more details. 19 : * 20 : * You should have received a copy of the GNU General Public License 21 : * along with this program; if not, write to the Free Software 22 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 : */ 24 : 25 : #include <ept/textsearch/textsearch.h> 26 : #include <ept/textsearch/maint/path.h> 27 : #include <ept/apt/apt.h> 28 : #include <ept/apt/packagerecord.h> 29 : //#include <ept/debtags/debtags.h> 30 : 31 : #include <wibble/regexp.h> 32 : #include <cctype> 33 : #include <cmath> 34 : 35 : #include <xapian/queryparser.h> 36 : 37 : #include <algorithm> 38 : 39 : #include <iostream> 40 : 41 : using namespace std; 42 : using namespace ept::apt; 43 : using namespace ept::debtags; 44 : 45 : namespace ept { 46 : namespace textsearch { 47 : 48 : size_t max_index = 0; 49 : 50 11 : TextSearch::TextSearch() 51 11 : : m_timestamp(0), m_stem("en") 52 : { 53 22 : m_timestamp = Path::indexTimestamp(); 54 11 : if (m_timestamp) 55 9 : m_db.add_database(Xapian::Database(Path::index())); 56 11 : } 57 : 58 7 : std::string TextSearch::toLower(const std::string& str) 59 : { 60 7 : std::string res; 61 7 : res.reserve(str.size()); 62 44 : for (std::string::const_iterator i = str.begin(); i != str.end(); ++i) 63 37 : res += tolower(*i); 64 0 : return res; 65 : } 66 : 67 3 : bool TextSearch::needsRebuild(apt::Apt& apt) 68 : { 69 3 : return apt.timestamp() > m_timestamp; 70 : } 71 : 72 0 : void TextSearch::normalize_and_add(Xapian::Document& doc, const std::string& term, int& pos) const 73 : { 74 0 : string t = TextSearch::toLower(term); 75 0 : string s = m_stem(t); 76 0 : doc.add_term(t); 77 0 : if (s != t) 78 0 : doc.add_term(s); 79 0 : } 80 : 81 10 : bool TextSearch::rebuildIfNeeded(apt::Apt& apt, const std::vector<const TextSearch::ExtraIndexer*>& extraIndexers) 82 : { 83 : // Check if a rebuild is needed, and keep a copy of the APT timestamp for 84 : // saving later 85 10 : time_t aptts = apt.timestamp(); 86 10 : if (aptts <= m_timestamp) 87 4 : return false; 88 : 89 : // Reindex 90 6 : Xapian::WritableDatabase database(Xapian::Flint::open(Path::index(), Xapian::DB_CREATE_OR_OPEN)); 91 6 : Xapian::TermGenerator termgen; 92 6 : termgen.set_stemmer(m_stem); 93 : //database.begin_transaction(); 94 6 : PackageRecord rec; 95 6 : size_t count = 0; 96 2610 : for (Apt::record_iterator i = apt.recordBegin(); 97 : i != apt.recordEnd(); ++i, ++count) 98 : { 99 : // If we are testing, we can set a limit to how many packages we index, 100 : // to avoid it taking too much time 101 2604 : if (max_index != 0 && count > max_index) 102 0 : break; 103 : 104 2604 : rec.scan(*i); 105 : 106 2604 : Xapian::Document doc; 107 2604 : doc.set_data(rec.package()); 108 : 109 2604 : string pkgid = "XP" + rec.package(); 110 : //std::cerr << "Add " << pkgid << ": " << idx << std::endl; 111 2604 : doc.add_term(pkgid); 112 : 113 : // Index tags as well 114 2604 : set<string> tags = rec.tag(); 115 2604 : for (set<string>::const_iterator ti = tags.begin(); 116 : ti != tags.end(); ++ti) 117 0 : doc.add_term("XT"+*ti); 118 : 119 2604 : termgen.set_document(doc); 120 2604 : termgen.index_text_without_positions(rec.package()); 121 5208 : termgen.index_text_without_positions(rec.description()); 122 : 123 : // Add the values 124 5208 : doc.add_value(VAL_APT_INSTALLED_SIZE, Xapian::sortable_serialise(rec.installedSize())); 125 2604 : doc.add_value(VAL_APT_PACKAGE_SIZE, Xapian::sortable_serialise(rec.packageSize())); 126 : 127 2604 : if (m_timestamp) 128 2170 : database.replace_document(pkgid, doc); 129 : else 130 434 : database.add_document(doc); 131 6 : } 132 : 133 : //database.commit_transaction(); 134 : 135 6 : if (!m_timestamp) 136 1 : m_db.add_database(Xapian::Database(Path::index())); 137 : else 138 5 : m_db.reopen(); 139 : 140 6 : m_timestamp = aptts; 141 : 142 6 : Path::setTimestamp(aptts); 143 : 144 6 : return true; 145 : } 146 : 147 2 : Xapian::Query TextSearch::makeORQuery(const std::string& keywords) const 148 : { 149 2 : wibble::Tokenizer tok(keywords, "[A-Za-z0-9_-]+", REG_EXTENDED); 150 4 : return makeORQuery(tok.begin(), tok.end()); 151 : } 152 : 153 1 : Xapian::Query TextSearch::makePartialORQuery(const std::string& keywords) const 154 : { 155 1 : wibble::Tokenizer tok(keywords, "[A-Za-z0-9_-]+", REG_EXTENDED); 156 1 : vector<string> tokens; 157 : // FIXME: make the Tokenizer iterators properly iterable 158 2 : for (wibble::Tokenizer::const_iterator i = tok.begin(); 159 : i != tok.end(); ++i) 160 1 : tokens.push_back(*i); 161 : // Add all the terms starting with 'last' 162 1 : if (!tokens.empty()) 163 : { 164 1 : string& last = *tokens.rbegin(); 165 1 : if (last.size() == 1) 166 : // Ignore one-letter partial terms: they make the query uselessly 167 : // large and slow, and it's worth just to wait for more characters 168 : // to come 169 0 : tokens.resize(tokens.size() - 1); 170 : else 171 1 : copy(m_db.allterms_begin(last), m_db.allterms_end(last), back_inserter(tokens)); 172 : /* 173 : for (Xapian::TermIterator t = m_db.allterms_begin(last); 174 : t != m_db.allterms_end(last); ++t) 175 : tokens.push_back(*t); 176 : */ 177 : } 178 1 : return makeORQuery(tokens.begin(), tokens.end()); 179 : } 180 : 181 10 : Xapian::docid TextSearch::docidByName(const std::string& pkgname) const 182 : { 183 10 : Xapian::PostingIterator i = m_db.postlist_begin("XP"+pkgname); 184 10 : if (i == m_db.postlist_end("XP"+pkgname)) 185 5 : return 0; 186 : else 187 5 : return *i; 188 : } 189 : 190 : struct TagFilter : public Xapian::ExpandDecider 191 4 : { 192 0 : virtual bool operator()(const std::string &term) const { return term[0] == 'T'; } 193 : }; 194 : 195 2 : static TagFilter tagFilter; 196 : 197 0 : vector<string> TextSearch::expand(Xapian::Enquire& enq) const 198 : { 199 0 : Xapian::RSet rset; 200 : // Get the top 5 results as 'good ones' to compute the search expansion 201 0 : Xapian::MSet mset = enq.get_mset(0, 5); 202 0 : for (Xapian::MSet::iterator i = mset.begin(); i != mset.end(); ++i) 203 0 : rset.add_document(i); 204 : // Get the expanded set, only expanding the query with tag names 205 0 : Xapian::ESet eset = enq.get_eset(5, rset, &tagFilter); 206 0 : vector<string> res; 207 0 : for (Xapian::ESetIterator i = eset.begin(); i != eset.end(); ++i) 208 0 : res.push_back(*i); 209 0 : return res; 210 : } 211 : 212 0 : Xapian::Query TextSearch::makeRelatedQuery(const std::string& pkgname) const 213 : { 214 0 : Xapian::Enquire enquire(db()); 215 : 216 : // Retrieve the document for the given package 217 0 : enquire.set_query(Xapian::Query("XP"+pkgname)); 218 0 : Xapian::MSet matches = enquire.get_mset(0, 1); 219 0 : Xapian::MSetIterator mi = matches.begin(); 220 0 : if (mi == matches.end()) return Xapian::Query(); 221 0 : Xapian::Document doc = mi.get_document(); 222 : 223 : // Return the query to get the list of similar documents 224 0 : return Xapian::Query(Xapian::Query::OP_OR, doc.termlist_begin(), doc.termlist_end()); 225 : } 226 : 227 4 : double TextSearch::getDoubleValue(const std::string& pkgname, Xapian::valueno val_id) const 228 : { 229 4 : Xapian::docid id = docidByName(pkgname); 230 4 : if (id == 0) 231 2 : return 0.0; 232 2 : Xapian::Document doc = db().get_document(id); 233 2 : string val = doc.get_value(val_id); 234 2 : if (val.empty()) 235 0 : return 0.0; 236 : else 237 2 : return Xapian::sortable_unserialise(val); 238 : } 239 : 240 4 : int TextSearch::getIntValue(const std::string& pkgname, Xapian::valueno val_id) const 241 : { 242 4 : Xapian::docid id = docidByName(pkgname); 243 4 : if (id == 0) 244 2 : return 0; 245 2 : Xapian::Document doc = db().get_document(id); 246 2 : string val = doc.get_value(val_id); 247 2 : if (val.empty()) 248 0 : return 0; 249 : else 250 2 : return (int)nearbyint(Xapian::sortable_unserialise(val)); 251 : } 252 : 253 : } 254 6 : } 255 : 256 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Stream buffer classes -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007, 2008 Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License 18 : // along with this library; see the file COPYING. If not, write to 19 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 20 : // Boston, MA 02110-1301, USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /** @file streambuf 32 : * This is a Standard C++ Library header. 33 : */ 34 : 35 : // 36 : // ISO C++ 14882: 27.5 Stream buffers 37 : // 38 : 39 : #ifndef _GLIBXX_STREAMBUF 40 : #define _GLIBXX_STREAMBUF 1 41 : 42 : #pragma GCC system_header 43 : 44 : #include <bits/c++config.h> 45 : #include <iosfwd> 46 : #include <bits/localefwd.h> 47 : #include <bits/ios_base.h> 48 : #include <bits/cpp_type_traits.h> 49 : #include <ext/type_traits.h> 50 : 51 : _GLIBCXX_BEGIN_NAMESPACE(std) 52 : 53 : template<typename _CharT, typename _Traits> 54 : streamsize 55 : __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>*, 56 : basic_streambuf<_CharT, _Traits>*, bool&); 57 : 58 : /** 59 : * @brief The actual work of input and output (interface). 60 : * 61 : * This is a base class. Derived stream buffers each control a 62 : * pair of character sequences: one for input, and one for output. 63 : * 64 : * Section [27.5.1] of the standard describes the requirements and 65 : * behavior of stream buffer classes. That section (three paragraphs) 66 : * is reproduced here, for simplicity and accuracy. 67 : * 68 : * -# Stream buffers can impose various constraints on the sequences 69 : * they control. Some constraints are: 70 : * - The controlled input sequence can be not readable. 71 : * - The controlled output sequence can be not writable. 72 : * - The controlled sequences can be associated with the contents of 73 : * other representations for character sequences, such as external 74 : * files. 75 : * - The controlled sequences can support operations @e directly to or 76 : * from associated sequences. 77 : * - The controlled sequences can impose limitations on how the 78 : * program can read characters from a sequence, write characters to 79 : * a sequence, put characters back into an input sequence, or alter 80 : * the stream position. 81 : * . 82 : * -# Each sequence is characterized by three pointers which, if non-null, 83 : * all point into the same @c charT array object. The array object 84 : * represents, at any moment, a (sub)sequence of characters from the 85 : * sequence. Operations performed on a sequence alter the values 86 : * stored in these pointers, perform reads and writes directly to or 87 : * from associated sequences, and alter "the stream position" and 88 : * conversion state as needed to maintain this subsequence relationship. 89 : * The three pointers are: 90 : * - the <em>beginning pointer</em>, or lowest element address in the 91 : * array (called @e xbeg here); 92 : * - the <em>next pointer</em>, or next element address that is a 93 : * current candidate for reading or writing (called @e xnext here); 94 : * - the <em>end pointer</em>, or first element address beyond the 95 : * end of the array (called @e xend here). 96 : * . 97 : * -# The following semantic constraints shall always apply for any set 98 : * of three pointers for a sequence, using the pointer names given 99 : * immediately above: 100 : * - If @e xnext is not a null pointer, then @e xbeg and @e xend shall 101 : * also be non-null pointers into the same @c charT array, as 102 : * described above; otherwise, @e xbeg and @e xend shall also be null. 103 : * - If @e xnext is not a null pointer and @e xnext < @e xend for an 104 : * output sequence, then a <em>write position</em> is available. 105 : * In this case, @e *xnext shall be assignable as the next element 106 : * to write (to put, or to store a character value, into the sequence). 107 : * - If @e xnext is not a null pointer and @e xbeg < @e xnext for an 108 : * input sequence, then a <em>putback position</em> is available. 109 : * In this case, @e xnext[-1] shall have a defined value and is the 110 : * next (preceding) element to store a character that is put back 111 : * into the input sequence. 112 : * - If @e xnext is not a null pointer and @e xnext< @e xend for an 113 : * input sequence, then a <em>read position</em> is available. 114 : * In this case, @e *xnext shall have a defined value and is the 115 : * next element to read (to get, or to obtain a character value, 116 : * from the sequence). 117 : */ 118 : template<typename _CharT, typename _Traits> 119 : class basic_streambuf 120 : { 121 : public: 122 : //@{ 123 : /** 124 : * These are standard types. They permit a standardized way of 125 : * referring to names of (or names dependant on) the template 126 : * parameters, which are specific to the implementation. 127 : */ 128 : typedef _CharT char_type; 129 : typedef _Traits traits_type; 130 : typedef typename traits_type::int_type int_type; 131 : typedef typename traits_type::pos_type pos_type; 132 : typedef typename traits_type::off_type off_type; 133 : //@} 134 : 135 : //@{ 136 : /// This is a non-standard type. 137 : typedef basic_streambuf<char_type, traits_type> __streambuf_type; 138 : //@} 139 : 140 : friend class basic_ios<char_type, traits_type>; 141 : friend class basic_istream<char_type, traits_type>; 142 : friend class basic_ostream<char_type, traits_type>; 143 : friend class istreambuf_iterator<char_type, traits_type>; 144 : friend class ostreambuf_iterator<char_type, traits_type>; 145 : 146 : friend streamsize 147 : __copy_streambufs_eof<>(__streambuf_type*, __streambuf_type*, bool&); 148 : 149 : template<bool _IsMove, typename _CharT2> 150 : friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, 151 : _CharT2*>::__type 152 : __copy_move_a2(istreambuf_iterator<_CharT2>, 153 : istreambuf_iterator<_CharT2>, _CharT2*); 154 : 155 : template<typename _CharT2> 156 : friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, 157 : istreambuf_iterator<_CharT2> >::__type 158 : find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, 159 : const _CharT2&); 160 : 161 : template<typename _CharT2, typename _Traits2> 162 : friend basic_istream<_CharT2, _Traits2>& 163 : operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*); 164 : 165 : template<typename _CharT2, typename _Traits2, typename _Alloc> 166 : friend basic_istream<_CharT2, _Traits2>& 167 : operator>>(basic_istream<_CharT2, _Traits2>&, 168 : basic_string<_CharT2, _Traits2, _Alloc>&); 169 : 170 : template<typename _CharT2, typename _Traits2, typename _Alloc> 171 : friend basic_istream<_CharT2, _Traits2>& 172 : getline(basic_istream<_CharT2, _Traits2>&, 173 : basic_string<_CharT2, _Traits2, _Alloc>&, _CharT2); 174 : 175 : protected: 176 : //@{ 177 : /** 178 : * This is based on _IO_FILE, just reordered to be more consistent, 179 : * and is intended to be the most minimal abstraction for an 180 : * internal buffer. 181 : * - get == input == read 182 : * - put == output == write 183 : */ 184 : char_type* _M_in_beg; // Start of get area. 185 : char_type* _M_in_cur; // Current read area. 186 : char_type* _M_in_end; // End of get area. 187 : char_type* _M_out_beg; // Start of put area. 188 : char_type* _M_out_cur; // Current put area. 189 : char_type* _M_out_end; // End of put area. 190 : 191 : /// Current locale setting. 192 : locale _M_buf_locale; 193 : 194 : public: 195 : /// Destructor deallocates no buffer space. 196 : virtual 197 0 : ~basic_streambuf() 198 0 : { } 199 : 200 : // [27.5.2.2.1] locales 201 : /** 202 : * @brief Entry point for imbue(). 203 : * @param loc The new locale. 204 : * @return The previous locale. 205 : * 206 : * Calls the derived imbue(loc). 207 : */ 208 : locale 209 : pubimbue(const locale &__loc) 210 : { 211 : locale __tmp(this->getloc()); 212 : this->imbue(__loc); 213 : _M_buf_locale = __loc; 214 : return __tmp; 215 : } 216 : 217 : /** 218 : * @brief Locale access. 219 : * @return The current locale in effect. 220 : * 221 : * If pubimbue(loc) has been called, then the most recent @c loc 222 : * is returned. Otherwise the global locale in effect at the time 223 : * of construction is returned. 224 : */ 225 : locale 226 : getloc() const 227 : { return _M_buf_locale; } 228 : 229 : // [27.5.2.2.2] buffer management and positioning 230 : //@{ 231 : /** 232 : * @brief Entry points for derived buffer functions. 233 : * 234 : * The public versions of @c pubfoo dispatch to the protected 235 : * derived @c foo member functions, passing the arguments (if any) 236 : * and returning the result unchanged. 237 : */ 238 : __streambuf_type* 239 : pubsetbuf(char_type* __s, streamsize __n) 240 : { return this->setbuf(__s, __n); } 241 : 242 : pos_type 243 : pubseekoff(off_type __off, ios_base::seekdir __way, 244 : ios_base::openmode __mode = ios_base::in | ios_base::out) 245 : { return this->seekoff(__off, __way, __mode); } 246 : 247 : pos_type 248 : pubseekpos(pos_type __sp, 249 : ios_base::openmode __mode = ios_base::in | ios_base::out) 250 : { return this->seekpos(__sp, __mode); } 251 : 252 : int 253 : pubsync() { return this->sync(); } 254 : //@} 255 : 256 : // [27.5.2.2.3] get area 257 : /** 258 : * @brief Looking ahead into the stream. 259 : * @return The number of characters available. 260 : * 261 : * If a read position is available, returns the number of characters 262 : * available for reading before the buffer must be refilled. 263 : * Otherwise returns the derived @c showmanyc(). 264 : */ 265 : streamsize 266 : in_avail() 267 : { 268 : const streamsize __ret = this->egptr() - this->gptr(); 269 : return __ret ? __ret : this->showmanyc(); 270 : } 271 : 272 : /** 273 : * @brief Getting the next character. 274 : * @return The next character, or eof. 275 : * 276 : * Calls @c sbumpc(), and if that function returns 277 : * @c traits::eof(), so does this function. Otherwise, @c sgetc(). 278 : */ 279 : int_type 280 : snextc() 281 : { 282 : int_type __ret = traits_type::eof(); 283 : if (__builtin_expect(!traits_type::eq_int_type(this->sbumpc(), 284 : __ret), true)) 285 : __ret = this->sgetc(); 286 : return __ret; 287 : } 288 : 289 : /** 290 : * @brief Getting the next character. 291 : * @return The next character, or eof. 292 : * 293 : * If the input read position is available, returns that character 294 : * and increments the read pointer, otherwise calls and returns 295 : * @c uflow(). 296 : */ 297 : int_type 298 : sbumpc() 299 : { 300 : int_type __ret; 301 : if (__builtin_expect(this->gptr() < this->egptr(), true)) 302 : { 303 : __ret = traits_type::to_int_type(*this->gptr()); 304 : this->gbump(1); 305 : } 306 : else 307 : __ret = this->uflow(); 308 : return __ret; 309 : } 310 : 311 : /** 312 : * @brief Getting the next character. 313 : * @return The next character, or eof. 314 : * 315 : * If the input read position is available, returns that character, 316 : * otherwise calls and returns @c underflow(). Does not move the 317 : * read position after fetching the character. 318 : */ 319 : int_type 320 : sgetc() 321 : { 322 : int_type __ret; 323 : if (__builtin_expect(this->gptr() < this->egptr(), true)) 324 : __ret = traits_type::to_int_type(*this->gptr()); 325 : else 326 : __ret = this->underflow(); 327 : return __ret; 328 : } 329 : 330 : /** 331 : * @brief Entry point for xsgetn. 332 : * @param s A buffer area. 333 : * @param n A count. 334 : * 335 : * Returns xsgetn(s,n). The effect is to fill @a s[0] through 336 : * @a s[n-1] with characters from the input sequence, if possible. 337 : */ 338 : streamsize 339 : sgetn(char_type* __s, streamsize __n) 340 : { return this->xsgetn(__s, __n); } 341 : 342 : // [27.5.2.2.4] putback 343 : /** 344 : * @brief Pushing characters back into the input stream. 345 : * @param c The character to push back. 346 : * @return The previous character, if possible. 347 : * 348 : * Similar to sungetc(), but @a c is pushed onto the stream instead 349 : * of "the previous character". If successful, the next character 350 : * fetched from the input stream will be @a c. 351 : */ 352 : int_type 353 : sputbackc(char_type __c) 354 : { 355 : int_type __ret; 356 : const bool __testpos = this->eback() < this->gptr(); 357 : if (__builtin_expect(!__testpos || 358 : !traits_type::eq(__c, this->gptr()[-1]), false)) 359 : __ret = this->pbackfail(traits_type::to_int_type(__c)); 360 : else 361 : { 362 : this->gbump(-1); 363 : __ret = traits_type::to_int_type(*this->gptr()); 364 : } 365 : return __ret; 366 : } 367 : 368 : /** 369 : * @brief Moving backwards in the input stream. 370 : * @return The previous character, if possible. 371 : * 372 : * If a putback position is available, this function decrements the 373 : * input pointer and returns that character. Otherwise, calls and 374 : * returns pbackfail(). The effect is to "unget" the last character 375 : * "gotten". 376 : */ 377 : int_type 378 : sungetc() 379 : { 380 : int_type __ret; 381 : if (__builtin_expect(this->eback() < this->gptr(), true)) 382 : { 383 : this->gbump(-1); 384 : __ret = traits_type::to_int_type(*this->gptr()); 385 : } 386 : else 387 : __ret = this->pbackfail(); 388 : return __ret; 389 : } 390 : 391 : // [27.5.2.2.5] put area 392 : /** 393 : * @brief Entry point for all single-character output functions. 394 : * @param c A character to output. 395 : * @return @a c, if possible. 396 : * 397 : * One of two public output functions. 398 : * 399 : * If a write position is available for the output sequence (i.e., 400 : * the buffer is not full), stores @a c in that position, increments 401 : * the position, and returns @c traits::to_int_type(c). If a write 402 : * position is not available, returns @c overflow(c). 403 : */ 404 : int_type 405 : sputc(char_type __c) 406 : { 407 : int_type __ret; 408 : if (__builtin_expect(this->pptr() < this->epptr(), true)) 409 : { 410 : *this->pptr() = __c; 411 : this->pbump(1); 412 : __ret = traits_type::to_int_type(__c); 413 : } 414 : else 415 : __ret = this->overflow(traits_type::to_int_type(__c)); 416 : return __ret; 417 : } 418 : 419 : /** 420 : * @brief Entry point for all single-character output functions. 421 : * @param s A buffer read area. 422 : * @param n A count. 423 : * 424 : * One of two public output functions. 425 : * 426 : * 427 : * Returns xsputn(s,n). The effect is to write @a s[0] through 428 : * @a s[n-1] to the output sequence, if possible. 429 : */ 430 : streamsize 431 : sputn(const char_type* __s, streamsize __n) 432 : { return this->xsputn(__s, __n); } 433 : 434 : protected: 435 : /** 436 : * @brief Base constructor. 437 : * 438 : * Only called from derived constructors, and sets up all the 439 : * buffer data to zero, including the pointers described in the 440 : * basic_streambuf class description. Note that, as a result, 441 : * - the class starts with no read nor write positions available, 442 : * - this is not an error 443 : */ 444 0 : basic_streambuf() 445 : : _M_in_beg(0), _M_in_cur(0), _M_in_end(0), 446 : _M_out_beg(0), _M_out_cur(0), _M_out_end(0), 447 0 : _M_buf_locale(locale()) 448 0 : { } 449 : 450 : // [27.5.2.3.1] get area access 451 : //@{ 452 : /** 453 : * @brief Access to the get area. 454 : * 455 : * These functions are only available to other protected functions, 456 : * including derived classes. 457 : * 458 : * - eback() returns the beginning pointer for the input sequence 459 : * - gptr() returns the next pointer for the input sequence 460 : * - egptr() returns the end pointer for the input sequence 461 : */ 462 : char_type* 463 : eback() const { return _M_in_beg; } 464 : 465 : char_type* 466 0 : gptr() const { return _M_in_cur; } 467 : 468 : char_type* 469 0 : egptr() const { return _M_in_end; } 470 : //@} 471 : 472 : /** 473 : * @brief Moving the read position. 474 : * @param n The delta by which to move. 475 : * 476 : * This just advances the read position without returning any data. 477 : */ 478 : void 479 0 : gbump(int __n) { _M_in_cur += __n; } 480 : 481 : /** 482 : * @brief Setting the three read area pointers. 483 : * @param gbeg A pointer. 484 : * @param gnext A pointer. 485 : * @param gend A pointer. 486 : * @post @a gbeg == @c eback(), @a gnext == @c gptr(), and 487 : * @a gend == @c egptr() 488 : */ 489 : void 490 : setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) 491 : { 492 : _M_in_beg = __gbeg; 493 : _M_in_cur = __gnext; 494 : _M_in_end = __gend; 495 : } 496 : 497 : // [27.5.2.3.2] put area access 498 : //@{ 499 : /** 500 : * @brief Access to the put area. 501 : * 502 : * These functions are only available to other protected functions, 503 : * including derived classes. 504 : * 505 : * - pbase() returns the beginning pointer for the output sequence 506 : * - pptr() returns the next pointer for the output sequence 507 : * - epptr() returns the end pointer for the output sequence 508 : */ 509 : char_type* 510 0 : pbase() const { return _M_out_beg; } 511 : 512 : char_type* 513 0 : pptr() const { return _M_out_cur; } 514 : 515 : char_type* 516 : epptr() const { return _M_out_end; } 517 : //@} 518 : 519 : /** 520 : * @brief Moving the write position. 521 : * @param n The delta by which to move. 522 : * 523 : * This just advances the write position without returning any data. 524 : */ 525 : void 526 0 : pbump(int __n) { _M_out_cur += __n; } 527 : 528 : /** 529 : * @brief Setting the three write area pointers. 530 : * @param pbeg A pointer. 531 : * @param pend A pointer. 532 : * @post @a pbeg == @c pbase(), @a pbeg == @c pptr(), and 533 : * @a pend == @c epptr() 534 : */ 535 : void 536 0 : setp(char_type* __pbeg, char_type* __pend) 537 : { 538 0 : _M_out_beg = _M_out_cur = __pbeg; 539 0 : _M_out_end = __pend; 540 0 : } 541 : 542 : // [27.5.2.4] virtual functions 543 : // [27.5.2.4.1] locales 544 : /** 545 : * @brief Changes translations. 546 : * @param loc A new locale. 547 : * 548 : * Translations done during I/O which depend on the current locale 549 : * are changed by this call. The standard adds, "Between invocations 550 : * of this function a class derived from streambuf can safely cache 551 : * results of calls to locale functions and to members of facets 552 : * so obtained." 553 : * 554 : * @note Base class version does nothing. 555 : */ 556 : virtual void 557 0 : imbue(const locale&) 558 0 : { } 559 : 560 : // [27.5.2.4.2] buffer management and positioning 561 : /** 562 : * @brief Manipulates the buffer. 563 : * 564 : * Each derived class provides its own appropriate behavior. See 565 : * the next-to-last paragraph of 566 : * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 for 567 : * more on this function. 568 : * 569 : * @note Base class version does nothing, returns @c this. 570 : */ 571 : virtual basic_streambuf<char_type,_Traits>* 572 0 : setbuf(char_type*, streamsize) 573 0 : { return this; } 574 : 575 : /** 576 : * @brief Alters the stream positions. 577 : * 578 : * Each derived class provides its own appropriate behavior. 579 : * @note Base class version does nothing, returns a @c pos_type 580 : * that represents an invalid stream position. 581 : */ 582 : virtual pos_type 583 : seekoff(off_type, ios_base::seekdir, 584 0 : ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out) 585 0 : { return pos_type(off_type(-1)); } 586 : 587 : /** 588 : * @brief Alters the stream positions. 589 : * 590 : * Each derived class provides its own appropriate behavior. 591 : * @note Base class version does nothing, returns a @c pos_type 592 : * that represents an invalid stream position. 593 : */ 594 : virtual pos_type 595 : seekpos(pos_type, 596 0 : ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out) 597 0 : { return pos_type(off_type(-1)); } 598 : 599 : /** 600 : * @brief Synchronizes the buffer arrays with the controlled sequences. 601 : * @return -1 on failure. 602 : * 603 : * Each derived class provides its own appropriate behavior, 604 : * including the definition of "failure". 605 : * @note Base class version does nothing, returns zero. 606 : */ 607 : virtual int 608 0 : sync() { return 0; } 609 : 610 : // [27.5.2.4.3] get area 611 : /** 612 : * @brief Investigating the data available. 613 : * @return An estimate of the number of characters available in the 614 : * input sequence, or -1. 615 : * 616 : * "If it returns a positive value, then successive calls to 617 : * @c underflow() will not return @c traits::eof() until at least that 618 : * number of characters have been supplied. If @c showmanyc() 619 : * returns -1, then calls to @c underflow() or @c uflow() will fail." 620 : * [27.5.2.4.3]/1 621 : * 622 : * @note Base class version does nothing, returns zero. 623 : * @note The standard adds that "the intention is not only that the 624 : * calls [to underflow or uflow] will not return @c eof() but 625 : * that they will return "immediately". 626 : * @note The standard adds that "the morphemes of @c showmanyc are 627 : * "es-how-many-see", not "show-manic". 628 : */ 629 : virtual streamsize 630 0 : showmanyc() { return 0; } 631 : 632 : /** 633 : * @brief Multiple character extraction. 634 : * @param s A buffer area. 635 : * @param n Maximum number of characters to assign. 636 : * @return The number of characters assigned. 637 : * 638 : * Fills @a s[0] through @a s[n-1] with characters from the input 639 : * sequence, as if by @c sbumpc(). Stops when either @a n characters 640 : * have been copied, or when @c traits::eof() would be copied. 641 : * 642 : * It is expected that derived classes provide a more efficient 643 : * implementation by overriding this definition. 644 : */ 645 : virtual streamsize 646 : xsgetn(char_type* __s, streamsize __n); 647 : 648 : /** 649 : * @brief Fetches more data from the controlled sequence. 650 : * @return The first character from the <em>pending sequence</em>. 651 : * 652 : * Informally, this function is called when the input buffer is 653 : * exhausted (or does not exist, as buffering need not actually be 654 : * done). If a buffer exists, it is "refilled". In either case, the 655 : * next available character is returned, or @c traits::eof() to 656 : * indicate a null pending sequence. 657 : * 658 : * For a formal definition of the pending sequence, see a good text 659 : * such as Langer & Kreft, or [27.5.2.4.3]/7-14. 660 : * 661 : * A functioning input streambuf can be created by overriding only 662 : * this function (no buffer area will be used). For an example, see 663 : * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#6 664 : * 665 : * @note Base class version does nothing, returns eof(). 666 : */ 667 : virtual int_type 668 0 : underflow() 669 0 : { return traits_type::eof(); } 670 : 671 : /** 672 : * @brief Fetches more data from the controlled sequence. 673 : * @return The first character from the <em>pending sequence</em>. 674 : * 675 : * Informally, this function does the same thing as @c underflow(), 676 : * and in fact is required to call that function. It also returns 677 : * the new character, like @c underflow() does. However, this 678 : * function also moves the read position forward by one. 679 : */ 680 : virtual int_type 681 0 : uflow() 682 : { 683 0 : int_type __ret = traits_type::eof(); 684 : const bool __testeof = traits_type::eq_int_type(this->underflow(), 685 0 : __ret); 686 0 : if (!__testeof) 687 : { 688 0 : __ret = traits_type::to_int_type(*this->gptr()); 689 0 : this->gbump(1); 690 : } 691 0 : return __ret; 692 : } 693 : 694 : // [27.5.2.4.4] putback 695 : /** 696 : * @brief Tries to back up the input sequence. 697 : * @param c The character to be inserted back into the sequence. 698 : * @return eof() on failure, "some other value" on success 699 : * @post The constraints of @c gptr(), @c eback(), and @c pptr() 700 : * are the same as for @c underflow(). 701 : * 702 : * @note Base class version does nothing, returns eof(). 703 : */ 704 : virtual int_type 705 0 : pbackfail(int_type /* __c */ = traits_type::eof()) 706 0 : { return traits_type::eof(); } 707 : 708 : // Put area: 709 : /** 710 : * @brief Multiple character insertion. 711 : * @param s A buffer area. 712 : * @param n Maximum number of characters to write. 713 : * @return The number of characters written. 714 : * 715 : * Writes @a s[0] through @a s[n-1] to the output sequence, as if 716 : * by @c sputc(). Stops when either @a n characters have been 717 : * copied, or when @c sputc() would return @c traits::eof(). 718 : * 719 : * It is expected that derived classes provide a more efficient 720 : * implementation by overriding this definition. 721 : */ 722 : virtual streamsize 723 : xsputn(const char_type* __s, streamsize __n); 724 : 725 : /** 726 : * @brief Consumes data from the buffer; writes to the 727 : * controlled sequence. 728 : * @param c An additional character to consume. 729 : * @return eof() to indicate failure, something else (usually 730 : * @a c, or not_eof()) 731 : * 732 : * Informally, this function is called when the output buffer is full 733 : * (or does not exist, as buffering need not actually be done). If a 734 : * buffer exists, it is "consumed", with "some effect" on the 735 : * controlled sequence. (Typically, the buffer is written out to the 736 : * sequence verbatim.) In either case, the character @a c is also 737 : * written out, if @a c is not @c eof(). 738 : * 739 : * For a formal definition of this function, see a good text 740 : * such as Langer & Kreft, or [27.5.2.4.5]/3-7. 741 : * 742 : * A functioning output streambuf can be created by overriding only 743 : * this function (no buffer area will be used). 744 : * 745 : * @note Base class version does nothing, returns eof(). 746 : */ 747 : virtual int_type 748 : overflow(int_type /* __c */ = traits_type::eof()) 749 : { return traits_type::eof(); } 750 : 751 : #if _GLIBCXX_DEPRECATED 752 : // Annex D.6 753 : public: 754 : /** 755 : * @brief Tosses a character. 756 : * 757 : * Advances the read pointer, ignoring the character that would have 758 : * been read. 759 : * 760 : * See http://gcc.gnu.org/ml/libstdc++/2002-05/msg00168.html 761 : */ 762 : void 763 : stossc() 764 : { 765 : if (this->gptr() < this->egptr()) 766 : this->gbump(1); 767 : else 768 : this->uflow(); 769 : } 770 : #endif 771 : 772 : private: 773 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 774 : // Side effect of DR 50. 775 : basic_streambuf(const __streambuf_type& __sb) 776 : : _M_in_beg(__sb._M_in_beg), _M_in_cur(__sb._M_in_cur), 777 : _M_in_end(__sb._M_in_end), _M_out_beg(__sb._M_out_beg), 778 : _M_out_cur(__sb._M_out_cur), _M_out_end(__sb._M_out_cur), 779 : _M_buf_locale(__sb._M_buf_locale) 780 : { } 781 : 782 : __streambuf_type& 783 : operator=(const __streambuf_type&) { return *this; }; 784 : }; 785 : 786 : // Explicit specialization declarations, defined in src/streambuf.cc. 787 : template<> 788 : streamsize 789 : __copy_streambufs_eof(basic_streambuf<char>* __sbin, 790 : basic_streambuf<char>* __sbout, bool& __ineof); 791 : #ifdef _GLIBCXX_USE_WCHAR_T 792 : template<> 793 : streamsize 794 : __copy_streambufs_eof(basic_streambuf<wchar_t>* __sbin, 795 : basic_streambuf<wchar_t>* __sbout, bool& __ineof); 796 : #endif 797 : 798 : _GLIBCXX_END_NAMESPACE 799 : 800 : #ifndef _GLIBCXX_EXPORT_TEMPLATE 801 : # include <bits/streambuf.tcc> 802 : #endif 803 : 804 : #endif /* _GLIBCXX_STREAMBUF */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // auto_ptr implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2007, 2008 Free Software Foundation, Inc. 4 : // 5 : // This file is part of the GNU ISO C++ Library. This library is free 6 : // software; you can redistribute it and/or modify it under the 7 : // terms of the GNU General Public License as published by the 8 : // Free Software Foundation; either version 2, or (at your option) 9 : // any later version. 10 : 11 : // This library is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : 16 : // You should have received a copy of the GNU General Public License 17 : // along with this library; see the file COPYING. If not, write to 18 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 19 : // Boston, MA 02110-1301, USA. 20 : 21 : // As a special exception, you may use this file as part of a free software 22 : // library without restriction. Specifically, if other files instantiate 23 : // templates or use macros or inline functions from this file, or you compile 24 : // this file and link it with other files to produce an executable, this 25 : // file does not by itself cause the resulting executable to be covered by 26 : // the GNU General Public License. This exception does not however 27 : // invalidate any other reasons why the executable file might be covered by 28 : // the GNU General Public License. 29 : 30 : /** @file backward/auto_ptr.h 31 : * This is an internal header file, included by other library headers. 32 : * You should not attempt to use it directly. 33 : */ 34 : 35 : #ifndef _STL_AUTO_PTR_H 36 : #define _STL_AUTO_PTR_H 1 37 : 38 : #include <bits/c++config.h> 39 : #include <debug/debug.h> 40 : 41 : _GLIBCXX_BEGIN_NAMESPACE(std) 42 : 43 : /** 44 : * A wrapper class to provide auto_ptr with reference semantics. 45 : * For example, an auto_ptr can be assigned (or constructed from) 46 : * the result of a function which returns an auto_ptr by value. 47 : * 48 : * All the auto_ptr_ref stuff should happen behind the scenes. 49 : */ 50 : template<typename _Tp1> 51 : struct auto_ptr_ref 52 : { 53 : _Tp1* _M_ptr; 54 : 55 : explicit 56 666 : auto_ptr_ref(_Tp1* __p): _M_ptr(__p) { } 57 : } _GLIBCXX_DEPRECATED_ATTR; 58 : 59 : 60 : /** 61 : * @brief A simple smart pointer providing strict ownership semantics. 62 : * 63 : * The Standard says: 64 : * <pre> 65 : * An @c auto_ptr owns the object it holds a pointer to. Copying 66 : * an @c auto_ptr copies the pointer and transfers ownership to the 67 : * destination. If more than one @c auto_ptr owns the same object 68 : * at the same time the behavior of the program is undefined. 69 : * 70 : * The uses of @c auto_ptr include providing temporary 71 : * exception-safety for dynamically allocated memory, passing 72 : * ownership of dynamically allocated memory to a function, and 73 : * returning dynamically allocated memory from a function. @c 74 : * auto_ptr does not meet the CopyConstructible and Assignable 75 : * requirements for Standard Library <a 76 : * href="tables.html#65">container</a> elements and thus 77 : * instantiating a Standard Library container with an @c auto_ptr 78 : * results in undefined behavior. 79 : * </pre> 80 : * Quoted from [20.4.5]/3. 81 : * 82 : * Good examples of what can and cannot be done with auto_ptr can 83 : * be found in the libstdc++ testsuite. 84 : * 85 : * _GLIBCXX_RESOLVE_LIB_DEFECTS 86 : * 127. auto_ptr<> conversion issues 87 : * These resolutions have all been incorporated. 88 : */ 89 : template<typename _Tp> 90 : class auto_ptr 91 : { 92 : private: 93 : _Tp* _M_ptr; 94 : 95 : public: 96 : /// The pointed-to type. 97 : typedef _Tp element_type; 98 : 99 : /** 100 : * @brief An %auto_ptr is usually constructed from a raw pointer. 101 : * @param p A pointer (defaults to NULL). 102 : * 103 : * This object now @e owns the object pointed to by @a p. 104 : */ 105 : explicit 106 666 : auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { } 107 : 108 : /** 109 : * @brief An %auto_ptr can be constructed from another %auto_ptr. 110 : * @param a Another %auto_ptr of the same type. 111 : * 112 : * This object now @e owns the object previously owned by @a a, 113 : * which has given up ownership. 114 : */ 115 590 : auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { } 116 : 117 : /** 118 : * @brief An %auto_ptr can be constructed from another %auto_ptr. 119 : * @param a Another %auto_ptr of a different but related type. 120 : * 121 : * A pointer-to-Tp1 must be convertible to a 122 : * pointer-to-Tp/element_type. 123 : * 124 : * This object now @e owns the object previously owned by @a a, 125 : * which has given up ownership. 126 : */ 127 : template<typename _Tp1> 128 : auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { } 129 : 130 : /** 131 : * @brief %auto_ptr assignment operator. 132 : * @param a Another %auto_ptr of the same type. 133 : * 134 : * This object now @e owns the object previously owned by @a a, 135 : * which has given up ownership. The object that this one @e 136 : * used to own and track has been deleted. 137 : */ 138 : auto_ptr& 139 : operator=(auto_ptr& __a) throw() 140 : { 141 : reset(__a.release()); 142 : return *this; 143 : } 144 : 145 : /** 146 : * @brief %auto_ptr assignment operator. 147 : * @param a Another %auto_ptr of a different but related type. 148 : * 149 : * A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type. 150 : * 151 : * This object now @e owns the object previously owned by @a a, 152 : * which has given up ownership. The object that this one @e 153 : * used to own and track has been deleted. 154 : */ 155 : template<typename _Tp1> 156 : auto_ptr& 157 : operator=(auto_ptr<_Tp1>& __a) throw() 158 : { 159 : reset(__a.release()); 160 : return *this; 161 : } 162 : 163 : /** 164 : * When the %auto_ptr goes out of scope, the object it owns is 165 : * deleted. If it no longer owns anything (i.e., @c get() is 166 : * @c NULL), then this has no effect. 167 : * 168 : * The C++ standard says there is supposed to be an empty throw 169 : * specification here, but omitting it is standard conforming. Its 170 : * presence can be detected only if _Tp::~_Tp() throws, but this is 171 : * prohibited. [17.4.3.6]/2 172 : */ 173 1922 : ~auto_ptr() { delete _M_ptr; } 174 : 175 : /** 176 : * @brief Smart pointer dereferencing. 177 : * 178 : * If this %auto_ptr no longer owns anything, then this 179 : * operation will crash. (For a smart pointer, "no longer owns 180 : * anything" is the same as being a null pointer, and you know 181 : * what happens when you dereference one of those...) 182 : */ 183 : element_type& 184 : operator*() const throw() 185 : { 186 : _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 187 : return *_M_ptr; 188 : } 189 : 190 : /** 191 : * @brief Smart pointer dereferencing. 192 : * 193 : * This returns the pointer itself, which the language then will 194 : * automatically cause to be dereferenced. 195 : */ 196 : element_type* 197 590 : operator->() const throw() 198 : { 199 : _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 200 590 : return _M_ptr; 201 : } 202 : 203 : /** 204 : * @brief Bypassing the smart pointer. 205 : * @return The raw pointer being managed. 206 : * 207 : * You can get a copy of the pointer that this object owns, for 208 : * situations such as passing to a function which only accepts 209 : * a raw pointer. 210 : * 211 : * @note This %auto_ptr still owns the memory. 212 : */ 213 : element_type* 214 1256 : get() const throw() { return _M_ptr; } 215 : 216 : /** 217 : * @brief Bypassing the smart pointer. 218 : * @return The raw pointer being managed. 219 : * 220 : * You can get a copy of the pointer that this object owns, for 221 : * situations such as passing to a function which only accepts 222 : * a raw pointer. 223 : * 224 : * @note This %auto_ptr no longer owns the memory. When this object 225 : * goes out of scope, nothing will happen. 226 : */ 227 : element_type* 228 1256 : release() throw() 229 : { 230 1256 : element_type* __tmp = _M_ptr; 231 1256 : _M_ptr = 0; 232 1256 : return __tmp; 233 : } 234 : 235 : /** 236 : * @brief Forcibly deletes the managed object. 237 : * @param p A pointer (defaults to NULL). 238 : * 239 : * This object now @e owns the object pointed to by @a p. The 240 : * previous object has been deleted. 241 : */ 242 : void 243 : reset(element_type* __p = 0) throw() 244 : { 245 : if (__p != _M_ptr) 246 : { 247 : delete _M_ptr; 248 : _M_ptr = __p; 249 : } 250 : } 251 : 252 : /** 253 : * @brief Automatic conversions 254 : * 255 : * These operations convert an %auto_ptr into and from an auto_ptr_ref 256 : * automatically as needed. This allows constructs such as 257 : * @code 258 : * auto_ptr<Derived> func_returning_auto_ptr(.....); 259 : * ... 260 : * auto_ptr<Base> ptr = func_returning_auto_ptr(.....); 261 : * @endcode 262 : */ 263 666 : auto_ptr(auto_ptr_ref<element_type> __ref) throw() 264 666 : : _M_ptr(__ref._M_ptr) { } 265 : 266 : auto_ptr& 267 : operator=(auto_ptr_ref<element_type> __ref) throw() 268 : { 269 : if (__ref._M_ptr != this->get()) 270 : { 271 : delete _M_ptr; 272 : _M_ptr = __ref._M_ptr; 273 : } 274 : return *this; 275 : } 276 : 277 : template<typename _Tp1> 278 666 : operator auto_ptr_ref<_Tp1>() throw() 279 666 : { return auto_ptr_ref<_Tp1>(this->release()); } 280 : 281 : template<typename _Tp1> 282 : operator auto_ptr<_Tp1>() throw() 283 : { return auto_ptr<_Tp1>(this->release()); } 284 : } _GLIBCXX_DEPRECATED_ATTR; 285 : 286 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 287 : // 541. shared_ptr template assignment and void 288 : template<> 289 : class auto_ptr<void> 290 : { 291 : public: 292 : typedef void element_type; 293 : } _GLIBCXX_DEPRECATED_ATTR; 294 : 295 : _GLIBCXX_END_NAMESPACE 296 : 297 : #endif /* _STL_AUTO_PTR_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
auto_ptr.h |
|
100.0 % | 15 / 15 lines | |
binders.h |
|
100.0 % | 7 / 7 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Functor implementations -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996-1998 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file backward/binders.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _GLIBCXX_BINDERS_H 63 : #define _GLIBCXX_BINDERS_H 1 64 : 65 : _GLIBCXX_BEGIN_NAMESPACE(std) 66 : 67 : // 20.3.6 binders 68 : /** @defgroup s20_3_6_binder Binder Classes 69 : * Binders turn functions/functors with two arguments into functors with 70 : * a single argument, storing an argument to be applied later. For 71 : * example, a variable @c B of type @c binder1st is constructed from a 72 : * functor @c f and an argument @c x. Later, B's @c operator() is called 73 : * with a single argument @c y. The return value is the value of @c f(x,y). 74 : * @c B can be "called" with various arguments (y1, y2, ...) and will in 75 : * turn call @c f(x,y1), @c f(x,y2), ... 76 : * 77 : * The function @c bind1st is provided to save some typing. It takes the 78 : * function and an argument as parameters, and returns an instance of 79 : * @c binder1st. 80 : * 81 : * The type @c binder2nd and its creator function @c bind2nd do the same 82 : * thing, but the stored argument is passed as the second parameter instead 83 : * of the first, e.g., @c bind2nd(std::minus<float>,1.3) will create a 84 : * functor whose @c operator() accepts a floating-point number, subtracts 85 : * 1.3 from it, and returns the result. (If @c bind1st had been used, 86 : * the functor would perform "1.3 - x" instead. 87 : * 88 : * Creator-wrapper functions like @c bind1st are intended to be used in 89 : * calling algorithms. Their return values will be temporary objects. 90 : * (The goal is to not require you to type names like 91 : * @c std::binder1st<std::plus<int>> for declaring a variable to hold the 92 : * return value from @c bind1st(std::plus<int>,5). 93 : * 94 : * These become more useful when combined with the composition functions. 95 : * 96 : * @{ 97 : */ 98 : /// One of the @link s20_3_6_binder binder functors@endlink. 99 : template<typename _Operation> 100 : class binder1st 101 : : public unary_function<typename _Operation::second_argument_type, 102 : typename _Operation::result_type> 103 16 : { 104 : protected: 105 : _Operation op; 106 : typename _Operation::first_argument_type value; 107 : 108 : public: 109 : binder1st(const _Operation& __x, 110 19 : const typename _Operation::first_argument_type& __y) 111 19 : : op(__x), value(__y) { } 112 : 113 : typename _Operation::result_type 114 70 : operator()(const typename _Operation::second_argument_type& __x) const 115 70 : { return op(value, __x); } 116 : 117 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 118 : // 109. Missing binders for non-const sequence elements 119 : typename _Operation::result_type 120 : operator()(typename _Operation::second_argument_type& __x) const 121 : { return op(value, __x); } 122 : } _GLIBCXX_DEPRECATED_ATTR; 123 : 124 : /// One of the @link s20_3_6_binder binder functors@endlink. 125 : template<typename _Operation, typename _Tp> 126 : inline binder1st<_Operation> 127 19 : bind1st(const _Operation& __fn, const _Tp& __x) 128 : { 129 : typedef typename _Operation::first_argument_type _Arg1_type; 130 19 : return binder1st<_Operation>(__fn, _Arg1_type(__x)); 131 : } 132 : 133 : /// One of the @link s20_3_6_binder binder functors@endlink. 134 : template<typename _Operation> 135 : class binder2nd 136 : : public unary_function<typename _Operation::first_argument_type, 137 : typename _Operation::result_type> 138 : { 139 : protected: 140 : _Operation op; 141 : typename _Operation::second_argument_type value; 142 : 143 : public: 144 : binder2nd(const _Operation& __x, 145 : const typename _Operation::second_argument_type& __y) 146 : : op(__x), value(__y) { } 147 : 148 : typename _Operation::result_type 149 : operator()(const typename _Operation::first_argument_type& __x) const 150 : { return op(__x, value); } 151 : 152 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 153 : // 109. Missing binders for non-const sequence elements 154 : typename _Operation::result_type 155 : operator()(typename _Operation::first_argument_type& __x) const 156 : { return op(__x, value); } 157 : } _GLIBCXX_DEPRECATED_ATTR; 158 : 159 : /// One of the @link s20_3_6_binder binder functors@endlink. 160 : template<typename _Operation, typename _Tp> 161 : inline binder2nd<_Operation> 162 : bind2nd(const _Operation& __fn, const _Tp& __x) 163 : { 164 : typedef typename _Operation::second_argument_type _Arg2_type; 165 : return binder2nd<_Operation>(__fn, _Arg2_type(__x)); 166 : } 167 : /** @} */ 168 : 169 : _GLIBCXX_END_NAMESPACE 170 : 171 : #endif /* _GLIBCXX_BINDERS_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Input streams -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007, 2008 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License 19 : // along with this library; see the file COPYING. If not, write to 20 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 21 : // Boston, MA 02110-1301, USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : // 33 : // ISO C++ 14882: 27.6.1 Input streams 34 : // 35 : 36 : /** @file istream 37 : * This is a Standard C++ Library header. 38 : */ 39 : 40 : #ifndef _GLIBCXX_ISTREAM 41 : #define _GLIBCXX_ISTREAM 1 42 : 43 : #pragma GCC system_header 44 : 45 : #include <ios> 46 : #include <ostream> 47 : 48 : _GLIBCXX_BEGIN_NAMESPACE(std) 49 : 50 : // [27.6.1.1] Template class basic_istream 51 : /** 52 : * @brief Controlling input. 53 : * 54 : * This is the base class for all input streams. It provides text 55 : * formatting of all builtin types, and communicates with any class 56 : * derived from basic_streambuf to do the actual input. 57 : */ 58 : template<typename _CharT, typename _Traits> 59 : class basic_istream : virtual public basic_ios<_CharT, _Traits> 60 : { 61 : public: 62 : // Types (inherited from basic_ios (27.4.4)): 63 : typedef _CharT char_type; 64 : typedef typename _Traits::int_type int_type; 65 : typedef typename _Traits::pos_type pos_type; 66 : typedef typename _Traits::off_type off_type; 67 : typedef _Traits traits_type; 68 : 69 : // Non-standard Types: 70 : typedef basic_streambuf<_CharT, _Traits> __streambuf_type; 71 : typedef basic_ios<_CharT, _Traits> __ios_type; 72 : typedef basic_istream<_CharT, _Traits> __istream_type; 73 : typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > 74 : __num_get_type; 75 : typedef ctype<_CharT> __ctype_type; 76 : 77 : protected: 78 : // Data Members: 79 : /** 80 : * The number of characters extracted in the previous unformatted 81 : * function; see gcount(). 82 : */ 83 : streamsize _M_gcount; 84 : 85 : public: 86 : // [27.6.1.1.1] constructor/destructor 87 : /** 88 : * @brief Base constructor. 89 : * 90 : * This ctor is almost never called by the user directly, rather from 91 : * derived classes' initialization lists, which pass a pointer to 92 : * their own stream buffer. 93 : */ 94 : explicit 95 : basic_istream(__streambuf_type* __sb) 96 : : _M_gcount(streamsize(0)) 97 : { this->init(__sb); } 98 : 99 : /** 100 : * @brief Base destructor. 101 : * 102 : * This does very little apart from providing a virtual base dtor. 103 : */ 104 : virtual 105 0 : ~basic_istream() 106 0 : { _M_gcount = streamsize(0); } 107 : 108 : // [27.6.1.1.2] prefix/suffix 109 : class sentry; 110 : friend class sentry; 111 : 112 : // [27.6.1.2] formatted input 113 : // [27.6.1.2.3] basic_istream::operator>> 114 : //@{ 115 : /** 116 : * @brief Interface for manipulators. 117 : * 118 : * Manipulators such as @c std::ws and @c std::dec use these 119 : * functions in constructs like "std::cin >> std::ws". For more 120 : * information, see the iomanip header. 121 : */ 122 : __istream_type& 123 : operator>>(__istream_type& (*__pf)(__istream_type&)) 124 : { return __pf(*this); } 125 : 126 : __istream_type& 127 : operator>>(__ios_type& (*__pf)(__ios_type&)) 128 : { 129 : __pf(*this); 130 : return *this; 131 : } 132 : 133 : __istream_type& 134 : operator>>(ios_base& (*__pf)(ios_base&)) 135 : { 136 : __pf(*this); 137 : return *this; 138 : } 139 : //@} 140 : 141 : // [27.6.1.2.2] arithmetic extractors 142 : /** 143 : * @name Arithmetic Extractors 144 : * 145 : * All the @c operator>> functions (aka <em>formatted input 146 : * functions</em>) have some common behavior. Each starts by 147 : * constructing a temporary object of type std::basic_istream::sentry 148 : * with the second argument (noskipws) set to false. This has several 149 : * effects, concluding with the setting of a status flag; see the 150 : * sentry documentation for more. 151 : * 152 : * If the sentry status is good, the function tries to extract 153 : * whatever data is appropriate for the type of the argument. 154 : * 155 : * If an exception is thrown during extraction, ios_base::badbit 156 : * will be turned on in the stream's error state without causing an 157 : * ios_base::failure to be thrown. The original exception will then 158 : * be rethrown. 159 : */ 160 : //@{ 161 : /** 162 : * @brief Basic arithmetic extractors 163 : * @param A variable of builtin type. 164 : * @return @c *this if successful 165 : * 166 : * These functions use the stream's current locale (specifically, the 167 : * @c num_get facet) to parse the input data. 168 : */ 169 : __istream_type& 170 : operator>>(bool& __n) 171 : { return _M_extract(__n); } 172 : 173 : __istream_type& 174 : operator>>(short& __n); 175 : 176 : __istream_type& 177 : operator>>(unsigned short& __n) 178 : { return _M_extract(__n); } 179 : 180 : __istream_type& 181 : operator>>(int& __n); 182 : 183 : __istream_type& 184 : operator>>(unsigned int& __n) 185 : { return _M_extract(__n); } 186 : 187 : __istream_type& 188 : operator>>(long& __n) 189 : { return _M_extract(__n); } 190 : 191 : __istream_type& 192 : operator>>(unsigned long& __n) 193 : { return _M_extract(__n); } 194 : 195 : #ifdef _GLIBCXX_USE_LONG_LONG 196 : __istream_type& 197 : operator>>(long long& __n) 198 : { return _M_extract(__n); } 199 : 200 : __istream_type& 201 : operator>>(unsigned long long& __n) 202 : { return _M_extract(__n); } 203 : #endif 204 : 205 : __istream_type& 206 : operator>>(float& __f) 207 : { return _M_extract(__f); } 208 : 209 : __istream_type& 210 : operator>>(double& __f) 211 : { return _M_extract(__f); } 212 : 213 : __istream_type& 214 : operator>>(long double& __f) 215 : { return _M_extract(__f); } 216 : 217 : __istream_type& 218 : operator>>(void*& __p) 219 : { return _M_extract(__p); } 220 : 221 : /** 222 : * @brief Extracting into another streambuf. 223 : * @param sb A pointer to a streambuf 224 : * 225 : * This function behaves like one of the basic arithmetic extractors, 226 : * in that it also constructs a sentry object and has the same error 227 : * handling behavior. 228 : * 229 : * If @a sb is NULL, the stream will set failbit in its error state. 230 : * 231 : * Characters are extracted from this stream and inserted into the 232 : * @a sb streambuf until one of the following occurs: 233 : * 234 : * - the input stream reaches end-of-file, 235 : * - insertion into the output buffer fails (in this case, the 236 : * character that would have been inserted is not extracted), or 237 : * - an exception occurs (and in this case is caught) 238 : * 239 : * If the function inserts no characters, failbit is set. 240 : */ 241 : __istream_type& 242 : operator>>(__streambuf_type* __sb); 243 : //@} 244 : 245 : // [27.6.1.3] unformatted input 246 : /** 247 : * @brief Character counting 248 : * @return The number of characters extracted by the previous 249 : * unformatted input function dispatched for this stream. 250 : */ 251 : streamsize 252 : gcount() const 253 : { return _M_gcount; } 254 : 255 : /** 256 : * @name Unformatted Input Functions 257 : * 258 : * All the unformatted input functions have some common behavior. 259 : * Each starts by constructing a temporary object of type 260 : * std::basic_istream::sentry with the second argument (noskipws) 261 : * set to true. This has several effects, concluding with the 262 : * setting of a status flag; see the sentry documentation for more. 263 : * 264 : * If the sentry status is good, the function tries to extract 265 : * whatever data is appropriate for the type of the argument. 266 : * 267 : * The number of characters extracted is stored for later retrieval 268 : * by gcount(). 269 : * 270 : * If an exception is thrown during extraction, ios_base::badbit 271 : * will be turned on in the stream's error state without causing an 272 : * ios_base::failure to be thrown. The original exception will then 273 : * be rethrown. 274 : */ 275 : //@{ 276 : /** 277 : * @brief Simple extraction. 278 : * @return A character, or eof(). 279 : * 280 : * Tries to extract a character. If none are available, sets failbit 281 : * and returns traits::eof(). 282 : */ 283 : int_type 284 : get(); 285 : 286 : /** 287 : * @brief Simple extraction. 288 : * @param c The character in which to store data. 289 : * @return *this 290 : * 291 : * Tries to extract a character and store it in @a c. If none are 292 : * available, sets failbit and returns traits::eof(). 293 : * 294 : * @note This function is not overloaded on signed char and 295 : * unsigned char. 296 : */ 297 : __istream_type& 298 : get(char_type& __c); 299 : 300 : /** 301 : * @brief Simple multiple-character extraction. 302 : * @param s Pointer to an array. 303 : * @param n Maximum number of characters to store in @a s. 304 : * @param delim A "stop" character. 305 : * @return *this 306 : * 307 : * Characters are extracted and stored into @a s until one of the 308 : * following happens: 309 : * 310 : * - @c n-1 characters are stored 311 : * - the input sequence reaches EOF 312 : * - the next character equals @a delim, in which case the character 313 : * is not extracted 314 : * 315 : * If no characters are stored, failbit is set in the stream's error 316 : * state. 317 : * 318 : * In any case, a null character is stored into the next location in 319 : * the array. 320 : * 321 : * @note This function is not overloaded on signed char and 322 : * unsigned char. 323 : */ 324 : __istream_type& 325 : get(char_type* __s, streamsize __n, char_type __delim); 326 : 327 : /** 328 : * @brief Simple multiple-character extraction. 329 : * @param s Pointer to an array. 330 : * @param n Maximum number of characters to store in @a s. 331 : * @return *this 332 : * 333 : * Returns @c get(s,n,widen('\n')). 334 : */ 335 : __istream_type& 336 : get(char_type* __s, streamsize __n) 337 : { return this->get(__s, __n, this->widen('\n')); } 338 : 339 : /** 340 : * @brief Extraction into another streambuf. 341 : * @param sb A streambuf in which to store data. 342 : * @param delim A "stop" character. 343 : * @return *this 344 : * 345 : * Characters are extracted and inserted into @a sb until one of the 346 : * following happens: 347 : * 348 : * - the input sequence reaches EOF 349 : * - insertion into the output buffer fails (in this case, the 350 : * character that would have been inserted is not extracted) 351 : * - the next character equals @a delim (in this case, the character 352 : * is not extracted) 353 : * - an exception occurs (and in this case is caught) 354 : * 355 : * If no characters are stored, failbit is set in the stream's error 356 : * state. 357 : */ 358 : __istream_type& 359 : get(__streambuf_type& __sb, char_type __delim); 360 : 361 : /** 362 : * @brief Extraction into another streambuf. 363 : * @param sb A streambuf in which to store data. 364 : * @return *this 365 : * 366 : * Returns @c get(sb,widen('\n')). 367 : */ 368 : __istream_type& 369 : get(__streambuf_type& __sb) 370 : { return this->get(__sb, this->widen('\n')); } 371 : 372 : /** 373 : * @brief String extraction. 374 : * @param s A character array in which to store the data. 375 : * @param n Maximum number of characters to extract. 376 : * @param delim A "stop" character. 377 : * @return *this 378 : * 379 : * Extracts and stores characters into @a s until one of the 380 : * following happens. Note that these criteria are required to be 381 : * tested in the order listed here, to allow an input line to exactly 382 : * fill the @a s array without setting failbit. 383 : * 384 : * -# the input sequence reaches end-of-file, in which case eofbit 385 : * is set in the stream error state 386 : * -# the next character equals @c delim, in which case the character 387 : * is extracted (and therefore counted in @c gcount()) but not stored 388 : * -# @c n-1 characters are stored, in which case failbit is set 389 : * in the stream error state 390 : * 391 : * If no characters are extracted, failbit is set. (An empty line of 392 : * input should therefore not cause failbit to be set.) 393 : * 394 : * In any case, a null character is stored in the next location in 395 : * the array. 396 : */ 397 : __istream_type& 398 : getline(char_type* __s, streamsize __n, char_type __delim); 399 : 400 : /** 401 : * @brief String extraction. 402 : * @param s A character array in which to store the data. 403 : * @param n Maximum number of characters to extract. 404 : * @return *this 405 : * 406 : * Returns @c getline(s,n,widen('\n')). 407 : */ 408 : __istream_type& 409 : getline(char_type* __s, streamsize __n) 410 : { return this->getline(__s, __n, this->widen('\n')); } 411 : 412 : /** 413 : * @brief Discarding characters 414 : * @param n Number of characters to discard. 415 : * @param delim A "stop" character. 416 : * @return *this 417 : * 418 : * Extracts characters and throws them away until one of the 419 : * following happens: 420 : * - if @a n @c != @c std::numeric_limits<int>::max(), @a n 421 : * characters are extracted 422 : * - the input sequence reaches end-of-file 423 : * - the next character equals @a delim (in this case, the character 424 : * is extracted); note that this condition will never occur if 425 : * @a delim equals @c traits::eof(). 426 : * 427 : * NB: Provide three overloads, instead of the single function 428 : * (with defaults) mandated by the Standard: this leads to a 429 : * better performing implementation, while still conforming to 430 : * the Standard. 431 : */ 432 : __istream_type& 433 : ignore(); 434 : 435 : __istream_type& 436 : ignore(streamsize __n); 437 : 438 : __istream_type& 439 : ignore(streamsize __n, int_type __delim); 440 : 441 : /** 442 : * @brief Looking ahead in the stream 443 : * @return The next character, or eof(). 444 : * 445 : * If, after constructing the sentry object, @c good() is false, 446 : * returns @c traits::eof(). Otherwise reads but does not extract 447 : * the next input character. 448 : */ 449 : int_type 450 : peek(); 451 : 452 : /** 453 : * @brief Extraction without delimiters. 454 : * @param s A character array. 455 : * @param n Maximum number of characters to store. 456 : * @return *this 457 : * 458 : * If the stream state is @c good(), extracts characters and stores 459 : * them into @a s until one of the following happens: 460 : * - @a n characters are stored 461 : * - the input sequence reaches end-of-file, in which case the error 462 : * state is set to @c failbit|eofbit. 463 : * 464 : * @note This function is not overloaded on signed char and 465 : * unsigned char. 466 : */ 467 : __istream_type& 468 : read(char_type* __s, streamsize __n); 469 : 470 : /** 471 : * @brief Extraction until the buffer is exhausted, but no more. 472 : * @param s A character array. 473 : * @param n Maximum number of characters to store. 474 : * @return The number of characters extracted. 475 : * 476 : * Extracts characters and stores them into @a s depending on the 477 : * number of characters remaining in the streambuf's buffer, 478 : * @c rdbuf()->in_avail(), called @c A here: 479 : * - if @c A @c == @c -1, sets eofbit and extracts no characters 480 : * - if @c A @c == @c 0, extracts no characters 481 : * - if @c A @c > @c 0, extracts @c min(A,n) 482 : * 483 : * The goal is to empty the current buffer, and to not request any 484 : * more from the external input sequence controlled by the streambuf. 485 : */ 486 : streamsize 487 : readsome(char_type* __s, streamsize __n); 488 : 489 : /** 490 : * @brief Unextracting a single character. 491 : * @param c The character to push back into the input stream. 492 : * @return *this 493 : * 494 : * If @c rdbuf() is not null, calls @c rdbuf()->sputbackc(c). 495 : * 496 : * If @c rdbuf() is null or if @c sputbackc() fails, sets badbit in 497 : * the error state. 498 : * 499 : * @note Since no characters are extracted, the next call to 500 : * @c gcount() will return 0, as required by DR 60. 501 : */ 502 : __istream_type& 503 : putback(char_type __c); 504 : 505 : /** 506 : * @brief Unextracting the previous character. 507 : * @return *this 508 : * 509 : * If @c rdbuf() is not null, calls @c rdbuf()->sungetc(c). 510 : * 511 : * If @c rdbuf() is null or if @c sungetc() fails, sets badbit in 512 : * the error state. 513 : * 514 : * @note Since no characters are extracted, the next call to 515 : * @c gcount() will return 0, as required by DR 60. 516 : */ 517 : __istream_type& 518 : unget(); 519 : 520 : /** 521 : * @brief Synchronizing the stream buffer. 522 : * @return 0 on success, -1 on failure 523 : * 524 : * If @c rdbuf() is a null pointer, returns -1. 525 : * 526 : * Otherwise, calls @c rdbuf()->pubsync(), and if that returns -1, 527 : * sets badbit and returns -1. 528 : * 529 : * Otherwise, returns 0. 530 : * 531 : * @note This function does not count the number of characters 532 : * extracted, if any, and therefore does not affect the next 533 : * call to @c gcount(). 534 : */ 535 : int 536 : sync(); 537 : 538 : /** 539 : * @brief Getting the current read position. 540 : * @return A file position object. 541 : * 542 : * If @c fail() is not false, returns @c pos_type(-1) to indicate 543 : * failure. Otherwise returns @c rdbuf()->pubseekoff(0,cur,in). 544 : * 545 : * @note This function does not count the number of characters 546 : * extracted, if any, and therefore does not affect the next 547 : * call to @c gcount(). 548 : */ 549 : pos_type 550 : tellg(); 551 : 552 : /** 553 : * @brief Changing the current read position. 554 : * @param pos A file position object. 555 : * @return *this 556 : * 557 : * If @c fail() is not true, calls @c rdbuf()->pubseekpos(pos). If 558 : * that function fails, sets failbit. 559 : * 560 : * @note This function does not count the number of characters 561 : * extracted, if any, and therefore does not affect the next 562 : * call to @c gcount(). 563 : */ 564 : __istream_type& 565 : seekg(pos_type); 566 : 567 : /** 568 : * @brief Changing the current read position. 569 : * @param off A file offset object. 570 : * @param dir The direction in which to seek. 571 : * @return *this 572 : * 573 : * If @c fail() is not true, calls @c rdbuf()->pubseekoff(off,dir). 574 : * If that function fails, sets failbit. 575 : * 576 : * @note This function does not count the number of characters 577 : * extracted, if any, and therefore does not affect the next 578 : * call to @c gcount(). 579 : */ 580 : __istream_type& 581 : seekg(off_type, ios_base::seekdir); 582 : //@} 583 : 584 : protected: 585 0 : basic_istream() 586 0 : : _M_gcount(streamsize(0)) 587 0 : { this->init(0); } 588 : 589 : template<typename _ValueT> 590 : __istream_type& 591 : _M_extract(_ValueT& __v); 592 : }; 593 : 594 : // Explicit specialization declarations, defined in src/istream.cc. 595 : template<> 596 : basic_istream<char>& 597 : basic_istream<char>:: 598 : getline(char_type* __s, streamsize __n, char_type __delim); 599 : 600 : template<> 601 : basic_istream<char>& 602 : basic_istream<char>:: 603 : ignore(streamsize __n); 604 : 605 : template<> 606 : basic_istream<char>& 607 : basic_istream<char>:: 608 : ignore(streamsize __n, int_type __delim); 609 : 610 : #ifdef _GLIBCXX_USE_WCHAR_T 611 : template<> 612 : basic_istream<wchar_t>& 613 : basic_istream<wchar_t>:: 614 : getline(char_type* __s, streamsize __n, char_type __delim); 615 : 616 : template<> 617 : basic_istream<wchar_t>& 618 : basic_istream<wchar_t>:: 619 : ignore(streamsize __n); 620 : 621 : template<> 622 : basic_istream<wchar_t>& 623 : basic_istream<wchar_t>:: 624 : ignore(streamsize __n, int_type __delim); 625 : #endif 626 : 627 : /** 628 : * @brief Performs setup work for input streams. 629 : * 630 : * Objects of this class are created before all of the standard 631 : * extractors are run. It is responsible for "exception-safe prefix and 632 : * suffix operations," although only prefix actions are currently required 633 : * by the standard. Additional actions may be added by the 634 : * implementation, and we list them in 635 : * http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/howto.html#5 636 : * under [27.6] notes. 637 : */ 638 : template<typename _CharT, typename _Traits> 639 : class basic_istream<_CharT, _Traits>::sentry 640 : { 641 : public: 642 : /// Easy access to dependant types. 643 : typedef _Traits traits_type; 644 : typedef basic_streambuf<_CharT, _Traits> __streambuf_type; 645 : typedef basic_istream<_CharT, _Traits> __istream_type; 646 : typedef typename __istream_type::__ctype_type __ctype_type; 647 : typedef typename _Traits::int_type __int_type; 648 : 649 : /** 650 : * @brief The constructor performs all the work. 651 : * @param is The input stream to guard. 652 : * @param noskipws Whether to consume whitespace or not. 653 : * 654 : * If the stream state is good (@a is.good() is true), then the 655 : * following actions are performed, otherwise the sentry state is 656 : * false ("not okay") and failbit is set in the stream state. 657 : * 658 : * The sentry's preparatory actions are: 659 : * 660 : * -# if the stream is tied to an output stream, @c is.tie()->flush() 661 : * is called to synchronize the output sequence 662 : * -# if @a noskipws is false, and @c ios_base::skipws is set in 663 : * @c is.flags(), the sentry extracts and discards whitespace 664 : * characters from the stream. The currently imbued locale is 665 : * used to determine whether each character is whitespace. 666 : * 667 : * If the stream state is still good, then the sentry state becomes 668 : * true ("okay"). 669 : */ 670 : explicit 671 : sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false); 672 : 673 : /** 674 : * @brief Quick status checking. 675 : * @return The sentry state. 676 : * 677 : * For ease of use, sentries may be converted to booleans. The 678 : * return value is that of the sentry state (true == okay). 679 : */ 680 : operator bool() const 681 : { return _M_ok; } 682 : 683 : private: 684 : bool _M_ok; 685 : }; 686 : 687 : // [27.6.1.2.3] character extraction templates 688 : //@{ 689 : /** 690 : * @brief Character extractors 691 : * @param in An input stream. 692 : * @param c A character reference. 693 : * @return in 694 : * 695 : * Behaves like one of the formatted arithmetic extractors described in 696 : * std::basic_istream. After constructing a sentry object with good 697 : * status, this function extracts a character (if one is available) and 698 : * stores it in @a c. Otherwise, sets failbit in the input stream. 699 : */ 700 : template<typename _CharT, typename _Traits> 701 : basic_istream<_CharT, _Traits>& 702 : operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c); 703 : 704 : template<class _Traits> 705 : inline basic_istream<char, _Traits>& 706 : operator>>(basic_istream<char, _Traits>& __in, unsigned char& __c) 707 : { return (__in >> reinterpret_cast<char&>(__c)); } 708 : 709 : template<class _Traits> 710 : inline basic_istream<char, _Traits>& 711 : operator>>(basic_istream<char, _Traits>& __in, signed char& __c) 712 : { return (__in >> reinterpret_cast<char&>(__c)); } 713 : //@} 714 : 715 : //@{ 716 : /** 717 : * @brief Character string extractors 718 : * @param in An input stream. 719 : * @param s A pointer to a character array. 720 : * @return in 721 : * 722 : * Behaves like one of the formatted arithmetic extractors described in 723 : * std::basic_istream. After constructing a sentry object with good 724 : * status, this function extracts up to @c n characters and stores them 725 : * into the array starting at @a s. @c n is defined as: 726 : * 727 : * - if @c width() is greater than zero, @c n is width() 728 : * - otherwise @c n is "the number of elements of the largest array of 729 : * @c char_type that can store a terminating @c eos." [27.6.1.2.3]/6 730 : * 731 : * Characters are extracted and stored until one of the following happens: 732 : * - @c n-1 characters are stored 733 : * - EOF is reached 734 : * - the next character is whitespace according to the current locale 735 : * - the next character is a null byte (i.e., @c charT() ) 736 : * 737 : * @c width(0) is then called for the input stream. 738 : * 739 : * If no characters are extracted, sets failbit. 740 : */ 741 : template<typename _CharT, typename _Traits> 742 : basic_istream<_CharT, _Traits>& 743 : operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s); 744 : 745 : // Explicit specialization declaration, defined in src/istream.cc. 746 : template<> 747 : basic_istream<char>& 748 : operator>>(basic_istream<char>& __in, char* __s); 749 : 750 : template<class _Traits> 751 : inline basic_istream<char, _Traits>& 752 : operator>>(basic_istream<char, _Traits>& __in, unsigned char* __s) 753 : { return (__in >> reinterpret_cast<char*>(__s)); } 754 : 755 : template<class _Traits> 756 : inline basic_istream<char, _Traits>& 757 : operator>>(basic_istream<char, _Traits>& __in, signed char* __s) 758 : { return (__in >> reinterpret_cast<char*>(__s)); } 759 : //@} 760 : 761 : // 27.6.1.5 Template class basic_iostream 762 : /** 763 : * @brief Merging istream and ostream capabilities. 764 : * 765 : * This class multiply inherits from the input and output stream classes 766 : * simply to provide a single interface. 767 : */ 768 : template<typename _CharT, typename _Traits> 769 : class basic_iostream 770 : : public basic_istream<_CharT, _Traits>, 771 : public basic_ostream<_CharT, _Traits> 772 : { 773 : public: 774 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 775 : // 271. basic_iostream missing typedefs 776 : // Types (inherited): 777 : typedef _CharT char_type; 778 : typedef typename _Traits::int_type int_type; 779 : typedef typename _Traits::pos_type pos_type; 780 : typedef typename _Traits::off_type off_type; 781 : typedef _Traits traits_type; 782 : 783 : // Non-standard Types: 784 : typedef basic_istream<_CharT, _Traits> __istream_type; 785 : typedef basic_ostream<_CharT, _Traits> __ostream_type; 786 : 787 : /** 788 : * @brief Constructor does nothing. 789 : * 790 : * Both of the parent classes are initialized with the same 791 : * streambuf pointer passed to this constructor. 792 : */ 793 : explicit 794 : basic_iostream(basic_streambuf<_CharT, _Traits>* __sb) 795 : : __istream_type(__sb), __ostream_type(__sb) { } 796 : 797 : /** 798 : * @brief Destructor does nothing. 799 : */ 800 : virtual 801 0 : ~basic_iostream() { } 802 : 803 : protected: 804 0 : basic_iostream() 805 0 : : __istream_type(), __ostream_type() { } 806 : }; 807 : 808 : // [27.6.1.4] standard basic_istream manipulators 809 : /** 810 : * @brief Quick and easy way to eat whitespace 811 : * 812 : * This manipulator extracts whitespace characters, stopping when the 813 : * next character is non-whitespace, or when the input sequence is empty. 814 : * If the sequence is empty, @c eofbit is set in the stream, but not 815 : * @c failbit. 816 : * 817 : * The current locale is used to distinguish whitespace characters. 818 : * 819 : * Example: 820 : * @code 821 : * MyClass mc; 822 : * 823 : * std::cin >> std::ws >> mc; 824 : * @endcode 825 : * will skip leading whitespace before calling operator>> on cin and your 826 : * object. Note that the same effect can be achieved by creating a 827 : * std::basic_istream::sentry inside your definition of operator>>. 828 : */ 829 : template<typename _CharT, typename _Traits> 830 : basic_istream<_CharT, _Traits>& 831 : ws(basic_istream<_CharT, _Traits>& __is); 832 : 833 : _GLIBCXX_END_NAMESPACE 834 : 835 : #ifndef _GLIBCXX_EXPORT_TEMPLATE 836 : # include <bits/istream.tcc> 837 : #endif 838 : 839 : #endif /* _GLIBCXX_ISTREAM */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Output streams -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007, 2008 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License 19 : // along with this library; see the file COPYING. If not, write to 20 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 21 : // Boston, MA 02110-1301, USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file ostream 33 : * This is a Standard C++ Library header. 34 : */ 35 : 36 : // 37 : // ISO C++ 14882: 27.6.2 Output streams 38 : // 39 : 40 : #ifndef _GLIBCXX_OSTREAM 41 : #define _GLIBCXX_OSTREAM 1 42 : 43 : #pragma GCC system_header 44 : 45 : #include <ios> 46 : #include <bits/ostream_insert.h> 47 : 48 : _GLIBCXX_BEGIN_NAMESPACE(std) 49 : 50 : // [27.6.2.1] Template class basic_ostream 51 : /** 52 : * @brief Controlling output. 53 : * 54 : * This is the base class for all output streams. It provides text 55 : * formatting of all builtin types, and communicates with any class 56 : * derived from basic_streambuf to do the actual output. 57 : */ 58 : template<typename _CharT, typename _Traits> 59 : class basic_ostream : virtual public basic_ios<_CharT, _Traits> 60 : { 61 : public: 62 : // Types (inherited from basic_ios (27.4.4)): 63 : typedef _CharT char_type; 64 : typedef typename _Traits::int_type int_type; 65 : typedef typename _Traits::pos_type pos_type; 66 : typedef typename _Traits::off_type off_type; 67 : typedef _Traits traits_type; 68 : 69 : // Non-standard Types: 70 : typedef basic_streambuf<_CharT, _Traits> __streambuf_type; 71 : typedef basic_ios<_CharT, _Traits> __ios_type; 72 : typedef basic_ostream<_CharT, _Traits> __ostream_type; 73 : typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > 74 : __num_put_type; 75 : typedef ctype<_CharT> __ctype_type; 76 : 77 : // [27.6.2.2] constructor/destructor 78 : /** 79 : * @brief Base constructor. 80 : * 81 : * This ctor is almost never called by the user directly, rather from 82 : * derived classes' initialization lists, which pass a pointer to 83 : * their own stream buffer. 84 : */ 85 : explicit 86 0 : basic_ostream(__streambuf_type* __sb) 87 0 : { this->init(__sb); } 88 : 89 : /** 90 : * @brief Base destructor. 91 : * 92 : * This does very little apart from providing a virtual base dtor. 93 : */ 94 : virtual 95 0 : ~basic_ostream() { } 96 : 97 : // [27.6.2.3] prefix/suffix 98 : class sentry; 99 : friend class sentry; 100 : 101 : // [27.6.2.5] formatted output 102 : // [27.6.2.5.3] basic_ostream::operator<< 103 : //@{ 104 : /** 105 : * @brief Interface for manipulators. 106 : * 107 : * Manipulators such as @c std::endl and @c std::hex use these 108 : * functions in constructs like "std::cout << std::endl". For more 109 : * information, see the iomanip header. 110 : */ 111 : __ostream_type& 112 0 : operator<<(__ostream_type& (*__pf)(__ostream_type&)) 113 : { 114 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 115 : // DR 60. What is a formatted input function? 116 : // The inserters for manipulators are *not* formatted output functions. 117 0 : return __pf(*this); 118 : } 119 : 120 : __ostream_type& 121 : operator<<(__ios_type& (*__pf)(__ios_type&)) 122 : { 123 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 124 : // DR 60. What is a formatted input function? 125 : // The inserters for manipulators are *not* formatted output functions. 126 : __pf(*this); 127 : return *this; 128 : } 129 : 130 : __ostream_type& 131 0 : operator<<(ios_base& (*__pf) (ios_base&)) 132 : { 133 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 134 : // DR 60. What is a formatted input function? 135 : // The inserters for manipulators are *not* formatted output functions. 136 0 : __pf(*this); 137 0 : return *this; 138 : } 139 : //@} 140 : 141 : // [27.6.2.5.2] arithmetic inserters 142 : /** 143 : * @name Arithmetic Inserters 144 : * 145 : * All the @c operator<< functions (aka <em>formatted output 146 : * functions</em>) have some common behavior. Each starts by 147 : * constructing a temporary object of type std::basic_ostream::sentry. 148 : * This can have several effects, concluding with the setting of a 149 : * status flag; see the sentry documentation for more. 150 : * 151 : * If the sentry status is good, the function tries to generate 152 : * whatever data is appropriate for the type of the argument. 153 : * 154 : * If an exception is thrown during insertion, ios_base::badbit 155 : * will be turned on in the stream's error state without causing an 156 : * ios_base::failure to be thrown. The original exception will then 157 : * be rethrown. 158 : */ 159 : //@{ 160 : /** 161 : * @brief Basic arithmetic inserters 162 : * @param A variable of builtin type. 163 : * @return @c *this if successful 164 : * 165 : * These functions use the stream's current locale (specifically, the 166 : * @c num_get facet) to perform numeric formatting. 167 : */ 168 : __ostream_type& 169 0 : operator<<(long __n) 170 0 : { return _M_insert(__n); } 171 : 172 : __ostream_type& 173 : operator<<(unsigned long __n) 174 : { return _M_insert(__n); } 175 : 176 : __ostream_type& 177 0 : operator<<(bool __n) 178 0 : { return _M_insert(__n); } 179 : 180 : __ostream_type& 181 : operator<<(short __n); 182 : 183 : __ostream_type& 184 : operator<<(unsigned short __n) 185 : { 186 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 187 : // 117. basic_ostream uses nonexistent num_put member functions. 188 : return _M_insert(static_cast<unsigned long>(__n)); 189 : } 190 : 191 : __ostream_type& 192 : operator<<(int __n); 193 : 194 : __ostream_type& 195 0 : operator<<(unsigned int __n) 196 : { 197 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 198 : // 117. basic_ostream uses nonexistent num_put member functions. 199 0 : return _M_insert(static_cast<unsigned long>(__n)); 200 : } 201 : 202 : #ifdef _GLIBCXX_USE_LONG_LONG 203 : __ostream_type& 204 0 : operator<<(long long __n) 205 0 : { return _M_insert(__n); } 206 : 207 : __ostream_type& 208 : operator<<(unsigned long long __n) 209 : { return _M_insert(__n); } 210 : #endif 211 : 212 : __ostream_type& 213 0 : operator<<(double __f) 214 0 : { return _M_insert(__f); } 215 : 216 : __ostream_type& 217 : operator<<(float __f) 218 : { 219 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 220 : // 117. basic_ostream uses nonexistent num_put member functions. 221 : return _M_insert(static_cast<double>(__f)); 222 : } 223 : 224 : __ostream_type& 225 : operator<<(long double __f) 226 : { return _M_insert(__f); } 227 : 228 : __ostream_type& 229 0 : operator<<(const void* __p) 230 0 : { return _M_insert(__p); } 231 : 232 : /** 233 : * @brief Extracting from another streambuf. 234 : * @param sb A pointer to a streambuf 235 : * 236 : * This function behaves like one of the basic arithmetic extractors, 237 : * in that it also constructs a sentry object and has the same error 238 : * handling behavior. 239 : * 240 : * If @a sb is NULL, the stream will set failbit in its error state. 241 : * 242 : * Characters are extracted from @a sb and inserted into @c *this 243 : * until one of the following occurs: 244 : * 245 : * - the input stream reaches end-of-file, 246 : * - insertion into the output sequence fails (in this case, the 247 : * character that would have been inserted is not extracted), or 248 : * - an exception occurs while getting a character from @a sb, which 249 : * sets failbit in the error state 250 : * 251 : * If the function inserts no characters, failbit is set. 252 : */ 253 : __ostream_type& 254 : operator<<(__streambuf_type* __sb); 255 : //@} 256 : 257 : // [27.6.2.6] unformatted output functions 258 : /** 259 : * @name Unformatted Output Functions 260 : * 261 : * All the unformatted output functions have some common behavior. 262 : * Each starts by constructing a temporary object of type 263 : * std::basic_ostream::sentry. This has several effects, concluding 264 : * with the setting of a status flag; see the sentry documentation 265 : * for more. 266 : * 267 : * If the sentry status is good, the function tries to generate 268 : * whatever data is appropriate for the type of the argument. 269 : * 270 : * If an exception is thrown during insertion, ios_base::badbit 271 : * will be turned on in the stream's error state. If badbit is on in 272 : * the stream's exceptions mask, the exception will be rethrown 273 : * without completing its actions. 274 : */ 275 : //@{ 276 : /** 277 : * @brief Simple insertion. 278 : * @param c The character to insert. 279 : * @return *this 280 : * 281 : * Tries to insert @a c. 282 : * 283 : * @note This function is not overloaded on signed char and 284 : * unsigned char. 285 : */ 286 : __ostream_type& 287 : put(char_type __c); 288 : 289 : // Core write functionality, without sentry. 290 : void 291 : _M_write(const char_type* __s, streamsize __n) 292 : { 293 : const streamsize __put = this->rdbuf()->sputn(__s, __n); 294 : if (__put != __n) 295 : this->setstate(ios_base::badbit); 296 : } 297 : 298 : /** 299 : * @brief Character string insertion. 300 : * @param s The array to insert. 301 : * @param n Maximum number of characters to insert. 302 : * @return *this 303 : * 304 : * Characters are copied from @a s and inserted into the stream until 305 : * one of the following happens: 306 : * 307 : * - @a n characters are inserted 308 : * - inserting into the output sequence fails (in this case, badbit 309 : * will be set in the stream's error state) 310 : * 311 : * @note This function is not overloaded on signed char and 312 : * unsigned char. 313 : */ 314 : __ostream_type& 315 : write(const char_type* __s, streamsize __n); 316 : //@} 317 : 318 : /** 319 : * @brief Synchronizing the stream buffer. 320 : * @return *this 321 : * 322 : * If @c rdbuf() is a null pointer, changes nothing. 323 : * 324 : * Otherwise, calls @c rdbuf()->pubsync(), and if that returns -1, 325 : * sets badbit. 326 : */ 327 : __ostream_type& 328 : flush(); 329 : 330 : // [27.6.2.4] seek members 331 : /** 332 : * @brief Getting the current write position. 333 : * @return A file position object. 334 : * 335 : * If @c fail() is not false, returns @c pos_type(-1) to indicate 336 : * failure. Otherwise returns @c rdbuf()->pubseekoff(0,cur,out). 337 : */ 338 : pos_type 339 : tellp(); 340 : 341 : /** 342 : * @brief Changing the current write position. 343 : * @param pos A file position object. 344 : * @return *this 345 : * 346 : * If @c fail() is not true, calls @c rdbuf()->pubseekpos(pos). If 347 : * that function fails, sets failbit. 348 : */ 349 : __ostream_type& 350 : seekp(pos_type); 351 : 352 : /** 353 : * @brief Changing the current write position. 354 : * @param off A file offset object. 355 : * @param dir The direction in which to seek. 356 : * @return *this 357 : * 358 : * If @c fail() is not true, calls @c rdbuf()->pubseekoff(off,dir). 359 : * If that function fails, sets failbit. 360 : */ 361 : __ostream_type& 362 : seekp(off_type, ios_base::seekdir); 363 : 364 : protected: 365 0 : basic_ostream() 366 0 : { this->init(0); } 367 : 368 : template<typename _ValueT> 369 : __ostream_type& 370 : _M_insert(_ValueT __v); 371 : }; 372 : 373 : /** 374 : * @brief Performs setup work for output streams. 375 : * 376 : * Objects of this class are created before all of the standard 377 : * inserters are run. It is responsible for "exception-safe prefix and 378 : * suffix operations." Additional actions may be added by the 379 : * implementation, and we list them in 380 : * http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/howto.html#5 381 : * under [27.6] notes. 382 : */ 383 : template <typename _CharT, typename _Traits> 384 : class basic_ostream<_CharT, _Traits>::sentry 385 : { 386 : // Data Members: 387 : bool _M_ok; 388 : basic_ostream<_CharT, _Traits>& _M_os; 389 : 390 : public: 391 : /** 392 : * @brief The constructor performs preparatory work. 393 : * @param os The output stream to guard. 394 : * 395 : * If the stream state is good (@a os.good() is true), then if the 396 : * stream is tied to another output stream, @c is.tie()->flush() 397 : * is called to synchronize the output sequences. 398 : * 399 : * If the stream state is still good, then the sentry state becomes 400 : * true ("okay"). 401 : */ 402 : explicit 403 : sentry(basic_ostream<_CharT, _Traits>& __os); 404 : 405 : /** 406 : * @brief Possibly flushes the stream. 407 : * 408 : * If @c ios_base::unitbuf is set in @c os.flags(), and 409 : * @c std::uncaught_exception() is true, the sentry destructor calls 410 : * @c flush() on the output stream. 411 : */ 412 : ~sentry() 413 : { 414 : // XXX MT 415 : if (bool(_M_os.flags() & ios_base::unitbuf) && !uncaught_exception()) 416 : { 417 : // Can't call flush directly or else will get into recursive lock. 418 : if (_M_os.rdbuf() && _M_os.rdbuf()->pubsync() == -1) 419 : _M_os.setstate(ios_base::badbit); 420 : } 421 : } 422 : 423 : /** 424 : * @brief Quick status checking. 425 : * @return The sentry state. 426 : * 427 : * For ease of use, sentries may be converted to booleans. The 428 : * return value is that of the sentry state (true == okay). 429 : */ 430 : operator bool() const 431 : { return _M_ok; } 432 : }; 433 : 434 : // [27.6.2.5.4] character insertion templates 435 : //@{ 436 : /** 437 : * @brief Character inserters 438 : * @param out An output stream. 439 : * @param c A character. 440 : * @return out 441 : * 442 : * Behaves like one of the formatted arithmetic inserters described in 443 : * std::basic_ostream. After constructing a sentry object with good 444 : * status, this function inserts a single character and any required 445 : * padding (as determined by [22.2.2.2.2]). @c out.width(0) is then 446 : * called. 447 : * 448 : * If @a c is of type @c char and the character type of the stream is not 449 : * @c char, the character is widened before insertion. 450 : */ 451 : template<typename _CharT, typename _Traits> 452 : inline basic_ostream<_CharT, _Traits>& 453 : operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) 454 : { return __ostream_insert(__out, &__c, 1); } 455 : 456 : template<typename _CharT, typename _Traits> 457 : inline basic_ostream<_CharT, _Traits>& 458 : operator<<(basic_ostream<_CharT, _Traits>& __out, char __c) 459 : { return (__out << __out.widen(__c)); } 460 : 461 : // Specialization 462 : template <class _Traits> 463 : inline basic_ostream<char, _Traits>& 464 0 : operator<<(basic_ostream<char, _Traits>& __out, char __c) 465 0 : { return __ostream_insert(__out, &__c, 1); } 466 : 467 : // Signed and unsigned 468 : template<class _Traits> 469 : inline basic_ostream<char, _Traits>& 470 : operator<<(basic_ostream<char, _Traits>& __out, signed char __c) 471 : { return (__out << static_cast<char>(__c)); } 472 : 473 : template<class _Traits> 474 : inline basic_ostream<char, _Traits>& 475 : operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c) 476 : { return (__out << static_cast<char>(__c)); } 477 : //@} 478 : 479 : //@{ 480 : /** 481 : * @brief String inserters 482 : * @param out An output stream. 483 : * @param s A character string. 484 : * @return out 485 : * @pre @a s must be a non-NULL pointer 486 : * 487 : * Behaves like one of the formatted arithmetic inserters described in 488 : * std::basic_ostream. After constructing a sentry object with good 489 : * status, this function inserts @c traits::length(s) characters starting 490 : * at @a s, widened if necessary, followed by any required padding (as 491 : * determined by [22.2.2.2.2]). @c out.width(0) is then called. 492 : */ 493 : template<typename _CharT, typename _Traits> 494 : inline basic_ostream<_CharT, _Traits>& 495 : operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s) 496 : { 497 : if (!__s) 498 : __out.setstate(ios_base::badbit); 499 : else 500 : __ostream_insert(__out, __s, 501 : static_cast<streamsize>(_Traits::length(__s))); 502 : return __out; 503 : } 504 : 505 : template<typename _CharT, typename _Traits> 506 : basic_ostream<_CharT, _Traits> & 507 : operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s); 508 : 509 : // Partial specializations 510 : template<class _Traits> 511 : inline basic_ostream<char, _Traits>& 512 0 : operator<<(basic_ostream<char, _Traits>& __out, const char* __s) 513 : { 514 0 : if (!__s) 515 0 : __out.setstate(ios_base::badbit); 516 : else 517 0 : __ostream_insert(__out, __s, 518 : static_cast<streamsize>(_Traits::length(__s))); 519 0 : return __out; 520 : } 521 : 522 : // Signed and unsigned 523 : template<class _Traits> 524 : inline basic_ostream<char, _Traits>& 525 : operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s) 526 : { return (__out << reinterpret_cast<const char*>(__s)); } 527 : 528 : template<class _Traits> 529 : inline basic_ostream<char, _Traits> & 530 : operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s) 531 : { return (__out << reinterpret_cast<const char*>(__s)); } 532 : //@} 533 : 534 : // [27.6.2.7] standard basic_ostream manipulators 535 : /** 536 : * @brief Write a newline and flush the stream. 537 : * 538 : * This manipulator is often mistakenly used when a simple newline is 539 : * desired, leading to poor buffering performance. See 540 : * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 for more 541 : * on this subject. 542 : */ 543 : template<typename _CharT, typename _Traits> 544 : inline basic_ostream<_CharT, _Traits>& 545 0 : endl(basic_ostream<_CharT, _Traits>& __os) 546 0 : { return flush(__os.put(__os.widen('\n'))); } 547 : 548 : /** 549 : * @brief Write a null character into the output sequence. 550 : * 551 : * "Null character" is @c CharT() by definition. For CharT of @c char, 552 : * this correctly writes the ASCII @c NUL character string terminator. 553 : */ 554 : template<typename _CharT, typename _Traits> 555 : inline basic_ostream<_CharT, _Traits>& 556 : ends(basic_ostream<_CharT, _Traits>& __os) 557 : { return __os.put(_CharT()); } 558 : 559 : /** 560 : * @brief Flushes the output stream. 561 : * 562 : * This manipulator simply calls the stream's @c flush() member function. 563 : */ 564 : template<typename _CharT, typename _Traits> 565 : inline basic_ostream<_CharT, _Traits>& 566 0 : flush(basic_ostream<_CharT, _Traits>& __os) 567 0 : { return __os.flush(); } 568 : 569 : _GLIBCXX_END_NAMESPACE 570 : 571 : #ifndef _GLIBCXX_EXPORT_TEMPLATE 572 : # include <bits/ostream.tcc> 573 : #endif 574 : 575 : #endif /* _GLIBCXX_OSTREAM */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* Threads compatibility routines for libgcc2 and libobjc. */ 2 : /* Compile this one with gcc. */ 3 : /* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : Free Software Foundation, Inc. 5 : 6 : This file is part of GCC. 7 : 8 : GCC is free software; you can redistribute it and/or modify it under 9 : the terms of the GNU General Public License as published by the Free 10 : Software Foundation; either version 2, or (at your option) any later 11 : version. 12 : 13 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 : WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 : for more details. 17 : 18 : You should have received a copy of the GNU General Public License 19 : along with GCC; see the file COPYING. If not, write to the Free 20 : Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 21 : 02110-1301, USA. */ 22 : 23 : /* As a special exception, if you link this library with other files, 24 : some of which are compiled with GCC, to produce an executable, 25 : this library does not by itself cause the resulting executable 26 : to be covered by the GNU General Public License. 27 : This exception does not however invalidate any other reasons why 28 : the executable file might be covered by the GNU General Public License. */ 29 : 30 : #ifndef _GLIBCXX_GCC_GTHR_POSIX_H 31 : #define _GLIBCXX_GCC_GTHR_POSIX_H 32 : 33 : /* POSIX threads specific definitions. 34 : Easy, since the interface is just one-to-one mapping. */ 35 : 36 : #define __GTHREADS 1 37 : 38 : /* Some implementations of <pthread.h> require this to be defined. */ 39 : #if !defined(_REENTRANT) && defined(__osf__) 40 : #define _REENTRANT 1 41 : #endif 42 : 43 : #include <pthread.h> 44 : #include <unistd.h> 45 : 46 : typedef pthread_key_t __gthread_key_t; 47 : typedef pthread_once_t __gthread_once_t; 48 : typedef pthread_mutex_t __gthread_mutex_t; 49 : typedef pthread_mutex_t __gthread_recursive_mutex_t; 50 : typedef pthread_cond_t __gthread_cond_t; 51 : 52 : /* POSIX like conditional variables are supported. Please look at comments 53 : in gthr.h for details. */ 54 : #define __GTHREAD_HAS_COND 1 55 : 56 : #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER 57 : #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT 58 : #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) 59 : #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER 60 : #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) 61 : #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 62 : #else 63 : #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function 64 : #endif 65 : #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER 66 : 67 : #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK 68 : # ifndef __gthrw_pragma 69 : # define __gthrw_pragma(pragma) 70 : # endif 71 : # define __gthrw2(name,name2,type) \ 72 : static __typeof(type) name __attribute__ ((__weakref__(#name2))); \ 73 : __gthrw_pragma(weak type) 74 : # define __gthrw_(name) __gthrw_ ## name 75 : #else 76 : # define __gthrw2(name,name2,type) 77 : # define __gthrw_(name) name 78 : #endif 79 : 80 : /* Typically, __gthrw_foo is a weak reference to symbol foo. */ 81 : #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name) 82 : 83 : /* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to 84 : map a subset of the POSIX pthread API to mangled versions of their 85 : names. */ 86 : #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_) 87 : #define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name) 88 : __gthrw3(pthread_once) 89 : __gthrw3(pthread_getspecific) 90 : __gthrw3(pthread_setspecific) 91 : __gthrw3(pthread_create) 92 : __gthrw3(pthread_cancel) 93 : __gthrw3(pthread_mutex_lock) 94 : __gthrw3(pthread_mutex_trylock) 95 : __gthrw3(pthread_mutex_unlock) 96 : __gthrw3(pthread_mutex_init) 97 : __gthrw3(pthread_cond_broadcast) 98 : __gthrw3(pthread_cond_wait) 99 : #else 100 : __gthrw(pthread_once) 101 : __gthrw(pthread_getspecific) 102 : __gthrw(pthread_setspecific) 103 : __gthrw(pthread_create) 104 : __gthrw(pthread_cancel) 105 : __gthrw(pthread_mutex_lock) 106 : __gthrw(pthread_mutex_trylock) 107 : __gthrw(pthread_mutex_unlock) 108 : __gthrw(pthread_mutex_init) 109 : __gthrw(pthread_cond_broadcast) 110 : __gthrw(pthread_cond_wait) 111 : #endif 112 : 113 : __gthrw(pthread_key_create) 114 : __gthrw(pthread_key_delete) 115 : __gthrw(pthread_mutexattr_init) 116 : __gthrw(pthread_mutexattr_settype) 117 : __gthrw(pthread_mutexattr_destroy) 118 : 119 : 120 : #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) 121 : /* Objective-C. */ 122 : #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_) 123 : __gthrw3(pthread_cond_destroy) 124 : __gthrw3(pthread_cond_init) 125 : __gthrw3(pthread_cond_signal) 126 : __gthrw3(pthread_exit) 127 : __gthrw3(pthread_mutex_destroy) 128 : __gthrw3(pthread_self) 129 : #else 130 : __gthrw(pthread_cond_destroy) 131 : __gthrw(pthread_cond_init) 132 : __gthrw(pthread_cond_signal) 133 : __gthrw(pthread_exit) 134 : __gthrw(pthread_mutex_destroy) 135 : __gthrw(pthread_self) 136 : #endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */ 137 : #ifdef _POSIX_PRIORITY_SCHEDULING 138 : #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 139 : __gthrw(sched_get_priority_max) 140 : __gthrw(sched_get_priority_min) 141 : #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 142 : #endif /* _POSIX_PRIORITY_SCHEDULING */ 143 : __gthrw(sched_yield) 144 : __gthrw(pthread_attr_destroy) 145 : __gthrw(pthread_attr_init) 146 : __gthrw(pthread_attr_setdetachstate) 147 : #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 148 : __gthrw(pthread_getschedparam) 149 : __gthrw(pthread_setschedparam) 150 : #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 151 : #endif /* _LIBOBJC || _LIBOBJC_WEAK */ 152 : 153 : #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK 154 : 155 : /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if 156 : -pthreads is not specified. The functions are dummies and most return an 157 : error value. However pthread_once returns 0 without invoking the routine 158 : it is passed so we cannot pretend that the interface is active if -pthreads 159 : is not specified. On Solaris 2.5.1, the interface is not exposed at all so 160 : we need to play the usual game with weak symbols. On Solaris 10 and up, a 161 : working interface is always exposed. On FreeBSD 6 and later, libc also 162 : exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up 163 : to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc, 164 : which means the alternate __gthread_active_p below cannot be used there. */ 165 : 166 : #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__)) 167 : 168 : static volatile int __gthread_active = -1; 169 : 170 : static void 171 : __gthread_trigger (void) 172 : { 173 : __gthread_active = 1; 174 : } 175 : 176 : static inline int 177 : __gthread_active_p (void) 178 : { 179 : static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; 180 : static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT; 181 : 182 : /* Avoid reading __gthread_active twice on the main code path. */ 183 : int __gthread_active_latest_value = __gthread_active; 184 : 185 : /* This test is not protected to avoid taking a lock on the main code 186 : path so every update of __gthread_active in a threaded program must 187 : be atomic with regard to the result of the test. */ 188 : if (__builtin_expect (__gthread_active_latest_value < 0, 0)) 189 : { 190 : if (__gthrw_(pthread_once)) 191 : { 192 : /* If this really is a threaded program, then we must ensure that 193 : __gthread_active has been set to 1 before exiting this block. */ 194 : __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex); 195 : __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger); 196 : __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex); 197 : } 198 : 199 : /* Make sure we'll never enter this block again. */ 200 : if (__gthread_active < 0) 201 : __gthread_active = 0; 202 : 203 : __gthread_active_latest_value = __gthread_active; 204 : } 205 : 206 : return __gthread_active_latest_value != 0; 207 : } 208 : 209 : #else /* neither FreeBSD nor Solaris */ 210 : 211 : static inline int 212 0 : __gthread_active_p (void) 213 : { 214 : static void *const __gthread_active_ptr 215 : = __extension__ (void *) &__gthrw_(pthread_cancel); 216 0 : return __gthread_active_ptr != 0; 217 : } 218 : 219 : #endif /* FreeBSD or Solaris */ 220 : 221 : #else /* not __GXX_WEAK__ */ 222 : 223 : /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread 224 : calls in shared flavors of the HP-UX C library. Most of the stubs 225 : have no functionality. The details are described in the "libc cumulative 226 : patch" for each subversion of HP-UX 11. There are two special interfaces 227 : provided for checking whether an application is linked to a pthread 228 : library or not. However, these interfaces aren't available in early 229 : libc versions. We also can't use pthread_once as some libc versions 230 : call the init function. So, we use pthread_create to check whether it 231 : is possible to create a thread or not. The stub implementation returns 232 : the error number ENOSYS. */ 233 : 234 : #if defined(__hppa__) && defined(__hpux__) 235 : 236 : #include <errno.h> 237 : 238 : static volatile int __gthread_active = -1; 239 : 240 : static void * 241 : __gthread_start (void *arg __attribute__((unused))) 242 : { 243 : return NULL; 244 : } 245 : 246 : static void __gthread_active_init (void) __attribute__((noinline)); 247 : static void 248 : __gthread_active_init (void) 249 : { 250 : static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; 251 : pthread_t t; 252 : pthread_attr_t a; 253 : int result; 254 : 255 : __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex); 256 : if (__gthread_active < 0) 257 : { 258 : __gthrw_(pthread_attr_init) (&a); 259 : __gthrw_(pthread_attr_setdetachstate) (&a, PTHREAD_CREATE_DETACHED); 260 : result = __gthrw_(pthread_create) (&t, &a, __gthread_start, NULL); 261 : if (result != ENOSYS) 262 : __gthread_active = 1; 263 : else 264 : __gthread_active = 0; 265 : __gthrw_(pthread_attr_destroy) (&a); 266 : } 267 : __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex); 268 : } 269 : 270 : static inline int 271 : __gthread_active_p (void) 272 : { 273 : /* Avoid reading __gthread_active twice on the main code path. */ 274 : int __gthread_active_latest_value = __gthread_active; 275 : 276 : /* This test is not protected to avoid taking a lock on the main code 277 : path so every update of __gthread_active in a threaded program must 278 : be atomic with regard to the result of the test. */ 279 : if (__builtin_expect (__gthread_active_latest_value < 0, 0)) 280 : { 281 : __gthread_active_init (); 282 : __gthread_active_latest_value = __gthread_active; 283 : } 284 : 285 : return __gthread_active_latest_value != 0; 286 : } 287 : 288 : #else /* not hppa-hpux */ 289 : 290 : static inline int 291 : __gthread_active_p (void) 292 : { 293 : return 1; 294 : } 295 : 296 : #endif /* hppa-hpux */ 297 : 298 : #endif /* __GXX_WEAK__ */ 299 : 300 : #ifdef _LIBOBJC 301 : 302 : /* This is the config.h file in libobjc/ */ 303 : #include <config.h> 304 : 305 : #ifdef HAVE_SCHED_H 306 : # include <sched.h> 307 : #endif 308 : 309 : /* Key structure for maintaining thread specific storage */ 310 : static pthread_key_t _objc_thread_storage; 311 : static pthread_attr_t _objc_thread_attribs; 312 : 313 : /* Thread local storage for a single thread */ 314 : static void *thread_local_storage = NULL; 315 : 316 : /* Backend initialization functions */ 317 : 318 : /* Initialize the threads subsystem. */ 319 : static inline int 320 : __gthread_objc_init_thread_system (void) 321 : { 322 : if (__gthread_active_p ()) 323 : { 324 : /* Initialize the thread storage key. */ 325 : if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0) 326 : { 327 : /* The normal default detach state for threads is 328 : * PTHREAD_CREATE_JOINABLE which causes threads to not die 329 : * when you think they should. */ 330 : if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0 331 : && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs, 332 : PTHREAD_CREATE_DETACHED) == 0) 333 : return 0; 334 : } 335 : } 336 : 337 : return -1; 338 : } 339 : 340 : /* Close the threads subsystem. */ 341 : static inline int 342 : __gthread_objc_close_thread_system (void) 343 : { 344 : if (__gthread_active_p () 345 : && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0 346 : && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0) 347 : return 0; 348 : 349 : return -1; 350 : } 351 : 352 : /* Backend thread functions */ 353 : 354 : /* Create a new thread of execution. */ 355 : static inline objc_thread_t 356 : __gthread_objc_thread_detach (void (*func)(void *), void *arg) 357 : { 358 : objc_thread_t thread_id; 359 : pthread_t new_thread_handle; 360 : 361 : if (!__gthread_active_p ()) 362 : return NULL; 363 : 364 : if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg))) 365 : thread_id = (objc_thread_t) new_thread_handle; 366 : else 367 : thread_id = NULL; 368 : 369 : return thread_id; 370 : } 371 : 372 : /* Set the current thread's priority. */ 373 : static inline int 374 : __gthread_objc_thread_set_priority (int priority) 375 : { 376 : if (!__gthread_active_p ()) 377 : return -1; 378 : else 379 : { 380 : #ifdef _POSIX_PRIORITY_SCHEDULING 381 : #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 382 : pthread_t thread_id = __gthrw_(pthread_self) (); 383 : int policy; 384 : struct sched_param params; 385 : int priority_min, priority_max; 386 : 387 : if (__gthrw_(pthread_getschedparam) (thread_id, &policy, ¶ms) == 0) 388 : { 389 : if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1) 390 : return -1; 391 : 392 : if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1) 393 : return -1; 394 : 395 : if (priority > priority_max) 396 : priority = priority_max; 397 : else if (priority < priority_min) 398 : priority = priority_min; 399 : params.sched_priority = priority; 400 : 401 : /* 402 : * The solaris 7 and several other man pages incorrectly state that 403 : * this should be a pointer to policy but pthread.h is universally 404 : * at odds with this. 405 : */ 406 : if (__gthrw_(pthread_setschedparam) (thread_id, policy, ¶ms) == 0) 407 : return 0; 408 : } 409 : #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 410 : #endif /* _POSIX_PRIORITY_SCHEDULING */ 411 : return -1; 412 : } 413 : } 414 : 415 : /* Return the current thread's priority. */ 416 : static inline int 417 : __gthread_objc_thread_get_priority (void) 418 : { 419 : #ifdef _POSIX_PRIORITY_SCHEDULING 420 : #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 421 : if (__gthread_active_p ()) 422 : { 423 : int policy; 424 : struct sched_param params; 425 : 426 : if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, ¶ms) == 0) 427 : return params.sched_priority; 428 : else 429 : return -1; 430 : } 431 : else 432 : #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 433 : #endif /* _POSIX_PRIORITY_SCHEDULING */ 434 : return OBJC_THREAD_INTERACTIVE_PRIORITY; 435 : } 436 : 437 : /* Yield our process time to another thread. */ 438 : static inline void 439 : __gthread_objc_thread_yield (void) 440 : { 441 : if (__gthread_active_p ()) 442 : __gthrw_(sched_yield) (); 443 : } 444 : 445 : /* Terminate the current thread. */ 446 : static inline int 447 : __gthread_objc_thread_exit (void) 448 : { 449 : if (__gthread_active_p ()) 450 : /* exit the thread */ 451 : __gthrw_(pthread_exit) (&__objc_thread_exit_status); 452 : 453 : /* Failed if we reached here */ 454 : return -1; 455 : } 456 : 457 : /* Returns an integer value which uniquely describes a thread. */ 458 : static inline objc_thread_t 459 : __gthread_objc_thread_id (void) 460 : { 461 : if (__gthread_active_p ()) 462 : return (objc_thread_t) __gthrw_(pthread_self) (); 463 : else 464 : return (objc_thread_t) 1; 465 : } 466 : 467 : /* Sets the thread's local storage pointer. */ 468 : static inline int 469 : __gthread_objc_thread_set_data (void *value) 470 : { 471 : if (__gthread_active_p ()) 472 : return __gthrw_(pthread_setspecific) (_objc_thread_storage, value); 473 : else 474 : { 475 : thread_local_storage = value; 476 : return 0; 477 : } 478 : } 479 : 480 : /* Returns the thread's local storage pointer. */ 481 : static inline void * 482 : __gthread_objc_thread_get_data (void) 483 : { 484 : if (__gthread_active_p ()) 485 : return __gthrw_(pthread_getspecific) (_objc_thread_storage); 486 : else 487 : return thread_local_storage; 488 : } 489 : 490 : /* Backend mutex functions */ 491 : 492 : /* Allocate a mutex. */ 493 : static inline int 494 : __gthread_objc_mutex_allocate (objc_mutex_t mutex) 495 : { 496 : if (__gthread_active_p ()) 497 : { 498 : mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); 499 : 500 : if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL)) 501 : { 502 : objc_free (mutex->backend); 503 : mutex->backend = NULL; 504 : return -1; 505 : } 506 : } 507 : 508 : return 0; 509 : } 510 : 511 : /* Deallocate a mutex. */ 512 : static inline int 513 : __gthread_objc_mutex_deallocate (objc_mutex_t mutex) 514 : { 515 : if (__gthread_active_p ()) 516 : { 517 : int count; 518 : 519 : /* 520 : * Posix Threads specifically require that the thread be unlocked 521 : * for __gthrw_(pthread_mutex_destroy) to work. 522 : */ 523 : 524 : do 525 : { 526 : count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend); 527 : if (count < 0) 528 : return -1; 529 : } 530 : while (count); 531 : 532 : if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend)) 533 : return -1; 534 : 535 : objc_free (mutex->backend); 536 : mutex->backend = NULL; 537 : } 538 : return 0; 539 : } 540 : 541 : /* Grab a lock on a mutex. */ 542 : static inline int 543 : __gthread_objc_mutex_lock (objc_mutex_t mutex) 544 : { 545 : if (__gthread_active_p () 546 : && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0) 547 : { 548 : return -1; 549 : } 550 : 551 : return 0; 552 : } 553 : 554 : /* Try to grab a lock on a mutex. */ 555 : static inline int 556 : __gthread_objc_mutex_trylock (objc_mutex_t mutex) 557 : { 558 : if (__gthread_active_p () 559 : && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0) 560 : { 561 : return -1; 562 : } 563 : 564 : return 0; 565 : } 566 : 567 : /* Unlock the mutex */ 568 : static inline int 569 : __gthread_objc_mutex_unlock (objc_mutex_t mutex) 570 : { 571 : if (__gthread_active_p () 572 : && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0) 573 : { 574 : return -1; 575 : } 576 : 577 : return 0; 578 : } 579 : 580 : /* Backend condition mutex functions */ 581 : 582 : /* Allocate a condition. */ 583 : static inline int 584 : __gthread_objc_condition_allocate (objc_condition_t condition) 585 : { 586 : if (__gthread_active_p ()) 587 : { 588 : condition->backend = objc_malloc (sizeof (pthread_cond_t)); 589 : 590 : if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL)) 591 : { 592 : objc_free (condition->backend); 593 : condition->backend = NULL; 594 : return -1; 595 : } 596 : } 597 : 598 : return 0; 599 : } 600 : 601 : /* Deallocate a condition. */ 602 : static inline int 603 : __gthread_objc_condition_deallocate (objc_condition_t condition) 604 : { 605 : if (__gthread_active_p ()) 606 : { 607 : if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend)) 608 : return -1; 609 : 610 : objc_free (condition->backend); 611 : condition->backend = NULL; 612 : } 613 : return 0; 614 : } 615 : 616 : /* Wait on the condition */ 617 : static inline int 618 : __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) 619 : { 620 : if (__gthread_active_p ()) 621 : return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend, 622 : (pthread_mutex_t *) mutex->backend); 623 : else 624 : return 0; 625 : } 626 : 627 : /* Wake up all threads waiting on this condition. */ 628 : static inline int 629 : __gthread_objc_condition_broadcast (objc_condition_t condition) 630 : { 631 : if (__gthread_active_p ()) 632 : return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend); 633 : else 634 : return 0; 635 : } 636 : 637 : /* Wake up one thread waiting on this condition. */ 638 : static inline int 639 : __gthread_objc_condition_signal (objc_condition_t condition) 640 : { 641 : if (__gthread_active_p ()) 642 : return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend); 643 : else 644 : return 0; 645 : } 646 : 647 : #else /* _LIBOBJC */ 648 : 649 : static inline int 650 : __gthread_once (__gthread_once_t *once, void (*func) (void)) 651 : { 652 : if (__gthread_active_p ()) 653 : return __gthrw_(pthread_once) (once, func); 654 : else 655 : return -1; 656 : } 657 : 658 : static inline int 659 : __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) 660 : { 661 : return __gthrw_(pthread_key_create) (key, dtor); 662 : } 663 : 664 : static inline int 665 : __gthread_key_delete (__gthread_key_t key) 666 : { 667 : return __gthrw_(pthread_key_delete) (key); 668 : } 669 : 670 : static inline void * 671 : __gthread_getspecific (__gthread_key_t key) 672 : { 673 : return __gthrw_(pthread_getspecific) (key); 674 : } 675 : 676 : static inline int 677 : __gthread_setspecific (__gthread_key_t key, const void *ptr) 678 : { 679 : return __gthrw_(pthread_setspecific) (key, ptr); 680 : } 681 : 682 : static inline int 683 : __gthread_mutex_lock (__gthread_mutex_t *mutex) 684 : { 685 : if (__gthread_active_p ()) 686 : return __gthrw_(pthread_mutex_lock) (mutex); 687 : else 688 : return 0; 689 : } 690 : 691 : static inline int 692 : __gthread_mutex_trylock (__gthread_mutex_t *mutex) 693 : { 694 : if (__gthread_active_p ()) 695 : return __gthrw_(pthread_mutex_trylock) (mutex); 696 : else 697 : return 0; 698 : } 699 : 700 : static inline int 701 : __gthread_mutex_unlock (__gthread_mutex_t *mutex) 702 : { 703 : if (__gthread_active_p ()) 704 : return __gthrw_(pthread_mutex_unlock) (mutex); 705 : else 706 : return 0; 707 : } 708 : 709 : #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 710 : static inline int 711 : __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex) 712 : { 713 : if (__gthread_active_p ()) 714 : { 715 : pthread_mutexattr_t attr; 716 : int r; 717 : 718 : r = __gthrw_(pthread_mutexattr_init) (&attr); 719 : if (!r) 720 : r = __gthrw_(pthread_mutexattr_settype) (&attr, PTHREAD_MUTEX_RECURSIVE); 721 : if (!r) 722 : r = __gthrw_(pthread_mutex_init) (mutex, &attr); 723 : if (!r) 724 : r = __gthrw_(pthread_mutexattr_destroy) (&attr); 725 : return r; 726 : } 727 : return 0; 728 : } 729 : #endif 730 : 731 : static inline int 732 : __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex) 733 : { 734 : return __gthread_mutex_lock (mutex); 735 : } 736 : 737 : static inline int 738 : __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex) 739 : { 740 : return __gthread_mutex_trylock (mutex); 741 : } 742 : 743 : static inline int 744 : __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex) 745 : { 746 : return __gthread_mutex_unlock (mutex); 747 : } 748 : 749 : static inline int 750 : __gthread_cond_broadcast (__gthread_cond_t *cond) 751 : { 752 : return __gthrw_(pthread_cond_broadcast) (cond); 753 : } 754 : 755 : static inline int 756 : __gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex) 757 : { 758 : return __gthrw_(pthread_cond_wait) (cond, mutex); 759 : } 760 : 761 : static inline int 762 : __gthread_cond_wait_recursive (__gthread_cond_t *cond, 763 : __gthread_recursive_mutex_t *mutex) 764 : { 765 : return __gthread_cond_wait (cond, mutex); 766 : } 767 : 768 : #endif /* _LIBOBJC */ 769 : 770 : #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
gthr-default.h |
|
0.0 % | 0 / 2 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // RTTI support for -*- C++ -*- 2 : // Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 3 : // 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation 5 : // 6 : // This file is part of GCC. 7 : // 8 : // GCC is free software; you can redistribute it and/or modify 9 : // it under the terms of the GNU General Public License as published by 10 : // the Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : // 13 : // GCC is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : // 18 : // You should have received a copy of the GNU General Public License 19 : // along with GCC; see the file COPYING. If not, write to 20 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 21 : // Boston, MA 02110-1301, USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file typeinfo 33 : * This is a Standard C++ Library header. 34 : */ 35 : 36 : #ifndef _TYPEINFO 37 : #define _TYPEINFO 38 : 39 : #include <exception> 40 : 41 : #pragma GCC visibility push(default) 42 : 43 : extern "C++" { 44 : 45 : namespace __cxxabiv1 46 : { 47 : class __class_type_info; 48 : } // namespace __cxxabiv1 49 : 50 : // Determine whether typeinfo names for the same type are merged (in which 51 : // case comparison can just compare pointers) or not (in which case 52 : // strings must be compared and g++.dg/abi/local1.C will fail), and 53 : // whether comparison is to be implemented inline or not. By default we 54 : // use inline pointer comparison if weak symbols are available, and 55 : // out-of-line strcmp if not. Out-of-line pointer comparison is used 56 : // where the object files are to be portable to multiple systems, some of 57 : // which may not be able to use pointer comparison, but the particular 58 : // system for which libstdc++ is being built can use pointer comparison; 59 : // in particular for most ARM EABI systems, where the ABI specifies 60 : // out-of-line comparison. Inline strcmp is not currently supported. The 61 : // compiler's target configuration can override the defaults by defining 62 : // __GXX_TYPEINFO_EQUALITY_INLINE to 1 or 0 to indicate whether or not 63 : // comparison is inline, and __GXX_MERGED_TYPEINFO_NAMES to 1 or 0 to 64 : // indicate whether or not pointer comparison can be used. 65 : 66 : #ifndef __GXX_MERGED_TYPEINFO_NAMES 67 : #if !__GXX_WEAK__ 68 : // If weak symbols are not supported, typeinfo names are not merged. 69 : #define __GXX_MERGED_TYPEINFO_NAMES 0 70 : #else 71 : // On platforms that support weak symbols, typeinfo names are merged. 72 : #define __GXX_MERGED_TYPEINFO_NAMES 1 73 : #endif 74 : #endif 75 : 76 : // By default follow the same rules as for __GXX_MERGED_TYPEINFO_NAMES. 77 : #ifndef __GXX_TYPEINFO_EQUALITY_INLINE 78 : #if !__GXX_WEAK__ 79 : #define __GXX_TYPEINFO_EQUALITY_INLINE 0 80 : #else 81 : #define __GXX_TYPEINFO_EQUALITY_INLINE 1 82 : #endif 83 : #endif 84 : 85 : namespace std 86 : { 87 : /** 88 : * @brief Part of RTTI. 89 : * 90 : * The @c type_info class describes type information generated by 91 : * an implementation. 92 : */ 93 : class type_info 94 : { 95 : public: 96 : /** Destructor first. Being the first non-inline virtual function, this 97 : * controls in which translation unit the vtable is emitted. The 98 : * compiler makes use of that information to know where to emit 99 : * the runtime-mandated type_info structures in the new-abi. */ 100 : virtual ~type_info(); 101 : 102 : /** Returns an @e implementation-defined byte string; this is not 103 : * portable between compilers! */ 104 2 : const char* name() const 105 2 : { return __name; } 106 : 107 : #if !__GXX_TYPEINFO_EQUALITY_INLINE 108 : bool before(const type_info& __arg) const; 109 : 110 : // In old abi, or when weak symbols are not supported, there can 111 : // be multiple instances of a type_info object for one 112 : // type. Uniqueness must use the _name value, not object address. 113 : bool operator==(const type_info& __arg) const; 114 : #else 115 : #if !__GXX_MERGED_TYPEINFO_NAMES 116 : #error "Inline implementation of type_info comparision requires merging of type_info objects" 117 : #endif 118 : /** Returns true if @c *this precedes @c __arg in the implementation's 119 : * collation order. */ 120 : // In new abi we can rely on type_info's NTBS being unique, 121 : // and therefore address comparisons are sufficient. 122 0 : bool before(const type_info& __arg) const 123 0 : { return __name < __arg.__name; } 124 : 125 : bool operator==(const type_info& __arg) const 126 : { return __name == __arg.__name; } 127 : #endif 128 : bool operator!=(const type_info& __arg) const 129 : { return !operator==(__arg); } 130 : 131 : // Return true if this is a pointer type of some kind 132 : virtual bool __is_pointer_p() const; 133 : 134 : // Return true if this is a function type 135 : virtual bool __is_function_p() const; 136 : 137 : // Try and catch a thrown type. Store an adjusted pointer to the 138 : // caught type in THR_OBJ. If THR_TYPE is not a pointer type, then 139 : // THR_OBJ points to the thrown object. If THR_TYPE is a pointer 140 : // type, then THR_OBJ is the pointer itself. OUTER indicates the 141 : // number of outer pointers, and whether they were const 142 : // qualified. 143 : virtual bool __do_catch(const type_info *__thr_type, void **__thr_obj, 144 : unsigned __outer) const; 145 : 146 : // Internally used during catch matching 147 : virtual bool __do_upcast(const __cxxabiv1::__class_type_info *__target, 148 : void **__obj_ptr) const; 149 : 150 : protected: 151 : const char *__name; 152 : 153 : explicit type_info(const char *__n): __name(__n) { } 154 : 155 : private: 156 : /// Assigning type_info is not supported. 157 : type_info& operator=(const type_info&); 158 : type_info(const type_info&); 159 : }; 160 : 161 : /** 162 : * @brief Thrown during incorrect typecasting. 163 : * 164 : * If you attempt an invalid @c dynamic_cast expression, an instance of 165 : * this class (or something derived from this class) is thrown. */ 166 : class bad_cast : public exception 167 : { 168 : public: 169 : bad_cast() throw() { } 170 : 171 : // This declaration is not useless: 172 : // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 173 : virtual ~bad_cast() throw(); 174 : 175 : // See comment in eh_exception.cc. 176 : virtual const char* what() const throw(); 177 : }; 178 : 179 : /** If you use a NULL pointer in a @c typeid expression, this is thrown. */ 180 : class bad_typeid : public exception 181 : { 182 : public: 183 : bad_typeid () throw() { } 184 : 185 : // This declaration is not useless: 186 : // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 187 : virtual ~bad_typeid() throw(); 188 : 189 : // See comment in eh_exception.cc. 190 : virtual const char* what() const throw(); 191 : }; 192 : } // namespace std 193 : 194 : #pragma GCC visibility pop 195 : 196 : } // extern "C++" 197 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // File based streams -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007, 2008 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License 19 : // along with this library; see the file COPYING. If not, write to 20 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 21 : // Boston, MA 02110-1301, USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file fstream 33 : * This is a Standard C++ Library header. 34 : */ 35 : 36 : // 37 : // ISO C++ 14882: 27.8 File-based streams 38 : // 39 : 40 : #ifndef _GLIBCXX_FSTREAM 41 : #define _GLIBCXX_FSTREAM 1 42 : 43 : #pragma GCC system_header 44 : 45 : #include <istream> 46 : #include <ostream> 47 : #include <bits/codecvt.h> 48 : #include <cstdio> // For BUFSIZ 49 : #include <bits/basic_file.h> // For __basic_file, __c_lock 50 : 51 : _GLIBCXX_BEGIN_NAMESPACE(std) 52 : 53 : // [27.8.1.1] template class basic_filebuf 54 : /** 55 : * @brief The actual work of input and output (for files). 56 : * 57 : * This class associates both its input and output sequence with an 58 : * external disk file, and maintains a joint file position for both 59 : * sequences. Many of its semantics are described in terms of similar 60 : * behavior in the Standard C Library's @c FILE streams. 61 : */ 62 : // Requirements on traits_type, specific to this class: 63 : // traits_type::pos_type must be fpos<traits_type::state_type> 64 : // traits_type::off_type must be streamoff 65 : // traits_type::state_type must be Assignable and DefaultConstructible, 66 : // and traits_type::state_type() must be the initial state for codecvt. 67 : template<typename _CharT, typename _Traits> 68 : class basic_filebuf : public basic_streambuf<_CharT, _Traits> 69 : { 70 : public: 71 : // Types: 72 : typedef _CharT char_type; 73 : typedef _Traits traits_type; 74 : typedef typename traits_type::int_type int_type; 75 : typedef typename traits_type::pos_type pos_type; 76 : typedef typename traits_type::off_type off_type; 77 : 78 : typedef basic_streambuf<char_type, traits_type> __streambuf_type; 79 : typedef basic_filebuf<char_type, traits_type> __filebuf_type; 80 : typedef __basic_file<char> __file_type; 81 : typedef typename traits_type::state_type __state_type; 82 : typedef codecvt<char_type, char, __state_type> __codecvt_type; 83 : 84 : friend class ios_base; // For sync_with_stdio. 85 : 86 : protected: 87 : // Data Members: 88 : // MT lock inherited from libio or other low-level io library. 89 : __c_lock _M_lock; 90 : 91 : // External buffer. 92 : __file_type _M_file; 93 : 94 : /// Place to stash in || out || in | out settings for current filebuf. 95 : ios_base::openmode _M_mode; 96 : 97 : // Beginning state type for codecvt. 98 : __state_type _M_state_beg; 99 : 100 : // During output, the state that corresponds to pptr(), 101 : // during input, the state that corresponds to egptr() and 102 : // _M_ext_next. 103 : __state_type _M_state_cur; 104 : 105 : // Not used for output. During input, the state that corresponds 106 : // to eback() and _M_ext_buf. 107 : __state_type _M_state_last; 108 : 109 : /// Pointer to the beginning of internal buffer. 110 : char_type* _M_buf; 111 : 112 : /** 113 : * Actual size of internal buffer. This number is equal to the size 114 : * of the put area + 1 position, reserved for the overflow char of 115 : * a full area. 116 : */ 117 : size_t _M_buf_size; 118 : 119 : // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. 120 : bool _M_buf_allocated; 121 : 122 : /** 123 : * _M_reading == false && _M_writing == false for 'uncommitted' mode; 124 : * _M_reading == true for 'read' mode; 125 : * _M_writing == true for 'write' mode; 126 : * 127 : * NB: _M_reading == true && _M_writing == true is unused. 128 : */ 129 : bool _M_reading; 130 : bool _M_writing; 131 : 132 : //@{ 133 : /** 134 : * Necessary bits for putback buffer management. 135 : * 136 : * @note pbacks of over one character are not currently supported. 137 : */ 138 : char_type _M_pback; 139 : char_type* _M_pback_cur_save; 140 : char_type* _M_pback_end_save; 141 : bool _M_pback_init; 142 : //@} 143 : 144 : // Cached codecvt facet. 145 : const __codecvt_type* _M_codecvt; 146 : 147 : /** 148 : * Buffer for external characters. Used for input when 149 : * codecvt::always_noconv() == false. When valid, this corresponds 150 : * to eback(). 151 : */ 152 : char* _M_ext_buf; 153 : 154 : /** 155 : * Size of buffer held by _M_ext_buf. 156 : */ 157 : streamsize _M_ext_buf_size; 158 : 159 : /** 160 : * Pointers into the buffer held by _M_ext_buf that delimit a 161 : * subsequence of bytes that have been read but not yet converted. 162 : * When valid, _M_ext_next corresponds to egptr(). 163 : */ 164 : const char* _M_ext_next; 165 : char* _M_ext_end; 166 : 167 : /** 168 : * Initializes pback buffers, and moves normal buffers to safety. 169 : * Assumptions: 170 : * _M_in_cur has already been moved back 171 : */ 172 : void 173 : _M_create_pback() 174 : { 175 : if (!_M_pback_init) 176 : { 177 : _M_pback_cur_save = this->gptr(); 178 : _M_pback_end_save = this->egptr(); 179 : this->setg(&_M_pback, &_M_pback, &_M_pback + 1); 180 : _M_pback_init = true; 181 : } 182 : } 183 : 184 : /** 185 : * Deactivates pback buffer contents, and restores normal buffer. 186 : * Assumptions: 187 : * The pback buffer has only moved forward. 188 : */ 189 : void 190 : _M_destroy_pback() throw() 191 : { 192 : if (_M_pback_init) 193 : { 194 : // Length _M_in_cur moved in the pback buffer. 195 : _M_pback_cur_save += this->gptr() != this->eback(); 196 : this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save); 197 : _M_pback_init = false; 198 : } 199 : } 200 : 201 : public: 202 : // Constructors/destructor: 203 : /** 204 : * @brief Does not open any files. 205 : * 206 : * The default constructor initializes the parent class using its 207 : * own default ctor. 208 : */ 209 : basic_filebuf(); 210 : 211 : /** 212 : * @brief The destructor closes the file first. 213 : */ 214 : virtual 215 0 : ~basic_filebuf() 216 0 : { this->close(); } 217 : 218 : // Members: 219 : /** 220 : * @brief Returns true if the external file is open. 221 : */ 222 : bool 223 0 : is_open() const throw() 224 0 : { return _M_file.is_open(); } 225 : 226 : /** 227 : * @brief Opens an external file. 228 : * @param s The name of the file. 229 : * @param mode The open mode flags. 230 : * @return @c this on success, NULL on failure 231 : * 232 : * If a file is already open, this function immediately fails. 233 : * Otherwise it tries to open the file named @a s using the flags 234 : * given in @a mode. 235 : * 236 : * Table 92, adapted here, gives the relation between openmode 237 : * combinations and the equivalent fopen() flags. 238 : * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app, 239 : * and binary|in|app per DR 596) 240 : * +---------------------------------------------------------+ 241 : * | ios_base Flag combination stdio equivalent | 242 : * |binary in out trunc app | 243 : * +---------------------------------------------------------+ 244 : * | + "w" | 245 : * | + + "a" | 246 : * | + "a" | 247 : * | + + "w" | 248 : * | + "r" | 249 : * | + + "r+" | 250 : * | + + + "w+" | 251 : * | + + + "a+" | 252 : * | + + "a+" | 253 : * +---------------------------------------------------------+ 254 : * | + + "wb" | 255 : * | + + + "ab" | 256 : * | + + "ab" | 257 : * | + + + "wb" | 258 : * | + + "rb" | 259 : * | + + + "r+b" | 260 : * | + + + + "w+b" | 261 : * | + + + + "a+b" | 262 : * | + + + "a+b" | 263 : * +---------------------------------------------------------+ 264 : */ 265 : __filebuf_type* 266 : open(const char* __s, ios_base::openmode __mode); 267 : 268 : /** 269 : * @brief Closes the currently associated file. 270 : * @return @c this on success, NULL on failure 271 : * 272 : * If no file is currently open, this function immediately fails. 273 : * 274 : * If a "put buffer area" exists, @c overflow(eof) is called to flush 275 : * all the characters. The file is then closed. 276 : * 277 : * If any operations fail, this function also fails. 278 : */ 279 : __filebuf_type* 280 : close(); 281 : 282 : protected: 283 : void 284 : _M_allocate_internal_buffer(); 285 : 286 : void 287 : _M_destroy_internal_buffer() throw(); 288 : 289 : // [27.8.1.4] overridden virtual functions 290 : virtual streamsize 291 : showmanyc(); 292 : 293 : // Stroustrup, 1998, p. 628 294 : // underflow() and uflow() functions are called to get the next 295 : // character from the real input source when the buffer is empty. 296 : // Buffered input uses underflow() 297 : 298 : virtual int_type 299 : underflow(); 300 : 301 : virtual int_type 302 : pbackfail(int_type __c = _Traits::eof()); 303 : 304 : // Stroustrup, 1998, p 648 305 : // The overflow() function is called to transfer characters to the 306 : // real output destination when the buffer is full. A call to 307 : // overflow(c) outputs the contents of the buffer plus the 308 : // character c. 309 : // 27.5.2.4.5 310 : // Consume some sequence of the characters in the pending sequence. 311 : virtual int_type 312 : overflow(int_type __c = _Traits::eof()); 313 : 314 : // Convert internal byte sequence to external, char-based 315 : // sequence via codecvt. 316 : bool 317 : _M_convert_to_external(char_type*, streamsize); 318 : 319 : /** 320 : * @brief Manipulates the buffer. 321 : * @param s Pointer to a buffer area. 322 : * @param n Size of @a s. 323 : * @return @c this 324 : * 325 : * If no file has been opened, and both @a s and @a n are zero, then 326 : * the stream becomes unbuffered. Otherwise, @c s is used as a 327 : * buffer; see 328 : * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 329 : * for more. 330 : */ 331 : virtual __streambuf_type* 332 : setbuf(char_type* __s, streamsize __n); 333 : 334 : virtual pos_type 335 : seekoff(off_type __off, ios_base::seekdir __way, 336 : ios_base::openmode __mode = ios_base::in | ios_base::out); 337 : 338 : virtual pos_type 339 : seekpos(pos_type __pos, 340 : ios_base::openmode __mode = ios_base::in | ios_base::out); 341 : 342 : // Common code for seekoff and seekpos 343 : pos_type 344 : _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); 345 : 346 : virtual int 347 : sync(); 348 : 349 : virtual void 350 : imbue(const locale& __loc); 351 : 352 : virtual streamsize 353 : xsgetn(char_type* __s, streamsize __n); 354 : 355 : virtual streamsize 356 : xsputn(const char_type* __s, streamsize __n); 357 : 358 : // Flushes output buffer, then writes unshift sequence. 359 : bool 360 : _M_terminate_output(); 361 : 362 : /** 363 : * This function sets the pointers of the internal buffer, both get 364 : * and put areas. Typically: 365 : * 366 : * __off == egptr() - eback() upon underflow/uflow ('read' mode); 367 : * __off == 0 upon overflow ('write' mode); 368 : * __off == -1 upon open, setbuf, seekoff/pos ('uncommitted' mode). 369 : * 370 : * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size 371 : * reflects the actual allocated memory and the last cell is reserved 372 : * for the overflow char of a full put area. 373 : */ 374 : void 375 : _M_set_buffer(streamsize __off) 376 : { 377 : const bool __testin = _M_mode & ios_base::in; 378 : const bool __testout = _M_mode & ios_base::out; 379 : 380 : if (__testin && __off > 0) 381 : this->setg(_M_buf, _M_buf, _M_buf + __off); 382 : else 383 : this->setg(_M_buf, _M_buf, _M_buf); 384 : 385 : if (__testout && __off == 0 && _M_buf_size > 1 ) 386 : this->setp(_M_buf, _M_buf + _M_buf_size - 1); 387 : else 388 : this->setp(NULL, NULL); 389 : } 390 : }; 391 : 392 : // [27.8.1.5] Template class basic_ifstream 393 : /** 394 : * @brief Controlling input for files. 395 : * 396 : * This class supports reading from named files, using the inherited 397 : * functions from std::basic_istream. To control the associated 398 : * sequence, an instance of std::basic_filebuf is used, which this page 399 : * refers to as @c sb. 400 : */ 401 : template<typename _CharT, typename _Traits> 402 : class basic_ifstream : public basic_istream<_CharT, _Traits> 403 : { 404 : public: 405 : // Types: 406 : typedef _CharT char_type; 407 : typedef _Traits traits_type; 408 : typedef typename traits_type::int_type int_type; 409 : typedef typename traits_type::pos_type pos_type; 410 : typedef typename traits_type::off_type off_type; 411 : 412 : // Non-standard types: 413 : typedef basic_filebuf<char_type, traits_type> __filebuf_type; 414 : typedef basic_istream<char_type, traits_type> __istream_type; 415 : 416 : private: 417 : __filebuf_type _M_filebuf; 418 : 419 : public: 420 : // Constructors/Destructors: 421 : /** 422 : * @brief Default constructor. 423 : * 424 : * Initializes @c sb using its default constructor, and passes 425 : * @c &sb to the base class initializer. Does not open any files 426 : * (you haven't given it a filename to open). 427 : */ 428 0 : basic_ifstream() : __istream_type(), _M_filebuf() 429 0 : { this->init(&_M_filebuf); } 430 : 431 : /** 432 : * @brief Create an input file stream. 433 : * @param s Null terminated string specifying the filename. 434 : * @param mode Open file in specified mode (see std::ios_base). 435 : * 436 : * @c ios_base::in is automatically included in @a mode. 437 : * 438 : * Tip: When using std::string to hold the filename, you must use 439 : * .c_str() before passing it to this constructor. 440 : */ 441 : explicit 442 0 : basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) 443 0 : : __istream_type(), _M_filebuf() 444 : { 445 0 : this->init(&_M_filebuf); 446 0 : this->open(__s, __mode); 447 0 : } 448 : 449 : /** 450 : * @brief The destructor does nothing. 451 : * 452 : * The file is closed by the filebuf object, not the formatting 453 : * stream. 454 : */ 455 0 : ~basic_ifstream() 456 0 : { } 457 : 458 : // Members: 459 : /** 460 : * @brief Accessing the underlying buffer. 461 : * @return The current basic_filebuf buffer. 462 : * 463 : * This hides both signatures of std::basic_ios::rdbuf(). 464 : */ 465 : __filebuf_type* 466 : rdbuf() const 467 : { return const_cast<__filebuf_type*>(&_M_filebuf); } 468 : 469 : /** 470 : * @brief Wrapper to test for an open file. 471 : * @return @c rdbuf()->is_open() 472 : */ 473 : bool 474 0 : is_open() 475 0 : { return _M_filebuf.is_open(); } 476 : 477 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 478 : // 365. Lack of const-qualification in clause 27 479 : bool 480 : is_open() const 481 : { return _M_filebuf.is_open(); } 482 : 483 : /** 484 : * @brief Opens an external file. 485 : * @param s The name of the file. 486 : * @param mode The open mode flags. 487 : * 488 : * Calls @c std::basic_filebuf::open(s,mode|in). If that function 489 : * fails, @c failbit is set in the stream's error state. 490 : * 491 : * Tip: When using std::string to hold the filename, you must use 492 : * .c_str() before passing it to this constructor. 493 : */ 494 : void 495 0 : open(const char* __s, ios_base::openmode __mode = ios_base::in) 496 : { 497 0 : if (!_M_filebuf.open(__s, __mode | ios_base::in)) 498 0 : this->setstate(ios_base::failbit); 499 : else 500 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 501 : // 409. Closing an fstream should clear error state 502 0 : this->clear(); 503 0 : } 504 : 505 : /** 506 : * @brief Close the file. 507 : * 508 : * Calls @c std::basic_filebuf::close(). If that function 509 : * fails, @c failbit is set in the stream's error state. 510 : */ 511 : void 512 0 : close() 513 : { 514 0 : if (!_M_filebuf.close()) 515 0 : this->setstate(ios_base::failbit); 516 0 : } 517 : }; 518 : 519 : 520 : // [27.8.1.8] Template class basic_ofstream 521 : /** 522 : * @brief Controlling output for files. 523 : * 524 : * This class supports reading from named files, using the inherited 525 : * functions from std::basic_ostream. To control the associated 526 : * sequence, an instance of std::basic_filebuf is used, which this page 527 : * refers to as @c sb. 528 : */ 529 : template<typename _CharT, typename _Traits> 530 : class basic_ofstream : public basic_ostream<_CharT,_Traits> 531 : { 532 : public: 533 : // Types: 534 : typedef _CharT char_type; 535 : typedef _Traits traits_type; 536 : typedef typename traits_type::int_type int_type; 537 : typedef typename traits_type::pos_type pos_type; 538 : typedef typename traits_type::off_type off_type; 539 : 540 : // Non-standard types: 541 : typedef basic_filebuf<char_type, traits_type> __filebuf_type; 542 : typedef basic_ostream<char_type, traits_type> __ostream_type; 543 : 544 : private: 545 : __filebuf_type _M_filebuf; 546 : 547 : public: 548 : // Constructors: 549 : /** 550 : * @brief Default constructor. 551 : * 552 : * Initializes @c sb using its default constructor, and passes 553 : * @c &sb to the base class initializer. Does not open any files 554 : * (you haven't given it a filename to open). 555 : */ 556 : basic_ofstream(): __ostream_type(), _M_filebuf() 557 : { this->init(&_M_filebuf); } 558 : 559 : /** 560 : * @brief Create an output file stream. 561 : * @param s Null terminated string specifying the filename. 562 : * @param mode Open file in specified mode (see std::ios_base). 563 : * 564 : * @c ios_base::out|ios_base::trunc is automatically included in 565 : * @a mode. 566 : * 567 : * Tip: When using std::string to hold the filename, you must use 568 : * .c_str() before passing it to this constructor. 569 : */ 570 : explicit 571 : basic_ofstream(const char* __s, 572 0 : ios_base::openmode __mode = ios_base::out|ios_base::trunc) 573 0 : : __ostream_type(), _M_filebuf() 574 : { 575 0 : this->init(&_M_filebuf); 576 0 : this->open(__s, __mode); 577 0 : } 578 : 579 : /** 580 : * @brief The destructor does nothing. 581 : * 582 : * The file is closed by the filebuf object, not the formatting 583 : * stream. 584 : */ 585 0 : ~basic_ofstream() 586 0 : { } 587 : 588 : // Members: 589 : /** 590 : * @brief Accessing the underlying buffer. 591 : * @return The current basic_filebuf buffer. 592 : * 593 : * This hides both signatures of std::basic_ios::rdbuf(). 594 : */ 595 : __filebuf_type* 596 : rdbuf() const 597 : { return const_cast<__filebuf_type*>(&_M_filebuf); } 598 : 599 : /** 600 : * @brief Wrapper to test for an open file. 601 : * @return @c rdbuf()->is_open() 602 : */ 603 : bool 604 0 : is_open() 605 0 : { return _M_filebuf.is_open(); } 606 : 607 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 608 : // 365. Lack of const-qualification in clause 27 609 : bool 610 : is_open() const 611 : { return _M_filebuf.is_open(); } 612 : 613 : /** 614 : * @brief Opens an external file. 615 : * @param s The name of the file. 616 : * @param mode The open mode flags. 617 : * 618 : * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that 619 : * function fails, @c failbit is set in the stream's error state. 620 : * 621 : * Tip: When using std::string to hold the filename, you must use 622 : * .c_str() before passing it to this constructor. 623 : */ 624 : void 625 : open(const char* __s, 626 0 : ios_base::openmode __mode = ios_base::out | ios_base::trunc) 627 : { 628 0 : if (!_M_filebuf.open(__s, __mode | ios_base::out)) 629 0 : this->setstate(ios_base::failbit); 630 : else 631 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 632 : // 409. Closing an fstream should clear error state 633 0 : this->clear(); 634 0 : } 635 : 636 : /** 637 : * @brief Close the file. 638 : * 639 : * Calls @c std::basic_filebuf::close(). If that function 640 : * fails, @c failbit is set in the stream's error state. 641 : */ 642 : void 643 : close() 644 : { 645 : if (!_M_filebuf.close()) 646 : this->setstate(ios_base::failbit); 647 : } 648 : }; 649 : 650 : 651 : // [27.8.1.11] Template class basic_fstream 652 : /** 653 : * @brief Controlling input and output for files. 654 : * 655 : * This class supports reading from and writing to named files, using 656 : * the inherited functions from std::basic_iostream. To control the 657 : * associated sequence, an instance of std::basic_filebuf is used, which 658 : * this page refers to as @c sb. 659 : */ 660 : template<typename _CharT, typename _Traits> 661 : class basic_fstream : public basic_iostream<_CharT, _Traits> 662 : { 663 : public: 664 : // Types: 665 : typedef _CharT char_type; 666 : typedef _Traits traits_type; 667 : typedef typename traits_type::int_type int_type; 668 : typedef typename traits_type::pos_type pos_type; 669 : typedef typename traits_type::off_type off_type; 670 : 671 : // Non-standard types: 672 : typedef basic_filebuf<char_type, traits_type> __filebuf_type; 673 : typedef basic_ios<char_type, traits_type> __ios_type; 674 : typedef basic_iostream<char_type, traits_type> __iostream_type; 675 : 676 : private: 677 : __filebuf_type _M_filebuf; 678 : 679 : public: 680 : // Constructors/destructor: 681 : /** 682 : * @brief Default constructor. 683 : * 684 : * Initializes @c sb using its default constructor, and passes 685 : * @c &sb to the base class initializer. Does not open any files 686 : * (you haven't given it a filename to open). 687 : */ 688 : basic_fstream() 689 : : __iostream_type(), _M_filebuf() 690 : { this->init(&_M_filebuf); } 691 : 692 : /** 693 : * @brief Create an input/output file stream. 694 : * @param s Null terminated string specifying the filename. 695 : * @param mode Open file in specified mode (see std::ios_base). 696 : * 697 : * Tip: When using std::string to hold the filename, you must use 698 : * .c_str() before passing it to this constructor. 699 : */ 700 : explicit 701 : basic_fstream(const char* __s, 702 : ios_base::openmode __mode = ios_base::in | ios_base::out) 703 : : __iostream_type(NULL), _M_filebuf() 704 : { 705 : this->init(&_M_filebuf); 706 : this->open(__s, __mode); 707 : } 708 : 709 : /** 710 : * @brief The destructor does nothing. 711 : * 712 : * The file is closed by the filebuf object, not the formatting 713 : * stream. 714 : */ 715 : ~basic_fstream() 716 : { } 717 : 718 : // Members: 719 : /** 720 : * @brief Accessing the underlying buffer. 721 : * @return The current basic_filebuf buffer. 722 : * 723 : * This hides both signatures of std::basic_ios::rdbuf(). 724 : */ 725 : __filebuf_type* 726 : rdbuf() const 727 : { return const_cast<__filebuf_type*>(&_M_filebuf); } 728 : 729 : /** 730 : * @brief Wrapper to test for an open file. 731 : * @return @c rdbuf()->is_open() 732 : */ 733 : bool 734 : is_open() 735 : { return _M_filebuf.is_open(); } 736 : 737 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 738 : // 365. Lack of const-qualification in clause 27 739 : bool 740 : is_open() const 741 : { return _M_filebuf.is_open(); } 742 : 743 : /** 744 : * @brief Opens an external file. 745 : * @param s The name of the file. 746 : * @param mode The open mode flags. 747 : * 748 : * Calls @c std::basic_filebuf::open(s,mode). If that 749 : * function fails, @c failbit is set in the stream's error state. 750 : * 751 : * Tip: When using std::string to hold the filename, you must use 752 : * .c_str() before passing it to this constructor. 753 : */ 754 : void 755 : open(const char* __s, 756 : ios_base::openmode __mode = ios_base::in | ios_base::out) 757 : { 758 : if (!_M_filebuf.open(__s, __mode)) 759 : this->setstate(ios_base::failbit); 760 : else 761 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 762 : // 409. Closing an fstream should clear error state 763 : this->clear(); 764 : } 765 : 766 : /** 767 : * @brief Close the file. 768 : * 769 : * Calls @c std::basic_filebuf::close(). If that function 770 : * fails, @c failbit is set in the stream's error state. 771 : */ 772 : void 773 : close() 774 : { 775 : if (!_M_filebuf.close()) 776 : this->setstate(ios_base::failbit); 777 : } 778 : }; 779 : 780 : _GLIBCXX_END_NAMESPACE 781 : 782 : #ifndef _GLIBCXX_EXPORT_TEMPLATE 783 : # include <bits/fstream.tcc> 784 : #endif 785 : 786 : #endif /* _GLIBCXX_FSTREAM */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // The -*- C++ -*- dynamic memory management header. 2 : 3 : // Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 4 : // 2003, 2004, 2005, 2006, 2007 5 : // Free Software Foundation 6 : 7 : // This file is part of GCC. 8 : // 9 : // GCC is free software; you can redistribute it and/or modify 10 : // it under the terms of the GNU General Public License as published by 11 : // the Free Software Foundation; either version 2, or (at your option) 12 : // any later version. 13 : // 14 : // GCC is distributed in the hope that it will be useful, 15 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : // GNU General Public License for more details. 18 : // 19 : // You should have received a copy of the GNU General Public License 20 : // along with GCC; see the file COPYING. If not, write to 21 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 22 : // Boston, MA 02110-1301, USA. 23 : 24 : // As a special exception, you may use this file as part of a free software 25 : // library without restriction. Specifically, if other files instantiate 26 : // templates or use macros or inline functions from this file, or you compile 27 : // this file and link it with other files to produce an executable, this 28 : // file does not by itself cause the resulting executable to be covered by 29 : // the GNU General Public License. This exception does not however 30 : // invalidate any other reasons why the executable file might be covered by 31 : // the GNU General Public License. 32 : 33 : /** @file new 34 : * This is a Standard C++ Library header. 35 : * 36 : * The header @c new defines several functions to manage dynamic memory and 37 : * handling memory allocation errors; see 38 : * http://gcc.gnu.org/onlinedocs/libstdc++/18_support/howto.html#4 for more. 39 : */ 40 : 41 : #ifndef _NEW 42 : #define _NEW 43 : 44 : #include <cstddef> 45 : #include <exception> 46 : 47 : #pragma GCC visibility push(default) 48 : 49 : extern "C++" { 50 : 51 : namespace std 52 : { 53 : /** 54 : * @brief Exception possibly thrown by @c new. 55 : * 56 : * @c bad_alloc (or classes derived from it) is used to report allocation 57 : * errors from the throwing forms of @c new. */ 58 : class bad_alloc : public exception 59 : { 60 : public: 61 : bad_alloc() throw() { } 62 : 63 : // This declaration is not useless: 64 : // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 65 : virtual ~bad_alloc() throw(); 66 : 67 : // See comment in eh_exception.cc. 68 : virtual const char* what() const throw(); 69 : }; 70 : 71 : struct nothrow_t { }; 72 : 73 : extern const nothrow_t nothrow; 74 : 75 : /** If you write your own error handler to be called by @c new, it must 76 : * be of this type. */ 77 : typedef void (*new_handler)(); 78 : 79 : /// Takes a replacement handler as the argument, returns the 80 : /// previous handler. 81 : new_handler set_new_handler(new_handler) throw(); 82 : } // namespace std 83 : 84 : //@{ 85 : /** These are replaceable signatures: 86 : * - normal single new and delete (no arguments, throw @c bad_alloc on error) 87 : * - normal array new and delete (same) 88 : * - @c nothrow single new and delete (take a @c nothrow argument, return 89 : * @c NULL on error) 90 : * - @c nothrow array new and delete (same) 91 : * 92 : * Placement new and delete signatures (take a memory address argument, 93 : * does nothing) may not be replaced by a user's program. 94 : */ 95 : void* operator new(std::size_t) throw (std::bad_alloc); 96 : void* operator new[](std::size_t) throw (std::bad_alloc); 97 : void operator delete(void*) throw(); 98 : void operator delete[](void*) throw(); 99 : void* operator new(std::size_t, const std::nothrow_t&) throw(); 100 : void* operator new[](std::size_t, const std::nothrow_t&) throw(); 101 : void operator delete(void*, const std::nothrow_t&) throw(); 102 : void operator delete[](void*, const std::nothrow_t&) throw(); 103 : 104 : // Default placement versions of operator new. 105 5858225 : inline void* operator new(std::size_t, void* __p) throw() { return __p; } 106 : inline void* operator new[](std::size_t, void* __p) throw() { return __p; } 107 : 108 : // Default placement versions of operator delete. 109 0 : inline void operator delete (void*, void*) throw() { } 110 : inline void operator delete[](void*, void*) throw() { } 111 : //@} 112 : } // extern "C++" 113 : 114 : #pragma GCC visibility pop 115 : 116 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Forwarding declarations -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License 19 : // along with this library; see the file COPYING. If not, write to 20 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 21 : // Boston, MA 02110-1301, USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file iosfwd 33 : * This is a Standard C++ Library header. 34 : */ 35 : 36 : // 37 : // ISO C++ 14882: 27.2 Forward declarations 38 : // 39 : 40 : #ifndef _GLIBCXX_IOSFWD 41 : #define _GLIBCXX_IOSFWD 1 42 : 43 : #pragma GCC system_header 44 : 45 : #include <bits/c++config.h> 46 : #include <bits/stringfwd.h> // For string forward declarations. 47 : #include <bits/postypes.h> 48 : 49 : _GLIBCXX_BEGIN_NAMESPACE(std) 50 : 51 : template<typename _CharT, typename _Traits = char_traits<_CharT> > 52 : class basic_ios; 53 : 54 : template<typename _CharT, typename _Traits = char_traits<_CharT> > 55 : class basic_streambuf; 56 : 57 : template<typename _CharT, typename _Traits = char_traits<_CharT> > 58 : class basic_istream; 59 : 60 : template<typename _CharT, typename _Traits = char_traits<_CharT> > 61 : class basic_ostream; 62 : 63 : template<typename _CharT, typename _Traits = char_traits<_CharT> > 64 : class basic_iostream; 65 : 66 : template<typename _CharT, typename _Traits = char_traits<_CharT>, 67 : typename _Alloc = allocator<_CharT> > 68 0 : class basic_stringbuf; 69 : 70 : template<typename _CharT, typename _Traits = char_traits<_CharT>, 71 : typename _Alloc = allocator<_CharT> > 72 : class basic_istringstream; 73 : 74 : template<typename _CharT, typename _Traits = char_traits<_CharT>, 75 : typename _Alloc = allocator<_CharT> > 76 : class basic_ostringstream; 77 : 78 : template<typename _CharT, typename _Traits = char_traits<_CharT>, 79 : typename _Alloc = allocator<_CharT> > 80 : class basic_stringstream; 81 : 82 : template<typename _CharT, typename _Traits = char_traits<_CharT> > 83 : class basic_filebuf; 84 : 85 : template<typename _CharT, typename _Traits = char_traits<_CharT> > 86 : class basic_ifstream; 87 : 88 : template<typename _CharT, typename _Traits = char_traits<_CharT> > 89 : class basic_ofstream; 90 : 91 : template<typename _CharT, typename _Traits = char_traits<_CharT> > 92 : class basic_fstream; 93 : 94 : template<typename _CharT, typename _Traits = char_traits<_CharT> > 95 : class istreambuf_iterator; 96 : 97 : template<typename _CharT, typename _Traits = char_traits<_CharT> > 98 : class ostreambuf_iterator; 99 : 100 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 101 : // Not included. (??? Apparently no LWG number?) 102 : class ios_base; 103 : 104 : /** 105 : * @defgroup s27_2_iosfwd I/O Forward Declarations 106 : * 107 : * Nearly all of the I/O classes are parameterized on the type of 108 : * characters they read and write. (The major exception is ios_base at 109 : * the top of the hierarchy.) This is a change from pre-Standard 110 : * streams, which were not templates. 111 : * 112 : * For ease of use and compatibility, all of the basic_* I/O-related 113 : * classes are given typedef names for both of the builtin character 114 : * widths (wide and narrow). The typedefs are the same as the 115 : * pre-Standard names, for example: 116 : * 117 : * @code 118 : * typedef basic_ifstream<char> ifstream; 119 : * @endcode 120 : * 121 : * Because properly forward-declaring these classes can be difficult, you 122 : * should not do it yourself. Instead, include the <iosfwd> 123 : * header, which contains only declarations of all the I/O classes as 124 : * well as the typedefs. Trying to forward-declare the typedefs 125 : * themselves (e.g., "class ostream;") is not valid ISO C++. 126 : * 127 : * For more specific declarations, see 128 : * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#10 129 : * 130 : * @{ 131 : */ 132 : typedef basic_ios<char> ios; ///< @isiosfwd 133 : typedef basic_streambuf<char> streambuf; ///< @isiosfwd 134 : typedef basic_istream<char> istream; ///< @isiosfwd 135 : typedef basic_ostream<char> ostream; ///< @isiosfwd 136 : typedef basic_iostream<char> iostream; ///< @isiosfwd 137 : typedef basic_stringbuf<char> stringbuf; ///< @isiosfwd 138 : typedef basic_istringstream<char> istringstream; ///< @isiosfwd 139 : typedef basic_ostringstream<char> ostringstream; ///< @isiosfwd 140 : typedef basic_stringstream<char> stringstream; ///< @isiosfwd 141 : typedef basic_filebuf<char> filebuf; ///< @isiosfwd 142 : typedef basic_ifstream<char> ifstream; ///< @isiosfwd 143 : typedef basic_ofstream<char> ofstream; ///< @isiosfwd 144 : typedef basic_fstream<char> fstream; ///< @isiosfwd 145 : 146 : #ifdef _GLIBCXX_USE_WCHAR_T 147 : typedef basic_ios<wchar_t> wios; ///< @isiosfwd 148 : typedef basic_streambuf<wchar_t> wstreambuf; ///< @isiosfwd 149 : typedef basic_istream<wchar_t> wistream; ///< @isiosfwd 150 : typedef basic_ostream<wchar_t> wostream; ///< @isiosfwd 151 : typedef basic_iostream<wchar_t> wiostream; ///< @isiosfwd 152 : typedef basic_stringbuf<wchar_t> wstringbuf; ///< @isiosfwd 153 : typedef basic_istringstream<wchar_t> wistringstream; ///< @isiosfwd 154 : typedef basic_ostringstream<wchar_t> wostringstream; ///< @isiosfwd 155 : typedef basic_stringstream<wchar_t> wstringstream; ///< @isiosfwd 156 : typedef basic_filebuf<wchar_t> wfilebuf; ///< @isiosfwd 157 : typedef basic_ifstream<wchar_t> wifstream; ///< @isiosfwd 158 : typedef basic_ofstream<wchar_t> wofstream; ///< @isiosfwd 159 : typedef basic_fstream<wchar_t> wfstream; ///< @isiosfwd 160 : #endif 161 : /** @} */ 162 : 163 : _GLIBCXX_END_NAMESPACE 164 : 165 : #endif /* _GLIBCXX_IOSFWD */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Exception Handling support header for -*- C++ -*- 2 : 3 : // Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 4 : // 2004, 2005, 2006, 2007 5 : // Free Software Foundation 6 : // 7 : // This file is part of GCC. 8 : // 9 : // GCC is free software; you can redistribute it and/or modify 10 : // it under the terms of the GNU General Public License as published by 11 : // the Free Software Foundation; either version 2, or (at your option) 12 : // any later version. 13 : // 14 : // GCC is distributed in the hope that it will be useful, 15 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : // GNU General Public License for more details. 18 : // 19 : // You should have received a copy of the GNU General Public License 20 : // along with GCC; see the file COPYING. If not, write to 21 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 22 : // Boston, MA 02110-1301, USA. 23 : 24 : // As a special exception, you may use this file as part of a free software 25 : // library without restriction. Specifically, if other files instantiate 26 : // templates or use macros or inline functions from this file, or you compile 27 : // this file and link it with other files to produce an executable, this 28 : // file does not by itself cause the resulting executable to be covered by 29 : // the GNU General Public License. This exception does not however 30 : // invalidate any other reasons why the executable file might be covered by 31 : // the GNU General Public License. 32 : 33 : /** @file exception 34 : * This is a Standard C++ Library header. 35 : */ 36 : 37 : #ifndef __EXCEPTION__ 38 : #define __EXCEPTION__ 39 : 40 : #pragma GCC visibility push(default) 41 : 42 : #include <bits/c++config.h> 43 : 44 : extern "C++" { 45 : 46 : namespace std 47 : { 48 : /** 49 : * @brief Base class for all library exceptions. 50 : * 51 : * This is the base class for all exceptions thrown by the standard 52 : * library, and by certain language expressions. You are free to derive 53 : * your own %exception classes, or use a different hierarchy, or to 54 : * throw non-class data (e.g., fundamental types). 55 : */ 56 : class exception 57 0 : { 58 : public: 59 6 : exception() throw() { } 60 : virtual ~exception() throw(); 61 : 62 : /** Returns a C-style character string describing the general cause 63 : * of the current error. */ 64 : virtual const char* what() const throw(); 65 : }; 66 : 67 : /** If an %exception is thrown which is not listed in a function's 68 : * %exception specification, one of these may be thrown. */ 69 : class bad_exception : public exception 70 : { 71 : public: 72 : bad_exception() throw() { } 73 : 74 : // This declaration is not useless: 75 : // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 76 : virtual ~bad_exception() throw(); 77 : 78 : // See comment in eh_exception.cc. 79 : virtual const char* what() const throw(); 80 : }; 81 : 82 : /// If you write a replacement %terminate handler, it must be of this type. 83 : typedef void (*terminate_handler) (); 84 : 85 : /// If you write a replacement %unexpected handler, it must be of this type. 86 : typedef void (*unexpected_handler) (); 87 : 88 : /// Takes a new handler function as an argument, returns the old function. 89 : terminate_handler set_terminate(terminate_handler) throw(); 90 : 91 : /** The runtime will call this function if %exception handling must be 92 : * abandoned for any reason. It can also be called by the user. */ 93 : void terminate() __attribute__ ((__noreturn__)); 94 : 95 : /// Takes a new handler function as an argument, returns the old function. 96 : unexpected_handler set_unexpected(unexpected_handler) throw(); 97 : 98 : /** The runtime will call this function if an %exception is thrown which 99 : * violates the function's %exception specification. */ 100 : void unexpected() __attribute__ ((__noreturn__)); 101 : 102 : /** [18.6.4]/1: "Returns true after completing evaluation of a 103 : * throw-expression until either completing initialization of the 104 : * exception-declaration in the matching handler or entering @c unexpected() 105 : * due to the throw; or after entering @c terminate() for any reason 106 : * other than an explicit call to @c terminate(). [Note: This includes 107 : * stack unwinding [15.2]. end note]" 108 : * 109 : * 2: "When @c uncaught_exception() is true, throwing an %exception can 110 : * result in a call of @c terminate() (15.5.1)." 111 : */ 112 : bool uncaught_exception() throw(); 113 : } // namespace std 114 : 115 : _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 116 : 117 : /** A replacement for the standard terminate_handler which prints more 118 : information about the terminating exception (if any) on stderr. Call 119 : @code 120 : std::set_terminate (__gnu_cxx::__verbose_terminate_handler) 121 : @endcode 122 : to use. For more info, see 123 : http://gcc.gnu.org/onlinedocs/libstdc++/19_diagnostics/howto.html#4 124 : 125 : In 3.4 and later, this is on by default. 126 : */ 127 : void __verbose_terminate_handler (); 128 : 129 : _GLIBCXX_END_NAMESPACE 130 : 131 : } // extern "C++" 132 : 133 : #pragma GCC visibility pop 134 : 135 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Standard iostream objects -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2001, 2002, 2005 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License 18 : // along with this library; see the file COPYING. If not, write to 19 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 20 : // Boston, MA 02110-1301, USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /** @file iostream 32 : * This is a Standard C++ Library header. 33 : */ 34 : 35 : // 36 : // ISO C++ 14882: 27.3 Standard iostream objects 37 : // 38 : 39 : #ifndef _GLIBCXX_IOSTREAM 40 : #define _GLIBCXX_IOSTREAM 1 41 : 42 : #pragma GCC system_header 43 : 44 : #include <bits/c++config.h> 45 : #include <ostream> 46 : #include <istream> 47 : 48 : _GLIBCXX_BEGIN_NAMESPACE(std) 49 : 50 : /** 51 : * @name Standard Stream Objects 52 : * 53 : * The <iostream> header declares the eight <em>standard stream 54 : * objects</em>. For other declarations, see 55 : * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#10 and the 56 : * @link s27_2_iosfwd I/O forward declarations @endlink 57 : * 58 : * They are required by default to cooperate with the global C library's 59 : * @c FILE streams, and to be available during program startup and 60 : * termination. For more information, see the HOWTO linked to above. 61 : */ 62 : //@{ 63 : extern istream cin; ///< Linked to standard input 64 : extern ostream cout; ///< Linked to standard output 65 : extern ostream cerr; ///< Linked to standard error (unbuffered) 66 : extern ostream clog; ///< Linked to standard error (buffered) 67 : 68 : #ifdef _GLIBCXX_USE_WCHAR_T 69 : extern wistream wcin; ///< Linked to standard input 70 : extern wostream wcout; ///< Linked to standard output 71 : extern wostream wcerr; ///< Linked to standard error (unbuffered) 72 : extern wostream wclog; ///< Linked to standard error (buffered) 73 : #endif 74 : //@} 75 : 76 : // For construction of filebuffers for cout, cin, cerr, clog et. al. 77 104 : static ios_base::Init __ioinit; 78 : 79 : _GLIBCXX_END_NAMESPACE 80 : 81 : #endif /* _GLIBCXX_IOSTREAM */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // String based streams -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2008 Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License 18 : // along with this library; see the file COPYING. If not, write to 19 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 20 : // Boston, MA 02110-1301, USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /** @file sstream 32 : * This is a Standard C++ Library header. 33 : */ 34 : 35 : // 36 : // ISO C++ 14882: 27.7 String-based streams 37 : // 38 : 39 : #ifndef _GLIBCXX_SSTREAM 40 : #define _GLIBCXX_SSTREAM 1 41 : 42 : #pragma GCC system_header 43 : 44 : #include <istream> 45 : #include <ostream> 46 : 47 : _GLIBCXX_BEGIN_NAMESPACE(std) 48 : 49 : // [27.7.1] template class basic_stringbuf 50 : /** 51 : * @brief The actual work of input and output (for std::string). 52 : * 53 : * This class associates either or both of its input and output sequences 54 : * with a sequence of characters, which can be initialized from, or made 55 : * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) 56 : * 57 : * For this class, open modes (of type @c ios_base::openmode) have 58 : * @c in set if the input sequence can be read, and @c out set if the 59 : * output sequence can be written. 60 : */ 61 : template<typename _CharT, typename _Traits, typename _Alloc> 62 : class basic_stringbuf : public basic_streambuf<_CharT, _Traits> 63 : { 64 : public: 65 : // Types: 66 : typedef _CharT char_type; 67 : typedef _Traits traits_type; 68 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 69 : // 251. basic_stringbuf missing allocator_type 70 : typedef _Alloc allocator_type; 71 : typedef typename traits_type::int_type int_type; 72 : typedef typename traits_type::pos_type pos_type; 73 : typedef typename traits_type::off_type off_type; 74 : 75 : typedef basic_streambuf<char_type, traits_type> __streambuf_type; 76 : typedef basic_string<char_type, _Traits, _Alloc> __string_type; 77 : typedef typename __string_type::size_type __size_type; 78 : 79 : protected: 80 : /// Place to stash in || out || in | out settings for current stringbuf. 81 : ios_base::openmode _M_mode; 82 : 83 : // Data Members: 84 : __string_type _M_string; 85 : 86 : public: 87 : // Constructors: 88 : /** 89 : * @brief Starts with an empty string buffer. 90 : * @param mode Whether the buffer can read, or write, or both. 91 : * 92 : * The default constructor initializes the parent class using its 93 : * own default ctor. 94 : */ 95 : explicit 96 0 : basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) 97 0 : : __streambuf_type(), _M_mode(__mode), _M_string() 98 0 : { } 99 : 100 : /** 101 : * @brief Starts with an existing string buffer. 102 : * @param str A string to copy as a starting buffer. 103 : * @param mode Whether the buffer can read, or write, or both. 104 : * 105 : * This constructor initializes the parent class using its 106 : * own default ctor. 107 : */ 108 : explicit 109 : basic_stringbuf(const __string_type& __str, 110 0 : ios_base::openmode __mode = ios_base::in | ios_base::out) 111 0 : : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size()) 112 0 : { _M_stringbuf_init(__mode); } 113 : 114 : // Get and set: 115 : /** 116 : * @brief Copying out the string buffer. 117 : * @return A copy of one of the underlying sequences. 118 : * 119 : * "If the buffer is only created in input mode, the underlying 120 : * character sequence is equal to the input sequence; otherwise, it 121 : * is equal to the output sequence." [27.7.1.2]/1 122 : */ 123 : __string_type 124 0 : str() const 125 : { 126 0 : __string_type __ret; 127 0 : if (this->pptr()) 128 : { 129 : // The current egptr() may not be the actual string end. 130 0 : if (this->pptr() > this->egptr()) 131 0 : __ret = __string_type(this->pbase(), this->pptr()); 132 : else 133 0 : __ret = __string_type(this->pbase(), this->egptr()); 134 : } 135 : else 136 0 : __ret = _M_string; 137 0 : return __ret; 138 : } 139 : 140 : /** 141 : * @brief Setting a new buffer. 142 : * @param s The string to use as a new sequence. 143 : * 144 : * Deallocates any previous stored sequence, then copies @a s to 145 : * use as a new one. 146 : */ 147 : void 148 : str(const __string_type& __s) 149 : { 150 : // Cannot use _M_string = __s, since v3 strings are COW. 151 : _M_string.assign(__s.data(), __s.size()); 152 : _M_stringbuf_init(_M_mode); 153 : } 154 : 155 : protected: 156 : // Common initialization code goes here. 157 : void 158 0 : _M_stringbuf_init(ios_base::openmode __mode) 159 : { 160 0 : _M_mode = __mode; 161 0 : __size_type __len = 0; 162 0 : if (_M_mode & (ios_base::ate | ios_base::app)) 163 0 : __len = _M_string.size(); 164 0 : _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len); 165 0 : } 166 : 167 : virtual streamsize 168 : showmanyc() 169 : { 170 : streamsize __ret = -1; 171 : if (_M_mode & ios_base::in) 172 : { 173 : _M_update_egptr(); 174 : __ret = this->egptr() - this->gptr(); 175 : } 176 : return __ret; 177 : } 178 : 179 : virtual int_type 180 : underflow(); 181 : 182 : virtual int_type 183 : pbackfail(int_type __c = traits_type::eof()); 184 : 185 : virtual int_type 186 : overflow(int_type __c = traits_type::eof()); 187 : 188 : /** 189 : * @brief Manipulates the buffer. 190 : * @param s Pointer to a buffer area. 191 : * @param n Size of @a s. 192 : * @return @c this 193 : * 194 : * If no buffer has already been created, and both @a s and @a n are 195 : * non-zero, then @c s is used as a buffer; see 196 : * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 197 : * for more. 198 : */ 199 : virtual __streambuf_type* 200 : setbuf(char_type* __s, streamsize __n) 201 : { 202 : if (__s && __n >= 0) 203 : { 204 : // This is implementation-defined behavior, and assumes 205 : // that an external char_type array of length __n exists 206 : // and has been pre-allocated. If this is not the case, 207 : // things will quickly blow up. 208 : 209 : // Step 1: Destroy the current internal array. 210 : _M_string.clear(); 211 : 212 : // Step 2: Use the external array. 213 : _M_sync(__s, __n, 0); 214 : } 215 : return this; 216 : } 217 : 218 : virtual pos_type 219 : seekoff(off_type __off, ios_base::seekdir __way, 220 : ios_base::openmode __mode = ios_base::in | ios_base::out); 221 : 222 : virtual pos_type 223 : seekpos(pos_type __sp, 224 : ios_base::openmode __mode = ios_base::in | ios_base::out); 225 : 226 : // Internal function for correctly updating the internal buffer 227 : // for a particular _M_string, due to initialization or re-sizing 228 : // of an existing _M_string. 229 : void 230 : _M_sync(char_type* __base, __size_type __i, __size_type __o); 231 : 232 : // Internal function for correctly updating egptr() to the actual 233 : // string end. 234 : void 235 : _M_update_egptr() 236 : { 237 : const bool __testin = _M_mode & ios_base::in; 238 : if (this->pptr() && this->pptr() > this->egptr()) 239 : if (__testin) 240 : this->setg(this->eback(), this->gptr(), this->pptr()); 241 : else 242 : this->setg(this->pptr(), this->pptr(), this->pptr()); 243 : } 244 : }; 245 : 246 : 247 : // [27.7.2] Template class basic_istringstream 248 : /** 249 : * @brief Controlling input for std::string. 250 : * 251 : * This class supports reading from objects of type std::basic_string, 252 : * using the inherited functions from std::basic_istream. To control 253 : * the associated sequence, an instance of std::basic_stringbuf is used, 254 : * which this page refers to as @c sb. 255 : */ 256 : template<typename _CharT, typename _Traits, typename _Alloc> 257 : class basic_istringstream : public basic_istream<_CharT, _Traits> 258 : { 259 : public: 260 : // Types: 261 : typedef _CharT char_type; 262 : typedef _Traits traits_type; 263 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 264 : // 251. basic_stringbuf missing allocator_type 265 : typedef _Alloc allocator_type; 266 : typedef typename traits_type::int_type int_type; 267 : typedef typename traits_type::pos_type pos_type; 268 : typedef typename traits_type::off_type off_type; 269 : 270 : // Non-standard types: 271 : typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 272 : typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 273 : typedef basic_istream<char_type, traits_type> __istream_type; 274 : 275 : private: 276 : __stringbuf_type _M_stringbuf; 277 : 278 : public: 279 : // Constructors: 280 : /** 281 : * @brief Default constructor starts with an empty string buffer. 282 : * @param mode Whether the buffer can read, or write, or both. 283 : * 284 : * @c ios_base::in is automatically included in @a mode. 285 : * 286 : * Initializes @c sb using @c mode|in, and passes @c &sb to the base 287 : * class initializer. Does not allocate any buffer. 288 : * 289 : * That's a lie. We initialize the base class with NULL, because the 290 : * string class does its own memory management. 291 : */ 292 : explicit 293 : basic_istringstream(ios_base::openmode __mode = ios_base::in) 294 : : __istream_type(), _M_stringbuf(__mode | ios_base::in) 295 : { this->init(&_M_stringbuf); } 296 : 297 : /** 298 : * @brief Starts with an existing string buffer. 299 : * @param str A string to copy as a starting buffer. 300 : * @param mode Whether the buffer can read, or write, or both. 301 : * 302 : * @c ios_base::in is automatically included in @a mode. 303 : * 304 : * Initializes @c sb using @a str and @c mode|in, and passes @c &sb 305 : * to the base class initializer. 306 : * 307 : * That's a lie. We initialize the base class with NULL, because the 308 : * string class does its own memory management. 309 : */ 310 : explicit 311 : basic_istringstream(const __string_type& __str, 312 0 : ios_base::openmode __mode = ios_base::in) 313 0 : : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) 314 0 : { this->init(&_M_stringbuf); } 315 : 316 : /** 317 : * @brief The destructor does nothing. 318 : * 319 : * The buffer is deallocated by the stringbuf object, not the 320 : * formatting stream. 321 : */ 322 0 : ~basic_istringstream() 323 0 : { } 324 : 325 : // Members: 326 : /** 327 : * @brief Accessing the underlying buffer. 328 : * @return The current basic_stringbuf buffer. 329 : * 330 : * This hides both signatures of std::basic_ios::rdbuf(). 331 : */ 332 : __stringbuf_type* 333 : rdbuf() const 334 : { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 335 : 336 : /** 337 : * @brief Copying out the string buffer. 338 : * @return @c rdbuf()->str() 339 : */ 340 : __string_type 341 : str() const 342 : { return _M_stringbuf.str(); } 343 : 344 : /** 345 : * @brief Setting a new buffer. 346 : * @param s The string to use as a new sequence. 347 : * 348 : * Calls @c rdbuf()->str(s). 349 : */ 350 : void 351 : str(const __string_type& __s) 352 : { _M_stringbuf.str(__s); } 353 : }; 354 : 355 : 356 : // [27.7.3] Template class basic_ostringstream 357 : /** 358 : * @brief Controlling output for std::string. 359 : * 360 : * This class supports writing to objects of type std::basic_string, 361 : * using the inherited functions from std::basic_ostream. To control 362 : * the associated sequence, an instance of std::basic_stringbuf is used, 363 : * which this page refers to as @c sb. 364 : */ 365 : template <typename _CharT, typename _Traits, typename _Alloc> 366 : class basic_ostringstream : public basic_ostream<_CharT, _Traits> 367 : { 368 : public: 369 : // Types: 370 : typedef _CharT char_type; 371 : typedef _Traits traits_type; 372 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 373 : // 251. basic_stringbuf missing allocator_type 374 : typedef _Alloc allocator_type; 375 : typedef typename traits_type::int_type int_type; 376 : typedef typename traits_type::pos_type pos_type; 377 : typedef typename traits_type::off_type off_type; 378 : 379 : // Non-standard types: 380 : typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 381 : typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 382 : typedef basic_ostream<char_type, traits_type> __ostream_type; 383 : 384 : private: 385 : __stringbuf_type _M_stringbuf; 386 : 387 : public: 388 : // Constructors/destructor: 389 : /** 390 : * @brief Default constructor starts with an empty string buffer. 391 : * @param mode Whether the buffer can read, or write, or both. 392 : * 393 : * @c ios_base::out is automatically included in @a mode. 394 : * 395 : * Initializes @c sb using @c mode|out, and passes @c &sb to the base 396 : * class initializer. Does not allocate any buffer. 397 : * 398 : * That's a lie. We initialize the base class with NULL, because the 399 : * string class does its own memory management. 400 : */ 401 : explicit 402 0 : basic_ostringstream(ios_base::openmode __mode = ios_base::out) 403 0 : : __ostream_type(), _M_stringbuf(__mode | ios_base::out) 404 0 : { this->init(&_M_stringbuf); } 405 : 406 : /** 407 : * @brief Starts with an existing string buffer. 408 : * @param str A string to copy as a starting buffer. 409 : * @param mode Whether the buffer can read, or write, or both. 410 : * 411 : * @c ios_base::out is automatically included in @a mode. 412 : * 413 : * Initializes @c sb using @a str and @c mode|out, and passes @c &sb 414 : * to the base class initializer. 415 : * 416 : * That's a lie. We initialize the base class with NULL, because the 417 : * string class does its own memory management. 418 : */ 419 : explicit 420 : basic_ostringstream(const __string_type& __str, 421 : ios_base::openmode __mode = ios_base::out) 422 : : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) 423 : { this->init(&_M_stringbuf); } 424 : 425 : /** 426 : * @brief The destructor does nothing. 427 : * 428 : * The buffer is deallocated by the stringbuf object, not the 429 : * formatting stream. 430 : */ 431 0 : ~basic_ostringstream() 432 0 : { } 433 : 434 : // Members: 435 : /** 436 : * @brief Accessing the underlying buffer. 437 : * @return The current basic_stringbuf buffer. 438 : * 439 : * This hides both signatures of std::basic_ios::rdbuf(). 440 : */ 441 : __stringbuf_type* 442 : rdbuf() const 443 : { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 444 : 445 : /** 446 : * @brief Copying out the string buffer. 447 : * @return @c rdbuf()->str() 448 : */ 449 : __string_type 450 0 : str() const 451 0 : { return _M_stringbuf.str(); } 452 : 453 : /** 454 : * @brief Setting a new buffer. 455 : * @param s The string to use as a new sequence. 456 : * 457 : * Calls @c rdbuf()->str(s). 458 : */ 459 : void 460 : str(const __string_type& __s) 461 : { _M_stringbuf.str(__s); } 462 : }; 463 : 464 : 465 : // [27.7.4] Template class basic_stringstream 466 : /** 467 : * @brief Controlling input and output for std::string. 468 : * 469 : * This class supports reading from and writing to objects of type 470 : * std::basic_string, using the inherited functions from 471 : * std::basic_iostream. To control the associated sequence, an instance 472 : * of std::basic_stringbuf is used, which this page refers to as @c sb. 473 : */ 474 : template <typename _CharT, typename _Traits, typename _Alloc> 475 : class basic_stringstream : public basic_iostream<_CharT, _Traits> 476 : { 477 : public: 478 : // Types: 479 : typedef _CharT char_type; 480 : typedef _Traits traits_type; 481 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 482 : // 251. basic_stringbuf missing allocator_type 483 : typedef _Alloc allocator_type; 484 : typedef typename traits_type::int_type int_type; 485 : typedef typename traits_type::pos_type pos_type; 486 : typedef typename traits_type::off_type off_type; 487 : 488 : // Non-standard Types: 489 : typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 490 : typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 491 : typedef basic_iostream<char_type, traits_type> __iostream_type; 492 : 493 : private: 494 : __stringbuf_type _M_stringbuf; 495 : 496 : public: 497 : // Constructors/destructors 498 : /** 499 : * @brief Default constructor starts with an empty string buffer. 500 : * @param mode Whether the buffer can read, or write, or both. 501 : * 502 : * Initializes @c sb using @c mode, and passes @c &sb to the base 503 : * class initializer. Does not allocate any buffer. 504 : * 505 : * That's a lie. We initialize the base class with NULL, because the 506 : * string class does its own memory management. 507 : */ 508 : explicit 509 0 : basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) 510 0 : : __iostream_type(), _M_stringbuf(__m) 511 0 : { this->init(&_M_stringbuf); } 512 : 513 : /** 514 : * @brief Starts with an existing string buffer. 515 : * @param str A string to copy as a starting buffer. 516 : * @param mode Whether the buffer can read, or write, or both. 517 : * 518 : * Initializes @c sb using @a str and @c mode, and passes @c &sb 519 : * to the base class initializer. 520 : * 521 : * That's a lie. We initialize the base class with NULL, because the 522 : * string class does its own memory management. 523 : */ 524 : explicit 525 : basic_stringstream(const __string_type& __str, 526 0 : ios_base::openmode __m = ios_base::out | ios_base::in) 527 0 : : __iostream_type(), _M_stringbuf(__str, __m) 528 0 : { this->init(&_M_stringbuf); } 529 : 530 : /** 531 : * @brief The destructor does nothing. 532 : * 533 : * The buffer is deallocated by the stringbuf object, not the 534 : * formatting stream. 535 : */ 536 0 : ~basic_stringstream() 537 0 : { } 538 : 539 : // Members: 540 : /** 541 : * @brief Accessing the underlying buffer. 542 : * @return The current basic_stringbuf buffer. 543 : * 544 : * This hides both signatures of std::basic_ios::rdbuf(). 545 : */ 546 : __stringbuf_type* 547 : rdbuf() const 548 : { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 549 : 550 : /** 551 : * @brief Copying out the string buffer. 552 : * @return @c rdbuf()->str() 553 : */ 554 : __string_type 555 0 : str() const 556 0 : { return _M_stringbuf.str(); } 557 : 558 : /** 559 : * @brief Setting a new buffer. 560 : * @param s The string to use as a new sequence. 561 : * 562 : * Calls @c rdbuf()->str(s). 563 : */ 564 : void 565 : str(const __string_type& __s) 566 : { _M_stringbuf.str(__s); } 567 : }; 568 : 569 : _GLIBCXX_END_NAMESPACE 570 : 571 : #ifndef _GLIBCXX_EXPORT_TEMPLATE 572 : # include <bits/sstream.tcc> 573 : #endif 574 : 575 : #endif /* _GLIBCXX_SSTREAM */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- 2 : 3 : // Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. 4 : // 5 : // This file is part of the GNU ISO C++ Library. This library is free 6 : // software; you can redistribute it and/or modify it under the terms 7 : // of the GNU General Public License as published by the Free Software 8 : // Foundation; either version 2, or (at your option) any later 9 : // version. 10 : 11 : // This library is distributed in the hope that it will be useful, but 12 : // WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 : // General Public License for more details. 15 : 16 : // You should have received a copy of the GNU General Public License along 17 : // with this library; see the file COPYING. If not, write to the Free 18 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19 : // USA. 20 : 21 : // As a special exception, you may use this file as part of a free 22 : // software library without restriction. Specifically, if other files 23 : // instantiate templates or use macros or inline functions from this 24 : // file, or you compile this file and link it with other files to 25 : // produce an executable, this file does not by itself cause the 26 : // resulting executable to be covered by the GNU General Public 27 : // License. This exception does not however invalidate any other 28 : // reasons why the executable file might be covered by the GNU General 29 : // Public License. 30 : 31 : /** @file ext/type_traits.h 32 : * This file is a GNU extension to the Standard C++ Library. 33 : */ 34 : 35 : #ifndef _EXT_TYPE_TRAITS 36 : #define _EXT_TYPE_TRAITS 1 37 : 38 : #pragma GCC system_header 39 : 40 : #include <bits/c++config.h> 41 : #include <bits/cpp_type_traits.h> 42 : 43 : _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 44 : 45 : // Define a nested type if some predicate holds. 46 : template<bool, typename> 47 : struct __enable_if 48 : { }; 49 : 50 : template<typename _Tp> 51 : struct __enable_if<true, _Tp> 52 : { typedef _Tp __type; }; 53 : 54 : 55 : // Conditional expression for types. If true, first, if false, second. 56 : template<bool _Cond, typename _Iftrue, typename _Iffalse> 57 : struct __conditional_type 58 : { typedef _Iftrue __type; }; 59 : 60 : template<typename _Iftrue, typename _Iffalse> 61 : struct __conditional_type<false, _Iftrue, _Iffalse> 62 : { typedef _Iffalse __type; }; 63 : 64 : 65 : // Given an integral builtin type, return the corresponding unsigned type. 66 : template<typename _Tp> 67 : struct __add_unsigned 68 : { 69 : private: 70 : typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type; 71 : 72 : public: 73 : typedef typename __if_type::__type __type; 74 : }; 75 : 76 : template<> 77 : struct __add_unsigned<char> 78 : { typedef unsigned char __type; }; 79 : 80 : template<> 81 : struct __add_unsigned<signed char> 82 : { typedef unsigned char __type; }; 83 : 84 : template<> 85 : struct __add_unsigned<short> 86 : { typedef unsigned short __type; }; 87 : 88 : template<> 89 : struct __add_unsigned<int> 90 : { typedef unsigned int __type; }; 91 : 92 : template<> 93 : struct __add_unsigned<long> 94 : { typedef unsigned long __type; }; 95 : 96 : template<> 97 : struct __add_unsigned<long long> 98 : { typedef unsigned long long __type; }; 99 : 100 : // Declare but don't define. 101 : template<> 102 : struct __add_unsigned<bool>; 103 : 104 : template<> 105 : struct __add_unsigned<wchar_t>; 106 : 107 : 108 : // Given an integral builtin type, return the corresponding signed type. 109 : template<typename _Tp> 110 : struct __remove_unsigned 111 : { 112 : private: 113 : typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type; 114 : 115 : public: 116 : typedef typename __if_type::__type __type; 117 : }; 118 : 119 : template<> 120 : struct __remove_unsigned<char> 121 : { typedef signed char __type; }; 122 : 123 : template<> 124 : struct __remove_unsigned<unsigned char> 125 : { typedef signed char __type; }; 126 : 127 : template<> 128 : struct __remove_unsigned<unsigned short> 129 : { typedef short __type; }; 130 : 131 : template<> 132 : struct __remove_unsigned<unsigned int> 133 : { typedef int __type; }; 134 : 135 : template<> 136 : struct __remove_unsigned<unsigned long> 137 : { typedef long __type; }; 138 : 139 : template<> 140 : struct __remove_unsigned<unsigned long long> 141 : { typedef long long __type; }; 142 : 143 : // Declare but don't define. 144 : template<> 145 : struct __remove_unsigned<bool>; 146 : 147 : template<> 148 : struct __remove_unsigned<wchar_t>; 149 : 150 : 151 : // For use in string and vstring. 152 : template<typename _Type> 153 : inline bool 154 0 : __is_null_pointer(_Type* __ptr) 155 0 : { return __ptr == 0; } 156 : 157 : template<typename _Type> 158 : inline bool 159 1287 : __is_null_pointer(_Type) 160 1287 : { return false; } 161 : 162 : 163 : // For complex and cmath 164 : template<typename _Tp, bool = std::__is_integer<_Tp>::__value> 165 : struct __promote 166 : { typedef double __type; }; 167 : 168 : template<typename _Tp> 169 : struct __promote<_Tp, false> 170 : { typedef _Tp __type; }; 171 : 172 : template<typename _Tp, typename _Up> 173 : struct __promote_2 174 : { 175 : private: 176 : typedef typename __promote<_Tp>::__type __type1; 177 : typedef typename __promote<_Up>::__type __type2; 178 : 179 : public: 180 : typedef __typeof__(__type1() + __type2()) __type; 181 : }; 182 : 183 : template<typename _Tp, typename _Up, typename _Vp> 184 : struct __promote_3 185 : { 186 : private: 187 : typedef typename __promote<_Tp>::__type __type1; 188 : typedef typename __promote<_Up>::__type __type2; 189 : typedef typename __promote<_Vp>::__type __type3; 190 : 191 : public: 192 : typedef __typeof__(__type1() + __type2() + __type3()) __type; 193 : }; 194 : 195 : template<typename _Tp, typename _Up, typename _Vp, typename _Wp> 196 : struct __promote_4 197 : { 198 : private: 199 : typedef typename __promote<_Tp>::__type __type1; 200 : typedef typename __promote<_Up>::__type __type2; 201 : typedef typename __promote<_Vp>::__type __type3; 202 : typedef typename __promote<_Wp>::__type __type4; 203 : 204 : public: 205 : typedef __typeof__(__type1() + __type2() + __type3() + __type4()) __type; 206 : }; 207 : 208 : _GLIBCXX_END_NAMESPACE 209 : 210 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Allocator that wraps operator new -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4 : // 5 : // This file is part of the GNU ISO C++ Library. This library is free 6 : // software; you can redistribute it and/or modify it under the 7 : // terms of the GNU General Public License as published by the 8 : // Free Software Foundation; either version 2, or (at your option) 9 : // any later version. 10 : 11 : // This library is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : 16 : // You should have received a copy of the GNU General Public License along 17 : // with this library; see the file COPYING. If not, write to the Free 18 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19 : // USA. 20 : 21 : // As a special exception, you may use this file as part of a free software 22 : // library without restriction. Specifically, if other files instantiate 23 : // templates or use macros or inline functions from this file, or you compile 24 : // this file and link it with other files to produce an executable, this 25 : // file does not by itself cause the resulting executable to be covered by 26 : // the GNU General Public License. This exception does not however 27 : // invalidate any other reasons why the executable file might be covered by 28 : // the GNU General Public License. 29 : 30 : /** @file ext/new_allocator.h 31 : * This file is a GNU extension to the Standard C++ Library. 32 : */ 33 : 34 : #ifndef _NEW_ALLOCATOR_H 35 : #define _NEW_ALLOCATOR_H 1 36 : 37 : #include <new> 38 : #include <bits/functexcept.h> 39 : #include <bits/stl_move.h> 40 : 41 : _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 42 : 43 : using std::size_t; 44 : using std::ptrdiff_t; 45 : 46 : /** 47 : * @brief An allocator that uses global new, as per [20.4]. 48 : * 49 : * This is precisely the allocator defined in the C++ Standard. 50 : * - all allocation calls operator new 51 : * - all deallocation calls operator delete 52 : */ 53 : template<typename _Tp> 54 : class new_allocator 55 : { 56 : public: 57 : typedef size_t size_type; 58 : typedef ptrdiff_t difference_type; 59 : typedef _Tp* pointer; 60 : typedef const _Tp* const_pointer; 61 : typedef _Tp& reference; 62 : typedef const _Tp& const_reference; 63 : typedef _Tp value_type; 64 : 65 : template<typename _Tp1> 66 : struct rebind 67 : { typedef new_allocator<_Tp1> other; }; 68 : 69 11574945 : new_allocator() throw() { } 70 : 71 934618 : new_allocator(const new_allocator&) throw() { } 72 : 73 : template<typename _Tp1> 74 : new_allocator(const new_allocator<_Tp1>&) throw() { } 75 : 76 12615289 : ~new_allocator() throw() { } 77 : 78 : pointer 79 : address(reference __x) const { return &__x; } 80 : 81 : const_pointer 82 : address(const_reference __x) const { return &__x; } 83 : 84 : // NB: __n is permitted to be 0. The C++ standard says nothing 85 : // about what the return value is when __n == 0. 86 : pointer 87 5665535 : allocate(size_type __n, const void* = 0) 88 : { 89 5665535 : if (__builtin_expect(__n > this->max_size(), false)) 90 0 : std::__throw_bad_alloc(); 91 : 92 5665535 : return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); 93 : } 94 : 95 : // __p is not permitted to be a null pointer. 96 : void 97 5665395 : deallocate(pointer __p, size_type) 98 5665395 : { ::operator delete(__p); } 99 : 100 : size_type 101 5706963 : max_size() const throw() 102 5706963 : { return size_t(-1) / sizeof(_Tp); } 103 : 104 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 105 : // 402. wrong new expression in [some_] allocator::construct 106 : void 107 5786312 : construct(pointer __p, const _Tp& __val) 108 5786312 : { ::new((void *)__p) _Tp(__val); } 109 : 110 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 111 : template<typename... _Args> 112 : void 113 : construct(pointer __p, _Args&&... __args) 114 : { ::new((void *)__p) _Tp(std::forward<_Args>(__args)...); } 115 : #endif 116 : 117 : void 118 5644734 : destroy(pointer __p) { __p->~_Tp(); } 119 : }; 120 : 121 : template<typename _Tp> 122 : inline bool 123 : operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&) 124 : { return true; } 125 : 126 : template<typename _Tp> 127 : inline bool 128 : operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&) 129 : { return false; } 130 : 131 : _GLIBCXX_END_NAMESPACE 132 : 133 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
atomicity.h |
|
0.0 % | 0 / 10 lines | |
new_allocator.h |
|
92.9 % | 13 / 14 lines | |
type_traits.h |
|
50.0 % | 2 / 4 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Support for atomic operations -*- C++ -*- 2 : 3 : // Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. 4 : // 5 : // This file is part of the GNU ISO C++ Library. This library is free 6 : // software; you can redistribute it and/or modify it under the 7 : // terms of the GNU General Public License as published by the 8 : // Free Software Foundation; either version 2, or (at your option) 9 : // any later version. 10 : 11 : // This library is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : 16 : // You should have received a copy of the GNU General Public License along 17 : // with this library; see the file COPYING. If not, write to the Free 18 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19 : // USA. 20 : 21 : // As a special exception, you may use this file as part of a free software 22 : // library without restriction. Specifically, if other files instantiate 23 : // templates or use macros or inline functions from this file, or you compile 24 : // this file and link it with other files to produce an executable, this 25 : // file does not by itself cause the resulting executable to be covered by 26 : // the GNU General Public License. This exception does not however 27 : // invalidate any other reasons why the executable file might be covered by 28 : // the GNU General Public License. 29 : 30 : /** @file atomicity.h 31 : * This is an internal header file, included by other library headers. 32 : * You should not attempt to use it directly. 33 : */ 34 : 35 : #ifndef _GLIBCXX_ATOMICITY_H 36 : #define _GLIBCXX_ATOMICITY_H 1 37 : 38 : #include <bits/c++config.h> 39 : #include <bits/gthr.h> 40 : #include <bits/atomic_word.h> 41 : 42 : _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 43 : 44 : // Functions for portable atomic access. 45 : // To abstract locking primitives across all thread policies, use: 46 : // __exchange_and_add_dispatch 47 : // __atomic_add_dispatch 48 : #ifdef _GLIBCXX_ATOMIC_BUILTINS 49 : static inline _Atomic_word 50 0 : __exchange_and_add(volatile _Atomic_word* __mem, int __val) 51 0 : { return __sync_fetch_and_add(__mem, __val); } 52 : 53 : static inline void 54 : __atomic_add(volatile _Atomic_word* __mem, int __val) 55 : { __sync_fetch_and_add(__mem, __val); } 56 : #else 57 : _Atomic_word 58 : __attribute__ ((__unused__)) 59 : __exchange_and_add(volatile _Atomic_word*, int); 60 : 61 : void 62 : __attribute__ ((__unused__)) 63 : __atomic_add(volatile _Atomic_word*, int); 64 : #endif 65 : 66 : static inline _Atomic_word 67 0 : __exchange_and_add_single(_Atomic_word* __mem, int __val) 68 : { 69 0 : _Atomic_word __result = *__mem; 70 0 : *__mem += __val; 71 0 : return __result; 72 : } 73 : 74 : static inline void 75 : __atomic_add_single(_Atomic_word* __mem, int __val) 76 : { *__mem += __val; } 77 : 78 : static inline _Atomic_word 79 : __attribute__ ((__unused__)) 80 0 : __exchange_and_add_dispatch(_Atomic_word* __mem, int __val) 81 : { 82 : #ifdef __GTHREADS 83 0 : if (__gthread_active_p()) 84 0 : return __exchange_and_add(__mem, __val); 85 : else 86 0 : return __exchange_and_add_single(__mem, __val); 87 : #else 88 : return __exchange_and_add_single(__mem, __val); 89 : #endif 90 : } 91 : 92 : static inline void 93 : __attribute__ ((__unused__)) 94 : __atomic_add_dispatch(_Atomic_word* __mem, int __val) 95 : { 96 : #ifdef __GTHREADS 97 : if (__gthread_active_p()) 98 : __atomic_add(__mem, __val); 99 : else 100 : __atomic_add_single(__mem, __val); 101 : #else 102 : __atomic_add_single(__mem, __val); 103 : #endif 104 : } 105 : 106 : _GLIBCXX_END_NAMESPACE 107 : 108 : // Even if the CPU doesn't need a memory barrier, we need to ensure 109 : // that the compiler doesn't reorder memory accesses across the 110 : // barriers. 111 : #ifndef _GLIBCXX_READ_MEM_BARRIER 112 : #define _GLIBCXX_READ_MEM_BARRIER __asm __volatile ("":::"memory") 113 : #endif 114 : #ifndef _GLIBCXX_WRITE_MEM_BARRIER 115 : #define _GLIBCXX_WRITE_MEM_BARRIER __asm __volatile ("":::"memory") 116 : #endif 117 : 118 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Standard stream manipulators -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 4 : // 2006, 2007 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License 19 : // along with this library; see the file COPYING. If not, write to 20 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 21 : // Boston, MA 02110-1301, USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file iomanip 33 : * This is a Standard C++ Library header. 34 : */ 35 : 36 : // 37 : // ISO C++ 14882: 27.6.3 Standard manipulators 38 : // 39 : 40 : #ifndef _GLIBCXX_IOMANIP 41 : #define _GLIBCXX_IOMANIP 1 42 : 43 : #pragma GCC system_header 44 : 45 : #include <bits/c++config.h> 46 : #include <iosfwd> 47 : #include <bits/ios_base.h> 48 : 49 : _GLIBCXX_BEGIN_NAMESPACE(std) 50 : 51 : // [27.6.3] standard manipulators 52 : // Also see DR 183. 53 : 54 : struct _Resetiosflags { ios_base::fmtflags _M_mask; }; 55 : 56 : /** 57 : * @brief Manipulator for @c setf. 58 : * @param mask A format flags mask. 59 : * 60 : * Sent to a stream object, this manipulator resets the specified flags, 61 : * via @e stream.setf(0,mask). 62 : */ 63 : inline _Resetiosflags 64 : resetiosflags(ios_base::fmtflags __mask) 65 : { 66 : _Resetiosflags __x; 67 : __x._M_mask = __mask; 68 : return __x; 69 : } 70 : 71 : template<typename _CharT, typename _Traits> 72 : inline basic_istream<_CharT, _Traits>& 73 : operator>>(basic_istream<_CharT, _Traits>& __is, _Resetiosflags __f) 74 : { 75 : __is.setf(ios_base::fmtflags(0), __f._M_mask); 76 : return __is; 77 : } 78 : 79 : template<typename _CharT, typename _Traits> 80 : inline basic_ostream<_CharT, _Traits>& 81 : operator<<(basic_ostream<_CharT, _Traits>& __os, _Resetiosflags __f) 82 : { 83 : __os.setf(ios_base::fmtflags(0), __f._M_mask); 84 : return __os; 85 : } 86 : 87 : 88 : struct _Setiosflags { ios_base::fmtflags _M_mask; }; 89 : 90 : /** 91 : * @brief Manipulator for @c setf. 92 : * @param mask A format flags mask. 93 : * 94 : * Sent to a stream object, this manipulator sets the format flags 95 : * to @a mask. 96 : */ 97 : inline _Setiosflags 98 : setiosflags(ios_base::fmtflags __mask) 99 : { 100 : _Setiosflags __x; 101 : __x._M_mask = __mask; 102 : return __x; 103 : } 104 : 105 : template<typename _CharT, typename _Traits> 106 : inline basic_istream<_CharT, _Traits>& 107 : operator>>(basic_istream<_CharT, _Traits>& __is, _Setiosflags __f) 108 : { 109 : __is.setf(__f._M_mask); 110 : return __is; 111 : } 112 : 113 : template<typename _CharT, typename _Traits> 114 : inline basic_ostream<_CharT, _Traits>& 115 : operator<<(basic_ostream<_CharT, _Traits>& __os, _Setiosflags __f) 116 : { 117 : __os.setf(__f._M_mask); 118 : return __os; 119 : } 120 : 121 : 122 : struct _Setbase { int _M_base; }; 123 : 124 : /** 125 : * @brief Manipulator for @c setf. 126 : * @param base A numeric base. 127 : * 128 : * Sent to a stream object, this manipulator changes the 129 : * @c ios_base::basefield flags to @c oct, @c dec, or @c hex when @a base 130 : * is 8, 10, or 16, accordingly, and to 0 if @a base is any other value. 131 : */ 132 : inline _Setbase 133 : setbase(int __base) 134 : { 135 : _Setbase __x; 136 : __x._M_base = __base; 137 : return __x; 138 : } 139 : 140 : template<typename _CharT, typename _Traits> 141 : inline basic_istream<_CharT, _Traits>& 142 : operator>>(basic_istream<_CharT, _Traits>& __is, _Setbase __f) 143 : { 144 : __is.setf(__f._M_base == 8 ? ios_base::oct : 145 : __f._M_base == 10 ? ios_base::dec : 146 : __f._M_base == 16 ? ios_base::hex : 147 : ios_base::fmtflags(0), ios_base::basefield); 148 : return __is; 149 : } 150 : 151 : template<typename _CharT, typename _Traits> 152 : inline basic_ostream<_CharT, _Traits>& 153 : operator<<(basic_ostream<_CharT, _Traits>& __os, _Setbase __f) 154 : { 155 : __os.setf(__f._M_base == 8 ? ios_base::oct : 156 : __f._M_base == 10 ? ios_base::dec : 157 : __f._M_base == 16 ? ios_base::hex : 158 : ios_base::fmtflags(0), ios_base::basefield); 159 : return __os; 160 : } 161 : 162 : 163 : template<typename _CharT> 164 : struct _Setfill { _CharT _M_c; }; 165 : 166 : /** 167 : * @brief Manipulator for @c fill. 168 : * @param c The new fill character. 169 : * 170 : * Sent to a stream object, this manipulator calls @c fill(c) for that 171 : * object. 172 : */ 173 : template<typename _CharT> 174 : inline _Setfill<_CharT> 175 33 : setfill(_CharT __c) 176 : { 177 : _Setfill<_CharT> __x; 178 33 : __x._M_c = __c; 179 : return __x; 180 : } 181 : 182 : template<typename _CharT, typename _Traits> 183 : inline basic_istream<_CharT, _Traits>& 184 : operator>>(basic_istream<_CharT, _Traits>& __is, _Setfill<_CharT> __f) 185 : { 186 : __is.fill(__f._M_c); 187 : return __is; 188 : } 189 : 190 : template<typename _CharT, typename _Traits> 191 : inline basic_ostream<_CharT, _Traits>& 192 0 : operator<<(basic_ostream<_CharT, _Traits>& __os, _Setfill<_CharT> __f) 193 : { 194 0 : __os.fill(__f._M_c); 195 0 : return __os; 196 : } 197 : 198 : 199 : struct _Setprecision { int _M_n; }; 200 : 201 : /** 202 : * @brief Manipulator for @c precision. 203 : * @param n The new precision. 204 : * 205 : * Sent to a stream object, this manipulator calls @c precision(n) for 206 : * that object. 207 : */ 208 : inline _Setprecision 209 : setprecision(int __n) 210 : { 211 : _Setprecision __x; 212 : __x._M_n = __n; 213 : return __x; 214 : } 215 : 216 : template<typename _CharT, typename _Traits> 217 : inline basic_istream<_CharT, _Traits>& 218 : operator>>(basic_istream<_CharT, _Traits>& __is, _Setprecision __f) 219 : { 220 : __is.precision(__f._M_n); 221 : return __is; 222 : } 223 : 224 : template<typename _CharT, typename _Traits> 225 : inline basic_ostream<_CharT, _Traits>& 226 : operator<<(basic_ostream<_CharT, _Traits>& __os, _Setprecision __f) 227 : { 228 : __os.precision(__f._M_n); 229 : return __os; 230 : } 231 : 232 : 233 : struct _Setw { int _M_n; }; 234 : 235 : /** 236 : * @brief Manipulator for @c width. 237 : * @param n The new width. 238 : * 239 : * Sent to a stream object, this manipulator calls @c width(n) for 240 : * that object. 241 : */ 242 : inline _Setw 243 165 : setw(int __n) 244 : { 245 : _Setw __x; 246 165 : __x._M_n = __n; 247 : return __x; 248 : } 249 : 250 : template<typename _CharT, typename _Traits> 251 : inline basic_istream<_CharT, _Traits>& 252 : operator>>(basic_istream<_CharT, _Traits>& __is, _Setw __f) 253 : { 254 : __is.width(__f._M_n); 255 : return __is; 256 : } 257 : 258 : template<typename _CharT, typename _Traits> 259 : inline basic_ostream<_CharT, _Traits>& 260 0 : operator<<(basic_ostream<_CharT, _Traits>& __os, _Setw __f) 261 : { 262 0 : __os.width(__f._M_n); 263 0 : return __os; 264 : } 265 : 266 : // Inhibit implicit instantiations for required instantiations, 267 : // which are defined via explicit instantiations elsewhere. 268 : // NB: This syntax is a GNU extension. 269 : #if _GLIBCXX_EXTERN_TEMPLATE 270 : extern template ostream& operator<<(ostream&, _Setfill<char>); 271 : extern template ostream& operator<<(ostream&, _Setiosflags); 272 : extern template ostream& operator<<(ostream&, _Resetiosflags); 273 : extern template ostream& operator<<(ostream&, _Setbase); 274 : extern template ostream& operator<<(ostream&, _Setprecision); 275 : extern template ostream& operator<<(ostream&, _Setw); 276 : extern template istream& operator>>(istream&, _Setfill<char>); 277 : extern template istream& operator>>(istream&, _Setiosflags); 278 : extern template istream& operator>>(istream&, _Resetiosflags); 279 : extern template istream& operator>>(istream&, _Setbase); 280 : extern template istream& operator>>(istream&, _Setprecision); 281 : extern template istream& operator>>(istream&, _Setw); 282 : 283 : #ifdef _GLIBCXX_USE_WCHAR_T 284 : extern template wostream& operator<<(wostream&, _Setfill<wchar_t>); 285 : extern template wostream& operator<<(wostream&, _Setiosflags); 286 : extern template wostream& operator<<(wostream&, _Resetiosflags); 287 : extern template wostream& operator<<(wostream&, _Setbase); 288 : extern template wostream& operator<<(wostream&, _Setprecision); 289 : extern template wostream& operator<<(wostream&, _Setw); 290 : extern template wistream& operator>>(wistream&, _Setfill<wchar_t>); 291 : extern template wistream& operator>>(wistream&, _Setiosflags); 292 : extern template wistream& operator>>(wistream&, _Resetiosflags); 293 : extern template wistream& operator>>(wistream&, _Setbase); 294 : extern template wistream& operator>>(wistream&, _Setprecision); 295 : extern template wistream& operator>>(wistream&, _Setw); 296 : #endif 297 : #endif 298 : 299 : _GLIBCXX_END_NAMESPACE 300 : 301 : #endif /* _GLIBCXX_IOMANIP */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- C++ -*- C forwarding header. 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License 19 : // along with this library; see the file COPYING. If not, write to 20 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 21 : // Boston, MA 02110-1301, USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file include/cmath 33 : * This is a Standard C++ Library file. You should @c #include this file 34 : * in your programs, rather than any of the "*.h" implementation files. 35 : * 36 : * This is the C++ version of the Standard C Library header @c math.h, 37 : * and its contents are (mostly) the same as that header, but are all 38 : * contained in the namespace @c std (except for names which are defined 39 : * as macros in C). 40 : */ 41 : 42 : // 43 : // ISO C++ 14882: 26.5 C library 44 : // 45 : 46 : #pragma GCC system_header 47 : 48 : #include <bits/c++config.h> 49 : #include <bits/cpp_type_traits.h> 50 : #include <ext/type_traits.h> 51 : #include_next <math.h> 52 : 53 : #ifndef _GLIBCXX_CMATH 54 : #define _GLIBCXX_CMATH 1 55 : 56 : // Get rid of those macros defined in <math.h> in lieu of real functions. 57 : #undef abs 58 : #undef div 59 : #undef acos 60 : #undef asin 61 : #undef atan 62 : #undef atan2 63 : #undef ceil 64 : #undef cos 65 : #undef cosh 66 : #undef exp 67 : #undef fabs 68 : #undef floor 69 : #undef fmod 70 : #undef frexp 71 : #undef ldexp 72 : #undef log 73 : #undef log10 74 : #undef modf 75 : #undef pow 76 : #undef sin 77 : #undef sinh 78 : #undef sqrt 79 : #undef tan 80 : #undef tanh 81 : 82 : _GLIBCXX_BEGIN_NAMESPACE(std) 83 : 84 : // Forward declaration of a helper function. This really should be 85 : // an `exported' forward declaration. 86 : template<typename _Tp> 87 : _Tp __cmath_power(_Tp, unsigned int); 88 : 89 : template<typename _Tp> 90 : inline _Tp 91 : __pow_helper(_Tp __x, int __n) 92 : { 93 : return __n < 0 94 : ? _Tp(1)/__cmath_power(__x, -__n) 95 : : __cmath_power(__x, __n); 96 : } 97 : 98 : inline double 99 : abs(double __x) 100 : { return __builtin_fabs(__x); } 101 : 102 : inline float 103 : abs(float __x) 104 : { return __builtin_fabsf(__x); } 105 : 106 : inline long double 107 : abs(long double __x) 108 : { return __builtin_fabsl(__x); } 109 : 110 : using ::acos; 111 : 112 : inline float 113 : acos(float __x) 114 : { return __builtin_acosf(__x); } 115 : 116 : inline long double 117 : acos(long double __x) 118 : { return __builtin_acosl(__x); } 119 : 120 : template<typename _Tp> 121 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 122 : double>::__type 123 : acos(_Tp __x) 124 : { return __builtin_acos(__x); } 125 : 126 : using ::asin; 127 : 128 : inline float 129 : asin(float __x) 130 : { return __builtin_asinf(__x); } 131 : 132 : inline long double 133 : asin(long double __x) 134 : { return __builtin_asinl(__x); } 135 : 136 : template<typename _Tp> 137 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 138 : double>::__type 139 : asin(_Tp __x) 140 : { return __builtin_asin(__x); } 141 : 142 : using ::atan; 143 : 144 : inline float 145 : atan(float __x) 146 : { return __builtin_atanf(__x); } 147 : 148 : inline long double 149 : atan(long double __x) 150 : { return __builtin_atanl(__x); } 151 : 152 : template<typename _Tp> 153 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 154 : double>::__type 155 : atan(_Tp __x) 156 : { return __builtin_atan(__x); } 157 : 158 : using ::atan2; 159 : 160 : inline float 161 : atan2(float __y, float __x) 162 : { return __builtin_atan2f(__y, __x); } 163 : 164 : inline long double 165 : atan2(long double __y, long double __x) 166 : { return __builtin_atan2l(__y, __x); } 167 : 168 : template<typename _Tp, typename _Up> 169 : inline 170 : typename __gnu_cxx::__promote_2< 171 : typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value 172 : && __is_arithmetic<_Up>::__value, 173 : _Tp>::__type, _Up>::__type 174 : atan2(_Tp __y, _Up __x) 175 : { 176 : typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 177 : return atan2(__type(__y), __type(__x)); 178 : } 179 : 180 : using ::ceil; 181 : 182 : inline float 183 : ceil(float __x) 184 : { return __builtin_ceilf(__x); } 185 : 186 : inline long double 187 : ceil(long double __x) 188 : { return __builtin_ceill(__x); } 189 : 190 : template<typename _Tp> 191 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 192 : double>::__type 193 : ceil(_Tp __x) 194 : { return __builtin_ceil(__x); } 195 : 196 : using ::cos; 197 : 198 : inline float 199 : cos(float __x) 200 : { return __builtin_cosf(__x); } 201 : 202 : inline long double 203 : cos(long double __x) 204 : { return __builtin_cosl(__x); } 205 : 206 : template<typename _Tp> 207 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 208 : double>::__type 209 : cos(_Tp __x) 210 : { return __builtin_cos(__x); } 211 : 212 : using ::cosh; 213 : 214 : inline float 215 : cosh(float __x) 216 : { return __builtin_coshf(__x); } 217 : 218 : inline long double 219 : cosh(long double __x) 220 : { return __builtin_coshl(__x); } 221 : 222 : template<typename _Tp> 223 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 224 : double>::__type 225 : cosh(_Tp __x) 226 : { return __builtin_cosh(__x); } 227 : 228 : using ::exp; 229 : 230 : inline float 231 : exp(float __x) 232 : { return __builtin_expf(__x); } 233 : 234 : inline long double 235 : exp(long double __x) 236 : { return __builtin_expl(__x); } 237 : 238 : template<typename _Tp> 239 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 240 : double>::__type 241 : exp(_Tp __x) 242 : { return __builtin_exp(__x); } 243 : 244 : using ::fabs; 245 : 246 : inline float 247 : fabs(float __x) 248 : { return __builtin_fabsf(__x); } 249 : 250 : inline long double 251 : fabs(long double __x) 252 : { return __builtin_fabsl(__x); } 253 : 254 : template<typename _Tp> 255 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 256 : double>::__type 257 : fabs(_Tp __x) 258 : { return __builtin_fabs(__x); } 259 : 260 : using ::floor; 261 : 262 : inline float 263 : floor(float __x) 264 : { return __builtin_floorf(__x); } 265 : 266 : inline long double 267 : floor(long double __x) 268 : { return __builtin_floorl(__x); } 269 : 270 : template<typename _Tp> 271 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 272 : double>::__type 273 : floor(_Tp __x) 274 : { return __builtin_floor(__x); } 275 : 276 : using ::fmod; 277 : 278 : inline float 279 : fmod(float __x, float __y) 280 : { return __builtin_fmodf(__x, __y); } 281 : 282 : inline long double 283 : fmod(long double __x, long double __y) 284 : { return __builtin_fmodl(__x, __y); } 285 : 286 : using ::frexp; 287 : 288 : inline float 289 : frexp(float __x, int* __exp) 290 : { return __builtin_frexpf(__x, __exp); } 291 : 292 : inline long double 293 : frexp(long double __x, int* __exp) 294 : { return __builtin_frexpl(__x, __exp); } 295 : 296 : template<typename _Tp> 297 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 298 : double>::__type 299 : frexp(_Tp __x, int* __exp) 300 : { return __builtin_frexp(__x, __exp); } 301 : 302 : using ::ldexp; 303 : 304 : inline float 305 : ldexp(float __x, int __exp) 306 : { return __builtin_ldexpf(__x, __exp); } 307 : 308 : inline long double 309 : ldexp(long double __x, int __exp) 310 : { return __builtin_ldexpl(__x, __exp); } 311 : 312 : template<typename _Tp> 313 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 314 : double>::__type 315 : ldexp(_Tp __x, int __exp) 316 : { return __builtin_ldexp(__x, __exp); } 317 : 318 : using ::log; 319 : 320 : inline float 321 1 : log(float __x) 322 1 : { return __builtin_logf(__x); } 323 : 324 : inline long double 325 : log(long double __x) 326 : { return __builtin_logl(__x); } 327 : 328 : template<typename _Tp> 329 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 330 : double>::__type 331 : log(_Tp __x) 332 : { return __builtin_log(__x); } 333 : 334 : using ::log10; 335 : 336 : inline float 337 : log10(float __x) 338 : { return __builtin_log10f(__x); } 339 : 340 : inline long double 341 : log10(long double __x) 342 : { return __builtin_log10l(__x); } 343 : 344 : template<typename _Tp> 345 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 346 : double>::__type 347 : log10(_Tp __x) 348 : { return __builtin_log10(__x); } 349 : 350 : using ::modf; 351 : 352 : inline float 353 : modf(float __x, float* __iptr) 354 : { return __builtin_modff(__x, __iptr); } 355 : 356 : inline long double 357 : modf(long double __x, long double* __iptr) 358 : { return __builtin_modfl(__x, __iptr); } 359 : 360 : using ::pow; 361 : 362 : inline float 363 : pow(float __x, float __y) 364 : { return __builtin_powf(__x, __y); } 365 : 366 : inline long double 367 : pow(long double __x, long double __y) 368 : { return __builtin_powl(__x, __y); } 369 : 370 : // DR 550. 371 : inline double 372 : pow(double __x, int __i) 373 : { return __builtin_powi(__x, __i); } 374 : 375 : inline float 376 : pow(float __x, int __n) 377 : { return __builtin_powif(__x, __n); } 378 : 379 : inline long double 380 : pow(long double __x, int __n) 381 : { return __builtin_powil(__x, __n); } 382 : 383 : template<typename _Tp, typename _Up> 384 : inline 385 : typename __gnu_cxx::__promote_2< 386 : typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value 387 : && __is_arithmetic<_Up>::__value, 388 : _Tp>::__type, _Up>::__type 389 : pow(_Tp __x, _Up __y) 390 : { 391 : typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 392 : return pow(__type(__x), __type(__y)); 393 : } 394 : 395 : using ::sin; 396 : 397 : inline float 398 : sin(float __x) 399 : { return __builtin_sinf(__x); } 400 : 401 : inline long double 402 : sin(long double __x) 403 : { return __builtin_sinl(__x); } 404 : 405 : template<typename _Tp> 406 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 407 : double>::__type 408 : sin(_Tp __x) 409 : { return __builtin_sin(__x); } 410 : 411 : using ::sinh; 412 : 413 : inline float 414 : sinh(float __x) 415 : { return __builtin_sinhf(__x); } 416 : 417 : inline long double 418 : sinh(long double __x) 419 : { return __builtin_sinhl(__x); } 420 : 421 : template<typename _Tp> 422 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 423 : double>::__type 424 : sinh(_Tp __x) 425 : { return __builtin_sinh(__x); } 426 : 427 : using ::sqrt; 428 : 429 : inline float 430 : sqrt(float __x) 431 : { return __builtin_sqrtf(__x); } 432 : 433 : inline long double 434 : sqrt(long double __x) 435 : { return __builtin_sqrtl(__x); } 436 : 437 : template<typename _Tp> 438 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 439 : double>::__type 440 : sqrt(_Tp __x) 441 : { return __builtin_sqrt(__x); } 442 : 443 : using ::tan; 444 : 445 : inline float 446 : tan(float __x) 447 : { return __builtin_tanf(__x); } 448 : 449 : inline long double 450 : tan(long double __x) 451 : { return __builtin_tanl(__x); } 452 : 453 : template<typename _Tp> 454 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 455 : double>::__type 456 : tan(_Tp __x) 457 : { return __builtin_tan(__x); } 458 : 459 : using ::tanh; 460 : 461 : inline float 462 : tanh(float __x) 463 : { return __builtin_tanhf(__x); } 464 : 465 : inline long double 466 : tanh(long double __x) 467 : { return __builtin_tanhl(__x); } 468 : 469 : template<typename _Tp> 470 : inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 471 : double>::__type 472 : tanh(_Tp __x) 473 : { return __builtin_tanh(__x); } 474 : 475 : _GLIBCXX_END_NAMESPACE 476 : 477 : #if _GLIBCXX_USE_C99_MATH 478 : #if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC 479 : // These are possible macros imported from C99-land. For strict 480 : // conformance, remove possible C99-injected names from the global 481 : // namespace, and sequester them in the __gnu_cxx extension namespace. 482 : 483 : _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 484 : 485 : template<typename _Tp> 486 : inline int 487 : __capture_fpclassify(_Tp __f) { return fpclassify(__f); } 488 : 489 : _GLIBCXX_END_NAMESPACE 490 : 491 : // Only undefine the C99 FP macros, if actually captured for namespace movement 492 : #undef fpclassify 493 : #undef isfinite 494 : #undef isinf 495 : #undef isnan 496 : #undef isnormal 497 : #undef signbit 498 : #undef isgreater 499 : #undef isgreaterequal 500 : #undef isless 501 : #undef islessequal 502 : #undef islessgreater 503 : #undef isunordered 504 : 505 : _GLIBCXX_BEGIN_NAMESPACE(std) 506 : 507 : template<typename _Tp> 508 : inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, 509 : int>::__type 510 : fpclassify(_Tp __f) 511 : { 512 : typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 513 : return ::__gnu_cxx::__capture_fpclassify(__type(__f)); 514 : } 515 : 516 : template<typename _Tp> 517 : inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, 518 : int>::__type 519 : isfinite(_Tp __f) 520 : { 521 : typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 522 : return __builtin_isfinite(__type(__f)); 523 : } 524 : 525 : template<typename _Tp> 526 : inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, 527 : int>::__type 528 : isinf(_Tp __f) 529 : { 530 : typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 531 : return __builtin_isinf(__type(__f)); 532 : } 533 : 534 : template<typename _Tp> 535 : inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, 536 : int>::__type 537 : isnan(_Tp __f) 538 : { 539 : typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 540 : return __builtin_isnan(__type(__f)); 541 : } 542 : 543 : template<typename _Tp> 544 : inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, 545 : int>::__type 546 : isnormal(_Tp __f) 547 : { 548 : typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 549 : return __builtin_isnormal(__type(__f)); 550 : } 551 : 552 : template<typename _Tp> 553 : inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, 554 : int>::__type 555 : signbit(_Tp __f) 556 : { 557 : typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 558 : return __builtin_signbit(__type(__f)); 559 : } 560 : 561 : template<typename _Tp> 562 : inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, 563 : int>::__type 564 : isgreater(_Tp __f1, _Tp __f2) 565 : { 566 : typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 567 : return __builtin_isgreater(__type(__f1), __type(__f2)); 568 : } 569 : 570 : template<typename _Tp> 571 : inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, 572 : int>::__type 573 : isgreaterequal(_Tp __f1, _Tp __f2) 574 : { 575 : typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 576 : return __builtin_isgreaterequal(__type(__f1), __type(__f2)); 577 : } 578 : 579 : template<typename _Tp> 580 : inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, 581 : int>::__type 582 : isless(_Tp __f1, _Tp __f2) 583 : { 584 : typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 585 : return __builtin_isless(__type(__f1), __type(__f2)); 586 : } 587 : 588 : template<typename _Tp> 589 : inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, 590 : int>::__type 591 : islessequal(_Tp __f1, _Tp __f2) 592 : { 593 : typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 594 : return __builtin_islessequal(__type(__f1), __type(__f2)); 595 : } 596 : 597 : template<typename _Tp> 598 : inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, 599 : int>::__type 600 : islessgreater(_Tp __f1, _Tp __f2) 601 : { 602 : typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 603 : return __builtin_islessgreater(__type(__f1), __type(__f2)); 604 : } 605 : 606 : template<typename _Tp> 607 : inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, 608 : int>::__type 609 : isunordered(_Tp __f1, _Tp __f2) 610 : { 611 : typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 612 : return __builtin_isunordered(__type(__f1), __type(__f2)); 613 : } 614 : 615 : _GLIBCXX_END_NAMESPACE 616 : 617 : #endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ 618 : #endif 619 : 620 : #ifndef _GLIBCXX_EXPORT_TEMPLATE 621 : # include <bits/cmath.tcc> 622 : #endif 623 : 624 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 625 : # if defined(_GLIBCXX_INCLUDE_AS_TR1) 626 : # error C++0x header cannot be included from TR1 header 627 : # endif 628 : # if defined(_GLIBCXX_INCLUDE_AS_CXX0X) 629 : # include <tr1_impl/cmath> 630 : # else 631 : # define _GLIBCXX_INCLUDE_AS_CXX0X 632 : # define _GLIBCXX_BEGIN_NAMESPACE_TR1 633 : # define _GLIBCXX_END_NAMESPACE_TR1 634 : # define _GLIBCXX_TR1 635 : # include <tr1_impl/cmath> 636 : # undef _GLIBCXX_TR1 637 : # undef _GLIBCXX_END_NAMESPACE_TR1 638 : # undef _GLIBCXX_BEGIN_NAMESPACE_TR1 639 : # undef _GLIBCXX_INCLUDE_AS_CXX0X 640 : # endif 641 : #endif 642 : 643 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Standard exception classes -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2005, 2007 Free Software Foundation, Inc. 4 : // 5 : // This file is part of the GNU ISO C++ Library. This library is free 6 : // software; you can redistribute it and/or modify it under the 7 : // terms of the GNU General Public License as published by the 8 : // Free Software Foundation; either version 2, or (at your option) 9 : // any later version. 10 : 11 : // This library is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : 16 : // You should have received a copy of the GNU General Public License 17 : // along with this library; see the file COPYING. If not, write to 18 : // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 19 : // Boston, MA 02110-1301, USA. 20 : 21 : // As a special exception, you may use this file as part of a free software 22 : // library without restriction. Specifically, if other files instantiate 23 : // templates or use macros or inline functions from this file, or you compile 24 : // this file and link it with other files to produce an executable, this 25 : // file does not by itself cause the resulting executable to be covered by 26 : // the GNU General Public License. This exception does not however 27 : // invalidate any other reasons why the executable file might be covered by 28 : // the GNU General Public License. 29 : 30 : /** @file stdexcept 31 : * This is a Standard C++ Library header. 32 : */ 33 : 34 : // 35 : // ISO C++ 19.1 Exception classes 36 : // 37 : 38 : #ifndef _GLIBCXX_STDEXCEPT 39 : #define _GLIBCXX_STDEXCEPT 1 40 : 41 : #pragma GCC system_header 42 : 43 : #include <exception> 44 : #include <string> 45 : 46 : _GLIBCXX_BEGIN_NAMESPACE(std) 47 : 48 : /** Logic errors represent problems in the internal logic of a program; 49 : * in theory, these are preventable, and even detectable before the 50 : * program runs (e.g., violations of class invariants). 51 : * @brief One of two subclasses of exception. 52 : */ 53 : class logic_error : public exception 54 : { 55 : string _M_msg; 56 : 57 : public: 58 : /** Takes a character string describing the error. */ 59 : explicit 60 : logic_error(const string& __arg); 61 : 62 : virtual 63 : ~logic_error() throw(); 64 : 65 : /** Returns a C-style character string describing the general cause of 66 : * the current error (the same string passed to the ctor). */ 67 : virtual const char* 68 : what() const throw(); 69 : }; 70 : 71 : /** Thrown by the library, or by you, to report domain errors (domain in 72 : * the mathematical sense). */ 73 : class domain_error : public logic_error 74 : { 75 : public: 76 : explicit domain_error(const string& __arg); 77 : }; 78 : 79 : /** Thrown to report invalid arguments to functions. */ 80 : class invalid_argument : public logic_error 81 : { 82 : public: 83 : explicit invalid_argument(const string& __arg); 84 : }; 85 : 86 : /** Thrown when an object is constructed that would exceed its maximum 87 : * permitted size (e.g., a basic_string instance). */ 88 : class length_error : public logic_error 89 : { 90 : public: 91 : explicit length_error(const string& __arg); 92 : }; 93 : 94 : /** This represents an argument whose value is not within the expected 95 : * range (e.g., boundary checks in basic_string). */ 96 : class out_of_range : public logic_error 97 1 : { 98 : public: 99 : explicit out_of_range(const string& __arg); 100 : }; 101 : 102 : /** Runtime errors represent problems outside the scope of a program; 103 : * they cannot be easily predicted and can generally only be caught as 104 : * the program executes. 105 : * @brief One of two subclasses of exception. 106 : */ 107 : class runtime_error : public exception 108 : { 109 : string _M_msg; 110 : 111 : public: 112 : /** Takes a character string describing the error. */ 113 : explicit 114 : runtime_error(const string& __arg); 115 : 116 : virtual 117 : ~runtime_error() throw(); 118 : 119 : /** Returns a C-style character string describing the general cause of 120 : * the current error (the same string passed to the ctor). */ 121 : virtual const char* 122 : what() const throw(); 123 : }; 124 : 125 : /** Thrown to indicate range errors in internal computations. */ 126 : class range_error : public runtime_error 127 : { 128 : public: 129 : explicit range_error(const string& __arg); 130 : }; 131 : 132 : /** Thrown to indicate arithmetic overflow. */ 133 : class overflow_error : public runtime_error 134 : { 135 : public: 136 : explicit overflow_error(const string& __arg); 137 : }; 138 : 139 : /** Thrown to indicate arithmetic underflow. */ 140 : class underflow_error : public runtime_error 141 : { 142 : public: 143 : explicit underflow_error(const string& __arg); 144 : }; 145 : 146 : _GLIBCXX_END_NAMESPACE 147 : 148 : #endif /* _GLIBCXX_STDEXCEPT */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
cmath |
|
100.0 % | 2 / 2 lines | |
exception |
|
50.0 % | 1 / 2 lines | |
fstream |
|
0.0 % | 0 / 38 lines | |
iomanip |
|
40.0 % | 4 / 10 lines | |
iosfwd |
|
0.0 % | 0 / 1 lines | |
iostream |
|
100.0 % | 1 / 1 lines | |
istream |
|
0.0 % | 0 / 8 lines | |
new |
|
50.0 % | 1 / 2 lines | |
ostream |
|
0.0 % | 0 / 33 lines | |
sstream |
|
0.0 % | 0 / 43 lines | |
stdexcept |
|
100.0 % | 1 / 1 lines | |
streambuf |
|
0.0 % | 0 / 36 lines | |
typeinfo |
|
50.0 % | 2 / 4 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Functor implementations -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996-1998 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_function.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_FUNCTION_H 63 : #define _STL_FUNCTION_H 1 64 : 65 : _GLIBCXX_BEGIN_NAMESPACE(std) 66 : 67 : // 20.3.1 base classes 68 : /** @defgroup s20_3_1_base Functor Base Classes 69 : * Function objects, or @e functors, are objects with an @c operator() 70 : * defined and accessible. They can be passed as arguments to algorithm 71 : * templates and used in place of a function pointer. Not only is the 72 : * resulting expressiveness of the library increased, but the generated 73 : * code can be more efficient than what you might write by hand. When we 74 : * refer to "functors," then, generally we include function pointers in 75 : * the description as well. 76 : * 77 : * Often, functors are only created as temporaries passed to algorithm 78 : * calls, rather than being created as named variables. 79 : * 80 : * Two examples taken from the standard itself follow. To perform a 81 : * by-element addition of two vectors @c a and @c b containing @c double, 82 : * and put the result in @c a, use 83 : * \code 84 : * transform (a.begin(), a.end(), b.begin(), a.begin(), plus<double>()); 85 : * \endcode 86 : * To negate every element in @c a, use 87 : * \code 88 : * transform(a.begin(), a.end(), a.begin(), negate<double>()); 89 : * \endcode 90 : * The addition and negation functions will be inlined directly. 91 : * 92 : * The standard functors are derived from structs named @c unary_function 93 : * and @c binary_function. These two classes contain nothing but typedefs, 94 : * to aid in generic (template) programming. If you write your own 95 : * functors, you might consider doing the same. 96 : * 97 : * @{ 98 : */ 99 : /** 100 : * This is one of the @link s20_3_1_base functor base classes@endlink. 101 : */ 102 : template<typename _Arg, typename _Result> 103 : struct unary_function 104 21 : { 105 : typedef _Arg argument_type; ///< @c argument_type is the type of the 106 : /// argument (no surprises here) 107 : 108 : typedef _Result result_type; ///< @c result_type is the return type 109 : }; 110 : 111 : /** 112 : * This is one of the @link s20_3_1_base functor base classes@endlink. 113 : */ 114 : template<typename _Arg1, typename _Arg2, typename _Result> 115 : struct binary_function 116 : { 117 : typedef _Arg1 first_argument_type; ///< the type of the first argument 118 : /// (no surprises here) 119 : 120 : typedef _Arg2 second_argument_type; ///< the type of the second argument 121 : typedef _Result result_type; ///< type of the return type 122 : }; 123 : /** @} */ 124 : 125 : // 20.3.2 arithmetic 126 : /** @defgroup s20_3_2_arithmetic Arithmetic Classes 127 : 128 : * Because basic math often needs to be done during an algorithm, 129 : * the library provides functors for those operations. See the 130 : * documentation for @link s20_3_1_base the base classes@endlink 131 : * for examples of their use. 132 : * 133 : * @{ 134 : */ 135 : /// One of the @link s20_3_2_arithmetic math functors@endlink. 136 : template<typename _Tp> 137 : struct plus : public binary_function<_Tp, _Tp, _Tp> 138 : { 139 : _Tp 140 4 : operator()(const _Tp& __x, const _Tp& __y) const 141 4 : { return __x + __y; } 142 : }; 143 : 144 : /// One of the @link s20_3_2_arithmetic math functors@endlink. 145 : template<typename _Tp> 146 : struct minus : public binary_function<_Tp, _Tp, _Tp> 147 : { 148 : _Tp 149 : operator()(const _Tp& __x, const _Tp& __y) const 150 : { return __x - __y; } 151 : }; 152 : 153 : /// One of the @link s20_3_2_arithmetic math functors@endlink. 154 : template<typename _Tp> 155 : struct multiplies : public binary_function<_Tp, _Tp, _Tp> 156 : { 157 : _Tp 158 : operator()(const _Tp& __x, const _Tp& __y) const 159 : { return __x * __y; } 160 : }; 161 : 162 : /// One of the @link s20_3_2_arithmetic math functors@endlink. 163 : template<typename _Tp> 164 : struct divides : public binary_function<_Tp, _Tp, _Tp> 165 : { 166 : _Tp 167 : operator()(const _Tp& __x, const _Tp& __y) const 168 : { return __x / __y; } 169 : }; 170 : 171 : /// One of the @link s20_3_2_arithmetic math functors@endlink. 172 : template<typename _Tp> 173 : struct modulus : public binary_function<_Tp, _Tp, _Tp> 174 : { 175 : _Tp 176 : operator()(const _Tp& __x, const _Tp& __y) const 177 : { return __x % __y; } 178 : }; 179 : 180 : /// One of the @link s20_3_2_arithmetic math functors@endlink. 181 : template<typename _Tp> 182 : struct negate : public unary_function<_Tp, _Tp> 183 : { 184 : _Tp 185 : operator()(const _Tp& __x) const 186 : { return -__x; } 187 : }; 188 : /** @} */ 189 : 190 : // 20.3.3 comparisons 191 : /** @defgroup s20_3_3_comparisons Comparison Classes 192 : * The library provides six wrapper functors for all the basic comparisons 193 : * in C++, like @c <. 194 : * 195 : * @{ 196 : */ 197 : /// One of the @link s20_3_3_comparisons comparison functors@endlink. 198 : template<typename _Tp> 199 : struct equal_to : public binary_function<_Tp, _Tp, bool> 200 : { 201 : bool 202 66 : operator()(const _Tp& __x, const _Tp& __y) const 203 66 : { return __x == __y; } 204 : }; 205 : 206 : /// One of the @link s20_3_3_comparisons comparison functors@endlink. 207 : template<typename _Tp> 208 : struct not_equal_to : public binary_function<_Tp, _Tp, bool> 209 : { 210 : bool 211 : operator()(const _Tp& __x, const _Tp& __y) const 212 : { return __x != __y; } 213 : }; 214 : 215 : /// One of the @link s20_3_3_comparisons comparison functors@endlink. 216 : template<typename _Tp> 217 : struct greater : public binary_function<_Tp, _Tp, bool> 218 : { 219 : bool 220 : operator()(const _Tp& __x, const _Tp& __y) const 221 : { return __x > __y; } 222 : }; 223 : 224 : /// One of the @link s20_3_3_comparisons comparison functors@endlink. 225 : template<typename _Tp> 226 : struct less : public binary_function<_Tp, _Tp, bool> 227 : { 228 : bool 229 10727242 : operator()(const _Tp& __x, const _Tp& __y) const 230 10727242 : { return __x < __y; } 231 : }; 232 : 233 : /// One of the @link s20_3_3_comparisons comparison functors@endlink. 234 : template<typename _Tp> 235 : struct greater_equal : public binary_function<_Tp, _Tp, bool> 236 : { 237 : bool 238 : operator()(const _Tp& __x, const _Tp& __y) const 239 : { return __x >= __y; } 240 : }; 241 : 242 : /// One of the @link s20_3_3_comparisons comparison functors@endlink. 243 : template<typename _Tp> 244 : struct less_equal : public binary_function<_Tp, _Tp, bool> 245 : { 246 : bool 247 : operator()(const _Tp& __x, const _Tp& __y) const 248 : { return __x <= __y; } 249 : }; 250 : /** @} */ 251 : 252 : // 20.3.4 logical operations 253 : /** @defgroup s20_3_4_logical Boolean Operations Classes 254 : * Here are wrapper functors for Boolean operations: @c &&, @c ||, 255 : * and @c !. 256 : * 257 : * @{ 258 : */ 259 : /// One of the @link s20_3_4_logical Boolean operations functors@endlink. 260 : template<typename _Tp> 261 : struct logical_and : public binary_function<_Tp, _Tp, bool> 262 : { 263 : bool 264 : operator()(const _Tp& __x, const _Tp& __y) const 265 : { return __x && __y; } 266 : }; 267 : 268 : /// One of the @link s20_3_4_logical Boolean operations functors@endlink. 269 : template<typename _Tp> 270 : struct logical_or : public binary_function<_Tp, _Tp, bool> 271 : { 272 : bool 273 : operator()(const _Tp& __x, const _Tp& __y) const 274 : { return __x || __y; } 275 : }; 276 : 277 : /// One of the @link s20_3_4_logical Boolean operations functors@endlink. 278 : template<typename _Tp> 279 : struct logical_not : public unary_function<_Tp, bool> 280 : { 281 : bool 282 : operator()(const _Tp& __x) const 283 : { return !__x; } 284 : }; 285 : /** @} */ 286 : 287 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 288 : // DR 660. Missing Bitwise Operations. 289 : template<typename _Tp> 290 : struct bit_and : public binary_function<_Tp, _Tp, _Tp> 291 : { 292 : _Tp 293 : operator()(const _Tp& __x, const _Tp& __y) const 294 : { return __x & __y; } 295 : }; 296 : 297 : template<typename _Tp> 298 : struct bit_or : public binary_function<_Tp, _Tp, _Tp> 299 : { 300 : _Tp 301 : operator()(const _Tp& __x, const _Tp& __y) const 302 : { return __x | __y; } 303 : }; 304 : 305 : template<typename _Tp> 306 : struct bit_xor : public binary_function<_Tp, _Tp, _Tp> 307 : { 308 : _Tp 309 : operator()(const _Tp& __x, const _Tp& __y) const 310 : { return __x ^ __y; } 311 : }; 312 : 313 : // 20.3.5 negators 314 : /** @defgroup s20_3_5_negators Negators 315 : * The functions @c not1 and @c not2 each take a predicate functor 316 : * and return an instance of @c unary_negate or 317 : * @c binary_negate, respectively. These classes are functors whose 318 : * @c operator() performs the stored predicate function and then returns 319 : * the negation of the result. 320 : * 321 : * For example, given a vector of integers and a trivial predicate, 322 : * \code 323 : * struct IntGreaterThanThree 324 : * : public std::unary_function<int, bool> 325 : * { 326 : * bool operator() (int x) { return x > 3; } 327 : * }; 328 : * 329 : * std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree())); 330 : * \endcode 331 : * The call to @c find_if will locate the first index (i) of @c v for which 332 : * "!(v[i] > 3)" is true. 333 : * 334 : * The not1/unary_negate combination works on predicates taking a single 335 : * argument. The not2/binary_negate combination works on predicates which 336 : * take two arguments. 337 : * 338 : * @{ 339 : */ 340 : /// One of the @link s20_3_5_negators negation functors@endlink. 341 : template<typename _Predicate> 342 : class unary_negate 343 : : public unary_function<typename _Predicate::argument_type, bool> 344 : { 345 : protected: 346 : _Predicate _M_pred; 347 : 348 : public: 349 : explicit 350 : unary_negate(const _Predicate& __x) : _M_pred(__x) { } 351 : 352 : bool 353 : operator()(const typename _Predicate::argument_type& __x) const 354 : { return !_M_pred(__x); } 355 : }; 356 : 357 : /// One of the @link s20_3_5_negators negation functors@endlink. 358 : template<typename _Predicate> 359 : inline unary_negate<_Predicate> 360 : not1(const _Predicate& __pred) 361 : { return unary_negate<_Predicate>(__pred); } 362 : 363 : /// One of the @link s20_3_5_negators negation functors@endlink. 364 : template<typename _Predicate> 365 : class binary_negate 366 : : public binary_function<typename _Predicate::first_argument_type, 367 : typename _Predicate::second_argument_type, bool> 368 : { 369 : protected: 370 : _Predicate _M_pred; 371 : 372 : public: 373 : explicit 374 : binary_negate(const _Predicate& __x) : _M_pred(__x) { } 375 : 376 : bool 377 : operator()(const typename _Predicate::first_argument_type& __x, 378 : const typename _Predicate::second_argument_type& __y) const 379 : { return !_M_pred(__x, __y); } 380 : }; 381 : 382 : /// One of the @link s20_3_5_negators negation functors@endlink. 383 : template<typename _Predicate> 384 : inline binary_negate<_Predicate> 385 : not2(const _Predicate& __pred) 386 : { return binary_negate<_Predicate>(__pred); } 387 : /** @} */ 388 : 389 : // 20.3.7 adaptors pointers functions 390 : /** @defgroup s20_3_7_adaptors Adaptors for pointers to functions 391 : * The advantage of function objects over pointers to functions is that 392 : * the objects in the standard library declare nested typedefs describing 393 : * their argument and result types with uniform names (e.g., @c result_type 394 : * from the base classes @c unary_function and @c binary_function). 395 : * Sometimes those typedefs are required, not just optional. 396 : * 397 : * Adaptors are provided to turn pointers to unary (single-argument) and 398 : * binary (double-argument) functions into function objects. The 399 : * long-winded functor @c pointer_to_unary_function is constructed with a 400 : * function pointer @c f, and its @c operator() called with argument @c x 401 : * returns @c f(x). The functor @c pointer_to_binary_function does the same 402 : * thing, but with a double-argument @c f and @c operator(). 403 : * 404 : * The function @c ptr_fun takes a pointer-to-function @c f and constructs 405 : * an instance of the appropriate functor. 406 : * 407 : * @{ 408 : */ 409 : /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. 410 : template<typename _Arg, typename _Result> 411 : class pointer_to_unary_function : public unary_function<_Arg, _Result> 412 : { 413 : protected: 414 : _Result (*_M_ptr)(_Arg); 415 : 416 : public: 417 : pointer_to_unary_function() { } 418 : 419 : explicit 420 2 : pointer_to_unary_function(_Result (*__x)(_Arg)) 421 2 : : _M_ptr(__x) { } 422 : 423 : _Result 424 516 : operator()(_Arg __x) const 425 516 : { return _M_ptr(__x); } 426 : }; 427 : 428 : /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. 429 : template<typename _Arg, typename _Result> 430 : inline pointer_to_unary_function<_Arg, _Result> 431 2 : ptr_fun(_Result (*__x)(_Arg)) 432 2 : { return pointer_to_unary_function<_Arg, _Result>(__x); } 433 : 434 : /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. 435 : template<typename _Arg1, typename _Arg2, typename _Result> 436 : class pointer_to_binary_function 437 : : public binary_function<_Arg1, _Arg2, _Result> 438 : { 439 : protected: 440 : _Result (*_M_ptr)(_Arg1, _Arg2); 441 : 442 : public: 443 : pointer_to_binary_function() { } 444 : 445 : explicit 446 : pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) 447 : : _M_ptr(__x) { } 448 : 449 : _Result 450 : operator()(_Arg1 __x, _Arg2 __y) const 451 : { return _M_ptr(__x, __y); } 452 : }; 453 : 454 : /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. 455 : template<typename _Arg1, typename _Arg2, typename _Result> 456 : inline pointer_to_binary_function<_Arg1, _Arg2, _Result> 457 : ptr_fun(_Result (*__x)(_Arg1, _Arg2)) 458 : { return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); } 459 : /** @} */ 460 : 461 : template<typename _Tp> 462 : struct _Identity : public unary_function<_Tp,_Tp> 463 : { 464 : _Tp& 465 : operator()(_Tp& __x) const 466 : { return __x; } 467 : 468 : const _Tp& 469 16055496 : operator()(const _Tp& __x) const 470 16055496 : { return __x; } 471 : }; 472 : 473 : template<typename _Pair> 474 : struct _Select1st : public unary_function<_Pair, 475 : typename _Pair::first_type> 476 : { 477 : typename _Pair::first_type& 478 : operator()(_Pair& __x) const 479 : { return __x.first; } 480 : 481 : const typename _Pair::first_type& 482 4509167 : operator()(const _Pair& __x) const 483 4509167 : { return __x.first; } 484 : }; 485 : 486 : template<typename _Pair> 487 : struct _Select2nd : public unary_function<_Pair, 488 : typename _Pair::second_type> 489 : { 490 : typename _Pair::second_type& 491 : operator()(_Pair& __x) const 492 : { return __x.second; } 493 : 494 : const typename _Pair::second_type& 495 : operator()(const _Pair& __x) const 496 : { return __x.second; } 497 : }; 498 : 499 : // 20.3.8 adaptors pointers members 500 : /** @defgroup s20_3_8_memadaptors Adaptors for pointers to members 501 : * There are a total of 8 = 2^3 function objects in this family. 502 : * (1) Member functions taking no arguments vs member functions taking 503 : * one argument. 504 : * (2) Call through pointer vs call through reference. 505 : * (3) Const vs non-const member function. 506 : * 507 : * All of this complexity is in the function objects themselves. You can 508 : * ignore it by using the helper function mem_fun and mem_fun_ref, 509 : * which create whichever type of adaptor is appropriate. 510 : * 511 : * @{ 512 : */ 513 : /// One of the @link s20_3_8_memadaptors adaptors for member 514 : /// pointers@endlink. 515 : template<typename _Ret, typename _Tp> 516 : class mem_fun_t : public unary_function<_Tp*, _Ret> 517 : { 518 : public: 519 : explicit 520 : mem_fun_t(_Ret (_Tp::*__pf)()) 521 : : _M_f(__pf) { } 522 : 523 : _Ret 524 : operator()(_Tp* __p) const 525 : { return (__p->*_M_f)(); } 526 : 527 : private: 528 : _Ret (_Tp::*_M_f)(); 529 : }; 530 : 531 : /// One of the @link s20_3_8_memadaptors adaptors for member 532 : /// pointers@endlink. 533 : template<typename _Ret, typename _Tp> 534 : class const_mem_fun_t : public unary_function<const _Tp*, _Ret> 535 : { 536 : public: 537 : explicit 538 : const_mem_fun_t(_Ret (_Tp::*__pf)() const) 539 : : _M_f(__pf) { } 540 : 541 : _Ret 542 : operator()(const _Tp* __p) const 543 : { return (__p->*_M_f)(); } 544 : 545 : private: 546 : _Ret (_Tp::*_M_f)() const; 547 : }; 548 : 549 : /// One of the @link s20_3_8_memadaptors adaptors for member 550 : /// pointers@endlink. 551 : template<typename _Ret, typename _Tp> 552 : class mem_fun_ref_t : public unary_function<_Tp, _Ret> 553 : { 554 : public: 555 : explicit 556 : mem_fun_ref_t(_Ret (_Tp::*__pf)()) 557 : : _M_f(__pf) { } 558 : 559 : _Ret 560 : operator()(_Tp& __r) const 561 : { return (__r.*_M_f)(); } 562 : 563 : private: 564 : _Ret (_Tp::*_M_f)(); 565 : }; 566 : 567 : /// One of the @link s20_3_8_memadaptors adaptors for member 568 : /// pointers@endlink. 569 : template<typename _Ret, typename _Tp> 570 : class const_mem_fun_ref_t : public unary_function<_Tp, _Ret> 571 : { 572 : public: 573 : explicit 574 : const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) 575 : : _M_f(__pf) { } 576 : 577 : _Ret 578 : operator()(const _Tp& __r) const 579 : { return (__r.*_M_f)(); } 580 : 581 : private: 582 : _Ret (_Tp::*_M_f)() const; 583 : }; 584 : 585 : /// One of the @link s20_3_8_memadaptors adaptors for member 586 : /// pointers@endlink. 587 : template<typename _Ret, typename _Tp, typename _Arg> 588 : class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret> 589 : { 590 : public: 591 : explicit 592 : mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) 593 : : _M_f(__pf) { } 594 : 595 : _Ret 596 : operator()(_Tp* __p, _Arg __x) const 597 : { return (__p->*_M_f)(__x); } 598 : 599 : private: 600 : _Ret (_Tp::*_M_f)(_Arg); 601 : }; 602 : 603 : /// One of the @link s20_3_8_memadaptors adaptors for member 604 : /// pointers@endlink. 605 : template<typename _Ret, typename _Tp, typename _Arg> 606 : class const_mem_fun1_t : public binary_function<const _Tp*, _Arg, _Ret> 607 : { 608 : public: 609 : explicit 610 : const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) 611 : : _M_f(__pf) { } 612 : 613 : _Ret 614 : operator()(const _Tp* __p, _Arg __x) const 615 : { return (__p->*_M_f)(__x); } 616 : 617 : private: 618 : _Ret (_Tp::*_M_f)(_Arg) const; 619 : }; 620 : 621 : /// One of the @link s20_3_8_memadaptors adaptors for member 622 : /// pointers@endlink. 623 : template<typename _Ret, typename _Tp, typename _Arg> 624 : class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> 625 : { 626 : public: 627 : explicit 628 : mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) 629 : : _M_f(__pf) { } 630 : 631 : _Ret 632 : operator()(_Tp& __r, _Arg __x) const 633 : { return (__r.*_M_f)(__x); } 634 : 635 : private: 636 : _Ret (_Tp::*_M_f)(_Arg); 637 : }; 638 : 639 : /// One of the @link s20_3_8_memadaptors adaptors for member 640 : /// pointers@endlink. 641 : template<typename _Ret, typename _Tp, typename _Arg> 642 : class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> 643 : { 644 : public: 645 : explicit 646 : const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) 647 : : _M_f(__pf) { } 648 : 649 : _Ret 650 : operator()(const _Tp& __r, _Arg __x) const 651 : { return (__r.*_M_f)(__x); } 652 : 653 : private: 654 : _Ret (_Tp::*_M_f)(_Arg) const; 655 : }; 656 : 657 : // Mem_fun adaptor helper functions. There are only two: 658 : // mem_fun and mem_fun_ref. 659 : template<typename _Ret, typename _Tp> 660 : inline mem_fun_t<_Ret, _Tp> 661 : mem_fun(_Ret (_Tp::*__f)()) 662 : { return mem_fun_t<_Ret, _Tp>(__f); } 663 : 664 : template<typename _Ret, typename _Tp> 665 : inline const_mem_fun_t<_Ret, _Tp> 666 : mem_fun(_Ret (_Tp::*__f)() const) 667 : { return const_mem_fun_t<_Ret, _Tp>(__f); } 668 : 669 : template<typename _Ret, typename _Tp> 670 : inline mem_fun_ref_t<_Ret, _Tp> 671 : mem_fun_ref(_Ret (_Tp::*__f)()) 672 : { return mem_fun_ref_t<_Ret, _Tp>(__f); } 673 : 674 : template<typename _Ret, typename _Tp> 675 : inline const_mem_fun_ref_t<_Ret, _Tp> 676 : mem_fun_ref(_Ret (_Tp::*__f)() const) 677 : { return const_mem_fun_ref_t<_Ret, _Tp>(__f); } 678 : 679 : template<typename _Ret, typename _Tp, typename _Arg> 680 : inline mem_fun1_t<_Ret, _Tp, _Arg> 681 : mem_fun(_Ret (_Tp::*__f)(_Arg)) 682 : { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } 683 : 684 : template<typename _Ret, typename _Tp, typename _Arg> 685 : inline const_mem_fun1_t<_Ret, _Tp, _Arg> 686 : mem_fun(_Ret (_Tp::*__f)(_Arg) const) 687 : { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } 688 : 689 : template<typename _Ret, typename _Tp, typename _Arg> 690 : inline mem_fun1_ref_t<_Ret, _Tp, _Arg> 691 : mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) 692 : { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } 693 : 694 : template<typename _Ret, typename _Tp, typename _Arg> 695 : inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> 696 : mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) 697 : { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } 698 : 699 : /** @} */ 700 : 701 : _GLIBCXX_END_NAMESPACE 702 : 703 : #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED 704 : # include <backward/binders.h> 705 : #endif 706 : 707 : #endif /* _STL_FUNCTION_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Vector implementation (out of line) -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file vector.tcc 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _VECTOR_TCC 63 : #define _VECTOR_TCC 1 64 : 65 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) 66 : 67 : template<typename _Tp, typename _Alloc> 68 : void 69 : vector<_Tp, _Alloc>:: 70 10 : reserve(size_type __n) 71 : { 72 10 : if (__n > this->max_size()) 73 0 : __throw_length_error(__N("vector::reserve")); 74 10 : if (this->capacity() < __n) 75 : { 76 10 : const size_type __old_size = size(); 77 : pointer __tmp = _M_allocate_and_copy(__n, 78 : _GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_start), 79 10 : _GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_finish)); 80 10 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 81 : _M_get_Tp_allocator()); 82 10 : _M_deallocate(this->_M_impl._M_start, 83 : this->_M_impl._M_end_of_storage 84 : - this->_M_impl._M_start); 85 10 : this->_M_impl._M_start = __tmp; 86 10 : this->_M_impl._M_finish = __tmp + __old_size; 87 10 : this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; 88 : } 89 10 : } 90 : 91 : template<typename _Tp, typename _Alloc> 92 : typename vector<_Tp, _Alloc>::iterator 93 : vector<_Tp, _Alloc>:: 94 19 : insert(iterator __position, const value_type& __x) 95 : { 96 19 : const size_type __n = __position - begin(); 97 19 : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage 98 : && __position == end()) 99 : { 100 0 : this->_M_impl.construct(this->_M_impl._M_finish, __x); 101 0 : ++this->_M_impl._M_finish; 102 : } 103 : else 104 : { 105 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 106 : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) 107 : { 108 : _Tp __x_copy = __x; 109 : _M_insert_aux(__position, std::move(__x_copy)); 110 : } 111 : else 112 : #endif 113 19 : _M_insert_aux(__position, __x); 114 : } 115 19 : return iterator(this->_M_impl._M_start + __n); 116 : } 117 : 118 : template<typename _Tp, typename _Alloc> 119 : typename vector<_Tp, _Alloc>::iterator 120 : vector<_Tp, _Alloc>:: 121 2 : erase(iterator __position) 122 : { 123 2 : if (__position + 1 != end()) 124 0 : _GLIBCXX_MOVE3(__position + 1, end(), __position); 125 2 : --this->_M_impl._M_finish; 126 2 : this->_M_impl.destroy(this->_M_impl._M_finish); 127 2 : return __position; 128 : } 129 : 130 : template<typename _Tp, typename _Alloc> 131 : typename vector<_Tp, _Alloc>::iterator 132 : vector<_Tp, _Alloc>:: 133 : erase(iterator __first, iterator __last) 134 : { 135 : if (__last != end()) 136 : _GLIBCXX_MOVE3(__last, end(), __first); 137 : _M_erase_at_end(__first.base() + (end() - __last)); 138 : return __first; 139 : } 140 : 141 : template<typename _Tp, typename _Alloc> 142 : vector<_Tp, _Alloc>& 143 : vector<_Tp, _Alloc>:: 144 : operator=(const vector<_Tp, _Alloc>& __x) 145 : { 146 : if (&__x != this) 147 : { 148 : const size_type __xlen = __x.size(); 149 : if (__xlen > capacity()) 150 : { 151 : pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), 152 : __x.end()); 153 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 154 : _M_get_Tp_allocator()); 155 : _M_deallocate(this->_M_impl._M_start, 156 : this->_M_impl._M_end_of_storage 157 : - this->_M_impl._M_start); 158 : this->_M_impl._M_start = __tmp; 159 : this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen; 160 : } 161 : else if (size() >= __xlen) 162 : { 163 : std::_Destroy(std::copy(__x.begin(), __x.end(), begin()), 164 : end(), _M_get_Tp_allocator()); 165 : } 166 : else 167 : { 168 : std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(), 169 : this->_M_impl._M_start); 170 : std::__uninitialized_copy_a(__x._M_impl._M_start + size(), 171 : __x._M_impl._M_finish, 172 : this->_M_impl._M_finish, 173 : _M_get_Tp_allocator()); 174 : } 175 : this->_M_impl._M_finish = this->_M_impl._M_start + __xlen; 176 : } 177 : return *this; 178 : } 179 : 180 : template<typename _Tp, typename _Alloc> 181 : void 182 : vector<_Tp, _Alloc>:: 183 : _M_fill_assign(size_t __n, const value_type& __val) 184 : { 185 : if (__n > capacity()) 186 : { 187 : vector __tmp(__n, __val, _M_get_Tp_allocator()); 188 : __tmp.swap(*this); 189 : } 190 : else if (__n > size()) 191 : { 192 : std::fill(begin(), end(), __val); 193 : std::__uninitialized_fill_n_a(this->_M_impl._M_finish, 194 : __n - size(), __val, 195 : _M_get_Tp_allocator()); 196 : this->_M_impl._M_finish += __n - size(); 197 : } 198 : else 199 : _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val)); 200 : } 201 : 202 : template<typename _Tp, typename _Alloc> 203 : template<typename _InputIterator> 204 : void 205 : vector<_Tp, _Alloc>:: 206 : _M_assign_aux(_InputIterator __first, _InputIterator __last, 207 : std::input_iterator_tag) 208 : { 209 : pointer __cur(this->_M_impl._M_start); 210 : for (; __first != __last && __cur != this->_M_impl._M_finish; 211 : ++__cur, ++__first) 212 : *__cur = *__first; 213 : if (__first == __last) 214 : _M_erase_at_end(__cur); 215 : else 216 : insert(end(), __first, __last); 217 : } 218 : 219 : template<typename _Tp, typename _Alloc> 220 : template<typename _ForwardIterator> 221 : void 222 : vector<_Tp, _Alloc>:: 223 : _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, 224 : std::forward_iterator_tag) 225 : { 226 : const size_type __len = std::distance(__first, __last); 227 : 228 : if (__len > capacity()) 229 : { 230 : pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); 231 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 232 : _M_get_Tp_allocator()); 233 : _M_deallocate(this->_M_impl._M_start, 234 : this->_M_impl._M_end_of_storage 235 : - this->_M_impl._M_start); 236 : this->_M_impl._M_start = __tmp; 237 : this->_M_impl._M_finish = this->_M_impl._M_start + __len; 238 : this->_M_impl._M_end_of_storage = this->_M_impl._M_finish; 239 : } 240 : else if (size() >= __len) 241 : _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start)); 242 : else 243 : { 244 : _ForwardIterator __mid = __first; 245 : std::advance(__mid, size()); 246 : std::copy(__first, __mid, this->_M_impl._M_start); 247 : this->_M_impl._M_finish = 248 : std::__uninitialized_copy_a(__mid, __last, 249 : this->_M_impl._M_finish, 250 : _M_get_Tp_allocator()); 251 : } 252 : } 253 : 254 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 255 : template<typename _Tp, typename _Alloc> 256 : template<typename... _Args> 257 : typename vector<_Tp, _Alloc>::iterator 258 : vector<_Tp, _Alloc>:: 259 : emplace(iterator __position, _Args&&... __args) 260 : { 261 : const size_type __n = __position - begin(); 262 : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage 263 : && __position == end()) 264 : { 265 : this->_M_impl.construct(this->_M_impl._M_finish, 266 : std::forward<_Args>(__args)...); 267 : ++this->_M_impl._M_finish; 268 : } 269 : else 270 : _M_insert_aux(__position, std::forward<_Args>(__args)...); 271 : return iterator(this->_M_impl._M_start + __n); 272 : } 273 : 274 : template<typename _Tp, typename _Alloc> 275 : template<typename... _Args> 276 : void 277 : vector<_Tp, _Alloc>:: 278 : _M_insert_aux(iterator __position, _Args&&... __args) 279 : #else 280 : template<typename _Tp, typename _Alloc> 281 : void 282 : vector<_Tp, _Alloc>:: 283 20651 : _M_insert_aux(iterator __position, const _Tp& __x) 284 : #endif 285 : { 286 20651 : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) 287 : { 288 0 : this->_M_impl.construct(this->_M_impl._M_finish, 289 : _GLIBCXX_MOVE(*(this->_M_impl._M_finish 290 : - 1))); 291 0 : ++this->_M_impl._M_finish; 292 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 293 0 : _Tp __x_copy = __x; 294 : #endif 295 0 : _GLIBCXX_MOVE_BACKWARD3(__position.base(), 296 : this->_M_impl._M_finish - 2, 297 : this->_M_impl._M_finish - 1); 298 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 299 0 : *__position = __x_copy; 300 : #else 301 : *__position = _Tp(std::forward<_Args>(__args)...); 302 : #endif 303 : } 304 : else 305 : { 306 : const size_type __len = 307 20651 : _M_check_len(size_type(1), "vector::_M_insert_aux"); 308 20651 : pointer __new_start(this->_M_allocate(__len)); 309 20651 : pointer __new_finish(__new_start); 310 : try 311 : { 312 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 313 : this->_M_impl.construct(__new_start + (__position - begin()), 314 : std::forward<_Args>(__args)...); 315 : #endif 316 20651 : __new_finish = 317 : std::__uninitialized_move_a(this->_M_impl._M_start, 318 : __position.base(), __new_start, 319 : _M_get_Tp_allocator()); 320 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 321 20651 : this->_M_impl.construct(__new_finish, __x); 322 : #endif 323 20651 : ++__new_finish; 324 20651 : __new_finish = 325 : std::__uninitialized_move_a(__position.base(), 326 : this->_M_impl._M_finish, 327 : __new_finish, 328 : _M_get_Tp_allocator()); 329 : } 330 0 : catch(...) 331 : { 332 0 : std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); 333 0 : _M_deallocate(__new_start, __len); 334 0 : __throw_exception_again; 335 : } 336 20651 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 337 : _M_get_Tp_allocator()); 338 20651 : _M_deallocate(this->_M_impl._M_start, 339 : this->_M_impl._M_end_of_storage 340 : - this->_M_impl._M_start); 341 20651 : this->_M_impl._M_start = __new_start; 342 20651 : this->_M_impl._M_finish = __new_finish; 343 20651 : this->_M_impl._M_end_of_storage = __new_start + __len; 344 : } 345 20651 : } 346 : 347 : template<typename _Tp, typename _Alloc> 348 : void 349 : vector<_Tp, _Alloc>:: 350 22443 : _M_fill_insert(iterator __position, size_type __n, const value_type& __x) 351 : { 352 22443 : if (__n != 0) 353 : { 354 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 355 : value_type __x_copy = __x; 356 : #endif 357 22443 : if (size_type(this->_M_impl._M_end_of_storage 358 : - this->_M_impl._M_finish) >= __n) 359 : { 360 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 361 22386 : value_type __x_copy = __x; 362 : #endif 363 22386 : const size_type __elems_after = end() - __position; 364 22386 : pointer __old_finish(this->_M_impl._M_finish); 365 22386 : if (__elems_after > __n) 366 : { 367 0 : std::__uninitialized_move_a(this->_M_impl._M_finish - __n, 368 : this->_M_impl._M_finish, 369 : this->_M_impl._M_finish, 370 : _M_get_Tp_allocator()); 371 0 : this->_M_impl._M_finish += __n; 372 0 : _GLIBCXX_MOVE_BACKWARD3(__position.base(), 373 : __old_finish - __n, __old_finish); 374 0 : std::fill(__position.base(), __position.base() + __n, 375 : __x_copy); 376 : } 377 : else 378 : { 379 22386 : std::__uninitialized_fill_n_a(this->_M_impl._M_finish, 380 : __n - __elems_after, 381 : __x_copy, 382 : _M_get_Tp_allocator()); 383 22386 : this->_M_impl._M_finish += __n - __elems_after; 384 22386 : std::__uninitialized_move_a(__position.base(), __old_finish, 385 : this->_M_impl._M_finish, 386 : _M_get_Tp_allocator()); 387 22386 : this->_M_impl._M_finish += __elems_after; 388 22386 : std::fill(__position.base(), __old_finish, __x_copy); 389 : } 390 : } 391 : else 392 : { 393 : const size_type __len = 394 57 : _M_check_len(__n, "vector::_M_fill_insert"); 395 57 : pointer __new_start(this->_M_allocate(__len)); 396 57 : pointer __new_finish(__new_start); 397 : try 398 : { 399 57 : __new_finish = 400 : std::__uninitialized_move_a(this->_M_impl._M_start, 401 : __position.base(), 402 : __new_start, 403 : _M_get_Tp_allocator()); 404 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 405 : std::__uninitialized_fill_n_a(__new_finish, __n, __x_copy, 406 : #else 407 57 : std::__uninitialized_fill_n_a(__new_finish, __n, __x, 408 : #endif 409 : _M_get_Tp_allocator()); 410 57 : __new_finish += __n; 411 57 : __new_finish = 412 : std::__uninitialized_move_a(__position.base(), 413 : this->_M_impl._M_finish, 414 : __new_finish, 415 : _M_get_Tp_allocator()); 416 : } 417 0 : catch(...) 418 : { 419 0 : std::_Destroy(__new_start, __new_finish, 420 : _M_get_Tp_allocator()); 421 0 : _M_deallocate(__new_start, __len); 422 0 : __throw_exception_again; 423 : } 424 57 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 425 : _M_get_Tp_allocator()); 426 57 : _M_deallocate(this->_M_impl._M_start, 427 : this->_M_impl._M_end_of_storage 428 : - this->_M_impl._M_start); 429 57 : this->_M_impl._M_start = __new_start; 430 57 : this->_M_impl._M_finish = __new_finish; 431 57 : this->_M_impl._M_end_of_storage = __new_start + __len; 432 : } 433 : } 434 22443 : } 435 : 436 : template<typename _Tp, typename _Alloc> 437 : template<typename _InputIterator> 438 : void 439 : vector<_Tp, _Alloc>:: 440 : _M_range_insert(iterator __pos, _InputIterator __first, 441 : _InputIterator __last, std::input_iterator_tag) 442 : { 443 : for (; __first != __last; ++__first) 444 : { 445 : __pos = insert(__pos, *__first); 446 : ++__pos; 447 : } 448 : } 449 : 450 : template<typename _Tp, typename _Alloc> 451 : template<typename _ForwardIterator> 452 : void 453 : vector<_Tp, _Alloc>:: 454 : _M_range_insert(iterator __position, _ForwardIterator __first, 455 : _ForwardIterator __last, std::forward_iterator_tag) 456 : { 457 : if (__first != __last) 458 : { 459 : const size_type __n = std::distance(__first, __last); 460 : if (size_type(this->_M_impl._M_end_of_storage 461 : - this->_M_impl._M_finish) >= __n) 462 : { 463 : const size_type __elems_after = end() - __position; 464 : pointer __old_finish(this->_M_impl._M_finish); 465 : if (__elems_after > __n) 466 : { 467 : std::__uninitialized_move_a(this->_M_impl._M_finish - __n, 468 : this->_M_impl._M_finish, 469 : this->_M_impl._M_finish, 470 : _M_get_Tp_allocator()); 471 : this->_M_impl._M_finish += __n; 472 : _GLIBCXX_MOVE_BACKWARD3(__position.base(), 473 : __old_finish - __n, __old_finish); 474 : std::copy(__first, __last, __position); 475 : } 476 : else 477 : { 478 : _ForwardIterator __mid = __first; 479 : std::advance(__mid, __elems_after); 480 : std::__uninitialized_copy_a(__mid, __last, 481 : this->_M_impl._M_finish, 482 : _M_get_Tp_allocator()); 483 : this->_M_impl._M_finish += __n - __elems_after; 484 : std::__uninitialized_move_a(__position.base(), 485 : __old_finish, 486 : this->_M_impl._M_finish, 487 : _M_get_Tp_allocator()); 488 : this->_M_impl._M_finish += __elems_after; 489 : std::copy(__first, __mid, __position); 490 : } 491 : } 492 : else 493 : { 494 : const size_type __len = 495 : _M_check_len(__n, "vector::_M_range_insert"); 496 : pointer __new_start(this->_M_allocate(__len)); 497 : pointer __new_finish(__new_start); 498 : try 499 : { 500 : __new_finish = 501 : std::__uninitialized_move_a(this->_M_impl._M_start, 502 : __position.base(), 503 : __new_start, 504 : _M_get_Tp_allocator()); 505 : __new_finish = 506 : std::__uninitialized_copy_a(__first, __last, 507 : __new_finish, 508 : _M_get_Tp_allocator()); 509 : __new_finish = 510 : std::__uninitialized_move_a(__position.base(), 511 : this->_M_impl._M_finish, 512 : __new_finish, 513 : _M_get_Tp_allocator()); 514 : } 515 : catch(...) 516 : { 517 : std::_Destroy(__new_start, __new_finish, 518 : _M_get_Tp_allocator()); 519 : _M_deallocate(__new_start, __len); 520 : __throw_exception_again; 521 : } 522 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 523 : _M_get_Tp_allocator()); 524 : _M_deallocate(this->_M_impl._M_start, 525 : this->_M_impl._M_end_of_storage 526 : - this->_M_impl._M_start); 527 : this->_M_impl._M_start = __new_start; 528 : this->_M_impl._M_finish = __new_finish; 529 : this->_M_impl._M_end_of_storage = __new_start + __len; 530 : } 531 : } 532 : } 533 : 534 : 535 : // vector<bool> 536 : 537 : template<typename _Alloc> 538 : void 539 : vector<bool, _Alloc>:: 540 : reserve(size_type __n) 541 : { 542 : if (__n > this->max_size()) 543 : __throw_length_error(__N("vector::reserve")); 544 : if (this->capacity() < __n) 545 : { 546 : _Bit_type* __q = this->_M_allocate(__n); 547 : this->_M_impl._M_finish = _M_copy_aligned(begin(), end(), 548 : iterator(__q, 0)); 549 : this->_M_deallocate(); 550 : this->_M_impl._M_start = iterator(__q, 0); 551 : this->_M_impl._M_end_of_storage = (__q + (__n + int(_S_word_bit) - 1) 552 : / int(_S_word_bit)); 553 : } 554 : } 555 : 556 : template<typename _Alloc> 557 : void 558 : vector<bool, _Alloc>:: 559 : _M_fill_insert(iterator __position, size_type __n, bool __x) 560 : { 561 : if (__n == 0) 562 : return; 563 : if (capacity() - size() >= __n) 564 : { 565 : std::copy_backward(__position, end(), 566 : this->_M_impl._M_finish + difference_type(__n)); 567 : std::fill(__position, __position + difference_type(__n), __x); 568 : this->_M_impl._M_finish += difference_type(__n); 569 : } 570 : else 571 : { 572 : const size_type __len = 573 : _M_check_len(__n, "vector<bool>::_M_fill_insert"); 574 : _Bit_type * __q = this->_M_allocate(__len); 575 : iterator __i = _M_copy_aligned(begin(), __position, 576 : iterator(__q, 0)); 577 : std::fill(__i, __i + difference_type(__n), __x); 578 : this->_M_impl._M_finish = std::copy(__position, end(), 579 : __i + difference_type(__n)); 580 : this->_M_deallocate(); 581 : this->_M_impl._M_end_of_storage = (__q + ((__len 582 : + int(_S_word_bit) - 1) 583 : / int(_S_word_bit))); 584 : this->_M_impl._M_start = iterator(__q, 0); 585 : } 586 : } 587 : 588 : template<typename _Alloc> 589 : template<typename _ForwardIterator> 590 : void 591 : vector<bool, _Alloc>:: 592 : _M_insert_range(iterator __position, _ForwardIterator __first, 593 : _ForwardIterator __last, std::forward_iterator_tag) 594 : { 595 : if (__first != __last) 596 : { 597 : size_type __n = std::distance(__first, __last); 598 : if (capacity() - size() >= __n) 599 : { 600 : std::copy_backward(__position, end(), 601 : this->_M_impl._M_finish 602 : + difference_type(__n)); 603 : std::copy(__first, __last, __position); 604 : this->_M_impl._M_finish += difference_type(__n); 605 : } 606 : else 607 : { 608 : const size_type __len = 609 : _M_check_len(__n, "vector<bool>::_M_insert_range"); 610 : _Bit_type * __q = this->_M_allocate(__len); 611 : iterator __i = _M_copy_aligned(begin(), __position, 612 : iterator(__q, 0)); 613 : __i = std::copy(__first, __last, __i); 614 : this->_M_impl._M_finish = std::copy(__position, end(), __i); 615 : this->_M_deallocate(); 616 : this->_M_impl._M_end_of_storage = (__q 617 : + ((__len 618 : + int(_S_word_bit) - 1) 619 : / int(_S_word_bit))); 620 : this->_M_impl._M_start = iterator(__q, 0); 621 : } 622 : } 623 : } 624 : 625 : template<typename _Alloc> 626 : void 627 : vector<bool, _Alloc>:: 628 1 : _M_insert_aux(iterator __position, bool __x) 629 : { 630 1 : if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) 631 : { 632 0 : std::copy_backward(__position, this->_M_impl._M_finish, 633 : this->_M_impl._M_finish + 1); 634 0 : *__position = __x; 635 0 : ++this->_M_impl._M_finish; 636 : } 637 : else 638 : { 639 : const size_type __len = 640 1 : _M_check_len(size_type(1), "vector<bool>::_M_insert_aux"); 641 1 : _Bit_type * __q = this->_M_allocate(__len); 642 : iterator __i = _M_copy_aligned(begin(), __position, 643 1 : iterator(__q, 0)); 644 1 : *__i++ = __x; 645 1 : this->_M_impl._M_finish = std::copy(__position, end(), __i); 646 1 : this->_M_deallocate(); 647 1 : this->_M_impl._M_end_of_storage = (__q + ((__len 648 : + int(_S_word_bit) - 1) 649 : / int(_S_word_bit))); 650 1 : this->_M_impl._M_start = iterator(__q, 0); 651 : } 652 1 : } 653 : 654 : _GLIBCXX_END_NESTED_NAMESPACE 655 : 656 : #endif /* _VECTOR_TCC */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Core algorithmic facilities -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996-1998 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_algobase.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_ALGOBASE_H 63 : #define _STL_ALGOBASE_H 1 64 : 65 : #include <bits/c++config.h> 66 : #include <cstddef> 67 : #include <bits/functexcept.h> 68 : #include <bits/cpp_type_traits.h> 69 : #include <ext/type_traits.h> 70 : #include <ext/numeric_traits.h> 71 : #include <bits/stl_pair.h> 72 : #include <bits/stl_iterator_base_types.h> 73 : #include <bits/stl_iterator_base_funcs.h> 74 : #include <bits/stl_iterator.h> 75 : #include <bits/concept_check.h> 76 : #include <debug/debug.h> 77 : #include <bits/stl_move.h> // For std::swap and _GLIBCXX_MOVE 78 : 79 : _GLIBCXX_BEGIN_NAMESPACE(std) 80 : 81 : // See http://gcc.gnu.org/ml/libstdc++/2004-08/msg00167.html: in a 82 : // nutshell, we are partially implementing the resolution of DR 187, 83 : // when it's safe, i.e., the value_types are equal. 84 : template<bool _BoolType> 85 : struct __iter_swap 86 : { 87 : template<typename _ForwardIterator1, typename _ForwardIterator2> 88 : static void 89 : iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) 90 : { 91 : typedef typename iterator_traits<_ForwardIterator1>::value_type 92 : _ValueType1; 93 : _ValueType1 __tmp = _GLIBCXX_MOVE(*__a); 94 : *__a = _GLIBCXX_MOVE(*__b); 95 : *__b = _GLIBCXX_MOVE(__tmp); 96 : } 97 : }; 98 : 99 : template<> 100 : struct __iter_swap<true> 101 : { 102 : template<typename _ForwardIterator1, typename _ForwardIterator2> 103 : static void 104 7080 : iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) 105 : { 106 7080 : swap(*__a, *__b); 107 7080 : } 108 : }; 109 : 110 : /** 111 : * @brief Swaps the contents of two iterators. 112 : * @param a An iterator. 113 : * @param b Another iterator. 114 : * @return Nothing. 115 : * 116 : * This function swaps the values pointed to by two iterators, not the 117 : * iterators themselves. 118 : */ 119 : template<typename _ForwardIterator1, typename _ForwardIterator2> 120 : inline void 121 7080 : iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) 122 : { 123 : typedef typename iterator_traits<_ForwardIterator1>::value_type 124 : _ValueType1; 125 : typedef typename iterator_traits<_ForwardIterator2>::value_type 126 : _ValueType2; 127 : 128 : // concept requirements 129 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 130 : _ForwardIterator1>) 131 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 132 : _ForwardIterator2>) 133 : __glibcxx_function_requires(_ConvertibleConcept<_ValueType1, 134 : _ValueType2>) 135 : __glibcxx_function_requires(_ConvertibleConcept<_ValueType2, 136 : _ValueType1>) 137 : 138 : typedef typename iterator_traits<_ForwardIterator1>::reference 139 : _ReferenceType1; 140 : typedef typename iterator_traits<_ForwardIterator2>::reference 141 : _ReferenceType2; 142 7080 : std::__iter_swap<__are_same<_ValueType1, _ValueType2>::__value 143 : && __are_same<_ValueType1&, _ReferenceType1>::__value 144 : && __are_same<_ValueType2&, _ReferenceType2>::__value>:: 145 : iter_swap(__a, __b); 146 7080 : } 147 : 148 : /** 149 : * @brief Swap the elements of two sequences. 150 : * @param first1 A forward iterator. 151 : * @param last1 A forward iterator. 152 : * @param first2 A forward iterator. 153 : * @return An iterator equal to @p first2+(last1-first1). 154 : * 155 : * Swaps each element in the range @p [first1,last1) with the 156 : * corresponding element in the range @p [first2,(last1-first1)). 157 : * The ranges must not overlap. 158 : */ 159 : template<typename _ForwardIterator1, typename _ForwardIterator2> 160 : _ForwardIterator2 161 : swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 162 : _ForwardIterator2 __first2) 163 : { 164 : // concept requirements 165 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 166 : _ForwardIterator1>) 167 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 168 : _ForwardIterator2>) 169 : __glibcxx_requires_valid_range(__first1, __last1); 170 : 171 : for (; __first1 != __last1; ++__first1, ++__first2) 172 : std::iter_swap(__first1, __first2); 173 : return __first2; 174 : } 175 : 176 : /** 177 : * @brief This does what you think it does. 178 : * @param a A thing of arbitrary type. 179 : * @param b Another thing of arbitrary type. 180 : * @return The lesser of the parameters. 181 : * 182 : * This is the simple classic generic implementation. It will work on 183 : * temporary expressions, since they are only evaluated once, unlike a 184 : * preprocessor macro. 185 : */ 186 : template<typename _Tp> 187 : inline const _Tp& 188 0 : min(const _Tp& __a, const _Tp& __b) 189 : { 190 : // concept requirements 191 : __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) 192 : //return __b < __a ? __b : __a; 193 0 : if (__b < __a) 194 0 : return __b; 195 0 : return __a; 196 : } 197 : 198 : /** 199 : * @brief This does what you think it does. 200 : * @param a A thing of arbitrary type. 201 : * @param b Another thing of arbitrary type. 202 : * @return The greater of the parameters. 203 : * 204 : * This is the simple classic generic implementation. It will work on 205 : * temporary expressions, since they are only evaluated once, unlike a 206 : * preprocessor macro. 207 : */ 208 : template<typename _Tp> 209 : inline const _Tp& 210 20743 : max(const _Tp& __a, const _Tp& __b) 211 : { 212 : // concept requirements 213 : __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) 214 : //return __a < __b ? __b : __a; 215 20743 : if (__a < __b) 216 4790 : return __b; 217 15953 : return __a; 218 : } 219 : 220 : /** 221 : * @brief This does what you think it does. 222 : * @param a A thing of arbitrary type. 223 : * @param b Another thing of arbitrary type. 224 : * @param comp A @link s20_3_3_comparisons comparison functor@endlink. 225 : * @return The lesser of the parameters. 226 : * 227 : * This will work on temporary expressions, since they are only evaluated 228 : * once, unlike a preprocessor macro. 229 : */ 230 : template<typename _Tp, typename _Compare> 231 : inline const _Tp& 232 : min(const _Tp& __a, const _Tp& __b, _Compare __comp) 233 : { 234 : //return __comp(__b, __a) ? __b : __a; 235 : if (__comp(__b, __a)) 236 : return __b; 237 : return __a; 238 : } 239 : 240 : /** 241 : * @brief This does what you think it does. 242 : * @param a A thing of arbitrary type. 243 : * @param b Another thing of arbitrary type. 244 : * @param comp A @link s20_3_3_comparisons comparison functor@endlink. 245 : * @return The greater of the parameters. 246 : * 247 : * This will work on temporary expressions, since they are only evaluated 248 : * once, unlike a preprocessor macro. 249 : */ 250 : template<typename _Tp, typename _Compare> 251 : inline const _Tp& 252 : max(const _Tp& __a, const _Tp& __b, _Compare __comp) 253 : { 254 : //return __comp(__a, __b) ? __b : __a; 255 : if (__comp(__a, __b)) 256 : return __b; 257 : return __a; 258 : } 259 : 260 : 261 : // If _Iterator is a __normal_iterator return its base (a plain pointer, 262 : // normally) otherwise return it untouched. See copy, fill, ... 263 : template<typename _Iterator, 264 : bool _IsNormal = __is_normal_iterator<_Iterator>::__value> 265 : struct __niter_base 266 : { 267 : static _Iterator 268 256058 : __b(_Iterator __it) 269 256058 : { return __it; } 270 : }; 271 : 272 : template<typename _Iterator> 273 : struct __niter_base<_Iterator, true> 274 : { 275 : static typename _Iterator::iterator_type 276 23362 : __b(_Iterator __it) 277 23362 : { return __it.base(); } 278 : }; 279 : 280 : // Likewise, for move_iterator. 281 : template<typename _Iterator, 282 : bool _IsMove = __is_move_iterator<_Iterator>::__value> 283 : struct __miter_base 284 : { 285 : static _Iterator 286 156418 : __b(_Iterator __it) 287 156418 : { return __it; } 288 : }; 289 : 290 : template<typename _Iterator> 291 : struct __miter_base<_Iterator, true> 292 : { 293 : static typename _Iterator::iterator_type 294 : __b(_Iterator __it) 295 : { return __it.base(); } 296 : }; 297 : 298 : // All of these auxiliary structs serve two purposes. (1) Replace 299 : // calls to copy with memmove whenever possible. (Memmove, not memcpy, 300 : // because the input and output ranges are permitted to overlap.) 301 : // (2) If we're using random access iterators, then write the loop as 302 : // a for loop with an explicit count. 303 : 304 : template<bool, bool, typename> 305 : struct __copy_move 306 : { 307 : template<typename _II, typename _OI> 308 : static _OI 309 42335 : __copy_m(_II __first, _II __last, _OI __result) 310 : { 311 159330 : for (; __first != __last; ++__result, ++__first) 312 112959 : *__result = *__first; 313 42335 : return __result; 314 : } 315 : }; 316 : 317 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 318 : template<typename _Category> 319 : struct __copy_move<true, false, _Category> 320 : { 321 : template<typename _II, typename _OI> 322 : static _OI 323 : __copy_m(_II __first, _II __last, _OI __result) 324 : { 325 : for (; __first != __last; ++__result, ++__first) 326 : *__result = std::move(*__first); 327 : return __result; 328 : } 329 : }; 330 : #endif 331 : 332 : template<> 333 : struct __copy_move<false, false, random_access_iterator_tag> 334 : { 335 : template<typename _II, typename _OI> 336 : static _OI 337 945 : __copy_m(_II __first, _II __last, _OI __result) 338 : { 339 : typedef typename iterator_traits<_II>::difference_type _Distance; 340 12957 : for(_Distance __n = __last - __first; __n > 0; --__n) 341 : { 342 12012 : *__result = *__first; 343 12012 : ++__first; 344 12012 : ++__result; 345 : } 346 945 : return __result; 347 : } 348 : }; 349 : 350 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 351 : template<> 352 : struct __copy_move<true, false, random_access_iterator_tag> 353 : { 354 : template<typename _II, typename _OI> 355 : static _OI 356 : __copy_m(_II __first, _II __last, _OI __result) 357 : { 358 : typedef typename iterator_traits<_II>::difference_type _Distance; 359 : for(_Distance __n = __last - __first; __n > 0; --__n) 360 : { 361 : *__result = std::move(*__first); 362 : ++__first; 363 : ++__result; 364 : } 365 : return __result; 366 : } 367 : }; 368 : #endif 369 : 370 : template<bool _IsMove> 371 : struct __copy_move<_IsMove, true, random_access_iterator_tag> 372 : { 373 : template<typename _Tp> 374 : static _Tp* 375 27153 : __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result) 376 : { 377 27153 : __builtin_memmove(__result, __first, 378 : sizeof(_Tp) * (__last - __first)); 379 27153 : return __result + (__last - __first); 380 : } 381 : }; 382 : 383 : template<bool _IsMove, typename _II, typename _OI> 384 : inline _OI 385 70433 : __copy_move_a(_II __first, _II __last, _OI __result) 386 : { 387 : typedef typename iterator_traits<_II>::value_type _ValueTypeI; 388 : typedef typename iterator_traits<_OI>::value_type _ValueTypeO; 389 : typedef typename iterator_traits<_II>::iterator_category _Category; 390 : const bool __simple = (__is_pod(_ValueTypeI) 391 : && __is_pointer<_II>::__value 392 : && __is_pointer<_OI>::__value 393 70433 : && __are_same<_ValueTypeI, _ValueTypeO>::__value); 394 : 395 : return std::__copy_move<_IsMove, __simple, 396 70433 : _Category>::__copy_m(__first, __last, __result); 397 : } 398 : 399 : // Helpers for streambuf iterators (either istream or ostream). 400 : // NB: avoid including <iosfwd>, relatively large. 401 : template<typename _CharT> 402 : struct char_traits; 403 : 404 : template<typename _CharT, typename _Traits> 405 : class istreambuf_iterator; 406 : 407 : template<typename _CharT, typename _Traits> 408 : class ostreambuf_iterator; 409 : 410 : template<bool _IsMove, typename _CharT> 411 : typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 412 : ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type 413 : __copy_move_a2(_CharT*, _CharT*, 414 : ostreambuf_iterator<_CharT, char_traits<_CharT> >); 415 : 416 : template<bool _IsMove, typename _CharT> 417 : typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 418 : ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type 419 : __copy_move_a2(const _CharT*, const _CharT*, 420 : ostreambuf_iterator<_CharT, char_traits<_CharT> >); 421 : 422 : template<bool _IsMove, typename _CharT> 423 : typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 424 : _CharT*>::__type 425 : __copy_move_a2(istreambuf_iterator<_CharT, char_traits<_CharT> >, 426 : istreambuf_iterator<_CharT, char_traits<_CharT> >, _CharT*); 427 : 428 : template<bool _IsMove, typename _II, typename _OI> 429 : inline _OI 430 70433 : __copy_move_a2(_II __first, _II __last, _OI __result) 431 : { 432 : return _OI(std::__copy_move_a<_IsMove> 433 : (std::__niter_base<_II>::__b(__first), 434 : std::__niter_base<_II>::__b(__last), 435 70433 : std::__niter_base<_OI>::__b(__result))); 436 : } 437 : 438 : /** 439 : * @brief Copies the range [first,last) into result. 440 : * @param first An input iterator. 441 : * @param last An input iterator. 442 : * @param result An output iterator. 443 : * @return result + (first - last) 444 : * 445 : * This inline function will boil down to a call to @c memmove whenever 446 : * possible. Failing that, if random access iterators are passed, then the 447 : * loop count will be known (and therefore a candidate for compiler 448 : * optimizations such as unrolling). Result may not be contained within 449 : * [first,last); the copy_backward function should be used instead. 450 : * 451 : * Note that the end of the output range is permitted to be contained 452 : * within [first,last). 453 : */ 454 : template<typename _II, typename _OI> 455 : inline _OI 456 70433 : copy(_II __first, _II __last, _OI __result) 457 : { 458 : // concept requirements 459 : __glibcxx_function_requires(_InputIteratorConcept<_II>) 460 : __glibcxx_function_requires(_OutputIteratorConcept<_OI, 461 : typename iterator_traits<_II>::value_type>) 462 : __glibcxx_requires_valid_range(__first, __last); 463 : 464 : return (std::__copy_move_a2<__is_move_iterator<_II>::__value> 465 : (std::__miter_base<_II>::__b(__first), 466 70433 : std::__miter_base<_II>::__b(__last), __result)); 467 : } 468 : 469 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 470 : /** 471 : * @brief Moves the range [first,last) into result. 472 : * @param first An input iterator. 473 : * @param last An input iterator. 474 : * @param result An output iterator. 475 : * @return result + (first - last) 476 : * 477 : * This inline function will boil down to a call to @c memmove whenever 478 : * possible. Failing that, if random access iterators are passed, then the 479 : * loop count will be known (and therefore a candidate for compiler 480 : * optimizations such as unrolling). Result may not be contained within 481 : * [first,last); the move_backward function should be used instead. 482 : * 483 : * Note that the end of the output range is permitted to be contained 484 : * within [first,last). 485 : */ 486 : template<typename _II, typename _OI> 487 : inline _OI 488 : move(_II __first, _II __last, _OI __result) 489 : { 490 : // concept requirements 491 : __glibcxx_function_requires(_InputIteratorConcept<_II>) 492 : __glibcxx_function_requires(_OutputIteratorConcept<_OI, 493 : typename iterator_traits<_II>::value_type>) 494 : __glibcxx_requires_valid_range(__first, __last); 495 : 496 : return (std::__copy_move_a2<true> 497 : (std::__miter_base<_II>::__b(__first), 498 : std::__miter_base<_II>::__b(__last), __result)); 499 : } 500 : 501 : #define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::move(_Tp, _Up, _Vp) 502 : #else 503 : #define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::copy(_Tp, _Up, _Vp) 504 : #endif 505 : 506 : template<bool, bool, typename> 507 : struct __copy_move_backward 508 : { 509 : template<typename _BI1, typename _BI2> 510 : static _BI2 511 : __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) 512 : { 513 : while (__first != __last) 514 : *--__result = *--__last; 515 : return __result; 516 : } 517 : }; 518 : 519 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 520 : template<typename _Category> 521 : struct __copy_move_backward<true, false, _Category> 522 : { 523 : template<typename _BI1, typename _BI2> 524 : static _BI2 525 : __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) 526 : { 527 : while (__first != __last) 528 : *--__result = std::move(*--__last); 529 : return __result; 530 : } 531 : }; 532 : #endif 533 : 534 : template<> 535 : struct __copy_move_backward<false, false, random_access_iterator_tag> 536 : { 537 : template<typename _BI1, typename _BI2> 538 : static _BI2 539 150 : __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) 540 : { 541 : typename iterator_traits<_BI1>::difference_type __n; 542 524 : for (__n = __last - __first; __n > 0; --__n) 543 374 : *--__result = *--__last; 544 150 : return __result; 545 : } 546 : }; 547 : 548 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 549 : template<> 550 : struct __copy_move_backward<true, false, random_access_iterator_tag> 551 : { 552 : template<typename _BI1, typename _BI2> 553 : static _BI2 554 : __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) 555 : { 556 : typename iterator_traits<_BI1>::difference_type __n; 557 : for (__n = __last - __first; __n > 0; --__n) 558 : *--__result = std::move(*--__last); 559 : return __result; 560 : } 561 : }; 562 : #endif 563 : 564 : template<bool _IsMove> 565 : struct __copy_move_backward<_IsMove, true, random_access_iterator_tag> 566 : { 567 : template<typename _Tp> 568 : static _Tp* 569 7626 : __copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result) 570 : { 571 7626 : const ptrdiff_t _Num = __last - __first; 572 7626 : __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num); 573 7626 : return __result - _Num; 574 : } 575 : }; 576 : 577 : template<bool _IsMove, typename _BI1, typename _BI2> 578 : inline _BI2 579 7776 : __copy_move_backward_a(_BI1 __first, _BI1 __last, _BI2 __result) 580 : { 581 : typedef typename iterator_traits<_BI1>::value_type _ValueType1; 582 : typedef typename iterator_traits<_BI2>::value_type _ValueType2; 583 : typedef typename iterator_traits<_BI1>::iterator_category _Category; 584 : const bool __simple = (__is_pod(_ValueType1) 585 : && __is_pointer<_BI1>::__value 586 : && __is_pointer<_BI2>::__value 587 7776 : && __are_same<_ValueType1, _ValueType2>::__value); 588 : 589 : return std::__copy_move_backward<_IsMove, __simple, 590 : _Category>::__copy_move_b(__first, 591 : __last, 592 7776 : __result); 593 : } 594 : 595 : template<bool _IsMove, typename _BI1, typename _BI2> 596 : inline _BI2 597 7776 : __copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result) 598 : { 599 : return _BI2(std::__copy_move_backward_a<_IsMove> 600 : (std::__niter_base<_BI1>::__b(__first), 601 : std::__niter_base<_BI1>::__b(__last), 602 7776 : std::__niter_base<_BI2>::__b(__result))); 603 : } 604 : 605 : /** 606 : * @brief Copies the range [first,last) into result. 607 : * @param first A bidirectional iterator. 608 : * @param last A bidirectional iterator. 609 : * @param result A bidirectional iterator. 610 : * @return result - (first - last) 611 : * 612 : * The function has the same effect as copy, but starts at the end of the 613 : * range and works its way to the start, returning the start of the result. 614 : * This inline function will boil down to a call to @c memmove whenever 615 : * possible. Failing that, if random access iterators are passed, then the 616 : * loop count will be known (and therefore a candidate for compiler 617 : * optimizations such as unrolling). 618 : * 619 : * Result may not be in the range [first,last). Use copy instead. Note 620 : * that the start of the output range may overlap [first,last). 621 : */ 622 : template<typename _BI1, typename _BI2> 623 : inline _BI2 624 7776 : copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) 625 : { 626 : // concept requirements 627 : __glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>) 628 : __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>) 629 : __glibcxx_function_requires(_ConvertibleConcept< 630 : typename iterator_traits<_BI1>::value_type, 631 : typename iterator_traits<_BI2>::value_type>) 632 : __glibcxx_requires_valid_range(__first, __last); 633 : 634 : return (std::__copy_move_backward_a2<__is_move_iterator<_BI1>::__value> 635 : (std::__miter_base<_BI1>::__b(__first), 636 7776 : std::__miter_base<_BI1>::__b(__last), __result)); 637 : } 638 : 639 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 640 : /** 641 : * @brief Moves the range [first,last) into result. 642 : * @param first A bidirectional iterator. 643 : * @param last A bidirectional iterator. 644 : * @param result A bidirectional iterator. 645 : * @return result - (first - last) 646 : * 647 : * The function has the same effect as move, but starts at the end of the 648 : * range and works its way to the start, returning the start of the result. 649 : * This inline function will boil down to a call to @c memmove whenever 650 : * possible. Failing that, if random access iterators are passed, then the 651 : * loop count will be known (and therefore a candidate for compiler 652 : * optimizations such as unrolling). 653 : * 654 : * Result may not be in the range [first,last). Use move instead. Note 655 : * that the start of the output range may overlap [first,last). 656 : */ 657 : template<typename _BI1, typename _BI2> 658 : inline _BI2 659 : move_backward(_BI1 __first, _BI1 __last, _BI2 __result) 660 : { 661 : // concept requirements 662 : __glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>) 663 : __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>) 664 : __glibcxx_function_requires(_ConvertibleConcept< 665 : typename iterator_traits<_BI1>::value_type, 666 : typename iterator_traits<_BI2>::value_type>) 667 : __glibcxx_requires_valid_range(__first, __last); 668 : 669 : return (std::__copy_move_backward_a2<true> 670 : (std::__miter_base<_BI1>::__b(__first), 671 : std::__miter_base<_BI1>::__b(__last), __result)); 672 : } 673 : 674 : #define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::move_backward(_Tp, _Up, _Vp) 675 : #else 676 : #define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::copy_backward(_Tp, _Up, _Vp) 677 : #endif 678 : 679 : template<typename _ForwardIterator, typename _Tp> 680 : inline typename 681 : __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, void>::__type 682 : __fill_a(_ForwardIterator __first, _ForwardIterator __last, 683 22386 : const _Tp& __value) 684 : { 685 22386 : for (; __first != __last; ++__first) 686 0 : *__first = __value; 687 22386 : } 688 : 689 : template<typename _ForwardIterator, typename _Tp> 690 : inline typename 691 : __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, void>::__type 692 : __fill_a(_ForwardIterator __first, _ForwardIterator __last, 693 : const _Tp& __value) 694 : { 695 : const _Tp __tmp = __value; 696 : for (; __first != __last; ++__first) 697 : *__first = __tmp; 698 : } 699 : 700 : // Specialization: for char types we can use memset. 701 : template<typename _Tp> 702 : inline typename 703 : __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, void>::__type 704 : __fill_a(_Tp* __first, _Tp* __last, const _Tp& __c) 705 : { 706 : const _Tp __tmp = __c; 707 : __builtin_memset(__first, static_cast<unsigned char>(__tmp), 708 : __last - __first); 709 : } 710 : 711 : /** 712 : * @brief Fills the range [first,last) with copies of value. 713 : * @param first A forward iterator. 714 : * @param last A forward iterator. 715 : * @param value A reference-to-const of arbitrary type. 716 : * @return Nothing. 717 : * 718 : * This function fills a range with copies of the same value. For char 719 : * types filling contiguous areas of memory, this becomes an inline call 720 : * to @c memset or @c wmemset. 721 : */ 722 : template<typename _ForwardIterator, typename _Tp> 723 : inline void 724 22386 : fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) 725 : { 726 : // concept requirements 727 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 728 : _ForwardIterator>) 729 : __glibcxx_requires_valid_range(__first, __last); 730 : 731 22386 : std::__fill_a(std::__niter_base<_ForwardIterator>::__b(__first), 732 : std::__niter_base<_ForwardIterator>::__b(__last), __value); 733 22386 : } 734 : 735 : template<typename _OutputIterator, typename _Size, typename _Tp> 736 : inline typename 737 : __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, _OutputIterator>::__type 738 : __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value) 739 : { 740 : for (; __n > 0; --__n, ++__first) 741 : *__first = __value; 742 : return __first; 743 : } 744 : 745 : template<typename _OutputIterator, typename _Size, typename _Tp> 746 : inline typename 747 : __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, _OutputIterator>::__type 748 9 : __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value) 749 : { 750 9 : const _Tp __tmp = __value; 751 9 : for (; __n > 0; --__n, ++__first) 752 0 : *__first = __tmp; 753 9 : return __first; 754 : } 755 : 756 : template<typename _Size, typename _Tp> 757 : inline typename 758 : __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, _Tp*>::__type 759 : __fill_n_a(_Tp* __first, _Size __n, const _Tp& __c) 760 : { 761 : std::__fill_a(__first, __first + __n, __c); 762 : return __first + __n; 763 : } 764 : 765 : /** 766 : * @brief Fills the range [first,first+n) with copies of value. 767 : * @param first An output iterator. 768 : * @param n The count of copies to perform. 769 : * @param value A reference-to-const of arbitrary type. 770 : * @return The iterator at first+n. 771 : * 772 : * This function fills a range with copies of the same value. For char 773 : * types filling contiguous areas of memory, this becomes an inline call 774 : * to @c memset or @ wmemset. 775 : */ 776 : template<typename _OI, typename _Size, typename _Tp> 777 : inline _OI 778 9 : fill_n(_OI __first, _Size __n, const _Tp& __value) 779 : { 780 : // concept requirements 781 : __glibcxx_function_requires(_OutputIteratorConcept<_OI, _Tp>) 782 : 783 : return _OI(std::__fill_n_a(std::__niter_base<_OI>::__b(__first), 784 9 : __n, __value)); 785 : } 786 : 787 : template<bool _BoolType> 788 : struct __equal 789 : { 790 : template<typename _II1, typename _II2> 791 : static bool 792 4 : equal(_II1 __first1, _II1 __last1, _II2 __first2) 793 : { 794 51 : for (; __first1 != __last1; ++__first1, ++__first2) 795 47 : if (!(*__first1 == *__first2)) 796 0 : return false; 797 4 : return true; 798 : } 799 : }; 800 : 801 : template<> 802 : struct __equal<true> 803 : { 804 : template<typename _Tp> 805 : static bool 806 : equal(const _Tp* __first1, const _Tp* __last1, const _Tp* __first2) 807 : { 808 : return !__builtin_memcmp(__first1, __first2, sizeof(_Tp) 809 : * (__last1 - __first1)); 810 : } 811 : }; 812 : 813 : template<typename _II1, typename _II2> 814 : inline bool 815 4 : __equal_aux(_II1 __first1, _II1 __last1, _II2 __first2) 816 : { 817 : typedef typename iterator_traits<_II1>::value_type _ValueType1; 818 : typedef typename iterator_traits<_II2>::value_type _ValueType2; 819 : const bool __simple = (__is_integer<_ValueType1>::__value 820 : && __is_pointer<_II1>::__value 821 : && __is_pointer<_II2>::__value 822 4 : && __are_same<_ValueType1, _ValueType2>::__value); 823 : 824 4 : return std::__equal<__simple>::equal(__first1, __last1, __first2); 825 : } 826 : 827 : 828 : template<typename, typename> 829 : struct __lc_rai 830 : { 831 : template<typename _II1, typename _II2> 832 : static _II1 833 : __newlast1(_II1, _II1 __last1, _II2, _II2) 834 : { return __last1; } 835 : 836 : template<typename _II> 837 : static bool 838 : __cnd2(_II __first, _II __last) 839 : { return __first != __last; } 840 : }; 841 : 842 : template<> 843 : struct __lc_rai<random_access_iterator_tag, random_access_iterator_tag> 844 : { 845 : template<typename _RAI1, typename _RAI2> 846 : static _RAI1 847 : __newlast1(_RAI1 __first1, _RAI1 __last1, 848 : _RAI2 __first2, _RAI2 __last2) 849 : { 850 : const typename iterator_traits<_RAI1>::difference_type 851 : __diff1 = __last1 - __first1; 852 : const typename iterator_traits<_RAI2>::difference_type 853 : __diff2 = __last2 - __first2; 854 : return __diff2 < __diff1 ? __first1 + __diff2 : __last1; 855 : } 856 : 857 : template<typename _RAI> 858 : static bool 859 : __cnd2(_RAI, _RAI) 860 : { return true; } 861 : }; 862 : 863 : template<bool _BoolType> 864 : struct __lexicographical_compare 865 : { 866 : template<typename _II1, typename _II2> 867 : static bool __lc(_II1, _II1, _II2, _II2); 868 : }; 869 : 870 : template<bool _BoolType> 871 : template<typename _II1, typename _II2> 872 : bool 873 : __lexicographical_compare<_BoolType>:: 874 : __lc(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) 875 : { 876 : typedef typename iterator_traits<_II1>::iterator_category _Category1; 877 : typedef typename iterator_traits<_II2>::iterator_category _Category2; 878 : typedef std::__lc_rai<_Category1, _Category2> __rai_type; 879 : 880 : __last1 = __rai_type::__newlast1(__first1, __last1, 881 : __first2, __last2); 882 : for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2); 883 : ++__first1, ++__first2) 884 : { 885 : if (*__first1 < *__first2) 886 : return true; 887 : if (*__first2 < *__first1) 888 : return false; 889 : } 890 : return __first1 == __last1 && __first2 != __last2; 891 : } 892 : 893 : template<> 894 : struct __lexicographical_compare<true> 895 : { 896 : template<typename _Tp, typename _Up> 897 : static bool 898 : __lc(const _Tp* __first1, const _Tp* __last1, 899 : const _Up* __first2, const _Up* __last2) 900 : { 901 : const size_t __len1 = __last1 - __first1; 902 : const size_t __len2 = __last2 - __first2; 903 : const int __result = __builtin_memcmp(__first1, __first2, 904 : std::min(__len1, __len2)); 905 : return __result != 0 ? __result < 0 : __len1 < __len2; 906 : } 907 : }; 908 : 909 : template<typename _II1, typename _II2> 910 : inline bool 911 : __lexicographical_compare_aux(_II1 __first1, _II1 __last1, 912 : _II2 __first2, _II2 __last2) 913 : { 914 : typedef typename iterator_traits<_II1>::value_type _ValueType1; 915 : typedef typename iterator_traits<_II2>::value_type _ValueType2; 916 : const bool __simple = 917 : (__is_byte<_ValueType1>::__value && __is_byte<_ValueType2>::__value 918 : && !__gnu_cxx::__numeric_traits<_ValueType1>::__is_signed 919 : && !__gnu_cxx::__numeric_traits<_ValueType2>::__is_signed 920 : && __is_pointer<_II1>::__value 921 : && __is_pointer<_II2>::__value); 922 : 923 : return std::__lexicographical_compare<__simple>::__lc(__first1, __last1, 924 : __first2, __last2); 925 : } 926 : 927 : _GLIBCXX_END_NAMESPACE 928 : 929 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P) 930 : 931 : /** 932 : * @brief Tests a range for element-wise equality. 933 : * @param first1 An input iterator. 934 : * @param last1 An input iterator. 935 : * @param first2 An input iterator. 936 : * @return A boolean true or false. 937 : * 938 : * This compares the elements of two ranges using @c == and returns true or 939 : * false depending on whether all of the corresponding elements of the 940 : * ranges are equal. 941 : */ 942 : template<typename _II1, typename _II2> 943 : inline bool 944 4 : equal(_II1 __first1, _II1 __last1, _II2 __first2) 945 : { 946 : // concept requirements 947 : __glibcxx_function_requires(_InputIteratorConcept<_II1>) 948 : __glibcxx_function_requires(_InputIteratorConcept<_II2>) 949 : __glibcxx_function_requires(_EqualOpConcept< 950 : typename iterator_traits<_II1>::value_type, 951 : typename iterator_traits<_II2>::value_type>) 952 : __glibcxx_requires_valid_range(__first1, __last1); 953 : 954 : return std::__equal_aux(std::__niter_base<_II1>::__b(__first1), 955 : std::__niter_base<_II1>::__b(__last1), 956 4 : std::__niter_base<_II2>::__b(__first2)); 957 : } 958 : 959 : /** 960 : * @brief Tests a range for element-wise equality. 961 : * @param first1 An input iterator. 962 : * @param last1 An input iterator. 963 : * @param first2 An input iterator. 964 : * @param binary_pred A binary predicate @link s20_3_1_base 965 : * functor@endlink. 966 : * @return A boolean true or false. 967 : * 968 : * This compares the elements of two ranges using the binary_pred 969 : * parameter, and returns true or 970 : * false depending on whether all of the corresponding elements of the 971 : * ranges are equal. 972 : */ 973 : template<typename _IIter1, typename _IIter2, typename _BinaryPredicate> 974 : inline bool 975 : equal(_IIter1 __first1, _IIter1 __last1, 976 : _IIter2 __first2, _BinaryPredicate __binary_pred) 977 : { 978 : // concept requirements 979 : __glibcxx_function_requires(_InputIteratorConcept<_IIter1>) 980 : __glibcxx_function_requires(_InputIteratorConcept<_IIter2>) 981 : __glibcxx_requires_valid_range(__first1, __last1); 982 : 983 : for (; __first1 != __last1; ++__first1, ++__first2) 984 : if (!bool(__binary_pred(*__first1, *__first2))) 985 : return false; 986 : return true; 987 : } 988 : 989 : /** 990 : * @brief Performs "dictionary" comparison on ranges. 991 : * @param first1 An input iterator. 992 : * @param last1 An input iterator. 993 : * @param first2 An input iterator. 994 : * @param last2 An input iterator. 995 : * @return A boolean true or false. 996 : * 997 : * "Returns true if the sequence of elements defined by the range 998 : * [first1,last1) is lexicographically less than the sequence of elements 999 : * defined by the range [first2,last2). Returns false otherwise." 1000 : * (Quoted from [25.3.8]/1.) If the iterators are all character pointers, 1001 : * then this is an inline call to @c memcmp. 1002 : */ 1003 : template<typename _II1, typename _II2> 1004 : inline bool 1005 : lexicographical_compare(_II1 __first1, _II1 __last1, 1006 : _II2 __first2, _II2 __last2) 1007 : { 1008 : // concept requirements 1009 : typedef typename iterator_traits<_II1>::value_type _ValueType1; 1010 : typedef typename iterator_traits<_II2>::value_type _ValueType2; 1011 : __glibcxx_function_requires(_InputIteratorConcept<_II1>) 1012 : __glibcxx_function_requires(_InputIteratorConcept<_II2>) 1013 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) 1014 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 1015 : __glibcxx_requires_valid_range(__first1, __last1); 1016 : __glibcxx_requires_valid_range(__first2, __last2); 1017 : 1018 : return std::__lexicographical_compare_aux 1019 : (std::__niter_base<_II1>::__b(__first1), 1020 : std::__niter_base<_II1>::__b(__last1), 1021 : std::__niter_base<_II2>::__b(__first2), 1022 : std::__niter_base<_II2>::__b(__last2)); 1023 : } 1024 : 1025 : /** 1026 : * @brief Performs "dictionary" comparison on ranges. 1027 : * @param first1 An input iterator. 1028 : * @param last1 An input iterator. 1029 : * @param first2 An input iterator. 1030 : * @param last2 An input iterator. 1031 : * @param comp A @link s20_3_3_comparisons comparison functor@endlink. 1032 : * @return A boolean true or false. 1033 : * 1034 : * The same as the four-parameter @c lexicographical_compare, but uses the 1035 : * comp parameter instead of @c <. 1036 : */ 1037 : template<typename _II1, typename _II2, typename _Compare> 1038 : bool 1039 : lexicographical_compare(_II1 __first1, _II1 __last1, 1040 : _II2 __first2, _II2 __last2, _Compare __comp) 1041 : { 1042 : typedef typename iterator_traits<_II1>::iterator_category _Category1; 1043 : typedef typename iterator_traits<_II2>::iterator_category _Category2; 1044 : typedef std::__lc_rai<_Category1, _Category2> __rai_type; 1045 : 1046 : // concept requirements 1047 : __glibcxx_function_requires(_InputIteratorConcept<_II1>) 1048 : __glibcxx_function_requires(_InputIteratorConcept<_II2>) 1049 : __glibcxx_requires_valid_range(__first1, __last1); 1050 : __glibcxx_requires_valid_range(__first2, __last2); 1051 : 1052 : __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2); 1053 : for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2); 1054 : ++__first1, ++__first2) 1055 : { 1056 : if (__comp(*__first1, *__first2)) 1057 : return true; 1058 : if (__comp(*__first2, *__first1)) 1059 : return false; 1060 : } 1061 : return __first1 == __last1 && __first2 != __last2; 1062 : } 1063 : 1064 : /** 1065 : * @brief Finds the places in ranges which don't match. 1066 : * @param first1 An input iterator. 1067 : * @param last1 An input iterator. 1068 : * @param first2 An input iterator. 1069 : * @return A pair of iterators pointing to the first mismatch. 1070 : * 1071 : * This compares the elements of two ranges using @c == and returns a pair 1072 : * of iterators. The first iterator points into the first range, the 1073 : * second iterator points into the second range, and the elements pointed 1074 : * to by the iterators are not equal. 1075 : */ 1076 : template<typename _InputIterator1, typename _InputIterator2> 1077 : pair<_InputIterator1, _InputIterator2> 1078 : mismatch(_InputIterator1 __first1, _InputIterator1 __last1, 1079 : _InputIterator2 __first2) 1080 : { 1081 : // concept requirements 1082 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 1083 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 1084 : __glibcxx_function_requires(_EqualOpConcept< 1085 : typename iterator_traits<_InputIterator1>::value_type, 1086 : typename iterator_traits<_InputIterator2>::value_type>) 1087 : __glibcxx_requires_valid_range(__first1, __last1); 1088 : 1089 : while (__first1 != __last1 && *__first1 == *__first2) 1090 : { 1091 : ++__first1; 1092 : ++__first2; 1093 : } 1094 : return pair<_InputIterator1, _InputIterator2>(__first1, __first2); 1095 : } 1096 : 1097 : /** 1098 : * @brief Finds the places in ranges which don't match. 1099 : * @param first1 An input iterator. 1100 : * @param last1 An input iterator. 1101 : * @param first2 An input iterator. 1102 : * @param binary_pred A binary predicate @link s20_3_1_base 1103 : * functor@endlink. 1104 : * @return A pair of iterators pointing to the first mismatch. 1105 : * 1106 : * This compares the elements of two ranges using the binary_pred 1107 : * parameter, and returns a pair 1108 : * of iterators. The first iterator points into the first range, the 1109 : * second iterator points into the second range, and the elements pointed 1110 : * to by the iterators are not equal. 1111 : */ 1112 : template<typename _InputIterator1, typename _InputIterator2, 1113 : typename _BinaryPredicate> 1114 : pair<_InputIterator1, _InputIterator2> 1115 : mismatch(_InputIterator1 __first1, _InputIterator1 __last1, 1116 : _InputIterator2 __first2, _BinaryPredicate __binary_pred) 1117 : { 1118 : // concept requirements 1119 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 1120 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 1121 : __glibcxx_requires_valid_range(__first1, __last1); 1122 : 1123 : while (__first1 != __last1 && bool(__binary_pred(*__first1, *__first2))) 1124 : { 1125 : ++__first1; 1126 : ++__first2; 1127 : } 1128 : return pair<_InputIterator1, _InputIterator2>(__first1, __first2); 1129 : } 1130 : 1131 : _GLIBCXX_END_NESTED_NAMESPACE 1132 : 1133 : // NB: This file is included within many other C++ includes, as a way 1134 : // of getting the base algorithms. So, make sure that parallel bits 1135 : // come in too if requested. 1136 : #ifdef _GLIBCXX_PARALLEL 1137 : # include <parallel/algobase.h> 1138 : #endif 1139 : 1140 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Set implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996,1997 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_set.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_SET_H 63 : #define _STL_SET_H 1 64 : 65 : #include <bits/concept_check.h> 66 : 67 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) 68 : 69 : /** 70 : * @brief A standard container made up of unique keys, which can be 71 : * retrieved in logarithmic time. 72 : * 73 : * @ingroup Containers 74 : * @ingroup Assoc_containers 75 : * 76 : * Meets the requirements of a <a href="tables.html#65">container</a>, a 77 : * <a href="tables.html#66">reversible container</a>, and an 78 : * <a href="tables.html#69">associative container</a> (using unique keys). 79 : * 80 : * Sets support bidirectional iterators. 81 : * 82 : * @param Key Type of key objects. 83 : * @param Compare Comparison function object type, defaults to less<Key>. 84 : * @param Alloc Allocator type, defaults to allocator<Key>. 85 : * 86 : * The private tree data is declared exactly the same way for set and 87 : * multiset; the distinction is made entirely in how the tree functions are 88 : * called (*_unique versus *_equal, same as the standard). 89 : */ 90 : template<typename _Key, typename _Compare = std::less<_Key>, 91 : typename _Alloc = std::allocator<_Key> > 92 : class set 93 1308625 : { 94 : // concept requirements 95 : typedef typename _Alloc::value_type _Alloc_value_type; 96 : __glibcxx_class_requires(_Key, _SGIAssignableConcept) 97 : __glibcxx_class_requires4(_Compare, bool, _Key, _Key, 98 : _BinaryFunctionConcept) 99 : __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept) 100 : 101 : public: 102 : // typedefs: 103 : //@{ 104 : /// Public typedefs. 105 : typedef _Key key_type; 106 : typedef _Key value_type; 107 : typedef _Compare key_compare; 108 : typedef _Compare value_compare; 109 : typedef _Alloc allocator_type; 110 : //@} 111 : 112 : private: 113 : typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type; 114 : 115 : typedef _Rb_tree<key_type, value_type, _Identity<value_type>, 116 : key_compare, _Key_alloc_type> _Rep_type; 117 : _Rep_type _M_t; // Red-black tree representing set. 118 : 119 : public: 120 : //@{ 121 : /// Iterator-related typedefs. 122 : typedef typename _Key_alloc_type::pointer pointer; 123 : typedef typename _Key_alloc_type::const_pointer const_pointer; 124 : typedef typename _Key_alloc_type::reference reference; 125 : typedef typename _Key_alloc_type::const_reference const_reference; 126 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 127 : // DR 103. set::iterator is required to be modifiable, 128 : // but this allows modification of keys. 129 : typedef typename _Rep_type::const_iterator iterator; 130 : typedef typename _Rep_type::const_iterator const_iterator; 131 : typedef typename _Rep_type::const_reverse_iterator reverse_iterator; 132 : typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; 133 : typedef typename _Rep_type::size_type size_type; 134 : typedef typename _Rep_type::difference_type difference_type; 135 : //@} 136 : 137 : // allocation/deallocation 138 : /** 139 : * @brief Default constructor creates no elements. 140 : */ 141 277740 : set() 142 277740 : : _M_t() { } 143 : 144 : /** 145 : * @brief Creates a %set with no elements. 146 : * @param comp Comparator to use. 147 : * @param a An allocator object. 148 : */ 149 : explicit 150 : set(const _Compare& __comp, 151 : const allocator_type& __a = allocator_type()) 152 : : _M_t(__comp, __a) { } 153 : 154 : /** 155 : * @brief Builds a %set from a range. 156 : * @param first An input iterator. 157 : * @param last An input iterator. 158 : * 159 : * Create a %set consisting of copies of the elements from [first,last). 160 : * This is linear in N if the range is already sorted, and NlogN 161 : * otherwise (where N is distance(first,last)). 162 : */ 163 : template<typename _InputIterator> 164 : set(_InputIterator __first, _InputIterator __last) 165 : : _M_t() 166 : { _M_t._M_insert_unique(__first, __last); } 167 : 168 : /** 169 : * @brief Builds a %set from a range. 170 : * @param first An input iterator. 171 : * @param last An input iterator. 172 : * @param comp A comparison functor. 173 : * @param a An allocator object. 174 : * 175 : * Create a %set consisting of copies of the elements from [first,last). 176 : * This is linear in N if the range is already sorted, and NlogN 177 : * otherwise (where N is distance(first,last)). 178 : */ 179 : template<typename _InputIterator> 180 : set(_InputIterator __first, _InputIterator __last, 181 : const _Compare& __comp, 182 : const allocator_type& __a = allocator_type()) 183 : : _M_t(__comp, __a) 184 : { _M_t._M_insert_unique(__first, __last); } 185 : 186 : /** 187 : * @brief %Set copy constructor. 188 : * @param x A %set of identical element and allocator types. 189 : * 190 : * The newly-created %set uses a copy of the allocation object used 191 : * by @a x. 192 : */ 193 925151 : set(const set& __x) 194 925151 : : _M_t(__x._M_t) { } 195 : 196 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 197 : /** 198 : * @brief %Set move constructor 199 : * @param x A %set of identical element and allocator types. 200 : * 201 : * The newly-created %set contains the exact contents of @a x. 202 : * The contents of @a x are a valid, but unspecified %set. 203 : */ 204 : set(set&& __x) 205 : : _M_t(std::forward<_Rep_type>(__x._M_t)) { } 206 : #endif 207 : 208 : /** 209 : * @brief %Set assignment operator. 210 : * @param x A %set of identical element and allocator types. 211 : * 212 : * All the elements of @a x are copied, but unlike the copy constructor, 213 : * the allocator object is not copied. 214 : */ 215 : set& 216 80 : operator=(const set& __x) 217 : { 218 80 : _M_t = __x._M_t; 219 80 : return *this; 220 : } 221 : 222 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 223 : /** 224 : * @brief %Set move assignment operator. 225 : * @param x A %set of identical element and allocator types. 226 : * 227 : * The contents of @a x are moved into this %set (without copying). 228 : * @a x is a valid, but unspecified %set. 229 : */ 230 : set& 231 : operator=(set&& __x) 232 : { 233 : // NB: DR 675. 234 : this->clear(); 235 : this->swap(__x); 236 : return *this; 237 : } 238 : #endif 239 : 240 : // accessors: 241 : 242 : /// Returns the comparison object with which the %set was constructed. 243 : key_compare 244 : key_comp() const 245 : { return _M_t.key_comp(); } 246 : /// Returns the comparison object with which the %set was constructed. 247 : value_compare 248 : value_comp() const 249 : { return _M_t.key_comp(); } 250 : /// Returns the allocator object with which the %set was constructed. 251 : allocator_type 252 : get_allocator() const 253 : { return _M_t.get_allocator(); } 254 : 255 : /** 256 : * Returns a read-only (constant) iterator that points to the first 257 : * element in the %set. Iteration is done in ascending order according 258 : * to the keys. 259 : */ 260 : iterator 261 468023 : begin() const 262 468023 : { return _M_t.begin(); } 263 : 264 : /** 265 : * Returns a read-only (constant) iterator that points one past the last 266 : * element in the %set. Iteration is done in ascending order according 267 : * to the keys. 268 : */ 269 : iterator 270 1576796 : end() const 271 1576796 : { return _M_t.end(); } 272 : 273 : /** 274 : * Returns a read-only (constant) iterator that points to the last 275 : * element in the %set. Iteration is done in descending order according 276 : * to the keys. 277 : */ 278 : reverse_iterator 279 : rbegin() const 280 : { return _M_t.rbegin(); } 281 : 282 : /** 283 : * Returns a read-only (constant) reverse iterator that points to the 284 : * last pair in the %set. Iteration is done in descending order 285 : * according to the keys. 286 : */ 287 : reverse_iterator 288 : rend() const 289 : { return _M_t.rend(); } 290 : 291 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 292 : /** 293 : * Returns a read-only (constant) iterator that points to the first 294 : * element in the %set. Iteration is done in ascending order according 295 : * to the keys. 296 : */ 297 : iterator 298 : cbegin() const 299 : { return _M_t.begin(); } 300 : 301 : /** 302 : * Returns a read-only (constant) iterator that points one past the last 303 : * element in the %set. Iteration is done in ascending order according 304 : * to the keys. 305 : */ 306 : iterator 307 : cend() const 308 : { return _M_t.end(); } 309 : 310 : /** 311 : * Returns a read-only (constant) iterator that points to the last 312 : * element in the %set. Iteration is done in descending order according 313 : * to the keys. 314 : */ 315 : reverse_iterator 316 : crbegin() const 317 : { return _M_t.rbegin(); } 318 : 319 : /** 320 : * Returns a read-only (constant) reverse iterator that points to the 321 : * last pair in the %set. Iteration is done in descending order 322 : * according to the keys. 323 : */ 324 : reverse_iterator 325 : crend() const 326 : { return _M_t.rend(); } 327 : #endif 328 : 329 : /// Returns true if the %set is empty. 330 : bool 331 338386 : empty() const 332 338386 : { return _M_t.empty(); } 333 : 334 : /// Returns the size of the %set. 335 : size_type 336 84631 : size() const 337 84631 : { return _M_t.size(); } 338 : 339 : /// Returns the maximum size of the %set. 340 : size_type 341 : max_size() const 342 : { return _M_t.max_size(); } 343 : 344 : /** 345 : * @brief Swaps data with another %set. 346 : * @param x A %set of the same element and allocator types. 347 : * 348 : * This exchanges the elements between two sets in constant time. 349 : * (It is only swapping a pointer, an integer, and an instance of 350 : * the @c Compare type (which itself is often stateless and empty), so it 351 : * should be quite fast.) 352 : * Note that the global std::swap() function is specialized such that 353 : * std::swap(s1,s2) will feed to this function. 354 : */ 355 : void 356 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 357 : swap(set&& __x) 358 : #else 359 : swap(set& __x) 360 : #endif 361 : { _M_t.swap(__x._M_t); } 362 : 363 : // insert/erase 364 : /** 365 : * @brief Attempts to insert an element into the %set. 366 : * @param x Element to be inserted. 367 : * @return A pair, of which the first element is an iterator that points 368 : * to the possibly inserted element, and the second is a bool 369 : * that is true if the element was actually inserted. 370 : * 371 : * This function attempts to insert an element into the %set. A %set 372 : * relies on unique keys and thus an element is only inserted if it is 373 : * not already present in the %set. 374 : * 375 : * Insertion requires logarithmic time. 376 : */ 377 : std::pair<iterator, bool> 378 1422360 : insert(const value_type& __x) 379 : { 380 : std::pair<typename _Rep_type::iterator, bool> __p = 381 1422360 : _M_t._M_insert_unique(__x); 382 1422360 : return std::pair<iterator, bool>(__p.first, __p.second); 383 : } 384 : 385 : /** 386 : * @brief Attempts to insert an element into the %set. 387 : * @param position An iterator that serves as a hint as to where the 388 : * element should be inserted. 389 : * @param x Element to be inserted. 390 : * @return An iterator that points to the element with key of @a x (may 391 : * or may not be the element passed in). 392 : * 393 : * This function is not concerned about whether the insertion took place, 394 : * and thus does not return a boolean like the single-argument insert() 395 : * does. Note that the first parameter is only a hint and can 396 : * potentially improve the performance of the insertion process. A bad 397 : * hint would cause no gains in efficiency. 398 : * 399 : * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 400 : * for more on "hinting". 401 : * 402 : * Insertion requires logarithmic time (if the hint is not taken). 403 : */ 404 : iterator 405 107613 : insert(iterator __position, const value_type& __x) 406 107613 : { return _M_t._M_insert_unique_(__position, __x); } 407 : 408 : /** 409 : * @brief A template function that attempts to insert a range of elements. 410 : * @param first Iterator pointing to the start of the range to be 411 : * inserted. 412 : * @param last Iterator pointing to the end of the range. 413 : * 414 : * Complexity similar to that of the range constructor. 415 : */ 416 : template<typename _InputIterator> 417 : void 418 : insert(_InputIterator __first, _InputIterator __last) 419 : { _M_t._M_insert_unique(__first, __last); } 420 : 421 : /** 422 : * @brief Erases an element from a %set. 423 : * @param position An iterator pointing to the element to be erased. 424 : * 425 : * This function erases an element, pointed to by the given iterator, 426 : * from a %set. Note that this function only erases the element, and 427 : * that if the element is itself a pointer, the pointed-to memory is not 428 : * touched in any way. Managing the pointer is the user's responsibility. 429 : */ 430 : void 431 129 : erase(iterator __position) 432 129 : { _M_t.erase(__position); } 433 : 434 : /** 435 : * @brief Erases elements according to the provided key. 436 : * @param x Key of element to be erased. 437 : * @return The number of elements erased. 438 : * 439 : * This function erases all the elements located by the given key from 440 : * a %set. 441 : * Note that this function only erases the element, and that if 442 : * the element is itself a pointer, the pointed-to memory is not touched 443 : * in any way. Managing the pointer is the user's responsibility. 444 : */ 445 : size_type 446 9 : erase(const key_type& __x) 447 9 : { return _M_t.erase(__x); } 448 : 449 : /** 450 : * @brief Erases a [first,last) range of elements from a %set. 451 : * @param first Iterator pointing to the start of the range to be 452 : * erased. 453 : * @param last Iterator pointing to the end of the range to be erased. 454 : * 455 : * This function erases a sequence of elements from a %set. 456 : * Note that this function only erases the element, and that if 457 : * the element is itself a pointer, the pointed-to memory is not touched 458 : * in any way. Managing the pointer is the user's responsibility. 459 : */ 460 : void 461 : erase(iterator __first, iterator __last) 462 : { _M_t.erase(__first, __last); } 463 : 464 : /** 465 : * Erases all elements in a %set. Note that this function only erases 466 : * the elements, and that if the elements themselves are pointers, the 467 : * pointed-to memory is not touched in any way. Managing the pointer is 468 : * the user's responsibility. 469 : */ 470 : void 471 84600 : clear() 472 84600 : { _M_t.clear(); } 473 : 474 : // set operations: 475 : 476 : /** 477 : * @brief Finds the number of elements. 478 : * @param x Element to located. 479 : * @return Number of elements with specified key. 480 : * 481 : * This function only makes sense for multisets; for set the result will 482 : * either be 0 (not present) or 1 (present). 483 : */ 484 : size_type 485 : count(const key_type& __x) const 486 : { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } 487 : 488 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 489 : // 214. set::find() missing const overload 490 : //@{ 491 : /** 492 : * @brief Tries to locate an element in a %set. 493 : * @param x Element to be located. 494 : * @return Iterator pointing to sought-after element, or end() if not 495 : * found. 496 : * 497 : * This function takes a key and tries to locate the element with which 498 : * the key matches. If successful the function returns an iterator 499 : * pointing to the sought after element. If unsuccessful it returns the 500 : * past-the-end ( @c end() ) iterator. 501 : */ 502 : iterator 503 39 : find(const key_type& __x) 504 39 : { return _M_t.find(__x); } 505 : 506 : const_iterator 507 16 : find(const key_type& __x) const 508 16 : { return _M_t.find(__x); } 509 : //@} 510 : 511 : //@{ 512 : /** 513 : * @brief Finds the beginning of a subsequence matching given key. 514 : * @param x Key to be located. 515 : * @return Iterator pointing to first element equal to or greater 516 : * than key, or end(). 517 : * 518 : * This function returns the first element of a subsequence of elements 519 : * that matches the given key. If unsuccessful it returns an iterator 520 : * pointing to the first element that has a greater value than given key 521 : * or end() if no such element exists. 522 : */ 523 : iterator 524 : lower_bound(const key_type& __x) 525 : { return _M_t.lower_bound(__x); } 526 : 527 : const_iterator 528 : lower_bound(const key_type& __x) const 529 : { return _M_t.lower_bound(__x); } 530 : //@} 531 : 532 : //@{ 533 : /** 534 : * @brief Finds the end of a subsequence matching given key. 535 : * @param x Key to be located. 536 : * @return Iterator pointing to the first element 537 : * greater than key, or end(). 538 : */ 539 : iterator 540 : upper_bound(const key_type& __x) 541 : { return _M_t.upper_bound(__x); } 542 : 543 : const_iterator 544 : upper_bound(const key_type& __x) const 545 : { return _M_t.upper_bound(__x); } 546 : //@} 547 : 548 : //@{ 549 : /** 550 : * @brief Finds a subsequence matching given key. 551 : * @param x Key to be located. 552 : * @return Pair of iterators that possibly points to the subsequence 553 : * matching given key. 554 : * 555 : * This function is equivalent to 556 : * @code 557 : * std::make_pair(c.lower_bound(val), 558 : * c.upper_bound(val)) 559 : * @endcode 560 : * (but is faster than making the calls separately). 561 : * 562 : * This function probably only makes sense for multisets. 563 : */ 564 : std::pair<iterator, iterator> 565 : equal_range(const key_type& __x) 566 : { return _M_t.equal_range(__x); } 567 : 568 : std::pair<const_iterator, const_iterator> 569 : equal_range(const key_type& __x) const 570 : { return _M_t.equal_range(__x); } 571 : //@} 572 : 573 : template<typename _K1, typename _C1, typename _A1> 574 : friend bool 575 : operator==(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&); 576 : 577 : template<typename _K1, typename _C1, typename _A1> 578 : friend bool 579 : operator<(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&); 580 : }; 581 : 582 : 583 : /** 584 : * @brief Set equality comparison. 585 : * @param x A %set. 586 : * @param y A %set of the same type as @a x. 587 : * @return True iff the size and elements of the sets are equal. 588 : * 589 : * This is an equivalence relation. It is linear in the size of the sets. 590 : * Sets are considered equivalent if their sizes are equal, and if 591 : * corresponding elements compare equal. 592 : */ 593 : template<typename _Key, typename _Compare, typename _Alloc> 594 : inline bool 595 : operator==(const set<_Key, _Compare, _Alloc>& __x, 596 4 : const set<_Key, _Compare, _Alloc>& __y) 597 4 : { return __x._M_t == __y._M_t; } 598 : 599 : /** 600 : * @brief Set ordering relation. 601 : * @param x A %set. 602 : * @param y A %set of the same type as @a x. 603 : * @return True iff @a x is lexicographically less than @a y. 604 : * 605 : * This is a total ordering relation. It is linear in the size of the 606 : * maps. The elements must be comparable with @c <. 607 : * 608 : * See std::lexicographical_compare() for how the determination is made. 609 : */ 610 : template<typename _Key, typename _Compare, typename _Alloc> 611 : inline bool 612 : operator<(const set<_Key, _Compare, _Alloc>& __x, 613 : const set<_Key, _Compare, _Alloc>& __y) 614 : { return __x._M_t < __y._M_t; } 615 : 616 : /// Returns !(x == y). 617 : template<typename _Key, typename _Compare, typename _Alloc> 618 : inline bool 619 : operator!=(const set<_Key, _Compare, _Alloc>& __x, 620 : const set<_Key, _Compare, _Alloc>& __y) 621 : { return !(__x == __y); } 622 : 623 : /// Returns y < x. 624 : template<typename _Key, typename _Compare, typename _Alloc> 625 : inline bool 626 : operator>(const set<_Key, _Compare, _Alloc>& __x, 627 : const set<_Key, _Compare, _Alloc>& __y) 628 : { return __y < __x; } 629 : 630 : /// Returns !(y < x) 631 : template<typename _Key, typename _Compare, typename _Alloc> 632 : inline bool 633 : operator<=(const set<_Key, _Compare, _Alloc>& __x, 634 : const set<_Key, _Compare, _Alloc>& __y) 635 : { return !(__y < __x); } 636 : 637 : /// Returns !(x < y) 638 : template<typename _Key, typename _Compare, typename _Alloc> 639 : inline bool 640 : operator>=(const set<_Key, _Compare, _Alloc>& __x, 641 : const set<_Key, _Compare, _Alloc>& __y) 642 : { return !(__x < __y); } 643 : 644 : /// See std::set::swap(). 645 : template<typename _Key, typename _Compare, typename _Alloc> 646 : inline void 647 : swap(set<_Key, _Compare, _Alloc>& __x, set<_Key, _Compare, _Alloc>& __y) 648 : { __x.swap(__y); } 649 : 650 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 651 : template<typename _Key, typename _Compare, typename _Alloc> 652 : inline void 653 : swap(set<_Key, _Compare, _Alloc>&& __x, set<_Key, _Compare, _Alloc>& __y) 654 : { __x.swap(__y); } 655 : 656 : template<typename _Key, typename _Compare, typename _Alloc> 657 : inline void 658 : swap(set<_Key, _Compare, _Alloc>& __x, set<_Key, _Compare, _Alloc>&& __y) 659 : { __x.swap(__y); } 660 : #endif 661 : 662 : _GLIBCXX_END_NESTED_NAMESPACE 663 : 664 : #endif /* _STL_SET_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Components for manipulating sequences of characters -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007, 2008 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License along 19 : // with this library; see the file COPYING. If not, write to the Free 20 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 21 : // USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file basic_string.h 33 : * This is an internal header file, included by other library headers. 34 : * You should not attempt to use it directly. 35 : */ 36 : 37 : // 38 : // ISO C++ 14882: 21 Strings library 39 : // 40 : 41 : #ifndef _BASIC_STRING_H 42 : #define _BASIC_STRING_H 1 43 : 44 : #pragma GCC system_header 45 : 46 : #include <ext/atomicity.h> 47 : #include <debug/debug.h> 48 : 49 : _GLIBCXX_BEGIN_NAMESPACE(std) 50 : 51 : /** 52 : * @class basic_string basic_string.h <string> 53 : * @brief Managing sequences of characters and character-like objects. 54 : * 55 : * @ingroup Containers 56 : * @ingroup Sequences 57 : * 58 : * Meets the requirements of a <a href="tables.html#65">container</a>, a 59 : * <a href="tables.html#66">reversible container</a>, and a 60 : * <a href="tables.html#67">sequence</a>. Of the 61 : * <a href="tables.html#68">optional sequence requirements</a>, only 62 : * @c push_back, @c at, and array access are supported. 63 : * 64 : * @doctodo 65 : * 66 : * 67 : * Documentation? What's that? 68 : * Nathan Myers <ncm@cantrip.org>. 69 : * 70 : * A string looks like this: 71 : * 72 : * @code 73 : * [_Rep] 74 : * _M_length 75 : * [basic_string<char_type>] _M_capacity 76 : * _M_dataplus _M_refcount 77 : * _M_p ----------------> unnamed array of char_type 78 : * @endcode 79 : * 80 : * Where the _M_p points to the first character in the string, and 81 : * you cast it to a pointer-to-_Rep and subtract 1 to get a 82 : * pointer to the header. 83 : * 84 : * This approach has the enormous advantage that a string object 85 : * requires only one allocation. All the ugliness is confined 86 : * within a single pair of inline functions, which each compile to 87 : * a single "add" instruction: _Rep::_M_data(), and 88 : * string::_M_rep(); and the allocation function which gets a 89 : * block of raw bytes and with room enough and constructs a _Rep 90 : * object at the front. 91 : * 92 : * The reason you want _M_data pointing to the character array and 93 : * not the _Rep is so that the debugger can see the string 94 : * contents. (Probably we should add a non-inline member to get 95 : * the _Rep for the debugger to use, so users can check the actual 96 : * string length.) 97 : * 98 : * Note that the _Rep object is a POD so that you can have a 99 : * static "empty string" _Rep object already "constructed" before 100 : * static constructors have run. The reference-count encoding is 101 : * chosen so that a 0 indicates one reference, so you never try to 102 : * destroy the empty-string _Rep object. 103 : * 104 : * All but the last paragraph is considered pretty conventional 105 : * for a C++ string implementation. 106 : */ 107 : // 21.3 Template class basic_string 108 : template<typename _CharT, typename _Traits, typename _Alloc> 109 : class basic_string 110 : { 111 : typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type; 112 : 113 : // Types: 114 : public: 115 : typedef _Traits traits_type; 116 : typedef typename _Traits::char_type value_type; 117 : typedef _Alloc allocator_type; 118 : typedef typename _CharT_alloc_type::size_type size_type; 119 : typedef typename _CharT_alloc_type::difference_type difference_type; 120 : typedef typename _CharT_alloc_type::reference reference; 121 : typedef typename _CharT_alloc_type::const_reference const_reference; 122 : typedef typename _CharT_alloc_type::pointer pointer; 123 : typedef typename _CharT_alloc_type::const_pointer const_pointer; 124 : typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator; 125 : typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string> 126 : const_iterator; 127 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 128 : typedef std::reverse_iterator<iterator> reverse_iterator; 129 : 130 : private: 131 : // _Rep: string representation 132 : // Invariants: 133 : // 1. String really contains _M_length + 1 characters: due to 21.3.4 134 : // must be kept null-terminated. 135 : // 2. _M_capacity >= _M_length 136 : // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT). 137 : // 3. _M_refcount has three states: 138 : // -1: leaked, one reference, no ref-copies allowed, non-const. 139 : // 0: one reference, non-const. 140 : // n>0: n + 1 references, operations require a lock, const. 141 : // 4. All fields==0 is an empty string, given the extra storage 142 : // beyond-the-end for a null terminator; thus, the shared 143 : // empty string representation needs no constructor. 144 : 145 : struct _Rep_base 146 : { 147 : size_type _M_length; 148 : size_type _M_capacity; 149 : _Atomic_word _M_refcount; 150 : }; 151 : 152 : struct _Rep : _Rep_base 153 : { 154 : // Types: 155 : typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc; 156 : 157 : // (Public) Data members: 158 : 159 : // The maximum number of individual char_type elements of an 160 : // individual string is determined by _S_max_size. This is the 161 : // value that will be returned by max_size(). (Whereas npos 162 : // is the maximum number of bytes the allocator can allocate.) 163 : // If one was to divvy up the theoretical largest size string, 164 : // with a terminating character and m _CharT elements, it'd 165 : // look like this: 166 : // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT) 167 : // Solving for m: 168 : // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1 169 : // In addition, this implementation quarters this amount. 170 : static const size_type _S_max_size; 171 : static const _CharT _S_terminal; 172 : 173 : // The following storage is init'd to 0 by the linker, resulting 174 : // (carefully) in an empty string with one reference. 175 : static size_type _S_empty_rep_storage[]; 176 : 177 : static _Rep& 178 0 : _S_empty_rep() 179 : { 180 : // NB: Mild hack to avoid strict-aliasing warnings. Note that 181 : // _S_empty_rep_storage is never modified and the punning should 182 : // be reasonably safe in this case. 183 0 : void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage); 184 0 : return *reinterpret_cast<_Rep*>(__p); 185 : } 186 : 187 : bool 188 0 : _M_is_leaked() const 189 0 : { return this->_M_refcount < 0; } 190 : 191 : bool 192 0 : _M_is_shared() const 193 0 : { return this->_M_refcount > 0; } 194 : 195 : void 196 0 : _M_set_leaked() 197 0 : { this->_M_refcount = -1; } 198 : 199 : void 200 0 : _M_set_sharable() 201 0 : { this->_M_refcount = 0; } 202 : 203 : void 204 0 : _M_set_length_and_sharable(size_type __n) 205 : { 206 0 : this->_M_set_sharable(); // One reference. 207 0 : this->_M_length = __n; 208 0 : traits_type::assign(this->_M_refdata()[__n], _S_terminal); 209 : // grrr. (per 21.3.4) 210 : // You cannot leave those LWG people alone for a second. 211 0 : } 212 : 213 : _CharT* 214 0 : _M_refdata() throw() 215 0 : { return reinterpret_cast<_CharT*>(this + 1); } 216 : 217 : _CharT* 218 : _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) 219 : { 220 : return (!_M_is_leaked() && __alloc1 == __alloc2) 221 : ? _M_refcopy() : _M_clone(__alloc1); 222 : } 223 : 224 : // Create & Destroy 225 : static _Rep* 226 : _S_create(size_type, size_type, const _Alloc&); 227 : 228 : void 229 0 : _M_dispose(const _Alloc& __a) 230 : { 231 : #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING 232 0 : if (__builtin_expect(this != &_S_empty_rep(), false)) 233 : #endif 234 0 : if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, 235 : -1) <= 0) 236 0 : _M_destroy(__a); 237 0 : } // XXX MT 238 : 239 : void 240 : _M_destroy(const _Alloc&) throw(); 241 : 242 : _CharT* 243 : _M_refcopy() throw() 244 : { 245 : #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING 246 : if (__builtin_expect(this != &_S_empty_rep(), false)) 247 : #endif 248 : __gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1); 249 : return _M_refdata(); 250 : } // XXX MT 251 : 252 : _CharT* 253 : _M_clone(const _Alloc&, size_type __res = 0); 254 : }; 255 : 256 : // Use empty-base optimization: http://www.cantrip.org/emptyopt.html 257 : struct _Alloc_hider : _Alloc 258 0 : { 259 0 : _Alloc_hider(_CharT* __dat, const _Alloc& __a) 260 0 : : _Alloc(__a), _M_p(__dat) { } 261 : 262 : _CharT* _M_p; // The actual data. 263 : }; 264 : 265 : public: 266 : // Data Members (public): 267 : // NB: This is an unsigned type, and thus represents the maximum 268 : // size that the allocator can hold. 269 : /// Value returned by various member functions when they fail. 270 : static const size_type npos = static_cast<size_type>(-1); 271 : 272 : private: 273 : // Data Members (private): 274 : mutable _Alloc_hider _M_dataplus; 275 : 276 : _CharT* 277 0 : _M_data() const 278 0 : { return _M_dataplus._M_p; } 279 : 280 : _CharT* 281 : _M_data(_CharT* __p) 282 : { return (_M_dataplus._M_p = __p); } 283 : 284 : _Rep* 285 0 : _M_rep() const 286 0 : { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); } 287 : 288 : // For the internal use we have functions similar to `begin'/`end' 289 : // but they do not call _M_leak. 290 : iterator 291 0 : _M_ibegin() const 292 0 : { return iterator(_M_data()); } 293 : 294 : iterator 295 : _M_iend() const 296 : { return iterator(_M_data() + this->size()); } 297 : 298 : void 299 0 : _M_leak() // for use in begin() & non-const op[] 300 : { 301 0 : if (!_M_rep()->_M_is_leaked()) 302 0 : _M_leak_hard(); 303 0 : } 304 : 305 : size_type 306 0 : _M_check(size_type __pos, const char* __s) const 307 : { 308 0 : if (__pos > this->size()) 309 0 : __throw_out_of_range(__N(__s)); 310 0 : return __pos; 311 : } 312 : 313 : void 314 : _M_check_length(size_type __n1, size_type __n2, const char* __s) const 315 : { 316 : if (this->max_size() - (this->size() - __n1) < __n2) 317 : __throw_length_error(__N(__s)); 318 : } 319 : 320 : // NB: _M_limit doesn't check for a bad __pos value. 321 : size_type 322 : _M_limit(size_type __pos, size_type __off) const 323 : { 324 : const bool __testoff = __off < this->size() - __pos; 325 : return __testoff ? __off : this->size() - __pos; 326 : } 327 : 328 : // True if _Rep and source do not overlap. 329 : bool 330 : _M_disjunct(const _CharT* __s) const 331 : { 332 : return (less<const _CharT*>()(__s, _M_data()) 333 : || less<const _CharT*>()(_M_data() + this->size(), __s)); 334 : } 335 : 336 : // When __n = 1 way faster than the general multichar 337 : // traits_type::copy/move/assign. 338 : static void 339 0 : _M_copy(_CharT* __d, const _CharT* __s, size_type __n) 340 : { 341 0 : if (__n == 1) 342 0 : traits_type::assign(*__d, *__s); 343 : else 344 0 : traits_type::copy(__d, __s, __n); 345 0 : } 346 : 347 : static void 348 : _M_move(_CharT* __d, const _CharT* __s, size_type __n) 349 : { 350 : if (__n == 1) 351 : traits_type::assign(*__d, *__s); 352 : else 353 : traits_type::move(__d, __s, __n); 354 : } 355 : 356 : static void 357 : _M_assign(_CharT* __d, size_type __n, _CharT __c) 358 : { 359 : if (__n == 1) 360 : traits_type::assign(*__d, __c); 361 : else 362 : traits_type::assign(__d, __n, __c); 363 : } 364 : 365 : // _S_copy_chars is a separate template to permit specialization 366 : // to optimize for the common case of pointers as iterators. 367 : template<class _Iterator> 368 : static void 369 1012 : _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) 370 : { 371 11988 : for (; __k1 != __k2; ++__k1, ++__p) 372 10976 : traits_type::assign(*__p, *__k1); // These types are off. 373 1012 : } 374 : 375 : static void 376 0 : _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) 377 0 : { _S_copy_chars(__p, __k1.base(), __k2.base()); } 378 : 379 : static void 380 : _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) 381 : { _S_copy_chars(__p, __k1.base(), __k2.base()); } 382 : 383 : static void 384 0 : _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) 385 0 : { _M_copy(__p, __k1, __k2 - __k1); } 386 : 387 : static void 388 : _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) 389 : { _M_copy(__p, __k1, __k2 - __k1); } 390 : 391 : static int 392 0 : _S_compare(size_type __n1, size_type __n2) 393 : { 394 0 : const difference_type __d = difference_type(__n1 - __n2); 395 : 396 : if (__d > __gnu_cxx::__numeric_traits<int>::__max) 397 : return __gnu_cxx::__numeric_traits<int>::__max; 398 : else if (__d < __gnu_cxx::__numeric_traits<int>::__min) 399 : return __gnu_cxx::__numeric_traits<int>::__min; 400 : else 401 0 : return int(__d); 402 : } 403 : 404 : void 405 : _M_mutate(size_type __pos, size_type __len1, size_type __len2); 406 : 407 : void 408 : _M_leak_hard(); 409 : 410 : static _Rep& 411 0 : _S_empty_rep() 412 0 : { return _Rep::_S_empty_rep(); } 413 : 414 : public: 415 : // Construct/copy/destroy: 416 : // NB: We overload ctors in some cases instead of using default 417 : // arguments, per 17.4.4.4 para. 2 item 2. 418 : 419 : /** 420 : * @brief Default constructor creates an empty string. 421 : */ 422 : inline 423 : basic_string(); 424 : 425 : /** 426 : * @brief Construct an empty string using allocator @a a. 427 : */ 428 : explicit 429 : basic_string(const _Alloc& __a); 430 : 431 : // NB: per LWG issue 42, semantics different from IS: 432 : /** 433 : * @brief Construct string with copy of value of @a str. 434 : * @param str Source string. 435 : */ 436 : basic_string(const basic_string& __str); 437 : /** 438 : * @brief Construct string as copy of a substring. 439 : * @param str Source string. 440 : * @param pos Index of first character to copy from. 441 : * @param n Number of characters to copy (default remainder). 442 : */ 443 : basic_string(const basic_string& __str, size_type __pos, 444 : size_type __n = npos); 445 : /** 446 : * @brief Construct string as copy of a substring. 447 : * @param str Source string. 448 : * @param pos Index of first character to copy from. 449 : * @param n Number of characters to copy. 450 : * @param a Allocator to use. 451 : */ 452 : basic_string(const basic_string& __str, size_type __pos, 453 : size_type __n, const _Alloc& __a); 454 : 455 : /** 456 : * @brief Construct string initialized by a character array. 457 : * @param s Source character array. 458 : * @param n Number of characters to copy. 459 : * @param a Allocator to use (default is default allocator). 460 : * 461 : * NB: @a s must have at least @a n characters, '\0' has no special 462 : * meaning. 463 : */ 464 : basic_string(const _CharT* __s, size_type __n, 465 : const _Alloc& __a = _Alloc()); 466 : /** 467 : * @brief Construct string as copy of a C string. 468 : * @param s Source C string. 469 : * @param a Allocator to use (default is default allocator). 470 : */ 471 : basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()); 472 : /** 473 : * @brief Construct string as multiple characters. 474 : * @param n Number of characters. 475 : * @param c Character to use. 476 : * @param a Allocator to use (default is default allocator). 477 : */ 478 : basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()); 479 : 480 : /** 481 : * @brief Construct string as copy of a range. 482 : * @param beg Start of range. 483 : * @param end End of range. 484 : * @param a Allocator to use (default is default allocator). 485 : */ 486 : template<class _InputIterator> 487 : basic_string(_InputIterator __beg, _InputIterator __end, 488 : const _Alloc& __a = _Alloc()); 489 : 490 : /** 491 : * @brief Destroy the string instance. 492 : */ 493 0 : ~basic_string() 494 0 : { _M_rep()->_M_dispose(this->get_allocator()); } 495 : 496 : /** 497 : * @brief Assign the value of @a str to this string. 498 : * @param str Source string. 499 : */ 500 : basic_string& 501 0 : operator=(const basic_string& __str) 502 0 : { return this->assign(__str); } 503 : 504 : /** 505 : * @brief Copy contents of @a s into this string. 506 : * @param s Source null-terminated string. 507 : */ 508 : basic_string& 509 0 : operator=(const _CharT* __s) 510 0 : { return this->assign(__s); } 511 : 512 : /** 513 : * @brief Set value to string of length 1. 514 : * @param c Source character. 515 : * 516 : * Assigning to a character makes this string length 1 and 517 : * (*this)[0] == @a c. 518 : */ 519 : basic_string& 520 : operator=(_CharT __c) 521 : { 522 : this->assign(1, __c); 523 : return *this; 524 : } 525 : 526 : // Iterators: 527 : /** 528 : * Returns a read/write iterator that points to the first character in 529 : * the %string. Unshares the string. 530 : */ 531 : iterator 532 0 : begin() 533 : { 534 0 : _M_leak(); 535 0 : return iterator(_M_data()); 536 : } 537 : 538 : /** 539 : * Returns a read-only (constant) iterator that points to the first 540 : * character in the %string. 541 : */ 542 : const_iterator 543 0 : begin() const 544 0 : { return const_iterator(_M_data()); } 545 : 546 : /** 547 : * Returns a read/write iterator that points one past the last 548 : * character in the %string. Unshares the string. 549 : */ 550 : iterator 551 0 : end() 552 : { 553 0 : _M_leak(); 554 0 : return iterator(_M_data() + this->size()); 555 : } 556 : 557 : /** 558 : * Returns a read-only (constant) iterator that points one past the 559 : * last character in the %string. 560 : */ 561 : const_iterator 562 0 : end() const 563 0 : { return const_iterator(_M_data() + this->size()); } 564 : 565 : /** 566 : * Returns a read/write reverse iterator that points to the last 567 : * character in the %string. Iteration is done in reverse element 568 : * order. Unshares the string. 569 : */ 570 : reverse_iterator 571 : rbegin() 572 : { return reverse_iterator(this->end()); } 573 : 574 : /** 575 : * Returns a read-only (constant) reverse iterator that points 576 : * to the last character in the %string. Iteration is done in 577 : * reverse element order. 578 : */ 579 : const_reverse_iterator 580 : rbegin() const 581 : { return const_reverse_iterator(this->end()); } 582 : 583 : /** 584 : * Returns a read/write reverse iterator that points to one before the 585 : * first character in the %string. Iteration is done in reverse 586 : * element order. Unshares the string. 587 : */ 588 : reverse_iterator 589 : rend() 590 : { return reverse_iterator(this->begin()); } 591 : 592 : /** 593 : * Returns a read-only (constant) reverse iterator that points 594 : * to one before the first character in the %string. Iteration 595 : * is done in reverse element order. 596 : */ 597 : const_reverse_iterator 598 : rend() const 599 : { return const_reverse_iterator(this->begin()); } 600 : 601 : public: 602 : // Capacity: 603 : /// Returns the number of characters in the string, not including any 604 : /// null-termination. 605 : size_type 606 0 : size() const 607 0 : { return _M_rep()->_M_length; } 608 : 609 : /// Returns the number of characters in the string, not including any 610 : /// null-termination. 611 : size_type 612 0 : length() const 613 0 : { return _M_rep()->_M_length; } 614 : 615 : /// Returns the size() of the largest possible %string. 616 : size_type 617 : max_size() const 618 : { return _Rep::_S_max_size; } 619 : 620 : /** 621 : * @brief Resizes the %string to the specified number of characters. 622 : * @param n Number of characters the %string should contain. 623 : * @param c Character to fill any new elements. 624 : * 625 : * This function will %resize the %string to the specified 626 : * number of characters. If the number is smaller than the 627 : * %string's current size the %string is truncated, otherwise 628 : * the %string is extended and new elements are set to @a c. 629 : */ 630 : void 631 : resize(size_type __n, _CharT __c); 632 : 633 : /** 634 : * @brief Resizes the %string to the specified number of characters. 635 : * @param n Number of characters the %string should contain. 636 : * 637 : * This function will resize the %string to the specified length. If 638 : * the new size is smaller than the %string's current size the %string 639 : * is truncated, otherwise the %string is extended and new characters 640 : * are default-constructed. For basic types such as char, this means 641 : * setting them to 0. 642 : */ 643 : void 644 0 : resize(size_type __n) 645 0 : { this->resize(__n, _CharT()); } 646 : 647 : /** 648 : * Returns the total number of characters that the %string can hold 649 : * before needing to allocate more memory. 650 : */ 651 : size_type 652 0 : capacity() const 653 0 : { return _M_rep()->_M_capacity; } 654 : 655 : /** 656 : * @brief Attempt to preallocate enough memory for specified number of 657 : * characters. 658 : * @param res_arg Number of characters required. 659 : * @throw std::length_error If @a res_arg exceeds @c max_size(). 660 : * 661 : * This function attempts to reserve enough memory for the 662 : * %string to hold the specified number of characters. If the 663 : * number requested is more than max_size(), length_error is 664 : * thrown. 665 : * 666 : * The advantage of this function is that if optimal code is a 667 : * necessity and the user can determine the string length that will be 668 : * required, the user can reserve the memory in %advance, and thus 669 : * prevent a possible reallocation of memory and copying of %string 670 : * data. 671 : */ 672 : void 673 : reserve(size_type __res_arg = 0); 674 : 675 : /** 676 : * Erases the string, making it empty. 677 : */ 678 : void 679 0 : clear() 680 0 : { _M_mutate(0, this->size(), 0); } 681 : 682 : /** 683 : * Returns true if the %string is empty. Equivalent to *this == "". 684 : */ 685 : bool 686 0 : empty() const 687 0 : { return this->size() == 0; } 688 : 689 : // Element access: 690 : /** 691 : * @brief Subscript access to the data contained in the %string. 692 : * @param pos The index of the character to access. 693 : * @return Read-only (constant) reference to the character. 694 : * 695 : * This operator allows for easy, array-style, data access. 696 : * Note that data access with this operator is unchecked and 697 : * out_of_range lookups are not defined. (For checked lookups 698 : * see at().) 699 : */ 700 : const_reference 701 0 : operator[] (size_type __pos) const 702 : { 703 : _GLIBCXX_DEBUG_ASSERT(__pos <= size()); 704 0 : return _M_data()[__pos]; 705 : } 706 : 707 : /** 708 : * @brief Subscript access to the data contained in the %string. 709 : * @param pos The index of the character to access. 710 : * @return Read/write reference to the character. 711 : * 712 : * This operator allows for easy, array-style, data access. 713 : * Note that data access with this operator is unchecked and 714 : * out_of_range lookups are not defined. (For checked lookups 715 : * see at().) Unshares the string. 716 : */ 717 : reference 718 0 : operator[](size_type __pos) 719 : { 720 : // allow pos == size() as v3 extension: 721 : _GLIBCXX_DEBUG_ASSERT(__pos <= size()); 722 : // but be strict in pedantic mode: 723 : _GLIBCXX_DEBUG_PEDASSERT(__pos < size()); 724 0 : _M_leak(); 725 0 : return _M_data()[__pos]; 726 : } 727 : 728 : /** 729 : * @brief Provides access to the data contained in the %string. 730 : * @param n The index of the character to access. 731 : * @return Read-only (const) reference to the character. 732 : * @throw std::out_of_range If @a n is an invalid index. 733 : * 734 : * This function provides for safer data access. The parameter is 735 : * first checked that it is in the range of the string. The function 736 : * throws out_of_range if the check fails. 737 : */ 738 : const_reference 739 : at(size_type __n) const 740 : { 741 : if (__n >= this->size()) 742 : __throw_out_of_range(__N("basic_string::at")); 743 : return _M_data()[__n]; 744 : } 745 : 746 : /** 747 : * @brief Provides access to the data contained in the %string. 748 : * @param n The index of the character to access. 749 : * @return Read/write reference to the character. 750 : * @throw std::out_of_range If @a n is an invalid index. 751 : * 752 : * This function provides for safer data access. The parameter is 753 : * first checked that it is in the range of the string. The function 754 : * throws out_of_range if the check fails. Success results in 755 : * unsharing the string. 756 : */ 757 : reference 758 : at(size_type __n) 759 : { 760 : if (__n >= size()) 761 : __throw_out_of_range(__N("basic_string::at")); 762 : _M_leak(); 763 : return _M_data()[__n]; 764 : } 765 : 766 : // Modifiers: 767 : /** 768 : * @brief Append a string to this string. 769 : * @param str The string to append. 770 : * @return Reference to this string. 771 : */ 772 : basic_string& 773 0 : operator+=(const basic_string& __str) 774 0 : { return this->append(__str); } 775 : 776 : /** 777 : * @brief Append a C string. 778 : * @param s The C string to append. 779 : * @return Reference to this string. 780 : */ 781 : basic_string& 782 0 : operator+=(const _CharT* __s) 783 0 : { return this->append(__s); } 784 : 785 : /** 786 : * @brief Append a character. 787 : * @param c The character to append. 788 : * @return Reference to this string. 789 : */ 790 : basic_string& 791 0 : operator+=(_CharT __c) 792 : { 793 0 : this->push_back(__c); 794 0 : return *this; 795 : } 796 : 797 : /** 798 : * @brief Append a string to this string. 799 : * @param str The string to append. 800 : * @return Reference to this string. 801 : */ 802 : basic_string& 803 : append(const basic_string& __str); 804 : 805 : /** 806 : * @brief Append a substring. 807 : * @param str The string to append. 808 : * @param pos Index of the first character of str to append. 809 : * @param n The number of characters to append. 810 : * @return Reference to this string. 811 : * @throw std::out_of_range if @a pos is not a valid index. 812 : * 813 : * This function appends @a n characters from @a str starting at @a pos 814 : * to this string. If @a n is is larger than the number of available 815 : * characters in @a str, the remainder of @a str is appended. 816 : */ 817 : basic_string& 818 : append(const basic_string& __str, size_type __pos, size_type __n); 819 : 820 : /** 821 : * @brief Append a C substring. 822 : * @param s The C string to append. 823 : * @param n The number of characters to append. 824 : * @return Reference to this string. 825 : */ 826 : basic_string& 827 : append(const _CharT* __s, size_type __n); 828 : 829 : /** 830 : * @brief Append a C string. 831 : * @param s The C string to append. 832 : * @return Reference to this string. 833 : */ 834 : basic_string& 835 0 : append(const _CharT* __s) 836 : { 837 : __glibcxx_requires_string(__s); 838 0 : return this->append(__s, traits_type::length(__s)); 839 : } 840 : 841 : /** 842 : * @brief Append multiple characters. 843 : * @param n The number of characters to append. 844 : * @param c The character to use. 845 : * @return Reference to this string. 846 : * 847 : * Appends n copies of c to this string. 848 : */ 849 : basic_string& 850 : append(size_type __n, _CharT __c); 851 : 852 : /** 853 : * @brief Append a range of characters. 854 : * @param first Iterator referencing the first character to append. 855 : * @param last Iterator marking the end of the range. 856 : * @return Reference to this string. 857 : * 858 : * Appends characters in the range [first,last) to this string. 859 : */ 860 : template<class _InputIterator> 861 : basic_string& 862 : append(_InputIterator __first, _InputIterator __last) 863 : { return this->replace(_M_iend(), _M_iend(), __first, __last); } 864 : 865 : /** 866 : * @brief Append a single character. 867 : * @param c Character to append. 868 : */ 869 : void 870 0 : push_back(_CharT __c) 871 : { 872 0 : const size_type __len = 1 + this->size(); 873 0 : if (__len > this->capacity() || _M_rep()->_M_is_shared()) 874 0 : this->reserve(__len); 875 0 : traits_type::assign(_M_data()[this->size()], __c); 876 0 : _M_rep()->_M_set_length_and_sharable(__len); 877 0 : } 878 : 879 : /** 880 : * @brief Set value to contents of another string. 881 : * @param str Source string to use. 882 : * @return Reference to this string. 883 : */ 884 : basic_string& 885 : assign(const basic_string& __str); 886 : 887 : /** 888 : * @brief Set value to a substring of a string. 889 : * @param str The string to use. 890 : * @param pos Index of the first character of str. 891 : * @param n Number of characters to use. 892 : * @return Reference to this string. 893 : * @throw std::out_of_range if @a pos is not a valid index. 894 : * 895 : * This function sets this string to the substring of @a str consisting 896 : * of @a n characters at @a pos. If @a n is is larger than the number 897 : * of available characters in @a str, the remainder of @a str is used. 898 : */ 899 : basic_string& 900 : assign(const basic_string& __str, size_type __pos, size_type __n) 901 : { return this->assign(__str._M_data() 902 : + __str._M_check(__pos, "basic_string::assign"), 903 : __str._M_limit(__pos, __n)); } 904 : 905 : /** 906 : * @brief Set value to a C substring. 907 : * @param s The C string to use. 908 : * @param n Number of characters to use. 909 : * @return Reference to this string. 910 : * 911 : * This function sets the value of this string to the first @a n 912 : * characters of @a s. If @a n is is larger than the number of 913 : * available characters in @a s, the remainder of @a s is used. 914 : */ 915 : basic_string& 916 : assign(const _CharT* __s, size_type __n); 917 : 918 : /** 919 : * @brief Set value to contents of a C string. 920 : * @param s The C string to use. 921 : * @return Reference to this string. 922 : * 923 : * This function sets the value of this string to the value of @a s. 924 : * The data is copied, so there is no dependence on @a s once the 925 : * function returns. 926 : */ 927 : basic_string& 928 0 : assign(const _CharT* __s) 929 : { 930 : __glibcxx_requires_string(__s); 931 0 : return this->assign(__s, traits_type::length(__s)); 932 : } 933 : 934 : /** 935 : * @brief Set value to multiple characters. 936 : * @param n Length of the resulting string. 937 : * @param c The character to use. 938 : * @return Reference to this string. 939 : * 940 : * This function sets the value of this string to @a n copies of 941 : * character @a c. 942 : */ 943 : basic_string& 944 : assign(size_type __n, _CharT __c) 945 : { return _M_replace_aux(size_type(0), this->size(), __n, __c); } 946 : 947 : /** 948 : * @brief Set value to a range of characters. 949 : * @param first Iterator referencing the first character to append. 950 : * @param last Iterator marking the end of the range. 951 : * @return Reference to this string. 952 : * 953 : * Sets value of string to characters in the range [first,last). 954 : */ 955 : template<class _InputIterator> 956 : basic_string& 957 : assign(_InputIterator __first, _InputIterator __last) 958 : { return this->replace(_M_ibegin(), _M_iend(), __first, __last); } 959 : 960 : /** 961 : * @brief Insert multiple characters. 962 : * @param p Iterator referencing location in string to insert at. 963 : * @param n Number of characters to insert 964 : * @param c The character to insert. 965 : * @throw std::length_error If new length exceeds @c max_size(). 966 : * 967 : * Inserts @a n copies of character @a c starting at the position 968 : * referenced by iterator @a p. If adding characters causes the length 969 : * to exceed max_size(), length_error is thrown. The value of the 970 : * string doesn't change if an error is thrown. 971 : */ 972 : void 973 : insert(iterator __p, size_type __n, _CharT __c) 974 : { this->replace(__p, __p, __n, __c); } 975 : 976 : /** 977 : * @brief Insert a range of characters. 978 : * @param p Iterator referencing location in string to insert at. 979 : * @param beg Start of range. 980 : * @param end End of range. 981 : * @throw std::length_error If new length exceeds @c max_size(). 982 : * 983 : * Inserts characters in range [beg,end). If adding characters causes 984 : * the length to exceed max_size(), length_error is thrown. The value 985 : * of the string doesn't change if an error is thrown. 986 : */ 987 : template<class _InputIterator> 988 : void 989 : insert(iterator __p, _InputIterator __beg, _InputIterator __end) 990 : { this->replace(__p, __p, __beg, __end); } 991 : 992 : /** 993 : * @brief Insert value of a string. 994 : * @param pos1 Iterator referencing location in string to insert at. 995 : * @param str The string to insert. 996 : * @return Reference to this string. 997 : * @throw std::length_error If new length exceeds @c max_size(). 998 : * 999 : * Inserts value of @a str starting at @a pos1. If adding characters 1000 : * causes the length to exceed max_size(), length_error is thrown. The 1001 : * value of the string doesn't change if an error is thrown. 1002 : */ 1003 : basic_string& 1004 : insert(size_type __pos1, const basic_string& __str) 1005 : { return this->insert(__pos1, __str, size_type(0), __str.size()); } 1006 : 1007 : /** 1008 : * @brief Insert a substring. 1009 : * @param pos1 Iterator referencing location in string to insert at. 1010 : * @param str The string to insert. 1011 : * @param pos2 Start of characters in str to insert. 1012 : * @param n Number of characters to insert. 1013 : * @return Reference to this string. 1014 : * @throw std::length_error If new length exceeds @c max_size(). 1015 : * @throw std::out_of_range If @a pos1 > size() or 1016 : * @a pos2 > @a str.size(). 1017 : * 1018 : * Starting at @a pos1, insert @a n character of @a str beginning with 1019 : * @a pos2. If adding characters causes the length to exceed 1020 : * max_size(), length_error is thrown. If @a pos1 is beyond the end of 1021 : * this string or @a pos2 is beyond the end of @a str, out_of_range is 1022 : * thrown. The value of the string doesn't change if an error is 1023 : * thrown. 1024 : */ 1025 : basic_string& 1026 : insert(size_type __pos1, const basic_string& __str, 1027 : size_type __pos2, size_type __n) 1028 : { return this->insert(__pos1, __str._M_data() 1029 : + __str._M_check(__pos2, "basic_string::insert"), 1030 : __str._M_limit(__pos2, __n)); } 1031 : 1032 : /** 1033 : * @brief Insert a C substring. 1034 : * @param pos Iterator referencing location in string to insert at. 1035 : * @param s The C string to insert. 1036 : * @param n The number of characters to insert. 1037 : * @return Reference to this string. 1038 : * @throw std::length_error If new length exceeds @c max_size(). 1039 : * @throw std::out_of_range If @a pos is beyond the end of this 1040 : * string. 1041 : * 1042 : * Inserts the first @a n characters of @a s starting at @a pos. If 1043 : * adding characters causes the length to exceed max_size(), 1044 : * length_error is thrown. If @a pos is beyond end(), out_of_range is 1045 : * thrown. The value of the string doesn't change if an error is 1046 : * thrown. 1047 : */ 1048 : basic_string& 1049 : insert(size_type __pos, const _CharT* __s, size_type __n); 1050 : 1051 : /** 1052 : * @brief Insert a C string. 1053 : * @param pos Iterator referencing location in string to insert at. 1054 : * @param s The C string to insert. 1055 : * @return Reference to this string. 1056 : * @throw std::length_error If new length exceeds @c max_size(). 1057 : * @throw std::out_of_range If @a pos is beyond the end of this 1058 : * string. 1059 : * 1060 : * Inserts the first @a n characters of @a s starting at @a pos. If 1061 : * adding characters causes the length to exceed max_size(), 1062 : * length_error is thrown. If @a pos is beyond end(), out_of_range is 1063 : * thrown. The value of the string doesn't change if an error is 1064 : * thrown. 1065 : */ 1066 : basic_string& 1067 : insert(size_type __pos, const _CharT* __s) 1068 : { 1069 : __glibcxx_requires_string(__s); 1070 : return this->insert(__pos, __s, traits_type::length(__s)); 1071 : } 1072 : 1073 : /** 1074 : * @brief Insert multiple characters. 1075 : * @param pos Index in string to insert at. 1076 : * @param n Number of characters to insert 1077 : * @param c The character to insert. 1078 : * @return Reference to this string. 1079 : * @throw std::length_error If new length exceeds @c max_size(). 1080 : * @throw std::out_of_range If @a pos is beyond the end of this 1081 : * string. 1082 : * 1083 : * Inserts @a n copies of character @a c starting at index @a pos. If 1084 : * adding characters causes the length to exceed max_size(), 1085 : * length_error is thrown. If @a pos > length(), out_of_range is 1086 : * thrown. The value of the string doesn't change if an error is 1087 : * thrown. 1088 : */ 1089 : basic_string& 1090 : insert(size_type __pos, size_type __n, _CharT __c) 1091 : { return _M_replace_aux(_M_check(__pos, "basic_string::insert"), 1092 : size_type(0), __n, __c); } 1093 : 1094 : /** 1095 : * @brief Insert one character. 1096 : * @param p Iterator referencing position in string to insert at. 1097 : * @param c The character to insert. 1098 : * @return Iterator referencing newly inserted char. 1099 : * @throw std::length_error If new length exceeds @c max_size(). 1100 : * 1101 : * Inserts character @a c at position referenced by @a p. If adding 1102 : * character causes the length to exceed max_size(), length_error is 1103 : * thrown. If @a p is beyond end of string, out_of_range is thrown. 1104 : * The value of the string doesn't change if an error is thrown. 1105 : */ 1106 : iterator 1107 : insert(iterator __p, _CharT __c) 1108 : { 1109 : _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); 1110 : const size_type __pos = __p - _M_ibegin(); 1111 : _M_replace_aux(__pos, size_type(0), size_type(1), __c); 1112 : _M_rep()->_M_set_leaked(); 1113 : return iterator(_M_data() + __pos); 1114 : } 1115 : 1116 : /** 1117 : * @brief Remove characters. 1118 : * @param pos Index of first character to remove (default 0). 1119 : * @param n Number of characters to remove (default remainder). 1120 : * @return Reference to this string. 1121 : * @throw std::out_of_range If @a pos is beyond the end of this 1122 : * string. 1123 : * 1124 : * Removes @a n characters from this string starting at @a pos. The 1125 : * length of the string is reduced by @a n. If there are < @a n 1126 : * characters to remove, the remainder of the string is truncated. If 1127 : * @a p is beyond end of string, out_of_range is thrown. The value of 1128 : * the string doesn't change if an error is thrown. 1129 : */ 1130 : basic_string& 1131 : erase(size_type __pos = 0, size_type __n = npos) 1132 : { 1133 : _M_mutate(_M_check(__pos, "basic_string::erase"), 1134 : _M_limit(__pos, __n), size_type(0)); 1135 : return *this; 1136 : } 1137 : 1138 : /** 1139 : * @brief Remove one character. 1140 : * @param position Iterator referencing the character to remove. 1141 : * @return iterator referencing same location after removal. 1142 : * 1143 : * Removes the character at @a position from this string. The value 1144 : * of the string doesn't change if an error is thrown. 1145 : */ 1146 : iterator 1147 0 : erase(iterator __position) 1148 : { 1149 : _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin() 1150 : && __position < _M_iend()); 1151 0 : const size_type __pos = __position - _M_ibegin(); 1152 0 : _M_mutate(__pos, size_type(1), size_type(0)); 1153 0 : _M_rep()->_M_set_leaked(); 1154 0 : return iterator(_M_data() + __pos); 1155 : } 1156 : 1157 : /** 1158 : * @brief Remove a range of characters. 1159 : * @param first Iterator referencing the first character to remove. 1160 : * @param last Iterator referencing the end of the range. 1161 : * @return Iterator referencing location of first after removal. 1162 : * 1163 : * Removes the characters in the range [first,last) from this string. 1164 : * The value of the string doesn't change if an error is thrown. 1165 : */ 1166 : iterator 1167 : erase(iterator __first, iterator __last) 1168 : { 1169 : _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last 1170 : && __last <= _M_iend()); 1171 : const size_type __pos = __first - _M_ibegin(); 1172 : _M_mutate(__pos, __last - __first, size_type(0)); 1173 : _M_rep()->_M_set_leaked(); 1174 : return iterator(_M_data() + __pos); 1175 : } 1176 : 1177 : /** 1178 : * @brief Replace characters with value from another string. 1179 : * @param pos Index of first character to replace. 1180 : * @param n Number of characters to be replaced. 1181 : * @param str String to insert. 1182 : * @return Reference to this string. 1183 : * @throw std::out_of_range If @a pos is beyond the end of this 1184 : * string. 1185 : * @throw std::length_error If new length exceeds @c max_size(). 1186 : * 1187 : * Removes the characters in the range [pos,pos+n) from this string. 1188 : * In place, the value of @a str is inserted. If @a pos is beyond end 1189 : * of string, out_of_range is thrown. If the length of the result 1190 : * exceeds max_size(), length_error is thrown. The value of the string 1191 : * doesn't change if an error is thrown. 1192 : */ 1193 : basic_string& 1194 : replace(size_type __pos, size_type __n, const basic_string& __str) 1195 : { return this->replace(__pos, __n, __str._M_data(), __str.size()); } 1196 : 1197 : /** 1198 : * @brief Replace characters with value from another string. 1199 : * @param pos1 Index of first character to replace. 1200 : * @param n1 Number of characters to be replaced. 1201 : * @param str String to insert. 1202 : * @param pos2 Index of first character of str to use. 1203 : * @param n2 Number of characters from str to use. 1204 : * @return Reference to this string. 1205 : * @throw std::out_of_range If @a pos1 > size() or @a pos2 > 1206 : * str.size(). 1207 : * @throw std::length_error If new length exceeds @c max_size(). 1208 : * 1209 : * Removes the characters in the range [pos1,pos1 + n) from this 1210 : * string. In place, the value of @a str is inserted. If @a pos is 1211 : * beyond end of string, out_of_range is thrown. If the length of the 1212 : * result exceeds max_size(), length_error is thrown. The value of the 1213 : * string doesn't change if an error is thrown. 1214 : */ 1215 : basic_string& 1216 : replace(size_type __pos1, size_type __n1, const basic_string& __str, 1217 : size_type __pos2, size_type __n2) 1218 : { return this->replace(__pos1, __n1, __str._M_data() 1219 : + __str._M_check(__pos2, "basic_string::replace"), 1220 : __str._M_limit(__pos2, __n2)); } 1221 : 1222 : /** 1223 : * @brief Replace characters with value of a C substring. 1224 : * @param pos Index of first character to replace. 1225 : * @param n1 Number of characters to be replaced. 1226 : * @param s C string to insert. 1227 : * @param n2 Number of characters from @a s to use. 1228 : * @return Reference to this string. 1229 : * @throw std::out_of_range If @a pos1 > size(). 1230 : * @throw std::length_error If new length exceeds @c max_size(). 1231 : * 1232 : * Removes the characters in the range [pos,pos + n1) from this string. 1233 : * In place, the first @a n2 characters of @a s are inserted, or all 1234 : * of @a s if @a n2 is too large. If @a pos is beyond end of string, 1235 : * out_of_range is thrown. If the length of result exceeds max_size(), 1236 : * length_error is thrown. The value of the string doesn't change if 1237 : * an error is thrown. 1238 : */ 1239 : basic_string& 1240 : replace(size_type __pos, size_type __n1, const _CharT* __s, 1241 : size_type __n2); 1242 : 1243 : /** 1244 : * @brief Replace characters with value of a C string. 1245 : * @param pos Index of first character to replace. 1246 : * @param n1 Number of characters to be replaced. 1247 : * @param s C string to insert. 1248 : * @return Reference to this string. 1249 : * @throw std::out_of_range If @a pos > size(). 1250 : * @throw std::length_error If new length exceeds @c max_size(). 1251 : * 1252 : * Removes the characters in the range [pos,pos + n1) from this string. 1253 : * In place, the first @a n characters of @a s are inserted. If @a 1254 : * pos is beyond end of string, out_of_range is thrown. If the length 1255 : * of result exceeds max_size(), length_error is thrown. The value of 1256 : * the string doesn't change if an error is thrown. 1257 : */ 1258 : basic_string& 1259 : replace(size_type __pos, size_type __n1, const _CharT* __s) 1260 : { 1261 : __glibcxx_requires_string(__s); 1262 : return this->replace(__pos, __n1, __s, traits_type::length(__s)); 1263 : } 1264 : 1265 : /** 1266 : * @brief Replace characters with multiple characters. 1267 : * @param pos Index of first character to replace. 1268 : * @param n1 Number of characters to be replaced. 1269 : * @param n2 Number of characters to insert. 1270 : * @param c Character to insert. 1271 : * @return Reference to this string. 1272 : * @throw std::out_of_range If @a pos > size(). 1273 : * @throw std::length_error If new length exceeds @c max_size(). 1274 : * 1275 : * Removes the characters in the range [pos,pos + n1) from this string. 1276 : * In place, @a n2 copies of @a c are inserted. If @a pos is beyond 1277 : * end of string, out_of_range is thrown. If the length of result 1278 : * exceeds max_size(), length_error is thrown. The value of the string 1279 : * doesn't change if an error is thrown. 1280 : */ 1281 : basic_string& 1282 : replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) 1283 : { return _M_replace_aux(_M_check(__pos, "basic_string::replace"), 1284 : _M_limit(__pos, __n1), __n2, __c); } 1285 : 1286 : /** 1287 : * @brief Replace range of characters with string. 1288 : * @param i1 Iterator referencing start of range to replace. 1289 : * @param i2 Iterator referencing end of range to replace. 1290 : * @param str String value to insert. 1291 : * @return Reference to this string. 1292 : * @throw std::length_error If new length exceeds @c max_size(). 1293 : * 1294 : * Removes the characters in the range [i1,i2). In place, the value of 1295 : * @a str is inserted. If the length of result exceeds max_size(), 1296 : * length_error is thrown. The value of the string doesn't change if 1297 : * an error is thrown. 1298 : */ 1299 : basic_string& 1300 : replace(iterator __i1, iterator __i2, const basic_string& __str) 1301 : { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } 1302 : 1303 : /** 1304 : * @brief Replace range of characters with C substring. 1305 : * @param i1 Iterator referencing start of range to replace. 1306 : * @param i2 Iterator referencing end of range to replace. 1307 : * @param s C string value to insert. 1308 : * @param n Number of characters from s to insert. 1309 : * @return Reference to this string. 1310 : * @throw std::length_error If new length exceeds @c max_size(). 1311 : * 1312 : * Removes the characters in the range [i1,i2). In place, the first @a 1313 : * n characters of @a s are inserted. If the length of result exceeds 1314 : * max_size(), length_error is thrown. The value of the string doesn't 1315 : * change if an error is thrown. 1316 : */ 1317 : basic_string& 1318 : replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) 1319 : { 1320 : _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 1321 : && __i2 <= _M_iend()); 1322 : return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); 1323 : } 1324 : 1325 : /** 1326 : * @brief Replace range of characters with C string. 1327 : * @param i1 Iterator referencing start of range to replace. 1328 : * @param i2 Iterator referencing end of range to replace. 1329 : * @param s C string value to insert. 1330 : * @return Reference to this string. 1331 : * @throw std::length_error If new length exceeds @c max_size(). 1332 : * 1333 : * Removes the characters in the range [i1,i2). In place, the 1334 : * characters of @a s are inserted. If the length of result exceeds 1335 : * max_size(), length_error is thrown. The value of the string doesn't 1336 : * change if an error is thrown. 1337 : */ 1338 : basic_string& 1339 : replace(iterator __i1, iterator __i2, const _CharT* __s) 1340 : { 1341 : __glibcxx_requires_string(__s); 1342 : return this->replace(__i1, __i2, __s, traits_type::length(__s)); 1343 : } 1344 : 1345 : /** 1346 : * @brief Replace range of characters with multiple characters 1347 : * @param i1 Iterator referencing start of range to replace. 1348 : * @param i2 Iterator referencing end of range to replace. 1349 : * @param n Number of characters to insert. 1350 : * @param c Character to insert. 1351 : * @return Reference to this string. 1352 : * @throw std::length_error If new length exceeds @c max_size(). 1353 : * 1354 : * Removes the characters in the range [i1,i2). In place, @a n copies 1355 : * of @a c are inserted. If the length of result exceeds max_size(), 1356 : * length_error is thrown. The value of the string doesn't change if 1357 : * an error is thrown. 1358 : */ 1359 : basic_string& 1360 : replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) 1361 : { 1362 : _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 1363 : && __i2 <= _M_iend()); 1364 : return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c); 1365 : } 1366 : 1367 : /** 1368 : * @brief Replace range of characters with range. 1369 : * @param i1 Iterator referencing start of range to replace. 1370 : * @param i2 Iterator referencing end of range to replace. 1371 : * @param k1 Iterator referencing start of range to insert. 1372 : * @param k2 Iterator referencing end of range to insert. 1373 : * @return Reference to this string. 1374 : * @throw std::length_error If new length exceeds @c max_size(). 1375 : * 1376 : * Removes the characters in the range [i1,i2). In place, characters 1377 : * in the range [k1,k2) are inserted. If the length of result exceeds 1378 : * max_size(), length_error is thrown. The value of the string doesn't 1379 : * change if an error is thrown. 1380 : */ 1381 : template<class _InputIterator> 1382 : basic_string& 1383 : replace(iterator __i1, iterator __i2, 1384 : _InputIterator __k1, _InputIterator __k2) 1385 : { 1386 : _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 1387 : && __i2 <= _M_iend()); 1388 : __glibcxx_requires_valid_range(__k1, __k2); 1389 : typedef typename std::__is_integer<_InputIterator>::__type _Integral; 1390 : return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); 1391 : } 1392 : 1393 : // Specializations for the common case of pointer and iterator: 1394 : // useful to avoid the overhead of temporary buffering in _M_replace. 1395 : basic_string& 1396 : replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) 1397 : { 1398 : _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 1399 : && __i2 <= _M_iend()); 1400 : __glibcxx_requires_valid_range(__k1, __k2); 1401 : return this->replace(__i1 - _M_ibegin(), __i2 - __i1, 1402 : __k1, __k2 - __k1); 1403 : } 1404 : 1405 : basic_string& 1406 : replace(iterator __i1, iterator __i2, 1407 : const _CharT* __k1, const _CharT* __k2) 1408 : { 1409 : _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 1410 : && __i2 <= _M_iend()); 1411 : __glibcxx_requires_valid_range(__k1, __k2); 1412 : return this->replace(__i1 - _M_ibegin(), __i2 - __i1, 1413 : __k1, __k2 - __k1); 1414 : } 1415 : 1416 : basic_string& 1417 : replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) 1418 : { 1419 : _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 1420 : && __i2 <= _M_iend()); 1421 : __glibcxx_requires_valid_range(__k1, __k2); 1422 : return this->replace(__i1 - _M_ibegin(), __i2 - __i1, 1423 : __k1.base(), __k2 - __k1); 1424 : } 1425 : 1426 : basic_string& 1427 : replace(iterator __i1, iterator __i2, 1428 : const_iterator __k1, const_iterator __k2) 1429 : { 1430 : _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 1431 : && __i2 <= _M_iend()); 1432 : __glibcxx_requires_valid_range(__k1, __k2); 1433 : return this->replace(__i1 - _M_ibegin(), __i2 - __i1, 1434 : __k1.base(), __k2 - __k1); 1435 : } 1436 : 1437 : private: 1438 : template<class _Integer> 1439 : basic_string& 1440 : _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n, 1441 : _Integer __val, __true_type) 1442 : { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); } 1443 : 1444 : template<class _InputIterator> 1445 : basic_string& 1446 : _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, 1447 : _InputIterator __k2, __false_type); 1448 : 1449 : basic_string& 1450 : _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, 1451 : _CharT __c); 1452 : 1453 : basic_string& 1454 : _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, 1455 : size_type __n2); 1456 : 1457 : // _S_construct_aux is used to implement the 21.3.1 para 15 which 1458 : // requires special behaviour if _InIter is an integral type 1459 : template<class _InIterator> 1460 : static _CharT* 1461 : _S_construct_aux(_InIterator __beg, _InIterator __end, 1462 1287 : const _Alloc& __a, __false_type) 1463 : { 1464 : typedef typename iterator_traits<_InIterator>::iterator_category _Tag; 1465 1287 : return _S_construct(__beg, __end, __a, _Tag()); 1466 : } 1467 : 1468 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1469 : // 438. Ambiguity in the "do the right thing" clause 1470 : template<class _Integer> 1471 : static _CharT* 1472 : _S_construct_aux(_Integer __beg, _Integer __end, 1473 : const _Alloc& __a, __true_type) 1474 : { return _S_construct(static_cast<size_type>(__beg), __end, __a); } 1475 : 1476 : template<class _InIterator> 1477 : static _CharT* 1478 1287 : _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a) 1479 : { 1480 : typedef typename std::__is_integer<_InIterator>::__type _Integral; 1481 1287 : return _S_construct_aux(__beg, __end, __a, _Integral()); 1482 : } 1483 : 1484 : // For Input Iterators, used in istreambuf_iterators, etc. 1485 : template<class _InIterator> 1486 : static _CharT* 1487 : _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, 1488 : input_iterator_tag); 1489 : 1490 : // For forward_iterators up to random_access_iterators, used for 1491 : // string::iterator, _CharT*, etc. 1492 : template<class _FwdIterator> 1493 : static _CharT* 1494 : _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, 1495 : forward_iterator_tag); 1496 : 1497 : static _CharT* 1498 : _S_construct(size_type __req, _CharT __c, const _Alloc& __a); 1499 : 1500 : public: 1501 : 1502 : /** 1503 : * @brief Copy substring into C string. 1504 : * @param s C string to copy value into. 1505 : * @param n Number of characters to copy. 1506 : * @param pos Index of first character to copy. 1507 : * @return Number of characters actually copied 1508 : * @throw std::out_of_range If pos > size(). 1509 : * 1510 : * Copies up to @a n characters starting at @a pos into the C string @a 1511 : * s. If @a pos is greater than size(), out_of_range is thrown. 1512 : */ 1513 : size_type 1514 : copy(_CharT* __s, size_type __n, size_type __pos = 0) const; 1515 : 1516 : /** 1517 : * @brief Swap contents with another string. 1518 : * @param s String to swap with. 1519 : * 1520 : * Exchanges the contents of this string with that of @a s in constant 1521 : * time. 1522 : */ 1523 : void 1524 : swap(basic_string& __s); 1525 : 1526 : // String operations: 1527 : /** 1528 : * @brief Return const pointer to null-terminated contents. 1529 : * 1530 : * This is a handle to internal data. Do not modify or dire things may 1531 : * happen. 1532 : */ 1533 : const _CharT* 1534 0 : c_str() const 1535 0 : { return _M_data(); } 1536 : 1537 : /** 1538 : * @brief Return const pointer to contents. 1539 : * 1540 : * This is a handle to internal data. Do not modify or dire things may 1541 : * happen. 1542 : */ 1543 : const _CharT* 1544 0 : data() const 1545 0 : { return _M_data(); } 1546 : 1547 : /** 1548 : * @brief Return copy of allocator used to construct this string. 1549 : */ 1550 : allocator_type 1551 0 : get_allocator() const 1552 0 : { return _M_dataplus; } 1553 : 1554 : /** 1555 : * @brief Find position of a C substring. 1556 : * @param s C string to locate. 1557 : * @param pos Index of character to search from. 1558 : * @param n Number of characters from @a s to search for. 1559 : * @return Index of start of first occurrence. 1560 : * 1561 : * Starting from @a pos, searches forward for the first @a n characters 1562 : * in @a s within this string. If found, returns the index where it 1563 : * begins. If not found, returns npos. 1564 : */ 1565 : size_type 1566 : find(const _CharT* __s, size_type __pos, size_type __n) const; 1567 : 1568 : /** 1569 : * @brief Find position of a string. 1570 : * @param str String to locate. 1571 : * @param pos Index of character to search from (default 0). 1572 : * @return Index of start of first occurrence. 1573 : * 1574 : * Starting from @a pos, searches forward for value of @a str within 1575 : * this string. If found, returns the index where it begins. If not 1576 : * found, returns npos. 1577 : */ 1578 : size_type 1579 0 : find(const basic_string& __str, size_type __pos = 0) const 1580 0 : { return this->find(__str.data(), __pos, __str.size()); } 1581 : 1582 : /** 1583 : * @brief Find position of a C string. 1584 : * @param s C string to locate. 1585 : * @param pos Index of character to search from (default 0). 1586 : * @return Index of start of first occurrence. 1587 : * 1588 : * Starting from @a pos, searches forward for the value of @a s within 1589 : * this string. If found, returns the index where it begins. If not 1590 : * found, returns npos. 1591 : */ 1592 : size_type 1593 0 : find(const _CharT* __s, size_type __pos = 0) const 1594 : { 1595 : __glibcxx_requires_string(__s); 1596 0 : return this->find(__s, __pos, traits_type::length(__s)); 1597 : } 1598 : 1599 : /** 1600 : * @brief Find position of a character. 1601 : * @param c Character to locate. 1602 : * @param pos Index of character to search from (default 0). 1603 : * @return Index of first occurrence. 1604 : * 1605 : * Starting from @a pos, searches forward for @a c within this string. 1606 : * If found, returns the index where it was found. If not found, 1607 : * returns npos. 1608 : */ 1609 : size_type 1610 : find(_CharT __c, size_type __pos = 0) const; 1611 : 1612 : /** 1613 : * @brief Find last position of a string. 1614 : * @param str String to locate. 1615 : * @param pos Index of character to search back from (default end). 1616 : * @return Index of start of last occurrence. 1617 : * 1618 : * Starting from @a pos, searches backward for value of @a str within 1619 : * this string. If found, returns the index where it begins. If not 1620 : * found, returns npos. 1621 : */ 1622 : size_type 1623 : rfind(const basic_string& __str, size_type __pos = npos) const 1624 : { return this->rfind(__str.data(), __pos, __str.size()); } 1625 : 1626 : /** 1627 : * @brief Find last position of a C substring. 1628 : * @param s C string to locate. 1629 : * @param pos Index of character to search back from. 1630 : * @param n Number of characters from s to search for. 1631 : * @return Index of start of last occurrence. 1632 : * 1633 : * Starting from @a pos, searches backward for the first @a n 1634 : * characters in @a s within this string. If found, returns the index 1635 : * where it begins. If not found, returns npos. 1636 : */ 1637 : size_type 1638 : rfind(const _CharT* __s, size_type __pos, size_type __n) const; 1639 : 1640 : /** 1641 : * @brief Find last position of a C string. 1642 : * @param s C string to locate. 1643 : * @param pos Index of character to start search at (default end). 1644 : * @return Index of start of last occurrence. 1645 : * 1646 : * Starting from @a pos, searches backward for the value of @a s within 1647 : * this string. If found, returns the index where it begins. If not 1648 : * found, returns npos. 1649 : */ 1650 : size_type 1651 0 : rfind(const _CharT* __s, size_type __pos = npos) const 1652 : { 1653 : __glibcxx_requires_string(__s); 1654 0 : return this->rfind(__s, __pos, traits_type::length(__s)); 1655 : } 1656 : 1657 : /** 1658 : * @brief Find last position of a character. 1659 : * @param c Character to locate. 1660 : * @param pos Index of character to search back from (default end). 1661 : * @return Index of last occurrence. 1662 : * 1663 : * Starting from @a pos, searches backward for @a c within this string. 1664 : * If found, returns the index where it was found. If not found, 1665 : * returns npos. 1666 : */ 1667 : size_type 1668 : rfind(_CharT __c, size_type __pos = npos) const; 1669 : 1670 : /** 1671 : * @brief Find position of a character of string. 1672 : * @param str String containing characters to locate. 1673 : * @param pos Index of character to search from (default 0). 1674 : * @return Index of first occurrence. 1675 : * 1676 : * Starting from @a pos, searches forward for one of the characters of 1677 : * @a str within this string. If found, returns the index where it was 1678 : * found. If not found, returns npos. 1679 : */ 1680 : size_type 1681 : find_first_of(const basic_string& __str, size_type __pos = 0) const 1682 : { return this->find_first_of(__str.data(), __pos, __str.size()); } 1683 : 1684 : /** 1685 : * @brief Find position of a character of C substring. 1686 : * @param s String containing characters to locate. 1687 : * @param pos Index of character to search from. 1688 : * @param n Number of characters from s to search for. 1689 : * @return Index of first occurrence. 1690 : * 1691 : * Starting from @a pos, searches forward for one of the first @a n 1692 : * characters of @a s within this string. If found, returns the index 1693 : * where it was found. If not found, returns npos. 1694 : */ 1695 : size_type 1696 : find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; 1697 : 1698 : /** 1699 : * @brief Find position of a character of C string. 1700 : * @param s String containing characters to locate. 1701 : * @param pos Index of character to search from (default 0). 1702 : * @return Index of first occurrence. 1703 : * 1704 : * Starting from @a pos, searches forward for one of the characters of 1705 : * @a s within this string. If found, returns the index where it was 1706 : * found. If not found, returns npos. 1707 : */ 1708 : size_type 1709 : find_first_of(const _CharT* __s, size_type __pos = 0) const 1710 : { 1711 : __glibcxx_requires_string(__s); 1712 : return this->find_first_of(__s, __pos, traits_type::length(__s)); 1713 : } 1714 : 1715 : /** 1716 : * @brief Find position of a character. 1717 : * @param c Character to locate. 1718 : * @param pos Index of character to search from (default 0). 1719 : * @return Index of first occurrence. 1720 : * 1721 : * Starting from @a pos, searches forward for the character @a c within 1722 : * this string. If found, returns the index where it was found. If 1723 : * not found, returns npos. 1724 : * 1725 : * Note: equivalent to find(c, pos). 1726 : */ 1727 : size_type 1728 : find_first_of(_CharT __c, size_type __pos = 0) const 1729 : { return this->find(__c, __pos); } 1730 : 1731 : /** 1732 : * @brief Find last position of a character of string. 1733 : * @param str String containing characters to locate. 1734 : * @param pos Index of character to search back from (default end). 1735 : * @return Index of last occurrence. 1736 : * 1737 : * Starting from @a pos, searches backward for one of the characters of 1738 : * @a str within this string. If found, returns the index where it was 1739 : * found. If not found, returns npos. 1740 : */ 1741 : size_type 1742 : find_last_of(const basic_string& __str, size_type __pos = npos) const 1743 : { return this->find_last_of(__str.data(), __pos, __str.size()); } 1744 : 1745 : /** 1746 : * @brief Find last position of a character of C substring. 1747 : * @param s C string containing characters to locate. 1748 : * @param pos Index of character to search back from. 1749 : * @param n Number of characters from s to search for. 1750 : * @return Index of last occurrence. 1751 : * 1752 : * Starting from @a pos, searches backward for one of the first @a n 1753 : * characters of @a s within this string. If found, returns the index 1754 : * where it was found. If not found, returns npos. 1755 : */ 1756 : size_type 1757 : find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; 1758 : 1759 : /** 1760 : * @brief Find last position of a character of C string. 1761 : * @param s C string containing characters to locate. 1762 : * @param pos Index of character to search back from (default end). 1763 : * @return Index of last occurrence. 1764 : * 1765 : * Starting from @a pos, searches backward for one of the characters of 1766 : * @a s within this string. If found, returns the index where it was 1767 : * found. If not found, returns npos. 1768 : */ 1769 : size_type 1770 : find_last_of(const _CharT* __s, size_type __pos = npos) const 1771 : { 1772 : __glibcxx_requires_string(__s); 1773 : return this->find_last_of(__s, __pos, traits_type::length(__s)); 1774 : } 1775 : 1776 : /** 1777 : * @brief Find last position of a character. 1778 : * @param c Character to locate. 1779 : * @param pos Index of character to search back from (default end). 1780 : * @return Index of last occurrence. 1781 : * 1782 : * Starting from @a pos, searches backward for @a c within this string. 1783 : * If found, returns the index where it was found. If not found, 1784 : * returns npos. 1785 : * 1786 : * Note: equivalent to rfind(c, pos). 1787 : */ 1788 : size_type 1789 : find_last_of(_CharT __c, size_type __pos = npos) const 1790 : { return this->rfind(__c, __pos); } 1791 : 1792 : /** 1793 : * @brief Find position of a character not in string. 1794 : * @param str String containing characters to avoid. 1795 : * @param pos Index of character to search from (default 0). 1796 : * @return Index of first occurrence. 1797 : * 1798 : * Starting from @a pos, searches forward for a character not contained 1799 : * in @a str within this string. If found, returns the index where it 1800 : * was found. If not found, returns npos. 1801 : */ 1802 : size_type 1803 : find_first_not_of(const basic_string& __str, size_type __pos = 0) const 1804 : { return this->find_first_not_of(__str.data(), __pos, __str.size()); } 1805 : 1806 : /** 1807 : * @brief Find position of a character not in C substring. 1808 : * @param s C string containing characters to avoid. 1809 : * @param pos Index of character to search from. 1810 : * @param n Number of characters from s to consider. 1811 : * @return Index of first occurrence. 1812 : * 1813 : * Starting from @a pos, searches forward for a character not contained 1814 : * in the first @a n characters of @a s within this string. If found, 1815 : * returns the index where it was found. If not found, returns npos. 1816 : */ 1817 : size_type 1818 : find_first_not_of(const _CharT* __s, size_type __pos, 1819 : size_type __n) const; 1820 : 1821 : /** 1822 : * @brief Find position of a character not in C string. 1823 : * @param s C string containing characters to avoid. 1824 : * @param pos Index of character to search from (default 0). 1825 : * @return Index of first occurrence. 1826 : * 1827 : * Starting from @a pos, searches forward for a character not contained 1828 : * in @a s within this string. If found, returns the index where it 1829 : * was found. If not found, returns npos. 1830 : */ 1831 : size_type 1832 : find_first_not_of(const _CharT* __s, size_type __pos = 0) const 1833 : { 1834 : __glibcxx_requires_string(__s); 1835 : return this->find_first_not_of(__s, __pos, traits_type::length(__s)); 1836 : } 1837 : 1838 : /** 1839 : * @brief Find position of a different character. 1840 : * @param c Character to avoid. 1841 : * @param pos Index of character to search from (default 0). 1842 : * @return Index of first occurrence. 1843 : * 1844 : * Starting from @a pos, searches forward for a character other than @a c 1845 : * within this string. If found, returns the index where it was found. 1846 : * If not found, returns npos. 1847 : */ 1848 : size_type 1849 : find_first_not_of(_CharT __c, size_type __pos = 0) const; 1850 : 1851 : /** 1852 : * @brief Find last position of a character not in string. 1853 : * @param str String containing characters to avoid. 1854 : * @param pos Index of character to search back from (default end). 1855 : * @return Index of last occurrence. 1856 : * 1857 : * Starting from @a pos, searches backward for a character not 1858 : * contained in @a str within this string. If found, returns the index 1859 : * where it was found. If not found, returns npos. 1860 : */ 1861 : size_type 1862 : find_last_not_of(const basic_string& __str, size_type __pos = npos) const 1863 : { return this->find_last_not_of(__str.data(), __pos, __str.size()); } 1864 : 1865 : /** 1866 : * @brief Find last position of a character not in C substring. 1867 : * @param s C string containing characters to avoid. 1868 : * @param pos Index of character to search back from. 1869 : * @param n Number of characters from s to consider. 1870 : * @return Index of last occurrence. 1871 : * 1872 : * Starting from @a pos, searches backward for a character not 1873 : * contained in the first @a n characters of @a s within this string. 1874 : * If found, returns the index where it was found. If not found, 1875 : * returns npos. 1876 : */ 1877 : size_type 1878 : find_last_not_of(const _CharT* __s, size_type __pos, 1879 : size_type __n) const; 1880 : /** 1881 : * @brief Find last position of a character not in C string. 1882 : * @param s C string containing characters to avoid. 1883 : * @param pos Index of character to search back from (default end). 1884 : * @return Index of last occurrence. 1885 : * 1886 : * Starting from @a pos, searches backward for a character not 1887 : * contained in @a s within this string. If found, returns the index 1888 : * where it was found. If not found, returns npos. 1889 : */ 1890 : size_type 1891 0 : find_last_not_of(const _CharT* __s, size_type __pos = npos) const 1892 : { 1893 : __glibcxx_requires_string(__s); 1894 0 : return this->find_last_not_of(__s, __pos, traits_type::length(__s)); 1895 : } 1896 : 1897 : /** 1898 : * @brief Find last position of a different character. 1899 : * @param c Character to avoid. 1900 : * @param pos Index of character to search back from (default end). 1901 : * @return Index of last occurrence. 1902 : * 1903 : * Starting from @a pos, searches backward for a character other than 1904 : * @a c within this string. If found, returns the index where it was 1905 : * found. If not found, returns npos. 1906 : */ 1907 : size_type 1908 : find_last_not_of(_CharT __c, size_type __pos = npos) const; 1909 : 1910 : /** 1911 : * @brief Get a substring. 1912 : * @param pos Index of first character (default 0). 1913 : * @param n Number of characters in substring (default remainder). 1914 : * @return The new string. 1915 : * @throw std::out_of_range If pos > size(). 1916 : * 1917 : * Construct and return a new string using the @a n characters starting 1918 : * at @a pos. If the string is too short, use the remainder of the 1919 : * characters. If @a pos is beyond the end of the string, out_of_range 1920 : * is thrown. 1921 : */ 1922 : basic_string 1923 0 : substr(size_type __pos = 0, size_type __n = npos) const 1924 : { return basic_string(*this, 1925 0 : _M_check(__pos, "basic_string::substr"), __n); } 1926 : 1927 : /** 1928 : * @brief Compare to a string. 1929 : * @param str String to compare against. 1930 : * @return Integer < 0, 0, or > 0. 1931 : * 1932 : * Returns an integer < 0 if this string is ordered before @a str, 0 if 1933 : * their values are equivalent, or > 0 if this string is ordered after 1934 : * @a str. Determines the effective length rlen of the strings to 1935 : * compare as the smallest of size() and str.size(). The function 1936 : * then compares the two strings by calling traits::compare(data(), 1937 : * str.data(),rlen). If the result of the comparison is nonzero returns 1938 : * it, otherwise the shorter one is ordered first. 1939 : */ 1940 : int 1941 0 : compare(const basic_string& __str) const 1942 : { 1943 0 : const size_type __size = this->size(); 1944 0 : const size_type __osize = __str.size(); 1945 0 : const size_type __len = std::min(__size, __osize); 1946 : 1947 0 : int __r = traits_type::compare(_M_data(), __str.data(), __len); 1948 0 : if (!__r) 1949 0 : __r = _S_compare(__size, __osize); 1950 0 : return __r; 1951 : } 1952 : 1953 : /** 1954 : * @brief Compare substring to a string. 1955 : * @param pos Index of first character of substring. 1956 : * @param n Number of characters in substring. 1957 : * @param str String to compare against. 1958 : * @return Integer < 0, 0, or > 0. 1959 : * 1960 : * Form the substring of this string from the @a n characters starting 1961 : * at @a pos. Returns an integer < 0 if the substring is ordered 1962 : * before @a str, 0 if their values are equivalent, or > 0 if the 1963 : * substring is ordered after @a str. Determines the effective length 1964 : * rlen of the strings to compare as the smallest of the length of the 1965 : * substring and @a str.size(). The function then compares the two 1966 : * strings by calling traits::compare(substring.data(),str.data(),rlen). 1967 : * If the result of the comparison is nonzero returns it, otherwise the 1968 : * shorter one is ordered first. 1969 : */ 1970 : int 1971 : compare(size_type __pos, size_type __n, const basic_string& __str) const; 1972 : 1973 : /** 1974 : * @brief Compare substring to a substring. 1975 : * @param pos1 Index of first character of substring. 1976 : * @param n1 Number of characters in substring. 1977 : * @param str String to compare against. 1978 : * @param pos2 Index of first character of substring of str. 1979 : * @param n2 Number of characters in substring of str. 1980 : * @return Integer < 0, 0, or > 0. 1981 : * 1982 : * Form the substring of this string from the @a n1 characters starting 1983 : * at @a pos1. Form the substring of @a str from the @a n2 characters 1984 : * starting at @a pos2. Returns an integer < 0 if this substring is 1985 : * ordered before the substring of @a str, 0 if their values are 1986 : * equivalent, or > 0 if this substring is ordered after the substring 1987 : * of @a str. Determines the effective length rlen of the strings 1988 : * to compare as the smallest of the lengths of the substrings. The 1989 : * function then compares the two strings by calling 1990 : * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen). 1991 : * If the result of the comparison is nonzero returns it, otherwise the 1992 : * shorter one is ordered first. 1993 : */ 1994 : int 1995 : compare(size_type __pos1, size_type __n1, const basic_string& __str, 1996 : size_type __pos2, size_type __n2) const; 1997 : 1998 : /** 1999 : * @brief Compare to a C string. 2000 : * @param s C string to compare against. 2001 : * @return Integer < 0, 0, or > 0. 2002 : * 2003 : * Returns an integer < 0 if this string is ordered before @a s, 0 if 2004 : * their values are equivalent, or > 0 if this string is ordered after 2005 : * @a s. Determines the effective length rlen of the strings to 2006 : * compare as the smallest of size() and the length of a string 2007 : * constructed from @a s. The function then compares the two strings 2008 : * by calling traits::compare(data(),s,rlen). If the result of the 2009 : * comparison is nonzero returns it, otherwise the shorter one is 2010 : * ordered first. 2011 : */ 2012 : int 2013 : compare(const _CharT* __s) const; 2014 : 2015 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 2016 : // 5 String::compare specification questionable 2017 : /** 2018 : * @brief Compare substring to a C string. 2019 : * @param pos Index of first character of substring. 2020 : * @param n1 Number of characters in substring. 2021 : * @param s C string to compare against. 2022 : * @return Integer < 0, 0, or > 0. 2023 : * 2024 : * Form the substring of this string from the @a n1 characters starting 2025 : * at @a pos. Returns an integer < 0 if the substring is ordered 2026 : * before @a s, 0 if their values are equivalent, or > 0 if the 2027 : * substring is ordered after @a s. Determines the effective length 2028 : * rlen of the strings to compare as the smallest of the length of the 2029 : * substring and the length of a string constructed from @a s. The 2030 : * function then compares the two string by calling 2031 : * traits::compare(substring.data(),s,rlen). If the result of the 2032 : * comparison is nonzero returns it, otherwise the shorter one is 2033 : * ordered first. 2034 : */ 2035 : int 2036 : compare(size_type __pos, size_type __n1, const _CharT* __s) const; 2037 : 2038 : /** 2039 : * @brief Compare substring against a character array. 2040 : * @param pos1 Index of first character of substring. 2041 : * @param n1 Number of characters in substring. 2042 : * @param s character array to compare against. 2043 : * @param n2 Number of characters of s. 2044 : * @return Integer < 0, 0, or > 0. 2045 : * 2046 : * Form the substring of this string from the @a n1 characters starting 2047 : * at @a pos1. Form a string from the first @a n2 characters of @a s. 2048 : * Returns an integer < 0 if this substring is ordered before the string 2049 : * from @a s, 0 if their values are equivalent, or > 0 if this substring 2050 : * is ordered after the string from @a s. Determines the effective 2051 : * length rlen of the strings to compare as the smallest of the length 2052 : * of the substring and @a n2. The function then compares the two 2053 : * strings by calling traits::compare(substring.data(),s,rlen). If the 2054 : * result of the comparison is nonzero returns it, otherwise the shorter 2055 : * one is ordered first. 2056 : * 2057 : * NB: s must have at least n2 characters, '\0' has no special 2058 : * meaning. 2059 : */ 2060 : int 2061 : compare(size_type __pos, size_type __n1, const _CharT* __s, 2062 : size_type __n2) const; 2063 : }; 2064 : 2065 : template<typename _CharT, typename _Traits, typename _Alloc> 2066 : inline basic_string<_CharT, _Traits, _Alloc>:: 2067 0 : basic_string() 2068 : #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING 2069 0 : : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { } 2070 : #else 2071 : : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { } 2072 : #endif 2073 : 2074 : // operator+ 2075 : /** 2076 : * @brief Concatenate two strings. 2077 : * @param lhs First string. 2078 : * @param rhs Last string. 2079 : * @return New string with value of @a lhs followed by @a rhs. 2080 : */ 2081 : template<typename _CharT, typename _Traits, typename _Alloc> 2082 : basic_string<_CharT, _Traits, _Alloc> 2083 : operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2084 715370 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2085 : { 2086 715370 : basic_string<_CharT, _Traits, _Alloc> __str(__lhs); 2087 715370 : __str.append(__rhs); 2088 0 : return __str; 2089 : } 2090 : 2091 : /** 2092 : * @brief Concatenate C string and string. 2093 : * @param lhs First string. 2094 : * @param rhs Last string. 2095 : * @return New string with value of @a lhs followed by @a rhs. 2096 : */ 2097 : template<typename _CharT, typename _Traits, typename _Alloc> 2098 : basic_string<_CharT,_Traits,_Alloc> 2099 : operator+(const _CharT* __lhs, 2100 : const basic_string<_CharT,_Traits,_Alloc>& __rhs); 2101 : 2102 : /** 2103 : * @brief Concatenate character and string. 2104 : * @param lhs First string. 2105 : * @param rhs Last string. 2106 : * @return New string with @a lhs followed by @a rhs. 2107 : */ 2108 : template<typename _CharT, typename _Traits, typename _Alloc> 2109 : basic_string<_CharT,_Traits,_Alloc> 2110 : operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs); 2111 : 2112 : /** 2113 : * @brief Concatenate string and C string. 2114 : * @param lhs First string. 2115 : * @param rhs Last string. 2116 : * @return New string with @a lhs followed by @a rhs. 2117 : */ 2118 : template<typename _CharT, typename _Traits, typename _Alloc> 2119 : inline basic_string<_CharT, _Traits, _Alloc> 2120 : operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2121 5962 : const _CharT* __rhs) 2122 : { 2123 5962 : basic_string<_CharT, _Traits, _Alloc> __str(__lhs); 2124 5962 : __str.append(__rhs); 2125 0 : return __str; 2126 : } 2127 : 2128 : /** 2129 : * @brief Concatenate string and character. 2130 : * @param lhs First string. 2131 : * @param rhs Last string. 2132 : * @return New string with @a lhs followed by @a rhs. 2133 : */ 2134 : template<typename _CharT, typename _Traits, typename _Alloc> 2135 : inline basic_string<_CharT, _Traits, _Alloc> 2136 140 : operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs) 2137 : { 2138 : typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 2139 : typedef typename __string_type::size_type __size_type; 2140 140 : __string_type __str(__lhs); 2141 140 : __str.append(__size_type(1), __rhs); 2142 0 : return __str; 2143 : } 2144 : 2145 : // operator == 2146 : /** 2147 : * @brief Test equivalence of two strings. 2148 : * @param lhs First string. 2149 : * @param rhs Second string. 2150 : * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. 2151 : */ 2152 : template<typename _CharT, typename _Traits, typename _Alloc> 2153 : inline bool 2154 : operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2155 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2156 : { return __lhs.compare(__rhs) == 0; } 2157 : 2158 : template<typename _CharT> 2159 : inline 2160 : typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, bool>::__type 2161 : operator==(const basic_string<_CharT>& __lhs, 2162 134945 : const basic_string<_CharT>& __rhs) 2163 : { return (__lhs.size() == __rhs.size() 2164 : && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(), 2165 134945 : __lhs.size())); } 2166 : 2167 : /** 2168 : * @brief Test equivalence of C string and string. 2169 : * @param lhs C string. 2170 : * @param rhs String. 2171 : * @return True if @a rhs.compare(@a lhs) == 0. False otherwise. 2172 : */ 2173 : template<typename _CharT, typename _Traits, typename _Alloc> 2174 : inline bool 2175 : operator==(const _CharT* __lhs, 2176 0 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2177 0 : { return __rhs.compare(__lhs) == 0; } 2178 : 2179 : /** 2180 : * @brief Test equivalence of string and C string. 2181 : * @param lhs String. 2182 : * @param rhs C string. 2183 : * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. 2184 : */ 2185 : template<typename _CharT, typename _Traits, typename _Alloc> 2186 : inline bool 2187 : operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2188 156952 : const _CharT* __rhs) 2189 156952 : { return __lhs.compare(__rhs) == 0; } 2190 : 2191 : // operator != 2192 : /** 2193 : * @brief Test difference of two strings. 2194 : * @param lhs First string. 2195 : * @param rhs Second string. 2196 : * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. 2197 : */ 2198 : template<typename _CharT, typename _Traits, typename _Alloc> 2199 : inline bool 2200 : operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2201 84867 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2202 84867 : { return !(__lhs == __rhs); } 2203 : 2204 : /** 2205 : * @brief Test difference of C string and string. 2206 : * @param lhs C string. 2207 : * @param rhs String. 2208 : * @return True if @a rhs.compare(@a lhs) != 0. False otherwise. 2209 : */ 2210 : template<typename _CharT, typename _Traits, typename _Alloc> 2211 : inline bool 2212 : operator!=(const _CharT* __lhs, 2213 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2214 : { return !(__lhs == __rhs); } 2215 : 2216 : /** 2217 : * @brief Test difference of string and C string. 2218 : * @param lhs String. 2219 : * @param rhs C string. 2220 : * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. 2221 : */ 2222 : template<typename _CharT, typename _Traits, typename _Alloc> 2223 : inline bool 2224 : operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2225 74475 : const _CharT* __rhs) 2226 74475 : { return !(__lhs == __rhs); } 2227 : 2228 : // operator < 2229 : /** 2230 : * @brief Test if string precedes string. 2231 : * @param lhs First string. 2232 : * @param rhs Second string. 2233 : * @return True if @a lhs precedes @a rhs. False otherwise. 2234 : */ 2235 : template<typename _CharT, typename _Traits, typename _Alloc> 2236 : inline bool 2237 : operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2238 4885154 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2239 4885154 : { return __lhs.compare(__rhs) < 0; } 2240 : 2241 : /** 2242 : * @brief Test if string precedes C string. 2243 : * @param lhs String. 2244 : * @param rhs C string. 2245 : * @return True if @a lhs precedes @a rhs. False otherwise. 2246 : */ 2247 : template<typename _CharT, typename _Traits, typename _Alloc> 2248 : inline bool 2249 : operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2250 : const _CharT* __rhs) 2251 : { return __lhs.compare(__rhs) < 0; } 2252 : 2253 : /** 2254 : * @brief Test if C string precedes string. 2255 : * @param lhs C string. 2256 : * @param rhs String. 2257 : * @return True if @a lhs precedes @a rhs. False otherwise. 2258 : */ 2259 : template<typename _CharT, typename _Traits, typename _Alloc> 2260 : inline bool 2261 : operator<(const _CharT* __lhs, 2262 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2263 : { return __rhs.compare(__lhs) > 0; } 2264 : 2265 : // operator > 2266 : /** 2267 : * @brief Test if string follows string. 2268 : * @param lhs First string. 2269 : * @param rhs Second string. 2270 : * @return True if @a lhs follows @a rhs. False otherwise. 2271 : */ 2272 : template<typename _CharT, typename _Traits, typename _Alloc> 2273 : inline bool 2274 : operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2275 1024110 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2276 1024110 : { return __lhs.compare(__rhs) > 0; } 2277 : 2278 : /** 2279 : * @brief Test if string follows C string. 2280 : * @param lhs String. 2281 : * @param rhs C string. 2282 : * @return True if @a lhs follows @a rhs. False otherwise. 2283 : */ 2284 : template<typename _CharT, typename _Traits, typename _Alloc> 2285 : inline bool 2286 : operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2287 : const _CharT* __rhs) 2288 : { return __lhs.compare(__rhs) > 0; } 2289 : 2290 : /** 2291 : * @brief Test if C string follows string. 2292 : * @param lhs C string. 2293 : * @param rhs String. 2294 : * @return True if @a lhs follows @a rhs. False otherwise. 2295 : */ 2296 : template<typename _CharT, typename _Traits, typename _Alloc> 2297 : inline bool 2298 : operator>(const _CharT* __lhs, 2299 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2300 : { return __rhs.compare(__lhs) < 0; } 2301 : 2302 : // operator <= 2303 : /** 2304 : * @brief Test if string doesn't follow string. 2305 : * @param lhs First string. 2306 : * @param rhs Second string. 2307 : * @return True if @a lhs doesn't follow @a rhs. False otherwise. 2308 : */ 2309 : template<typename _CharT, typename _Traits, typename _Alloc> 2310 : inline bool 2311 : operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2312 58 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2313 58 : { return __lhs.compare(__rhs) <= 0; } 2314 : 2315 : /** 2316 : * @brief Test if string doesn't follow C string. 2317 : * @param lhs String. 2318 : * @param rhs C string. 2319 : * @return True if @a lhs doesn't follow @a rhs. False otherwise. 2320 : */ 2321 : template<typename _CharT, typename _Traits, typename _Alloc> 2322 : inline bool 2323 : operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2324 : const _CharT* __rhs) 2325 : { return __lhs.compare(__rhs) <= 0; } 2326 : 2327 : /** 2328 : * @brief Test if C string doesn't follow string. 2329 : * @param lhs C string. 2330 : * @param rhs String. 2331 : * @return True if @a lhs doesn't follow @a rhs. False otherwise. 2332 : */ 2333 : template<typename _CharT, typename _Traits, typename _Alloc> 2334 : inline bool 2335 : operator<=(const _CharT* __lhs, 2336 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2337 : { return __rhs.compare(__lhs) >= 0; } 2338 : 2339 : // operator >= 2340 : /** 2341 : * @brief Test if string doesn't precede string. 2342 : * @param lhs First string. 2343 : * @param rhs Second string. 2344 : * @return True if @a lhs doesn't precede @a rhs. False otherwise. 2345 : */ 2346 : template<typename _CharT, typename _Traits, typename _Alloc> 2347 : inline bool 2348 : operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2349 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2350 : { return __lhs.compare(__rhs) >= 0; } 2351 : 2352 : /** 2353 : * @brief Test if string doesn't precede C string. 2354 : * @param lhs String. 2355 : * @param rhs C string. 2356 : * @return True if @a lhs doesn't precede @a rhs. False otherwise. 2357 : */ 2358 : template<typename _CharT, typename _Traits, typename _Alloc> 2359 : inline bool 2360 : operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, 2361 : const _CharT* __rhs) 2362 : { return __lhs.compare(__rhs) >= 0; } 2363 : 2364 : /** 2365 : * @brief Test if C string doesn't precede string. 2366 : * @param lhs C string. 2367 : * @param rhs String. 2368 : * @return True if @a lhs doesn't precede @a rhs. False otherwise. 2369 : */ 2370 : template<typename _CharT, typename _Traits, typename _Alloc> 2371 : inline bool 2372 : operator>=(const _CharT* __lhs, 2373 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 2374 : { return __rhs.compare(__lhs) <= 0; } 2375 : 2376 : /** 2377 : * @brief Swap contents of two strings. 2378 : * @param lhs First string. 2379 : * @param rhs Second string. 2380 : * 2381 : * Exchanges the contents of @a lhs and @a rhs in constant time. 2382 : */ 2383 : template<typename _CharT, typename _Traits, typename _Alloc> 2384 : inline void 2385 : swap(basic_string<_CharT, _Traits, _Alloc>& __lhs, 2386 0 : basic_string<_CharT, _Traits, _Alloc>& __rhs) 2387 0 : { __lhs.swap(__rhs); } 2388 : 2389 : /** 2390 : * @brief Read stream into a string. 2391 : * @param is Input stream. 2392 : * @param str Buffer to store into. 2393 : * @return Reference to the input stream. 2394 : * 2395 : * Stores characters from @a is into @a str until whitespace is found, the 2396 : * end of the stream is encountered, or str.max_size() is reached. If 2397 : * is.width() is non-zero, that is the limit on the number of characters 2398 : * stored into @a str. Any previous contents of @a str are erased. 2399 : */ 2400 : template<typename _CharT, typename _Traits, typename _Alloc> 2401 : basic_istream<_CharT, _Traits>& 2402 : operator>>(basic_istream<_CharT, _Traits>& __is, 2403 : basic_string<_CharT, _Traits, _Alloc>& __str); 2404 : 2405 : template<> 2406 : basic_istream<char>& 2407 : operator>>(basic_istream<char>& __is, basic_string<char>& __str); 2408 : 2409 : /** 2410 : * @brief Write string to a stream. 2411 : * @param os Output stream. 2412 : * @param str String to write out. 2413 : * @return Reference to the output stream. 2414 : * 2415 : * Output characters of @a str into os following the same rules as for 2416 : * writing a C string. 2417 : */ 2418 : template<typename _CharT, typename _Traits, typename _Alloc> 2419 : inline basic_ostream<_CharT, _Traits>& 2420 : operator<<(basic_ostream<_CharT, _Traits>& __os, 2421 0 : const basic_string<_CharT, _Traits, _Alloc>& __str) 2422 : { 2423 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 2424 : // 586. string inserter not a formatted function 2425 0 : return __ostream_insert(__os, __str.data(), __str.size()); 2426 : } 2427 : 2428 : /** 2429 : * @brief Read a line from stream into a string. 2430 : * @param is Input stream. 2431 : * @param str Buffer to store into. 2432 : * @param delim Character marking end of line. 2433 : * @return Reference to the input stream. 2434 : * 2435 : * Stores characters from @a is into @a str until @a delim is found, the 2436 : * end of the stream is encountered, or str.max_size() is reached. If 2437 : * is.width() is non-zero, that is the limit on the number of characters 2438 : * stored into @a str. Any previous contents of @a str are erased. If @a 2439 : * delim was encountered, it is extracted but not stored into @a str. 2440 : */ 2441 : template<typename _CharT, typename _Traits, typename _Alloc> 2442 : basic_istream<_CharT, _Traits>& 2443 : getline(basic_istream<_CharT, _Traits>& __is, 2444 : basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim); 2445 : 2446 : /** 2447 : * @brief Read a line from stream into a string. 2448 : * @param is Input stream. 2449 : * @param str Buffer to store into. 2450 : * @return Reference to the input stream. 2451 : * 2452 : * Stores characters from is into @a str until '\n' is found, the end of 2453 : * the stream is encountered, or str.max_size() is reached. If is.width() 2454 : * is non-zero, that is the limit on the number of characters stored into 2455 : * @a str. Any previous contents of @a str are erased. If end of line was 2456 : * encountered, it is extracted but not stored into @a str. 2457 : */ 2458 : template<typename _CharT, typename _Traits, typename _Alloc> 2459 : inline basic_istream<_CharT, _Traits>& 2460 : getline(basic_istream<_CharT, _Traits>& __is, 2461 0 : basic_string<_CharT, _Traits, _Alloc>& __str) 2462 0 : { return getline(__is, __str, __is.widen('\n')); } 2463 : 2464 : template<> 2465 : basic_istream<char>& 2466 : getline(basic_istream<char>& __in, basic_string<char>& __str, 2467 : char __delim); 2468 : 2469 : #ifdef _GLIBCXX_USE_WCHAR_T 2470 : template<> 2471 : basic_istream<wchar_t>& 2472 : getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str, 2473 : wchar_t __delim); 2474 : #endif 2475 : 2476 : _GLIBCXX_END_NAMESPACE 2477 : 2478 : #endif /* _BASIC_STRING_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Position types -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007, 2008 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License along 19 : // with this library; see the file COPYING. If not, write to the Free 20 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 21 : // USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file postypes.h 33 : * This is an internal header file, included by other library headers. 34 : * You should not attempt to use it directly. 35 : */ 36 : 37 : // 38 : // ISO C++ 14882: 27.4.1 - Types 39 : // ISO C++ 14882: 27.4.3 - Template class fpos 40 : // 41 : 42 : #ifndef _GLIBCXX_POSTYPES_H 43 : #define _GLIBCXX_POSTYPES_H 1 44 : 45 : #pragma GCC system_header 46 : 47 : #include <cwchar> // For mbstate_t 48 : 49 : #ifdef _GLIBCXX_HAVE_STDINT_H 50 : #include <stdint.h> // For int64_t 51 : #endif 52 : 53 : _GLIBCXX_BEGIN_NAMESPACE(std) 54 : 55 : // The types streamoff, streampos and wstreampos and the class 56 : // template fpos<> are described in clauses 21.1.2, 21.1.3, 27.1.2, 57 : // 27.2, 27.4.1, 27.4.3 and D.6. Despite all this verbiage, the 58 : // behaviour of these types is mostly implementation defined or 59 : // unspecified. The behaviour in this implementation is as noted 60 : // below. 61 : 62 : /** 63 : * @brief Type used by fpos, char_traits<char>, and char_traits<wchar_t>. 64 : * 65 : * In clauses 21.1.3.1 and 27.4.1 streamoff is described as an 66 : * implementation defined type. 67 : * Note: In versions of GCC up to and including GCC 3.3, streamoff 68 : * was typedef long. 69 : */ 70 : #ifdef _GLIBCXX_HAVE_INT64_T 71 : typedef int64_t streamoff; 72 : #else 73 : typedef long long streamoff; 74 : #endif 75 : 76 : /// Integral type for I/O operation counts and buffer sizes. 77 : typedef ptrdiff_t streamsize; // Signed integral type 78 : 79 : /** 80 : * @brief Class representing stream positions. 81 : * 82 : * The standard places no requirements upon the template parameter StateT. 83 : * In this implementation StateT must be DefaultConstructible, 84 : * CopyConstructible and Assignable. The standard only requires that fpos 85 : * should contain a member of type StateT. In this implementation it also 86 : * contains an offset stored as a signed integer. 87 : * 88 : * @param StateT Type passed to and returned from state(). 89 : */ 90 : template<typename _StateT> 91 : class fpos 92 : { 93 : private: 94 : streamoff _M_off; 95 : _StateT _M_state; 96 : 97 : public: 98 : // The standard doesn't require that fpos objects can be default 99 : // constructed. This implementation provides a default 100 : // constructor that initializes the offset to 0 and default 101 : // constructs the state. 102 : fpos() 103 : : _M_off(0), _M_state() { } 104 : 105 : // The standard requires that fpos objects can be constructed 106 : // from streamoff objects using the constructor syntax, and 107 : // fails to give any meaningful semantics. In this 108 : // implementation implicit conversion is also allowed, and this 109 : // constructor stores the streamoff as the offset and default 110 : // constructs the state. 111 : /// Construct position from offset. 112 0 : fpos(streamoff __off) 113 0 : : _M_off(__off), _M_state() { } 114 : 115 : /// Convert to streamoff. 116 0 : operator streamoff() const { return _M_off; } 117 : 118 : /// Remember the value of @a st. 119 : void 120 : state(_StateT __st) 121 : { _M_state = __st; } 122 : 123 : /// Return the last set value of @a st. 124 : _StateT 125 : state() const 126 : { return _M_state; } 127 : 128 : // The standard requires that this operator must be defined, but 129 : // gives no semantics. In this implementation it just adds its 130 : // argument to the stored offset and returns *this. 131 : /// Add offset to this position. 132 : fpos& 133 : operator+=(streamoff __off) 134 : { 135 : _M_off += __off; 136 : return *this; 137 : } 138 : 139 : // The standard requires that this operator must be defined, but 140 : // gives no semantics. In this implementation it just subtracts 141 : // its argument from the stored offset and returns *this. 142 : /// Subtract offset from this position. 143 : fpos& 144 : operator-=(streamoff __off) 145 : { 146 : _M_off -= __off; 147 : return *this; 148 : } 149 : 150 : // The standard requires that this operator must be defined, but 151 : // defines its semantics only in terms of operator-. In this 152 : // implementation it constructs a copy of *this, adds the 153 : // argument to that copy using operator+= and then returns the 154 : // copy. 155 : /// Add position and offset. 156 : fpos 157 : operator+(streamoff __off) const 158 : { 159 : fpos __pos(*this); 160 : __pos += __off; 161 : return __pos; 162 : } 163 : 164 : // The standard requires that this operator must be defined, but 165 : // defines its semantics only in terms of operator+. In this 166 : // implementation it constructs a copy of *this, subtracts the 167 : // argument from that copy using operator-= and then returns the 168 : // copy. 169 : /// Subtract offset from position. 170 : fpos 171 : operator-(streamoff __off) const 172 : { 173 : fpos __pos(*this); 174 : __pos -= __off; 175 : return __pos; 176 : } 177 : 178 : // The standard requires that this operator must be defined, but 179 : // defines its semantics only in terms of operator+. In this 180 : // implementation it returns the difference between the offset 181 : // stored in *this and in the argument. 182 : /// Subtract position to return offset. 183 : streamoff 184 : operator-(const fpos& __other) const 185 : { return _M_off - __other._M_off; } 186 : }; 187 : 188 : // The standard only requires that operator== must be an 189 : // equivalence relation. In this implementation two fpos<StateT> 190 : // objects belong to the same equivalence class if the contained 191 : // offsets compare equal. 192 : /// Test if equivalent to another position. 193 : template<typename _StateT> 194 : inline bool 195 : operator==(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs) 196 : { return streamoff(__lhs) == streamoff(__rhs); } 197 : 198 : template<typename _StateT> 199 : inline bool 200 : operator!=(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs) 201 : { return streamoff(__lhs) != streamoff(__rhs); } 202 : 203 : // Clauses 21.1.3.1 and 21.1.3.2 describe streampos and wstreampos 204 : // as implementation defined types, but clause 27.2 requires that 205 : // they must both be typedefs for fpos<mbstate_t> 206 : /// File position for char streams. 207 : typedef fpos<mbstate_t> streampos; 208 : /// File position for wchar_t streams. 209 : typedef fpos<mbstate_t> wstreampos; 210 : 211 : _GLIBCXX_END_NAMESPACE 212 : 213 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // nonstandard construct and destroy functions -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996,1997 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_construct.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_CONSTRUCT_H 63 : #define _STL_CONSTRUCT_H 1 64 : 65 : #include <new> 66 : 67 : _GLIBCXX_BEGIN_NAMESPACE(std) 68 : 69 : /** 70 : * Constructs an object in existing memory by invoking an allocated 71 : * object's constructor with an initializer. 72 : */ 73 : template<typename _T1, typename _T2> 74 : inline void 75 23695 : _Construct(_T1* __p, const _T2& __value) 76 : { 77 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 78 : // 402. wrong new expression in [some_]allocator::construct 79 23695 : ::new(static_cast<void*>(__p)) _T1(__value); 80 23695 : } 81 : 82 : /** 83 : * Destroy the object pointed to by a pointer type. 84 : */ 85 : template<typename _Tp> 86 : inline void 87 82748 : _Destroy(_Tp* __pointer) 88 82748 : { __pointer->~_Tp(); } 89 : 90 : /** 91 : * Destroy a range of objects. If the value_type of the object has 92 : * a trivial destructor, the compiler should optimize all of this 93 : * away, otherwise the objects' destructors must be invoked. 94 : */ 95 : template<typename _ForwardIterator> 96 : inline void 97 33441 : _Destroy(_ForwardIterator __first, _ForwardIterator __last) 98 : { 99 : typedef typename iterator_traits<_ForwardIterator>::value_type 100 : _Value_type; 101 91960 : if (!__has_trivial_destructor(_Value_type)) 102 : for (; __first != __last; ++__first) 103 82748 : std::_Destroy(&*__first); 104 33441 : } 105 : 106 : /** 107 : * Destroy a range of objects using the supplied allocator. For 108 : * nondefault allocators we do not optimize away invocation of 109 : * destroy() even if _Tp has a trivial destructor. 110 : */ 111 : 112 : template <typename _Tp> class allocator; 113 : 114 : template<typename _ForwardIterator, typename _Allocator> 115 : void 116 : _Destroy(_ForwardIterator __first, _ForwardIterator __last, 117 : _Allocator& __alloc) 118 : { 119 : for (; __first != __last; ++__first) 120 : __alloc.destroy(&*__first); 121 : } 122 : 123 : template<typename _ForwardIterator, typename _Tp> 124 : inline void 125 : _Destroy(_ForwardIterator __first, _ForwardIterator __last, 126 33441 : allocator<_Tp>&) 127 : { 128 33441 : _Destroy(__first, __last); 129 33441 : } 130 : 131 : _GLIBCXX_END_NAMESPACE 132 : 133 : #endif /* _STL_CONSTRUCT_H */ 134 : |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Pair implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996,1997 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_pair.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_PAIR_H 63 : #define _STL_PAIR_H 1 64 : 65 : #include <bits/stl_move.h> // for std::move / std::forward, std::decay, and 66 : // std::swap 67 : 68 : _GLIBCXX_BEGIN_NAMESPACE(std) 69 : 70 : /// pair holds two objects of arbitrary type. 71 : template<class _T1, class _T2> 72 : struct pair 73 814163 : { 74 : typedef _T1 first_type; ///< @c first_type is the first bound type 75 : typedef _T2 second_type; ///< @c second_type is the second bound type 76 : 77 : _T1 first; ///< @c first is a copy of the first object 78 : _T2 second; ///< @c second is a copy of the second object 79 : 80 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 81 : // 265. std::pair::pair() effects overly restrictive 82 : /** The default constructor creates @c first and @c second using their 83 : * respective default constructors. */ 84 19 : pair() 85 19 : : first(), second() { } 86 : 87 : /** Two objects may be passed to a @c pair constructor to be copied. */ 88 3562241 : pair(const _T1& __a, const _T2& __b) 89 3562241 : : first(__a), second(__b) { } 90 : 91 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 92 : template<class _U1, class _U2> 93 : pair(_U1&& __x, _U2&& __y) 94 : : first(std::forward<_U1>(__x)), 95 : second(std::forward<_U2>(__y)) { } 96 : 97 : pair(pair&& __p) 98 : : first(std::move(__p.first)), 99 : second(std::move(__p.second)) { } 100 : #endif 101 : 102 : /** There is also a templated copy ctor for the @c pair class itself. */ 103 : template<class _U1, class _U2> 104 101375 : pair(const pair<_U1, _U2>& __p) 105 : : first(__p.first), 106 101375 : second(__p.second) { } 107 : 108 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 109 : template<class _U1, class _U2> 110 : pair(pair<_U1, _U2>&& __p) 111 : : first(std::move(__p.first)), 112 : second(std::move(__p.second)) { } 113 : 114 : // http://gcc.gnu.org/ml/libstdc++/2007-08/msg00052.html 115 : template<class _U1, class _Arg0, class... _Args> 116 : pair(_U1&& __x, _Arg0&& __arg0, _Args&&... __args) 117 : : first(std::forward<_U1>(__x)), 118 : second(std::forward<_Arg0>(__arg0), 119 : std::forward<_Args>(__args)...) { } 120 : 121 : pair& 122 : operator=(pair&& __p) 123 : { 124 : first = std::move(__p.first); 125 : second = std::move(__p.second); 126 : return *this; 127 : } 128 : 129 : template<class _U1, class _U2> 130 : pair& 131 : operator=(pair<_U1, _U2>&& __p) 132 : { 133 : first = std::move(__p.first); 134 : second = std::move(__p.second); 135 : return *this; 136 : } 137 : 138 : void 139 : swap(pair&& __p) 140 : { 141 : using std::swap; 142 : swap(first, __p.first); 143 : swap(second, __p.second); 144 : } 145 : #endif 146 : }; 147 : 148 : /// Two pairs of the same type are equal iff their members are equal. 149 : template<class _T1, class _T2> 150 : inline bool 151 : operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 152 : { return __x.first == __y.first && __x.second == __y.second; } 153 : 154 : /// <http://gcc.gnu.org/onlinedocs/libstdc++/20_util/howto.html#pairlt> 155 : template<class _T1, class _T2> 156 : inline bool 157 : operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 158 : { return __x.first < __y.first 159 : || (!(__y.first < __x.first) && __x.second < __y.second); } 160 : 161 : /// Uses @c operator== to find the result. 162 : template<class _T1, class _T2> 163 : inline bool 164 : operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 165 : { return !(__x == __y); } 166 : 167 : /// Uses @c operator< to find the result. 168 : template<class _T1, class _T2> 169 : inline bool 170 : operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 171 : { return __y < __x; } 172 : 173 : /// Uses @c operator< to find the result. 174 : template<class _T1, class _T2> 175 : inline bool 176 : operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 177 : { return !(__y < __x); } 178 : 179 : /// Uses @c operator< to find the result. 180 : template<class _T1, class _T2> 181 : inline bool 182 : operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 183 : { return !(__x < __y); } 184 : 185 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 186 : /// See std::pair::swap(). 187 : template<class _T1, class _T2> 188 : inline void 189 : swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) 190 : { __x.swap(__y); } 191 : 192 : template<class _T1, class _T2> 193 : inline void 194 : swap(pair<_T1, _T2>&& __x, pair<_T1, _T2>& __y) 195 : { __x.swap(__y); } 196 : 197 : template<class _T1, class _T2> 198 : inline void 199 : swap(pair<_T1, _T2>& __x, pair<_T1, _T2>&& __y) 200 : { __x.swap(__y); } 201 : #endif 202 : 203 : /** 204 : * @brief A convenience wrapper for creating a pair from two objects. 205 : * @param x The first object. 206 : * @param y The second object. 207 : * @return A newly-constructed pair<> object of the appropriate type. 208 : * 209 : * The standard requires that the objects be passed by reference-to-const, 210 : * but LWG issue #181 says they should be passed by const value. We follow 211 : * the LWG by default. 212 : */ 213 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 214 : // 181. make_pair() unintended behavior 215 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 216 : template<class _T1, class _T2> 217 : inline pair<_T1, _T2> 218 474889 : make_pair(_T1 __x, _T2 __y) 219 474889 : { return pair<_T1, _T2>(__x, __y); } 220 : #else 221 : template<typename _Tp> 222 : class reference_wrapper; 223 : 224 : // Helper which adds a reference to a type when given a reference_wrapper 225 : template<typename _Tp> 226 : struct __strip_reference_wrapper 227 : { 228 : typedef _Tp __type; 229 : }; 230 : 231 : template<typename _Tp> 232 : struct __strip_reference_wrapper<reference_wrapper<_Tp> > 233 : { 234 : typedef _Tp& __type; 235 : }; 236 : 237 : template<typename _Tp> 238 : struct __strip_reference_wrapper<const reference_wrapper<_Tp> > 239 : { 240 : typedef _Tp& __type; 241 : }; 242 : 243 : template<typename _Tp> 244 : struct __decay_and_strip 245 : { 246 : typedef typename __strip_reference_wrapper< 247 : typename decay<_Tp>::type>::__type __type; 248 : }; 249 : 250 : // NB: DR 706. 251 : template<class _T1, class _T2> 252 : inline pair<typename __decay_and_strip<_T1>::__type, 253 : typename __decay_and_strip<_T2>::__type> 254 : make_pair(_T1&& __x, _T2&& __y) 255 : { 256 : return pair<typename __decay_and_strip<_T1>::__type, 257 : typename __decay_and_strip<_T2>::__type> 258 : (std::forward<_T1>(__x), std::forward<_T2>(__y)); 259 : } 260 : #endif 261 : 262 : _GLIBCXX_END_NAMESPACE 263 : 264 : #endif /* _STL_PAIR_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Components for manipulating sequences of characters -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License along 19 : // with this library; see the file COPYING. If not, write to the Free 20 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 21 : // USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file basic_string.tcc 33 : * This is an internal header file, included by other library headers. 34 : * You should not attempt to use it directly. 35 : */ 36 : 37 : // 38 : // ISO C++ 14882: 21 Strings library 39 : // 40 : 41 : // Written by Jason Merrill based upon the specification by Takanori Adachi 42 : // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. 43 : 44 : #ifndef _BASIC_STRING_TCC 45 : #define _BASIC_STRING_TCC 1 46 : 47 : #pragma GCC system_header 48 : 49 : #include <cxxabi-forced.h> 50 : 51 : _GLIBCXX_BEGIN_NAMESPACE(std) 52 : 53 : template<typename _CharT, typename _Traits, typename _Alloc> 54 : const typename basic_string<_CharT, _Traits, _Alloc>::size_type 55 : basic_string<_CharT, _Traits, _Alloc>:: 56 : _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; 57 : 58 : template<typename _CharT, typename _Traits, typename _Alloc> 59 : const _CharT 60 : basic_string<_CharT, _Traits, _Alloc>:: 61 : _Rep::_S_terminal = _CharT(); 62 : 63 : template<typename _CharT, typename _Traits, typename _Alloc> 64 : const typename basic_string<_CharT, _Traits, _Alloc>::size_type 65 : basic_string<_CharT, _Traits, _Alloc>::npos; 66 : 67 : // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) 68 : // at static init time (before static ctors are run). 69 : template<typename _CharT, typename _Traits, typename _Alloc> 70 : typename basic_string<_CharT, _Traits, _Alloc>::size_type 71 : basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[ 72 : (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) / 73 : sizeof(size_type)]; 74 : 75 : // NB: This is the special case for Input Iterators, used in 76 : // istreambuf_iterators, etc. 77 : // Input Iterators have a cost structure very different from 78 : // pointers, calling for a different coding style. 79 : template<typename _CharT, typename _Traits, typename _Alloc> 80 : template<typename _InIterator> 81 : _CharT* 82 : basic_string<_CharT, _Traits, _Alloc>:: 83 : _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, 84 : input_iterator_tag) 85 : { 86 : #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING 87 : if (__beg == __end && __a == _Alloc()) 88 : return _S_empty_rep()._M_refdata(); 89 : #endif 90 : // Avoid reallocation for common case. 91 : _CharT __buf[128]; 92 : size_type __len = 0; 93 : while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) 94 : { 95 : __buf[__len++] = *__beg; 96 : ++__beg; 97 : } 98 : _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); 99 : _M_copy(__r->_M_refdata(), __buf, __len); 100 : try 101 : { 102 : while (__beg != __end) 103 : { 104 : if (__len == __r->_M_capacity) 105 : { 106 : // Allocate more space. 107 : _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); 108 : _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len); 109 : __r->_M_destroy(__a); 110 : __r = __another; 111 : } 112 : __r->_M_refdata()[__len++] = *__beg; 113 : ++__beg; 114 : } 115 : } 116 : catch(...) 117 : { 118 : __r->_M_destroy(__a); 119 : __throw_exception_again; 120 : } 121 : __r->_M_set_length_and_sharable(__len); 122 : return __r->_M_refdata(); 123 : } 124 : 125 : template<typename _CharT, typename _Traits, typename _Alloc> 126 : template <typename _InIterator> 127 : _CharT* 128 : basic_string<_CharT, _Traits, _Alloc>:: 129 : _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, 130 1287 : forward_iterator_tag) 131 : { 132 : #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING 133 1287 : if (__beg == __end && __a == _Alloc()) 134 0 : return _S_empty_rep()._M_refdata(); 135 : #endif 136 : // NB: Not required, but considered best practice. 137 1287 : if (__builtin_expect(__gnu_cxx::__is_null_pointer(__beg) 138 : && __beg != __end, 0)) 139 0 : __throw_logic_error(__N("basic_string::_S_construct NULL not valid")); 140 : 141 : const size_type __dnew = static_cast<size_type>(std::distance(__beg, 142 1287 : __end)); 143 : // Check for out_of_range and length_error exceptions. 144 1287 : _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); 145 : try 146 1287 : { _S_copy_chars(__r->_M_refdata(), __beg, __end); } 147 0 : catch(...) 148 : { 149 0 : __r->_M_destroy(__a); 150 0 : __throw_exception_again; 151 : } 152 1287 : __r->_M_set_length_and_sharable(__dnew); 153 1287 : return __r->_M_refdata(); 154 : } 155 : 156 : template<typename _CharT, typename _Traits, typename _Alloc> 157 : _CharT* 158 : basic_string<_CharT, _Traits, _Alloc>:: 159 : _S_construct(size_type __n, _CharT __c, const _Alloc& __a) 160 : { 161 : #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING 162 : if (__n == 0 && __a == _Alloc()) 163 : return _S_empty_rep()._M_refdata(); 164 : #endif 165 : // Check for out_of_range and length_error exceptions. 166 : _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); 167 : if (__n) 168 : _M_assign(__r->_M_refdata(), __n, __c); 169 : 170 : __r->_M_set_length_and_sharable(__n); 171 : return __r->_M_refdata(); 172 : } 173 : 174 : template<typename _CharT, typename _Traits, typename _Alloc> 175 : basic_string<_CharT, _Traits, _Alloc>:: 176 : basic_string(const basic_string& __str) 177 : : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), 178 : __str.get_allocator()), 179 : __str.get_allocator()) 180 : { } 181 : 182 : template<typename _CharT, typename _Traits, typename _Alloc> 183 : basic_string<_CharT, _Traits, _Alloc>:: 184 : basic_string(const _Alloc& __a) 185 : : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) 186 : { } 187 : 188 : template<typename _CharT, typename _Traits, typename _Alloc> 189 : basic_string<_CharT, _Traits, _Alloc>:: 190 : basic_string(const basic_string& __str, size_type __pos, size_type __n) 191 : : _M_dataplus(_S_construct(__str._M_data() 192 : + __str._M_check(__pos, 193 : "basic_string::basic_string"), 194 : __str._M_data() + __str._M_limit(__pos, __n) 195 : + __pos, _Alloc()), _Alloc()) 196 : { } 197 : 198 : template<typename _CharT, typename _Traits, typename _Alloc> 199 : basic_string<_CharT, _Traits, _Alloc>:: 200 : basic_string(const basic_string& __str, size_type __pos, 201 : size_type __n, const _Alloc& __a) 202 : : _M_dataplus(_S_construct(__str._M_data() 203 : + __str._M_check(__pos, 204 : "basic_string::basic_string"), 205 : __str._M_data() + __str._M_limit(__pos, __n) 206 : + __pos, __a), __a) 207 : { } 208 : 209 : // TBD: DPG annotate 210 : template<typename _CharT, typename _Traits, typename _Alloc> 211 : basic_string<_CharT, _Traits, _Alloc>:: 212 : basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) 213 : : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) 214 : { } 215 : 216 : // TBD: DPG annotate 217 : template<typename _CharT, typename _Traits, typename _Alloc> 218 : basic_string<_CharT, _Traits, _Alloc>:: 219 : basic_string(const _CharT* __s, const _Alloc& __a) 220 : : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) : 221 : __s + npos, __a), __a) 222 : { } 223 : 224 : template<typename _CharT, typename _Traits, typename _Alloc> 225 : basic_string<_CharT, _Traits, _Alloc>:: 226 : basic_string(size_type __n, _CharT __c, const _Alloc& __a) 227 : : _M_dataplus(_S_construct(__n, __c, __a), __a) 228 : { } 229 : 230 : // TBD: DPG annotate 231 : template<typename _CharT, typename _Traits, typename _Alloc> 232 : template<typename _InputIterator> 233 : basic_string<_CharT, _Traits, _Alloc>:: 234 1287 : basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) 235 1287 : : _M_dataplus(_S_construct(__beg, __end, __a), __a) 236 1287 : { } 237 : 238 : template<typename _CharT, typename _Traits, typename _Alloc> 239 : basic_string<_CharT, _Traits, _Alloc>& 240 : basic_string<_CharT, _Traits, _Alloc>:: 241 : assign(const basic_string& __str) 242 : { 243 : if (_M_rep() != __str._M_rep()) 244 : { 245 : // XXX MT 246 : const allocator_type __a = this->get_allocator(); 247 : _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); 248 : _M_rep()->_M_dispose(__a); 249 : _M_data(__tmp); 250 : } 251 : return *this; 252 : } 253 : 254 : template<typename _CharT, typename _Traits, typename _Alloc> 255 : basic_string<_CharT, _Traits, _Alloc>& 256 : basic_string<_CharT, _Traits, _Alloc>:: 257 : assign(const _CharT* __s, size_type __n) 258 : { 259 : __glibcxx_requires_string_len(__s, __n); 260 : _M_check_length(this->size(), __n, "basic_string::assign"); 261 : if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) 262 : return _M_replace_safe(size_type(0), this->size(), __s, __n); 263 : else 264 : { 265 : // Work in-place. 266 : const size_type __pos = __s - _M_data(); 267 : if (__pos >= __n) 268 : _M_copy(_M_data(), __s, __n); 269 : else if (__pos) 270 : _M_move(_M_data(), __s, __n); 271 : _M_rep()->_M_set_length_and_sharable(__n); 272 : return *this; 273 : } 274 : } 275 : 276 : template<typename _CharT, typename _Traits, typename _Alloc> 277 : basic_string<_CharT, _Traits, _Alloc>& 278 : basic_string<_CharT, _Traits, _Alloc>:: 279 : append(size_type __n, _CharT __c) 280 : { 281 : if (__n) 282 : { 283 : _M_check_length(size_type(0), __n, "basic_string::append"); 284 : const size_type __len = __n + this->size(); 285 : if (__len > this->capacity() || _M_rep()->_M_is_shared()) 286 : this->reserve(__len); 287 : _M_assign(_M_data() + this->size(), __n, __c); 288 : _M_rep()->_M_set_length_and_sharable(__len); 289 : } 290 : return *this; 291 : } 292 : 293 : template<typename _CharT, typename _Traits, typename _Alloc> 294 : basic_string<_CharT, _Traits, _Alloc>& 295 : basic_string<_CharT, _Traits, _Alloc>:: 296 : append(const _CharT* __s, size_type __n) 297 : { 298 : __glibcxx_requires_string_len(__s, __n); 299 : if (__n) 300 : { 301 : _M_check_length(size_type(0), __n, "basic_string::append"); 302 : const size_type __len = __n + this->size(); 303 : if (__len > this->capacity() || _M_rep()->_M_is_shared()) 304 : { 305 : if (_M_disjunct(__s)) 306 : this->reserve(__len); 307 : else 308 : { 309 : const size_type __off = __s - _M_data(); 310 : this->reserve(__len); 311 : __s = _M_data() + __off; 312 : } 313 : } 314 : _M_copy(_M_data() + this->size(), __s, __n); 315 : _M_rep()->_M_set_length_and_sharable(__len); 316 : } 317 : return *this; 318 : } 319 : 320 : template<typename _CharT, typename _Traits, typename _Alloc> 321 : basic_string<_CharT, _Traits, _Alloc>& 322 : basic_string<_CharT, _Traits, _Alloc>:: 323 : append(const basic_string& __str) 324 : { 325 : const size_type __size = __str.size(); 326 : if (__size) 327 : { 328 : const size_type __len = __size + this->size(); 329 : if (__len > this->capacity() || _M_rep()->_M_is_shared()) 330 : this->reserve(__len); 331 : _M_copy(_M_data() + this->size(), __str._M_data(), __size); 332 : _M_rep()->_M_set_length_and_sharable(__len); 333 : } 334 : return *this; 335 : } 336 : 337 : template<typename _CharT, typename _Traits, typename _Alloc> 338 : basic_string<_CharT, _Traits, _Alloc>& 339 : basic_string<_CharT, _Traits, _Alloc>:: 340 : append(const basic_string& __str, size_type __pos, size_type __n) 341 : { 342 : __str._M_check(__pos, "basic_string::append"); 343 : __n = __str._M_limit(__pos, __n); 344 : if (__n) 345 : { 346 : const size_type __len = __n + this->size(); 347 : if (__len > this->capacity() || _M_rep()->_M_is_shared()) 348 : this->reserve(__len); 349 : _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n); 350 : _M_rep()->_M_set_length_and_sharable(__len); 351 : } 352 : return *this; 353 : } 354 : 355 : template<typename _CharT, typename _Traits, typename _Alloc> 356 : basic_string<_CharT, _Traits, _Alloc>& 357 : basic_string<_CharT, _Traits, _Alloc>:: 358 : insert(size_type __pos, const _CharT* __s, size_type __n) 359 : { 360 : __glibcxx_requires_string_len(__s, __n); 361 : _M_check(__pos, "basic_string::insert"); 362 : _M_check_length(size_type(0), __n, "basic_string::insert"); 363 : if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) 364 : return _M_replace_safe(__pos, size_type(0), __s, __n); 365 : else 366 : { 367 : // Work in-place. 368 : const size_type __off = __s - _M_data(); 369 : _M_mutate(__pos, 0, __n); 370 : __s = _M_data() + __off; 371 : _CharT* __p = _M_data() + __pos; 372 : if (__s + __n <= __p) 373 : _M_copy(__p, __s, __n); 374 : else if (__s >= __p) 375 : _M_copy(__p, __s + __n, __n); 376 : else 377 : { 378 : const size_type __nleft = __p - __s; 379 : _M_copy(__p, __s, __nleft); 380 : _M_copy(__p + __nleft, __p + __n, __n - __nleft); 381 : } 382 : return *this; 383 : } 384 : } 385 : 386 : template<typename _CharT, typename _Traits, typename _Alloc> 387 : basic_string<_CharT, _Traits, _Alloc>& 388 : basic_string<_CharT, _Traits, _Alloc>:: 389 : replace(size_type __pos, size_type __n1, const _CharT* __s, 390 : size_type __n2) 391 : { 392 : __glibcxx_requires_string_len(__s, __n2); 393 : _M_check(__pos, "basic_string::replace"); 394 : __n1 = _M_limit(__pos, __n1); 395 : _M_check_length(__n1, __n2, "basic_string::replace"); 396 : bool __left; 397 : if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) 398 : return _M_replace_safe(__pos, __n1, __s, __n2); 399 : else if ((__left = __s + __n2 <= _M_data() + __pos) 400 : || _M_data() + __pos + __n1 <= __s) 401 : { 402 : // Work in-place: non-overlapping case. 403 : size_type __off = __s - _M_data(); 404 : __left ? __off : (__off += __n2 - __n1); 405 : _M_mutate(__pos, __n1, __n2); 406 : _M_copy(_M_data() + __pos, _M_data() + __off, __n2); 407 : return *this; 408 : } 409 : else 410 : { 411 : // Todo: overlapping case. 412 : const basic_string __tmp(__s, __n2); 413 : return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2); 414 : } 415 : } 416 : 417 : template<typename _CharT, typename _Traits, typename _Alloc> 418 : void 419 : basic_string<_CharT, _Traits, _Alloc>::_Rep:: 420 : _M_destroy(const _Alloc& __a) throw () 421 : { 422 : const size_type __size = sizeof(_Rep_base) + 423 : (this->_M_capacity + 1) * sizeof(_CharT); 424 : _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size); 425 : } 426 : 427 : template<typename _CharT, typename _Traits, typename _Alloc> 428 : void 429 : basic_string<_CharT, _Traits, _Alloc>:: 430 : _M_leak_hard() 431 : { 432 : #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING 433 : if (_M_rep() == &_S_empty_rep()) 434 : return; 435 : #endif 436 : if (_M_rep()->_M_is_shared()) 437 : _M_mutate(0, 0, 0); 438 : _M_rep()->_M_set_leaked(); 439 : } 440 : 441 : template<typename _CharT, typename _Traits, typename _Alloc> 442 : void 443 : basic_string<_CharT, _Traits, _Alloc>:: 444 : _M_mutate(size_type __pos, size_type __len1, size_type __len2) 445 : { 446 : const size_type __old_size = this->size(); 447 : const size_type __new_size = __old_size + __len2 - __len1; 448 : const size_type __how_much = __old_size - __pos - __len1; 449 : 450 : if (__new_size > this->capacity() || _M_rep()->_M_is_shared()) 451 : { 452 : // Must reallocate. 453 : const allocator_type __a = get_allocator(); 454 : _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a); 455 : 456 : if (__pos) 457 : _M_copy(__r->_M_refdata(), _M_data(), __pos); 458 : if (__how_much) 459 : _M_copy(__r->_M_refdata() + __pos + __len2, 460 : _M_data() + __pos + __len1, __how_much); 461 : 462 : _M_rep()->_M_dispose(__a); 463 : _M_data(__r->_M_refdata()); 464 : } 465 : else if (__how_much && __len1 != __len2) 466 : { 467 : // Work in-place. 468 : _M_move(_M_data() + __pos + __len2, 469 : _M_data() + __pos + __len1, __how_much); 470 : } 471 : _M_rep()->_M_set_length_and_sharable(__new_size); 472 : } 473 : 474 : template<typename _CharT, typename _Traits, typename _Alloc> 475 : void 476 : basic_string<_CharT, _Traits, _Alloc>:: 477 : reserve(size_type __res) 478 : { 479 : if (__res != this->capacity() || _M_rep()->_M_is_shared()) 480 : { 481 : // Make sure we don't shrink below the current size 482 : if (__res < this->size()) 483 : __res = this->size(); 484 : const allocator_type __a = get_allocator(); 485 : _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); 486 : _M_rep()->_M_dispose(__a); 487 : _M_data(__tmp); 488 : } 489 : } 490 : 491 : template<typename _CharT, typename _Traits, typename _Alloc> 492 : void 493 : basic_string<_CharT, _Traits, _Alloc>:: 494 : swap(basic_string& __s) 495 : { 496 : if (_M_rep()->_M_is_leaked()) 497 : _M_rep()->_M_set_sharable(); 498 : if (__s._M_rep()->_M_is_leaked()) 499 : __s._M_rep()->_M_set_sharable(); 500 : if (this->get_allocator() == __s.get_allocator()) 501 : { 502 : _CharT* __tmp = _M_data(); 503 : _M_data(__s._M_data()); 504 : __s._M_data(__tmp); 505 : } 506 : // The code below can usually be optimized away. 507 : else 508 : { 509 : const basic_string __tmp1(_M_ibegin(), _M_iend(), 510 : __s.get_allocator()); 511 : const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), 512 : this->get_allocator()); 513 : *this = __tmp2; 514 : __s = __tmp1; 515 : } 516 : } 517 : 518 : template<typename _CharT, typename _Traits, typename _Alloc> 519 : typename basic_string<_CharT, _Traits, _Alloc>::_Rep* 520 : basic_string<_CharT, _Traits, _Alloc>::_Rep:: 521 : _S_create(size_type __capacity, size_type __old_capacity, 522 : const _Alloc& __alloc) 523 : { 524 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 525 : // 83. String::npos vs. string::max_size() 526 : if (__capacity > _S_max_size) 527 : __throw_length_error(__N("basic_string::_S_create")); 528 : 529 : // The standard places no restriction on allocating more memory 530 : // than is strictly needed within this layer at the moment or as 531 : // requested by an explicit application call to reserve(). 532 : 533 : // Many malloc implementations perform quite poorly when an 534 : // application attempts to allocate memory in a stepwise fashion 535 : // growing each allocation size by only 1 char. Additionally, 536 : // it makes little sense to allocate less linear memory than the 537 : // natural blocking size of the malloc implementation. 538 : // Unfortunately, we would need a somewhat low-level calculation 539 : // with tuned parameters to get this perfect for any particular 540 : // malloc implementation. Fortunately, generalizations about 541 : // common features seen among implementations seems to suffice. 542 : 543 : // __pagesize need not match the actual VM page size for good 544 : // results in practice, thus we pick a common value on the low 545 : // side. __malloc_header_size is an estimate of the amount of 546 : // overhead per memory allocation (in practice seen N * sizeof 547 : // (void*) where N is 0, 2 or 4). According to folklore, 548 : // picking this value on the high side is better than 549 : // low-balling it (especially when this algorithm is used with 550 : // malloc implementations that allocate memory blocks rounded up 551 : // to a size which is a power of 2). 552 : const size_type __pagesize = 4096; 553 : const size_type __malloc_header_size = 4 * sizeof(void*); 554 : 555 : // The below implements an exponential growth policy, necessary to 556 : // meet amortized linear time requirements of the library: see 557 : // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. 558 : // It's active for allocations requiring an amount of memory above 559 : // system pagesize. This is consistent with the requirements of the 560 : // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html 561 : if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) 562 : __capacity = 2 * __old_capacity; 563 : 564 : // NB: Need an array of char_type[__capacity], plus a terminating 565 : // null char_type() element, plus enough for the _Rep data structure. 566 : // Whew. Seemingly so needy, yet so elemental. 567 : size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); 568 : 569 : const size_type __adj_size = __size + __malloc_header_size; 570 : if (__adj_size > __pagesize && __capacity > __old_capacity) 571 : { 572 : const size_type __extra = __pagesize - __adj_size % __pagesize; 573 : __capacity += __extra / sizeof(_CharT); 574 : // Never allocate a string bigger than _S_max_size. 575 : if (__capacity > _S_max_size) 576 : __capacity = _S_max_size; 577 : __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); 578 : } 579 : 580 : // NB: Might throw, but no worries about a leak, mate: _Rep() 581 : // does not throw. 582 : void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); 583 : _Rep *__p = new (__place) _Rep; 584 : __p->_M_capacity = __capacity; 585 : // ABI compatibility - 3.4.x set in _S_create both 586 : // _M_refcount and _M_length. All callers of _S_create 587 : // in basic_string.tcc then set just _M_length. 588 : // In 4.0.x and later both _M_refcount and _M_length 589 : // are initialized in the callers, unfortunately we can 590 : // have 3.4.x compiled code with _S_create callers inlined 591 : // calling 4.0.x+ _S_create. 592 : __p->_M_set_sharable(); 593 : return __p; 594 : } 595 : 596 : template<typename _CharT, typename _Traits, typename _Alloc> 597 : _CharT* 598 : basic_string<_CharT, _Traits, _Alloc>::_Rep:: 599 : _M_clone(const _Alloc& __alloc, size_type __res) 600 : { 601 : // Requested capacity of the clone. 602 : const size_type __requested_cap = this->_M_length + __res; 603 : _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, 604 : __alloc); 605 : if (this->_M_length) 606 : _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length); 607 : 608 : __r->_M_set_length_and_sharable(this->_M_length); 609 : return __r->_M_refdata(); 610 : } 611 : 612 : template<typename _CharT, typename _Traits, typename _Alloc> 613 : void 614 : basic_string<_CharT, _Traits, _Alloc>:: 615 : resize(size_type __n, _CharT __c) 616 : { 617 : const size_type __size = this->size(); 618 : _M_check_length(__size, __n, "basic_string::resize"); 619 : if (__size < __n) 620 : this->append(__n - __size, __c); 621 : else if (__n < __size) 622 : this->erase(__n); 623 : // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) 624 : } 625 : 626 : template<typename _CharT, typename _Traits, typename _Alloc> 627 : template<typename _InputIterator> 628 : basic_string<_CharT, _Traits, _Alloc>& 629 : basic_string<_CharT, _Traits, _Alloc>:: 630 : _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, 631 : _InputIterator __k2, __false_type) 632 : { 633 : const basic_string __s(__k1, __k2); 634 : const size_type __n1 = __i2 - __i1; 635 : _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch"); 636 : return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), 637 : __s.size()); 638 : } 639 : 640 : template<typename _CharT, typename _Traits, typename _Alloc> 641 : basic_string<_CharT, _Traits, _Alloc>& 642 : basic_string<_CharT, _Traits, _Alloc>:: 643 : _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, 644 : _CharT __c) 645 : { 646 : _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); 647 : _M_mutate(__pos1, __n1, __n2); 648 : if (__n2) 649 : _M_assign(_M_data() + __pos1, __n2, __c); 650 : return *this; 651 : } 652 : 653 : template<typename _CharT, typename _Traits, typename _Alloc> 654 : basic_string<_CharT, _Traits, _Alloc>& 655 : basic_string<_CharT, _Traits, _Alloc>:: 656 : _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, 657 : size_type __n2) 658 : { 659 : _M_mutate(__pos1, __n1, __n2); 660 : if (__n2) 661 : _M_copy(_M_data() + __pos1, __s, __n2); 662 : return *this; 663 : } 664 : 665 : template<typename _CharT, typename _Traits, typename _Alloc> 666 : basic_string<_CharT, _Traits, _Alloc> 667 : operator+(const _CharT* __lhs, 668 2633 : const basic_string<_CharT, _Traits, _Alloc>& __rhs) 669 : { 670 : __glibcxx_requires_string(__lhs); 671 : typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 672 : typedef typename __string_type::size_type __size_type; 673 2633 : const __size_type __len = _Traits::length(__lhs); 674 2633 : __string_type __str; 675 2633 : __str.reserve(__len + __rhs.size()); 676 2633 : __str.append(__lhs, __len); 677 2633 : __str.append(__rhs); 678 0 : return __str; 679 : } 680 : 681 : template<typename _CharT, typename _Traits, typename _Alloc> 682 : basic_string<_CharT, _Traits, _Alloc> 683 : operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) 684 : { 685 : typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 686 : typedef typename __string_type::size_type __size_type; 687 : __string_type __str; 688 : const __size_type __len = __rhs.size(); 689 : __str.reserve(__len + 1); 690 : __str.append(__size_type(1), __lhs); 691 : __str.append(__rhs); 692 : return __str; 693 : } 694 : 695 : template<typename _CharT, typename _Traits, typename _Alloc> 696 : typename basic_string<_CharT, _Traits, _Alloc>::size_type 697 : basic_string<_CharT, _Traits, _Alloc>:: 698 : copy(_CharT* __s, size_type __n, size_type __pos) const 699 : { 700 : _M_check(__pos, "basic_string::copy"); 701 : __n = _M_limit(__pos, __n); 702 : __glibcxx_requires_string_len(__s, __n); 703 : if (__n) 704 : _M_copy(__s, _M_data() + __pos, __n); 705 : // 21.3.5.7 par 3: do not append null. (good.) 706 : return __n; 707 : } 708 : 709 : template<typename _CharT, typename _Traits, typename _Alloc> 710 : typename basic_string<_CharT, _Traits, _Alloc>::size_type 711 : basic_string<_CharT, _Traits, _Alloc>:: 712 : find(const _CharT* __s, size_type __pos, size_type __n) const 713 : { 714 : __glibcxx_requires_string_len(__s, __n); 715 : const size_type __size = this->size(); 716 : const _CharT* __data = _M_data(); 717 : 718 : if (__n == 0) 719 : return __pos <= __size ? __pos : npos; 720 : 721 : if (__n <= __size) 722 : { 723 : for (; __pos <= __size - __n; ++__pos) 724 : if (traits_type::eq(__data[__pos], __s[0]) 725 : && traits_type::compare(__data + __pos + 1, 726 : __s + 1, __n - 1) == 0) 727 : return __pos; 728 : } 729 : return npos; 730 : } 731 : 732 : template<typename _CharT, typename _Traits, typename _Alloc> 733 : typename basic_string<_CharT, _Traits, _Alloc>::size_type 734 : basic_string<_CharT, _Traits, _Alloc>:: 735 : find(_CharT __c, size_type __pos) const 736 : { 737 : size_type __ret = npos; 738 : const size_type __size = this->size(); 739 : if (__pos < __size) 740 : { 741 : const _CharT* __data = _M_data(); 742 : const size_type __n = __size - __pos; 743 : const _CharT* __p = traits_type::find(__data + __pos, __n, __c); 744 : if (__p) 745 : __ret = __p - __data; 746 : } 747 : return __ret; 748 : } 749 : 750 : template<typename _CharT, typename _Traits, typename _Alloc> 751 : typename basic_string<_CharT, _Traits, _Alloc>::size_type 752 : basic_string<_CharT, _Traits, _Alloc>:: 753 : rfind(const _CharT* __s, size_type __pos, size_type __n) const 754 : { 755 : __glibcxx_requires_string_len(__s, __n); 756 : const size_type __size = this->size(); 757 : if (__n <= __size) 758 : { 759 : __pos = std::min(size_type(__size - __n), __pos); 760 : const _CharT* __data = _M_data(); 761 : do 762 : { 763 : if (traits_type::compare(__data + __pos, __s, __n) == 0) 764 : return __pos; 765 : } 766 : while (__pos-- > 0); 767 : } 768 : return npos; 769 : } 770 : 771 : template<typename _CharT, typename _Traits, typename _Alloc> 772 : typename basic_string<_CharT, _Traits, _Alloc>::size_type 773 : basic_string<_CharT, _Traits, _Alloc>:: 774 : rfind(_CharT __c, size_type __pos) const 775 : { 776 : size_type __size = this->size(); 777 : if (__size) 778 : { 779 : if (--__size > __pos) 780 : __size = __pos; 781 : for (++__size; __size-- > 0; ) 782 : if (traits_type::eq(_M_data()[__size], __c)) 783 : return __size; 784 : } 785 : return npos; 786 : } 787 : 788 : template<typename _CharT, typename _Traits, typename _Alloc> 789 : typename basic_string<_CharT, _Traits, _Alloc>::size_type 790 : basic_string<_CharT, _Traits, _Alloc>:: 791 : find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 792 : { 793 : __glibcxx_requires_string_len(__s, __n); 794 : for (; __n && __pos < this->size(); ++__pos) 795 : { 796 : const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); 797 : if (__p) 798 : return __pos; 799 : } 800 : return npos; 801 : } 802 : 803 : template<typename _CharT, typename _Traits, typename _Alloc> 804 : typename basic_string<_CharT, _Traits, _Alloc>::size_type 805 : basic_string<_CharT, _Traits, _Alloc>:: 806 : find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 807 : { 808 : __glibcxx_requires_string_len(__s, __n); 809 : size_type __size = this->size(); 810 : if (__size && __n) 811 : { 812 : if (--__size > __pos) 813 : __size = __pos; 814 : do 815 : { 816 : if (traits_type::find(__s, __n, _M_data()[__size])) 817 : return __size; 818 : } 819 : while (__size-- != 0); 820 : } 821 : return npos; 822 : } 823 : 824 : template<typename _CharT, typename _Traits, typename _Alloc> 825 : typename basic_string<_CharT, _Traits, _Alloc>::size_type 826 : basic_string<_CharT, _Traits, _Alloc>:: 827 : find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 828 : { 829 : __glibcxx_requires_string_len(__s, __n); 830 : for (; __pos < this->size(); ++__pos) 831 : if (!traits_type::find(__s, __n, _M_data()[__pos])) 832 : return __pos; 833 : return npos; 834 : } 835 : 836 : template<typename _CharT, typename _Traits, typename _Alloc> 837 : typename basic_string<_CharT, _Traits, _Alloc>::size_type 838 : basic_string<_CharT, _Traits, _Alloc>:: 839 : find_first_not_of(_CharT __c, size_type __pos) const 840 : { 841 : for (; __pos < this->size(); ++__pos) 842 : if (!traits_type::eq(_M_data()[__pos], __c)) 843 : return __pos; 844 : return npos; 845 : } 846 : 847 : template<typename _CharT, typename _Traits, typename _Alloc> 848 : typename basic_string<_CharT, _Traits, _Alloc>::size_type 849 : basic_string<_CharT, _Traits, _Alloc>:: 850 : find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 851 : { 852 : __glibcxx_requires_string_len(__s, __n); 853 : size_type __size = this->size(); 854 : if (__size) 855 : { 856 : if (--__size > __pos) 857 : __size = __pos; 858 : do 859 : { 860 : if (!traits_type::find(__s, __n, _M_data()[__size])) 861 : return __size; 862 : } 863 : while (__size--); 864 : } 865 : return npos; 866 : } 867 : 868 : template<typename _CharT, typename _Traits, typename _Alloc> 869 : typename basic_string<_CharT, _Traits, _Alloc>::size_type 870 : basic_string<_CharT, _Traits, _Alloc>:: 871 : find_last_not_of(_CharT __c, size_type __pos) const 872 : { 873 : size_type __size = this->size(); 874 : if (__size) 875 : { 876 : if (--__size > __pos) 877 : __size = __pos; 878 : do 879 : { 880 : if (!traits_type::eq(_M_data()[__size], __c)) 881 : return __size; 882 : } 883 : while (__size--); 884 : } 885 : return npos; 886 : } 887 : 888 : template<typename _CharT, typename _Traits, typename _Alloc> 889 : int 890 : basic_string<_CharT, _Traits, _Alloc>:: 891 : compare(size_type __pos, size_type __n, const basic_string& __str) const 892 : { 893 : _M_check(__pos, "basic_string::compare"); 894 : __n = _M_limit(__pos, __n); 895 : const size_type __osize = __str.size(); 896 : const size_type __len = std::min(__n, __osize); 897 : int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); 898 : if (!__r) 899 : __r = _S_compare(__n, __osize); 900 : return __r; 901 : } 902 : 903 : template<typename _CharT, typename _Traits, typename _Alloc> 904 : int 905 : basic_string<_CharT, _Traits, _Alloc>:: 906 : compare(size_type __pos1, size_type __n1, const basic_string& __str, 907 : size_type __pos2, size_type __n2) const 908 : { 909 : _M_check(__pos1, "basic_string::compare"); 910 : __str._M_check(__pos2, "basic_string::compare"); 911 : __n1 = _M_limit(__pos1, __n1); 912 : __n2 = __str._M_limit(__pos2, __n2); 913 : const size_type __len = std::min(__n1, __n2); 914 : int __r = traits_type::compare(_M_data() + __pos1, 915 : __str.data() + __pos2, __len); 916 : if (!__r) 917 : __r = _S_compare(__n1, __n2); 918 : return __r; 919 : } 920 : 921 : template<typename _CharT, typename _Traits, typename _Alloc> 922 : int 923 : basic_string<_CharT, _Traits, _Alloc>:: 924 : compare(const _CharT* __s) const 925 : { 926 : __glibcxx_requires_string(__s); 927 : const size_type __size = this->size(); 928 : const size_type __osize = traits_type::length(__s); 929 : const size_type __len = std::min(__size, __osize); 930 : int __r = traits_type::compare(_M_data(), __s, __len); 931 : if (!__r) 932 : __r = _S_compare(__size, __osize); 933 : return __r; 934 : } 935 : 936 : template<typename _CharT, typename _Traits, typename _Alloc> 937 : int 938 : basic_string <_CharT, _Traits, _Alloc>:: 939 : compare(size_type __pos, size_type __n1, const _CharT* __s) const 940 : { 941 : __glibcxx_requires_string(__s); 942 : _M_check(__pos, "basic_string::compare"); 943 : __n1 = _M_limit(__pos, __n1); 944 : const size_type __osize = traits_type::length(__s); 945 : const size_type __len = std::min(__n1, __osize); 946 : int __r = traits_type::compare(_M_data() + __pos, __s, __len); 947 : if (!__r) 948 : __r = _S_compare(__n1, __osize); 949 : return __r; 950 : } 951 : 952 : template<typename _CharT, typename _Traits, typename _Alloc> 953 : int 954 : basic_string <_CharT, _Traits, _Alloc>:: 955 : compare(size_type __pos, size_type __n1, const _CharT* __s, 956 : size_type __n2) const 957 : { 958 : __glibcxx_requires_string_len(__s, __n2); 959 : _M_check(__pos, "basic_string::compare"); 960 : __n1 = _M_limit(__pos, __n1); 961 : const size_type __len = std::min(__n1, __n2); 962 : int __r = traits_type::compare(_M_data() + __pos, __s, __len); 963 : if (!__r) 964 : __r = _S_compare(__n1, __n2); 965 : return __r; 966 : } 967 : 968 : // 21.3.7.9 basic_string::getline and operators 969 : template<typename _CharT, typename _Traits, typename _Alloc> 970 : basic_istream<_CharT, _Traits>& 971 : operator>>(basic_istream<_CharT, _Traits>& __in, 972 : basic_string<_CharT, _Traits, _Alloc>& __str) 973 : { 974 : typedef basic_istream<_CharT, _Traits> __istream_type; 975 : typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 976 : typedef typename __istream_type::ios_base __ios_base; 977 : typedef typename __istream_type::int_type __int_type; 978 : typedef typename __string_type::size_type __size_type; 979 : typedef ctype<_CharT> __ctype_type; 980 : typedef typename __ctype_type::ctype_base __ctype_base; 981 : 982 : __size_type __extracted = 0; 983 : typename __ios_base::iostate __err = __ios_base::goodbit; 984 : typename __istream_type::sentry __cerb(__in, false); 985 : if (__cerb) 986 : { 987 : try 988 : { 989 : // Avoid reallocation for common case. 990 : __str.erase(); 991 : _CharT __buf[128]; 992 : __size_type __len = 0; 993 : const streamsize __w = __in.width(); 994 : const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) 995 : : __str.max_size(); 996 : const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 997 : const __int_type __eof = _Traits::eof(); 998 : __int_type __c = __in.rdbuf()->sgetc(); 999 : 1000 : while (__extracted < __n 1001 : && !_Traits::eq_int_type(__c, __eof) 1002 : && !__ct.is(__ctype_base::space, 1003 : _Traits::to_char_type(__c))) 1004 : { 1005 : if (__len == sizeof(__buf) / sizeof(_CharT)) 1006 : { 1007 : __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 1008 : __len = 0; 1009 : } 1010 : __buf[__len++] = _Traits::to_char_type(__c); 1011 : ++__extracted; 1012 : __c = __in.rdbuf()->snextc(); 1013 : } 1014 : __str.append(__buf, __len); 1015 : 1016 : if (_Traits::eq_int_type(__c, __eof)) 1017 : __err |= __ios_base::eofbit; 1018 : __in.width(0); 1019 : } 1020 : catch(__cxxabiv1::__forced_unwind&) 1021 : { 1022 : __in._M_setstate(__ios_base::badbit); 1023 : __throw_exception_again; 1024 : } 1025 : catch(...) 1026 : { 1027 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1028 : // 91. Description of operator>> and getline() for string<> 1029 : // might cause endless loop 1030 : __in._M_setstate(__ios_base::badbit); 1031 : } 1032 : } 1033 : // 211. operator>>(istream&, string&) doesn't set failbit 1034 : if (!__extracted) 1035 : __err |= __ios_base::failbit; 1036 : if (__err) 1037 : __in.setstate(__err); 1038 : return __in; 1039 : } 1040 : 1041 : template<typename _CharT, typename _Traits, typename _Alloc> 1042 : basic_istream<_CharT, _Traits>& 1043 : getline(basic_istream<_CharT, _Traits>& __in, 1044 : basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) 1045 : { 1046 : typedef basic_istream<_CharT, _Traits> __istream_type; 1047 : typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 1048 : typedef typename __istream_type::ios_base __ios_base; 1049 : typedef typename __istream_type::int_type __int_type; 1050 : typedef typename __string_type::size_type __size_type; 1051 : 1052 : __size_type __extracted = 0; 1053 : const __size_type __n = __str.max_size(); 1054 : typename __ios_base::iostate __err = __ios_base::goodbit; 1055 : typename __istream_type::sentry __cerb(__in, true); 1056 : if (__cerb) 1057 : { 1058 : try 1059 : { 1060 : __str.erase(); 1061 : const __int_type __idelim = _Traits::to_int_type(__delim); 1062 : const __int_type __eof = _Traits::eof(); 1063 : __int_type __c = __in.rdbuf()->sgetc(); 1064 : 1065 : while (__extracted < __n 1066 : && !_Traits::eq_int_type(__c, __eof) 1067 : && !_Traits::eq_int_type(__c, __idelim)) 1068 : { 1069 : __str += _Traits::to_char_type(__c); 1070 : ++__extracted; 1071 : __c = __in.rdbuf()->snextc(); 1072 : } 1073 : 1074 : if (_Traits::eq_int_type(__c, __eof)) 1075 : __err |= __ios_base::eofbit; 1076 : else if (_Traits::eq_int_type(__c, __idelim)) 1077 : { 1078 : ++__extracted; 1079 : __in.rdbuf()->sbumpc(); 1080 : } 1081 : else 1082 : __err |= __ios_base::failbit; 1083 : } 1084 : catch(__cxxabiv1::__forced_unwind&) 1085 : { 1086 : __in._M_setstate(__ios_base::badbit); 1087 : __throw_exception_again; 1088 : } 1089 : catch(...) 1090 : { 1091 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1092 : // 91. Description of operator>> and getline() for string<> 1093 : // might cause endless loop 1094 : __in._M_setstate(__ios_base::badbit); 1095 : } 1096 : } 1097 : if (!__extracted) 1098 : __err |= __ios_base::failbit; 1099 : if (__err) 1100 : __in.setstate(__err); 1101 : return __in; 1102 : } 1103 : 1104 : // Inhibit implicit instantiations for required instantiations, 1105 : // which are defined via explicit instantiations elsewhere. 1106 : // NB: This syntax is a GNU extension. 1107 : #if _GLIBCXX_EXTERN_TEMPLATE 1108 : extern template class basic_string<char>; 1109 : extern template 1110 : basic_istream<char>& 1111 : operator>>(basic_istream<char>&, string&); 1112 : extern template 1113 : basic_ostream<char>& 1114 : operator<<(basic_ostream<char>&, const string&); 1115 : extern template 1116 : basic_istream<char>& 1117 : getline(basic_istream<char>&, string&, char); 1118 : extern template 1119 : basic_istream<char>& 1120 : getline(basic_istream<char>&, string&); 1121 : 1122 : #ifdef _GLIBCXX_USE_WCHAR_T 1123 : extern template class basic_string<wchar_t>; 1124 : extern template 1125 : basic_istream<wchar_t>& 1126 : operator>>(basic_istream<wchar_t>&, wstring&); 1127 : extern template 1128 : basic_ostream<wchar_t>& 1129 : operator<<(basic_ostream<wchar_t>&, const wstring&); 1130 : extern template 1131 : basic_istream<wchar_t>& 1132 : getline(basic_istream<wchar_t>&, wstring&, wchar_t); 1133 : extern template 1134 : basic_istream<wchar_t>& 1135 : getline(basic_istream<wchar_t>&, wstring&); 1136 : #endif 1137 : #endif 1138 : 1139 : _GLIBCXX_END_NAMESPACE 1140 : 1141 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Types used in iterator implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996-1998 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_iterator_base_types.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : * 61 : * This file contains all of the general iterator-related utility types, 62 : * such as iterator_traits and struct iterator. 63 : */ 64 : 65 : #ifndef _STL_ITERATOR_BASE_TYPES_H 66 : #define _STL_ITERATOR_BASE_TYPES_H 1 67 : 68 : #pragma GCC system_header 69 : 70 : #include <bits/c++config.h> 71 : #include <cstddef> 72 : 73 : _GLIBCXX_BEGIN_NAMESPACE(std) 74 : 75 : //@{ 76 : /** 77 : * @defgroup iterator_tags Iterator Tags 78 : * These are empty types, used to distinguish different iterators. The 79 : * distinction is not made by what they contain, but simply by what they 80 : * are. Different underlying algorithms can then be used based on the 81 : * different operations supported by different iterator types. 82 : */ 83 : /// Marking input iterators. 84 : struct input_iterator_tag {}; 85 : /// Marking output iterators. 86 : struct output_iterator_tag {}; 87 : /// Forward iterators support a superset of input iterator operations. 88 : struct forward_iterator_tag : public input_iterator_tag {}; 89 : /// Bidirectional iterators support a superset of forward iterator 90 : /// operations. 91 : struct bidirectional_iterator_tag : public forward_iterator_tag {}; 92 : /// Random-access iterators support a superset of bidirectional iterator 93 : /// operations. 94 : struct random_access_iterator_tag : public bidirectional_iterator_tag {}; 95 : //@} 96 : 97 : 98 : /** 99 : * @brief Common %iterator class. 100 : * 101 : * This class does nothing but define nested typedefs. %Iterator classes 102 : * can inherit from this class to save some work. The typedefs are then 103 : * used in specializations and overloading. 104 : * 105 : * In particular, there are no default implementations of requirements 106 : * such as @c operator++ and the like. (How could there be?) 107 : */ 108 : template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t, 109 : typename _Pointer = _Tp*, typename _Reference = _Tp&> 110 : struct iterator 111 304336 : { 112 : /// One of the @link iterator_tags tag types@endlink. 113 : typedef _Category iterator_category; 114 : /// The type "pointed to" by the iterator. 115 : typedef _Tp value_type; 116 : /// Distance between iterators is represented as this type. 117 : typedef _Distance difference_type; 118 : /// This type represents a pointer-to-value_type. 119 : typedef _Pointer pointer; 120 : /// This type represents a reference-to-value_type. 121 : typedef _Reference reference; 122 : }; 123 : 124 : /** 125 : * This class does nothing but define nested typedefs. The general 126 : * version simply "forwards" the nested typedefs from the Iterator 127 : * argument. Specialized versions for pointers and pointers-to-const 128 : * provide tighter, more correct semantics. 129 : */ 130 : template<typename _Iterator> 131 : struct iterator_traits 132 : { 133 : typedef typename _Iterator::iterator_category iterator_category; 134 : typedef typename _Iterator::value_type value_type; 135 : typedef typename _Iterator::difference_type difference_type; 136 : typedef typename _Iterator::pointer pointer; 137 : typedef typename _Iterator::reference reference; 138 : }; 139 : 140 : template<typename _Tp> 141 : struct iterator_traits<_Tp*> 142 : { 143 : typedef random_access_iterator_tag iterator_category; 144 : typedef _Tp value_type; 145 : typedef ptrdiff_t difference_type; 146 : typedef _Tp* pointer; 147 : typedef _Tp& reference; 148 : }; 149 : 150 : template<typename _Tp> 151 : struct iterator_traits<const _Tp*> 152 : { 153 : typedef random_access_iterator_tag iterator_category; 154 : typedef _Tp value_type; 155 : typedef ptrdiff_t difference_type; 156 : typedef const _Tp* pointer; 157 : typedef const _Tp& reference; 158 : }; 159 : 160 : /** 161 : * This function is not a part of the C++ standard but is syntactic 162 : * sugar for internal library use only. 163 : */ 164 : template<typename _Iter> 165 : inline typename iterator_traits<_Iter>::iterator_category 166 4730 : __iterator_category(const _Iter&) 167 4730 : { return typename iterator_traits<_Iter>::iterator_category(); } 168 : 169 : _GLIBCXX_END_NAMESPACE 170 : 171 : #endif /* _STL_ITERATOR_BASE_TYPES_H */ 172 : |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Iostreams base classes -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007, 2008 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License along 19 : // with this library; see the file COPYING. If not, write to the Free 20 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 21 : // USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file ios_base.h 33 : * This is an internal header file, included by other library headers. 34 : * You should not attempt to use it directly. 35 : */ 36 : 37 : // 38 : // ISO C++ 14882: 27.4 Iostreams base classes 39 : // 40 : 41 : #ifndef _IOS_BASE_H 42 : #define _IOS_BASE_H 1 43 : 44 : #pragma GCC system_header 45 : 46 : #include <ext/atomicity.h> 47 : #include <bits/localefwd.h> 48 : #include <bits/locale_classes.h> 49 : #include <cstdio> // For SEEK_CUR, SEEK_END 50 : 51 : _GLIBCXX_BEGIN_NAMESPACE(std) 52 : 53 : // The following definitions of bitmask types are enums, not ints, 54 : // as permitted (but not required) in the standard, in order to provide 55 : // better type safety in iostream calls. A side effect is that 56 : // expressions involving them are no longer compile-time constants. 57 : enum _Ios_Fmtflags 58 : { 59 : _S_boolalpha = 1L << 0, 60 : _S_dec = 1L << 1, 61 : _S_fixed = 1L << 2, 62 : _S_hex = 1L << 3, 63 : _S_internal = 1L << 4, 64 : _S_left = 1L << 5, 65 : _S_oct = 1L << 6, 66 : _S_right = 1L << 7, 67 : _S_scientific = 1L << 8, 68 : _S_showbase = 1L << 9, 69 : _S_showpoint = 1L << 10, 70 : _S_showpos = 1L << 11, 71 : _S_skipws = 1L << 12, 72 : _S_unitbuf = 1L << 13, 73 : _S_uppercase = 1L << 14, 74 : _S_adjustfield = _S_left | _S_right | _S_internal, 75 : _S_basefield = _S_dec | _S_oct | _S_hex, 76 : _S_floatfield = _S_scientific | _S_fixed, 77 : _S_ios_fmtflags_end = 1L << 16 78 : }; 79 : 80 : inline _Ios_Fmtflags 81 66 : operator&(_Ios_Fmtflags __a, _Ios_Fmtflags __b) 82 66 : { return _Ios_Fmtflags(static_cast<int>(__a) & static_cast<int>(__b)); } 83 : 84 : inline _Ios_Fmtflags 85 33 : operator|(_Ios_Fmtflags __a, _Ios_Fmtflags __b) 86 33 : { return _Ios_Fmtflags(static_cast<int>(__a) | static_cast<int>(__b)); } 87 : 88 : inline _Ios_Fmtflags 89 : operator^(_Ios_Fmtflags __a, _Ios_Fmtflags __b) 90 : { return _Ios_Fmtflags(static_cast<int>(__a) ^ static_cast<int>(__b)); } 91 : 92 : inline _Ios_Fmtflags& 93 33 : operator|=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) 94 33 : { return __a = __a | __b; } 95 : 96 : inline _Ios_Fmtflags& 97 33 : operator&=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) 98 33 : { return __a = __a & __b; } 99 : 100 : inline _Ios_Fmtflags& 101 : operator^=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) 102 : { return __a = __a ^ __b; } 103 : 104 : inline _Ios_Fmtflags 105 33 : operator~(_Ios_Fmtflags __a) 106 33 : { return _Ios_Fmtflags(~static_cast<int>(__a)); } 107 : 108 : 109 : enum _Ios_Openmode 110 : { 111 : _S_app = 1L << 0, 112 : _S_ate = 1L << 1, 113 : _S_bin = 1L << 2, 114 : _S_in = 1L << 3, 115 : _S_out = 1L << 4, 116 : _S_trunc = 1L << 5, 117 : _S_ios_openmode_end = 1L << 16 118 : }; 119 : 120 : inline _Ios_Openmode 121 0 : operator&(_Ios_Openmode __a, _Ios_Openmode __b) 122 0 : { return _Ios_Openmode(static_cast<int>(__a) & static_cast<int>(__b)); } 123 : 124 : inline _Ios_Openmode 125 1364 : operator|(_Ios_Openmode __a, _Ios_Openmode __b) 126 1364 : { return _Ios_Openmode(static_cast<int>(__a) | static_cast<int>(__b)); } 127 : 128 : inline _Ios_Openmode 129 : operator^(_Ios_Openmode __a, _Ios_Openmode __b) 130 : { return _Ios_Openmode(static_cast<int>(__a) ^ static_cast<int>(__b)); } 131 : 132 : inline _Ios_Openmode& 133 : operator|=(_Ios_Openmode& __a, _Ios_Openmode __b) 134 : { return __a = __a | __b; } 135 : 136 : inline _Ios_Openmode& 137 : operator&=(_Ios_Openmode& __a, _Ios_Openmode __b) 138 : { return __a = __a & __b; } 139 : 140 : inline _Ios_Openmode& 141 : operator^=(_Ios_Openmode& __a, _Ios_Openmode __b) 142 : { return __a = __a ^ __b; } 143 : 144 : inline _Ios_Openmode 145 : operator~(_Ios_Openmode __a) 146 : { return _Ios_Openmode(~static_cast<int>(__a)); } 147 : 148 : 149 : enum _Ios_Iostate 150 : { 151 : _S_goodbit = 0, 152 : _S_badbit = 1L << 0, 153 : _S_eofbit = 1L << 1, 154 : _S_failbit = 1L << 2, 155 : _S_ios_iostate_end = 1L << 16 156 : }; 157 : 158 : inline _Ios_Iostate 159 0 : operator&(_Ios_Iostate __a, _Ios_Iostate __b) 160 0 : { return _Ios_Iostate(static_cast<int>(__a) & static_cast<int>(__b)); } 161 : 162 : inline _Ios_Iostate 163 0 : operator|(_Ios_Iostate __a, _Ios_Iostate __b) 164 0 : { return _Ios_Iostate(static_cast<int>(__a) | static_cast<int>(__b)); } 165 : 166 : inline _Ios_Iostate 167 : operator^(_Ios_Iostate __a, _Ios_Iostate __b) 168 : { return _Ios_Iostate(static_cast<int>(__a) ^ static_cast<int>(__b)); } 169 : 170 : inline _Ios_Iostate& 171 : operator|=(_Ios_Iostate& __a, _Ios_Iostate __b) 172 : { return __a = __a | __b; } 173 : 174 : inline _Ios_Iostate& 175 : operator&=(_Ios_Iostate& __a, _Ios_Iostate __b) 176 : { return __a = __a & __b; } 177 : 178 : inline _Ios_Iostate& 179 : operator^=(_Ios_Iostate& __a, _Ios_Iostate __b) 180 : { return __a = __a ^ __b; } 181 : 182 : inline _Ios_Iostate 183 : operator~(_Ios_Iostate __a) 184 : { return _Ios_Iostate(~static_cast<int>(__a)); } 185 : 186 : enum _Ios_Seekdir 187 : { 188 : _S_beg = 0, 189 : _S_cur = SEEK_CUR, 190 : _S_end = SEEK_END, 191 : _S_ios_seekdir_end = 1L << 16 192 : }; 193 : 194 : // 27.4.2 Class ios_base 195 : /** 196 : * @brief The base of the I/O class hierarchy. 197 : * 198 : * This class defines everything that can be defined about I/O that does 199 : * not depend on the type of characters being input or output. Most 200 : * people will only see @c ios_base when they need to specify the full 201 : * name of the various I/O flags (e.g., the openmodes). 202 : */ 203 : class ios_base 204 : { 205 : public: 206 : 207 : // 27.4.2.1.1 Class ios_base::failure 208 : /// These are thrown to indicate problems. Doc me. 209 : class failure : public exception 210 : { 211 : public: 212 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 213 : // 48. Use of non-existent exception constructor 214 : explicit 215 : failure(const string& __str) throw(); 216 : 217 : // This declaration is not useless: 218 : // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 219 : virtual 220 : ~failure() throw(); 221 : 222 : virtual const char* 223 : what() const throw(); 224 : 225 : private: 226 : string _M_msg; 227 : }; 228 : 229 : // 27.4.2.1.2 Type ios_base::fmtflags 230 : /** 231 : * @brief This is a bitmask type. 232 : * 233 : * @c "_Ios_Fmtflags" is implementation-defined, but it is valid to 234 : * perform bitwise operations on these values and expect the Right 235 : * Thing to happen. Defined objects of type fmtflags are: 236 : * - boolalpha 237 : * - dec 238 : * - fixed 239 : * - hex 240 : * - internal 241 : * - left 242 : * - oct 243 : * - right 244 : * - scientific 245 : * - showbase 246 : * - showpoint 247 : * - showpos 248 : * - skipws 249 : * - unitbuf 250 : * - uppercase 251 : * - adjustfield 252 : * - basefield 253 : * - floatfield 254 : */ 255 : typedef _Ios_Fmtflags fmtflags; 256 : 257 : /// Insert/extract @c bool in alphabetic rather than numeric format. 258 : static const fmtflags boolalpha = _S_boolalpha; 259 : 260 : /// Converts integer input or generates integer output in decimal base. 261 : static const fmtflags dec = _S_dec; 262 : 263 : /// Generate floating-point output in fixed-point notation. 264 : static const fmtflags fixed = _S_fixed; 265 : 266 : /// Converts integer input or generates integer output in hexadecimal base. 267 : static const fmtflags hex = _S_hex; 268 : 269 : /// Adds fill characters at a designated internal point in certain 270 : /// generated output, or identical to @c right if no such point is 271 : /// designated. 272 : static const fmtflags internal = _S_internal; 273 : 274 : /// Adds fill characters on the right (final positions) of certain 275 : /// generated output. (I.e., the thing you print is flush left.) 276 : static const fmtflags left = _S_left; 277 : 278 : /// Converts integer input or generates integer output in octal base. 279 : static const fmtflags oct = _S_oct; 280 : 281 : /// Adds fill characters on the left (initial positions) of certain 282 : /// generated output. (I.e., the thing you print is flush right.) 283 : static const fmtflags right = _S_right; 284 : 285 : /// Generates floating-point output in scientific notation. 286 : static const fmtflags scientific = _S_scientific; 287 : 288 : /// Generates a prefix indicating the numeric base of generated integer 289 : /// output. 290 : static const fmtflags showbase = _S_showbase; 291 : 292 : /// Generates a decimal-point character unconditionally in generated 293 : /// floating-point output. 294 : static const fmtflags showpoint = _S_showpoint; 295 : 296 : /// Generates a + sign in non-negative generated numeric output. 297 : static const fmtflags showpos = _S_showpos; 298 : 299 : /// Skips leading white space before certain input operations. 300 : static const fmtflags skipws = _S_skipws; 301 : 302 : /// Flushes output after each output operation. 303 : static const fmtflags unitbuf = _S_unitbuf; 304 : 305 : /// Replaces certain lowercase letters with their uppercase equivalents 306 : /// in generated output. 307 : static const fmtflags uppercase = _S_uppercase; 308 : 309 : /// A mask of left|right|internal. Useful for the 2-arg form of @c setf. 310 : static const fmtflags adjustfield = _S_adjustfield; 311 : 312 : /// A mask of dec|oct|hex. Useful for the 2-arg form of @c setf. 313 : static const fmtflags basefield = _S_basefield; 314 : 315 : /// A mask of scientific|fixed. Useful for the 2-arg form of @c setf. 316 : static const fmtflags floatfield = _S_floatfield; 317 : 318 : // 27.4.2.1.3 Type ios_base::iostate 319 : /** 320 : * @brief This is a bitmask type. 321 : * 322 : * @c "_Ios_Iostate" is implementation-defined, but it is valid to 323 : * perform bitwise operations on these values and expect the Right 324 : * Thing to happen. Defined objects of type iostate are: 325 : * - badbit 326 : * - eofbit 327 : * - failbit 328 : * - goodbit 329 : */ 330 : typedef _Ios_Iostate iostate; 331 : 332 : /// Indicates a loss of integrity in an input or output sequence (such 333 : /// as an irrecoverable read error from a file). 334 : static const iostate badbit = _S_badbit; 335 : 336 : /// Indicates that an input operation reached the end of an input sequence. 337 : static const iostate eofbit = _S_eofbit; 338 : 339 : /// Indicates that an input operation failed to read the expected 340 : /// characters, or that an output operation failed to generate the 341 : /// desired characters. 342 : static const iostate failbit = _S_failbit; 343 : 344 : /// Indicates all is well. 345 : static const iostate goodbit = _S_goodbit; 346 : 347 : // 27.4.2.1.4 Type ios_base::openmode 348 : /** 349 : * @brief This is a bitmask type. 350 : * 351 : * @c "_Ios_Openmode" is implementation-defined, but it is valid to 352 : * perform bitwise operations on these values and expect the Right 353 : * Thing to happen. Defined objects of type openmode are: 354 : * - app 355 : * - ate 356 : * - binary 357 : * - in 358 : * - out 359 : * - trunc 360 : */ 361 : typedef _Ios_Openmode openmode; 362 : 363 : /// Seek to end before each write. 364 : static const openmode app = _S_app; 365 : 366 : /// Open and seek to end immediately after opening. 367 : static const openmode ate = _S_ate; 368 : 369 : /// Perform input and output in binary mode (as opposed to text mode). 370 : /// This is probably not what you think it is; see 371 : /// http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#3 and 372 : /// http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#7 for more. 373 : static const openmode binary = _S_bin; 374 : 375 : /// Open for input. Default for @c ifstream and fstream. 376 : static const openmode in = _S_in; 377 : 378 : /// Open for output. Default for @c ofstream and fstream. 379 : static const openmode out = _S_out; 380 : 381 : /// Open for input. Default for @c ofstream. 382 : static const openmode trunc = _S_trunc; 383 : 384 : // 27.4.2.1.5 Type ios_base::seekdir 385 : /** 386 : * @brief This is an enumerated type. 387 : * 388 : * @c "_Ios_Seekdir" is implementation-defined. Defined values 389 : * of type seekdir are: 390 : * - beg 391 : * - cur, equivalent to @c SEEK_CUR in the C standard library. 392 : * - end, equivalent to @c SEEK_END in the C standard library. 393 : */ 394 : typedef _Ios_Seekdir seekdir; 395 : 396 : /// Request a seek relative to the beginning of the stream. 397 : static const seekdir beg = _S_beg; 398 : 399 : /// Request a seek relative to the current position within the sequence. 400 : static const seekdir cur = _S_cur; 401 : 402 : /// Request a seek relative to the current end of the sequence. 403 : static const seekdir end = _S_end; 404 : 405 : // Annex D.6 406 : typedef int io_state; 407 : typedef int open_mode; 408 : typedef int seek_dir; 409 : 410 : typedef std::streampos streampos; 411 : typedef std::streamoff streamoff; 412 : 413 : // Callbacks; 414 : /** 415 : * @brief The set of events that may be passed to an event callback. 416 : * 417 : * erase_event is used during ~ios() and copyfmt(). imbue_event is used 418 : * during imbue(). copyfmt_event is used during copyfmt(). 419 : */ 420 : enum event 421 : { 422 : erase_event, 423 : imbue_event, 424 : copyfmt_event 425 : }; 426 : 427 : /** 428 : * @brief The type of an event callback function. 429 : * @param event One of the members of the event enum. 430 : * @param ios_base Reference to the ios_base object. 431 : * @param int The integer provided when the callback was registered. 432 : * 433 : * Event callbacks are user defined functions that get called during 434 : * several ios_base and basic_ios functions, specifically imbue(), 435 : * copyfmt(), and ~ios(). 436 : */ 437 : typedef void (*event_callback) (event, ios_base&, int); 438 : 439 : /** 440 : * @brief Add the callback __fn with parameter __index. 441 : * @param __fn The function to add. 442 : * @param __index The integer to pass to the function when invoked. 443 : * 444 : * Registers a function as an event callback with an integer parameter to 445 : * be passed to the function when invoked. Multiple copies of the 446 : * function are allowed. If there are multiple callbacks, they are 447 : * invoked in the order they were registered. 448 : */ 449 : void 450 : register_callback(event_callback __fn, int __index); 451 : 452 : protected: 453 : //@{ 454 : /** 455 : * ios_base data members (doc me) 456 : */ 457 : streamsize _M_precision; 458 : streamsize _M_width; 459 : fmtflags _M_flags; 460 : iostate _M_exception; 461 : iostate _M_streambuf_state; 462 : //@} 463 : 464 : // 27.4.2.6 Members for callbacks 465 : // 27.4.2.6 ios_base callbacks 466 : struct _Callback_list 467 : { 468 : // Data Members 469 : _Callback_list* _M_next; 470 : ios_base::event_callback _M_fn; 471 : int _M_index; 472 : _Atomic_word _M_refcount; // 0 means one reference. 473 : 474 : _Callback_list(ios_base::event_callback __fn, int __index, 475 : _Callback_list* __cb) 476 : : _M_next(__cb), _M_fn(__fn), _M_index(__index), _M_refcount(0) { } 477 : 478 : void 479 : _M_add_reference() { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); } 480 : 481 : // 0 => OK to delete. 482 : int 483 : _M_remove_reference() 484 : { return __gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1); } 485 : }; 486 : 487 : _Callback_list* _M_callbacks; 488 : 489 : void 490 : _M_call_callbacks(event __ev) throw(); 491 : 492 : void 493 : _M_dispose_callbacks(void); 494 : 495 : // 27.4.2.5 Members for iword/pword storage 496 : struct _Words 497 : { 498 : void* _M_pword; 499 : long _M_iword; 500 : _Words() : _M_pword(0), _M_iword(0) { } 501 : }; 502 : 503 : // Only for failed iword/pword calls. 504 : _Words _M_word_zero; 505 : 506 : // Guaranteed storage. 507 : // The first 5 iword and pword slots are reserved for internal use. 508 : enum { _S_local_word_size = 8 }; 509 : _Words _M_local_word[_S_local_word_size]; 510 : 511 : // Allocated storage. 512 : int _M_word_size; 513 : _Words* _M_word; 514 : 515 : _Words& 516 : _M_grow_words(int __index, bool __iword); 517 : 518 : // Members for locale and locale caching. 519 : locale _M_ios_locale; 520 : 521 : void 522 : _M_init(); 523 : 524 : public: 525 : 526 : // 27.4.2.1.6 Class ios_base::Init 527 : // Used to initialize standard streams. In theory, g++ could use 528 : // -finit-priority to order this stuff correctly without going 529 : // through these machinations. 530 : class Init 531 : { 532 : friend class ios_base; 533 : public: 534 : Init(); 535 : ~Init(); 536 : 537 : private: 538 : static _Atomic_word _S_refcount; 539 : static bool _S_synced_with_stdio; 540 : }; 541 : 542 : // [27.4.2.2] fmtflags state functions 543 : /** 544 : * @brief Access to format flags. 545 : * @return The format control flags for both input and output. 546 : */ 547 : fmtflags 548 : flags() const 549 : { return _M_flags; } 550 : 551 : /** 552 : * @brief Setting new format flags all at once. 553 : * @param fmtfl The new flags to set. 554 : * @return The previous format control flags. 555 : * 556 : * This function overwrites all the format flags with @a fmtfl. 557 : */ 558 : fmtflags 559 : flags(fmtflags __fmtfl) 560 : { 561 : fmtflags __old = _M_flags; 562 : _M_flags = __fmtfl; 563 : return __old; 564 : } 565 : 566 : /** 567 : * @brief Setting new format flags. 568 : * @param fmtfl Additional flags to set. 569 : * @return The previous format control flags. 570 : * 571 : * This function sets additional flags in format control. Flags that 572 : * were previously set remain set. 573 : */ 574 : fmtflags 575 : setf(fmtflags __fmtfl) 576 : { 577 : fmtflags __old = _M_flags; 578 : _M_flags |= __fmtfl; 579 : return __old; 580 : } 581 : 582 : /** 583 : * @brief Setting new format flags. 584 : * @param fmtfl Additional flags to set. 585 : * @param mask The flags mask for @a fmtfl. 586 : * @return The previous format control flags. 587 : * 588 : * This function clears @a mask in the format flags, then sets 589 : * @a fmtfl @c & @a mask. An example mask is @c ios_base::adjustfield. 590 : */ 591 : fmtflags 592 33 : setf(fmtflags __fmtfl, fmtflags __mask) 593 : { 594 33 : fmtflags __old = _M_flags; 595 33 : _M_flags &= ~__mask; 596 33 : _M_flags |= (__fmtfl & __mask); 597 33 : return __old; 598 : } 599 : 600 : /** 601 : * @brief Clearing format flags. 602 : * @param mask The flags to unset. 603 : * 604 : * This function clears @a mask in the format flags. 605 : */ 606 : void 607 : unsetf(fmtflags __mask) 608 : { _M_flags &= ~__mask; } 609 : 610 : /** 611 : * @brief Flags access. 612 : * @return The precision to generate on certain output operations. 613 : * 614 : * Be careful if you try to give a definition of "precision" here; see 615 : * DR 189. 616 : */ 617 : streamsize 618 : precision() const 619 : { return _M_precision; } 620 : 621 : /** 622 : * @brief Changing flags. 623 : * @param prec The new precision value. 624 : * @return The previous value of precision(). 625 : */ 626 : streamsize 627 : precision(streamsize __prec) 628 : { 629 : streamsize __old = _M_precision; 630 : _M_precision = __prec; 631 : return __old; 632 : } 633 : 634 : /** 635 : * @brief Flags access. 636 : * @return The minimum field width to generate on output operations. 637 : * 638 : * "Minimum field width" refers to the number of characters. 639 : */ 640 : streamsize 641 : width() const 642 : { return _M_width; } 643 : 644 : /** 645 : * @brief Changing flags. 646 : * @param wide The new width value. 647 : * @return The previous value of width(). 648 : */ 649 : streamsize 650 0 : width(streamsize __wide) 651 : { 652 0 : streamsize __old = _M_width; 653 0 : _M_width = __wide; 654 0 : return __old; 655 : } 656 : 657 : // [27.4.2.4] ios_base static members 658 : /** 659 : * @brief Interaction with the standard C I/O objects. 660 : * @param sync Whether to synchronize or not. 661 : * @return True if the standard streams were previously synchronized. 662 : * 663 : * The synchronization referred to is @e only that between the standard 664 : * C facilities (e.g., stdout) and the standard C++ objects (e.g., 665 : * cout). User-declared streams are unaffected. See 666 : * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#8 for more. 667 : */ 668 : static bool 669 : sync_with_stdio(bool __sync = true); 670 : 671 : // [27.4.2.3] ios_base locale functions 672 : /** 673 : * @brief Setting a new locale. 674 : * @param loc The new locale. 675 : * @return The previous locale. 676 : * 677 : * Sets the new locale for this stream, and then invokes each callback 678 : * with imbue_event. 679 : */ 680 : locale 681 : imbue(const locale& __loc); 682 : 683 : /** 684 : * @brief Locale access 685 : * @return A copy of the current locale. 686 : * 687 : * If @c imbue(loc) has previously been called, then this function 688 : * returns @c loc. Otherwise, it returns a copy of @c std::locale(), 689 : * the global C++ locale. 690 : */ 691 : locale 692 : getloc() const 693 : { return _M_ios_locale; } 694 : 695 : /** 696 : * @brief Locale access 697 : * @return A reference to the current locale. 698 : * 699 : * Like getloc above, but returns a reference instead of 700 : * generating a copy. 701 : */ 702 : const locale& 703 : _M_getloc() const 704 : { return _M_ios_locale; } 705 : 706 : // [27.4.2.5] ios_base storage functions 707 : /** 708 : * @brief Access to unique indices. 709 : * @return An integer different from all previous calls. 710 : * 711 : * This function returns a unique integer every time it is called. It 712 : * can be used for any purpose, but is primarily intended to be a unique 713 : * index for the iword and pword functions. The expectation is that an 714 : * application calls xalloc in order to obtain an index in the iword and 715 : * pword arrays that can be used without fear of conflict. 716 : * 717 : * The implementation maintains a static variable that is incremented and 718 : * returned on each invocation. xalloc is guaranteed to return an index 719 : * that is safe to use in the iword and pword arrays. 720 : */ 721 : static int 722 : xalloc() throw(); 723 : 724 : /** 725 : * @brief Access to integer array. 726 : * @param __ix Index into the array. 727 : * @return A reference to an integer associated with the index. 728 : * 729 : * The iword function provides access to an array of integers that can be 730 : * used for any purpose. The array grows as required to hold the 731 : * supplied index. All integers in the array are initialized to 0. 732 : * 733 : * The implementation reserves several indices. You should use xalloc to 734 : * obtain an index that is safe to use. Also note that since the array 735 : * can grow dynamically, it is not safe to hold onto the reference. 736 : */ 737 : long& 738 : iword(int __ix) 739 : { 740 : _Words& __word = (__ix < _M_word_size) 741 : ? _M_word[__ix] : _M_grow_words(__ix, true); 742 : return __word._M_iword; 743 : } 744 : 745 : /** 746 : * @brief Access to void pointer array. 747 : * @param __ix Index into the array. 748 : * @return A reference to a void* associated with the index. 749 : * 750 : * The pword function provides access to an array of pointers that can be 751 : * used for any purpose. The array grows as required to hold the 752 : * supplied index. All pointers in the array are initialized to 0. 753 : * 754 : * The implementation reserves several indices. You should use xalloc to 755 : * obtain an index that is safe to use. Also note that since the array 756 : * can grow dynamically, it is not safe to hold onto the reference. 757 : */ 758 : void*& 759 : pword(int __ix) 760 : { 761 : _Words& __word = (__ix < _M_word_size) 762 : ? _M_word[__ix] : _M_grow_words(__ix, false); 763 : return __word._M_pword; 764 : } 765 : 766 : // Destructor 767 : /** 768 : * Invokes each callback with erase_event. Destroys local storage. 769 : * 770 : * Note that the ios_base object for the standard streams never gets 771 : * destroyed. As a result, any callbacks registered with the standard 772 : * streams will not get invoked with erase_event (unless copyfmt is 773 : * used). 774 : */ 775 : virtual ~ios_base(); 776 : 777 : protected: 778 : ios_base(); 779 : 780 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 781 : // 50. Copy constructor and assignment operator of ios_base 782 : private: 783 : ios_base(const ios_base&); 784 : 785 : ios_base& 786 : operator=(const ios_base&); 787 : }; 788 : 789 : // [27.4.5.1] fmtflags manipulators 790 : /// Calls base.setf(ios_base::boolalpha). 791 : inline ios_base& 792 : boolalpha(ios_base& __base) 793 : { 794 : __base.setf(ios_base::boolalpha); 795 : return __base; 796 : } 797 : 798 : /// Calls base.unsetf(ios_base::boolalpha). 799 : inline ios_base& 800 : noboolalpha(ios_base& __base) 801 : { 802 : __base.unsetf(ios_base::boolalpha); 803 : return __base; 804 : } 805 : 806 : /// Calls base.setf(ios_base::showbase). 807 : inline ios_base& 808 : showbase(ios_base& __base) 809 : { 810 : __base.setf(ios_base::showbase); 811 : return __base; 812 : } 813 : 814 : /// Calls base.unsetf(ios_base::showbase). 815 : inline ios_base& 816 : noshowbase(ios_base& __base) 817 : { 818 : __base.unsetf(ios_base::showbase); 819 : return __base; 820 : } 821 : 822 : /// Calls base.setf(ios_base::showpoint). 823 : inline ios_base& 824 : showpoint(ios_base& __base) 825 : { 826 : __base.setf(ios_base::showpoint); 827 : return __base; 828 : } 829 : 830 : /// Calls base.unsetf(ios_base::showpoint). 831 : inline ios_base& 832 : noshowpoint(ios_base& __base) 833 : { 834 : __base.unsetf(ios_base::showpoint); 835 : return __base; 836 : } 837 : 838 : /// Calls base.setf(ios_base::showpos). 839 : inline ios_base& 840 : showpos(ios_base& __base) 841 : { 842 : __base.setf(ios_base::showpos); 843 : return __base; 844 : } 845 : 846 : /// Calls base.unsetf(ios_base::showpos). 847 : inline ios_base& 848 : noshowpos(ios_base& __base) 849 : { 850 : __base.unsetf(ios_base::showpos); 851 : return __base; 852 : } 853 : 854 : /// Calls base.setf(ios_base::skipws). 855 : inline ios_base& 856 : skipws(ios_base& __base) 857 : { 858 : __base.setf(ios_base::skipws); 859 : return __base; 860 : } 861 : 862 : /// Calls base.unsetf(ios_base::skipws). 863 : inline ios_base& 864 : noskipws(ios_base& __base) 865 : { 866 : __base.unsetf(ios_base::skipws); 867 : return __base; 868 : } 869 : 870 : /// Calls base.setf(ios_base::uppercase). 871 : inline ios_base& 872 : uppercase(ios_base& __base) 873 : { 874 : __base.setf(ios_base::uppercase); 875 : return __base; 876 : } 877 : 878 : /// Calls base.unsetf(ios_base::uppercase). 879 : inline ios_base& 880 : nouppercase(ios_base& __base) 881 : { 882 : __base.unsetf(ios_base::uppercase); 883 : return __base; 884 : } 885 : 886 : /// Calls base.setf(ios_base::unitbuf). 887 : inline ios_base& 888 : unitbuf(ios_base& __base) 889 : { 890 : __base.setf(ios_base::unitbuf); 891 : return __base; 892 : } 893 : 894 : /// Calls base.unsetf(ios_base::unitbuf). 895 : inline ios_base& 896 : nounitbuf(ios_base& __base) 897 : { 898 : __base.unsetf(ios_base::unitbuf); 899 : return __base; 900 : } 901 : 902 : // [27.4.5.2] adjustfield manipulators 903 : /// Calls base.setf(ios_base::internal, ios_base::adjustfield). 904 : inline ios_base& 905 33 : internal(ios_base& __base) 906 : { 907 33 : __base.setf(ios_base::internal, ios_base::adjustfield); 908 33 : return __base; 909 : } 910 : 911 : /// Calls base.setf(ios_base::left, ios_base::adjustfield). 912 : inline ios_base& 913 : left(ios_base& __base) 914 : { 915 : __base.setf(ios_base::left, ios_base::adjustfield); 916 : return __base; 917 : } 918 : 919 : /// Calls base.setf(ios_base::right, ios_base::adjustfield). 920 : inline ios_base& 921 : right(ios_base& __base) 922 : { 923 : __base.setf(ios_base::right, ios_base::adjustfield); 924 : return __base; 925 : } 926 : 927 : // [27.4.5.3] basefield manipulators 928 : /// Calls base.setf(ios_base::dec, ios_base::basefield). 929 : inline ios_base& 930 : dec(ios_base& __base) 931 : { 932 : __base.setf(ios_base::dec, ios_base::basefield); 933 : return __base; 934 : } 935 : 936 : /// Calls base.setf(ios_base::hex, ios_base::basefield). 937 : inline ios_base& 938 : hex(ios_base& __base) 939 : { 940 : __base.setf(ios_base::hex, ios_base::basefield); 941 : return __base; 942 : } 943 : 944 : /// Calls base.setf(ios_base::oct, ios_base::basefield). 945 : inline ios_base& 946 : oct(ios_base& __base) 947 : { 948 : __base.setf(ios_base::oct, ios_base::basefield); 949 : return __base; 950 : } 951 : 952 : // [27.4.5.4] floatfield manipulators 953 : /// Calls base.setf(ios_base::fixed, ios_base::floatfield). 954 : inline ios_base& 955 : fixed(ios_base& __base) 956 : { 957 : __base.setf(ios_base::fixed, ios_base::floatfield); 958 : return __base; 959 : } 960 : 961 : /// Calls base.setf(ios_base::scientific, ios_base::floatfield). 962 : inline ios_base& 963 : scientific(ios_base& __base) 964 : { 965 : __base.setf(ios_base::scientific, ios_base::floatfield); 966 : return __base; 967 : } 968 : 969 : _GLIBCXX_END_NAMESPACE 970 : 971 : #endif /* _IOS_BASE_H */ 972 : |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Move, forward and identity for C++0x + swap -*- C++ -*- 2 : 3 : // Copyright (C) 2007 Free Software Foundation, Inc. 4 : // 5 : // This file is part of the GNU ISO C++ Library. This library is free 6 : // software; you can redistribute it and/or modify it under the 7 : // terms of the GNU General Public License as published by the 8 : // Free Software Foundation; either version 2, or (at your option) 9 : // any later version. 10 : 11 : // This library is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : 16 : // You should have received a copy of the GNU General Public License along 17 : // with this library; see the file COPYING. If not, write to the Free 18 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19 : // USA. 20 : 21 : // As a special exception, you may use this file as part of a free software 22 : // library without restriction. Specifically, if other files instantiate 23 : // templates or use macros or inline functions from this file, or you compile 24 : // this file and link it with other files to produce an executable, this 25 : // file does not by itself cause the resulting executable to be covered by 26 : // the GNU General Public License. This exception does not however 27 : // invalidate any other reasons why the executable file might be covered by 28 : // the GNU General Public License. 29 : 30 : /** @file stl_move.h 31 : * This is an internal header file, included by other library headers. 32 : * You should not attempt to use it directly. 33 : */ 34 : 35 : #ifndef _STL_MOVE_H 36 : #define _STL_MOVE_H 1 37 : 38 : #include <bits/c++config.h> 39 : #include <bits/concept_check.h> 40 : 41 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 42 : #include <type_traits> 43 : 44 : _GLIBCXX_BEGIN_NAMESPACE(std) 45 : 46 : // 20.2.2, forward/move 47 : template<typename _Tp> 48 : struct identity 49 : { 50 : typedef _Tp type; 51 : }; 52 : 53 : template<typename _Tp> 54 : inline _Tp&& 55 : forward(typename std::identity<_Tp>::type&& __t) 56 : { return __t; } 57 : 58 : template<typename _Tp> 59 : inline typename std::remove_reference<_Tp>::type&& 60 : move(_Tp&& __t) 61 : { return __t; } 62 : 63 : _GLIBCXX_END_NAMESPACE 64 : 65 : #define _GLIBCXX_MOVE(_Tp) std::move(_Tp) 66 : #else 67 : #define _GLIBCXX_MOVE(_Tp) (_Tp) 68 : #endif 69 : 70 : _GLIBCXX_BEGIN_NAMESPACE(std) 71 : 72 : /** 73 : * @brief Swaps two values. 74 : * @param a A thing of arbitrary type. 75 : * @param b Another thing of arbitrary type. 76 : * @return Nothing. 77 : */ 78 : template<typename _Tp> 79 : inline void 80 7080 : swap(_Tp& __a, _Tp& __b) 81 : { 82 : // concept requirements 83 : __glibcxx_function_requires(_SGIAssignableConcept<_Tp>) 84 : 85 7080 : _Tp __tmp = _GLIBCXX_MOVE(__a); 86 7080 : __a = _GLIBCXX_MOVE(__b); 87 7080 : __b = _GLIBCXX_MOVE(__tmp); 88 7080 : } 89 : 90 : _GLIBCXX_END_NAMESPACE 91 : 92 : #endif /* _STL_MOVE_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Raw memory manipulators -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996,1997 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_uninitialized.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_UNINITIALIZED_H 63 : #define _STL_UNINITIALIZED_H 1 64 : 65 : _GLIBCXX_BEGIN_NAMESPACE(std) 66 : 67 : template<bool> 68 : struct __uninitialized_copy 69 : { 70 : template<typename _InputIterator, typename _ForwardIterator> 71 : static _ForwardIterator 72 : uninitialized_copy(_InputIterator __first, _InputIterator __last, 73 36673 : _ForwardIterator __result) 74 : { 75 36673 : _ForwardIterator __cur = __result; 76 : try 77 : { 78 84888 : for (; __first != __last; ++__first, ++__cur) 79 48215 : ::new(static_cast<void*>(&*__cur)) typename 80 : iterator_traits<_ForwardIterator>::value_type(*__first); 81 36660 : return __cur; 82 : } 83 0 : catch(...) 84 : { 85 0 : std::_Destroy(__result, __cur); 86 0 : __throw_exception_again; 87 : } 88 : } 89 : }; 90 : 91 : template<> 92 : struct __uninitialized_copy<true> 93 : { 94 : template<typename _InputIterator, typename _ForwardIterator> 95 : static _ForwardIterator 96 : uninitialized_copy(_InputIterator __first, _InputIterator __last, 97 27152 : _ForwardIterator __result) 98 27152 : { return std::copy(__first, __last, __result); } 99 : }; 100 : 101 : /** 102 : * @brief Copies the range [first,last) into result. 103 : * @param first An input iterator. 104 : * @param last An input iterator. 105 : * @param result An output iterator. 106 : * @return result + (first - last) 107 : * 108 : * Like copy(), but does not require an initialized output range. 109 : */ 110 : template<typename _InputIterator, typename _ForwardIterator> 111 : inline _ForwardIterator 112 : uninitialized_copy(_InputIterator __first, _InputIterator __last, 113 63825 : _ForwardIterator __result) 114 : { 115 : typedef typename iterator_traits<_InputIterator>::value_type 116 : _ValueType1; 117 : typedef typename iterator_traits<_ForwardIterator>::value_type 118 : _ValueType2; 119 : 120 : return std::__uninitialized_copy<(__is_pod(_ValueType1) 121 : && __is_pod(_ValueType2))>:: 122 63825 : uninitialized_copy(__first, __last, __result); 123 : } 124 : 125 : 126 : template<bool> 127 : struct __uninitialized_fill 128 : { 129 : template<typename _ForwardIterator, typename _Tp> 130 : static void 131 : uninitialized_fill(_ForwardIterator __first, 132 : _ForwardIterator __last, const _Tp& __x) 133 : { 134 : _ForwardIterator __cur = __first; 135 : try 136 : { 137 : for (; __cur != __last; ++__cur) 138 : std::_Construct(&*__cur, __x); 139 : } 140 : catch(...) 141 : { 142 : std::_Destroy(__first, __cur); 143 : __throw_exception_again; 144 : } 145 : } 146 : }; 147 : 148 : template<> 149 : struct __uninitialized_fill<true> 150 : { 151 : template<typename _ForwardIterator, typename _Tp> 152 : static void 153 : uninitialized_fill(_ForwardIterator __first, 154 : _ForwardIterator __last, const _Tp& __x) 155 : { std::fill(__first, __last, __x); } 156 : }; 157 : 158 : /** 159 : * @brief Copies the value x into the range [first,last). 160 : * @param first An input iterator. 161 : * @param last An input iterator. 162 : * @param x The source value. 163 : * @return Nothing. 164 : * 165 : * Like fill(), but does not require an initialized output range. 166 : */ 167 : template<typename _ForwardIterator, typename _Tp> 168 : inline void 169 : uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, 170 : const _Tp& __x) 171 : { 172 : typedef typename iterator_traits<_ForwardIterator>::value_type 173 : _ValueType; 174 : 175 : std::__uninitialized_fill<__is_pod(_ValueType)>:: 176 : uninitialized_fill(__first, __last, __x); 177 : } 178 : 179 : 180 : template<bool> 181 : struct __uninitialized_fill_n 182 : { 183 : template<typename _ForwardIterator, typename _Size, typename _Tp> 184 : static void 185 : uninitialized_fill_n(_ForwardIterator __first, _Size __n, 186 22443 : const _Tp& __x) 187 : { 188 22443 : _ForwardIterator __cur = __first; 189 : try 190 : { 191 46138 : for (; __n > 0; --__n, ++__cur) 192 23695 : std::_Construct(&*__cur, __x); 193 : } 194 0 : catch(...) 195 : { 196 0 : std::_Destroy(__first, __cur); 197 0 : __throw_exception_again; 198 : } 199 22443 : } 200 : }; 201 : 202 : template<> 203 : struct __uninitialized_fill_n<true> 204 : { 205 : template<typename _ForwardIterator, typename _Size, typename _Tp> 206 : static void 207 : uninitialized_fill_n(_ForwardIterator __first, _Size __n, 208 9 : const _Tp& __x) 209 9 : { std::fill_n(__first, __n, __x); } 210 : }; 211 : 212 : /** 213 : * @brief Copies the value x into the range [first,first+n). 214 : * @param first An input iterator. 215 : * @param n The number of copies to make. 216 : * @param x The source value. 217 : * @return Nothing. 218 : * 219 : * Like fill_n(), but does not require an initialized output range. 220 : */ 221 : template<typename _ForwardIterator, typename _Size, typename _Tp> 222 : inline void 223 22452 : uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 224 : { 225 : typedef typename iterator_traits<_ForwardIterator>::value_type 226 : _ValueType; 227 : 228 22452 : std::__uninitialized_fill_n<__is_pod(_ValueType)>:: 229 : uninitialized_fill_n(__first, __n, __x); 230 22452 : } 231 : 232 : // Extensions: versions of uninitialized_copy, uninitialized_fill, 233 : // and uninitialized_fill_n that take an allocator parameter. 234 : // We dispatch back to the standard versions when we're given the 235 : // default allocator. For nondefault allocators we do not use 236 : // any of the POD optimizations. 237 : 238 : template<typename _InputIterator, typename _ForwardIterator, 239 : typename _Allocator> 240 : _ForwardIterator 241 : __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 242 : _ForwardIterator __result, _Allocator& __alloc) 243 : { 244 : _ForwardIterator __cur = __result; 245 : try 246 : { 247 : for (; __first != __last; ++__first, ++__cur) 248 : __alloc.construct(&*__cur, *__first); 249 : return __cur; 250 : } 251 : catch(...) 252 : { 253 : std::_Destroy(__result, __cur, __alloc); 254 : __throw_exception_again; 255 : } 256 : } 257 : 258 : template<typename _InputIterator, typename _ForwardIterator, typename _Tp> 259 : inline _ForwardIterator 260 : __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 261 63825 : _ForwardIterator __result, allocator<_Tp>&) 262 63825 : { return std::uninitialized_copy(__first, __last, __result); } 263 : 264 : template<typename _InputIterator, typename _ForwardIterator, 265 : typename _Allocator> 266 : inline _ForwardIterator 267 : __uninitialized_move_a(_InputIterator __first, _InputIterator __last, 268 63802 : _ForwardIterator __result, _Allocator& __alloc) 269 : { 270 : return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 271 : _GLIBCXX_MAKE_MOVE_ITERATOR(__last), 272 63802 : __result, __alloc); 273 : } 274 : 275 : template<typename _ForwardIterator, typename _Tp, typename _Allocator> 276 : void 277 : __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 278 : const _Tp& __x, _Allocator& __alloc) 279 : { 280 : _ForwardIterator __cur = __first; 281 : try 282 : { 283 : for (; __cur != __last; ++__cur) 284 : __alloc.construct(&*__cur, __x); 285 : } 286 : catch(...) 287 : { 288 : std::_Destroy(__first, __cur, __alloc); 289 : __throw_exception_again; 290 : } 291 : } 292 : 293 : template<typename _ForwardIterator, typename _Tp, typename _Tp2> 294 : inline void 295 : __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 296 : const _Tp& __x, allocator<_Tp2>&) 297 : { std::uninitialized_fill(__first, __last, __x); } 298 : 299 : template<typename _ForwardIterator, typename _Size, typename _Tp, 300 : typename _Allocator> 301 : void 302 : __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 303 : const _Tp& __x, _Allocator& __alloc) 304 : { 305 : _ForwardIterator __cur = __first; 306 : try 307 : { 308 : for (; __n > 0; --__n, ++__cur) 309 : __alloc.construct(&*__cur, __x); 310 : } 311 : catch(...) 312 : { 313 : std::_Destroy(__first, __cur, __alloc); 314 : __throw_exception_again; 315 : } 316 : } 317 : 318 : template<typename _ForwardIterator, typename _Size, typename _Tp, 319 : typename _Tp2> 320 : inline void 321 : __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 322 22452 : const _Tp& __x, allocator<_Tp2>&) 323 22452 : { std::uninitialized_fill_n(__first, __n, __x); } 324 : 325 : 326 : // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, 327 : // __uninitialized_fill_move, __uninitialized_move_fill. 328 : // All of these algorithms take a user-supplied allocator, which is used 329 : // for construction and destruction. 330 : 331 : // __uninitialized_copy_move 332 : // Copies [first1, last1) into [result, result + (last1 - first1)), and 333 : // move [first2, last2) into 334 : // [result, result + (last1 - first1) + (last2 - first2)). 335 : template<typename _InputIterator1, typename _InputIterator2, 336 : typename _ForwardIterator, typename _Allocator> 337 : inline _ForwardIterator 338 : __uninitialized_copy_move(_InputIterator1 __first1, 339 : _InputIterator1 __last1, 340 : _InputIterator2 __first2, 341 : _InputIterator2 __last2, 342 : _ForwardIterator __result, 343 0 : _Allocator& __alloc) 344 : { 345 : _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, 346 : __result, 347 0 : __alloc); 348 : try 349 : { 350 0 : return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); 351 : } 352 0 : catch(...) 353 : { 354 0 : std::_Destroy(__result, __mid, __alloc); 355 0 : __throw_exception_again; 356 : } 357 : } 358 : 359 : // __uninitialized_move_copy 360 : // Moves [first1, last1) into [result, result + (last1 - first1)), and 361 : // copies [first2, last2) into 362 : // [result, result + (last1 - first1) + (last2 - first2)). 363 : template<typename _InputIterator1, typename _InputIterator2, 364 : typename _ForwardIterator, typename _Allocator> 365 : inline _ForwardIterator 366 : __uninitialized_move_copy(_InputIterator1 __first1, 367 : _InputIterator1 __last1, 368 : _InputIterator2 __first2, 369 : _InputIterator2 __last2, 370 : _ForwardIterator __result, 371 0 : _Allocator& __alloc) 372 : { 373 : _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, 374 : __result, 375 0 : __alloc); 376 : try 377 : { 378 0 : return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); 379 : } 380 0 : catch(...) 381 : { 382 0 : std::_Destroy(__result, __mid, __alloc); 383 0 : __throw_exception_again; 384 : } 385 : } 386 : 387 : // __uninitialized_fill_move 388 : // Fills [result, mid) with x, and moves [first, last) into 389 : // [mid, mid + (last - first)). 390 : template<typename _ForwardIterator, typename _Tp, typename _InputIterator, 391 : typename _Allocator> 392 : inline _ForwardIterator 393 : __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, 394 : const _Tp& __x, _InputIterator __first, 395 : _InputIterator __last, _Allocator& __alloc) 396 : { 397 : std::__uninitialized_fill_a(__result, __mid, __x, __alloc); 398 : try 399 : { 400 : return std::__uninitialized_move_a(__first, __last, __mid, __alloc); 401 : } 402 : catch(...) 403 : { 404 : std::_Destroy(__result, __mid, __alloc); 405 : __throw_exception_again; 406 : } 407 : } 408 : 409 : // __uninitialized_move_fill 410 : // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and 411 : // fills [first2 + (last1 - first1), last2) with x. 412 : template<typename _InputIterator, typename _ForwardIterator, typename _Tp, 413 : typename _Allocator> 414 : inline void 415 : __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, 416 : _ForwardIterator __first2, 417 : _ForwardIterator __last2, const _Tp& __x, 418 : _Allocator& __alloc) 419 : { 420 : _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, 421 : __first2, 422 : __alloc); 423 : try 424 : { 425 : std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); 426 : } 427 : catch(...) 428 : { 429 : std::_Destroy(__first2, __mid2, __alloc); 430 : __throw_exception_again; 431 : } 432 : } 433 : 434 : _GLIBCXX_END_NAMESPACE 435 : 436 : #endif /* _STL_UNINITIALIZED_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // RB tree implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1996,1997 34 : * Silicon Graphics Computer Systems, Inc. 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Silicon Graphics makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1994 46 : * Hewlett-Packard Company 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Hewlett-Packard Company makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : * 56 : * 57 : */ 58 : 59 : /** @file stl_tree.h 60 : * This is an internal header file, included by other library headers. 61 : * You should not attempt to use it directly. 62 : */ 63 : 64 : #ifndef _STL_TREE_H 65 : #define _STL_TREE_H 1 66 : 67 : #include <bits/stl_algobase.h> 68 : #include <bits/allocator.h> 69 : #include <bits/stl_function.h> 70 : #include <bits/cpp_type_traits.h> 71 : 72 : _GLIBCXX_BEGIN_NAMESPACE(std) 73 : 74 : // Red-black tree class, designed for use in implementing STL 75 : // associative containers (set, multiset, map, and multimap). The 76 : // insertion and deletion algorithms are based on those in Cormen, 77 : // Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 78 : // 1990), except that 79 : // 80 : // (1) the header cell is maintained with links not only to the root 81 : // but also to the leftmost node of the tree, to enable constant 82 : // time begin(), and to the rightmost node of the tree, to enable 83 : // linear time performance when used with the generic set algorithms 84 : // (set_union, etc.) 85 : // 86 : // (2) when a node being deleted has two children its successor node 87 : // is relinked into its place, rather than copied, so that the only 88 : // iterators invalidated are those referring to the deleted node. 89 : 90 : enum _Rb_tree_color { _S_red = false, _S_black = true }; 91 : 92 : struct _Rb_tree_node_base 93 : { 94 : typedef _Rb_tree_node_base* _Base_ptr; 95 : typedef const _Rb_tree_node_base* _Const_Base_ptr; 96 : 97 : _Rb_tree_color _M_color; 98 : _Base_ptr _M_parent; 99 : _Base_ptr _M_left; 100 : _Base_ptr _M_right; 101 : 102 : static _Base_ptr 103 880633 : _S_minimum(_Base_ptr __x) 104 : { 105 880633 : while (__x->_M_left != 0) __x = __x->_M_left; 106 880633 : return __x; 107 : } 108 : 109 : static _Const_Base_ptr 110 : _S_minimum(_Const_Base_ptr __x) 111 : { 112 : while (__x->_M_left != 0) __x = __x->_M_left; 113 : return __x; 114 : } 115 : 116 : static _Base_ptr 117 880633 : _S_maximum(_Base_ptr __x) 118 : { 119 880633 : while (__x->_M_right != 0) __x = __x->_M_right; 120 880633 : return __x; 121 : } 122 : 123 : static _Const_Base_ptr 124 : _S_maximum(_Const_Base_ptr __x) 125 : { 126 : while (__x->_M_right != 0) __x = __x->_M_right; 127 : return __x; 128 : } 129 : }; 130 : 131 : template<typename _Val> 132 : struct _Rb_tree_node : public _Rb_tree_node_base 133 : { 134 : typedef _Rb_tree_node<_Val>* _Link_type; 135 : _Val _M_value_field; 136 : }; 137 : 138 : _Rb_tree_node_base* 139 : _Rb_tree_increment(_Rb_tree_node_base* __x); 140 : 141 : const _Rb_tree_node_base* 142 : _Rb_tree_increment(const _Rb_tree_node_base* __x); 143 : 144 : _Rb_tree_node_base* 145 : _Rb_tree_decrement(_Rb_tree_node_base* __x); 146 : 147 : const _Rb_tree_node_base* 148 : _Rb_tree_decrement(const _Rb_tree_node_base* __x); 149 : 150 : template<typename _Tp> 151 : struct _Rb_tree_iterator 152 : { 153 : typedef _Tp value_type; 154 : typedef _Tp& reference; 155 : typedef _Tp* pointer; 156 : 157 : typedef bidirectional_iterator_tag iterator_category; 158 : typedef ptrdiff_t difference_type; 159 : 160 : typedef _Rb_tree_iterator<_Tp> _Self; 161 : typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; 162 : typedef _Rb_tree_node<_Tp>* _Link_type; 163 : 164 : _Rb_tree_iterator() 165 : : _M_node() { } 166 : 167 : explicit 168 4550329 : _Rb_tree_iterator(_Link_type __x) 169 4550329 : : _M_node(__x) { } 170 : 171 : reference 172 9593 : operator*() const 173 9593 : { return static_cast<_Link_type>(_M_node)->_M_value_field; } 174 : 175 : pointer 176 32985 : operator->() const 177 32985 : { return &static_cast<_Link_type>(_M_node)->_M_value_field; } 178 : 179 : _Self& 180 : operator++() 181 : { 182 : _M_node = _Rb_tree_increment(_M_node); 183 : return *this; 184 : } 185 : 186 : _Self 187 658 : operator++(int) 188 : { 189 658 : _Self __tmp = *this; 190 658 : _M_node = _Rb_tree_increment(_M_node); 191 : return __tmp; 192 : } 193 : 194 : _Self& 195 83333 : operator--() 196 : { 197 83333 : _M_node = _Rb_tree_decrement(_M_node); 198 83333 : return *this; 199 : } 200 : 201 : _Self 202 : operator--(int) 203 : { 204 : _Self __tmp = *this; 205 : _M_node = _Rb_tree_decrement(_M_node); 206 : return __tmp; 207 : } 208 : 209 : bool 210 638793 : operator==(const _Self& __x) const 211 638793 : { return _M_node == __x._M_node; } 212 : 213 : bool 214 749 : operator!=(const _Self& __x) const 215 749 : { return _M_node != __x._M_node; } 216 : 217 : _Base_ptr _M_node; 218 : }; 219 : 220 : template<typename _Tp> 221 : struct _Rb_tree_const_iterator 222 : { 223 : typedef _Tp value_type; 224 : typedef const _Tp& reference; 225 : typedef const _Tp* pointer; 226 : 227 : typedef _Rb_tree_iterator<_Tp> iterator; 228 : 229 : typedef bidirectional_iterator_tag iterator_category; 230 : typedef ptrdiff_t difference_type; 231 : 232 : typedef _Rb_tree_const_iterator<_Tp> _Self; 233 : typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr; 234 : typedef const _Rb_tree_node<_Tp>* _Link_type; 235 : 236 : _Rb_tree_const_iterator() 237 : : _M_node() { } 238 : 239 : explicit 240 2494703 : _Rb_tree_const_iterator(_Link_type __x) 241 2494703 : : _M_node(__x) { } 242 : 243 1643427 : _Rb_tree_const_iterator(const iterator& __it) 244 1643427 : : _M_node(__it._M_node) { } 245 : 246 : reference 247 1553025 : operator*() const 248 1553025 : { return static_cast<_Link_type>(_M_node)->_M_value_field; } 249 : 250 : pointer 251 817027 : operator->() const 252 817027 : { return &static_cast<_Link_type>(_M_node)->_M_value_field; } 253 : 254 : _Self& 255 1717591 : operator++() 256 : { 257 1717591 : _M_node = _Rb_tree_increment(_M_node); 258 1717591 : return *this; 259 : } 260 : 261 : _Self 262 9048 : operator++(int) 263 : { 264 9048 : _Self __tmp = *this; 265 9048 : _M_node = _Rb_tree_increment(_M_node); 266 : return __tmp; 267 : } 268 : 269 : _Self& 270 2000 : operator--() 271 : { 272 2000 : _M_node = _Rb_tree_decrement(_M_node); 273 2000 : return *this; 274 : } 275 : 276 : _Self 277 : operator--(int) 278 : { 279 : _Self __tmp = *this; 280 : _M_node = _Rb_tree_decrement(_M_node); 281 : return __tmp; 282 : } 283 : 284 : bool 285 177758 : operator==(const _Self& __x) const 286 177758 : { return _M_node == __x._M_node; } 287 : 288 : bool 289 2095612 : operator!=(const _Self& __x) const 290 2095612 : { return _M_node != __x._M_node; } 291 : 292 : _Base_ptr _M_node; 293 : }; 294 : 295 : template<typename _Val> 296 : inline bool 297 : operator==(const _Rb_tree_iterator<_Val>& __x, 298 : const _Rb_tree_const_iterator<_Val>& __y) 299 : { return __x._M_node == __y._M_node; } 300 : 301 : template<typename _Val> 302 : inline bool 303 : operator!=(const _Rb_tree_iterator<_Val>& __x, 304 : const _Rb_tree_const_iterator<_Val>& __y) 305 : { return __x._M_node != __y._M_node; } 306 : 307 : void 308 : _Rb_tree_insert_and_rebalance(const bool __insert_left, 309 : _Rb_tree_node_base* __x, 310 : _Rb_tree_node_base* __p, 311 : _Rb_tree_node_base& __header); 312 : 313 : _Rb_tree_node_base* 314 : _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, 315 : _Rb_tree_node_base& __header); 316 : 317 : 318 : template<typename _Key, typename _Val, typename _KeyOfValue, 319 : typename _Compare, typename _Alloc = allocator<_Val> > 320 : class _Rb_tree 321 : { 322 : typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other 323 : _Node_allocator; 324 : 325 : protected: 326 : typedef _Rb_tree_node_base* _Base_ptr; 327 : typedef const _Rb_tree_node_base* _Const_Base_ptr; 328 : 329 : public: 330 : typedef _Key key_type; 331 : typedef _Val value_type; 332 : typedef value_type* pointer; 333 : typedef const value_type* const_pointer; 334 : typedef value_type& reference; 335 : typedef const value_type& const_reference; 336 : typedef _Rb_tree_node<_Val>* _Link_type; 337 : typedef const _Rb_tree_node<_Val>* _Const_Link_type; 338 : typedef size_t size_type; 339 : typedef ptrdiff_t difference_type; 340 : typedef _Alloc allocator_type; 341 : 342 : _Node_allocator& 343 : _M_get_Node_allocator() 344 : { return *static_cast<_Node_allocator*>(&this->_M_impl); } 345 : 346 : const _Node_allocator& 347 12223942 : _M_get_Node_allocator() const 348 12223942 : { return *static_cast<const _Node_allocator*>(&this->_M_impl); } 349 : 350 : allocator_type 351 11289346 : get_allocator() const 352 11289346 : { return allocator_type(_M_get_Node_allocator()); } 353 : 354 : protected: 355 : _Link_type 356 5644688 : _M_get_node() 357 5644688 : { return _M_impl._Node_allocator::allocate(1); } 358 : 359 : void 360 5644658 : _M_put_node(_Link_type __p) 361 5644658 : { _M_impl._Node_allocator::deallocate(__p, 1); } 362 : 363 : _Link_type 364 5644688 : _M_create_node(const value_type& __x) 365 : { 366 5644688 : _Link_type __tmp = _M_get_node(); 367 : try 368 5644688 : { get_allocator().construct(&__tmp->_M_value_field, __x); } 369 0 : catch(...) 370 : { 371 0 : _M_put_node(__tmp); 372 0 : __throw_exception_again; 373 : } 374 5644688 : return __tmp; 375 : } 376 : 377 : _Link_type 378 3573982 : _M_clone_node(_Const_Link_type __x) 379 : { 380 3573982 : _Link_type __tmp = _M_create_node(__x->_M_value_field); 381 3573982 : __tmp->_M_color = __x->_M_color; 382 3573982 : __tmp->_M_left = 0; 383 3573982 : __tmp->_M_right = 0; 384 3573982 : return __tmp; 385 : } 386 : 387 : void 388 5644658 : _M_destroy_node(_Link_type __p) 389 : { 390 5644658 : get_allocator().destroy(&__p->_M_value_field); 391 5644658 : _M_put_node(__p); 392 5644658 : } 393 : 394 : protected: 395 : template<typename _Key_compare, 396 : bool _Is_pod_comparator = __is_pod(_Key_compare)> 397 : struct _Rb_tree_impl : public _Node_allocator 398 1320929 : { 399 : _Key_compare _M_key_compare; 400 : _Rb_tree_node_base _M_header; 401 : size_type _M_node_count; // Keeps track of size of tree. 402 : 403 280599 : _Rb_tree_impl() 404 : : _Node_allocator(), _M_key_compare(), _M_header(), 405 280599 : _M_node_count(0) 406 280599 : { _M_initialize(); } 407 : 408 934596 : _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a) 409 : : _Node_allocator(__a), _M_key_compare(__comp), _M_header(), 410 934596 : _M_node_count(0) 411 934596 : { _M_initialize(); } 412 : 413 : private: 414 : void 415 1215195 : _M_initialize() 416 : { 417 1215195 : this->_M_header._M_color = _S_red; 418 1215195 : this->_M_header._M_parent = 0; 419 1215195 : this->_M_header._M_left = &this->_M_header; 420 1215195 : this->_M_header._M_right = &this->_M_header; 421 1215195 : } 422 : }; 423 : 424 : _Rb_tree_impl<_Compare> _M_impl; 425 : 426 : protected: 427 : _Base_ptr& 428 2729891 : _M_root() 429 2729891 : { return this->_M_impl._M_header._M_parent; } 430 : 431 : _Const_Base_ptr 432 934693 : _M_root() const 433 934693 : { return this->_M_impl._M_header._M_parent; } 434 : 435 : _Base_ptr& 436 970809 : _M_leftmost() 437 970809 : { return this->_M_impl._M_header._M_left; } 438 : 439 : _Const_Base_ptr 440 : _M_leftmost() const 441 : { return this->_M_impl._M_header._M_left; } 442 : 443 : _Base_ptr& 444 2012568 : _M_rightmost() 445 2012568 : { return this->_M_impl._M_header._M_right; } 446 : 447 : _Const_Base_ptr 448 : _M_rightmost() const 449 : { return this->_M_impl._M_header._M_right; } 450 : 451 : _Link_type 452 3119123 : _M_begin() 453 3119123 : { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } 454 : 455 : _Const_Link_type 456 884565 : _M_begin() const 457 : { 458 : return static_cast<_Const_Link_type> 459 884565 : (this->_M_impl._M_header._M_parent); 460 : } 461 : 462 : _Link_type 463 5489610 : _M_end() 464 5489610 : { return static_cast<_Link_type>(&this->_M_impl._M_header); } 465 : 466 : _Const_Link_type 467 3932 : _M_end() const 468 3932 : { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); } 469 : 470 : static const_reference 471 7342455 : _S_value(_Const_Link_type __x) 472 7342455 : { return __x->_M_value_field; } 473 : 474 : static const _Key& 475 7342455 : _S_key(_Const_Link_type __x) 476 7342455 : { return _KeyOfValue()(_S_value(__x)); } 477 : 478 : static _Link_type 479 6468290 : _S_left(_Base_ptr __x) 480 6468290 : { return static_cast<_Link_type>(__x->_M_left); } 481 : 482 : static _Const_Link_type 483 3579867 : _S_left(_Const_Base_ptr __x) 484 3579867 : { return static_cast<_Const_Link_type>(__x->_M_left); } 485 : 486 : static _Link_type 487 12155056 : _S_right(_Base_ptr __x) 488 12155056 : { return static_cast<_Link_type>(__x->_M_right); } 489 : 490 : static _Const_Link_type 491 1503831 : _S_right(_Const_Base_ptr __x) 492 1503831 : { return static_cast<_Const_Link_type>(__x->_M_right); } 493 : 494 : static const_reference 495 3381491 : _S_value(_Const_Base_ptr __x) 496 3381491 : { return static_cast<_Const_Link_type>(__x)->_M_value_field; } 497 : 498 : static const _Key& 499 3381491 : _S_key(_Const_Base_ptr __x) 500 3381491 : { return _KeyOfValue()(_S_value(__x)); } 501 : 502 : static _Base_ptr 503 880633 : _S_minimum(_Base_ptr __x) 504 880633 : { return _Rb_tree_node_base::_S_minimum(__x); } 505 : 506 : static _Const_Base_ptr 507 : _S_minimum(_Const_Base_ptr __x) 508 : { return _Rb_tree_node_base::_S_minimum(__x); } 509 : 510 : static _Base_ptr 511 880633 : _S_maximum(_Base_ptr __x) 512 880633 : { return _Rb_tree_node_base::_S_maximum(__x); } 513 : 514 : static _Const_Base_ptr 515 : _S_maximum(_Const_Base_ptr __x) 516 : { return _Rb_tree_node_base::_S_maximum(__x); } 517 : 518 : public: 519 : typedef _Rb_tree_iterator<value_type> iterator; 520 : typedef _Rb_tree_const_iterator<value_type> const_iterator; 521 : 522 : typedef std::reverse_iterator<iterator> reverse_iterator; 523 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 524 : 525 : private: 526 : iterator 527 : _M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __y, 528 : const value_type& __v); 529 : 530 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 531 : // 233. Insertion hints in associative containers. 532 : iterator 533 : _M_insert_lower(_Base_ptr __x, _Base_ptr __y, const value_type& __v); 534 : 535 : iterator 536 : _M_insert_equal_lower(const value_type& __x); 537 : 538 : _Link_type 539 : _M_copy(_Const_Link_type __x, _Link_type __p); 540 : 541 : void 542 : _M_erase(_Link_type __x); 543 : 544 : iterator 545 : _M_lower_bound(_Link_type __x, _Link_type __y, 546 : const _Key& __k); 547 : 548 : const_iterator 549 : _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y, 550 : const _Key& __k) const; 551 : 552 : iterator 553 : _M_upper_bound(_Link_type __x, _Link_type __y, 554 : const _Key& __k); 555 : 556 : const_iterator 557 : _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y, 558 : const _Key& __k) const; 559 : 560 : public: 561 : // allocation/deallocation 562 280599 : _Rb_tree() { } 563 : 564 : _Rb_tree(const _Compare& __comp, 565 : const allocator_type& __a = allocator_type()) 566 : : _M_impl(__comp, __a) { } 567 : 568 934596 : _Rb_tree(const _Rb_tree& __x) 569 934596 : : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator()) 570 : { 571 934596 : if (__x._M_root() != 0) 572 : { 573 880580 : _M_root() = _M_copy(__x._M_begin(), _M_end()); 574 880580 : _M_leftmost() = _S_minimum(_M_root()); 575 880580 : _M_rightmost() = _S_maximum(_M_root()); 576 880580 : _M_impl._M_node_count = __x._M_impl._M_node_count; 577 : } 578 934596 : } 579 : 580 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 581 : _Rb_tree(_Rb_tree&& __x); 582 : #endif 583 : 584 1320929 : ~_Rb_tree() 585 1320929 : { _M_erase(_M_begin()); } 586 : 587 : _Rb_tree& 588 : operator=(const _Rb_tree& __x); 589 : 590 : // Accessors. 591 : _Compare 592 3296 : key_comp() const 593 3296 : { return _M_impl._M_key_compare; } 594 : 595 : iterator 596 538878 : begin() 597 : { 598 : return iterator(static_cast<_Link_type> 599 538878 : (this->_M_impl._M_header._M_left)); 600 : } 601 : 602 : const_iterator 603 468185 : begin() const 604 : { 605 : return const_iterator(static_cast<_Const_Link_type> 606 468185 : (this->_M_impl._M_header._M_left)); 607 : } 608 : 609 : iterator 610 230534 : end() 611 230534 : { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); } 612 : 613 : const_iterator 614 2022586 : end() const 615 : { 616 : return const_iterator(static_cast<_Const_Link_type> 617 2022586 : (&this->_M_impl._M_header)); 618 : } 619 : 620 : reverse_iterator 621 : rbegin() 622 : { return reverse_iterator(end()); } 623 : 624 : const_reverse_iterator 625 32 : rbegin() const 626 32 : { return const_reverse_iterator(end()); } 627 : 628 : reverse_iterator 629 : rend() 630 : { return reverse_iterator(begin()); } 631 : 632 : const_reverse_iterator 633 : rend() const 634 : { return const_reverse_iterator(begin()); } 635 : 636 : bool 637 342325 : empty() const 638 342325 : { return _M_impl._M_node_count == 0; } 639 : 640 : size_type 641 734435 : size() const 642 734435 : { return _M_impl._M_node_count; } 643 : 644 : size_type 645 : max_size() const 646 : { return get_allocator().max_size(); } 647 : 648 : void 649 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 650 : swap(_Rb_tree&& __t); 651 : #else 652 : swap(_Rb_tree& __t); 653 : #endif 654 : 655 : // Insert/erase. 656 : pair<iterator, bool> 657 : _M_insert_unique(const value_type& __x); 658 : 659 : iterator 660 : _M_insert_equal(const value_type& __x); 661 : 662 : iterator 663 : _M_insert_unique_(const_iterator __position, const value_type& __x); 664 : 665 : iterator 666 : _M_insert_equal_(const_iterator __position, const value_type& __x); 667 : 668 : template<typename _InputIterator> 669 : void 670 : _M_insert_unique(_InputIterator __first, _InputIterator __last); 671 : 672 : template<typename _InputIterator> 673 : void 674 : _M_insert_equal(_InputIterator __first, _InputIterator __last); 675 : 676 : void 677 : erase(iterator __position); 678 : 679 : void 680 : erase(const_iterator __position); 681 : 682 : size_type 683 : erase(const key_type& __x); 684 : 685 : void 686 : erase(iterator __first, iterator __last); 687 : 688 : void 689 : erase(const_iterator __first, const_iterator __last); 690 : 691 : void 692 : erase(const key_type* __first, const key_type* __last); 693 : 694 : void 695 87992 : clear() 696 : { 697 87992 : _M_erase(_M_begin()); 698 87992 : _M_leftmost() = _M_end(); 699 87992 : _M_root() = 0; 700 87992 : _M_rightmost() = _M_end(); 701 87992 : _M_impl._M_node_count = 0; 702 87992 : } 703 : 704 : // Set operations. 705 : iterator 706 : find(const key_type& __k); 707 : 708 : const_iterator 709 : find(const key_type& __k) const; 710 : 711 : size_type 712 : count(const key_type& __k) const; 713 : 714 : iterator 715 6297 : lower_bound(const key_type& __k) 716 6297 : { return _M_lower_bound(_M_begin(), _M_end(), __k); } 717 : 718 : const_iterator 719 : lower_bound(const key_type& __k) const 720 : { return _M_lower_bound(_M_begin(), _M_end(), __k); } 721 : 722 : iterator 723 : upper_bound(const key_type& __k) 724 : { return _M_upper_bound(_M_begin(), _M_end(), __k); } 725 : 726 : const_iterator 727 : upper_bound(const key_type& __k) const 728 : { return _M_upper_bound(_M_begin(), _M_end(), __k); } 729 : 730 : pair<iterator, iterator> 731 : equal_range(const key_type& __k); 732 : 733 : pair<const_iterator, const_iterator> 734 : equal_range(const key_type& __k) const; 735 : 736 : // Debugging. 737 : bool 738 : __rb_verify() const; 739 : }; 740 : 741 : template<typename _Key, typename _Val, typename _KeyOfValue, 742 : typename _Compare, typename _Alloc> 743 : inline bool 744 : operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 745 4 : const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 746 : { 747 : return __x.size() == __y.size() 748 4 : && std::equal(__x.begin(), __x.end(), __y.begin()); 749 : } 750 : 751 : template<typename _Key, typename _Val, typename _KeyOfValue, 752 : typename _Compare, typename _Alloc> 753 : inline bool 754 : operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 755 : const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 756 : { 757 : return std::lexicographical_compare(__x.begin(), __x.end(), 758 : __y.begin(), __y.end()); 759 : } 760 : 761 : template<typename _Key, typename _Val, typename _KeyOfValue, 762 : typename _Compare, typename _Alloc> 763 : inline bool 764 : operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 765 : const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 766 : { return !(__x == __y); } 767 : 768 : template<typename _Key, typename _Val, typename _KeyOfValue, 769 : typename _Compare, typename _Alloc> 770 : inline bool 771 : operator>(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 772 : const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 773 : { return __y < __x; } 774 : 775 : template<typename _Key, typename _Val, typename _KeyOfValue, 776 : typename _Compare, typename _Alloc> 777 : inline bool 778 : operator<=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 779 : const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 780 : { return !(__y < __x); } 781 : 782 : template<typename _Key, typename _Val, typename _KeyOfValue, 783 : typename _Compare, typename _Alloc> 784 : inline bool 785 : operator>=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 786 : const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 787 : { return !(__x < __y); } 788 : 789 : template<typename _Key, typename _Val, typename _KeyOfValue, 790 : typename _Compare, typename _Alloc> 791 : inline void 792 : swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, 793 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) 794 : { __x.swap(__y); } 795 : 796 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 797 : template<typename _Key, typename _Val, typename _KeyOfValue, 798 : typename _Compare, typename _Alloc> 799 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 800 : _Rb_tree(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __x) 801 : : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator()) 802 : { 803 : if (__x._M_root() != 0) 804 : { 805 : _M_root() = __x._M_root(); 806 : _M_leftmost() = __x._M_leftmost(); 807 : _M_rightmost() = __x._M_rightmost(); 808 : _M_root()->_M_parent = _M_end(); 809 : 810 : __x._M_root() = 0; 811 : __x._M_leftmost() = __x._M_end(); 812 : __x._M_rightmost() = __x._M_end(); 813 : 814 : this->_M_impl._M_node_count = __x._M_impl._M_node_count; 815 : __x._M_impl._M_node_count = 0; 816 : } 817 : } 818 : #endif 819 : 820 : template<typename _Key, typename _Val, typename _KeyOfValue, 821 : typename _Compare, typename _Alloc> 822 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& 823 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 824 97 : operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x) 825 : { 826 97 : if (this != &__x) 827 : { 828 : // Note that _Key may be a constant type. 829 97 : clear(); 830 97 : _M_impl._M_key_compare = __x._M_impl._M_key_compare; 831 97 : if (__x._M_root() != 0) 832 : { 833 53 : _M_root() = _M_copy(__x._M_begin(), _M_end()); 834 53 : _M_leftmost() = _S_minimum(_M_root()); 835 53 : _M_rightmost() = _S_maximum(_M_root()); 836 53 : _M_impl._M_node_count = __x._M_impl._M_node_count; 837 : } 838 : } 839 97 : return *this; 840 : } 841 : 842 : template<typename _Key, typename _Val, typename _KeyOfValue, 843 : typename _Compare, typename _Alloc> 844 : typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 845 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 846 2070706 : _M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __p, const _Val& __v) 847 : { 848 : bool __insert_left = (__x != 0 || __p == _M_end() 849 : || _M_impl._M_key_compare(_KeyOfValue()(__v), 850 2070706 : _S_key(__p))); 851 : 852 2070706 : _Link_type __z = _M_create_node(__v); 853 : 854 2070706 : _Rb_tree_insert_and_rebalance(__insert_left, __z, 855 : const_cast<_Base_ptr>(__p), 856 : this->_M_impl._M_header); 857 2070706 : ++_M_impl._M_node_count; 858 2070706 : return iterator(__z); 859 : } 860 : 861 : template<typename _Key, typename _Val, typename _KeyOfValue, 862 : typename _Compare, typename _Alloc> 863 : typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 864 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 865 : _M_insert_lower(_Base_ptr __x, _Base_ptr __p, const _Val& __v) 866 : { 867 : bool __insert_left = (__x != 0 || __p == _M_end() 868 : || !_M_impl._M_key_compare(_S_key(__p), 869 : _KeyOfValue()(__v))); 870 : 871 : _Link_type __z = _M_create_node(__v); 872 : 873 : _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, 874 : this->_M_impl._M_header); 875 : ++_M_impl._M_node_count; 876 : return iterator(__z); 877 : } 878 : 879 : template<typename _Key, typename _Val, typename _KeyOfValue, 880 : typename _Compare, typename _Alloc> 881 : typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 882 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 883 : _M_insert_equal_lower(const _Val& __v) 884 : { 885 : _Link_type __x = _M_begin(); 886 : _Link_type __y = _M_end(); 887 : while (__x != 0) 888 : { 889 : __y = __x; 890 : __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ? 891 : _S_left(__x) : _S_right(__x); 892 : } 893 : return _M_insert_lower(__x, __y, __v); 894 : } 895 : 896 : template<typename _Key, typename _Val, typename _KoV, 897 : typename _Compare, typename _Alloc> 898 : typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type 899 : _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>:: 900 2381075 : _M_copy(_Const_Link_type __x, _Link_type __p) 901 : { 902 : // Structural copy. __x and __p must be non-null. 903 2381075 : _Link_type __top = _M_clone_node(__x); 904 2381075 : __top->_M_parent = __p; 905 : 906 : try 907 : { 908 2381075 : if (__x->_M_right) 909 1355924 : __top->_M_right = _M_copy(_S_right(__x), __top); 910 2381075 : __p = __top; 911 2381075 : __x = _S_left(__x); 912 : 913 5955057 : while (__x != 0) 914 : { 915 1192907 : _Link_type __y = _M_clone_node(__x); 916 1192907 : __p->_M_left = __y; 917 1192907 : __y->_M_parent = __p; 918 1192907 : if (__x->_M_right) 919 144518 : __y->_M_right = _M_copy(_S_right(__x), __y); 920 1192907 : __p = __y; 921 1192907 : __x = _S_left(__x); 922 : } 923 : } 924 0 : catch(...) 925 : { 926 0 : _M_erase(__top); 927 0 : __throw_exception_again; 928 : } 929 2381075 : return __top; 930 : } 931 : 932 : template<typename _Key, typename _Val, typename _KeyOfValue, 933 : typename _Compare, typename _Alloc> 934 : void 935 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 936 7053477 : _M_erase(_Link_type __x) 937 : { 938 : // Erase without rebalancing. 939 19751483 : while (__x != 0) 940 : { 941 5644529 : _M_erase(_S_right(__x)); 942 5644529 : _Link_type __y = _S_left(__x); 943 5644529 : _M_destroy_node(__x); 944 5644529 : __x = __y; 945 : } 946 7053477 : } 947 : 948 : template<typename _Key, typename _Val, typename _KeyOfValue, 949 : typename _Compare, typename _Alloc> 950 : typename _Rb_tree<_Key, _Val, _KeyOfValue, 951 : _Compare, _Alloc>::iterator 952 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 953 : _M_lower_bound(_Link_type __x, _Link_type __y, 954 56455 : const _Key& __k) 955 : { 956 956283 : while (__x != 0) 957 843373 : if (!_M_impl._M_key_compare(_S_key(__x), __k)) 958 159236 : __y = __x, __x = _S_left(__x); 959 : else 960 684137 : __x = _S_right(__x); 961 56455 : return iterator(__y); 962 : } 963 : 964 : template<typename _Key, typename _Val, typename _KeyOfValue, 965 : typename _Compare, typename _Alloc> 966 : typename _Rb_tree<_Key, _Val, _KeyOfValue, 967 : _Compare, _Alloc>::const_iterator 968 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 969 : _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y, 970 3932 : const _Key& __k) const 971 : { 972 16029 : while (__x != 0) 973 8165 : if (!_M_impl._M_key_compare(_S_key(__x), __k)) 974 5885 : __y = __x, __x = _S_left(__x); 975 : else 976 2280 : __x = _S_right(__x); 977 3932 : return const_iterator(__y); 978 : } 979 : 980 : template<typename _Key, typename _Val, typename _KeyOfValue, 981 : typename _Compare, typename _Alloc> 982 : typename _Rb_tree<_Key, _Val, _KeyOfValue, 983 : _Compare, _Alloc>::iterator 984 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 985 : _M_upper_bound(_Link_type __x, _Link_type __y, 986 2 : const _Key& __k) 987 : { 988 4 : while (__x != 0) 989 0 : if (_M_impl._M_key_compare(__k, _S_key(__x))) 990 0 : __y = __x, __x = _S_left(__x); 991 : else 992 0 : __x = _S_right(__x); 993 2 : return iterator(__y); 994 : } 995 : 996 : template<typename _Key, typename _Val, typename _KeyOfValue, 997 : typename _Compare, typename _Alloc> 998 : typename _Rb_tree<_Key, _Val, _KeyOfValue, 999 : _Compare, _Alloc>::const_iterator 1000 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1001 : _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y, 1002 : const _Key& __k) const 1003 : { 1004 : while (__x != 0) 1005 : if (_M_impl._M_key_compare(__k, _S_key(__x))) 1006 : __y = __x, __x = _S_left(__x); 1007 : else 1008 : __x = _S_right(__x); 1009 : return const_iterator(__y); 1010 : } 1011 : 1012 : template<typename _Key, typename _Val, typename _KeyOfValue, 1013 : typename _Compare, typename _Alloc> 1014 : pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, 1015 : _Compare, _Alloc>::iterator, 1016 : typename _Rb_tree<_Key, _Val, _KeyOfValue, 1017 : _Compare, _Alloc>::iterator> 1018 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1019 9 : equal_range(const _Key& __k) 1020 : { 1021 9 : _Link_type __x = _M_begin(); 1022 9 : _Link_type __y = _M_end(); 1023 20 : while (__x != 0) 1024 : { 1025 4 : if (_M_impl._M_key_compare(_S_key(__x), __k)) 1026 0 : __x = _S_right(__x); 1027 4 : else if (_M_impl._M_key_compare(__k, _S_key(__x))) 1028 2 : __y = __x, __x = _S_left(__x); 1029 : else 1030 : { 1031 2 : _Link_type __xu(__x), __yu(__y); 1032 2 : __y = __x, __x = _S_left(__x); 1033 2 : __xu = _S_right(__xu); 1034 : return pair<iterator, 1035 : iterator>(_M_lower_bound(__x, __y, __k), 1036 2 : _M_upper_bound(__xu, __yu, __k)); 1037 : } 1038 : } 1039 : return pair<iterator, iterator>(iterator(__y), 1040 7 : iterator(__y)); 1041 : } 1042 : 1043 : template<typename _Key, typename _Val, typename _KeyOfValue, 1044 : typename _Compare, typename _Alloc> 1045 : pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, 1046 : _Compare, _Alloc>::const_iterator, 1047 : typename _Rb_tree<_Key, _Val, _KeyOfValue, 1048 : _Compare, _Alloc>::const_iterator> 1049 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1050 : equal_range(const _Key& __k) const 1051 : { 1052 : _Const_Link_type __x = _M_begin(); 1053 : _Const_Link_type __y = _M_end(); 1054 : while (__x != 0) 1055 : { 1056 : if (_M_impl._M_key_compare(_S_key(__x), __k)) 1057 : __x = _S_right(__x); 1058 : else if (_M_impl._M_key_compare(__k, _S_key(__x))) 1059 : __y = __x, __x = _S_left(__x); 1060 : else 1061 : { 1062 : _Const_Link_type __xu(__x), __yu(__y); 1063 : __y = __x, __x = _S_left(__x); 1064 : __xu = _S_right(__xu); 1065 : return pair<const_iterator, 1066 : const_iterator>(_M_lower_bound(__x, __y, __k), 1067 : _M_upper_bound(__xu, __yu, __k)); 1068 : } 1069 : } 1070 : return pair<const_iterator, const_iterator>(const_iterator(__y), 1071 : const_iterator(__y)); 1072 : } 1073 : 1074 : template<typename _Key, typename _Val, typename _KeyOfValue, 1075 : typename _Compare, typename _Alloc> 1076 : void 1077 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1078 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1079 : swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __t) 1080 : #else 1081 : swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t) 1082 : #endif 1083 : { 1084 : if (_M_root() == 0) 1085 : { 1086 : if (__t._M_root() != 0) 1087 : { 1088 : _M_root() = __t._M_root(); 1089 : _M_leftmost() = __t._M_leftmost(); 1090 : _M_rightmost() = __t._M_rightmost(); 1091 : _M_root()->_M_parent = _M_end(); 1092 : 1093 : __t._M_root() = 0; 1094 : __t._M_leftmost() = __t._M_end(); 1095 : __t._M_rightmost() = __t._M_end(); 1096 : } 1097 : } 1098 : else if (__t._M_root() == 0) 1099 : { 1100 : __t._M_root() = _M_root(); 1101 : __t._M_leftmost() = _M_leftmost(); 1102 : __t._M_rightmost() = _M_rightmost(); 1103 : __t._M_root()->_M_parent = __t._M_end(); 1104 : 1105 : _M_root() = 0; 1106 : _M_leftmost() = _M_end(); 1107 : _M_rightmost() = _M_end(); 1108 : } 1109 : else 1110 : { 1111 : std::swap(_M_root(),__t._M_root()); 1112 : std::swap(_M_leftmost(),__t._M_leftmost()); 1113 : std::swap(_M_rightmost(),__t._M_rightmost()); 1114 : 1115 : _M_root()->_M_parent = _M_end(); 1116 : __t._M_root()->_M_parent = __t._M_end(); 1117 : } 1118 : // No need to swap header's color as it does not change. 1119 : std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count); 1120 : std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare); 1121 : 1122 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1123 : // 431. Swapping containers with unequal allocators. 1124 : std::__alloc_swap<_Node_allocator>:: 1125 : _S_do_it(_M_get_Node_allocator(), __t._M_get_Node_allocator()); 1126 : } 1127 : 1128 : template<typename _Key, typename _Val, typename _KeyOfValue, 1129 : typename _Compare, typename _Alloc> 1130 : pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, 1131 : _Compare, _Alloc>::iterator, bool> 1132 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1133 1653740 : _M_insert_unique(const _Val& __v) 1134 : { 1135 1653740 : _Link_type __x = _M_begin(); 1136 1653740 : _Link_type __y = _M_end(); 1137 1653740 : bool __comp = true; 1138 9798389 : while (__x != 0) 1139 : { 1140 6490909 : __y = __x; 1141 6490909 : __comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)); 1142 6490909 : __x = __comp ? _S_left(__x) : _S_right(__x); 1143 : } 1144 1653740 : iterator __j = iterator(__y); 1145 1653740 : if (__comp) 1146 : { 1147 536188 : if (__j == begin()) 1148 452855 : return pair<iterator, bool>(_M_insert_(__x, __y, __v), true); 1149 : else 1150 83333 : --__j; 1151 : } 1152 1200885 : if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) 1153 1095156 : return pair<iterator, bool>(_M_insert_(__x, __y, __v), true); 1154 105729 : return pair<iterator, bool>(__j, false); 1155 : } 1156 : 1157 : template<typename _Key, typename _Val, typename _KeyOfValue, 1158 : typename _Compare, typename _Alloc> 1159 : typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 1160 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1161 : _M_insert_equal(const _Val& __v) 1162 : { 1163 : _Link_type __x = _M_begin(); 1164 : _Link_type __y = _M_end(); 1165 : while (__x != 0) 1166 : { 1167 : __y = __x; 1168 : __x = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? 1169 : _S_left(__x) : _S_right(__x); 1170 : } 1171 : return _M_insert_(__x, __y, __v); 1172 : } 1173 : 1174 : template<typename _Key, typename _Val, typename _KeyOfValue, 1175 : typename _Compare, typename _Alloc> 1176 : typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 1177 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1178 652700 : _M_insert_unique_(const_iterator __position, const _Val& __v) 1179 : { 1180 : // end() 1181 652700 : if (__position._M_node == _M_end()) 1182 : { 1183 649758 : if (size() > 0 1184 : && _M_impl._M_key_compare(_S_key(_M_rightmost()), 1185 : _KeyOfValue()(__v))) 1186 521501 : return _M_insert_(0, _M_rightmost(), __v); 1187 : else 1188 128257 : return _M_insert_unique(__v).first; 1189 : } 1190 2942 : else if (_M_impl._M_key_compare(_KeyOfValue()(__v), 1191 : _S_key(__position._M_node))) 1192 : { 1193 : // First, try before... 1194 2040 : const_iterator __before = __position; 1195 2040 : if (__position._M_node == _M_leftmost()) // begin() 1196 72 : return _M_insert_(_M_leftmost(), _M_leftmost(), __v); 1197 1968 : else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), 1198 : _KeyOfValue()(__v))) 1199 : { 1200 1101 : if (_S_right(__before._M_node) == 0) 1201 562 : return _M_insert_(0, __before._M_node, __v); 1202 : else 1203 : return _M_insert_(__position._M_node, 1204 539 : __position._M_node, __v); 1205 : } 1206 : else 1207 867 : return _M_insert_unique(__v).first; 1208 : } 1209 902 : else if (_M_impl._M_key_compare(_S_key(__position._M_node), 1210 : _KeyOfValue()(__v))) 1211 : { 1212 : // ... then try after. 1213 902 : const_iterator __after = __position; 1214 902 : if (__position._M_node == _M_rightmost()) 1215 13 : return _M_insert_(0, _M_rightmost(), __v); 1216 889 : else if (_M_impl._M_key_compare(_KeyOfValue()(__v), 1217 : _S_key((++__after)._M_node))) 1218 : { 1219 8 : if (_S_right(__position._M_node) == 0) 1220 4 : return _M_insert_(0, __position._M_node, __v); 1221 : else 1222 4 : return _M_insert_(__after._M_node, __after._M_node, __v); 1223 : } 1224 : else 1225 881 : return _M_insert_unique(__v).first; 1226 : } 1227 : else 1228 : // Equivalent keys. 1229 : return iterator(static_cast<_Link_type> 1230 0 : (const_cast<_Base_ptr>(__position._M_node))); 1231 : } 1232 : 1233 : template<typename _Key, typename _Val, typename _KeyOfValue, 1234 : typename _Compare, typename _Alloc> 1235 : typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator 1236 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1237 : _M_insert_equal_(const_iterator __position, const _Val& __v) 1238 : { 1239 : // end() 1240 : if (__position._M_node == _M_end()) 1241 : { 1242 : if (size() > 0 1243 : && !_M_impl._M_key_compare(_KeyOfValue()(__v), 1244 : _S_key(_M_rightmost()))) 1245 : return _M_insert_(0, _M_rightmost(), __v); 1246 : else 1247 : return _M_insert_equal(__v); 1248 : } 1249 : else if (!_M_impl._M_key_compare(_S_key(__position._M_node), 1250 : _KeyOfValue()(__v))) 1251 : { 1252 : // First, try before... 1253 : const_iterator __before = __position; 1254 : if (__position._M_node == _M_leftmost()) // begin() 1255 : return _M_insert_(_M_leftmost(), _M_leftmost(), __v); 1256 : else if (!_M_impl._M_key_compare(_KeyOfValue()(__v), 1257 : _S_key((--__before)._M_node))) 1258 : { 1259 : if (_S_right(__before._M_node) == 0) 1260 : return _M_insert_(0, __before._M_node, __v); 1261 : else 1262 : return _M_insert_(__position._M_node, 1263 : __position._M_node, __v); 1264 : } 1265 : else 1266 : return _M_insert_equal(__v); 1267 : } 1268 : else 1269 : { 1270 : // ... then try after. 1271 : const_iterator __after = __position; 1272 : if (__position._M_node == _M_rightmost()) 1273 : return _M_insert_(0, _M_rightmost(), __v); 1274 : else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), 1275 : _KeyOfValue()(__v))) 1276 : { 1277 : if (_S_right(__position._M_node) == 0) 1278 : return _M_insert_(0, __position._M_node, __v); 1279 : else 1280 : return _M_insert_(__after._M_node, __after._M_node, __v); 1281 : } 1282 : else 1283 : return _M_insert_equal_lower(__v); 1284 : } 1285 : } 1286 : 1287 : template<typename _Key, typename _Val, typename _KoV, 1288 : typename _Cmp, typename _Alloc> 1289 : template<class _II> 1290 : void 1291 : _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: 1292 : _M_insert_unique(_II __first, _II __last) 1293 : { 1294 : for (; __first != __last; ++__first) 1295 : _M_insert_unique_(end(), *__first); 1296 : } 1297 : 1298 : template<typename _Key, typename _Val, typename _KoV, 1299 : typename _Cmp, typename _Alloc> 1300 : template<class _II> 1301 : void 1302 : _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: 1303 : _M_insert_equal(_II __first, _II __last) 1304 : { 1305 : for (; __first != __last; ++__first) 1306 : _M_insert_equal_(end(), *__first); 1307 : } 1308 : 1309 : template<typename _Key, typename _Val, typename _KeyOfValue, 1310 : typename _Compare, typename _Alloc> 1311 : inline void 1312 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1313 0 : erase(iterator __position) 1314 : { 1315 : _Link_type __y = 1316 : static_cast<_Link_type>(_Rb_tree_rebalance_for_erase 1317 : (__position._M_node, 1318 0 : this->_M_impl._M_header)); 1319 0 : _M_destroy_node(__y); 1320 0 : --_M_impl._M_node_count; 1321 0 : } 1322 : 1323 : template<typename _Key, typename _Val, typename _KeyOfValue, 1324 : typename _Compare, typename _Alloc> 1325 : inline void 1326 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1327 129 : erase(const_iterator __position) 1328 : { 1329 : _Link_type __y = 1330 : static_cast<_Link_type>(_Rb_tree_rebalance_for_erase 1331 : (const_cast<_Base_ptr>(__position._M_node), 1332 129 : this->_M_impl._M_header)); 1333 129 : _M_destroy_node(__y); 1334 129 : --_M_impl._M_node_count; 1335 129 : } 1336 : 1337 : template<typename _Key, typename _Val, typename _KeyOfValue, 1338 : typename _Compare, typename _Alloc> 1339 : typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type 1340 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1341 9 : erase(const _Key& __x) 1342 : { 1343 9 : pair<iterator, iterator> __p = equal_range(__x); 1344 9 : const size_type __old_size = size(); 1345 9 : erase(__p.first, __p.second); 1346 9 : return __old_size - size(); 1347 : } 1348 : 1349 : template<typename _Key, typename _Val, typename _KeyOfValue, 1350 : typename _Compare, typename _Alloc> 1351 : void 1352 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1353 9 : erase(iterator __first, iterator __last) 1354 : { 1355 9 : if (__first == begin() && __last == end()) 1356 7 : clear(); 1357 : else 1358 4 : while (__first != __last) 1359 0 : erase(__first++); 1360 9 : } 1361 : 1362 : template<typename _Key, typename _Val, typename _KeyOfValue, 1363 : typename _Compare, typename _Alloc> 1364 : void 1365 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1366 : erase(const_iterator __first, const_iterator __last) 1367 : { 1368 : if (__first == begin() && __last == end()) 1369 : clear(); 1370 : else 1371 : while (__first != __last) 1372 : erase(__first++); 1373 : } 1374 : 1375 : template<typename _Key, typename _Val, typename _KeyOfValue, 1376 : typename _Compare, typename _Alloc> 1377 : void 1378 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1379 : erase(const _Key* __first, const _Key* __last) 1380 : { 1381 : while (__first != __last) 1382 : erase(*__first++); 1383 : } 1384 : 1385 : template<typename _Key, typename _Val, typename _KeyOfValue, 1386 : typename _Compare, typename _Alloc> 1387 : typename _Rb_tree<_Key, _Val, _KeyOfValue, 1388 : _Compare, _Alloc>::iterator 1389 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1390 50156 : find(const _Key& __k) 1391 : { 1392 50156 : iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k); 1393 : return (__j == end() 1394 : || _M_impl._M_key_compare(__k, 1395 50156 : _S_key(__j._M_node))) ? end() : __j; 1396 : } 1397 : 1398 : template<typename _Key, typename _Val, typename _KeyOfValue, 1399 : typename _Compare, typename _Alloc> 1400 : typename _Rb_tree<_Key, _Val, _KeyOfValue, 1401 : _Compare, _Alloc>::const_iterator 1402 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1403 3932 : find(const _Key& __k) const 1404 : { 1405 3932 : const_iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k); 1406 : return (__j == end() 1407 : || _M_impl._M_key_compare(__k, 1408 3932 : _S_key(__j._M_node))) ? end() : __j; 1409 : } 1410 : 1411 : template<typename _Key, typename _Val, typename _KeyOfValue, 1412 : typename _Compare, typename _Alloc> 1413 : typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type 1414 : _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: 1415 : count(const _Key& __k) const 1416 : { 1417 : pair<const_iterator, const_iterator> __p = equal_range(__k); 1418 : const size_type __n = std::distance(__p.first, __p.second); 1419 : return __n; 1420 : } 1421 : 1422 : unsigned int 1423 : _Rb_tree_black_count(const _Rb_tree_node_base* __node, 1424 : const _Rb_tree_node_base* __root); 1425 : 1426 : template<typename _Key, typename _Val, typename _KeyOfValue, 1427 : typename _Compare, typename _Alloc> 1428 : bool 1429 : _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const 1430 : { 1431 : if (_M_impl._M_node_count == 0 || begin() == end()) 1432 : return _M_impl._M_node_count == 0 && begin() == end() 1433 : && this->_M_impl._M_header._M_left == _M_end() 1434 : && this->_M_impl._M_header._M_right == _M_end(); 1435 : 1436 : unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root()); 1437 : for (const_iterator __it = begin(); __it != end(); ++__it) 1438 : { 1439 : _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node); 1440 : _Const_Link_type __L = _S_left(__x); 1441 : _Const_Link_type __R = _S_right(__x); 1442 : 1443 : if (__x->_M_color == _S_red) 1444 : if ((__L && __L->_M_color == _S_red) 1445 : || (__R && __R->_M_color == _S_red)) 1446 : return false; 1447 : 1448 : if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L))) 1449 : return false; 1450 : if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x))) 1451 : return false; 1452 : 1453 : if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len) 1454 : return false; 1455 : } 1456 : 1457 : if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) 1458 : return false; 1459 : if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) 1460 : return false; 1461 : return true; 1462 : } 1463 : 1464 : _GLIBCXX_END_NAMESPACE 1465 : 1466 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Deque implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1997 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_deque.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_DEQUE_H 63 : #define _STL_DEQUE_H 1 64 : 65 : #include <bits/concept_check.h> 66 : #include <bits/stl_iterator_base_types.h> 67 : #include <bits/stl_iterator_base_funcs.h> 68 : 69 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) 70 : 71 : /** 72 : * @brief This function controls the size of memory nodes. 73 : * @param size The size of an element. 74 : * @return The number (not byte size) of elements per node. 75 : * 76 : * This function started off as a compiler kludge from SGI, but seems to 77 : * be a useful wrapper around a repeated constant expression. The '512' is 78 : * tunable (and no other code needs to change), but no investigation has 79 : * been done since inheriting the SGI code. 80 : */ 81 : inline size_t 82 7753 : __deque_buf_size(size_t __size) 83 7753 : { return __size < 512 ? size_t(512 / __size) : size_t(1); } 84 : 85 : 86 : /** 87 : * @brief A deque::iterator. 88 : * 89 : * Quite a bit of intelligence here. Much of the functionality of 90 : * deque is actually passed off to this class. A deque holds two 91 : * of these internally, marking its valid range. Access to 92 : * elements is done as offsets of either of those two, relying on 93 : * operator overloading in this class. 94 : * 95 : * All the functions are op overloads except for _M_set_node. 96 : */ 97 : template<typename _Tp, typename _Ref, typename _Ptr> 98 : struct _Deque_iterator 99 : { 100 : typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; 101 : typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; 102 : 103 7595 : static size_t _S_buffer_size() 104 7595 : { return __deque_buf_size(sizeof(_Tp)); } 105 : 106 : typedef std::random_access_iterator_tag iterator_category; 107 : typedef _Tp value_type; 108 : typedef _Ptr pointer; 109 : typedef _Ref reference; 110 : typedef size_t size_type; 111 : typedef ptrdiff_t difference_type; 112 : typedef _Tp** _Map_pointer; 113 : typedef _Deque_iterator _Self; 114 : 115 : _Tp* _M_cur; 116 : _Tp* _M_first; 117 : _Tp* _M_last; 118 : _Map_pointer _M_node; 119 : 120 : _Deque_iterator(_Tp* __x, _Map_pointer __y) 121 : : _M_cur(__x), _M_first(*__y), 122 : _M_last(*__y + _S_buffer_size()), _M_node(__y) { } 123 : 124 68 : _Deque_iterator() 125 68 : : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) { } 126 : 127 45179 : _Deque_iterator(const iterator& __x) 128 : : _M_cur(__x._M_cur), _M_first(__x._M_first), 129 45179 : _M_last(__x._M_last), _M_node(__x._M_node) { } 130 : 131 : reference 132 24883 : operator*() const 133 24883 : { return *_M_cur; } 134 : 135 : pointer 136 : operator->() const 137 : { return _M_cur; } 138 : 139 : _Self& 140 24754 : operator++() 141 : { 142 24754 : ++_M_cur; 143 24754 : if (_M_cur == _M_last) 144 : { 145 29 : _M_set_node(_M_node + 1); 146 29 : _M_cur = _M_first; 147 : } 148 24754 : return *this; 149 : } 150 : 151 : _Self 152 : operator++(int) 153 : { 154 : _Self __tmp = *this; 155 : ++*this; 156 : return __tmp; 157 : } 158 : 159 : _Self& 160 39 : operator--() 161 : { 162 39 : if (_M_cur == _M_first) 163 : { 164 0 : _M_set_node(_M_node - 1); 165 0 : _M_cur = _M_last; 166 : } 167 39 : --_M_cur; 168 39 : return *this; 169 : } 170 : 171 : _Self 172 : operator--(int) 173 : { 174 : _Self __tmp = *this; 175 : --*this; 176 : return __tmp; 177 : } 178 : 179 : _Self& 180 180 : operator+=(difference_type __n) 181 : { 182 180 : const difference_type __offset = __n + (_M_cur - _M_first); 183 180 : if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) 184 178 : _M_cur += __n; 185 : else 186 : { 187 : const difference_type __node_offset = 188 : __offset > 0 ? __offset / difference_type(_S_buffer_size()) 189 : : -difference_type((-__offset - 1) 190 2 : / _S_buffer_size()) - 1; 191 2 : _M_set_node(_M_node + __node_offset); 192 2 : _M_cur = _M_first + (__offset - __node_offset 193 : * difference_type(_S_buffer_size())); 194 : } 195 180 : return *this; 196 : } 197 : 198 : _Self 199 180 : operator+(difference_type __n) const 200 : { 201 180 : _Self __tmp = *this; 202 180 : return __tmp += __n; 203 : } 204 : 205 : _Self& 206 0 : operator-=(difference_type __n) 207 0 : { return *this += -__n; } 208 : 209 : _Self 210 0 : operator-(difference_type __n) const 211 : { 212 0 : _Self __tmp = *this; 213 0 : return __tmp -= __n; 214 : } 215 : 216 : reference 217 : operator[](difference_type __n) const 218 : { return *(*this + __n); } 219 : 220 : /** 221 : * Prepares to traverse new_node. Sets everything except 222 : * _M_cur, which should therefore be set by the caller 223 : * immediately afterwards, based on _M_first and _M_last. 224 : */ 225 : void 226 112 : _M_set_node(_Map_pointer __new_node) 227 : { 228 112 : _M_node = __new_node; 229 112 : _M_first = *__new_node; 230 112 : _M_last = _M_first + difference_type(_S_buffer_size()); 231 112 : } 232 : }; 233 : 234 : // Note: we also provide overloads whose operands are of the same type in 235 : // order to avoid ambiguous overload resolution when std::rel_ops operators 236 : // are in scope (for additional details, see libstdc++/3628) 237 : template<typename _Tp, typename _Ref, typename _Ptr> 238 : inline bool 239 : operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, 240 19443 : const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) 241 19443 : { return __x._M_cur == __y._M_cur; } 242 : 243 : template<typename _Tp, typename _RefL, typename _PtrL, 244 : typename _RefR, typename _PtrR> 245 : inline bool 246 : operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, 247 : const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) 248 : { return __x._M_cur == __y._M_cur; } 249 : 250 : template<typename _Tp, typename _Ref, typename _Ptr> 251 : inline bool 252 : operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, 253 12091 : const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) 254 12091 : { return !(__x == __y); } 255 : 256 : template<typename _Tp, typename _RefL, typename _PtrL, 257 : typename _RefR, typename _PtrR> 258 : inline bool 259 : operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, 260 : const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) 261 : { return !(__x == __y); } 262 : 263 : template<typename _Tp, typename _Ref, typename _Ptr> 264 : inline bool 265 : operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, 266 : const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) 267 : { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) 268 : : (__x._M_node < __y._M_node); } 269 : 270 : template<typename _Tp, typename _RefL, typename _PtrL, 271 : typename _RefR, typename _PtrR> 272 : inline bool 273 : operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, 274 : const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) 275 : { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) 276 : : (__x._M_node < __y._M_node); } 277 : 278 : template<typename _Tp, typename _Ref, typename _Ptr> 279 : inline bool 280 : operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, 281 : const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) 282 : { return __y < __x; } 283 : 284 : template<typename _Tp, typename _RefL, typename _PtrL, 285 : typename _RefR, typename _PtrR> 286 : inline bool 287 : operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, 288 : const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) 289 : { return __y < __x; } 290 : 291 : template<typename _Tp, typename _Ref, typename _Ptr> 292 : inline bool 293 : operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, 294 : const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) 295 : { return !(__y < __x); } 296 : 297 : template<typename _Tp, typename _RefL, typename _PtrL, 298 : typename _RefR, typename _PtrR> 299 : inline bool 300 : operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, 301 : const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) 302 : { return !(__y < __x); } 303 : 304 : template<typename _Tp, typename _Ref, typename _Ptr> 305 : inline bool 306 : operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, 307 : const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) 308 : { return !(__x < __y); } 309 : 310 : template<typename _Tp, typename _RefL, typename _PtrL, 311 : typename _RefR, typename _PtrR> 312 : inline bool 313 : operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, 314 : const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) 315 : { return !(__x < __y); } 316 : 317 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 318 : // According to the resolution of DR179 not only the various comparison 319 : // operators but also operator- must accept mixed iterator/const_iterator 320 : // parameters. 321 : template<typename _Tp, typename _Ref, typename _Ptr> 322 : inline typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type 323 : operator-(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, 324 7299 : const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) 325 : { 326 : return typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type 327 : (_Deque_iterator<_Tp, _Ref, _Ptr>::_S_buffer_size()) 328 : * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) 329 7299 : + (__y._M_last - __y._M_cur); 330 : } 331 : 332 : template<typename _Tp, typename _RefL, typename _PtrL, 333 : typename _RefR, typename _PtrR> 334 : inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type 335 : operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, 336 : const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) 337 : { 338 : return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type 339 : (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) 340 : * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) 341 : + (__y._M_last - __y._M_cur); 342 : } 343 : 344 : template<typename _Tp, typename _Ref, typename _Ptr> 345 : inline _Deque_iterator<_Tp, _Ref, _Ptr> 346 : operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) 347 : { return __x + __n; } 348 : 349 : template<typename _Tp> 350 : void 351 : fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first, 352 : const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value); 353 : 354 : /** 355 : * Deque base class. This class provides the unified face for %deque's 356 : * allocation. This class's constructor and destructor allocate and 357 : * deallocate (but do not initialize) storage. This makes %exception 358 : * safety easier. 359 : * 360 : * Nothing in this class ever constructs or destroys an actual Tp element. 361 : * (Deque handles that itself.) Only/All memory management is performed 362 : * here. 363 : */ 364 : template<typename _Tp, typename _Alloc> 365 : class _Deque_base 366 : { 367 : public: 368 : typedef _Alloc allocator_type; 369 : 370 : allocator_type 371 : get_allocator() const 372 : { return allocator_type(_M_get_Tp_allocator()); } 373 : 374 : typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; 375 : typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; 376 : 377 21 : _Deque_base() 378 21 : : _M_impl() 379 21 : { _M_initialize_map(0); } 380 : 381 13 : _Deque_base(const allocator_type& __a, size_t __num_elements) 382 13 : : _M_impl(__a) 383 13 : { _M_initialize_map(__num_elements); } 384 : 385 : _Deque_base(const allocator_type& __a) 386 : : _M_impl(__a) 387 : { } 388 : 389 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 390 : _Deque_base(_Deque_base&& __x) 391 : : _M_impl(__x._M_get_Tp_allocator()) 392 : { 393 : _M_initialize_map(0); 394 : if (__x._M_impl._M_map) 395 : { 396 : std::swap(this->_M_impl._M_start, __x._M_impl._M_start); 397 : std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); 398 : std::swap(this->_M_impl._M_map, __x._M_impl._M_map); 399 : std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size); 400 : } 401 : } 402 : #endif 403 : 404 : ~_Deque_base(); 405 : 406 : protected: 407 : //This struct encapsulates the implementation of the std::deque 408 : //standard container and at the same time makes use of the EBO 409 : //for empty allocators. 410 : typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type; 411 : 412 : typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; 413 : 414 : struct _Deque_impl 415 : : public _Tp_alloc_type 416 30 : { 417 : _Tp** _M_map; 418 : size_t _M_map_size; 419 : iterator _M_start; 420 : iterator _M_finish; 421 : 422 21 : _Deque_impl() 423 : : _Tp_alloc_type(), _M_map(0), _M_map_size(0), 424 21 : _M_start(), _M_finish() 425 21 : { } 426 : 427 13 : _Deque_impl(const _Tp_alloc_type& __a) 428 : : _Tp_alloc_type(__a), _M_map(0), _M_map_size(0), 429 13 : _M_start(), _M_finish() 430 13 : { } 431 : }; 432 : 433 : _Tp_alloc_type& 434 1085 : _M_get_Tp_allocator() 435 1085 : { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } 436 : 437 : const _Tp_alloc_type& 438 77 : _M_get_Tp_allocator() const 439 77 : { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); } 440 : 441 : _Map_alloc_type 442 64 : _M_get_map_allocator() const 443 64 : { return _Map_alloc_type(_M_get_Tp_allocator()); } 444 : 445 : _Tp* 446 47 : _M_allocate_node() 447 : { 448 47 : return _M_impl._Tp_alloc_type::allocate(__deque_buf_size(sizeof(_Tp))); 449 : } 450 : 451 : void 452 43 : _M_deallocate_node(_Tp* __p) 453 : { 454 43 : _M_impl._Tp_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp))); 455 43 : } 456 : 457 : _Tp** 458 34 : _M_allocate_map(size_t __n) 459 34 : { return _M_get_map_allocator().allocate(__n); } 460 : 461 : void 462 30 : _M_deallocate_map(_Tp** __p, size_t __n) 463 30 : { _M_get_map_allocator().deallocate(__p, __n); } 464 : 465 : protected: 466 : void _M_initialize_map(size_t); 467 : void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); 468 : void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); 469 : enum { _S_initial_map_size = 8 }; 470 : 471 : _Deque_impl _M_impl; 472 : }; 473 : 474 : template<typename _Tp, typename _Alloc> 475 : _Deque_base<_Tp, _Alloc>:: 476 30 : ~_Deque_base() 477 : { 478 30 : if (this->_M_impl._M_map) 479 : { 480 30 : _M_destroy_nodes(this->_M_impl._M_start._M_node, 481 : this->_M_impl._M_finish._M_node + 1); 482 30 : _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); 483 : } 484 30 : } 485 : 486 : /** 487 : * @brief Layout storage. 488 : * @param num_elements The count of T's for which to allocate space 489 : * at first. 490 : * @return Nothing. 491 : * 492 : * The initial underlying memory layout is a bit complicated... 493 : */ 494 : template<typename _Tp, typename _Alloc> 495 : void 496 : _Deque_base<_Tp, _Alloc>:: 497 34 : _M_initialize_map(size_t __num_elements) 498 : { 499 : const size_t __num_nodes = (__num_elements/ __deque_buf_size(sizeof(_Tp)) 500 34 : + 1); 501 : 502 34 : this->_M_impl._M_map_size = std::max((size_t) _S_initial_map_size, 503 : size_t(__num_nodes + 2)); 504 34 : this->_M_impl._M_map = _M_allocate_map(this->_M_impl._M_map_size); 505 : 506 : // For "small" maps (needing less than _M_map_size nodes), allocation 507 : // starts in the middle elements and grows outwards. So nstart may be 508 : // the beginning of _M_map, but for small maps it may be as far in as 509 : // _M_map+3. 510 : 511 : _Tp** __nstart = (this->_M_impl._M_map 512 34 : + (this->_M_impl._M_map_size - __num_nodes) / 2); 513 34 : _Tp** __nfinish = __nstart + __num_nodes; 514 : 515 : try 516 34 : { _M_create_nodes(__nstart, __nfinish); } 517 0 : catch(...) 518 : { 519 0 : _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); 520 0 : this->_M_impl._M_map = 0; 521 0 : this->_M_impl._M_map_size = 0; 522 0 : __throw_exception_again; 523 : } 524 : 525 34 : this->_M_impl._M_start._M_set_node(__nstart); 526 34 : this->_M_impl._M_finish._M_set_node(__nfinish - 1); 527 34 : this->_M_impl._M_start._M_cur = _M_impl._M_start._M_first; 528 34 : this->_M_impl._M_finish._M_cur = (this->_M_impl._M_finish._M_first 529 : + __num_elements 530 : % __deque_buf_size(sizeof(_Tp))); 531 34 : } 532 : 533 : template<typename _Tp, typename _Alloc> 534 : void 535 : _Deque_base<_Tp, _Alloc>:: 536 34 : _M_create_nodes(_Tp** __nstart, _Tp** __nfinish) 537 : { 538 : _Tp** __cur; 539 : try 540 : { 541 68 : for (__cur = __nstart; __cur < __nfinish; ++__cur) 542 34 : *__cur = this->_M_allocate_node(); 543 : } 544 0 : catch(...) 545 : { 546 0 : _M_destroy_nodes(__nstart, __cur); 547 0 : __throw_exception_again; 548 : } 549 34 : } 550 : 551 : template<typename _Tp, typename _Alloc> 552 : void 553 : _Deque_base<_Tp, _Alloc>:: 554 1046 : _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) 555 : { 556 1089 : for (_Tp** __n = __nstart; __n < __nfinish; ++__n) 557 43 : _M_deallocate_node(*__n); 558 1046 : } 559 : 560 : /** 561 : * @brief A standard container using fixed-size memory allocation and 562 : * constant-time manipulation of elements at either end. 563 : * 564 : * @ingroup Containers 565 : * @ingroup Sequences 566 : * 567 : * Meets the requirements of a <a href="tables.html#65">container</a>, a 568 : * <a href="tables.html#66">reversible container</a>, and a 569 : * <a href="tables.html#67">sequence</a>, including the 570 : * <a href="tables.html#68">optional sequence requirements</a>. 571 : * 572 : * In previous HP/SGI versions of deque, there was an extra template 573 : * parameter so users could control the node size. This extension turned 574 : * out to violate the C++ standard (it can be detected using template 575 : * template parameters), and it was removed. 576 : * 577 : * Here's how a deque<Tp> manages memory. Each deque has 4 members: 578 : * 579 : * - Tp** _M_map 580 : * - size_t _M_map_size 581 : * - iterator _M_start, _M_finish 582 : * 583 : * map_size is at least 8. %map is an array of map_size 584 : * pointers-to-"nodes". (The name %map has nothing to do with the 585 : * std::map class, and "nodes" should not be confused with 586 : * std::list's usage of "node".) 587 : * 588 : * A "node" has no specific type name as such, but it is referred 589 : * to as "node" in this file. It is a simple array-of-Tp. If Tp 590 : * is very large, there will be one Tp element per node (i.e., an 591 : * "array" of one). For non-huge Tp's, node size is inversely 592 : * related to Tp size: the larger the Tp, the fewer Tp's will fit 593 : * in a node. The goal here is to keep the total size of a node 594 : * relatively small and constant over different Tp's, to improve 595 : * allocator efficiency. 596 : * 597 : * Not every pointer in the %map array will point to a node. If 598 : * the initial number of elements in the deque is small, the 599 : * /middle/ %map pointers will be valid, and the ones at the edges 600 : * will be unused. This same situation will arise as the %map 601 : * grows: available %map pointers, if any, will be on the ends. As 602 : * new nodes are created, only a subset of the %map's pointers need 603 : * to be copied "outward". 604 : * 605 : * Class invariants: 606 : * - For any nonsingular iterator i: 607 : * - i.node points to a member of the %map array. (Yes, you read that 608 : * correctly: i.node does not actually point to a node.) The member of 609 : * the %map array is what actually points to the node. 610 : * - i.first == *(i.node) (This points to the node (first Tp element).) 611 : * - i.last == i.first + node_size 612 : * - i.cur is a pointer in the range [i.first, i.last). NOTE: 613 : * the implication of this is that i.cur is always a dereferenceable 614 : * pointer, even if i is a past-the-end iterator. 615 : * - Start and Finish are always nonsingular iterators. NOTE: this 616 : * means that an empty deque must have one node, a deque with <N 617 : * elements (where N is the node buffer size) must have one node, a 618 : * deque with N through (2N-1) elements must have two nodes, etc. 619 : * - For every node other than start.node and finish.node, every 620 : * element in the node is an initialized object. If start.node == 621 : * finish.node, then [start.cur, finish.cur) are initialized 622 : * objects, and the elements outside that range are uninitialized 623 : * storage. Otherwise, [start.cur, start.last) and [finish.first, 624 : * finish.cur) are initialized objects, and [start.first, start.cur) 625 : * and [finish.cur, finish.last) are uninitialized storage. 626 : * - [%map, %map + map_size) is a valid, non-empty range. 627 : * - [start.node, finish.node] is a valid range contained within 628 : * [%map, %map + map_size). 629 : * - A pointer in the range [%map, %map + map_size) points to an allocated 630 : * node if and only if the pointer is in the range 631 : * [start.node, finish.node]. 632 : * 633 : * Here's the magic: nothing in deque is "aware" of the discontiguous 634 : * storage! 635 : * 636 : * The memory setup and layout occurs in the parent, _Base, and the iterator 637 : * class is entirely responsible for "leaping" from one node to the next. 638 : * All the implementation routines for deque itself work only through the 639 : * start and finish iterators. This keeps the routines simple and sane, 640 : * and we can use other standard algorithms as well. 641 : */ 642 : template<typename _Tp, typename _Alloc = std::allocator<_Tp> > 643 : class deque : protected _Deque_base<_Tp, _Alloc> 644 : { 645 : // concept requirements 646 : typedef typename _Alloc::value_type _Alloc_value_type; 647 : __glibcxx_class_requires(_Tp, _SGIAssignableConcept) 648 : __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) 649 : 650 : typedef _Deque_base<_Tp, _Alloc> _Base; 651 : typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; 652 : 653 : public: 654 : typedef _Tp value_type; 655 : typedef typename _Tp_alloc_type::pointer pointer; 656 : typedef typename _Tp_alloc_type::const_pointer const_pointer; 657 : typedef typename _Tp_alloc_type::reference reference; 658 : typedef typename _Tp_alloc_type::const_reference const_reference; 659 : typedef typename _Base::iterator iterator; 660 : typedef typename _Base::const_iterator const_iterator; 661 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 662 : typedef std::reverse_iterator<iterator> reverse_iterator; 663 : typedef size_t size_type; 664 : typedef ptrdiff_t difference_type; 665 : typedef _Alloc allocator_type; 666 : 667 : protected: 668 : typedef pointer* _Map_pointer; 669 : 670 0 : static size_t _S_buffer_size() 671 0 : { return __deque_buf_size(sizeof(_Tp)); } 672 : 673 : // Functions controlling memory layout, and nothing else. 674 : using _Base::_M_initialize_map; 675 : using _Base::_M_create_nodes; 676 : using _Base::_M_destroy_nodes; 677 : using _Base::_M_allocate_node; 678 : using _Base::_M_deallocate_node; 679 : using _Base::_M_allocate_map; 680 : using _Base::_M_deallocate_map; 681 : using _Base::_M_get_Tp_allocator; 682 : 683 : /** 684 : * A total of four data members accumulated down the hierarchy. 685 : * May be accessed via _M_impl.* 686 : */ 687 : using _Base::_M_impl; 688 : 689 : public: 690 : // [23.2.1.1] construct/copy/destroy 691 : // (assign() and get_allocator() are also listed in this section) 692 : /** 693 : * @brief Default constructor creates no elements. 694 : */ 695 21 : deque() 696 21 : : _Base() { } 697 : 698 : /** 699 : * @brief Creates a %deque with no elements. 700 : * @param a An allocator object. 701 : */ 702 : explicit 703 : deque(const allocator_type& __a) 704 : : _Base(__a, 0) { } 705 : 706 : /** 707 : * @brief Creates a %deque with copies of an exemplar element. 708 : * @param n The number of elements to initially create. 709 : * @param value An element to copy. 710 : * @param a An allocator. 711 : * 712 : * This constructor fills the %deque with @a n copies of @a value. 713 : */ 714 : explicit 715 : deque(size_type __n, const value_type& __value = value_type(), 716 : const allocator_type& __a = allocator_type()) 717 : : _Base(__a, __n) 718 : { _M_fill_initialize(__value); } 719 : 720 : /** 721 : * @brief %Deque copy constructor. 722 : * @param x A %deque of identical element and allocator types. 723 : * 724 : * The newly-created %deque uses a copy of the allocation object used 725 : * by @a x. 726 : */ 727 13 : deque(const deque& __x) 728 13 : : _Base(__x._M_get_Tp_allocator(), __x.size()) 729 13 : { std::__uninitialized_copy_a(__x.begin(), __x.end(), 730 : this->_M_impl._M_start, 731 13 : _M_get_Tp_allocator()); } 732 : 733 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 734 : /** 735 : * @brief %Deque move constructor. 736 : * @param x A %deque of identical element and allocator types. 737 : * 738 : * The newly-created %deque contains the exact contents of @a x. 739 : * The contents of @a x are a valid, but unspecified %deque. 740 : */ 741 : deque(deque&& __x) 742 : : _Base(std::forward<_Base>(__x)) { } 743 : #endif 744 : 745 : /** 746 : * @brief Builds a %deque from a range. 747 : * @param first An input iterator. 748 : * @param last An input iterator. 749 : * @param a An allocator object. 750 : * 751 : * Create a %deque consisting of copies of the elements from [first, 752 : * last). 753 : * 754 : * If the iterators are forward, bidirectional, or random-access, then 755 : * this will call the elements' copy constructor N times (where N is 756 : * distance(first,last)) and do no memory reallocation. But if only 757 : * input iterators are used, then this will do at most 2N calls to the 758 : * copy constructor, and logN memory reallocations. 759 : */ 760 : template<typename _InputIterator> 761 : deque(_InputIterator __first, _InputIterator __last, 762 : const allocator_type& __a = allocator_type()) 763 : : _Base(__a) 764 : { 765 : // Check whether it's an integral type. If so, it's not an iterator. 766 : typedef typename std::__is_integer<_InputIterator>::__type _Integral; 767 : _M_initialize_dispatch(__first, __last, _Integral()); 768 : } 769 : 770 : /** 771 : * The dtor only erases the elements, and note that if the elements 772 : * themselves are pointers, the pointed-to memory is not touched in any 773 : * way. Managing the pointer is the user's responsibility. 774 : */ 775 30 : ~deque() 776 30 : { _M_destroy_data(begin(), end(), _M_get_Tp_allocator()); } 777 : 778 : /** 779 : * @brief %Deque assignment operator. 780 : * @param x A %deque of identical element and allocator types. 781 : * 782 : * All the elements of @a x are copied, but unlike the copy constructor, 783 : * the allocator object is not copied. 784 : */ 785 : deque& 786 : operator=(const deque& __x); 787 : 788 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 789 : /** 790 : * @brief %Deque move assignment operator. 791 : * @param x A %deque of identical element and allocator types. 792 : * 793 : * The contents of @a x are moved into this deque (without copying). 794 : * @a x is a valid, but unspecified %deque. 795 : */ 796 : deque& 797 : operator=(deque&& __x) 798 : { 799 : // NB: DR 675. 800 : this->clear(); 801 : this->swap(__x); 802 : return *this; 803 : } 804 : #endif 805 : 806 : /** 807 : * @brief Assigns a given value to a %deque. 808 : * @param n Number of elements to be assigned. 809 : * @param val Value to be assigned. 810 : * 811 : * This function fills a %deque with @a n copies of the given 812 : * value. Note that the assignment completely changes the 813 : * %deque and that the resulting %deque's size is the same as 814 : * the number of elements assigned. Old data may be lost. 815 : */ 816 : void 817 : assign(size_type __n, const value_type& __val) 818 : { _M_fill_assign(__n, __val); } 819 : 820 : /** 821 : * @brief Assigns a range to a %deque. 822 : * @param first An input iterator. 823 : * @param last An input iterator. 824 : * 825 : * This function fills a %deque with copies of the elements in the 826 : * range [first,last). 827 : * 828 : * Note that the assignment completely changes the %deque and that the 829 : * resulting %deque's size is the same as the number of elements 830 : * assigned. Old data may be lost. 831 : */ 832 : template<typename _InputIterator> 833 : void 834 : assign(_InputIterator __first, _InputIterator __last) 835 : { 836 : typedef typename std::__is_integer<_InputIterator>::__type _Integral; 837 : _M_assign_dispatch(__first, __last, _Integral()); 838 : } 839 : 840 : /// Get a copy of the memory allocation object. 841 : allocator_type 842 : get_allocator() const 843 : { return _Base::get_allocator(); } 844 : 845 : // iterators 846 : /** 847 : * Returns a read/write iterator that points to the first element in the 848 : * %deque. Iteration is done in ordinary element order. 849 : */ 850 : iterator 851 7800 : begin() 852 7800 : { return this->_M_impl._M_start; } 853 : 854 : /** 855 : * Returns a read-only (constant) iterator that points to the first 856 : * element in the %deque. Iteration is done in ordinary element order. 857 : */ 858 : const_iterator 859 17 : begin() const 860 17 : { return this->_M_impl._M_start; } 861 : 862 : /** 863 : * Returns a read/write iterator that points one past the last 864 : * element in the %deque. Iteration is done in ordinary 865 : * element order. 866 : */ 867 : iterator 868 10575 : end() 869 10575 : { return this->_M_impl._M_finish; } 870 : 871 : /** 872 : * Returns a read-only (constant) iterator that points one past 873 : * the last element in the %deque. Iteration is done in 874 : * ordinary element order. 875 : */ 876 : const_iterator 877 17 : end() const 878 17 : { return this->_M_impl._M_finish; } 879 : 880 : /** 881 : * Returns a read/write reverse iterator that points to the 882 : * last element in the %deque. Iteration is done in reverse 883 : * element order. 884 : */ 885 : reverse_iterator 886 : rbegin() 887 : { return reverse_iterator(this->_M_impl._M_finish); } 888 : 889 : /** 890 : * Returns a read-only (constant) reverse iterator that points 891 : * to the last element in the %deque. Iteration is done in 892 : * reverse element order. 893 : */ 894 : const_reverse_iterator 895 : rbegin() const 896 : { return const_reverse_iterator(this->_M_impl._M_finish); } 897 : 898 : /** 899 : * Returns a read/write reverse iterator that points to one 900 : * before the first element in the %deque. Iteration is done 901 : * in reverse element order. 902 : */ 903 : reverse_iterator 904 : rend() 905 : { return reverse_iterator(this->_M_impl._M_start); } 906 : 907 : /** 908 : * Returns a read-only (constant) reverse iterator that points 909 : * to one before the first element in the %deque. Iteration is 910 : * done in reverse element order. 911 : */ 912 : const_reverse_iterator 913 : rend() const 914 : { return const_reverse_iterator(this->_M_impl._M_start); } 915 : 916 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 917 : /** 918 : * Returns a read-only (constant) iterator that points to the first 919 : * element in the %deque. Iteration is done in ordinary element order. 920 : */ 921 : const_iterator 922 : cbegin() const 923 : { return this->_M_impl._M_start; } 924 : 925 : /** 926 : * Returns a read-only (constant) iterator that points one past 927 : * the last element in the %deque. Iteration is done in 928 : * ordinary element order. 929 : */ 930 : const_iterator 931 : cend() const 932 : { return this->_M_impl._M_finish; } 933 : 934 : /** 935 : * Returns a read-only (constant) reverse iterator that points 936 : * to the last element in the %deque. Iteration is done in 937 : * reverse element order. 938 : */ 939 : const_reverse_iterator 940 : crbegin() const 941 : { return const_reverse_iterator(this->_M_impl._M_finish); } 942 : 943 : /** 944 : * Returns a read-only (constant) reverse iterator that points 945 : * to one before the first element in the %deque. Iteration is 946 : * done in reverse element order. 947 : */ 948 : const_reverse_iterator 949 : crend() const 950 : { return const_reverse_iterator(this->_M_impl._M_start); } 951 : #endif 952 : 953 : // [23.2.1.2] capacity 954 : /** Returns the number of elements in the %deque. */ 955 : size_type 956 111 : size() const 957 111 : { return this->_M_impl._M_finish - this->_M_impl._M_start; } 958 : 959 : /** Returns the size() of the largest possible %deque. */ 960 : size_type 961 0 : max_size() const 962 0 : { return _M_get_Tp_allocator().max_size(); } 963 : 964 : /** 965 : * @brief Resizes the %deque to the specified number of elements. 966 : * @param new_size Number of elements the %deque should contain. 967 : * @param x Data with which new elements should be populated. 968 : * 969 : * This function will %resize the %deque to the specified 970 : * number of elements. If the number is smaller than the 971 : * %deque's current size the %deque is truncated, otherwise the 972 : * %deque is extended and new elements are populated with given 973 : * data. 974 : */ 975 : void 976 : resize(size_type __new_size, value_type __x = value_type()) 977 : { 978 : const size_type __len = size(); 979 : if (__new_size < __len) 980 : _M_erase_at_end(this->_M_impl._M_start + difference_type(__new_size)); 981 : else 982 : insert(this->_M_impl._M_finish, __new_size - __len, __x); 983 : } 984 : 985 : /** 986 : * Returns true if the %deque is empty. (Thus begin() would 987 : * equal end().) 988 : */ 989 : bool 990 32 : empty() const 991 32 : { return this->_M_impl._M_finish == this->_M_impl._M_start; } 992 : 993 : // element access 994 : /** 995 : * @brief Subscript access to the data contained in the %deque. 996 : * @param n The index of the element for which data should be 997 : * accessed. 998 : * @return Read/write reference to data. 999 : * 1000 : * This operator allows for easy, array-style, data access. 1001 : * Note that data access with this operator is unchecked and 1002 : * out_of_range lookups are not defined. (For checked lookups 1003 : * see at().) 1004 : */ 1005 : reference 1006 : operator[](size_type __n) 1007 : { return this->_M_impl._M_start[difference_type(__n)]; } 1008 : 1009 : /** 1010 : * @brief Subscript access to the data contained in the %deque. 1011 : * @param n The index of the element for which data should be 1012 : * accessed. 1013 : * @return Read-only (constant) reference to data. 1014 : * 1015 : * This operator allows for easy, array-style, data access. 1016 : * Note that data access with this operator is unchecked and 1017 : * out_of_range lookups are not defined. (For checked lookups 1018 : * see at().) 1019 : */ 1020 : const_reference 1021 : operator[](size_type __n) const 1022 : { return this->_M_impl._M_start[difference_type(__n)]; } 1023 : 1024 : protected: 1025 : /// Safety check used only from at(). 1026 : void 1027 : _M_range_check(size_type __n) const 1028 : { 1029 : if (__n >= this->size()) 1030 : __throw_out_of_range(__N("deque::_M_range_check")); 1031 : } 1032 : 1033 : public: 1034 : /** 1035 : * @brief Provides access to the data contained in the %deque. 1036 : * @param n The index of the element for which data should be 1037 : * accessed. 1038 : * @return Read/write reference to data. 1039 : * @throw std::out_of_range If @a n is an invalid index. 1040 : * 1041 : * This function provides for safer data access. The parameter 1042 : * is first checked that it is in the range of the deque. The 1043 : * function throws out_of_range if the check fails. 1044 : */ 1045 : reference 1046 : at(size_type __n) 1047 : { 1048 : _M_range_check(__n); 1049 : return (*this)[__n]; 1050 : } 1051 : 1052 : /** 1053 : * @brief Provides access to the data contained in the %deque. 1054 : * @param n The index of the element for which data should be 1055 : * accessed. 1056 : * @return Read-only (constant) reference to data. 1057 : * @throw std::out_of_range If @a n is an invalid index. 1058 : * 1059 : * This function provides for safer data access. The parameter is first 1060 : * checked that it is in the range of the deque. The function throws 1061 : * out_of_range if the check fails. 1062 : */ 1063 : const_reference 1064 : at(size_type __n) const 1065 : { 1066 : _M_range_check(__n); 1067 : return (*this)[__n]; 1068 : } 1069 : 1070 : /** 1071 : * Returns a read/write reference to the data at the first 1072 : * element of the %deque. 1073 : */ 1074 : reference 1075 : front() 1076 : { return *begin(); } 1077 : 1078 : /** 1079 : * Returns a read-only (constant) reference to the data at the first 1080 : * element of the %deque. 1081 : */ 1082 : const_reference 1083 : front() const 1084 : { return *begin(); } 1085 : 1086 : /** 1087 : * Returns a read/write reference to the data at the last element of the 1088 : * %deque. 1089 : */ 1090 : reference 1091 39 : back() 1092 : { 1093 39 : iterator __tmp = end(); 1094 39 : --__tmp; 1095 39 : return *__tmp; 1096 : } 1097 : 1098 : /** 1099 : * Returns a read-only (constant) reference to the data at the last 1100 : * element of the %deque. 1101 : */ 1102 : const_reference 1103 : back() const 1104 : { 1105 : const_iterator __tmp = end(); 1106 : --__tmp; 1107 : return *__tmp; 1108 : } 1109 : 1110 : // [23.2.1.2] modifiers 1111 : /** 1112 : * @brief Add data to the front of the %deque. 1113 : * @param x Data to be added. 1114 : * 1115 : * This is a typical stack operation. The function creates an 1116 : * element at the front of the %deque and assigns the given 1117 : * data to it. Due to the nature of a %deque this operation 1118 : * can be done in constant time. 1119 : */ 1120 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 1121 : void 1122 : push_front(const value_type& __x) 1123 : { 1124 : if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) 1125 : { 1126 : this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1, __x); 1127 : --this->_M_impl._M_start._M_cur; 1128 : } 1129 : else 1130 : _M_push_front_aux(__x); 1131 : } 1132 : #else 1133 : template<typename... _Args> 1134 : void 1135 : push_front(_Args&&... __args) 1136 : { 1137 : if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) 1138 : { 1139 : this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1, 1140 : std::forward<_Args>(__args)...); 1141 : --this->_M_impl._M_start._M_cur; 1142 : } 1143 : else 1144 : _M_push_front_aux(std::forward<_Args>(__args)...); 1145 : } 1146 : #endif 1147 : 1148 : /** 1149 : * @brief Add data to the end of the %deque. 1150 : * @param x Data to be added. 1151 : * 1152 : * This is a typical stack operation. The function creates an 1153 : * element at the end of the %deque and assigns the given data 1154 : * to it. Due to the nature of a %deque this operation can be 1155 : * done in constant time. 1156 : */ 1157 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 1158 : void 1159 12012 : push_back(const value_type& __x) 1160 : { 1161 12012 : if (this->_M_impl._M_finish._M_cur 1162 : != this->_M_impl._M_finish._M_last - 1) 1163 : { 1164 11999 : this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __x); 1165 11999 : ++this->_M_impl._M_finish._M_cur; 1166 : } 1167 : else 1168 13 : _M_push_back_aux(__x); 1169 12012 : } 1170 : #else 1171 : template<typename... _Args> 1172 : void 1173 : push_back(_Args&&... __args) 1174 : { 1175 : if (this->_M_impl._M_finish._M_cur 1176 : != this->_M_impl._M_finish._M_last - 1) 1177 : { 1178 : this->_M_impl.construct(this->_M_impl._M_finish._M_cur, 1179 : std::forward<_Args>(__args)...); 1180 : ++this->_M_impl._M_finish._M_cur; 1181 : } 1182 : else 1183 : _M_push_back_aux(std::forward<_Args>(__args)...); 1184 : } 1185 : #endif 1186 : 1187 : /** 1188 : * @brief Removes first element. 1189 : * 1190 : * This is a typical stack operation. It shrinks the %deque by one. 1191 : * 1192 : * Note that no data is returned, and if the first element's data is 1193 : * needed, it should be retrieved before pop_front() is called. 1194 : */ 1195 : void 1196 : pop_front() 1197 : { 1198 : if (this->_M_impl._M_start._M_cur 1199 : != this->_M_impl._M_start._M_last - 1) 1200 : { 1201 : this->_M_impl.destroy(this->_M_impl._M_start._M_cur); 1202 : ++this->_M_impl._M_start._M_cur; 1203 : } 1204 : else 1205 : _M_pop_front_aux(); 1206 : } 1207 : 1208 : /** 1209 : * @brief Removes last element. 1210 : * 1211 : * This is a typical stack operation. It shrinks the %deque by one. 1212 : * 1213 : * Note that no data is returned, and if the last element's data is 1214 : * needed, it should be retrieved before pop_back() is called. 1215 : */ 1216 : void 1217 24 : pop_back() 1218 : { 1219 24 : if (this->_M_impl._M_finish._M_cur 1220 : != this->_M_impl._M_finish._M_first) 1221 : { 1222 24 : --this->_M_impl._M_finish._M_cur; 1223 24 : this->_M_impl.destroy(this->_M_impl._M_finish._M_cur); 1224 : } 1225 : else 1226 0 : _M_pop_back_aux(); 1227 24 : } 1228 : 1229 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1230 : /** 1231 : * @brief Inserts an object in %deque before specified iterator. 1232 : * @param position An iterator into the %deque. 1233 : * @param args Arguments. 1234 : * @return An iterator that points to the inserted data. 1235 : * 1236 : * This function will insert an object of type T constructed 1237 : * with T(std::forward<Args>(args)...) before the specified location. 1238 : */ 1239 : template<typename... _Args> 1240 : iterator 1241 : emplace(iterator __position, _Args&&... __args); 1242 : #endif 1243 : 1244 : /** 1245 : * @brief Inserts given value into %deque before specified iterator. 1246 : * @param position An iterator into the %deque. 1247 : * @param x Data to be inserted. 1248 : * @return An iterator that points to the inserted data. 1249 : * 1250 : * This function will insert a copy of the given value before the 1251 : * specified location. 1252 : */ 1253 : iterator 1254 : insert(iterator __position, const value_type& __x); 1255 : 1256 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1257 : /** 1258 : * @brief Inserts given rvalue into %deque before specified iterator. 1259 : * @param position An iterator into the %deque. 1260 : * @param x Data to be inserted. 1261 : * @return An iterator that points to the inserted data. 1262 : * 1263 : * This function will insert a copy of the given rvalue before the 1264 : * specified location. 1265 : */ 1266 : iterator 1267 : insert(iterator __position, value_type&& __x) 1268 : { return emplace(__position, std::move(__x)); } 1269 : #endif 1270 : 1271 : /** 1272 : * @brief Inserts a number of copies of given data into the %deque. 1273 : * @param position An iterator into the %deque. 1274 : * @param n Number of elements to be inserted. 1275 : * @param x Data to be inserted. 1276 : * 1277 : * This function will insert a specified number of copies of the given 1278 : * data before the location specified by @a position. 1279 : */ 1280 : void 1281 : insert(iterator __position, size_type __n, const value_type& __x) 1282 : { _M_fill_insert(__position, __n, __x); } 1283 : 1284 : /** 1285 : * @brief Inserts a range into the %deque. 1286 : * @param position An iterator into the %deque. 1287 : * @param first An input iterator. 1288 : * @param last An input iterator. 1289 : * 1290 : * This function will insert copies of the data in the range 1291 : * [first,last) into the %deque before the location specified 1292 : * by @a pos. This is known as "range insert." 1293 : */ 1294 : template<typename _InputIterator> 1295 : void 1296 : insert(iterator __position, _InputIterator __first, 1297 0 : _InputIterator __last) 1298 : { 1299 : // Check whether it's an integral type. If so, it's not an iterator. 1300 : typedef typename std::__is_integer<_InputIterator>::__type _Integral; 1301 0 : _M_insert_dispatch(__position, __first, __last, _Integral()); 1302 0 : } 1303 : 1304 : /** 1305 : * @brief Remove element at given position. 1306 : * @param position Iterator pointing to element to be erased. 1307 : * @return An iterator pointing to the next element (or end()). 1308 : * 1309 : * This function will erase the element at the given position and thus 1310 : * shorten the %deque by one. 1311 : * 1312 : * The user is cautioned that 1313 : * this function only erases the element, and that if the element is 1314 : * itself a pointer, the pointed-to memory is not touched in any way. 1315 : * Managing the pointer is the user's responsibility. 1316 : */ 1317 : iterator 1318 : erase(iterator __position); 1319 : 1320 : /** 1321 : * @brief Remove a range of elements. 1322 : * @param first Iterator pointing to the first element to be erased. 1323 : * @param last Iterator pointing to one past the last element to be 1324 : * erased. 1325 : * @return An iterator pointing to the element pointed to by @a last 1326 : * prior to erasing (or end()). 1327 : * 1328 : * This function will erase the elements in the range [first,last) and 1329 : * shorten the %deque accordingly. 1330 : * 1331 : * The user is cautioned that 1332 : * this function only erases the elements, and that if the elements 1333 : * themselves are pointers, the pointed-to memory is not touched in any 1334 : * way. Managing the pointer is the user's responsibility. 1335 : */ 1336 : iterator 1337 : erase(iterator __first, iterator __last); 1338 : 1339 : /** 1340 : * @brief Swaps data with another %deque. 1341 : * @param x A %deque of the same element and allocator types. 1342 : * 1343 : * This exchanges the elements between two deques in constant time. 1344 : * (Four pointers, so it should be quite fast.) 1345 : * Note that the global std::swap() function is specialized such that 1346 : * std::swap(d1,d2) will feed to this function. 1347 : */ 1348 : void 1349 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1350 : swap(deque&& __x) 1351 : #else 1352 : swap(deque& __x) 1353 : #endif 1354 : { 1355 : std::swap(this->_M_impl._M_start, __x._M_impl._M_start); 1356 : std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); 1357 : std::swap(this->_M_impl._M_map, __x._M_impl._M_map); 1358 : std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size); 1359 : 1360 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1361 : // 431. Swapping containers with unequal allocators. 1362 : std::__alloc_swap<_Tp_alloc_type>::_S_do_it(_M_get_Tp_allocator(), 1363 : __x._M_get_Tp_allocator()); 1364 : } 1365 : 1366 : /** 1367 : * Erases all the elements. Note that this function only erases the 1368 : * elements, and that if the elements themselves are pointers, the 1369 : * pointed-to memory is not touched in any way. Managing the pointer is 1370 : * the user's responsibility. 1371 : */ 1372 : void 1373 922 : clear() 1374 922 : { _M_erase_at_end(begin()); } 1375 : 1376 : protected: 1377 : // Internal constructor functions follow. 1378 : 1379 : // called by the range constructor to implement [23.1.1]/9 1380 : 1381 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1382 : // 438. Ambiguity in the "do the right thing" clause 1383 : template<typename _Integer> 1384 : void 1385 : _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) 1386 : { 1387 : _M_initialize_map(static_cast<size_type>(__n)); 1388 : _M_fill_initialize(__x); 1389 : } 1390 : 1391 : // called by the range constructor to implement [23.1.1]/9 1392 : template<typename _InputIterator> 1393 : void 1394 : _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, 1395 : __false_type) 1396 : { 1397 : typedef typename std::iterator_traits<_InputIterator>:: 1398 : iterator_category _IterCategory; 1399 : _M_range_initialize(__first, __last, _IterCategory()); 1400 : } 1401 : 1402 : // called by the second initialize_dispatch above 1403 : //@{ 1404 : /** 1405 : * @brief Fills the deque with whatever is in [first,last). 1406 : * @param first An input iterator. 1407 : * @param last An input iterator. 1408 : * @return Nothing. 1409 : * 1410 : * If the iterators are actually forward iterators (or better), then the 1411 : * memory layout can be done all at once. Else we move forward using 1412 : * push_back on each value from the iterator. 1413 : */ 1414 : template<typename _InputIterator> 1415 : void 1416 : _M_range_initialize(_InputIterator __first, _InputIterator __last, 1417 : std::input_iterator_tag); 1418 : 1419 : // called by the second initialize_dispatch above 1420 : template<typename _ForwardIterator> 1421 : void 1422 : _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, 1423 : std::forward_iterator_tag); 1424 : //@} 1425 : 1426 : /** 1427 : * @brief Fills the %deque with copies of value. 1428 : * @param value Initial value. 1429 : * @return Nothing. 1430 : * @pre _M_start and _M_finish have already been initialized, 1431 : * but none of the %deque's elements have yet been constructed. 1432 : * 1433 : * This function is called only when the user provides an explicit size 1434 : * (with or without an explicit exemplar value). 1435 : */ 1436 : void 1437 : _M_fill_initialize(const value_type& __value); 1438 : 1439 : // Internal assign functions follow. The *_aux functions do the actual 1440 : // assignment work for the range versions. 1441 : 1442 : // called by the range assign to implement [23.1.1]/9 1443 : 1444 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1445 : // 438. Ambiguity in the "do the right thing" clause 1446 : template<typename _Integer> 1447 : void 1448 : _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) 1449 : { _M_fill_assign(__n, __val); } 1450 : 1451 : // called by the range assign to implement [23.1.1]/9 1452 : template<typename _InputIterator> 1453 : void 1454 : _M_assign_dispatch(_InputIterator __first, _InputIterator __last, 1455 : __false_type) 1456 : { 1457 : typedef typename std::iterator_traits<_InputIterator>:: 1458 : iterator_category _IterCategory; 1459 : _M_assign_aux(__first, __last, _IterCategory()); 1460 : } 1461 : 1462 : // called by the second assign_dispatch above 1463 : template<typename _InputIterator> 1464 : void 1465 : _M_assign_aux(_InputIterator __first, _InputIterator __last, 1466 : std::input_iterator_tag); 1467 : 1468 : // called by the second assign_dispatch above 1469 : template<typename _ForwardIterator> 1470 : void 1471 : _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, 1472 : std::forward_iterator_tag) 1473 : { 1474 : const size_type __len = std::distance(__first, __last); 1475 : if (__len > size()) 1476 : { 1477 : _ForwardIterator __mid = __first; 1478 : std::advance(__mid, size()); 1479 : std::copy(__first, __mid, begin()); 1480 : insert(end(), __mid, __last); 1481 : } 1482 : else 1483 : _M_erase_at_end(std::copy(__first, __last, begin())); 1484 : } 1485 : 1486 : // Called by assign(n,t), and the range assign when it turns out 1487 : // to be the same thing. 1488 : void 1489 : _M_fill_assign(size_type __n, const value_type& __val) 1490 : { 1491 : if (__n > size()) 1492 : { 1493 : std::fill(begin(), end(), __val); 1494 : insert(end(), __n - size(), __val); 1495 : } 1496 : else 1497 : { 1498 : _M_erase_at_end(begin() + difference_type(__n)); 1499 : std::fill(begin(), end(), __val); 1500 : } 1501 : } 1502 : 1503 : //@{ 1504 : /// Helper functions for push_* and pop_*. 1505 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 1506 : void _M_push_back_aux(const value_type&); 1507 : 1508 : void _M_push_front_aux(const value_type&); 1509 : #else 1510 : template<typename... _Args> 1511 : void _M_push_back_aux(_Args&&... __args); 1512 : 1513 : template<typename... _Args> 1514 : void _M_push_front_aux(_Args&&... __args); 1515 : #endif 1516 : 1517 : void _M_pop_back_aux(); 1518 : 1519 : void _M_pop_front_aux(); 1520 : //@} 1521 : 1522 : // Internal insert functions follow. The *_aux functions do the actual 1523 : // insertion work when all shortcuts fail. 1524 : 1525 : // called by the range insert to implement [23.1.1]/9 1526 : 1527 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1528 : // 438. Ambiguity in the "do the right thing" clause 1529 : template<typename _Integer> 1530 : void 1531 : _M_insert_dispatch(iterator __pos, 1532 : _Integer __n, _Integer __x, __true_type) 1533 : { _M_fill_insert(__pos, __n, __x); } 1534 : 1535 : // called by the range insert to implement [23.1.1]/9 1536 : template<typename _InputIterator> 1537 : void 1538 : _M_insert_dispatch(iterator __pos, 1539 : _InputIterator __first, _InputIterator __last, 1540 0 : __false_type) 1541 : { 1542 : typedef typename std::iterator_traits<_InputIterator>:: 1543 : iterator_category _IterCategory; 1544 0 : _M_range_insert_aux(__pos, __first, __last, _IterCategory()); 1545 0 : } 1546 : 1547 : // called by the second insert_dispatch above 1548 : template<typename _InputIterator> 1549 : void 1550 : _M_range_insert_aux(iterator __pos, _InputIterator __first, 1551 : _InputIterator __last, std::input_iterator_tag); 1552 : 1553 : // called by the second insert_dispatch above 1554 : template<typename _ForwardIterator> 1555 : void 1556 : _M_range_insert_aux(iterator __pos, _ForwardIterator __first, 1557 : _ForwardIterator __last, std::forward_iterator_tag); 1558 : 1559 : // Called by insert(p,n,x), and the range insert when it turns out to be 1560 : // the same thing. Can use fill functions in optimal situations, 1561 : // otherwise passes off to insert_aux(p,n,x). 1562 : void 1563 : _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); 1564 : 1565 : // called by insert(p,x) 1566 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 1567 : iterator 1568 : _M_insert_aux(iterator __pos, const value_type& __x); 1569 : #else 1570 : template<typename... _Args> 1571 : iterator 1572 : _M_insert_aux(iterator __pos, _Args&&... __args); 1573 : #endif 1574 : 1575 : // called by insert(p,n,x) via fill_insert 1576 : void 1577 : _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); 1578 : 1579 : // called by range_insert_aux for forward iterators 1580 : template<typename _ForwardIterator> 1581 : void 1582 : _M_insert_aux(iterator __pos, 1583 : _ForwardIterator __first, _ForwardIterator __last, 1584 : size_type __n); 1585 : 1586 : 1587 : // Internal erase functions follow. 1588 : 1589 : void 1590 : _M_destroy_data_aux(iterator __first, iterator __last); 1591 : 1592 : // Called by ~deque(). 1593 : // NB: Doesn't deallocate the nodes. 1594 : template<typename _Alloc1> 1595 : void 1596 : _M_destroy_data(iterator __first, iterator __last, const _Alloc1&) 1597 : { _M_destroy_data_aux(__first, __last); } 1598 : 1599 : void 1600 : _M_destroy_data(iterator __first, iterator __last, 1601 1046 : const std::allocator<_Tp>&) 1602 : { 1603 : if (!__has_trivial_destructor(value_type)) 1604 26 : _M_destroy_data_aux(__first, __last); 1605 1046 : } 1606 : 1607 : // Called by erase(q1, q2). 1608 : void 1609 90 : _M_erase_at_begin(iterator __pos) 1610 : { 1611 90 : _M_destroy_data(begin(), __pos, _M_get_Tp_allocator()); 1612 90 : _M_destroy_nodes(this->_M_impl._M_start._M_node, __pos._M_node); 1613 90 : this->_M_impl._M_start = __pos; 1614 90 : } 1615 : 1616 : // Called by erase(q1, q2), resize(), clear(), _M_assign_aux, 1617 : // _M_fill_assign, operator=. 1618 : void 1619 926 : _M_erase_at_end(iterator __pos) 1620 : { 1621 926 : _M_destroy_data(__pos, end(), _M_get_Tp_allocator()); 1622 926 : _M_destroy_nodes(__pos._M_node + 1, 1623 : this->_M_impl._M_finish._M_node + 1); 1624 926 : this->_M_impl._M_finish = __pos; 1625 926 : } 1626 : 1627 : //@{ 1628 : /// Memory-handling helpers for the previous internal insert functions. 1629 : iterator 1630 0 : _M_reserve_elements_at_front(size_type __n) 1631 : { 1632 : const size_type __vacancies = this->_M_impl._M_start._M_cur 1633 0 : - this->_M_impl._M_start._M_first; 1634 0 : if (__n > __vacancies) 1635 0 : _M_new_elements_at_front(__n - __vacancies); 1636 0 : return this->_M_impl._M_start - difference_type(__n); 1637 : } 1638 : 1639 : iterator 1640 0 : _M_reserve_elements_at_back(size_type __n) 1641 : { 1642 : const size_type __vacancies = (this->_M_impl._M_finish._M_last 1643 0 : - this->_M_impl._M_finish._M_cur) - 1; 1644 0 : if (__n > __vacancies) 1645 0 : _M_new_elements_at_back(__n - __vacancies); 1646 0 : return this->_M_impl._M_finish + difference_type(__n); 1647 : } 1648 : 1649 : void 1650 : _M_new_elements_at_front(size_type __new_elements); 1651 : 1652 : void 1653 : _M_new_elements_at_back(size_type __new_elements); 1654 : //@} 1655 : 1656 : 1657 : //@{ 1658 : /** 1659 : * @brief Memory-handling helpers for the major %map. 1660 : * 1661 : * Makes sure the _M_map has space for new nodes. Does not 1662 : * actually add the nodes. Can invalidate _M_map pointers. 1663 : * (And consequently, %deque iterators.) 1664 : */ 1665 : void 1666 13 : _M_reserve_map_at_back(size_type __nodes_to_add = 1) 1667 : { 1668 13 : if (__nodes_to_add + 1 > this->_M_impl._M_map_size 1669 : - (this->_M_impl._M_finish._M_node - this->_M_impl._M_map)) 1670 0 : _M_reallocate_map(__nodes_to_add, false); 1671 13 : } 1672 : 1673 : void 1674 0 : _M_reserve_map_at_front(size_type __nodes_to_add = 1) 1675 : { 1676 0 : if (__nodes_to_add > size_type(this->_M_impl._M_start._M_node 1677 : - this->_M_impl._M_map)) 1678 0 : _M_reallocate_map(__nodes_to_add, true); 1679 0 : } 1680 : 1681 : void 1682 : _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); 1683 : //@} 1684 : }; 1685 : 1686 : 1687 : /** 1688 : * @brief Deque equality comparison. 1689 : * @param x A %deque. 1690 : * @param y A %deque of the same type as @a x. 1691 : * @return True iff the size and elements of the deques are equal. 1692 : * 1693 : * This is an equivalence relation. It is linear in the size of the 1694 : * deques. Deques are considered equivalent if their sizes are equal, 1695 : * and if corresponding elements compare equal. 1696 : */ 1697 : template<typename _Tp, typename _Alloc> 1698 : inline bool 1699 : operator==(const deque<_Tp, _Alloc>& __x, 1700 : const deque<_Tp, _Alloc>& __y) 1701 : { return __x.size() == __y.size() 1702 : && std::equal(__x.begin(), __x.end(), __y.begin()); } 1703 : 1704 : /** 1705 : * @brief Deque ordering relation. 1706 : * @param x A %deque. 1707 : * @param y A %deque of the same type as @a x. 1708 : * @return True iff @a x is lexicographically less than @a y. 1709 : * 1710 : * This is a total ordering relation. It is linear in the size of the 1711 : * deques. The elements must be comparable with @c <. 1712 : * 1713 : * See std::lexicographical_compare() for how the determination is made. 1714 : */ 1715 : template<typename _Tp, typename _Alloc> 1716 : inline bool 1717 : operator<(const deque<_Tp, _Alloc>& __x, 1718 : const deque<_Tp, _Alloc>& __y) 1719 : { return std::lexicographical_compare(__x.begin(), __x.end(), 1720 : __y.begin(), __y.end()); } 1721 : 1722 : /// Based on operator== 1723 : template<typename _Tp, typename _Alloc> 1724 : inline bool 1725 : operator!=(const deque<_Tp, _Alloc>& __x, 1726 : const deque<_Tp, _Alloc>& __y) 1727 : { return !(__x == __y); } 1728 : 1729 : /// Based on operator< 1730 : template<typename _Tp, typename _Alloc> 1731 : inline bool 1732 : operator>(const deque<_Tp, _Alloc>& __x, 1733 : const deque<_Tp, _Alloc>& __y) 1734 : { return __y < __x; } 1735 : 1736 : /// Based on operator< 1737 : template<typename _Tp, typename _Alloc> 1738 : inline bool 1739 : operator<=(const deque<_Tp, _Alloc>& __x, 1740 : const deque<_Tp, _Alloc>& __y) 1741 : { return !(__y < __x); } 1742 : 1743 : /// Based on operator< 1744 : template<typename _Tp, typename _Alloc> 1745 : inline bool 1746 : operator>=(const deque<_Tp, _Alloc>& __x, 1747 : const deque<_Tp, _Alloc>& __y) 1748 : { return !(__x < __y); } 1749 : 1750 : /// See std::deque::swap(). 1751 : template<typename _Tp, typename _Alloc> 1752 : inline void 1753 : swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) 1754 : { __x.swap(__y); } 1755 : 1756 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1757 : template<typename _Tp, typename _Alloc> 1758 : inline void 1759 : swap(deque<_Tp,_Alloc>&& __x, deque<_Tp,_Alloc>& __y) 1760 : { __x.swap(__y); } 1761 : 1762 : template<typename _Tp, typename _Alloc> 1763 : inline void 1764 : swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>&& __y) 1765 : { __x.swap(__y); } 1766 : #endif 1767 : 1768 : _GLIBCXX_END_NESTED_NAMESPACE 1769 : 1770 : #endif /* _STL_DEQUE_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Vector implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_vector.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_VECTOR_H 63 : #define _STL_VECTOR_H 1 64 : 65 : #include <bits/stl_iterator_base_funcs.h> 66 : #include <bits/functexcept.h> 67 : #include <bits/concept_check.h> 68 : 69 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) 70 : 71 : /// See bits/stl_deque.h's _Deque_base for an explanation. 72 : template<typename _Tp, typename _Alloc> 73 : struct _Vector_base 74 : { 75 : typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; 76 : 77 : struct _Vector_impl 78 : : public _Tp_alloc_type 79 4841 : { 80 : _Tp* _M_start; 81 : _Tp* _M_finish; 82 : _Tp* _M_end_of_storage; 83 : 84 4840 : _Vector_impl() 85 4840 : : _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0) 86 4840 : { } 87 : 88 9 : _Vector_impl(_Tp_alloc_type const& __a) 89 9 : : _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) 90 9 : { } 91 : }; 92 : 93 : public: 94 : typedef _Alloc allocator_type; 95 : 96 : _Tp_alloc_type& 97 119679 : _M_get_Tp_allocator() 98 119679 : { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } 99 : 100 : const _Tp_alloc_type& 101 41426 : _M_get_Tp_allocator() const 102 41426 : { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); } 103 : 104 : allocator_type 105 : get_allocator() const 106 : { return allocator_type(_M_get_Tp_allocator()); } 107 : 108 4840 : _Vector_base() 109 4840 : : _M_impl() { } 110 : 111 : _Vector_base(const allocator_type& __a) 112 : : _M_impl(__a) { } 113 : 114 9 : _Vector_base(size_t __n, const allocator_type& __a) 115 9 : : _M_impl(__a) 116 : { 117 9 : this->_M_impl._M_start = this->_M_allocate(__n); 118 9 : this->_M_impl._M_finish = this->_M_impl._M_start; 119 9 : this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; 120 9 : } 121 : 122 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 123 : _Vector_base(_Vector_base&& __x) 124 : : _M_impl(__x._M_get_Tp_allocator()) 125 : { 126 : this->_M_impl._M_start = __x._M_impl._M_start; 127 : this->_M_impl._M_finish = __x._M_impl._M_finish; 128 : this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage; 129 : __x._M_impl._M_start = 0; 130 : __x._M_impl._M_finish = 0; 131 : __x._M_impl._M_end_of_storage = 0; 132 : } 133 : #endif 134 : 135 4841 : ~_Vector_base() 136 4841 : { _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage 137 4841 : - this->_M_impl._M_start); } 138 : 139 : public: 140 : _Vector_impl _M_impl; 141 : 142 : _Tp* 143 20727 : _M_allocate(size_t __n) 144 20727 : { return __n != 0 ? _M_impl.allocate(__n) : 0; } 145 : 146 : void 147 25559 : _M_deallocate(_Tp* __p, size_t __n) 148 : { 149 25559 : if (__p) 150 20616 : _M_impl.deallocate(__p, __n); 151 25559 : } 152 : }; 153 : 154 : 155 : /** 156 : * @brief A standard container which offers fixed time access to 157 : * individual elements in any order. 158 : * 159 : * @ingroup Containers 160 : * @ingroup Sequences 161 : * 162 : * Meets the requirements of a <a href="tables.html#65">container</a>, a 163 : * <a href="tables.html#66">reversible container</a>, and a 164 : * <a href="tables.html#67">sequence</a>, including the 165 : * <a href="tables.html#68">optional sequence requirements</a> with the 166 : * %exception of @c push_front and @c pop_front. 167 : * 168 : * In some terminology a %vector can be described as a dynamic 169 : * C-style array, it offers fast and efficient access to individual 170 : * elements in any order and saves the user from worrying about 171 : * memory and size allocation. Subscripting ( @c [] ) access is 172 : * also provided as with C-style arrays. 173 : */ 174 : template<typename _Tp, typename _Alloc = std::allocator<_Tp> > 175 : class vector : protected _Vector_base<_Tp, _Alloc> 176 : { 177 : // Concept requirements. 178 : typedef typename _Alloc::value_type _Alloc_value_type; 179 : __glibcxx_class_requires(_Tp, _SGIAssignableConcept) 180 : __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) 181 : 182 : typedef _Vector_base<_Tp, _Alloc> _Base; 183 : typedef vector<_Tp, _Alloc> vector_type; 184 : typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; 185 : 186 : public: 187 : typedef _Tp value_type; 188 : typedef typename _Tp_alloc_type::pointer pointer; 189 : typedef typename _Tp_alloc_type::const_pointer const_pointer; 190 : typedef typename _Tp_alloc_type::reference reference; 191 : typedef typename _Tp_alloc_type::const_reference const_reference; 192 : typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator; 193 : typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type> 194 : const_iterator; 195 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 196 : typedef std::reverse_iterator<iterator> reverse_iterator; 197 : typedef size_t size_type; 198 : typedef ptrdiff_t difference_type; 199 : typedef _Alloc allocator_type; 200 : 201 : protected: 202 : using _Base::_M_allocate; 203 : using _Base::_M_deallocate; 204 : using _Base::_M_impl; 205 : using _Base::_M_get_Tp_allocator; 206 : 207 : public: 208 : // [23.2.4.1] construct/copy/destroy 209 : // (assign() and get_allocator() are also listed in this section) 210 : /** 211 : * @brief Default constructor creates no elements. 212 : */ 213 4840 : vector() 214 4840 : : _Base() { } 215 : 216 : /** 217 : * @brief Creates a %vector with no elements. 218 : * @param a An allocator object. 219 : */ 220 : explicit 221 : vector(const allocator_type& __a) 222 : : _Base(__a) { } 223 : 224 : /** 225 : * @brief Creates a %vector with copies of an exemplar element. 226 : * @param n The number of elements to initially create. 227 : * @param value An element to copy. 228 : * @param a An allocator. 229 : * 230 : * This constructor fills the %vector with @a n copies of @a value. 231 : */ 232 : explicit 233 : vector(size_type __n, const value_type& __value = value_type(), 234 9 : const allocator_type& __a = allocator_type()) 235 9 : : _Base(__n, __a) 236 9 : { _M_fill_initialize(__n, __value); } 237 : 238 : /** 239 : * @brief %Vector copy constructor. 240 : * @param x A %vector of identical element and allocator types. 241 : * 242 : * The newly-created %vector uses a copy of the allocation 243 : * object used by @a x. All the elements of @a x are copied, 244 : * but any extra memory in 245 : * @a x (for fast expansion) will not be copied. 246 : */ 247 0 : vector(const vector& __x) 248 0 : : _Base(__x.size(), __x._M_get_Tp_allocator()) 249 0 : { this->_M_impl._M_finish = 250 : std::__uninitialized_copy_a(__x.begin(), __x.end(), 251 : this->_M_impl._M_start, 252 : _M_get_Tp_allocator()); 253 0 : } 254 : 255 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 256 : /** 257 : * @brief %Vector move constructor. 258 : * @param x A %vector of identical element and allocator types. 259 : * 260 : * The newly-created %vector contains the exact contents of @a x. 261 : * The contents of @a x are a valid, but unspecified %vector. 262 : */ 263 : vector(vector&& __x) 264 : : _Base(std::forward<_Base>(__x)) { } 265 : #endif 266 : 267 : /** 268 : * @brief Builds a %vector from a range. 269 : * @param first An input iterator. 270 : * @param last An input iterator. 271 : * @param a An allocator. 272 : * 273 : * Create a %vector consisting of copies of the elements from 274 : * [first,last). 275 : * 276 : * If the iterators are forward, bidirectional, or 277 : * random-access, then this will call the elements' copy 278 : * constructor N times (where N is distance(first,last)) and do 279 : * no memory reallocation. But if only input iterators are 280 : * used, then this will do at most 2N calls to the copy 281 : * constructor, and logN memory reallocations. 282 : */ 283 : template<typename _InputIterator> 284 : vector(_InputIterator __first, _InputIterator __last, 285 : const allocator_type& __a = allocator_type()) 286 : : _Base(__a) 287 : { 288 : // Check whether it's an integral type. If so, it's not an iterator. 289 : typedef typename std::__is_integer<_InputIterator>::__type _Integral; 290 : _M_initialize_dispatch(__first, __last, _Integral()); 291 : } 292 : 293 : /** 294 : * The dtor only erases the elements, and note that if the 295 : * elements themselves are pointers, the pointed-to memory is 296 : * not touched in any way. Managing the pointer is the user's 297 : * responsibility. 298 : */ 299 4841 : ~vector() 300 4841 : { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 301 4841 : _M_get_Tp_allocator()); } 302 : 303 : /** 304 : * @brief %Vector assignment operator. 305 : * @param x A %vector of identical element and allocator types. 306 : * 307 : * All the elements of @a x are copied, but any extra memory in 308 : * @a x (for fast expansion) will not be copied. Unlike the 309 : * copy constructor, the allocator object is not copied. 310 : */ 311 : vector& 312 : operator=(const vector& __x); 313 : 314 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 315 : /** 316 : * @brief %Vector move assignment operator. 317 : * @param x A %vector of identical element and allocator types. 318 : * 319 : * The contents of @a x are moved into this %vector (without copying). 320 : * @a x is a valid, but unspecified %vector. 321 : */ 322 : vector& 323 : operator=(vector&& __x) 324 : { 325 : // NB: DR 675. 326 : this->clear(); 327 : this->swap(__x); 328 : return *this; 329 : } 330 : #endif 331 : 332 : /** 333 : * @brief Assigns a given value to a %vector. 334 : * @param n Number of elements to be assigned. 335 : * @param val Value to be assigned. 336 : * 337 : * This function fills a %vector with @a n copies of the given 338 : * value. Note that the assignment completely changes the 339 : * %vector and that the resulting %vector's size is the same as 340 : * the number of elements assigned. Old data may be lost. 341 : */ 342 : void 343 : assign(size_type __n, const value_type& __val) 344 : { _M_fill_assign(__n, __val); } 345 : 346 : /** 347 : * @brief Assigns a range to a %vector. 348 : * @param first An input iterator. 349 : * @param last An input iterator. 350 : * 351 : * This function fills a %vector with copies of the elements in the 352 : * range [first,last). 353 : * 354 : * Note that the assignment completely changes the %vector and 355 : * that the resulting %vector's size is the same as the number 356 : * of elements assigned. Old data may be lost. 357 : */ 358 : template<typename _InputIterator> 359 : void 360 : assign(_InputIterator __first, _InputIterator __last) 361 : { 362 : // Check whether it's an integral type. If so, it's not an iterator. 363 : typedef typename std::__is_integer<_InputIterator>::__type _Integral; 364 : _M_assign_dispatch(__first, __last, _Integral()); 365 : } 366 : 367 : /// Get a copy of the memory allocation object. 368 : using _Base::get_allocator; 369 : 370 : // iterators 371 : /** 372 : * Returns a read/write iterator that points to the first 373 : * element in the %vector. Iteration is done in ordinary 374 : * element order. 375 : */ 376 : iterator 377 4034 : begin() 378 4034 : { return iterator(this->_M_impl._M_start); } 379 : 380 : /** 381 : * Returns a read-only (constant) iterator that points to the 382 : * first element in the %vector. Iteration is done in ordinary 383 : * element order. 384 : */ 385 : const_iterator 386 91 : begin() const 387 91 : { return const_iterator(this->_M_impl._M_start); } 388 : 389 : /** 390 : * Returns a read/write iterator that points one past the last 391 : * element in the %vector. Iteration is done in ordinary 392 : * element order. 393 : */ 394 : iterator 395 69161 : end() 396 69161 : { return iterator(this->_M_impl._M_finish); } 397 : 398 : /** 399 : * Returns a read-only (constant) iterator that points one past 400 : * the last element in the %vector. Iteration is done in 401 : * ordinary element order. 402 : */ 403 : const_iterator 404 175 : end() const 405 175 : { return const_iterator(this->_M_impl._M_finish); } 406 : 407 : /** 408 : * Returns a read/write reverse iterator that points to the 409 : * last element in the %vector. Iteration is done in reverse 410 : * element order. 411 : */ 412 : reverse_iterator 413 1 : rbegin() 414 1 : { return reverse_iterator(end()); } 415 : 416 : /** 417 : * Returns a read-only (constant) reverse iterator that points 418 : * to the last element in the %vector. Iteration is done in 419 : * reverse element order. 420 : */ 421 : const_reverse_iterator 422 : rbegin() const 423 : { return const_reverse_iterator(end()); } 424 : 425 : /** 426 : * Returns a read/write reverse iterator that points to one 427 : * before the first element in the %vector. Iteration is done 428 : * in reverse element order. 429 : */ 430 : reverse_iterator 431 : rend() 432 : { return reverse_iterator(begin()); } 433 : 434 : /** 435 : * Returns a read-only (constant) reverse iterator that points 436 : * to one before the first element in the %vector. Iteration 437 : * is done in reverse element order. 438 : */ 439 : const_reverse_iterator 440 : rend() const 441 : { return const_reverse_iterator(begin()); } 442 : 443 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 444 : /** 445 : * Returns a read-only (constant) iterator that points to the 446 : * first element in the %vector. Iteration is done in ordinary 447 : * element order. 448 : */ 449 : const_iterator 450 : cbegin() const 451 : { return const_iterator(this->_M_impl._M_start); } 452 : 453 : /** 454 : * Returns a read-only (constant) iterator that points one past 455 : * the last element in the %vector. Iteration is done in 456 : * ordinary element order. 457 : */ 458 : const_iterator 459 : cend() const 460 : { return const_iterator(this->_M_impl._M_finish); } 461 : 462 : /** 463 : * Returns a read-only (constant) reverse iterator that points 464 : * to the last element in the %vector. Iteration is done in 465 : * reverse element order. 466 : */ 467 : const_reverse_iterator 468 : crbegin() const 469 : { return const_reverse_iterator(end()); } 470 : 471 : /** 472 : * Returns a read-only (constant) reverse iterator that points 473 : * to one before the first element in the %vector. Iteration 474 : * is done in reverse element order. 475 : */ 476 : const_reverse_iterator 477 : crend() const 478 : { return const_reverse_iterator(begin()); } 479 : #endif 480 : 481 : // [23.2.4.2] capacity 482 : /** Returns the number of elements in the %vector. */ 483 : size_type 484 1028954 : size() const 485 1028954 : { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); } 486 : 487 : /** Returns the size() of the largest possible %vector. */ 488 : size_type 489 41426 : max_size() const 490 41426 : { return _M_get_Tp_allocator().max_size(); } 491 : 492 : /** 493 : * @brief Resizes the %vector to the specified number of elements. 494 : * @param new_size Number of elements the %vector should contain. 495 : * @param x Data with which new elements should be populated. 496 : * 497 : * This function will %resize the %vector to the specified 498 : * number of elements. If the number is smaller than the 499 : * %vector's current size the %vector is truncated, otherwise 500 : * the %vector is extended and new elements are populated with 501 : * given data. 502 : */ 503 : void 504 22443 : resize(size_type __new_size, value_type __x = value_type()) 505 : { 506 22443 : if (__new_size < size()) 507 0 : _M_erase_at_end(this->_M_impl._M_start + __new_size); 508 : else 509 22443 : insert(end(), __new_size - size(), __x); 510 22443 : } 511 : 512 : /** 513 : * Returns the total number of elements that the %vector can 514 : * hold before needing to allocate more memory. 515 : */ 516 : size_type 517 10 : capacity() const 518 : { return size_type(this->_M_impl._M_end_of_storage 519 10 : - this->_M_impl._M_start); } 520 : 521 : /** 522 : * Returns true if the %vector is empty. (Thus begin() would 523 : * equal end().) 524 : */ 525 : bool 526 25 : empty() const 527 25 : { return begin() == end(); } 528 : 529 : /** 530 : * @brief Attempt to preallocate enough memory for specified number of 531 : * elements. 532 : * @param n Number of elements required. 533 : * @throw std::length_error If @a n exceeds @c max_size(). 534 : * 535 : * This function attempts to reserve enough memory for the 536 : * %vector to hold the specified number of elements. If the 537 : * number requested is more than max_size(), length_error is 538 : * thrown. 539 : * 540 : * The advantage of this function is that if optimal code is a 541 : * necessity and the user can determine the number of elements 542 : * that will be required, the user can reserve the memory in 543 : * %advance, and thus prevent a possible reallocation of memory 544 : * and copying of %vector data. 545 : */ 546 : void 547 : reserve(size_type __n); 548 : 549 : // element access 550 : /** 551 : * @brief Subscript access to the data contained in the %vector. 552 : * @param n The index of the element for which data should be 553 : * accessed. 554 : * @return Read/write reference to data. 555 : * 556 : * This operator allows for easy, array-style, data access. 557 : * Note that data access with this operator is unchecked and 558 : * out_of_range lookups are not defined. (For checked lookups 559 : * see at().) 560 : */ 561 : reference 562 256895 : operator[](size_type __n) 563 256895 : { return *(this->_M_impl._M_start + __n); } 564 : 565 : /** 566 : * @brief Subscript access to the data contained in the %vector. 567 : * @param n The index of the element for which data should be 568 : * accessed. 569 : * @return Read-only (constant) reference to data. 570 : * 571 : * This operator allows for easy, array-style, data access. 572 : * Note that data access with this operator is unchecked and 573 : * out_of_range lookups are not defined. (For checked lookups 574 : * see at().) 575 : */ 576 : const_reference 577 1925198 : operator[](size_type __n) const 578 1925198 : { return *(this->_M_impl._M_start + __n); } 579 : 580 : protected: 581 : /// Safety check used only from at(). 582 : void 583 : _M_range_check(size_type __n) const 584 : { 585 : if (__n >= this->size()) 586 : __throw_out_of_range(__N("vector::_M_range_check")); 587 : } 588 : 589 : public: 590 : /** 591 : * @brief Provides access to the data contained in the %vector. 592 : * @param n The index of the element for which data should be 593 : * accessed. 594 : * @return Read/write reference to data. 595 : * @throw std::out_of_range If @a n is an invalid index. 596 : * 597 : * This function provides for safer data access. The parameter 598 : * is first checked that it is in the range of the vector. The 599 : * function throws out_of_range if the check fails. 600 : */ 601 : reference 602 : at(size_type __n) 603 : { 604 : _M_range_check(__n); 605 : return (*this)[__n]; 606 : } 607 : 608 : /** 609 : * @brief Provides access to the data contained in the %vector. 610 : * @param n The index of the element for which data should be 611 : * accessed. 612 : * @return Read-only (constant) reference to data. 613 : * @throw std::out_of_range If @a n is an invalid index. 614 : * 615 : * This function provides for safer data access. The parameter 616 : * is first checked that it is in the range of the vector. The 617 : * function throws out_of_range if the check fails. 618 : */ 619 : const_reference 620 : at(size_type __n) const 621 : { 622 : _M_range_check(__n); 623 : return (*this)[__n]; 624 : } 625 : 626 : /** 627 : * Returns a read/write reference to the data at the first 628 : * element of the %vector. 629 : */ 630 : reference 631 : front() 632 : { return *begin(); } 633 : 634 : /** 635 : * Returns a read-only (constant) reference to the data at the first 636 : * element of the %vector. 637 : */ 638 : const_reference 639 : front() const 640 : { return *begin(); } 641 : 642 : /** 643 : * Returns a read/write reference to the data at the last 644 : * element of the %vector. 645 : */ 646 : reference 647 3 : back() 648 3 : { return *(end() - 1); } 649 : 650 : /** 651 : * Returns a read-only (constant) reference to the data at the 652 : * last element of the %vector. 653 : */ 654 : const_reference 655 : back() const 656 : { return *(end() - 1); } 657 : 658 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 659 : // DR 464. Suggestion for new member functions in standard containers. 660 : // data access 661 : /** 662 : * Returns a pointer such that [data(), data() + size()) is a valid 663 : * range. For a non-empty %vector, data() == &front(). 664 : */ 665 : pointer 666 : data() 667 : { return pointer(this->_M_impl._M_start); } 668 : 669 : const_pointer 670 : data() const 671 : { return const_pointer(this->_M_impl._M_start); } 672 : 673 : // [23.2.4.3] modifiers 674 : /** 675 : * @brief Add data to the end of the %vector. 676 : * @param x Data to be added. 677 : * 678 : * This is a typical stack operation. The function creates an 679 : * element at the end of the %vector and assigns the given data 680 : * to it. Due to the nature of a %vector this operation can be 681 : * done in constant time if the %vector has preallocated space 682 : * available. 683 : */ 684 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 685 : void 686 129213 : push_back(const value_type& __x) 687 : { 688 129213 : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) 689 : { 690 108914 : this->_M_impl.construct(this->_M_impl._M_finish, __x); 691 108914 : ++this->_M_impl._M_finish; 692 : } 693 : else 694 20299 : _M_insert_aux(end(), __x); 695 129213 : } 696 : #else 697 : template<typename... _Args> 698 : void 699 : push_back(_Args&&... __args) 700 : { 701 : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) 702 : { 703 : this->_M_impl.construct(this->_M_impl._M_finish, 704 : std::forward<_Args>(__args)...); 705 : ++this->_M_impl._M_finish; 706 : } 707 : else 708 : _M_insert_aux(end(), std::forward<_Args>(__args)...); 709 : } 710 : #endif 711 : 712 : /** 713 : * @brief Removes last element. 714 : * 715 : * This is a typical stack operation. It shrinks the %vector by one. 716 : * 717 : * Note that no data is returned, and if the last element's 718 : * data is needed, it should be retrieved before pop_back() is 719 : * called. 720 : */ 721 : void 722 3 : pop_back() 723 : { 724 3 : --this->_M_impl._M_finish; 725 3 : this->_M_impl.destroy(this->_M_impl._M_finish); 726 3 : } 727 : 728 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 729 : /** 730 : * @brief Inserts an object in %vector before specified iterator. 731 : * @param position An iterator into the %vector. 732 : * @param args Arguments. 733 : * @return An iterator that points to the inserted data. 734 : * 735 : * This function will insert an object of type T constructed 736 : * with T(std::forward<Args>(args)...) before the specified location. 737 : * Note that this kind of operation could be expensive for a %vector 738 : * and if it is frequently used the user should consider using 739 : * std::list. 740 : */ 741 : template<typename... _Args> 742 : iterator 743 : emplace(iterator __position, _Args&&... __args); 744 : #endif 745 : 746 : /** 747 : * @brief Inserts given value into %vector before specified iterator. 748 : * @param position An iterator into the %vector. 749 : * @param x Data to be inserted. 750 : * @return An iterator that points to the inserted data. 751 : * 752 : * This function will insert a copy of the given value before 753 : * the specified location. Note that this kind of operation 754 : * could be expensive for a %vector and if it is frequently 755 : * used the user should consider using std::list. 756 : */ 757 : iterator 758 : insert(iterator __position, const value_type& __x); 759 : 760 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 761 : /** 762 : * @brief Inserts given rvalue into %vector before specified iterator. 763 : * @param position An iterator into the %vector. 764 : * @param x Data to be inserted. 765 : * @return An iterator that points to the inserted data. 766 : * 767 : * This function will insert a copy of the given rvalue before 768 : * the specified location. Note that this kind of operation 769 : * could be expensive for a %vector and if it is frequently 770 : * used the user should consider using std::list. 771 : */ 772 : iterator 773 : insert(iterator __position, value_type&& __x) 774 : { return emplace(__position, std::move(__x)); } 775 : #endif 776 : 777 : /** 778 : * @brief Inserts a number of copies of given data into the %vector. 779 : * @param position An iterator into the %vector. 780 : * @param n Number of elements to be inserted. 781 : * @param x Data to be inserted. 782 : * 783 : * This function will insert a specified number of copies of 784 : * the given data before the location specified by @a position. 785 : * 786 : * Note that this kind of operation could be expensive for a 787 : * %vector and if it is frequently used the user should 788 : * consider using std::list. 789 : */ 790 : void 791 22443 : insert(iterator __position, size_type __n, const value_type& __x) 792 22443 : { _M_fill_insert(__position, __n, __x); } 793 : 794 : /** 795 : * @brief Inserts a range into the %vector. 796 : * @param position An iterator into the %vector. 797 : * @param first An input iterator. 798 : * @param last An input iterator. 799 : * 800 : * This function will insert copies of the data in the range 801 : * [first,last) into the %vector before the location specified 802 : * by @a pos. 803 : * 804 : * Note that this kind of operation could be expensive for a 805 : * %vector and if it is frequently used the user should 806 : * consider using std::list. 807 : */ 808 : template<typename _InputIterator> 809 : void 810 : insert(iterator __position, _InputIterator __first, 811 : _InputIterator __last) 812 : { 813 : // Check whether it's an integral type. If so, it's not an iterator. 814 : typedef typename std::__is_integer<_InputIterator>::__type _Integral; 815 : _M_insert_dispatch(__position, __first, __last, _Integral()); 816 : } 817 : 818 : /** 819 : * @brief Remove element at given position. 820 : * @param position Iterator pointing to element to be erased. 821 : * @return An iterator pointing to the next element (or end()). 822 : * 823 : * This function will erase the element at the given position and thus 824 : * shorten the %vector by one. 825 : * 826 : * Note This operation could be expensive and if it is 827 : * frequently used the user should consider using std::list. 828 : * The user is also cautioned that this function only erases 829 : * the element, and that if the element is itself a pointer, 830 : * the pointed-to memory is not touched in any way. Managing 831 : * the pointer is the user's responsibility. 832 : */ 833 : iterator 834 : erase(iterator __position); 835 : 836 : /** 837 : * @brief Remove a range of elements. 838 : * @param first Iterator pointing to the first element to be erased. 839 : * @param last Iterator pointing to one past the last element to be 840 : * erased. 841 : * @return An iterator pointing to the element pointed to by @a last 842 : * prior to erasing (or end()). 843 : * 844 : * This function will erase the elements in the range [first,last) and 845 : * shorten the %vector accordingly. 846 : * 847 : * Note This operation could be expensive and if it is 848 : * frequently used the user should consider using std::list. 849 : * The user is also cautioned that this function only erases 850 : * the elements, and that if the elements themselves are 851 : * pointers, the pointed-to memory is not touched in any way. 852 : * Managing the pointer is the user's responsibility. 853 : */ 854 : iterator 855 : erase(iterator __first, iterator __last); 856 : 857 : /** 858 : * @brief Swaps data with another %vector. 859 : * @param x A %vector of the same element and allocator types. 860 : * 861 : * This exchanges the elements between two vectors in constant time. 862 : * (Three pointers, so it should be quite fast.) 863 : * Note that the global std::swap() function is specialized such that 864 : * std::swap(v1,v2) will feed to this function. 865 : */ 866 : void 867 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 868 : swap(vector&& __x) 869 : #else 870 : swap(vector& __x) 871 : #endif 872 : { 873 : std::swap(this->_M_impl._M_start, __x._M_impl._M_start); 874 : std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); 875 : std::swap(this->_M_impl._M_end_of_storage, 876 : __x._M_impl._M_end_of_storage); 877 : 878 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 879 : // 431. Swapping containers with unequal allocators. 880 : std::__alloc_swap<_Tp_alloc_type>::_S_do_it(_M_get_Tp_allocator(), 881 : __x._M_get_Tp_allocator()); 882 : } 883 : 884 : /** 885 : * Erases all the elements. Note that this function only erases the 886 : * elements, and that if the elements themselves are pointers, the 887 : * pointed-to memory is not touched in any way. Managing the pointer is 888 : * the user's responsibility. 889 : */ 890 : void 891 7856 : clear() 892 7856 : { _M_erase_at_end(this->_M_impl._M_start); } 893 : 894 : protected: 895 : /** 896 : * Memory expansion handler. Uses the member allocation function to 897 : * obtain @a n bytes of memory, and then copies [first,last) into it. 898 : */ 899 : template<typename _ForwardIterator> 900 : pointer 901 : _M_allocate_and_copy(size_type __n, 902 10 : _ForwardIterator __first, _ForwardIterator __last) 903 : { 904 10 : pointer __result = this->_M_allocate(__n); 905 : try 906 : { 907 10 : std::__uninitialized_copy_a(__first, __last, __result, 908 : _M_get_Tp_allocator()); 909 10 : return __result; 910 : } 911 0 : catch(...) 912 : { 913 0 : _M_deallocate(__result, __n); 914 0 : __throw_exception_again; 915 : } 916 : } 917 : 918 : 919 : // Internal constructor functions follow. 920 : 921 : // Called by the range constructor to implement [23.1.1]/9 922 : 923 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 924 : // 438. Ambiguity in the "do the right thing" clause 925 : template<typename _Integer> 926 : void 927 : _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) 928 : { 929 : this->_M_impl._M_start = _M_allocate(static_cast<size_type>(__n)); 930 : this->_M_impl._M_end_of_storage = 931 : this->_M_impl._M_start + static_cast<size_type>(__n); 932 : _M_fill_initialize(static_cast<size_type>(__n), __value); 933 : } 934 : 935 : // Called by the range constructor to implement [23.1.1]/9 936 : template<typename _InputIterator> 937 : void 938 : _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, 939 : __false_type) 940 : { 941 : typedef typename std::iterator_traits<_InputIterator>:: 942 : iterator_category _IterCategory; 943 : _M_range_initialize(__first, __last, _IterCategory()); 944 : } 945 : 946 : // Called by the second initialize_dispatch above 947 : template<typename _InputIterator> 948 : void 949 : _M_range_initialize(_InputIterator __first, 950 : _InputIterator __last, std::input_iterator_tag) 951 : { 952 : for (; __first != __last; ++__first) 953 : push_back(*__first); 954 : } 955 : 956 : // Called by the second initialize_dispatch above 957 : template<typename _ForwardIterator> 958 : void 959 : _M_range_initialize(_ForwardIterator __first, 960 : _ForwardIterator __last, std::forward_iterator_tag) 961 : { 962 : const size_type __n = std::distance(__first, __last); 963 : this->_M_impl._M_start = this->_M_allocate(__n); 964 : this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; 965 : this->_M_impl._M_finish = 966 : std::__uninitialized_copy_a(__first, __last, 967 : this->_M_impl._M_start, 968 : _M_get_Tp_allocator()); 969 : } 970 : 971 : // Called by the first initialize_dispatch above and by the 972 : // vector(n,value,a) constructor. 973 : void 974 9 : _M_fill_initialize(size_type __n, const value_type& __value) 975 : { 976 9 : std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, 977 : _M_get_Tp_allocator()); 978 9 : this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; 979 9 : } 980 : 981 : 982 : // Internal assign functions follow. The *_aux functions do the actual 983 : // assignment work for the range versions. 984 : 985 : // Called by the range assign to implement [23.1.1]/9 986 : 987 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 988 : // 438. Ambiguity in the "do the right thing" clause 989 : template<typename _Integer> 990 : void 991 : _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) 992 : { _M_fill_assign(__n, __val); } 993 : 994 : // Called by the range assign to implement [23.1.1]/9 995 : template<typename _InputIterator> 996 : void 997 : _M_assign_dispatch(_InputIterator __first, _InputIterator __last, 998 : __false_type) 999 : { 1000 : typedef typename std::iterator_traits<_InputIterator>:: 1001 : iterator_category _IterCategory; 1002 : _M_assign_aux(__first, __last, _IterCategory()); 1003 : } 1004 : 1005 : // Called by the second assign_dispatch above 1006 : template<typename _InputIterator> 1007 : void 1008 : _M_assign_aux(_InputIterator __first, _InputIterator __last, 1009 : std::input_iterator_tag); 1010 : 1011 : // Called by the second assign_dispatch above 1012 : template<typename _ForwardIterator> 1013 : void 1014 : _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, 1015 : std::forward_iterator_tag); 1016 : 1017 : // Called by assign(n,t), and the range assign when it turns out 1018 : // to be the same thing. 1019 : void 1020 : _M_fill_assign(size_type __n, const value_type& __val); 1021 : 1022 : 1023 : // Internal insert functions follow. 1024 : 1025 : // Called by the range insert to implement [23.1.1]/9 1026 : 1027 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1028 : // 438. Ambiguity in the "do the right thing" clause 1029 : template<typename _Integer> 1030 : void 1031 : _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, 1032 : __true_type) 1033 : { _M_fill_insert(__pos, __n, __val); } 1034 : 1035 : // Called by the range insert to implement [23.1.1]/9 1036 : template<typename _InputIterator> 1037 : void 1038 : _M_insert_dispatch(iterator __pos, _InputIterator __first, 1039 : _InputIterator __last, __false_type) 1040 : { 1041 : typedef typename std::iterator_traits<_InputIterator>:: 1042 : iterator_category _IterCategory; 1043 : _M_range_insert(__pos, __first, __last, _IterCategory()); 1044 : } 1045 : 1046 : // Called by the second insert_dispatch above 1047 : template<typename _InputIterator> 1048 : void 1049 : _M_range_insert(iterator __pos, _InputIterator __first, 1050 : _InputIterator __last, std::input_iterator_tag); 1051 : 1052 : // Called by the second insert_dispatch above 1053 : template<typename _ForwardIterator> 1054 : void 1055 : _M_range_insert(iterator __pos, _ForwardIterator __first, 1056 : _ForwardIterator __last, std::forward_iterator_tag); 1057 : 1058 : // Called by insert(p,n,x), and the range insert when it turns out to be 1059 : // the same thing. 1060 : void 1061 : _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); 1062 : 1063 : // Called by insert(p,x) 1064 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 1065 : void 1066 : _M_insert_aux(iterator __position, const value_type& __x); 1067 : #else 1068 : template<typename... _Args> 1069 : void 1070 : _M_insert_aux(iterator __position, _Args&&... __args); 1071 : #endif 1072 : 1073 : // Called by the latter. 1074 : size_type 1075 20708 : _M_check_len(size_type __n, const char* __s) const 1076 : { 1077 20708 : if (max_size() - size() < __n) 1078 0 : __throw_length_error(__N(__s)); 1079 : 1080 20708 : const size_type __len = size() + std::max(size(), __n); 1081 20708 : return (__len < size() || __len > max_size()) ? max_size() : __len; 1082 : } 1083 : 1084 : // Internal erase functions follow. 1085 : 1086 : // Called by erase(q1,q2), clear(), resize(), _M_fill_assign, 1087 : // _M_assign_aux. 1088 : void 1089 7856 : _M_erase_at_end(pointer __pos) 1090 : { 1091 7856 : std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator()); 1092 7856 : this->_M_impl._M_finish = __pos; 1093 7856 : } 1094 : }; 1095 : 1096 : 1097 : /** 1098 : * @brief Vector equality comparison. 1099 : * @param x A %vector. 1100 : * @param y A %vector of the same type as @a x. 1101 : * @return True iff the size and elements of the vectors are equal. 1102 : * 1103 : * This is an equivalence relation. It is linear in the size of the 1104 : * vectors. Vectors are considered equivalent if their sizes are equal, 1105 : * and if corresponding elements compare equal. 1106 : */ 1107 : template<typename _Tp, typename _Alloc> 1108 : inline bool 1109 : operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 1110 : { return (__x.size() == __y.size() 1111 : && std::equal(__x.begin(), __x.end(), __y.begin())); } 1112 : 1113 : /** 1114 : * @brief Vector ordering relation. 1115 : * @param x A %vector. 1116 : * @param y A %vector of the same type as @a x. 1117 : * @return True iff @a x is lexicographically less than @a y. 1118 : * 1119 : * This is a total ordering relation. It is linear in the size of the 1120 : * vectors. The elements must be comparable with @c <. 1121 : * 1122 : * See std::lexicographical_compare() for how the determination is made. 1123 : */ 1124 : template<typename _Tp, typename _Alloc> 1125 : inline bool 1126 : operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 1127 : { return std::lexicographical_compare(__x.begin(), __x.end(), 1128 : __y.begin(), __y.end()); } 1129 : 1130 : /// Based on operator== 1131 : template<typename _Tp, typename _Alloc> 1132 : inline bool 1133 : operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 1134 : { return !(__x == __y); } 1135 : 1136 : /// Based on operator< 1137 : template<typename _Tp, typename _Alloc> 1138 : inline bool 1139 : operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 1140 : { return __y < __x; } 1141 : 1142 : /// Based on operator< 1143 : template<typename _Tp, typename _Alloc> 1144 : inline bool 1145 : operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 1146 : { return !(__y < __x); } 1147 : 1148 : /// Based on operator< 1149 : template<typename _Tp, typename _Alloc> 1150 : inline bool 1151 : operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 1152 : { return !(__x < __y); } 1153 : 1154 : /// See std::vector::swap(). 1155 : template<typename _Tp, typename _Alloc> 1156 : inline void 1157 : swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) 1158 : { __x.swap(__y); } 1159 : 1160 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1161 : template<typename _Tp, typename _Alloc> 1162 : inline void 1163 : swap(vector<_Tp, _Alloc>&& __x, vector<_Tp, _Alloc>& __y) 1164 : { __x.swap(__y); } 1165 : 1166 : template<typename _Tp, typename _Alloc> 1167 : inline void 1168 : swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>&& __y) 1169 : { __x.swap(__y); } 1170 : #endif 1171 : 1172 : _GLIBCXX_END_NESTED_NAMESPACE 1173 : 1174 : #endif /* _STL_VECTOR_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Functions used by iterators -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996-1998 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_iterator_base_funcs.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : * 61 : * This file contains all of the general iterator-related utility 62 : * functions, such as distance() and advance(). 63 : */ 64 : 65 : #ifndef _STL_ITERATOR_BASE_FUNCS_H 66 : #define _STL_ITERATOR_BASE_FUNCS_H 1 67 : 68 : #pragma GCC system_header 69 : #include <bits/concept_check.h> 70 : 71 : _GLIBCXX_BEGIN_NAMESPACE(std) 72 : 73 : template<typename _InputIterator> 74 : inline typename iterator_traits<_InputIterator>::difference_type 75 : __distance(_InputIterator __first, _InputIterator __last, 76 13 : input_iterator_tag) 77 : { 78 : // concept requirements 79 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 80 : 81 13 : typename iterator_traits<_InputIterator>::difference_type __n = 0; 82 37 : while (__first != __last) 83 : { 84 11 : ++__first; 85 11 : ++__n; 86 : } 87 13 : return __n; 88 : } 89 : 90 : template<typename _RandomAccessIterator> 91 : inline typename iterator_traits<_RandomAccessIterator>::difference_type 92 : __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, 93 1287 : random_access_iterator_tag) 94 : { 95 : // concept requirements 96 : __glibcxx_function_requires(_RandomAccessIteratorConcept< 97 : _RandomAccessIterator>) 98 1287 : return __last - __first; 99 : } 100 : 101 : /** 102 : * @brief A generalization of pointer arithmetic. 103 : * @param first An input iterator. 104 : * @param last An input iterator. 105 : * @return The distance between them. 106 : * 107 : * Returns @c n such that first + n == last. This requires that @p last 108 : * must be reachable from @p first. Note that @c n may be negative. 109 : * 110 : * For random access iterators, this uses their @c + and @c - operations 111 : * and are constant time. For other %iterator classes they are linear time. 112 : */ 113 : template<typename _InputIterator> 114 : inline typename iterator_traits<_InputIterator>::difference_type 115 1300 : distance(_InputIterator __first, _InputIterator __last) 116 : { 117 : // concept requirements -- taken care of in __distance 118 : return std::__distance(__first, __last, 119 1300 : std::__iterator_category(__first)); 120 : } 121 : 122 : template<typename _InputIterator, typename _Distance> 123 : inline void 124 10 : __advance(_InputIterator& __i, _Distance __n, input_iterator_tag) 125 : { 126 : // concept requirements 127 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 128 41 : while (__n--) 129 21 : ++__i; 130 10 : } 131 : 132 : template<typename _BidirectionalIterator, typename _Distance> 133 : inline void 134 : __advance(_BidirectionalIterator& __i, _Distance __n, 135 55 : bidirectional_iterator_tag) 136 : { 137 : // concept requirements 138 : __glibcxx_function_requires(_BidirectionalIteratorConcept< 139 : _BidirectionalIterator>) 140 55 : if (__n > 0) 141 165 : while (__n--) 142 55 : ++__i; 143 : else 144 0 : while (__n++) 145 0 : --__i; 146 55 : } 147 : 148 : template<typename _RandomAccessIterator, typename _Distance> 149 : inline void 150 : __advance(_RandomAccessIterator& __i, _Distance __n, 151 0 : random_access_iterator_tag) 152 : { 153 : // concept requirements 154 : __glibcxx_function_requires(_RandomAccessIteratorConcept< 155 : _RandomAccessIterator>) 156 0 : __i += __n; 157 0 : } 158 : 159 : /** 160 : * @brief A generalization of pointer arithmetic. 161 : * @param i An input iterator. 162 : * @param n The "delta" by which to change @p i. 163 : * @return Nothing. 164 : * 165 : * This increments @p i by @p n. For bidirectional and random access 166 : * iterators, @p n may be negative, in which case @p i is decremented. 167 : * 168 : * For random access iterators, this uses their @c + and @c - operations 169 : * and are constant time. For other %iterator classes they are linear time. 170 : */ 171 : template<typename _InputIterator, typename _Distance> 172 : inline void 173 65 : advance(_InputIterator& __i, _Distance __n) 174 : { 175 : // concept requirements -- taken care of in __advance 176 65 : typename iterator_traits<_InputIterator>::difference_type __d = __n; 177 65 : std::__advance(__i, __d, std::__iterator_category(__i)); 178 65 : } 179 : 180 : _GLIBCXX_END_NAMESPACE 181 : 182 : #endif /* _STL_ITERATOR_BASE_FUNCS_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
allocator.h |
|
71.4 % | 5 / 7 lines | |
basic_ios.h |
|
0.0 % | 0 / 35 lines | |
basic_string.h |
|
17.4 % | 31 / 178 lines | |
basic_string.tcc |
|
73.9 % | 17 / 23 lines | |
char_traits.h |
|
46.2 % | 6 / 13 lines | |
deque.tcc |
|
19.0 % | 28 / 147 lines | |
ios_base.h |
|
66.7 % | 20 / 30 lines | |
list.tcc |
|
100.0 % | 11 / 11 lines | |
locale_facets.h |
|
0.0 % | 0 / 13 lines | |
postypes.h |
|
0.0 % | 0 / 3 lines | |
stl_algo.h |
|
85.0 % | 192 / 226 lines | |
stl_algobase.h |
|
91.1 % | 72 / 79 lines | |
stl_bvector.h |
|
70.4 % | 81 / 115 lines | |
stl_construct.h |
|
100.0 % | 12 / 12 lines | |
stl_deque.h |
|
78.3 % | 148 / 189 lines | |
stl_function.h |
|
100.0 % | 17 / 17 lines | |
stl_heap.h |
|
0.0 % | 0 / 92 lines | |
stl_iterator.h |
|
93.9 % | 62 / 66 lines | |
stl_iterator_base_funcs.h |
|
82.1 % | 23 / 28 lines | |
stl_iterator_base_types.h |
|
100.0 % | 3 / 3 lines | |
stl_list.h |
|
93.6 % | 88 / 94 lines | |
stl_map.h |
|
100.0 % | 41 / 41 lines | |
stl_move.h |
|
100.0 % | 5 / 5 lines | |
stl_pair.h |
|
100.0 % | 9 / 9 lines | |
stl_set.h |
|
100.0 % | 33 / 33 lines | |
stl_stack.h |
|
100.0 % | 12 / 12 lines | |
stl_tree.h |
|
94.2 % | 278 / 295 lines | |
stl_uninitialized.h |
|
58.1 % | 25 / 43 lines | |
stl_vector.h |
|
91.3 % | 94 / 103 lines | |
stream_iterator.h |
|
100.0 % | 33 / 33 lines | |
vector.tcc |
|
75.0 % | 72 / 96 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Locale support -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License along 19 : // with this library; see the file COPYING. If not, write to the Free 20 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 21 : // USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file locale_facets.h 33 : * This is an internal header file, included by other library headers. 34 : * You should not attempt to use it directly. 35 : */ 36 : 37 : // 38 : // ISO C++ 14882: 22.1 Locales 39 : // 40 : 41 : #ifndef _LOCALE_FACETS_H 42 : #define _LOCALE_FACETS_H 1 43 : 44 : #pragma GCC system_header 45 : 46 : #include <cwctype> // For wctype_t 47 : #include <cctype> 48 : #include <bits/ctype_base.h> 49 : #include <iosfwd> 50 : #include <bits/ios_base.h> // For ios_base, ios_base::iostate 51 : #include <streambuf> 52 : #include <bits/cpp_type_traits.h> 53 : #include <ext/type_traits.h> 54 : #include <ext/numeric_traits.h> 55 : #include <bits/streambuf_iterator.h> 56 : 57 : _GLIBCXX_BEGIN_NAMESPACE(std) 58 : 59 : // NB: Don't instantiate required wchar_t facets if no wchar_t support. 60 : #ifdef _GLIBCXX_USE_WCHAR_T 61 : # define _GLIBCXX_NUM_FACETS 28 62 : #else 63 : # define _GLIBCXX_NUM_FACETS 14 64 : #endif 65 : 66 : // Convert string to numeric value of type _Tv and store results. 67 : // NB: This is specialized for all required types, there is no 68 : // generic definition. 69 : template<typename _Tv> 70 : void 71 : __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err, 72 : const __c_locale& __cloc); 73 : 74 : // Explicit specializations for required types. 75 : template<> 76 : void 77 : __convert_to_v(const char*, float&, ios_base::iostate&, 78 : const __c_locale&); 79 : 80 : template<> 81 : void 82 : __convert_to_v(const char*, double&, ios_base::iostate&, 83 : const __c_locale&); 84 : 85 : template<> 86 : void 87 : __convert_to_v(const char*, long double&, ios_base::iostate&, 88 : const __c_locale&); 89 : 90 : // NB: __pad is a struct, rather than a function, so it can be 91 : // partially-specialized. 92 : template<typename _CharT, typename _Traits> 93 : struct __pad 94 : { 95 : static void 96 : _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, 97 : const _CharT* __olds, const streamsize __newlen, 98 : const streamsize __oldlen); 99 : }; 100 : 101 : // Used by both numeric and monetary facets. 102 : // Inserts "group separator" characters into an array of characters. 103 : // It's recursive, one iteration per group. It moves the characters 104 : // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this 105 : // only with __gsize != 0. 106 : template<typename _CharT> 107 : _CharT* 108 : __add_grouping(_CharT* __s, _CharT __sep, 109 : const char* __gbeg, size_t __gsize, 110 : const _CharT* __first, const _CharT* __last); 111 : 112 : // This template permits specializing facet output code for 113 : // ostreambuf_iterator. For ostreambuf_iterator, sputn is 114 : // significantly more efficient than incrementing iterators. 115 : template<typename _CharT> 116 : inline 117 : ostreambuf_iterator<_CharT> 118 : __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len) 119 : { 120 : __s._M_put(__ws, __len); 121 : return __s; 122 : } 123 : 124 : // This is the unspecialized form of the template. 125 : template<typename _CharT, typename _OutIter> 126 : inline 127 : _OutIter 128 : __write(_OutIter __s, const _CharT* __ws, int __len) 129 : { 130 : for (int __j = 0; __j < __len; __j++, ++__s) 131 : *__s = __ws[__j]; 132 : return __s; 133 : } 134 : 135 : 136 : // 22.2.1.1 Template class ctype 137 : // Include host and configuration specific ctype enums for ctype_base. 138 : 139 : // Common base for ctype<_CharT>. 140 : /** 141 : * @brief Common base for ctype facet 142 : * 143 : * This template class provides implementations of the public functions 144 : * that forward to the protected virtual functions. 145 : * 146 : * This template also provides abstract stubs for the protected virtual 147 : * functions. 148 : */ 149 : template<typename _CharT> 150 : class __ctype_abstract_base : public locale::facet, public ctype_base 151 : { 152 : public: 153 : // Types: 154 : /// Typedef for the template parameter 155 : typedef _CharT char_type; 156 : 157 : /** 158 : * @brief Test char_type classification. 159 : * 160 : * This function finds a mask M for @a c and compares it to mask @a m. 161 : * It does so by returning the value of ctype<char_type>::do_is(). 162 : * 163 : * @param c The char_type to compare the mask of. 164 : * @param m The mask to compare against. 165 : * @return (M & m) != 0. 166 : */ 167 : bool 168 : is(mask __m, char_type __c) const 169 : { return this->do_is(__m, __c); } 170 : 171 : /** 172 : * @brief Return a mask array. 173 : * 174 : * This function finds the mask for each char_type in the range [lo,hi) 175 : * and successively writes it to vec. vec must have as many elements 176 : * as the char array. It does so by returning the value of 177 : * ctype<char_type>::do_is(). 178 : * 179 : * @param lo Pointer to start of range. 180 : * @param hi Pointer to end of range. 181 : * @param vec Pointer to an array of mask storage. 182 : * @return @a hi. 183 : */ 184 : const char_type* 185 : is(const char_type *__lo, const char_type *__hi, mask *__vec) const 186 : { return this->do_is(__lo, __hi, __vec); } 187 : 188 : /** 189 : * @brief Find char_type matching a mask 190 : * 191 : * This function searches for and returns the first char_type c in 192 : * [lo,hi) for which is(m,c) is true. It does so by returning 193 : * ctype<char_type>::do_scan_is(). 194 : * 195 : * @param m The mask to compare against. 196 : * @param lo Pointer to start of range. 197 : * @param hi Pointer to end of range. 198 : * @return Pointer to matching char_type if found, else @a hi. 199 : */ 200 : const char_type* 201 : scan_is(mask __m, const char_type* __lo, const char_type* __hi) const 202 : { return this->do_scan_is(__m, __lo, __hi); } 203 : 204 : /** 205 : * @brief Find char_type not matching a mask 206 : * 207 : * This function searches for and returns the first char_type c in 208 : * [lo,hi) for which is(m,c) is false. It does so by returning 209 : * ctype<char_type>::do_scan_not(). 210 : * 211 : * @param m The mask to compare against. 212 : * @param lo Pointer to first char in range. 213 : * @param hi Pointer to end of range. 214 : * @return Pointer to non-matching char if found, else @a hi. 215 : */ 216 : const char_type* 217 : scan_not(mask __m, const char_type* __lo, const char_type* __hi) const 218 : { return this->do_scan_not(__m, __lo, __hi); } 219 : 220 : /** 221 : * @brief Convert to uppercase. 222 : * 223 : * This function converts the argument to uppercase if possible. 224 : * If not possible (for example, '2'), returns the argument. It does 225 : * so by returning ctype<char_type>::do_toupper(). 226 : * 227 : * @param c The char_type to convert. 228 : * @return The uppercase char_type if convertible, else @a c. 229 : */ 230 : char_type 231 : toupper(char_type __c) const 232 : { return this->do_toupper(__c); } 233 : 234 : /** 235 : * @brief Convert array to uppercase. 236 : * 237 : * This function converts each char_type in the range [lo,hi) to 238 : * uppercase if possible. Other elements remain untouched. It does so 239 : * by returning ctype<char_type>:: do_toupper(lo, hi). 240 : * 241 : * @param lo Pointer to start of range. 242 : * @param hi Pointer to end of range. 243 : * @return @a hi. 244 : */ 245 : const char_type* 246 : toupper(char_type *__lo, const char_type* __hi) const 247 : { return this->do_toupper(__lo, __hi); } 248 : 249 : /** 250 : * @brief Convert to lowercase. 251 : * 252 : * This function converts the argument to lowercase if possible. If 253 : * not possible (for example, '2'), returns the argument. It does so 254 : * by returning ctype<char_type>::do_tolower(c). 255 : * 256 : * @param c The char_type to convert. 257 : * @return The lowercase char_type if convertible, else @a c. 258 : */ 259 : char_type 260 : tolower(char_type __c) const 261 : { return this->do_tolower(__c); } 262 : 263 : /** 264 : * @brief Convert array to lowercase. 265 : * 266 : * This function converts each char_type in the range [lo,hi) to 267 : * lowercase if possible. Other elements remain untouched. It does so 268 : * by returning ctype<char_type>:: do_tolower(lo, hi). 269 : * 270 : * @param lo Pointer to start of range. 271 : * @param hi Pointer to end of range. 272 : * @return @a hi. 273 : */ 274 : const char_type* 275 : tolower(char_type* __lo, const char_type* __hi) const 276 : { return this->do_tolower(__lo, __hi); } 277 : 278 : /** 279 : * @brief Widen char to char_type 280 : * 281 : * This function converts the char argument to char_type using the 282 : * simplest reasonable transformation. It does so by returning 283 : * ctype<char_type>::do_widen(c). 284 : * 285 : * Note: this is not what you want for codepage conversions. See 286 : * codecvt for that. 287 : * 288 : * @param c The char to convert. 289 : * @return The converted char_type. 290 : */ 291 : char_type 292 : widen(char __c) const 293 : { return this->do_widen(__c); } 294 : 295 : /** 296 : * @brief Widen array to char_type 297 : * 298 : * This function converts each char in the input to char_type using the 299 : * simplest reasonable transformation. It does so by returning 300 : * ctype<char_type>::do_widen(c). 301 : * 302 : * Note: this is not what you want for codepage conversions. See 303 : * codecvt for that. 304 : * 305 : * @param lo Pointer to start of range. 306 : * @param hi Pointer to end of range. 307 : * @param to Pointer to the destination array. 308 : * @return @a hi. 309 : */ 310 : const char* 311 : widen(const char* __lo, const char* __hi, char_type* __to) const 312 : { return this->do_widen(__lo, __hi, __to); } 313 : 314 : /** 315 : * @brief Narrow char_type to char 316 : * 317 : * This function converts the char_type to char using the simplest 318 : * reasonable transformation. If the conversion fails, dfault is 319 : * returned instead. It does so by returning 320 : * ctype<char_type>::do_narrow(c). 321 : * 322 : * Note: this is not what you want for codepage conversions. See 323 : * codecvt for that. 324 : * 325 : * @param c The char_type to convert. 326 : * @param dfault Char to return if conversion fails. 327 : * @return The converted char. 328 : */ 329 : char 330 : narrow(char_type __c, char __dfault) const 331 : { return this->do_narrow(__c, __dfault); } 332 : 333 : /** 334 : * @brief Narrow array to char array 335 : * 336 : * This function converts each char_type in the input to char using the 337 : * simplest reasonable transformation and writes the results to the 338 : * destination array. For any char_type in the input that cannot be 339 : * converted, @a dfault is used instead. It does so by returning 340 : * ctype<char_type>::do_narrow(lo, hi, dfault, to). 341 : * 342 : * Note: this is not what you want for codepage conversions. See 343 : * codecvt for that. 344 : * 345 : * @param lo Pointer to start of range. 346 : * @param hi Pointer to end of range. 347 : * @param dfault Char to use if conversion fails. 348 : * @param to Pointer to the destination array. 349 : * @return @a hi. 350 : */ 351 : const char_type* 352 : narrow(const char_type* __lo, const char_type* __hi, 353 : char __dfault, char *__to) const 354 : { return this->do_narrow(__lo, __hi, __dfault, __to); } 355 : 356 : protected: 357 : explicit 358 : __ctype_abstract_base(size_t __refs = 0): facet(__refs) { } 359 : 360 : virtual 361 : ~__ctype_abstract_base() { } 362 : 363 : /** 364 : * @brief Test char_type classification. 365 : * 366 : * This function finds a mask M for @a c and compares it to mask @a m. 367 : * 368 : * do_is() is a hook for a derived facet to change the behavior of 369 : * classifying. do_is() must always return the same result for the 370 : * same input. 371 : * 372 : * @param c The char_type to find the mask of. 373 : * @param m The mask to compare against. 374 : * @return (M & m) != 0. 375 : */ 376 : virtual bool 377 : do_is(mask __m, char_type __c) const = 0; 378 : 379 : /** 380 : * @brief Return a mask array. 381 : * 382 : * This function finds the mask for each char_type in the range [lo,hi) 383 : * and successively writes it to vec. vec must have as many elements 384 : * as the input. 385 : * 386 : * do_is() is a hook for a derived facet to change the behavior of 387 : * classifying. do_is() must always return the same result for the 388 : * same input. 389 : * 390 : * @param lo Pointer to start of range. 391 : * @param hi Pointer to end of range. 392 : * @param vec Pointer to an array of mask storage. 393 : * @return @a hi. 394 : */ 395 : virtual const char_type* 396 : do_is(const char_type* __lo, const char_type* __hi, 397 : mask* __vec) const = 0; 398 : 399 : /** 400 : * @brief Find char_type matching mask 401 : * 402 : * This function searches for and returns the first char_type c in 403 : * [lo,hi) for which is(m,c) is true. 404 : * 405 : * do_scan_is() is a hook for a derived facet to change the behavior of 406 : * match searching. do_is() must always return the same result for the 407 : * same input. 408 : * 409 : * @param m The mask to compare against. 410 : * @param lo Pointer to start of range. 411 : * @param hi Pointer to end of range. 412 : * @return Pointer to a matching char_type if found, else @a hi. 413 : */ 414 : virtual const char_type* 415 : do_scan_is(mask __m, const char_type* __lo, 416 : const char_type* __hi) const = 0; 417 : 418 : /** 419 : * @brief Find char_type not matching mask 420 : * 421 : * This function searches for and returns a pointer to the first 422 : * char_type c of [lo,hi) for which is(m,c) is false. 423 : * 424 : * do_scan_is() is a hook for a derived facet to change the behavior of 425 : * match searching. do_is() must always return the same result for the 426 : * same input. 427 : * 428 : * @param m The mask to compare against. 429 : * @param lo Pointer to start of range. 430 : * @param hi Pointer to end of range. 431 : * @return Pointer to a non-matching char_type if found, else @a hi. 432 : */ 433 : virtual const char_type* 434 : do_scan_not(mask __m, const char_type* __lo, 435 : const char_type* __hi) const = 0; 436 : 437 : /** 438 : * @brief Convert to uppercase. 439 : * 440 : * This virtual function converts the char_type argument to uppercase 441 : * if possible. If not possible (for example, '2'), returns the 442 : * argument. 443 : * 444 : * do_toupper() is a hook for a derived facet to change the behavior of 445 : * uppercasing. do_toupper() must always return the same result for 446 : * the same input. 447 : * 448 : * @param c The char_type to convert. 449 : * @return The uppercase char_type if convertible, else @a c. 450 : */ 451 : virtual char_type 452 : do_toupper(char_type) const = 0; 453 : 454 : /** 455 : * @brief Convert array to uppercase. 456 : * 457 : * This virtual function converts each char_type in the range [lo,hi) 458 : * to uppercase if possible. Other elements remain untouched. 459 : * 460 : * do_toupper() is a hook for a derived facet to change the behavior of 461 : * uppercasing. do_toupper() must always return the same result for 462 : * the same input. 463 : * 464 : * @param lo Pointer to start of range. 465 : * @param hi Pointer to end of range. 466 : * @return @a hi. 467 : */ 468 : virtual const char_type* 469 : do_toupper(char_type* __lo, const char_type* __hi) const = 0; 470 : 471 : /** 472 : * @brief Convert to lowercase. 473 : * 474 : * This virtual function converts the argument to lowercase if 475 : * possible. If not possible (for example, '2'), returns the argument. 476 : * 477 : * do_tolower() is a hook for a derived facet to change the behavior of 478 : * lowercasing. do_tolower() must always return the same result for 479 : * the same input. 480 : * 481 : * @param c The char_type to convert. 482 : * @return The lowercase char_type if convertible, else @a c. 483 : */ 484 : virtual char_type 485 : do_tolower(char_type) const = 0; 486 : 487 : /** 488 : * @brief Convert array to lowercase. 489 : * 490 : * This virtual function converts each char_type in the range [lo,hi) 491 : * to lowercase if possible. Other elements remain untouched. 492 : * 493 : * do_tolower() is a hook for a derived facet to change the behavior of 494 : * lowercasing. do_tolower() must always return the same result for 495 : * the same input. 496 : * 497 : * @param lo Pointer to start of range. 498 : * @param hi Pointer to end of range. 499 : * @return @a hi. 500 : */ 501 : virtual const char_type* 502 : do_tolower(char_type* __lo, const char_type* __hi) const = 0; 503 : 504 : /** 505 : * @brief Widen char 506 : * 507 : * This virtual function converts the char to char_type using the 508 : * simplest reasonable transformation. 509 : * 510 : * do_widen() is a hook for a derived facet to change the behavior of 511 : * widening. do_widen() must always return the same result for the 512 : * same input. 513 : * 514 : * Note: this is not what you want for codepage conversions. See 515 : * codecvt for that. 516 : * 517 : * @param c The char to convert. 518 : * @return The converted char_type 519 : */ 520 : virtual char_type 521 : do_widen(char) const = 0; 522 : 523 : /** 524 : * @brief Widen char array 525 : * 526 : * This function converts each char in the input to char_type using the 527 : * simplest reasonable transformation. 528 : * 529 : * do_widen() is a hook for a derived facet to change the behavior of 530 : * widening. do_widen() must always return the same result for the 531 : * same input. 532 : * 533 : * Note: this is not what you want for codepage conversions. See 534 : * codecvt for that. 535 : * 536 : * @param lo Pointer to start range. 537 : * @param hi Pointer to end of range. 538 : * @param to Pointer to the destination array. 539 : * @return @a hi. 540 : */ 541 : virtual const char* 542 : do_widen(const char* __lo, const char* __hi, 543 : char_type* __dest) const = 0; 544 : 545 : /** 546 : * @brief Narrow char_type to char 547 : * 548 : * This virtual function converts the argument to char using the 549 : * simplest reasonable transformation. If the conversion fails, dfault 550 : * is returned instead. 551 : * 552 : * do_narrow() is a hook for a derived facet to change the behavior of 553 : * narrowing. do_narrow() must always return the same result for the 554 : * same input. 555 : * 556 : * Note: this is not what you want for codepage conversions. See 557 : * codecvt for that. 558 : * 559 : * @param c The char_type to convert. 560 : * @param dfault Char to return if conversion fails. 561 : * @return The converted char. 562 : */ 563 : virtual char 564 : do_narrow(char_type, char __dfault) const = 0; 565 : 566 : /** 567 : * @brief Narrow char_type array to char 568 : * 569 : * This virtual function converts each char_type in the range [lo,hi) to 570 : * char using the simplest reasonable transformation and writes the 571 : * results to the destination array. For any element in the input that 572 : * cannot be converted, @a dfault is used instead. 573 : * 574 : * do_narrow() is a hook for a derived facet to change the behavior of 575 : * narrowing. do_narrow() must always return the same result for the 576 : * same input. 577 : * 578 : * Note: this is not what you want for codepage conversions. See 579 : * codecvt for that. 580 : * 581 : * @param lo Pointer to start of range. 582 : * @param hi Pointer to end of range. 583 : * @param dfault Char to use if conversion fails. 584 : * @param to Pointer to the destination array. 585 : * @return @a hi. 586 : */ 587 : virtual const char_type* 588 : do_narrow(const char_type* __lo, const char_type* __hi, 589 : char __dfault, char* __dest) const = 0; 590 : }; 591 : 592 : // NB: Generic, mostly useless implementation. 593 : /** 594 : * @brief Template ctype facet 595 : * 596 : * This template class defines classification and conversion functions for 597 : * character sets. It wraps <cctype> functionality. Ctype gets used by 598 : * streams for many I/O operations. 599 : * 600 : * This template provides the protected virtual functions the developer 601 : * will have to replace in a derived class or specialization to make a 602 : * working facet. The public functions that access them are defined in 603 : * __ctype_abstract_base, to allow for implementation flexibility. See 604 : * ctype<wchar_t> for an example. The functions are documented in 605 : * __ctype_abstract_base. 606 : * 607 : * Note: implementations are provided for all the protected virtual 608 : * functions, but will likely not be useful. 609 : */ 610 : template<typename _CharT> 611 : class ctype : public __ctype_abstract_base<_CharT> 612 : { 613 : public: 614 : // Types: 615 : typedef _CharT char_type; 616 : typedef typename __ctype_abstract_base<_CharT>::mask mask; 617 : 618 : /// The facet id for ctype<char_type> 619 : static locale::id id; 620 : 621 : explicit 622 : ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { } 623 : 624 : protected: 625 : virtual 626 : ~ctype(); 627 : 628 : virtual bool 629 : do_is(mask __m, char_type __c) const; 630 : 631 : virtual const char_type* 632 : do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; 633 : 634 : virtual const char_type* 635 : do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; 636 : 637 : virtual const char_type* 638 : do_scan_not(mask __m, const char_type* __lo, 639 : const char_type* __hi) const; 640 : 641 : virtual char_type 642 : do_toupper(char_type __c) const; 643 : 644 : virtual const char_type* 645 : do_toupper(char_type* __lo, const char_type* __hi) const; 646 : 647 : virtual char_type 648 : do_tolower(char_type __c) const; 649 : 650 : virtual const char_type* 651 : do_tolower(char_type* __lo, const char_type* __hi) const; 652 : 653 : virtual char_type 654 : do_widen(char __c) const; 655 : 656 : virtual const char* 657 : do_widen(const char* __lo, const char* __hi, char_type* __dest) const; 658 : 659 : virtual char 660 : do_narrow(char_type, char __dfault) const; 661 : 662 : virtual const char_type* 663 : do_narrow(const char_type* __lo, const char_type* __hi, 664 : char __dfault, char* __dest) const; 665 : }; 666 : 667 : template<typename _CharT> 668 : locale::id ctype<_CharT>::id; 669 : 670 : // 22.2.1.3 ctype<char> specialization. 671 : /** 672 : * @brief The ctype<char> specialization. 673 : * 674 : * This class defines classification and conversion functions for 675 : * the char type. It gets used by char streams for many I/O 676 : * operations. The char specialization provides a number of 677 : * optimizations as well. 678 : */ 679 : template<> 680 : class ctype<char> : public locale::facet, public ctype_base 681 : { 682 : public: 683 : // Types: 684 : /// Typedef for the template parameter char. 685 : typedef char char_type; 686 : 687 : protected: 688 : // Data Members: 689 : __c_locale _M_c_locale_ctype; 690 : bool _M_del; 691 : __to_type _M_toupper; 692 : __to_type _M_tolower; 693 : const mask* _M_table; 694 : mutable char _M_widen_ok; 695 : mutable char _M_widen[1 + static_cast<unsigned char>(-1)]; 696 : mutable char _M_narrow[1 + static_cast<unsigned char>(-1)]; 697 : mutable char _M_narrow_ok; // 0 uninitialized, 1 init, 698 : // 2 memcpy can't be used 699 : 700 : public: 701 : /// The facet id for ctype<char> 702 : static locale::id id; 703 : /// The size of the mask table. It is SCHAR_MAX + 1. 704 : static const size_t table_size = 1 + static_cast<unsigned char>(-1); 705 : 706 : /** 707 : * @brief Constructor performs initialization. 708 : * 709 : * This is the constructor provided by the standard. 710 : * 711 : * @param table If non-zero, table is used as the per-char mask. 712 : * Else classic_table() is used. 713 : * @param del If true, passes ownership of table to this facet. 714 : * @param refs Passed to the base facet class. 715 : */ 716 : explicit 717 : ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0); 718 : 719 : /** 720 : * @brief Constructor performs static initialization. 721 : * 722 : * This constructor is used to construct the initial C locale facet. 723 : * 724 : * @param cloc Handle to C locale data. 725 : * @param table If non-zero, table is used as the per-char mask. 726 : * @param del If true, passes ownership of table to this facet. 727 : * @param refs Passed to the base facet class. 728 : */ 729 : explicit 730 : ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false, 731 : size_t __refs = 0); 732 : 733 : /** 734 : * @brief Test char classification. 735 : * 736 : * This function compares the mask table[c] to @a m. 737 : * 738 : * @param c The char to compare the mask of. 739 : * @param m The mask to compare against. 740 : * @return True if m & table[c] is true, false otherwise. 741 : */ 742 : inline bool 743 : is(mask __m, char __c) const; 744 : 745 : /** 746 : * @brief Return a mask array. 747 : * 748 : * This function finds the mask for each char in the range [lo, hi) and 749 : * successively writes it to vec. vec must have as many elements as 750 : * the char array. 751 : * 752 : * @param lo Pointer to start of range. 753 : * @param hi Pointer to end of range. 754 : * @param vec Pointer to an array of mask storage. 755 : * @return @a hi. 756 : */ 757 : inline const char* 758 : is(const char* __lo, const char* __hi, mask* __vec) const; 759 : 760 : /** 761 : * @brief Find char matching a mask 762 : * 763 : * This function searches for and returns the first char in [lo,hi) for 764 : * which is(m,char) is true. 765 : * 766 : * @param m The mask to compare against. 767 : * @param lo Pointer to start of range. 768 : * @param hi Pointer to end of range. 769 : * @return Pointer to a matching char if found, else @a hi. 770 : */ 771 : inline const char* 772 : scan_is(mask __m, const char* __lo, const char* __hi) const; 773 : 774 : /** 775 : * @brief Find char not matching a mask 776 : * 777 : * This function searches for and returns a pointer to the first char 778 : * in [lo,hi) for which is(m,char) is false. 779 : * 780 : * @param m The mask to compare against. 781 : * @param lo Pointer to start of range. 782 : * @param hi Pointer to end of range. 783 : * @return Pointer to a non-matching char if found, else @a hi. 784 : */ 785 : inline const char* 786 : scan_not(mask __m, const char* __lo, const char* __hi) const; 787 : 788 : /** 789 : * @brief Convert to uppercase. 790 : * 791 : * This function converts the char argument to uppercase if possible. 792 : * If not possible (for example, '2'), returns the argument. 793 : * 794 : * toupper() acts as if it returns ctype<char>::do_toupper(c). 795 : * do_toupper() must always return the same result for the same input. 796 : * 797 : * @param c The char to convert. 798 : * @return The uppercase char if convertible, else @a c. 799 : */ 800 : char_type 801 : toupper(char_type __c) const 802 : { return this->do_toupper(__c); } 803 : 804 : /** 805 : * @brief Convert array to uppercase. 806 : * 807 : * This function converts each char in the range [lo,hi) to uppercase 808 : * if possible. Other chars remain untouched. 809 : * 810 : * toupper() acts as if it returns ctype<char>:: do_toupper(lo, hi). 811 : * do_toupper() must always return the same result for the same input. 812 : * 813 : * @param lo Pointer to first char in range. 814 : * @param hi Pointer to end of range. 815 : * @return @a hi. 816 : */ 817 : const char_type* 818 : toupper(char_type *__lo, const char_type* __hi) const 819 : { return this->do_toupper(__lo, __hi); } 820 : 821 : /** 822 : * @brief Convert to lowercase. 823 : * 824 : * This function converts the char argument to lowercase if possible. 825 : * If not possible (for example, '2'), returns the argument. 826 : * 827 : * tolower() acts as if it returns ctype<char>::do_tolower(c). 828 : * do_tolower() must always return the same result for the same input. 829 : * 830 : * @param c The char to convert. 831 : * @return The lowercase char if convertible, else @a c. 832 : */ 833 : char_type 834 : tolower(char_type __c) const 835 : { return this->do_tolower(__c); } 836 : 837 : /** 838 : * @brief Convert array to lowercase. 839 : * 840 : * This function converts each char in the range [lo,hi) to lowercase 841 : * if possible. Other chars remain untouched. 842 : * 843 : * tolower() acts as if it returns ctype<char>:: do_tolower(lo, hi). 844 : * do_tolower() must always return the same result for the same input. 845 : * 846 : * @param lo Pointer to first char in range. 847 : * @param hi Pointer to end of range. 848 : * @return @a hi. 849 : */ 850 : const char_type* 851 : tolower(char_type* __lo, const char_type* __hi) const 852 : { return this->do_tolower(__lo, __hi); } 853 : 854 : /** 855 : * @brief Widen char 856 : * 857 : * This function converts the char to char_type using the simplest 858 : * reasonable transformation. For an underived ctype<char> facet, the 859 : * argument will be returned unchanged. 860 : * 861 : * This function works as if it returns ctype<char>::do_widen(c). 862 : * do_widen() must always return the same result for the same input. 863 : * 864 : * Note: this is not what you want for codepage conversions. See 865 : * codecvt for that. 866 : * 867 : * @param c The char to convert. 868 : * @return The converted character. 869 : */ 870 : char_type 871 0 : widen(char __c) const 872 : { 873 0 : if (_M_widen_ok) 874 0 : return _M_widen[static_cast<unsigned char>(__c)]; 875 0 : this->_M_widen_init(); 876 0 : return this->do_widen(__c); 877 : } 878 : 879 : /** 880 : * @brief Widen char array 881 : * 882 : * This function converts each char in the input to char using the 883 : * simplest reasonable transformation. For an underived ctype<char> 884 : * facet, the argument will be copied unchanged. 885 : * 886 : * This function works as if it returns ctype<char>::do_widen(c). 887 : * do_widen() must always return the same result for the same input. 888 : * 889 : * Note: this is not what you want for codepage conversions. See 890 : * codecvt for that. 891 : * 892 : * @param lo Pointer to first char in range. 893 : * @param hi Pointer to end of range. 894 : * @param to Pointer to the destination array. 895 : * @return @a hi. 896 : */ 897 : const char* 898 : widen(const char* __lo, const char* __hi, char_type* __to) const 899 : { 900 : if (_M_widen_ok == 1) 901 : { 902 : __builtin_memcpy(__to, __lo, __hi - __lo); 903 : return __hi; 904 : } 905 : if (!_M_widen_ok) 906 : _M_widen_init(); 907 : return this->do_widen(__lo, __hi, __to); 908 : } 909 : 910 : /** 911 : * @brief Narrow char 912 : * 913 : * This function converts the char to char using the simplest 914 : * reasonable transformation. If the conversion fails, dfault is 915 : * returned instead. For an underived ctype<char> facet, @a c 916 : * will be returned unchanged. 917 : * 918 : * This function works as if it returns ctype<char>::do_narrow(c). 919 : * do_narrow() must always return the same result for the same input. 920 : * 921 : * Note: this is not what you want for codepage conversions. See 922 : * codecvt for that. 923 : * 924 : * @param c The char to convert. 925 : * @param dfault Char to return if conversion fails. 926 : * @return The converted character. 927 : */ 928 : char 929 : narrow(char_type __c, char __dfault) const 930 : { 931 : if (_M_narrow[static_cast<unsigned char>(__c)]) 932 : return _M_narrow[static_cast<unsigned char>(__c)]; 933 : const char __t = do_narrow(__c, __dfault); 934 : if (__t != __dfault) 935 : _M_narrow[static_cast<unsigned char>(__c)] = __t; 936 : return __t; 937 : } 938 : 939 : /** 940 : * @brief Narrow char array 941 : * 942 : * This function converts each char in the input to char using the 943 : * simplest reasonable transformation and writes the results to the 944 : * destination array. For any char in the input that cannot be 945 : * converted, @a dfault is used instead. For an underived ctype<char> 946 : * facet, the argument will be copied unchanged. 947 : * 948 : * This function works as if it returns ctype<char>::do_narrow(lo, hi, 949 : * dfault, to). do_narrow() must always return the same result for the 950 : * same input. 951 : * 952 : * Note: this is not what you want for codepage conversions. See 953 : * codecvt for that. 954 : * 955 : * @param lo Pointer to start of range. 956 : * @param hi Pointer to end of range. 957 : * @param dfault Char to use if conversion fails. 958 : * @param to Pointer to the destination array. 959 : * @return @a hi. 960 : */ 961 : const char_type* 962 : narrow(const char_type* __lo, const char_type* __hi, 963 : char __dfault, char *__to) const 964 : { 965 : if (__builtin_expect(_M_narrow_ok == 1, true)) 966 : { 967 : __builtin_memcpy(__to, __lo, __hi - __lo); 968 : return __hi; 969 : } 970 : if (!_M_narrow_ok) 971 : _M_narrow_init(); 972 : return this->do_narrow(__lo, __hi, __dfault, __to); 973 : } 974 : 975 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 976 : // DR 695. ctype<char>::classic_table() not accessible. 977 : /// Returns a pointer to the mask table provided to the constructor, or 978 : /// the default from classic_table() if none was provided. 979 : const mask* 980 : table() const throw() 981 : { return _M_table; } 982 : 983 : /// Returns a pointer to the C locale mask table. 984 : static const mask* 985 : classic_table() throw(); 986 : protected: 987 : 988 : /** 989 : * @brief Destructor. 990 : * 991 : * This function deletes table() if @a del was true in the 992 : * constructor. 993 : */ 994 : virtual 995 : ~ctype(); 996 : 997 : /** 998 : * @brief Convert to uppercase. 999 : * 1000 : * This virtual function converts the char argument to uppercase if 1001 : * possible. If not possible (for example, '2'), returns the argument. 1002 : * 1003 : * do_toupper() is a hook for a derived facet to change the behavior of 1004 : * uppercasing. do_toupper() must always return the same result for 1005 : * the same input. 1006 : * 1007 : * @param c The char to convert. 1008 : * @return The uppercase char if convertible, else @a c. 1009 : */ 1010 : virtual char_type 1011 : do_toupper(char_type) const; 1012 : 1013 : /** 1014 : * @brief Convert array to uppercase. 1015 : * 1016 : * This virtual function converts each char in the range [lo,hi) to 1017 : * uppercase if possible. Other chars remain untouched. 1018 : * 1019 : * do_toupper() is a hook for a derived facet to change the behavior of 1020 : * uppercasing. do_toupper() must always return the same result for 1021 : * the same input. 1022 : * 1023 : * @param lo Pointer to start of range. 1024 : * @param hi Pointer to end of range. 1025 : * @return @a hi. 1026 : */ 1027 : virtual const char_type* 1028 : do_toupper(char_type* __lo, const char_type* __hi) const; 1029 : 1030 : /** 1031 : * @brief Convert to lowercase. 1032 : * 1033 : * This virtual function converts the char argument to lowercase if 1034 : * possible. If not possible (for example, '2'), returns the argument. 1035 : * 1036 : * do_tolower() is a hook for a derived facet to change the behavior of 1037 : * lowercasing. do_tolower() must always return the same result for 1038 : * the same input. 1039 : * 1040 : * @param c The char to convert. 1041 : * @return The lowercase char if convertible, else @a c. 1042 : */ 1043 : virtual char_type 1044 : do_tolower(char_type) const; 1045 : 1046 : /** 1047 : * @brief Convert array to lowercase. 1048 : * 1049 : * This virtual function converts each char in the range [lo,hi) to 1050 : * lowercase if possible. Other chars remain untouched. 1051 : * 1052 : * do_tolower() is a hook for a derived facet to change the behavior of 1053 : * lowercasing. do_tolower() must always return the same result for 1054 : * the same input. 1055 : * 1056 : * @param lo Pointer to first char in range. 1057 : * @param hi Pointer to end of range. 1058 : * @return @a hi. 1059 : */ 1060 : virtual const char_type* 1061 : do_tolower(char_type* __lo, const char_type* __hi) const; 1062 : 1063 : /** 1064 : * @brief Widen char 1065 : * 1066 : * This virtual function converts the char to char using the simplest 1067 : * reasonable transformation. For an underived ctype<char> facet, the 1068 : * argument will be returned unchanged. 1069 : * 1070 : * do_widen() is a hook for a derived facet to change the behavior of 1071 : * widening. do_widen() must always return the same result for the 1072 : * same input. 1073 : * 1074 : * Note: this is not what you want for codepage conversions. See 1075 : * codecvt for that. 1076 : * 1077 : * @param c The char to convert. 1078 : * @return The converted character. 1079 : */ 1080 : virtual char_type 1081 : do_widen(char __c) const 1082 : { return __c; } 1083 : 1084 : /** 1085 : * @brief Widen char array 1086 : * 1087 : * This function converts each char in the range [lo,hi) to char using 1088 : * the simplest reasonable transformation. For an underived 1089 : * ctype<char> facet, the argument will be copied unchanged. 1090 : * 1091 : * do_widen() is a hook for a derived facet to change the behavior of 1092 : * widening. do_widen() must always return the same result for the 1093 : * same input. 1094 : * 1095 : * Note: this is not what you want for codepage conversions. See 1096 : * codecvt for that. 1097 : * 1098 : * @param lo Pointer to start of range. 1099 : * @param hi Pointer to end of range. 1100 : * @param to Pointer to the destination array. 1101 : * @return @a hi. 1102 : */ 1103 : virtual const char* 1104 : do_widen(const char* __lo, const char* __hi, char_type* __dest) const 1105 : { 1106 : __builtin_memcpy(__dest, __lo, __hi - __lo); 1107 : return __hi; 1108 : } 1109 : 1110 : /** 1111 : * @brief Narrow char 1112 : * 1113 : * This virtual function converts the char to char using the simplest 1114 : * reasonable transformation. If the conversion fails, dfault is 1115 : * returned instead. For an underived ctype<char> facet, @a c will be 1116 : * returned unchanged. 1117 : * 1118 : * do_narrow() is a hook for a derived facet to change the behavior of 1119 : * narrowing. do_narrow() must always return the same result for the 1120 : * same input. 1121 : * 1122 : * Note: this is not what you want for codepage conversions. See 1123 : * codecvt for that. 1124 : * 1125 : * @param c The char to convert. 1126 : * @param dfault Char to return if conversion fails. 1127 : * @return The converted char. 1128 : */ 1129 : virtual char 1130 : do_narrow(char_type __c, char) const 1131 : { return __c; } 1132 : 1133 : /** 1134 : * @brief Narrow char array to char array 1135 : * 1136 : * This virtual function converts each char in the range [lo,hi) to 1137 : * char using the simplest reasonable transformation and writes the 1138 : * results to the destination array. For any char in the input that 1139 : * cannot be converted, @a dfault is used instead. For an underived 1140 : * ctype<char> facet, the argument will be copied unchanged. 1141 : * 1142 : * do_narrow() is a hook for a derived facet to change the behavior of 1143 : * narrowing. do_narrow() must always return the same result for the 1144 : * same input. 1145 : * 1146 : * Note: this is not what you want for codepage conversions. See 1147 : * codecvt for that. 1148 : * 1149 : * @param lo Pointer to start of range. 1150 : * @param hi Pointer to end of range. 1151 : * @param dfault Char to use if conversion fails. 1152 : * @param to Pointer to the destination array. 1153 : * @return @a hi. 1154 : */ 1155 : virtual const char_type* 1156 : do_narrow(const char_type* __lo, const char_type* __hi, 1157 : char, char* __dest) const 1158 : { 1159 : __builtin_memcpy(__dest, __lo, __hi - __lo); 1160 : return __hi; 1161 : } 1162 : 1163 : private: 1164 : 1165 0 : void _M_widen_init() const 1166 : { 1167 : char __tmp[sizeof(_M_widen)]; 1168 0 : for (size_t __i = 0; __i < sizeof(_M_widen); ++__i) 1169 0 : __tmp[__i] = __i; 1170 0 : do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen); 1171 : 1172 0 : _M_widen_ok = 1; 1173 : // Set _M_widen_ok to 2 if memcpy can't be used. 1174 0 : if (__builtin_memcmp(__tmp, _M_widen, sizeof(_M_widen))) 1175 0 : _M_widen_ok = 2; 1176 0 : } 1177 : 1178 : // Fill in the narrowing cache and flag whether all values are 1179 : // valid or not. _M_narrow_ok is set to 2 if memcpy can't 1180 : // be used. 1181 : void _M_narrow_init() const 1182 : { 1183 : char __tmp[sizeof(_M_narrow)]; 1184 : for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i) 1185 : __tmp[__i] = __i; 1186 : do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow); 1187 : 1188 : _M_narrow_ok = 1; 1189 : if (__builtin_memcmp(__tmp, _M_narrow, sizeof(_M_narrow))) 1190 : _M_narrow_ok = 2; 1191 : else 1192 : { 1193 : // Deal with the special case of zero: renarrow with a 1194 : // different default and compare. 1195 : char __c; 1196 : do_narrow(__tmp, __tmp + 1, 1, &__c); 1197 : if (__c == 1) 1198 : _M_narrow_ok = 2; 1199 : } 1200 : } 1201 : }; 1202 : 1203 : template<> 1204 : const ctype<char>& 1205 : use_facet<ctype<char> >(const locale& __loc); 1206 : 1207 : #ifdef _GLIBCXX_USE_WCHAR_T 1208 : // 22.2.1.3 ctype<wchar_t> specialization 1209 : /** 1210 : * @brief The ctype<wchar_t> specialization. 1211 : * 1212 : * This class defines classification and conversion functions for the 1213 : * wchar_t type. It gets used by wchar_t streams for many I/O operations. 1214 : * The wchar_t specialization provides a number of optimizations as well. 1215 : * 1216 : * ctype<wchar_t> inherits its public methods from 1217 : * __ctype_abstract_base<wchar_t>. 1218 : */ 1219 : template<> 1220 : class ctype<wchar_t> : public __ctype_abstract_base<wchar_t> 1221 : { 1222 : public: 1223 : // Types: 1224 : /// Typedef for the template parameter wchar_t. 1225 : typedef wchar_t char_type; 1226 : typedef wctype_t __wmask_type; 1227 : 1228 : protected: 1229 : __c_locale _M_c_locale_ctype; 1230 : 1231 : // Pre-computed narrowed and widened chars. 1232 : bool _M_narrow_ok; 1233 : char _M_narrow[128]; 1234 : wint_t _M_widen[1 + static_cast<unsigned char>(-1)]; 1235 : 1236 : // Pre-computed elements for do_is. 1237 : mask _M_bit[16]; 1238 : __wmask_type _M_wmask[16]; 1239 : 1240 : public: 1241 : // Data Members: 1242 : /// The facet id for ctype<wchar_t> 1243 : static locale::id id; 1244 : 1245 : /** 1246 : * @brief Constructor performs initialization. 1247 : * 1248 : * This is the constructor provided by the standard. 1249 : * 1250 : * @param refs Passed to the base facet class. 1251 : */ 1252 : explicit 1253 : ctype(size_t __refs = 0); 1254 : 1255 : /** 1256 : * @brief Constructor performs static initialization. 1257 : * 1258 : * This constructor is used to construct the initial C locale facet. 1259 : * 1260 : * @param cloc Handle to C locale data. 1261 : * @param refs Passed to the base facet class. 1262 : */ 1263 : explicit 1264 : ctype(__c_locale __cloc, size_t __refs = 0); 1265 : 1266 : protected: 1267 : __wmask_type 1268 : _M_convert_to_wmask(const mask __m) const; 1269 : 1270 : /// Destructor 1271 : virtual 1272 : ~ctype(); 1273 : 1274 : /** 1275 : * @brief Test wchar_t classification. 1276 : * 1277 : * This function finds a mask M for @a c and compares it to mask @a m. 1278 : * 1279 : * do_is() is a hook for a derived facet to change the behavior of 1280 : * classifying. do_is() must always return the same result for the 1281 : * same input. 1282 : * 1283 : * @param c The wchar_t to find the mask of. 1284 : * @param m The mask to compare against. 1285 : * @return (M & m) != 0. 1286 : */ 1287 : virtual bool 1288 : do_is(mask __m, char_type __c) const; 1289 : 1290 : /** 1291 : * @brief Return a mask array. 1292 : * 1293 : * This function finds the mask for each wchar_t in the range [lo,hi) 1294 : * and successively writes it to vec. vec must have as many elements 1295 : * as the input. 1296 : * 1297 : * do_is() is a hook for a derived facet to change the behavior of 1298 : * classifying. do_is() must always return the same result for the 1299 : * same input. 1300 : * 1301 : * @param lo Pointer to start of range. 1302 : * @param hi Pointer to end of range. 1303 : * @param vec Pointer to an array of mask storage. 1304 : * @return @a hi. 1305 : */ 1306 : virtual const char_type* 1307 : do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; 1308 : 1309 : /** 1310 : * @brief Find wchar_t matching mask 1311 : * 1312 : * This function searches for and returns the first wchar_t c in 1313 : * [lo,hi) for which is(m,c) is true. 1314 : * 1315 : * do_scan_is() is a hook for a derived facet to change the behavior of 1316 : * match searching. do_is() must always return the same result for the 1317 : * same input. 1318 : * 1319 : * @param m The mask to compare against. 1320 : * @param lo Pointer to start of range. 1321 : * @param hi Pointer to end of range. 1322 : * @return Pointer to a matching wchar_t if found, else @a hi. 1323 : */ 1324 : virtual const char_type* 1325 : do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; 1326 : 1327 : /** 1328 : * @brief Find wchar_t not matching mask 1329 : * 1330 : * This function searches for and returns a pointer to the first 1331 : * wchar_t c of [lo,hi) for which is(m,c) is false. 1332 : * 1333 : * do_scan_is() is a hook for a derived facet to change the behavior of 1334 : * match searching. do_is() must always return the same result for the 1335 : * same input. 1336 : * 1337 : * @param m The mask to compare against. 1338 : * @param lo Pointer to start of range. 1339 : * @param hi Pointer to end of range. 1340 : * @return Pointer to a non-matching wchar_t if found, else @a hi. 1341 : */ 1342 : virtual const char_type* 1343 : do_scan_not(mask __m, const char_type* __lo, 1344 : const char_type* __hi) const; 1345 : 1346 : /** 1347 : * @brief Convert to uppercase. 1348 : * 1349 : * This virtual function converts the wchar_t argument to uppercase if 1350 : * possible. If not possible (for example, '2'), returns the argument. 1351 : * 1352 : * do_toupper() is a hook for a derived facet to change the behavior of 1353 : * uppercasing. do_toupper() must always return the same result for 1354 : * the same input. 1355 : * 1356 : * @param c The wchar_t to convert. 1357 : * @return The uppercase wchar_t if convertible, else @a c. 1358 : */ 1359 : virtual char_type 1360 : do_toupper(char_type) const; 1361 : 1362 : /** 1363 : * @brief Convert array to uppercase. 1364 : * 1365 : * This virtual function converts each wchar_t in the range [lo,hi) to 1366 : * uppercase if possible. Other elements remain untouched. 1367 : * 1368 : * do_toupper() is a hook for a derived facet to change the behavior of 1369 : * uppercasing. do_toupper() must always return the same result for 1370 : * the same input. 1371 : * 1372 : * @param lo Pointer to start of range. 1373 : * @param hi Pointer to end of range. 1374 : * @return @a hi. 1375 : */ 1376 : virtual const char_type* 1377 : do_toupper(char_type* __lo, const char_type* __hi) const; 1378 : 1379 : /** 1380 : * @brief Convert to lowercase. 1381 : * 1382 : * This virtual function converts the argument to lowercase if 1383 : * possible. If not possible (for example, '2'), returns the argument. 1384 : * 1385 : * do_tolower() is a hook for a derived facet to change the behavior of 1386 : * lowercasing. do_tolower() must always return the same result for 1387 : * the same input. 1388 : * 1389 : * @param c The wchar_t to convert. 1390 : * @return The lowercase wchar_t if convertible, else @a c. 1391 : */ 1392 : virtual char_type 1393 : do_tolower(char_type) const; 1394 : 1395 : /** 1396 : * @brief Convert array to lowercase. 1397 : * 1398 : * This virtual function converts each wchar_t in the range [lo,hi) to 1399 : * lowercase if possible. Other elements remain untouched. 1400 : * 1401 : * do_tolower() is a hook for a derived facet to change the behavior of 1402 : * lowercasing. do_tolower() must always return the same result for 1403 : * the same input. 1404 : * 1405 : * @param lo Pointer to start of range. 1406 : * @param hi Pointer to end of range. 1407 : * @return @a hi. 1408 : */ 1409 : virtual const char_type* 1410 : do_tolower(char_type* __lo, const char_type* __hi) const; 1411 : 1412 : /** 1413 : * @brief Widen char to wchar_t 1414 : * 1415 : * This virtual function converts the char to wchar_t using the 1416 : * simplest reasonable transformation. For an underived ctype<wchar_t> 1417 : * facet, the argument will be cast to wchar_t. 1418 : * 1419 : * do_widen() is a hook for a derived facet to change the behavior of 1420 : * widening. do_widen() must always return the same result for the 1421 : * same input. 1422 : * 1423 : * Note: this is not what you want for codepage conversions. See 1424 : * codecvt for that. 1425 : * 1426 : * @param c The char to convert. 1427 : * @return The converted wchar_t. 1428 : */ 1429 : virtual char_type 1430 : do_widen(char) const; 1431 : 1432 : /** 1433 : * @brief Widen char array to wchar_t array 1434 : * 1435 : * This function converts each char in the input to wchar_t using the 1436 : * simplest reasonable transformation. For an underived ctype<wchar_t> 1437 : * facet, the argument will be copied, casting each element to wchar_t. 1438 : * 1439 : * do_widen() is a hook for a derived facet to change the behavior of 1440 : * widening. do_widen() must always return the same result for the 1441 : * same input. 1442 : * 1443 : * Note: this is not what you want for codepage conversions. See 1444 : * codecvt for that. 1445 : * 1446 : * @param lo Pointer to start range. 1447 : * @param hi Pointer to end of range. 1448 : * @param to Pointer to the destination array. 1449 : * @return @a hi. 1450 : */ 1451 : virtual const char* 1452 : do_widen(const char* __lo, const char* __hi, char_type* __dest) const; 1453 : 1454 : /** 1455 : * @brief Narrow wchar_t to char 1456 : * 1457 : * This virtual function converts the argument to char using 1458 : * the simplest reasonable transformation. If the conversion 1459 : * fails, dfault is returned instead. For an underived 1460 : * ctype<wchar_t> facet, @a c will be cast to char and 1461 : * returned. 1462 : * 1463 : * do_narrow() is a hook for a derived facet to change the 1464 : * behavior of narrowing. do_narrow() must always return the 1465 : * same result for the same input. 1466 : * 1467 : * Note: this is not what you want for codepage conversions. See 1468 : * codecvt for that. 1469 : * 1470 : * @param c The wchar_t to convert. 1471 : * @param dfault Char to return if conversion fails. 1472 : * @return The converted char. 1473 : */ 1474 : virtual char 1475 : do_narrow(char_type, char __dfault) const; 1476 : 1477 : /** 1478 : * @brief Narrow wchar_t array to char array 1479 : * 1480 : * This virtual function converts each wchar_t in the range [lo,hi) to 1481 : * char using the simplest reasonable transformation and writes the 1482 : * results to the destination array. For any wchar_t in the input that 1483 : * cannot be converted, @a dfault is used instead. For an underived 1484 : * ctype<wchar_t> facet, the argument will be copied, casting each 1485 : * element to char. 1486 : * 1487 : * do_narrow() is a hook for a derived facet to change the behavior of 1488 : * narrowing. do_narrow() must always return the same result for the 1489 : * same input. 1490 : * 1491 : * Note: this is not what you want for codepage conversions. See 1492 : * codecvt for that. 1493 : * 1494 : * @param lo Pointer to start of range. 1495 : * @param hi Pointer to end of range. 1496 : * @param dfault Char to use if conversion fails. 1497 : * @param to Pointer to the destination array. 1498 : * @return @a hi. 1499 : */ 1500 : virtual const char_type* 1501 : do_narrow(const char_type* __lo, const char_type* __hi, 1502 : char __dfault, char* __dest) const; 1503 : 1504 : // For use at construction time only. 1505 : void 1506 : _M_initialize_ctype(); 1507 : }; 1508 : 1509 : template<> 1510 : const ctype<wchar_t>& 1511 : use_facet<ctype<wchar_t> >(const locale& __loc); 1512 : #endif //_GLIBCXX_USE_WCHAR_T 1513 : 1514 : /// class ctype_byname [22.2.1.2]. 1515 : template<typename _CharT> 1516 : class ctype_byname : public ctype<_CharT> 1517 : { 1518 : public: 1519 : typedef typename ctype<_CharT>::mask mask; 1520 : 1521 : explicit 1522 : ctype_byname(const char* __s, size_t __refs = 0); 1523 : 1524 : protected: 1525 : virtual 1526 : ~ctype_byname() { }; 1527 : }; 1528 : 1529 : /// 22.2.1.4 Class ctype_byname specializations. 1530 : template<> 1531 : class ctype_byname<char> : public ctype<char> 1532 : { 1533 : public: 1534 : explicit 1535 : ctype_byname(const char* __s, size_t __refs = 0); 1536 : 1537 : protected: 1538 : virtual 1539 : ~ctype_byname(); 1540 : }; 1541 : 1542 : #ifdef _GLIBCXX_USE_WCHAR_T 1543 : template<> 1544 : class ctype_byname<wchar_t> : public ctype<wchar_t> 1545 : { 1546 : public: 1547 : explicit 1548 : ctype_byname(const char* __s, size_t __refs = 0); 1549 : 1550 : protected: 1551 : virtual 1552 : ~ctype_byname(); 1553 : }; 1554 : #endif 1555 : 1556 : _GLIBCXX_END_NAMESPACE 1557 : 1558 : // Include host and configuration specific ctype inlines. 1559 : #include <bits/ctype_inline.h> 1560 : 1561 : _GLIBCXX_BEGIN_NAMESPACE(std) 1562 : 1563 : // 22.2.2 The numeric category. 1564 : class __num_base 1565 : { 1566 : public: 1567 : // NB: Code depends on the order of _S_atoms_out elements. 1568 : // Below are the indices into _S_atoms_out. 1569 : enum 1570 : { 1571 : _S_ominus, 1572 : _S_oplus, 1573 : _S_ox, 1574 : _S_oX, 1575 : _S_odigits, 1576 : _S_odigits_end = _S_odigits + 16, 1577 : _S_oudigits = _S_odigits_end, 1578 : _S_oudigits_end = _S_oudigits + 16, 1579 : _S_oe = _S_odigits + 14, // For scientific notation, 'e' 1580 : _S_oE = _S_oudigits + 14, // For scientific notation, 'E' 1581 : _S_oend = _S_oudigits_end 1582 : }; 1583 : 1584 : // A list of valid numeric literals for output. This array 1585 : // contains chars that will be passed through the current locale's 1586 : // ctype<_CharT>.widen() and then used to render numbers. 1587 : // For the standard "C" locale, this is 1588 : // "-+xX0123456789abcdef0123456789ABCDEF". 1589 : static const char* _S_atoms_out; 1590 : 1591 : // String literal of acceptable (narrow) input, for num_get. 1592 : // "-+xX0123456789abcdefABCDEF" 1593 : static const char* _S_atoms_in; 1594 : 1595 : enum 1596 : { 1597 : _S_iminus, 1598 : _S_iplus, 1599 : _S_ix, 1600 : _S_iX, 1601 : _S_izero, 1602 : _S_ie = _S_izero + 14, 1603 : _S_iE = _S_izero + 20, 1604 : _S_iend = 26 1605 : }; 1606 : 1607 : // num_put 1608 : // Construct and return valid scanf format for floating point types. 1609 : static void 1610 : _S_format_float(const ios_base& __io, char* __fptr, char __mod); 1611 : }; 1612 : 1613 : template<typename _CharT> 1614 : struct __numpunct_cache : public locale::facet 1615 : { 1616 : const char* _M_grouping; 1617 : size_t _M_grouping_size; 1618 : bool _M_use_grouping; 1619 : const _CharT* _M_truename; 1620 : size_t _M_truename_size; 1621 : const _CharT* _M_falsename; 1622 : size_t _M_falsename_size; 1623 : _CharT _M_decimal_point; 1624 : _CharT _M_thousands_sep; 1625 : 1626 : // A list of valid numeric literals for output: in the standard 1627 : // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF". 1628 : // This array contains the chars after having been passed 1629 : // through the current locale's ctype<_CharT>.widen(). 1630 : _CharT _M_atoms_out[__num_base::_S_oend]; 1631 : 1632 : // A list of valid numeric literals for input: in the standard 1633 : // "C" locale, this is "-+xX0123456789abcdefABCDEF" 1634 : // This array contains the chars after having been passed 1635 : // through the current locale's ctype<_CharT>.widen(). 1636 : _CharT _M_atoms_in[__num_base::_S_iend]; 1637 : 1638 : bool _M_allocated; 1639 : 1640 : __numpunct_cache(size_t __refs = 0) : facet(__refs), 1641 : _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), 1642 : _M_truename(NULL), _M_truename_size(0), _M_falsename(NULL), 1643 : _M_falsename_size(0), _M_decimal_point(_CharT()), 1644 : _M_thousands_sep(_CharT()), _M_allocated(false) 1645 : { } 1646 : 1647 : ~__numpunct_cache(); 1648 : 1649 : void 1650 : _M_cache(const locale& __loc); 1651 : 1652 : private: 1653 : __numpunct_cache& 1654 : operator=(const __numpunct_cache&); 1655 : 1656 : explicit 1657 : __numpunct_cache(const __numpunct_cache&); 1658 : }; 1659 : 1660 : template<typename _CharT> 1661 : __numpunct_cache<_CharT>::~__numpunct_cache() 1662 : { 1663 : if (_M_allocated) 1664 : { 1665 : delete [] _M_grouping; 1666 : delete [] _M_truename; 1667 : delete [] _M_falsename; 1668 : } 1669 : } 1670 : 1671 : /** 1672 : * @brief Numpunct facet. 1673 : * 1674 : * This facet stores several pieces of information related to printing and 1675 : * scanning numbers, such as the decimal point character. It takes a 1676 : * template parameter specifying the char type. The numpunct facet is 1677 : * used by streams for many I/O operations involving numbers. 1678 : * 1679 : * The numpunct template uses protected virtual functions to provide the 1680 : * actual results. The public accessors forward the call to the virtual 1681 : * functions. These virtual functions are hooks for developers to 1682 : * implement the behavior they require from a numpunct facet. 1683 : */ 1684 : template<typename _CharT> 1685 : class numpunct : public locale::facet 1686 : { 1687 : public: 1688 : // Types: 1689 : //@{ 1690 : /// Public typedefs 1691 : typedef _CharT char_type; 1692 : typedef basic_string<_CharT> string_type; 1693 : //@} 1694 : typedef __numpunct_cache<_CharT> __cache_type; 1695 : 1696 : protected: 1697 : __cache_type* _M_data; 1698 : 1699 : public: 1700 : /// Numpunct facet id. 1701 : static locale::id id; 1702 : 1703 : /** 1704 : * @brief Numpunct constructor. 1705 : * 1706 : * @param refs Refcount to pass to the base class. 1707 : */ 1708 : explicit 1709 : numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) 1710 : { _M_initialize_numpunct(); } 1711 : 1712 : /** 1713 : * @brief Internal constructor. Not for general use. 1714 : * 1715 : * This is a constructor for use by the library itself to set up the 1716 : * predefined locale facets. 1717 : * 1718 : * @param cache __numpunct_cache object. 1719 : * @param refs Refcount to pass to the base class. 1720 : */ 1721 : explicit 1722 : numpunct(__cache_type* __cache, size_t __refs = 0) 1723 : : facet(__refs), _M_data(__cache) 1724 : { _M_initialize_numpunct(); } 1725 : 1726 : /** 1727 : * @brief Internal constructor. Not for general use. 1728 : * 1729 : * This is a constructor for use by the library itself to set up new 1730 : * locales. 1731 : * 1732 : * @param cloc The "C" locale. 1733 : * @param refs Refcount to pass to the base class. 1734 : */ 1735 : explicit 1736 : numpunct(__c_locale __cloc, size_t __refs = 0) 1737 : : facet(__refs), _M_data(NULL) 1738 : { _M_initialize_numpunct(__cloc); } 1739 : 1740 : /** 1741 : * @brief Return decimal point character. 1742 : * 1743 : * This function returns a char_type to use as a decimal point. It 1744 : * does so by returning returning 1745 : * numpunct<char_type>::do_decimal_point(). 1746 : * 1747 : * @return @a char_type representing a decimal point. 1748 : */ 1749 : char_type 1750 : decimal_point() const 1751 : { return this->do_decimal_point(); } 1752 : 1753 : /** 1754 : * @brief Return thousands separator character. 1755 : * 1756 : * This function returns a char_type to use as a thousands 1757 : * separator. It does so by returning returning 1758 : * numpunct<char_type>::do_thousands_sep(). 1759 : * 1760 : * @return char_type representing a thousands separator. 1761 : */ 1762 : char_type 1763 : thousands_sep() const 1764 : { return this->do_thousands_sep(); } 1765 : 1766 : /** 1767 : * @brief Return grouping specification. 1768 : * 1769 : * This function returns a string representing groupings for the 1770 : * integer part of a number. Groupings indicate where thousands 1771 : * separators should be inserted in the integer part of a number. 1772 : * 1773 : * Each char in the return string is interpret as an integer 1774 : * rather than a character. These numbers represent the number 1775 : * of digits in a group. The first char in the string 1776 : * represents the number of digits in the least significant 1777 : * group. If a char is negative, it indicates an unlimited 1778 : * number of digits for the group. If more chars from the 1779 : * string are required to group a number, the last char is used 1780 : * repeatedly. 1781 : * 1782 : * For example, if the grouping() returns "\003\002" and is 1783 : * applied to the number 123456789, this corresponds to 1784 : * 12,34,56,789. Note that if the string was "32", this would 1785 : * put more than 50 digits into the least significant group if 1786 : * the character set is ASCII. 1787 : * 1788 : * The string is returned by calling 1789 : * numpunct<char_type>::do_grouping(). 1790 : * 1791 : * @return string representing grouping specification. 1792 : */ 1793 : string 1794 : grouping() const 1795 : { return this->do_grouping(); } 1796 : 1797 : /** 1798 : * @brief Return string representation of bool true. 1799 : * 1800 : * This function returns a string_type containing the text 1801 : * representation for true bool variables. It does so by calling 1802 : * numpunct<char_type>::do_truename(). 1803 : * 1804 : * @return string_type representing printed form of true. 1805 : */ 1806 : string_type 1807 : truename() const 1808 : { return this->do_truename(); } 1809 : 1810 : /** 1811 : * @brief Return string representation of bool false. 1812 : * 1813 : * This function returns a string_type containing the text 1814 : * representation for false bool variables. It does so by calling 1815 : * numpunct<char_type>::do_falsename(). 1816 : * 1817 : * @return string_type representing printed form of false. 1818 : */ 1819 : string_type 1820 : falsename() const 1821 : { return this->do_falsename(); } 1822 : 1823 : protected: 1824 : /// Destructor. 1825 : virtual 1826 : ~numpunct(); 1827 : 1828 : /** 1829 : * @brief Return decimal point character. 1830 : * 1831 : * Returns a char_type to use as a decimal point. This function is a 1832 : * hook for derived classes to change the value returned. 1833 : * 1834 : * @return @a char_type representing a decimal point. 1835 : */ 1836 : virtual char_type 1837 : do_decimal_point() const 1838 : { return _M_data->_M_decimal_point; } 1839 : 1840 : /** 1841 : * @brief Return thousands separator character. 1842 : * 1843 : * Returns a char_type to use as a thousands separator. This function 1844 : * is a hook for derived classes to change the value returned. 1845 : * 1846 : * @return @a char_type representing a thousands separator. 1847 : */ 1848 : virtual char_type 1849 : do_thousands_sep() const 1850 : { return _M_data->_M_thousands_sep; } 1851 : 1852 : /** 1853 : * @brief Return grouping specification. 1854 : * 1855 : * Returns a string representing groupings for the integer part of a 1856 : * number. This function is a hook for derived classes to change the 1857 : * value returned. @see grouping() for details. 1858 : * 1859 : * @return String representing grouping specification. 1860 : */ 1861 : virtual string 1862 : do_grouping() const 1863 : { return _M_data->_M_grouping; } 1864 : 1865 : /** 1866 : * @brief Return string representation of bool true. 1867 : * 1868 : * Returns a string_type containing the text representation for true 1869 : * bool variables. This function is a hook for derived classes to 1870 : * change the value returned. 1871 : * 1872 : * @return string_type representing printed form of true. 1873 : */ 1874 : virtual string_type 1875 : do_truename() const 1876 : { return _M_data->_M_truename; } 1877 : 1878 : /** 1879 : * @brief Return string representation of bool false. 1880 : * 1881 : * Returns a string_type containing the text representation for false 1882 : * bool variables. This function is a hook for derived classes to 1883 : * change the value returned. 1884 : * 1885 : * @return string_type representing printed form of false. 1886 : */ 1887 : virtual string_type 1888 : do_falsename() const 1889 : { return _M_data->_M_falsename; } 1890 : 1891 : // For use at construction time only. 1892 : void 1893 : _M_initialize_numpunct(__c_locale __cloc = NULL); 1894 : }; 1895 : 1896 : template<typename _CharT> 1897 : locale::id numpunct<_CharT>::id; 1898 : 1899 : template<> 1900 : numpunct<char>::~numpunct(); 1901 : 1902 : template<> 1903 : void 1904 : numpunct<char>::_M_initialize_numpunct(__c_locale __cloc); 1905 : 1906 : #ifdef _GLIBCXX_USE_WCHAR_T 1907 : template<> 1908 : numpunct<wchar_t>::~numpunct(); 1909 : 1910 : template<> 1911 : void 1912 : numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc); 1913 : #endif 1914 : 1915 : /// class numpunct_byname [22.2.3.2]. 1916 : template<typename _CharT> 1917 : class numpunct_byname : public numpunct<_CharT> 1918 : { 1919 : public: 1920 : typedef _CharT char_type; 1921 : typedef basic_string<_CharT> string_type; 1922 : 1923 : explicit 1924 : numpunct_byname(const char* __s, size_t __refs = 0) 1925 : : numpunct<_CharT>(__refs) 1926 : { 1927 : if (__builtin_strcmp(__s, "C") != 0 1928 : && __builtin_strcmp(__s, "POSIX") != 0) 1929 : { 1930 : __c_locale __tmp; 1931 : this->_S_create_c_locale(__tmp, __s); 1932 : this->_M_initialize_numpunct(__tmp); 1933 : this->_S_destroy_c_locale(__tmp); 1934 : } 1935 : } 1936 : 1937 : protected: 1938 : virtual 1939 : ~numpunct_byname() { } 1940 : }; 1941 : 1942 : _GLIBCXX_BEGIN_LDBL_NAMESPACE 1943 : 1944 : /** 1945 : * @brief Facet for parsing number strings. 1946 : * 1947 : * This facet encapsulates the code to parse and return a number 1948 : * from a string. It is used by the istream numeric extraction 1949 : * operators. 1950 : * 1951 : * The num_get template uses protected virtual functions to provide the 1952 : * actual results. The public accessors forward the call to the virtual 1953 : * functions. These virtual functions are hooks for developers to 1954 : * implement the behavior they require from the num_get facet. 1955 : */ 1956 : template<typename _CharT, typename _InIter> 1957 : class num_get : public locale::facet 1958 : { 1959 : public: 1960 : // Types: 1961 : //@{ 1962 : /// Public typedefs 1963 : typedef _CharT char_type; 1964 : typedef _InIter iter_type; 1965 : //@} 1966 : 1967 : /// Numpunct facet id. 1968 : static locale::id id; 1969 : 1970 : /** 1971 : * @brief Constructor performs initialization. 1972 : * 1973 : * This is the constructor provided by the standard. 1974 : * 1975 : * @param refs Passed to the base facet class. 1976 : */ 1977 : explicit 1978 : num_get(size_t __refs = 0) : facet(__refs) { } 1979 : 1980 : /** 1981 : * @brief Numeric parsing. 1982 : * 1983 : * Parses the input stream into the bool @a v. It does so by calling 1984 : * num_get::do_get(). 1985 : * 1986 : * If ios_base::boolalpha is set, attempts to read 1987 : * ctype<CharT>::truename() or ctype<CharT>::falsename(). Sets 1988 : * @a v to true or false if successful. Sets err to 1989 : * ios_base::failbit if reading the string fails. Sets err to 1990 : * ios_base::eofbit if the stream is emptied. 1991 : * 1992 : * If ios_base::boolalpha is not set, proceeds as with reading a long, 1993 : * except if the value is 1, sets @a v to true, if the value is 0, sets 1994 : * @a v to false, and otherwise set err to ios_base::failbit. 1995 : * 1996 : * @param in Start of input stream. 1997 : * @param end End of input stream. 1998 : * @param io Source of locale and flags. 1999 : * @param err Error flags to set. 2000 : * @param v Value to format and insert. 2001 : * @return Iterator after reading. 2002 : */ 2003 : iter_type 2004 : get(iter_type __in, iter_type __end, ios_base& __io, 2005 : ios_base::iostate& __err, bool& __v) const 2006 : { return this->do_get(__in, __end, __io, __err, __v); } 2007 : 2008 : //@{ 2009 : /** 2010 : * @brief Numeric parsing. 2011 : * 2012 : * Parses the input stream into the integral variable @a v. It does so 2013 : * by calling num_get::do_get(). 2014 : * 2015 : * Parsing is affected by the flag settings in @a io. 2016 : * 2017 : * The basic parse is affected by the value of io.flags() & 2018 : * ios_base::basefield. If equal to ios_base::oct, parses like the 2019 : * scanf %o specifier. Else if equal to ios_base::hex, parses like %X 2020 : * specifier. Else if basefield equal to 0, parses like the %i 2021 : * specifier. Otherwise, parses like %d for signed and %u for unsigned 2022 : * types. The matching type length modifier is also used. 2023 : * 2024 : * Digit grouping is interpreted according to numpunct::grouping() and 2025 : * numpunct::thousands_sep(). If the pattern of digit groups isn't 2026 : * consistent, sets err to ios_base::failbit. 2027 : * 2028 : * If parsing the string yields a valid value for @a v, @a v is set. 2029 : * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. 2030 : * Sets err to ios_base::eofbit if the stream is emptied. 2031 : * 2032 : * @param in Start of input stream. 2033 : * @param end End of input stream. 2034 : * @param io Source of locale and flags. 2035 : * @param err Error flags to set. 2036 : * @param v Value to format and insert. 2037 : * @return Iterator after reading. 2038 : */ 2039 : iter_type 2040 : get(iter_type __in, iter_type __end, ios_base& __io, 2041 : ios_base::iostate& __err, long& __v) const 2042 : { return this->do_get(__in, __end, __io, __err, __v); } 2043 : 2044 : iter_type 2045 : get(iter_type __in, iter_type __end, ios_base& __io, 2046 : ios_base::iostate& __err, unsigned short& __v) const 2047 : { return this->do_get(__in, __end, __io, __err, __v); } 2048 : 2049 : iter_type 2050 : get(iter_type __in, iter_type __end, ios_base& __io, 2051 : ios_base::iostate& __err, unsigned int& __v) const 2052 : { return this->do_get(__in, __end, __io, __err, __v); } 2053 : 2054 : iter_type 2055 : get(iter_type __in, iter_type __end, ios_base& __io, 2056 : ios_base::iostate& __err, unsigned long& __v) const 2057 : { return this->do_get(__in, __end, __io, __err, __v); } 2058 : 2059 : #ifdef _GLIBCXX_USE_LONG_LONG 2060 : iter_type 2061 : get(iter_type __in, iter_type __end, ios_base& __io, 2062 : ios_base::iostate& __err, long long& __v) const 2063 : { return this->do_get(__in, __end, __io, __err, __v); } 2064 : 2065 : iter_type 2066 : get(iter_type __in, iter_type __end, ios_base& __io, 2067 : ios_base::iostate& __err, unsigned long long& __v) const 2068 : { return this->do_get(__in, __end, __io, __err, __v); } 2069 : #endif 2070 : //@} 2071 : 2072 : //@{ 2073 : /** 2074 : * @brief Numeric parsing. 2075 : * 2076 : * Parses the input stream into the integral variable @a v. It does so 2077 : * by calling num_get::do_get(). 2078 : * 2079 : * The input characters are parsed like the scanf %g specifier. The 2080 : * matching type length modifier is also used. 2081 : * 2082 : * The decimal point character used is numpunct::decimal_point(). 2083 : * Digit grouping is interpreted according to numpunct::grouping() and 2084 : * numpunct::thousands_sep(). If the pattern of digit groups isn't 2085 : * consistent, sets err to ios_base::failbit. 2086 : * 2087 : * If parsing the string yields a valid value for @a v, @a v is set. 2088 : * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. 2089 : * Sets err to ios_base::eofbit if the stream is emptied. 2090 : * 2091 : * @param in Start of input stream. 2092 : * @param end End of input stream. 2093 : * @param io Source of locale and flags. 2094 : * @param err Error flags to set. 2095 : * @param v Value to format and insert. 2096 : * @return Iterator after reading. 2097 : */ 2098 : iter_type 2099 : get(iter_type __in, iter_type __end, ios_base& __io, 2100 : ios_base::iostate& __err, float& __v) const 2101 : { return this->do_get(__in, __end, __io, __err, __v); } 2102 : 2103 : iter_type 2104 : get(iter_type __in, iter_type __end, ios_base& __io, 2105 : ios_base::iostate& __err, double& __v) const 2106 : { return this->do_get(__in, __end, __io, __err, __v); } 2107 : 2108 : iter_type 2109 : get(iter_type __in, iter_type __end, ios_base& __io, 2110 : ios_base::iostate& __err, long double& __v) const 2111 : { return this->do_get(__in, __end, __io, __err, __v); } 2112 : //@} 2113 : 2114 : /** 2115 : * @brief Numeric parsing. 2116 : * 2117 : * Parses the input stream into the pointer variable @a v. It does so 2118 : * by calling num_get::do_get(). 2119 : * 2120 : * The input characters are parsed like the scanf %p specifier. 2121 : * 2122 : * Digit grouping is interpreted according to numpunct::grouping() and 2123 : * numpunct::thousands_sep(). If the pattern of digit groups isn't 2124 : * consistent, sets err to ios_base::failbit. 2125 : * 2126 : * Note that the digit grouping effect for pointers is a bit ambiguous 2127 : * in the standard and shouldn't be relied on. See DR 344. 2128 : * 2129 : * If parsing the string yields a valid value for @a v, @a v is set. 2130 : * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. 2131 : * Sets err to ios_base::eofbit if the stream is emptied. 2132 : * 2133 : * @param in Start of input stream. 2134 : * @param end End of input stream. 2135 : * @param io Source of locale and flags. 2136 : * @param err Error flags to set. 2137 : * @param v Value to format and insert. 2138 : * @return Iterator after reading. 2139 : */ 2140 : iter_type 2141 : get(iter_type __in, iter_type __end, ios_base& __io, 2142 : ios_base::iostate& __err, void*& __v) const 2143 : { return this->do_get(__in, __end, __io, __err, __v); } 2144 : 2145 : protected: 2146 : /// Destructor. 2147 : virtual ~num_get() { } 2148 : 2149 : iter_type 2150 : _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, 2151 : string& __xtrc) const; 2152 : 2153 : template<typename _ValueT> 2154 : iter_type 2155 : _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, 2156 : _ValueT& __v) const; 2157 : 2158 : template<typename _CharT2> 2159 : typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, int>::__type 2160 : _M_find(const _CharT2*, size_t __len, _CharT2 __c) const 2161 : { 2162 : int __ret = -1; 2163 : if (__len <= 10) 2164 : { 2165 : if (__c >= _CharT2('0') && __c < _CharT2(_CharT2('0') + __len)) 2166 : __ret = __c - _CharT2('0'); 2167 : } 2168 : else 2169 : { 2170 : if (__c >= _CharT2('0') && __c <= _CharT2('9')) 2171 : __ret = __c - _CharT2('0'); 2172 : else if (__c >= _CharT2('a') && __c <= _CharT2('f')) 2173 : __ret = 10 + (__c - _CharT2('a')); 2174 : else if (__c >= _CharT2('A') && __c <= _CharT2('F')) 2175 : __ret = 10 + (__c - _CharT2('A')); 2176 : } 2177 : return __ret; 2178 : } 2179 : 2180 : template<typename _CharT2> 2181 : typename __gnu_cxx::__enable_if<!__is_char<_CharT2>::__value, 2182 : int>::__type 2183 : _M_find(const _CharT2* __zero, size_t __len, _CharT2 __c) const 2184 : { 2185 : int __ret = -1; 2186 : const char_type* __q = char_traits<_CharT2>::find(__zero, __len, __c); 2187 : if (__q) 2188 : { 2189 : __ret = __q - __zero; 2190 : if (__ret > 15) 2191 : __ret -= 6; 2192 : } 2193 : return __ret; 2194 : } 2195 : 2196 : //@{ 2197 : /** 2198 : * @brief Numeric parsing. 2199 : * 2200 : * Parses the input stream into the variable @a v. This function is a 2201 : * hook for derived classes to change the value returned. @see get() 2202 : * for more details. 2203 : * 2204 : * @param in Start of input stream. 2205 : * @param end End of input stream. 2206 : * @param io Source of locale and flags. 2207 : * @param err Error flags to set. 2208 : * @param v Value to format and insert. 2209 : * @return Iterator after reading. 2210 : */ 2211 : virtual iter_type 2212 : do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; 2213 : 2214 : 2215 : virtual iter_type 2216 : do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const; 2217 : 2218 : virtual iter_type 2219 : do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2220 : unsigned short&) const; 2221 : 2222 : virtual iter_type 2223 : do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2224 : unsigned int&) const; 2225 : 2226 : virtual iter_type 2227 : do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2228 : unsigned long&) const; 2229 : 2230 : #ifdef _GLIBCXX_USE_LONG_LONG 2231 : virtual iter_type 2232 : do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2233 : long long&) const; 2234 : 2235 : virtual iter_type 2236 : do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2237 : unsigned long long&) const; 2238 : #endif 2239 : 2240 : virtual iter_type 2241 : do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2242 : float&) const; 2243 : 2244 : virtual iter_type 2245 : do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2246 : double&) const; 2247 : 2248 : // XXX GLIBCXX_ABI Deprecated 2249 : #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 2250 : virtual iter_type 2251 : __do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2252 : double&) const; 2253 : #else 2254 : virtual iter_type 2255 : do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2256 : long double&) const; 2257 : #endif 2258 : 2259 : virtual iter_type 2260 : do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2261 : void*&) const; 2262 : 2263 : // XXX GLIBCXX_ABI Deprecated 2264 : #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 2265 : virtual iter_type 2266 : do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 2267 : long double&) const; 2268 : #endif 2269 : //@} 2270 : }; 2271 : 2272 : template<typename _CharT, typename _InIter> 2273 : locale::id num_get<_CharT, _InIter>::id; 2274 : 2275 : 2276 : /** 2277 : * @brief Facet for converting numbers to strings. 2278 : * 2279 : * This facet encapsulates the code to convert a number to a string. It is 2280 : * used by the ostream numeric insertion operators. 2281 : * 2282 : * The num_put template uses protected virtual functions to provide the 2283 : * actual results. The public accessors forward the call to the virtual 2284 : * functions. These virtual functions are hooks for developers to 2285 : * implement the behavior they require from the num_put facet. 2286 : */ 2287 : template<typename _CharT, typename _OutIter> 2288 : class num_put : public locale::facet 2289 : { 2290 : public: 2291 : // Types: 2292 : //@{ 2293 : /// Public typedefs 2294 : typedef _CharT char_type; 2295 : typedef _OutIter iter_type; 2296 : //@} 2297 : 2298 : /// Numpunct facet id. 2299 : static locale::id id; 2300 : 2301 : /** 2302 : * @brief Constructor performs initialization. 2303 : * 2304 : * This is the constructor provided by the standard. 2305 : * 2306 : * @param refs Passed to the base facet class. 2307 : */ 2308 : explicit 2309 : num_put(size_t __refs = 0) : facet(__refs) { } 2310 : 2311 : /** 2312 : * @brief Numeric formatting. 2313 : * 2314 : * Formats the boolean @a v and inserts it into a stream. It does so 2315 : * by calling num_put::do_put(). 2316 : * 2317 : * If ios_base::boolalpha is set, writes ctype<CharT>::truename() or 2318 : * ctype<CharT>::falsename(). Otherwise formats @a v as an int. 2319 : * 2320 : * @param s Stream to write to. 2321 : * @param io Source of locale and flags. 2322 : * @param fill Char_type to use for filling. 2323 : * @param v Value to format and insert. 2324 : * @return Iterator after writing. 2325 : */ 2326 : iter_type 2327 : put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const 2328 : { return this->do_put(__s, __f, __fill, __v); } 2329 : 2330 : //@{ 2331 : /** 2332 : * @brief Numeric formatting. 2333 : * 2334 : * Formats the integral value @a v and inserts it into a 2335 : * stream. It does so by calling num_put::do_put(). 2336 : * 2337 : * Formatting is affected by the flag settings in @a io. 2338 : * 2339 : * The basic format is affected by the value of io.flags() & 2340 : * ios_base::basefield. If equal to ios_base::oct, formats like the 2341 : * printf %o specifier. Else if equal to ios_base::hex, formats like 2342 : * %x or %X with ios_base::uppercase unset or set respectively. 2343 : * Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu 2344 : * for unsigned values. Note that if both oct and hex are set, neither 2345 : * will take effect. 2346 : * 2347 : * If ios_base::showpos is set, '+' is output before positive values. 2348 : * If ios_base::showbase is set, '0' precedes octal values (except 0) 2349 : * and '0[xX]' precedes hex values. 2350 : * 2351 : * Thousands separators are inserted according to numpunct::grouping() 2352 : * and numpunct::thousands_sep(). The decimal point character used is 2353 : * numpunct::decimal_point(). 2354 : * 2355 : * If io.width() is non-zero, enough @a fill characters are inserted to 2356 : * make the result at least that wide. If 2357 : * (io.flags() & ios_base::adjustfield) == ios_base::left, result is 2358 : * padded at the end. If ios_base::internal, then padding occurs 2359 : * immediately after either a '+' or '-' or after '0x' or '0X'. 2360 : * Otherwise, padding occurs at the beginning. 2361 : * 2362 : * @param s Stream to write to. 2363 : * @param io Source of locale and flags. 2364 : * @param fill Char_type to use for filling. 2365 : * @param v Value to format and insert. 2366 : * @return Iterator after writing. 2367 : */ 2368 : iter_type 2369 : put(iter_type __s, ios_base& __f, char_type __fill, long __v) const 2370 : { return this->do_put(__s, __f, __fill, __v); } 2371 : 2372 : iter_type 2373 : put(iter_type __s, ios_base& __f, char_type __fill, 2374 : unsigned long __v) const 2375 : { return this->do_put(__s, __f, __fill, __v); } 2376 : 2377 : #ifdef _GLIBCXX_USE_LONG_LONG 2378 : iter_type 2379 : put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const 2380 : { return this->do_put(__s, __f, __fill, __v); } 2381 : 2382 : iter_type 2383 : put(iter_type __s, ios_base& __f, char_type __fill, 2384 : unsigned long long __v) const 2385 : { return this->do_put(__s, __f, __fill, __v); } 2386 : #endif 2387 : //@} 2388 : 2389 : //@{ 2390 : /** 2391 : * @brief Numeric formatting. 2392 : * 2393 : * Formats the floating point value @a v and inserts it into a stream. 2394 : * It does so by calling num_put::do_put(). 2395 : * 2396 : * Formatting is affected by the flag settings in @a io. 2397 : * 2398 : * The basic format is affected by the value of io.flags() & 2399 : * ios_base::floatfield. If equal to ios_base::fixed, formats like the 2400 : * printf %f specifier. Else if equal to ios_base::scientific, formats 2401 : * like %e or %E with ios_base::uppercase unset or set respectively. 2402 : * Otherwise, formats like %g or %G depending on uppercase. Note that 2403 : * if both fixed and scientific are set, the effect will also be like 2404 : * %g or %G. 2405 : * 2406 : * The output precision is given by io.precision(). This precision is 2407 : * capped at numeric_limits::digits10 + 2 (different for double and 2408 : * long double). The default precision is 6. 2409 : * 2410 : * If ios_base::showpos is set, '+' is output before positive values. 2411 : * If ios_base::showpoint is set, a decimal point will always be 2412 : * output. 2413 : * 2414 : * Thousands separators are inserted according to numpunct::grouping() 2415 : * and numpunct::thousands_sep(). The decimal point character used is 2416 : * numpunct::decimal_point(). 2417 : * 2418 : * If io.width() is non-zero, enough @a fill characters are inserted to 2419 : * make the result at least that wide. If 2420 : * (io.flags() & ios_base::adjustfield) == ios_base::left, result is 2421 : * padded at the end. If ios_base::internal, then padding occurs 2422 : * immediately after either a '+' or '-' or after '0x' or '0X'. 2423 : * Otherwise, padding occurs at the beginning. 2424 : * 2425 : * @param s Stream to write to. 2426 : * @param io Source of locale and flags. 2427 : * @param fill Char_type to use for filling. 2428 : * @param v Value to format and insert. 2429 : * @return Iterator after writing. 2430 : */ 2431 : iter_type 2432 : put(iter_type __s, ios_base& __f, char_type __fill, double __v) const 2433 : { return this->do_put(__s, __f, __fill, __v); } 2434 : 2435 : iter_type 2436 : put(iter_type __s, ios_base& __f, char_type __fill, 2437 : long double __v) const 2438 : { return this->do_put(__s, __f, __fill, __v); } 2439 : //@} 2440 : 2441 : /** 2442 : * @brief Numeric formatting. 2443 : * 2444 : * Formats the pointer value @a v and inserts it into a stream. It 2445 : * does so by calling num_put::do_put(). 2446 : * 2447 : * This function formats @a v as an unsigned long with ios_base::hex 2448 : * and ios_base::showbase set. 2449 : * 2450 : * @param s Stream to write to. 2451 : * @param io Source of locale and flags. 2452 : * @param fill Char_type to use for filling. 2453 : * @param v Value to format and insert. 2454 : * @return Iterator after writing. 2455 : */ 2456 : iter_type 2457 : put(iter_type __s, ios_base& __f, char_type __fill, 2458 : const void* __v) const 2459 : { return this->do_put(__s, __f, __fill, __v); } 2460 : 2461 : protected: 2462 : template<typename _ValueT> 2463 : iter_type 2464 : _M_insert_float(iter_type, ios_base& __io, char_type __fill, 2465 : char __mod, _ValueT __v) const; 2466 : 2467 : void 2468 : _M_group_float(const char* __grouping, size_t __grouping_size, 2469 : char_type __sep, const char_type* __p, char_type* __new, 2470 : char_type* __cs, int& __len) const; 2471 : 2472 : template<typename _ValueT> 2473 : iter_type 2474 : _M_insert_int(iter_type, ios_base& __io, char_type __fill, 2475 : _ValueT __v) const; 2476 : 2477 : void 2478 : _M_group_int(const char* __grouping, size_t __grouping_size, 2479 : char_type __sep, ios_base& __io, char_type* __new, 2480 : char_type* __cs, int& __len) const; 2481 : 2482 : void 2483 : _M_pad(char_type __fill, streamsize __w, ios_base& __io, 2484 : char_type* __new, const char_type* __cs, int& __len) const; 2485 : 2486 : /// Destructor. 2487 : virtual 2488 : ~num_put() { }; 2489 : 2490 : //@{ 2491 : /** 2492 : * @brief Numeric formatting. 2493 : * 2494 : * These functions do the work of formatting numeric values and 2495 : * inserting them into a stream. This function is a hook for derived 2496 : * classes to change the value returned. 2497 : * 2498 : * @param s Stream to write to. 2499 : * @param io Source of locale and flags. 2500 : * @param fill Char_type to use for filling. 2501 : * @param v Value to format and insert. 2502 : * @return Iterator after writing. 2503 : */ 2504 : virtual iter_type 2505 : do_put(iter_type, ios_base&, char_type __fill, bool __v) const; 2506 : 2507 : virtual iter_type 2508 : do_put(iter_type, ios_base&, char_type __fill, long __v) const; 2509 : 2510 : virtual iter_type 2511 : do_put(iter_type, ios_base&, char_type __fill, unsigned long) const; 2512 : 2513 : #ifdef _GLIBCXX_USE_LONG_LONG 2514 : virtual iter_type 2515 : do_put(iter_type, ios_base&, char_type __fill, long long __v) const; 2516 : 2517 : virtual iter_type 2518 : do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const; 2519 : #endif 2520 : 2521 : virtual iter_type 2522 : do_put(iter_type, ios_base&, char_type __fill, double __v) const; 2523 : 2524 : // XXX GLIBCXX_ABI Deprecated 2525 : #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 2526 : virtual iter_type 2527 : __do_put(iter_type, ios_base&, char_type __fill, double __v) const; 2528 : #else 2529 : virtual iter_type 2530 : do_put(iter_type, ios_base&, char_type __fill, long double __v) const; 2531 : #endif 2532 : 2533 : virtual iter_type 2534 : do_put(iter_type, ios_base&, char_type __fill, const void* __v) const; 2535 : 2536 : // XXX GLIBCXX_ABI Deprecated 2537 : #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 2538 : virtual iter_type 2539 : do_put(iter_type, ios_base&, char_type __fill, long double __v) const; 2540 : #endif 2541 : //@} 2542 : }; 2543 : 2544 : template <typename _CharT, typename _OutIter> 2545 : locale::id num_put<_CharT, _OutIter>::id; 2546 : 2547 : _GLIBCXX_END_LDBL_NAMESPACE 2548 : 2549 : // Subclause convenience interfaces, inlines. 2550 : // NB: These are inline because, when used in a loop, some compilers 2551 : // can hoist the body out of the loop; then it's just as fast as the 2552 : // C is*() function. 2553 : 2554 : /// Convenience interface to ctype.is(ctype_base::space, __c). 2555 : template<typename _CharT> 2556 : inline bool 2557 : isspace(_CharT __c, const locale& __loc) 2558 : { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); } 2559 : 2560 : /// Convenience interface to ctype.is(ctype_base::print, __c). 2561 : template<typename _CharT> 2562 : inline bool 2563 : isprint(_CharT __c, const locale& __loc) 2564 : { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); } 2565 : 2566 : /// Convenience interface to ctype.is(ctype_base::cntrl, __c). 2567 : template<typename _CharT> 2568 : inline bool 2569 : iscntrl(_CharT __c, const locale& __loc) 2570 : { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); } 2571 : 2572 : /// Convenience interface to ctype.is(ctype_base::upper, __c). 2573 : template<typename _CharT> 2574 : inline bool 2575 : isupper(_CharT __c, const locale& __loc) 2576 : { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); } 2577 : 2578 : /// Convenience interface to ctype.is(ctype_base::lower, __c). 2579 : template<typename _CharT> 2580 : inline bool 2581 : islower(_CharT __c, const locale& __loc) 2582 : { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); } 2583 : 2584 : /// Convenience interface to ctype.is(ctype_base::alpha, __c). 2585 : template<typename _CharT> 2586 : inline bool 2587 : isalpha(_CharT __c, const locale& __loc) 2588 : { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); } 2589 : 2590 : /// Convenience interface to ctype.is(ctype_base::digit, __c). 2591 : template<typename _CharT> 2592 : inline bool 2593 : isdigit(_CharT __c, const locale& __loc) 2594 : { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); } 2595 : 2596 : /// Convenience interface to ctype.is(ctype_base::punct, __c). 2597 : template<typename _CharT> 2598 : inline bool 2599 : ispunct(_CharT __c, const locale& __loc) 2600 : { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); } 2601 : 2602 : /// Convenience interface to ctype.is(ctype_base::xdigit, __c). 2603 : template<typename _CharT> 2604 : inline bool 2605 : isxdigit(_CharT __c, const locale& __loc) 2606 : { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); } 2607 : 2608 : /// Convenience interface to ctype.is(ctype_base::alnum, __c). 2609 : template<typename _CharT> 2610 : inline bool 2611 : isalnum(_CharT __c, const locale& __loc) 2612 : { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); } 2613 : 2614 : /// Convenience interface to ctype.is(ctype_base::graph, __c). 2615 : template<typename _CharT> 2616 : inline bool 2617 : isgraph(_CharT __c, const locale& __loc) 2618 : { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); } 2619 : 2620 : /// Convenience interface to ctype.toupper(__c). 2621 : template<typename _CharT> 2622 : inline _CharT 2623 : toupper(_CharT __c, const locale& __loc) 2624 : { return use_facet<ctype<_CharT> >(__loc).toupper(__c); } 2625 : 2626 : /// Convenience interface to ctype.tolower(__c). 2627 : template<typename _CharT> 2628 : inline _CharT 2629 : tolower(_CharT __c, const locale& __loc) 2630 : { return use_facet<ctype<_CharT> >(__loc).tolower(__c); } 2631 : 2632 : _GLIBCXX_END_NAMESPACE 2633 : 2634 : #ifndef _GLIBCXX_EXPORT_TEMPLATE 2635 : # include <bits/locale_facets.tcc> 2636 : #endif 2637 : 2638 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Deque implementation (out of line) -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1997 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file deque.tcc 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _DEQUE_TCC 63 : #define _DEQUE_TCC 1 64 : 65 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) 66 : 67 : template <typename _Tp, typename _Alloc> 68 : deque<_Tp, _Alloc>& 69 : deque<_Tp, _Alloc>:: 70 4 : operator=(const deque& __x) 71 : { 72 4 : const size_type __len = size(); 73 4 : if (&__x != this) 74 : { 75 4 : if (__len >= __x.size()) 76 4 : _M_erase_at_end(std::copy(__x.begin(), __x.end(), 77 : this->_M_impl._M_start)); 78 : else 79 : { 80 0 : const_iterator __mid = __x.begin() + difference_type(__len); 81 0 : std::copy(__x.begin(), __mid, this->_M_impl._M_start); 82 0 : insert(this->_M_impl._M_finish, __mid, __x.end()); 83 : } 84 : } 85 4 : return *this; 86 : } 87 : 88 : template <typename _Tp, typename _Alloc> 89 : typename deque<_Tp, _Alloc>::iterator 90 : deque<_Tp, _Alloc>:: 91 : insert(iterator __position, const value_type& __x) 92 : { 93 : if (__position._M_cur == this->_M_impl._M_start._M_cur) 94 : { 95 : push_front(__x); 96 : return this->_M_impl._M_start; 97 : } 98 : else if (__position._M_cur == this->_M_impl._M_finish._M_cur) 99 : { 100 : push_back(__x); 101 : iterator __tmp = this->_M_impl._M_finish; 102 : --__tmp; 103 : return __tmp; 104 : } 105 : else 106 : return _M_insert_aux(__position, __x); 107 : } 108 : 109 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 110 : template<typename _Tp, typename _Alloc> 111 : template<typename... _Args> 112 : typename deque<_Tp, _Alloc>::iterator 113 : deque<_Tp, _Alloc>:: 114 : emplace(iterator __position, _Args&&... __args) 115 : { 116 : if (__position._M_cur == this->_M_impl._M_start._M_cur) 117 : { 118 : push_front(std::forward<_Args>(__args)...); 119 : return this->_M_impl._M_start; 120 : } 121 : else if (__position._M_cur == this->_M_impl._M_finish._M_cur) 122 : { 123 : push_back(std::forward<_Args>(__args)...); 124 : iterator __tmp = this->_M_impl._M_finish; 125 : --__tmp; 126 : return __tmp; 127 : } 128 : else 129 : return _M_insert_aux(__position, std::forward<_Args>(__args)...); 130 : } 131 : #endif 132 : 133 : template <typename _Tp, typename _Alloc> 134 : typename deque<_Tp, _Alloc>::iterator 135 : deque<_Tp, _Alloc>:: 136 : erase(iterator __position) 137 : { 138 : iterator __next = __position; 139 : ++__next; 140 : const difference_type __index = __position - begin(); 141 : if (static_cast<size_type>(__index) < (size() >> 1)) 142 : { 143 : if (__position != begin()) 144 : _GLIBCXX_MOVE_BACKWARD3(begin(), __position, __next); 145 : pop_front(); 146 : } 147 : else 148 : { 149 : if (__next != end()) 150 : _GLIBCXX_MOVE3(__next, end(), __position); 151 : pop_back(); 152 : } 153 : return begin() + __index; 154 : } 155 : 156 : template <typename _Tp, typename _Alloc> 157 : typename deque<_Tp, _Alloc>::iterator 158 : deque<_Tp, _Alloc>:: 159 1012 : erase(iterator __first, iterator __last) 160 : { 161 1012 : if (__first == begin() && __last == end()) 162 : { 163 922 : clear(); 164 922 : return end(); 165 : } 166 : else 167 : { 168 90 : const difference_type __n = __last - __first; 169 90 : const difference_type __elems_before = __first - begin(); 170 90 : if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2) 171 : { 172 90 : if (__first != begin()) 173 0 : _GLIBCXX_MOVE_BACKWARD3(begin(), __first, __last); 174 90 : _M_erase_at_begin(begin() + __n); 175 : } 176 : else 177 : { 178 0 : if (__last != end()) 179 0 : _GLIBCXX_MOVE3(__last, end(), __first); 180 0 : _M_erase_at_end(end() - __n); 181 : } 182 90 : return begin() + __elems_before; 183 : } 184 : } 185 : 186 : template <typename _Tp, class _Alloc> 187 : template <typename _InputIterator> 188 : void 189 : deque<_Tp, _Alloc>:: 190 : _M_assign_aux(_InputIterator __first, _InputIterator __last, 191 : std::input_iterator_tag) 192 : { 193 : iterator __cur = begin(); 194 : for (; __first != __last && __cur != end(); ++__cur, ++__first) 195 : *__cur = *__first; 196 : if (__first == __last) 197 : _M_erase_at_end(__cur); 198 : else 199 : insert(end(), __first, __last); 200 : } 201 : 202 : template <typename _Tp, typename _Alloc> 203 : void 204 : deque<_Tp, _Alloc>:: 205 : _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) 206 : { 207 : if (__pos._M_cur == this->_M_impl._M_start._M_cur) 208 : { 209 : iterator __new_start = _M_reserve_elements_at_front(__n); 210 : try 211 : { 212 : std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start, 213 : __x, _M_get_Tp_allocator()); 214 : this->_M_impl._M_start = __new_start; 215 : } 216 : catch(...) 217 : { 218 : _M_destroy_nodes(__new_start._M_node, 219 : this->_M_impl._M_start._M_node); 220 : __throw_exception_again; 221 : } 222 : } 223 : else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) 224 : { 225 : iterator __new_finish = _M_reserve_elements_at_back(__n); 226 : try 227 : { 228 : std::__uninitialized_fill_a(this->_M_impl._M_finish, 229 : __new_finish, __x, 230 : _M_get_Tp_allocator()); 231 : this->_M_impl._M_finish = __new_finish; 232 : } 233 : catch(...) 234 : { 235 : _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 236 : __new_finish._M_node + 1); 237 : __throw_exception_again; 238 : } 239 : } 240 : else 241 : _M_insert_aux(__pos, __n, __x); 242 : } 243 : 244 : template <typename _Tp, typename _Alloc> 245 : void 246 : deque<_Tp, _Alloc>:: 247 : _M_fill_initialize(const value_type& __value) 248 : { 249 : _Map_pointer __cur; 250 : try 251 : { 252 : for (__cur = this->_M_impl._M_start._M_node; 253 : __cur < this->_M_impl._M_finish._M_node; 254 : ++__cur) 255 : std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(), 256 : __value, _M_get_Tp_allocator()); 257 : std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first, 258 : this->_M_impl._M_finish._M_cur, 259 : __value, _M_get_Tp_allocator()); 260 : } 261 : catch(...) 262 : { 263 : std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur), 264 : _M_get_Tp_allocator()); 265 : __throw_exception_again; 266 : } 267 : } 268 : 269 : template <typename _Tp, typename _Alloc> 270 : template <typename _InputIterator> 271 : void 272 : deque<_Tp, _Alloc>:: 273 : _M_range_initialize(_InputIterator __first, _InputIterator __last, 274 : std::input_iterator_tag) 275 : { 276 : this->_M_initialize_map(0); 277 : try 278 : { 279 : for (; __first != __last; ++__first) 280 : push_back(*__first); 281 : } 282 : catch(...) 283 : { 284 : clear(); 285 : __throw_exception_again; 286 : } 287 : } 288 : 289 : template <typename _Tp, typename _Alloc> 290 : template <typename _ForwardIterator> 291 : void 292 : deque<_Tp, _Alloc>:: 293 : _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, 294 : std::forward_iterator_tag) 295 : { 296 : const size_type __n = std::distance(__first, __last); 297 : this->_M_initialize_map(__n); 298 : 299 : _Map_pointer __cur_node; 300 : try 301 : { 302 : for (__cur_node = this->_M_impl._M_start._M_node; 303 : __cur_node < this->_M_impl._M_finish._M_node; 304 : ++__cur_node) 305 : { 306 : _ForwardIterator __mid = __first; 307 : std::advance(__mid, _S_buffer_size()); 308 : std::__uninitialized_copy_a(__first, __mid, *__cur_node, 309 : _M_get_Tp_allocator()); 310 : __first = __mid; 311 : } 312 : std::__uninitialized_copy_a(__first, __last, 313 : this->_M_impl._M_finish._M_first, 314 : _M_get_Tp_allocator()); 315 : } 316 : catch(...) 317 : { 318 : std::_Destroy(this->_M_impl._M_start, 319 : iterator(*__cur_node, __cur_node), 320 : _M_get_Tp_allocator()); 321 : __throw_exception_again; 322 : } 323 : } 324 : 325 : // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1. 326 : template<typename _Tp, typename _Alloc> 327 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 328 : template<typename... _Args> 329 : void 330 : deque<_Tp, _Alloc>:: 331 : _M_push_back_aux(_Args&&... __args) 332 : #else 333 : void 334 : deque<_Tp, _Alloc>:: 335 13 : _M_push_back_aux(const value_type& __t) 336 : #endif 337 : { 338 13 : _M_reserve_map_at_back(); 339 13 : *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); 340 : try 341 : { 342 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 343 : this->_M_impl.construct(this->_M_impl._M_finish._M_cur, 344 : std::forward<_Args>(__args)...); 345 : #else 346 13 : this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t); 347 : #endif 348 13 : this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node 349 : + 1); 350 13 : this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; 351 : } 352 0 : catch(...) 353 : { 354 0 : _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); 355 0 : __throw_exception_again; 356 : } 357 13 : } 358 : 359 : // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first. 360 : template<typename _Tp, typename _Alloc> 361 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 362 : template<typename... _Args> 363 : void 364 : deque<_Tp, _Alloc>:: 365 : _M_push_front_aux(_Args&&... __args) 366 : #else 367 : void 368 : deque<_Tp, _Alloc>:: 369 : _M_push_front_aux(const value_type& __t) 370 : #endif 371 : { 372 : _M_reserve_map_at_front(); 373 : *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); 374 : try 375 : { 376 : this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node 377 : - 1); 378 : this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; 379 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 380 : this->_M_impl.construct(this->_M_impl._M_start._M_cur, 381 : std::forward<_Args>(__args)...); 382 : #else 383 : this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t); 384 : #endif 385 : } 386 : catch(...) 387 : { 388 : ++this->_M_impl._M_start; 389 : _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); 390 : __throw_exception_again; 391 : } 392 : } 393 : 394 : // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first. 395 : template <typename _Tp, typename _Alloc> 396 : void deque<_Tp, _Alloc>:: 397 0 : _M_pop_back_aux() 398 : { 399 0 : _M_deallocate_node(this->_M_impl._M_finish._M_first); 400 0 : this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1); 401 0 : this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1; 402 0 : this->_M_impl.destroy(this->_M_impl._M_finish._M_cur); 403 0 : } 404 : 405 : // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1. 406 : // Note that if the deque has at least one element (a precondition for this 407 : // member function), and if 408 : // _M_impl._M_start._M_cur == _M_impl._M_start._M_last, 409 : // then the deque must have at least two nodes. 410 : template <typename _Tp, typename _Alloc> 411 : void deque<_Tp, _Alloc>:: 412 : _M_pop_front_aux() 413 : { 414 : this->_M_impl.destroy(this->_M_impl._M_start._M_cur); 415 : _M_deallocate_node(this->_M_impl._M_start._M_first); 416 : this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1); 417 : this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first; 418 : } 419 : 420 : template <typename _Tp, typename _Alloc> 421 : template <typename _InputIterator> 422 : void 423 : deque<_Tp, _Alloc>:: 424 : _M_range_insert_aux(iterator __pos, 425 : _InputIterator __first, _InputIterator __last, 426 : std::input_iterator_tag) 427 : { std::copy(__first, __last, std::inserter(*this, __pos)); } 428 : 429 : template <typename _Tp, typename _Alloc> 430 : template <typename _ForwardIterator> 431 : void 432 : deque<_Tp, _Alloc>:: 433 : _M_range_insert_aux(iterator __pos, 434 : _ForwardIterator __first, _ForwardIterator __last, 435 0 : std::forward_iterator_tag) 436 : { 437 0 : const size_type __n = std::distance(__first, __last); 438 0 : if (__pos._M_cur == this->_M_impl._M_start._M_cur) 439 : { 440 0 : iterator __new_start = _M_reserve_elements_at_front(__n); 441 : try 442 : { 443 0 : std::__uninitialized_copy_a(__first, __last, __new_start, 444 : _M_get_Tp_allocator()); 445 0 : this->_M_impl._M_start = __new_start; 446 : } 447 0 : catch(...) 448 : { 449 0 : _M_destroy_nodes(__new_start._M_node, 450 : this->_M_impl._M_start._M_node); 451 0 : __throw_exception_again; 452 : } 453 : } 454 0 : else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) 455 : { 456 0 : iterator __new_finish = _M_reserve_elements_at_back(__n); 457 : try 458 : { 459 0 : std::__uninitialized_copy_a(__first, __last, 460 : this->_M_impl._M_finish, 461 : _M_get_Tp_allocator()); 462 0 : this->_M_impl._M_finish = __new_finish; 463 : } 464 0 : catch(...) 465 : { 466 0 : _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 467 : __new_finish._M_node + 1); 468 0 : __throw_exception_again; 469 : } 470 : } 471 : else 472 0 : _M_insert_aux(__pos, __first, __last, __n); 473 0 : } 474 : 475 : template<typename _Tp, typename _Alloc> 476 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 477 : template<typename... _Args> 478 : typename deque<_Tp, _Alloc>::iterator 479 : deque<_Tp, _Alloc>:: 480 : _M_insert_aux(iterator __pos, _Args&&... __args) 481 : { 482 : value_type __x_copy(std::forward<_Args>(__args)...); // XXX copy 483 : #else 484 : typename deque<_Tp, _Alloc>::iterator 485 : deque<_Tp, _Alloc>:: 486 : _M_insert_aux(iterator __pos, const value_type& __x) 487 : { 488 : value_type __x_copy = __x; // XXX copy 489 : #endif 490 : difference_type __index = __pos - this->_M_impl._M_start; 491 : if (static_cast<size_type>(__index) < size() / 2) 492 : { 493 : push_front(_GLIBCXX_MOVE(front())); 494 : iterator __front1 = this->_M_impl._M_start; 495 : ++__front1; 496 : iterator __front2 = __front1; 497 : ++__front2; 498 : __pos = this->_M_impl._M_start + __index; 499 : iterator __pos1 = __pos; 500 : ++__pos1; 501 : _GLIBCXX_MOVE3(__front2, __pos1, __front1); 502 : } 503 : else 504 : { 505 : push_back(_GLIBCXX_MOVE(back())); 506 : iterator __back1 = this->_M_impl._M_finish; 507 : --__back1; 508 : iterator __back2 = __back1; 509 : --__back2; 510 : __pos = this->_M_impl._M_start + __index; 511 : _GLIBCXX_MOVE_BACKWARD3(__pos, __back2, __back1); 512 : } 513 : *__pos = _GLIBCXX_MOVE(__x_copy); 514 : return __pos; 515 : } 516 : 517 : template <typename _Tp, typename _Alloc> 518 : void 519 : deque<_Tp, _Alloc>:: 520 : _M_insert_aux(iterator __pos, size_type __n, const value_type& __x) 521 : { 522 : const difference_type __elems_before = __pos - this->_M_impl._M_start; 523 : const size_type __length = this->size(); 524 : value_type __x_copy = __x; 525 : if (__elems_before < difference_type(__length / 2)) 526 : { 527 : iterator __new_start = _M_reserve_elements_at_front(__n); 528 : iterator __old_start = this->_M_impl._M_start; 529 : __pos = this->_M_impl._M_start + __elems_before; 530 : try 531 : { 532 : if (__elems_before >= difference_type(__n)) 533 : { 534 : iterator __start_n = (this->_M_impl._M_start 535 : + difference_type(__n)); 536 : std::__uninitialized_move_a(this->_M_impl._M_start, 537 : __start_n, __new_start, 538 : _M_get_Tp_allocator()); 539 : this->_M_impl._M_start = __new_start; 540 : _GLIBCXX_MOVE3(__start_n, __pos, __old_start); 541 : std::fill(__pos - difference_type(__n), __pos, __x_copy); 542 : } 543 : else 544 : { 545 : std::__uninitialized_move_fill(this->_M_impl._M_start, 546 : __pos, __new_start, 547 : this->_M_impl._M_start, 548 : __x_copy, 549 : _M_get_Tp_allocator()); 550 : this->_M_impl._M_start = __new_start; 551 : std::fill(__old_start, __pos, __x_copy); 552 : } 553 : } 554 : catch(...) 555 : { 556 : _M_destroy_nodes(__new_start._M_node, 557 : this->_M_impl._M_start._M_node); 558 : __throw_exception_again; 559 : } 560 : } 561 : else 562 : { 563 : iterator __new_finish = _M_reserve_elements_at_back(__n); 564 : iterator __old_finish = this->_M_impl._M_finish; 565 : const difference_type __elems_after = 566 : difference_type(__length) - __elems_before; 567 : __pos = this->_M_impl._M_finish - __elems_after; 568 : try 569 : { 570 : if (__elems_after > difference_type(__n)) 571 : { 572 : iterator __finish_n = (this->_M_impl._M_finish 573 : - difference_type(__n)); 574 : std::__uninitialized_move_a(__finish_n, 575 : this->_M_impl._M_finish, 576 : this->_M_impl._M_finish, 577 : _M_get_Tp_allocator()); 578 : this->_M_impl._M_finish = __new_finish; 579 : _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish); 580 : std::fill(__pos, __pos + difference_type(__n), __x_copy); 581 : } 582 : else 583 : { 584 : std::__uninitialized_fill_move(this->_M_impl._M_finish, 585 : __pos + difference_type(__n), 586 : __x_copy, __pos, 587 : this->_M_impl._M_finish, 588 : _M_get_Tp_allocator()); 589 : this->_M_impl._M_finish = __new_finish; 590 : std::fill(__pos, __old_finish, __x_copy); 591 : } 592 : } 593 : catch(...) 594 : { 595 : _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 596 : __new_finish._M_node + 1); 597 : __throw_exception_again; 598 : } 599 : } 600 : } 601 : 602 : template <typename _Tp, typename _Alloc> 603 : template <typename _ForwardIterator> 604 : void 605 : deque<_Tp, _Alloc>:: 606 : _M_insert_aux(iterator __pos, 607 : _ForwardIterator __first, _ForwardIterator __last, 608 0 : size_type __n) 609 : { 610 0 : const difference_type __elemsbefore = __pos - this->_M_impl._M_start; 611 0 : const size_type __length = size(); 612 0 : if (static_cast<size_type>(__elemsbefore) < __length / 2) 613 : { 614 0 : iterator __new_start = _M_reserve_elements_at_front(__n); 615 0 : iterator __old_start = this->_M_impl._M_start; 616 0 : __pos = this->_M_impl._M_start + __elemsbefore; 617 : try 618 : { 619 0 : if (__elemsbefore >= difference_type(__n)) 620 : { 621 : iterator __start_n = (this->_M_impl._M_start 622 0 : + difference_type(__n)); 623 0 : std::__uninitialized_move_a(this->_M_impl._M_start, 624 : __start_n, __new_start, 625 : _M_get_Tp_allocator()); 626 0 : this->_M_impl._M_start = __new_start; 627 0 : _GLIBCXX_MOVE3(__start_n, __pos, __old_start); 628 0 : std::copy(__first, __last, __pos - difference_type(__n)); 629 : } 630 : else 631 : { 632 0 : _ForwardIterator __mid = __first; 633 0 : std::advance(__mid, difference_type(__n) - __elemsbefore); 634 0 : std::__uninitialized_move_copy(this->_M_impl._M_start, 635 : __pos, __first, __mid, 636 : __new_start, 637 : _M_get_Tp_allocator()); 638 0 : this->_M_impl._M_start = __new_start; 639 0 : std::copy(__mid, __last, __old_start); 640 : } 641 : } 642 0 : catch(...) 643 : { 644 0 : _M_destroy_nodes(__new_start._M_node, 645 : this->_M_impl._M_start._M_node); 646 0 : __throw_exception_again; 647 : } 648 : } 649 : else 650 : { 651 0 : iterator __new_finish = _M_reserve_elements_at_back(__n); 652 0 : iterator __old_finish = this->_M_impl._M_finish; 653 : const difference_type __elemsafter = 654 0 : difference_type(__length) - __elemsbefore; 655 0 : __pos = this->_M_impl._M_finish - __elemsafter; 656 : try 657 : { 658 0 : if (__elemsafter > difference_type(__n)) 659 : { 660 : iterator __finish_n = (this->_M_impl._M_finish 661 0 : - difference_type(__n)); 662 0 : std::__uninitialized_move_a(__finish_n, 663 : this->_M_impl._M_finish, 664 : this->_M_impl._M_finish, 665 : _M_get_Tp_allocator()); 666 0 : this->_M_impl._M_finish = __new_finish; 667 0 : _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish); 668 0 : std::copy(__first, __last, __pos); 669 : } 670 : else 671 : { 672 0 : _ForwardIterator __mid = __first; 673 0 : std::advance(__mid, __elemsafter); 674 0 : std::__uninitialized_copy_move(__mid, __last, __pos, 675 : this->_M_impl._M_finish, 676 : this->_M_impl._M_finish, 677 : _M_get_Tp_allocator()); 678 0 : this->_M_impl._M_finish = __new_finish; 679 0 : std::copy(__first, __mid, __pos); 680 : } 681 : } 682 0 : catch(...) 683 : { 684 0 : _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 685 : __new_finish._M_node + 1); 686 0 : __throw_exception_again; 687 : } 688 : } 689 0 : } 690 : 691 : template<typename _Tp, typename _Alloc> 692 : void 693 : deque<_Tp, _Alloc>:: 694 26 : _M_destroy_data_aux(iterator __first, iterator __last) 695 : { 696 26 : for (_Map_pointer __node = __first._M_node + 1; 697 : __node < __last._M_node; ++__node) 698 0 : std::_Destroy(*__node, *__node + _S_buffer_size(), 699 : _M_get_Tp_allocator()); 700 : 701 26 : if (__first._M_node != __last._M_node) 702 : { 703 0 : std::_Destroy(__first._M_cur, __first._M_last, 704 : _M_get_Tp_allocator()); 705 0 : std::_Destroy(__last._M_first, __last._M_cur, 706 : _M_get_Tp_allocator()); 707 : } 708 : else 709 26 : std::_Destroy(__first._M_cur, __last._M_cur, 710 : _M_get_Tp_allocator()); 711 26 : } 712 : 713 : template <typename _Tp, typename _Alloc> 714 : void 715 : deque<_Tp, _Alloc>:: 716 0 : _M_new_elements_at_front(size_type __new_elems) 717 : { 718 0 : if (this->max_size() - this->size() < __new_elems) 719 0 : __throw_length_error(__N("deque::_M_new_elements_at_front")); 720 : 721 : const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) 722 0 : / _S_buffer_size()); 723 0 : _M_reserve_map_at_front(__new_nodes); 724 : size_type __i; 725 : try 726 : { 727 0 : for (__i = 1; __i <= __new_nodes; ++__i) 728 0 : *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node(); 729 : } 730 0 : catch(...) 731 : { 732 0 : for (size_type __j = 1; __j < __i; ++__j) 733 0 : _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j)); 734 0 : __throw_exception_again; 735 : } 736 0 : } 737 : 738 : template <typename _Tp, typename _Alloc> 739 : void 740 : deque<_Tp, _Alloc>:: 741 0 : _M_new_elements_at_back(size_type __new_elems) 742 : { 743 0 : if (this->max_size() - this->size() < __new_elems) 744 0 : __throw_length_error(__N("deque::_M_new_elements_at_back")); 745 : 746 : const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) 747 0 : / _S_buffer_size()); 748 0 : _M_reserve_map_at_back(__new_nodes); 749 : size_type __i; 750 : try 751 : { 752 0 : for (__i = 1; __i <= __new_nodes; ++__i) 753 0 : *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node(); 754 : } 755 0 : catch(...) 756 : { 757 0 : for (size_type __j = 1; __j < __i; ++__j) 758 0 : _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j)); 759 0 : __throw_exception_again; 760 : } 761 0 : } 762 : 763 : template <typename _Tp, typename _Alloc> 764 : void 765 : deque<_Tp, _Alloc>:: 766 0 : _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front) 767 : { 768 : const size_type __old_num_nodes 769 0 : = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1; 770 0 : const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; 771 : 772 : _Map_pointer __new_nstart; 773 0 : if (this->_M_impl._M_map_size > 2 * __new_num_nodes) 774 : { 775 0 : __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size 776 : - __new_num_nodes) / 2 777 : + (__add_at_front ? __nodes_to_add : 0); 778 0 : if (__new_nstart < this->_M_impl._M_start._M_node) 779 0 : std::copy(this->_M_impl._M_start._M_node, 780 : this->_M_impl._M_finish._M_node + 1, 781 : __new_nstart); 782 : else 783 0 : std::copy_backward(this->_M_impl._M_start._M_node, 784 : this->_M_impl._M_finish._M_node + 1, 785 : __new_nstart + __old_num_nodes); 786 : } 787 : else 788 : { 789 : size_type __new_map_size = this->_M_impl._M_map_size 790 : + std::max(this->_M_impl._M_map_size, 791 0 : __nodes_to_add) + 2; 792 : 793 0 : _Map_pointer __new_map = this->_M_allocate_map(__new_map_size); 794 0 : __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 795 : + (__add_at_front ? __nodes_to_add : 0); 796 0 : std::copy(this->_M_impl._M_start._M_node, 797 : this->_M_impl._M_finish._M_node + 1, 798 : __new_nstart); 799 0 : _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); 800 : 801 0 : this->_M_impl._M_map = __new_map; 802 0 : this->_M_impl._M_map_size = __new_map_size; 803 : } 804 : 805 0 : this->_M_impl._M_start._M_set_node(__new_nstart); 806 0 : this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); 807 0 : } 808 : 809 : // Overload for deque::iterators, exploiting the "segmented-iterator 810 : // optimization". NB: leave const_iterators alone! 811 : template<typename _Tp> 812 : void 813 : fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first, 814 : const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value) 815 : { 816 : typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; 817 : 818 : for (typename _Self::_Map_pointer __node = __first._M_node + 1; 819 : __node < __last._M_node; ++__node) 820 : std::fill(*__node, *__node + _Self::_S_buffer_size(), __value); 821 : 822 : if (__first._M_node != __last._M_node) 823 : { 824 : std::fill(__first._M_cur, __first._M_last, __value); 825 : std::fill(__last._M_first, __last._M_cur, __value); 826 : } 827 : else 828 : std::fill(__first._M_cur, __last._M_cur, __value); 829 : } 830 : 831 : _GLIBCXX_END_NESTED_NAMESPACE 832 : 833 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // vector<bool> specialization -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996-1999 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_bvector.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_BVECTOR_H 63 : #define _STL_BVECTOR_H 1 64 : 65 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) 66 : 67 : typedef unsigned long _Bit_type; 68 : enum { _S_word_bit = int(__CHAR_BIT__ * sizeof(_Bit_type)) }; 69 : 70 : struct _Bit_reference 71 : { 72 : _Bit_type * _M_p; 73 : _Bit_type _M_mask; 74 : 75 5 : _Bit_reference(_Bit_type * __x, _Bit_type __y) 76 5 : : _M_p(__x), _M_mask(__y) { } 77 : 78 : _Bit_reference() : _M_p(0), _M_mask(0) { } 79 : 80 3 : operator bool() const 81 3 : { return !!(*_M_p & _M_mask); } 82 : 83 : _Bit_reference& 84 2 : operator=(bool __x) 85 : { 86 2 : if (__x) 87 1 : *_M_p |= _M_mask; 88 : else 89 1 : *_M_p &= ~_M_mask; 90 2 : return *this; 91 : } 92 : 93 : _Bit_reference& 94 0 : operator=(const _Bit_reference& __x) 95 0 : { return *this = bool(__x); } 96 : 97 : bool 98 : operator==(const _Bit_reference& __x) const 99 : { return bool(*this) == bool(__x); } 100 : 101 : bool 102 : operator<(const _Bit_reference& __x) const 103 : { return !bool(*this) && bool(__x); } 104 : 105 : void 106 : flip() 107 : { *_M_p ^= _M_mask; } 108 : }; 109 : 110 : struct _Bit_iterator_base 111 : : public std::iterator<std::random_access_iterator_tag, bool> 112 : { 113 : _Bit_type * _M_p; 114 : unsigned int _M_offset; 115 : 116 31 : _Bit_iterator_base(_Bit_type * __x, unsigned int __y) 117 31 : : _M_p(__x), _M_offset(__y) { } 118 : 119 : void 120 2 : _M_bump_up() 121 : { 122 2 : if (_M_offset++ == int(_S_word_bit) - 1) 123 : { 124 0 : _M_offset = 0; 125 0 : ++_M_p; 126 : } 127 2 : } 128 : 129 : void 130 0 : _M_bump_down() 131 : { 132 0 : if (_M_offset-- == 0) 133 : { 134 0 : _M_offset = int(_S_word_bit) - 1; 135 0 : --_M_p; 136 : } 137 0 : } 138 : 139 : void 140 0 : _M_incr(ptrdiff_t __i) 141 : { 142 0 : difference_type __n = __i + _M_offset; 143 0 : _M_p += __n / int(_S_word_bit); 144 0 : __n = __n % int(_S_word_bit); 145 0 : if (__n < 0) 146 : { 147 0 : __n += int(_S_word_bit); 148 0 : --_M_p; 149 : } 150 0 : _M_offset = static_cast<unsigned int>(__n); 151 0 : } 152 : 153 : bool 154 3 : operator==(const _Bit_iterator_base& __i) const 155 3 : { return _M_p == __i._M_p && _M_offset == __i._M_offset; } 156 : 157 : bool 158 : operator<(const _Bit_iterator_base& __i) const 159 : { 160 : return _M_p < __i._M_p 161 : || (_M_p == __i._M_p && _M_offset < __i._M_offset); 162 : } 163 : 164 : bool 165 : operator!=(const _Bit_iterator_base& __i) const 166 : { return !(*this == __i); } 167 : 168 : bool 169 : operator>(const _Bit_iterator_base& __i) const 170 : { return __i < *this; } 171 : 172 : bool 173 : operator<=(const _Bit_iterator_base& __i) const 174 : { return !(__i < *this); } 175 : 176 : bool 177 : operator>=(const _Bit_iterator_base& __i) const 178 : { return !(*this < __i); } 179 : }; 180 : 181 : inline ptrdiff_t 182 9 : operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y) 183 : { 184 : return (int(_S_word_bit) * (__x._M_p - __y._M_p) 185 9 : + __x._M_offset - __y._M_offset); 186 : } 187 : 188 : struct _Bit_iterator : public _Bit_iterator_base 189 : { 190 : typedef _Bit_reference reference; 191 : typedef _Bit_reference* pointer; 192 : typedef _Bit_iterator iterator; 193 : 194 2 : _Bit_iterator() : _Bit_iterator_base(0, 0) { } 195 : 196 3 : _Bit_iterator(_Bit_type * __x, unsigned int __y) 197 3 : : _Bit_iterator_base(__x, __y) { } 198 : 199 : reference 200 2 : operator*() const 201 2 : { return reference(_M_p, 1UL << _M_offset); } 202 : 203 : iterator& 204 0 : operator++() 205 : { 206 0 : _M_bump_up(); 207 0 : return *this; 208 : } 209 : 210 : iterator 211 2 : operator++(int) 212 : { 213 2 : iterator __tmp = *this; 214 2 : _M_bump_up(); 215 : return __tmp; 216 : } 217 : 218 : iterator& 219 0 : operator--() 220 : { 221 0 : _M_bump_down(); 222 0 : return *this; 223 : } 224 : 225 : iterator 226 : operator--(int) 227 : { 228 : iterator __tmp = *this; 229 : _M_bump_down(); 230 : return __tmp; 231 : } 232 : 233 : iterator& 234 0 : operator+=(difference_type __i) 235 : { 236 0 : _M_incr(__i); 237 0 : return *this; 238 : } 239 : 240 : iterator& 241 : operator-=(difference_type __i) 242 : { 243 : *this += -__i; 244 : return *this; 245 : } 246 : 247 : iterator 248 0 : operator+(difference_type __i) const 249 : { 250 0 : iterator __tmp = *this; 251 0 : return __tmp += __i; 252 : } 253 : 254 : iterator 255 : operator-(difference_type __i) const 256 : { 257 : iterator __tmp = *this; 258 : return __tmp -= __i; 259 : } 260 : 261 : reference 262 : operator[](difference_type __i) const 263 : { return *(*this + __i); } 264 : }; 265 : 266 : inline _Bit_iterator 267 : operator+(ptrdiff_t __n, const _Bit_iterator& __x) 268 : { return __x + __n; } 269 : 270 : struct _Bit_const_iterator : public _Bit_iterator_base 271 : { 272 : typedef bool reference; 273 : typedef bool const_reference; 274 : typedef const bool* pointer; 275 : typedef _Bit_const_iterator const_iterator; 276 : 277 : _Bit_const_iterator() : _Bit_iterator_base(0, 0) { } 278 : 279 4 : _Bit_const_iterator(_Bit_type * __x, unsigned int __y) 280 4 : : _Bit_iterator_base(__x, __y) { } 281 : 282 22 : _Bit_const_iterator(const _Bit_iterator& __x) 283 22 : : _Bit_iterator_base(__x._M_p, __x._M_offset) { } 284 : 285 : const_reference 286 3 : operator*() const 287 3 : { return _Bit_reference(_M_p, 1UL << _M_offset); } 288 : 289 : const_iterator& 290 0 : operator++() 291 : { 292 0 : _M_bump_up(); 293 0 : return *this; 294 : } 295 : 296 : const_iterator 297 : operator++(int) 298 : { 299 : const_iterator __tmp = *this; 300 : _M_bump_up(); 301 : return __tmp; 302 : } 303 : 304 : const_iterator& 305 : operator--() 306 : { 307 : _M_bump_down(); 308 : return *this; 309 : } 310 : 311 : const_iterator 312 : operator--(int) 313 : { 314 : const_iterator __tmp = *this; 315 : _M_bump_down(); 316 : return __tmp; 317 : } 318 : 319 : const_iterator& 320 : operator+=(difference_type __i) 321 : { 322 : _M_incr(__i); 323 : return *this; 324 : } 325 : 326 : const_iterator& 327 : operator-=(difference_type __i) 328 : { 329 : *this += -__i; 330 : return *this; 331 : } 332 : 333 : const_iterator 334 : operator+(difference_type __i) const 335 : { 336 : const_iterator __tmp = *this; 337 : return __tmp += __i; 338 : } 339 : 340 : const_iterator 341 : operator-(difference_type __i) const 342 : { 343 : const_iterator __tmp = *this; 344 : return __tmp -= __i; 345 : } 346 : 347 : const_reference 348 : operator[](difference_type __i) const 349 : { return *(*this + __i); } 350 : }; 351 : 352 : inline _Bit_const_iterator 353 : operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) 354 : { return __x + __n; } 355 : 356 : inline void 357 : __fill_bvector(_Bit_iterator __first, _Bit_iterator __last, bool __x) 358 : { 359 : for (; __first != __last; ++__first) 360 : *__first = __x; 361 : } 362 : 363 : inline void 364 : fill(_Bit_iterator __first, _Bit_iterator __last, const bool& __x) 365 : { 366 : if (__first._M_p != __last._M_p) 367 : { 368 : std::fill(__first._M_p + 1, __last._M_p, __x ? ~0 : 0); 369 : __fill_bvector(__first, _Bit_iterator(__first._M_p + 1, 0), __x); 370 : __fill_bvector(_Bit_iterator(__last._M_p, 0), __last, __x); 371 : } 372 : else 373 : __fill_bvector(__first, __last, __x); 374 : } 375 : 376 : template<typename _Alloc> 377 : struct _Bvector_base 378 : { 379 : typedef typename _Alloc::template rebind<_Bit_type>::other 380 : _Bit_alloc_type; 381 : 382 : struct _Bvector_impl 383 : : public _Bit_alloc_type 384 1 : { 385 : _Bit_iterator _M_start; 386 : _Bit_iterator _M_finish; 387 : _Bit_type* _M_end_of_storage; 388 : 389 1 : _Bvector_impl() 390 1 : : _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage(0) 391 1 : { } 392 : 393 : _Bvector_impl(const _Bit_alloc_type& __a) 394 : : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0) 395 : { } 396 : }; 397 : 398 : public: 399 : typedef _Alloc allocator_type; 400 : 401 : _Bit_alloc_type& 402 : _M_get_Bit_allocator() 403 : { return *static_cast<_Bit_alloc_type*>(&this->_M_impl); } 404 : 405 : const _Bit_alloc_type& 406 2 : _M_get_Bit_allocator() const 407 2 : { return *static_cast<const _Bit_alloc_type*>(&this->_M_impl); } 408 : 409 : allocator_type 410 : get_allocator() const 411 : { return allocator_type(_M_get_Bit_allocator()); } 412 : 413 1 : _Bvector_base() 414 1 : : _M_impl() { } 415 : 416 : _Bvector_base(const allocator_type& __a) 417 : : _M_impl(__a) { } 418 : 419 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 420 : _Bvector_base(_Bvector_base&& __x) 421 : : _M_impl(__x._M_get_Bit_allocator()) 422 : { 423 : this->_M_impl._M_start = __x._M_impl._M_start; 424 : this->_M_impl._M_finish = __x._M_impl._M_finish; 425 : this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage; 426 : __x._M_impl._M_start = _Bit_iterator(); 427 : __x._M_impl._M_finish = _Bit_iterator(); 428 : __x._M_impl._M_end_of_storage = 0; 429 : } 430 : #endif 431 : 432 1 : ~_Bvector_base() 433 1 : { this->_M_deallocate(); } 434 : 435 : protected: 436 : _Bvector_impl _M_impl; 437 : 438 : _Bit_type* 439 1 : _M_allocate(size_t __n) 440 : { return _M_impl.allocate((__n + int(_S_word_bit) - 1) 441 1 : / int(_S_word_bit)); } 442 : 443 : void 444 2 : _M_deallocate() 445 : { 446 2 : if (_M_impl._M_start._M_p) 447 1 : _M_impl.deallocate(_M_impl._M_start._M_p, 448 : _M_impl._M_end_of_storage - _M_impl._M_start._M_p); 449 2 : } 450 : }; 451 : 452 : _GLIBCXX_END_NESTED_NAMESPACE 453 : 454 : // Declare a partial specialization of vector<T, Alloc>. 455 : #include <bits/stl_vector.h> 456 : 457 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) 458 : 459 : /** 460 : * @brief A specialization of vector for booleans which offers fixed time 461 : * access to individual elements in any order. 462 : * 463 : * Note that vector<bool> does not actually meet the requirements for being 464 : * a container. This is because the reference and pointer types are not 465 : * really references and pointers to bool. See DR96 for details. @see 466 : * vector for function documentation. 467 : * 468 : * @ingroup Containers 469 : * @ingroup Sequences 470 : * 471 : * In some terminology a %vector can be described as a dynamic 472 : * C-style array, it offers fast and efficient access to individual 473 : * elements in any order and saves the user from worrying about 474 : * memory and size allocation. Subscripting ( @c [] ) access is 475 : * also provided as with C-style arrays. 476 : */ 477 : template<typename _Alloc> 478 : class vector<bool, _Alloc> : protected _Bvector_base<_Alloc> 479 : { 480 : typedef _Bvector_base<_Alloc> _Base; 481 : 482 : public: 483 : typedef bool value_type; 484 : typedef size_t size_type; 485 : typedef ptrdiff_t difference_type; 486 : typedef _Bit_reference reference; 487 : typedef bool const_reference; 488 : typedef _Bit_reference* pointer; 489 : typedef const bool* const_pointer; 490 : typedef _Bit_iterator iterator; 491 : typedef _Bit_const_iterator const_iterator; 492 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 493 : typedef std::reverse_iterator<iterator> reverse_iterator; 494 : typedef _Alloc allocator_type; 495 : 496 : allocator_type get_allocator() const 497 : { return _Base::get_allocator(); } 498 : 499 : protected: 500 : using _Base::_M_allocate; 501 : using _Base::_M_deallocate; 502 : using _Base::_M_get_Bit_allocator; 503 : 504 : public: 505 1 : vector() 506 1 : : _Base() { } 507 : 508 : explicit 509 : vector(const allocator_type& __a) 510 : : _Base(__a) { } 511 : 512 : explicit 513 : vector(size_type __n, const bool& __value = bool(), 514 : const allocator_type& __a = allocator_type()) 515 : : _Base(__a) 516 : { 517 : _M_initialize(__n); 518 : std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage, 519 : __value ? ~0 : 0); 520 : } 521 : 522 : vector(const vector& __x) 523 : : _Base(__x._M_get_Bit_allocator()) 524 : { 525 : _M_initialize(__x.size()); 526 : _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start); 527 : } 528 : 529 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 530 : vector(vector&& __x) 531 : : _Base(std::forward<_Base>(__x)) { } 532 : #endif 533 : 534 : template<typename _InputIterator> 535 : vector(_InputIterator __first, _InputIterator __last, 536 : const allocator_type& __a = allocator_type()) 537 : : _Base(__a) 538 : { 539 : typedef typename std::__is_integer<_InputIterator>::__type _Integral; 540 : _M_initialize_dispatch(__first, __last, _Integral()); 541 : } 542 : 543 1 : ~vector() { } 544 : 545 : vector& 546 : operator=(const vector& __x) 547 : { 548 : if (&__x == this) 549 : return *this; 550 : if (__x.size() > capacity()) 551 : { 552 : this->_M_deallocate(); 553 : _M_initialize(__x.size()); 554 : } 555 : this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(), 556 : begin()); 557 : return *this; 558 : } 559 : 560 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 561 : vector& 562 : operator=(vector&& __x) 563 : { 564 : // NB: DR 675. 565 : this->clear(); 566 : this->swap(__x); 567 : return *this; 568 : } 569 : #endif 570 : 571 : // assign(), a generalized assignment member function. Two 572 : // versions: one that takes a count, and one that takes a range. 573 : // The range version is a member template, so we dispatch on whether 574 : // or not the type is an integer. 575 : void 576 : assign(size_type __n, const bool& __x) 577 : { _M_fill_assign(__n, __x); } 578 : 579 : template<typename _InputIterator> 580 : void 581 : assign(_InputIterator __first, _InputIterator __last) 582 : { 583 : typedef typename std::__is_integer<_InputIterator>::__type _Integral; 584 : _M_assign_dispatch(__first, __last, _Integral()); 585 : } 586 : 587 : iterator 588 1 : begin() 589 1 : { return this->_M_impl._M_start; } 590 : 591 : const_iterator 592 10 : begin() const 593 10 : { return this->_M_impl._M_start; } 594 : 595 : iterator 596 2 : end() 597 2 : { return this->_M_impl._M_finish; } 598 : 599 : const_iterator 600 10 : end() const 601 10 : { return this->_M_impl._M_finish; } 602 : 603 : reverse_iterator 604 : rbegin() 605 : { return reverse_iterator(end()); } 606 : 607 : const_reverse_iterator 608 : rbegin() const 609 : { return const_reverse_iterator(end()); } 610 : 611 : reverse_iterator 612 : rend() 613 : { return reverse_iterator(begin()); } 614 : 615 : const_reverse_iterator 616 : rend() const 617 : { return const_reverse_iterator(begin()); } 618 : 619 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 620 : const_iterator 621 : cbegin() const 622 : { return this->_M_impl._M_start; } 623 : 624 : const_iterator 625 : cend() const 626 : { return this->_M_impl._M_finish; } 627 : 628 : const_reverse_iterator 629 : crbegin() const 630 : { return const_reverse_iterator(end()); } 631 : 632 : const_reverse_iterator 633 : crend() const 634 : { return const_reverse_iterator(begin()); } 635 : #endif 636 : 637 : size_type 638 7 : size() const 639 7 : { return size_type(end() - begin()); } 640 : 641 : size_type 642 2 : max_size() const 643 : { 644 : const size_type __isize = 645 : __gnu_cxx::__numeric_traits<difference_type>::__max 646 2 : - int(_S_word_bit) + 1; 647 2 : const size_type __asize = _M_get_Bit_allocator().max_size(); 648 : return (__asize <= __isize / int(_S_word_bit) 649 2 : ? __asize * int(_S_word_bit) : __isize); 650 : } 651 : 652 : size_type 653 : capacity() const 654 : { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0) 655 : - begin()); } 656 : 657 : bool 658 3 : empty() const 659 3 : { return begin() == end(); } 660 : 661 : reference 662 : operator[](size_type __n) 663 : { 664 : return *iterator(this->_M_impl._M_start._M_p 665 : + __n / int(_S_word_bit), __n % int(_S_word_bit)); 666 : } 667 : 668 : const_reference 669 3 : operator[](size_type __n) const 670 : { 671 : return *const_iterator(this->_M_impl._M_start._M_p 672 3 : + __n / int(_S_word_bit), __n % int(_S_word_bit)); 673 : } 674 : 675 : protected: 676 : void 677 : _M_range_check(size_type __n) const 678 : { 679 : if (__n >= this->size()) 680 : __throw_out_of_range(__N("vector<bool>::_M_range_check")); 681 : } 682 : 683 : public: 684 : reference 685 : at(size_type __n) 686 : { _M_range_check(__n); return (*this)[__n]; } 687 : 688 : const_reference 689 : at(size_type __n) const 690 : { _M_range_check(__n); return (*this)[__n]; } 691 : 692 : void 693 : reserve(size_type __n); 694 : 695 : reference 696 : front() 697 : { return *begin(); } 698 : 699 : const_reference 700 : front() const 701 : { return *begin(); } 702 : 703 : reference 704 : back() 705 : { return *(end() - 1); } 706 : 707 : const_reference 708 : back() const 709 : { return *(end() - 1); } 710 : 711 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 712 : // DR 464. Suggestion for new member functions in standard containers. 713 : // N.B. DR 464 says nothing about vector<bool> but we need something 714 : // here due to the way we are implementing DR 464 in the debug-mode 715 : // vector class. 716 : void 717 : data() { } 718 : 719 : void 720 2 : push_back(bool __x) 721 : { 722 2 : if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) 723 1 : *this->_M_impl._M_finish++ = __x; 724 : else 725 1 : _M_insert_aux(end(), __x); 726 2 : } 727 : 728 : void 729 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 730 : swap(vector&& __x) 731 : #else 732 : swap(vector& __x) 733 : #endif 734 : { 735 : std::swap(this->_M_impl._M_start, __x._M_impl._M_start); 736 : std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); 737 : std::swap(this->_M_impl._M_end_of_storage, 738 : __x._M_impl._M_end_of_storage); 739 : 740 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 741 : // 431. Swapping containers with unequal allocators. 742 : std::__alloc_swap<typename _Base::_Bit_alloc_type>:: 743 : _S_do_it(_M_get_Bit_allocator(), __x._M_get_Bit_allocator()); 744 : } 745 : 746 : // [23.2.5]/1, third-to-last entry in synopsis listing 747 : static void 748 : swap(reference __x, reference __y) 749 : { 750 : bool __tmp = __x; 751 : __x = __y; 752 : __y = __tmp; 753 : } 754 : 755 : iterator 756 : insert(iterator __position, const bool& __x = bool()) 757 : { 758 : const difference_type __n = __position - begin(); 759 : if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage 760 : && __position == end()) 761 : *this->_M_impl._M_finish++ = __x; 762 : else 763 : _M_insert_aux(__position, __x); 764 : return begin() + __n; 765 : } 766 : 767 : template<typename _InputIterator> 768 : void 769 : insert(iterator __position, 770 : _InputIterator __first, _InputIterator __last) 771 : { 772 : typedef typename std::__is_integer<_InputIterator>::__type _Integral; 773 : _M_insert_dispatch(__position, __first, __last, _Integral()); 774 : } 775 : 776 : void 777 : insert(iterator __position, size_type __n, const bool& __x) 778 : { _M_fill_insert(__position, __n, __x); } 779 : 780 : void 781 : pop_back() 782 : { --this->_M_impl._M_finish; } 783 : 784 : iterator 785 : erase(iterator __position) 786 : { 787 : if (__position + 1 != end()) 788 : std::copy(__position + 1, end(), __position); 789 : --this->_M_impl._M_finish; 790 : return __position; 791 : } 792 : 793 : iterator 794 : erase(iterator __first, iterator __last) 795 : { 796 : _M_erase_at_end(std::copy(__last, end(), __first)); 797 : return __first; 798 : } 799 : 800 : void 801 : resize(size_type __new_size, bool __x = bool()) 802 : { 803 : if (__new_size < size()) 804 : _M_erase_at_end(begin() + difference_type(__new_size)); 805 : else 806 : insert(end(), __new_size - size(), __x); 807 : } 808 : 809 : void 810 : flip() 811 : { 812 : for (_Bit_type * __p = this->_M_impl._M_start._M_p; 813 : __p != this->_M_impl._M_end_of_storage; ++__p) 814 : *__p = ~*__p; 815 : } 816 : 817 : void 818 : clear() 819 : { _M_erase_at_end(begin()); } 820 : 821 : 822 : protected: 823 : // Precondition: __first._M_offset == 0 && __result._M_offset == 0. 824 : iterator 825 : _M_copy_aligned(const_iterator __first, const_iterator __last, 826 1 : iterator __result) 827 : { 828 1 : _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p); 829 : return std::copy(const_iterator(__last._M_p, 0), __last, 830 1 : iterator(__q, 0)); 831 : } 832 : 833 : void 834 : _M_initialize(size_type __n) 835 : { 836 : _Bit_type* __q = this->_M_allocate(__n); 837 : this->_M_impl._M_end_of_storage = (__q 838 : + ((__n + int(_S_word_bit) - 1) 839 : / int(_S_word_bit))); 840 : this->_M_impl._M_start = iterator(__q, 0); 841 : this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); 842 : } 843 : 844 : // Check whether it's an integral type. If so, it's not an iterator. 845 : 846 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 847 : // 438. Ambiguity in the "do the right thing" clause 848 : template<typename _Integer> 849 : void 850 : _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) 851 : { 852 : _M_initialize(static_cast<size_type>(__n)); 853 : std::fill(this->_M_impl._M_start._M_p, 854 : this->_M_impl._M_end_of_storage, __x ? ~0 : 0); 855 : } 856 : 857 : template<typename _InputIterator> 858 : void 859 : _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, 860 : __false_type) 861 : { _M_initialize_range(__first, __last, 862 : std::__iterator_category(__first)); } 863 : 864 : template<typename _InputIterator> 865 : void 866 : _M_initialize_range(_InputIterator __first, _InputIterator __last, 867 : std::input_iterator_tag) 868 : { 869 : for (; __first != __last; ++__first) 870 : push_back(*__first); 871 : } 872 : 873 : template<typename _ForwardIterator> 874 : void 875 : _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, 876 : std::forward_iterator_tag) 877 : { 878 : const size_type __n = std::distance(__first, __last); 879 : _M_initialize(__n); 880 : std::copy(__first, __last, this->_M_impl._M_start); 881 : } 882 : 883 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 884 : // 438. Ambiguity in the "do the right thing" clause 885 : template<typename _Integer> 886 : void 887 : _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) 888 : { _M_fill_assign(__n, __val); } 889 : 890 : template<class _InputIterator> 891 : void 892 : _M_assign_dispatch(_InputIterator __first, _InputIterator __last, 893 : __false_type) 894 : { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } 895 : 896 : void 897 : _M_fill_assign(size_t __n, bool __x) 898 : { 899 : if (__n > size()) 900 : { 901 : std::fill(this->_M_impl._M_start._M_p, 902 : this->_M_impl._M_end_of_storage, __x ? ~0 : 0); 903 : insert(end(), __n - size(), __x); 904 : } 905 : else 906 : { 907 : _M_erase_at_end(begin() + __n); 908 : std::fill(this->_M_impl._M_start._M_p, 909 : this->_M_impl._M_end_of_storage, __x ? ~0 : 0); 910 : } 911 : } 912 : 913 : template<typename _InputIterator> 914 : void 915 : _M_assign_aux(_InputIterator __first, _InputIterator __last, 916 : std::input_iterator_tag) 917 : { 918 : iterator __cur = begin(); 919 : for (; __first != __last && __cur != end(); ++__cur, ++__first) 920 : *__cur = *__first; 921 : if (__first == __last) 922 : _M_erase_at_end(__cur); 923 : else 924 : insert(end(), __first, __last); 925 : } 926 : 927 : template<typename _ForwardIterator> 928 : void 929 : _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, 930 : std::forward_iterator_tag) 931 : { 932 : const size_type __len = std::distance(__first, __last); 933 : if (__len < size()) 934 : _M_erase_at_end(std::copy(__first, __last, begin())); 935 : else 936 : { 937 : _ForwardIterator __mid = __first; 938 : std::advance(__mid, size()); 939 : std::copy(__first, __mid, begin()); 940 : insert(end(), __mid, __last); 941 : } 942 : } 943 : 944 : // Check whether it's an integral type. If so, it's not an iterator. 945 : 946 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 947 : // 438. Ambiguity in the "do the right thing" clause 948 : template<typename _Integer> 949 : void 950 : _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, 951 : __true_type) 952 : { _M_fill_insert(__pos, __n, __x); } 953 : 954 : template<typename _InputIterator> 955 : void 956 : _M_insert_dispatch(iterator __pos, 957 : _InputIterator __first, _InputIterator __last, 958 : __false_type) 959 : { _M_insert_range(__pos, __first, __last, 960 : std::__iterator_category(__first)); } 961 : 962 : void 963 : _M_fill_insert(iterator __position, size_type __n, bool __x); 964 : 965 : template<typename _InputIterator> 966 : void 967 : _M_insert_range(iterator __pos, _InputIterator __first, 968 : _InputIterator __last, std::input_iterator_tag) 969 : { 970 : for (; __first != __last; ++__first) 971 : { 972 : __pos = insert(__pos, *__first); 973 : ++__pos; 974 : } 975 : } 976 : 977 : template<typename _ForwardIterator> 978 : void 979 : _M_insert_range(iterator __position, _ForwardIterator __first, 980 : _ForwardIterator __last, std::forward_iterator_tag); 981 : 982 : void 983 : _M_insert_aux(iterator __position, bool __x); 984 : 985 : size_type 986 1 : _M_check_len(size_type __n, const char* __s) const 987 : { 988 1 : if (max_size() - size() < __n) 989 0 : __throw_length_error(__N(__s)); 990 : 991 1 : const size_type __len = size() + std::max(size(), __n); 992 1 : return (__len < size() || __len > max_size()) ? max_size() : __len; 993 : } 994 : 995 : void 996 : _M_erase_at_end(iterator __pos) 997 : { this->_M_impl._M_finish = __pos; } 998 : }; 999 : 1000 : _GLIBCXX_END_NESTED_NAMESPACE 1001 : 1002 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Algorithm implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_algo.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_ALGO_H 63 : #define _STL_ALGO_H 1 64 : 65 : #include <cstdlib> // for rand 66 : #include <bits/algorithmfwd.h> 67 : #include <bits/stl_heap.h> 68 : #include <bits/stl_tempbuf.h> // for _Temporary_buffer 69 : #include <debug/debug.h> 70 : 71 : // See concept_check.h for the __glibcxx_*_requires macros. 72 : 73 : _GLIBCXX_BEGIN_NAMESPACE(std) 74 : 75 : /** 76 : * @brief Find the median of three values. 77 : * @param a A value. 78 : * @param b A value. 79 : * @param c A value. 80 : * @return One of @p a, @p b or @p c. 81 : * 82 : * If @c {l,m,n} is some convolution of @p {a,b,c} such that @c l<=m<=n 83 : * then the value returned will be @c m. 84 : * This is an SGI extension. 85 : * @ingroup SGIextensions 86 : */ 87 : template<typename _Tp> 88 : inline const _Tp& 89 133 : __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) 90 : { 91 : // concept requirements 92 : __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) 93 133 : if (__a < __b) 94 132 : if (__b < __c) 95 132 : return __b; 96 0 : else if (__a < __c) 97 0 : return __c; 98 : else 99 0 : return __a; 100 1 : else if (__a < __c) 101 0 : return __a; 102 1 : else if (__b < __c) 103 0 : return __c; 104 : else 105 1 : return __b; 106 : } 107 : 108 : /** 109 : * @brief Find the median of three values using a predicate for comparison. 110 : * @param a A value. 111 : * @param b A value. 112 : * @param c A value. 113 : * @param comp A binary predicate. 114 : * @return One of @p a, @p b or @p c. 115 : * 116 : * If @c {l,m,n} is some convolution of @p {a,b,c} such that @p comp(l,m) 117 : * and @p comp(m,n) are both true then the value returned will be @c m. 118 : * This is an SGI extension. 119 : * @ingroup SGIextensions 120 : */ 121 : template<typename _Tp, typename _Compare> 122 : inline const _Tp& 123 710 : __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) 124 : { 125 : // concept requirements 126 : __glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool, 127 : _Tp, _Tp>) 128 710 : if (__comp(__a, __b)) 129 433 : if (__comp(__b, __c)) 130 143 : return __b; 131 290 : else if (__comp(__a, __c)) 132 54 : return __c; 133 : else 134 236 : return __a; 135 277 : else if (__comp(__a, __c)) 136 81 : return __a; 137 196 : else if (__comp(__b, __c)) 138 99 : return __c; 139 : else 140 97 : return __b; 141 : } 142 : 143 : // for_each 144 : 145 : /// This is an overload used by find() for the Input Iterator case. 146 : template<typename _InputIterator, typename _Tp> 147 : inline _InputIterator 148 : __find(_InputIterator __first, _InputIterator __last, 149 : const _Tp& __val, input_iterator_tag) 150 : { 151 : while (__first != __last && !(*__first == __val)) 152 : ++__first; 153 : return __first; 154 : } 155 : 156 : /// This is an overload used by find_if() for the Input Iterator case. 157 : template<typename _InputIterator, typename _Predicate> 158 : inline _InputIterator 159 : __find_if(_InputIterator __first, _InputIterator __last, 160 3 : _Predicate __pred, input_iterator_tag) 161 : { 162 7 : while (__first != __last && !bool(__pred(*__first))) 163 1 : ++__first; 164 3 : return __first; 165 : } 166 : 167 : /// This is an overload used by find() for the RAI case. 168 : template<typename _RandomAccessIterator, typename _Tp> 169 : _RandomAccessIterator 170 : __find(_RandomAccessIterator __first, _RandomAccessIterator __last, 171 3362 : const _Tp& __val, random_access_iterator_tag) 172 : { 173 : typename iterator_traits<_RandomAccessIterator>::difference_type 174 3362 : __trip_count = (__last - __first) >> 2; 175 : 176 5967 : for (; __trip_count > 0; --__trip_count) 177 : { 178 3337 : if (*__first == __val) 179 42 : return __first; 180 3295 : ++__first; 181 : 182 3295 : if (*__first == __val) 183 16 : return __first; 184 3279 : ++__first; 185 : 186 3279 : if (*__first == __val) 187 42 : return __first; 188 3237 : ++__first; 189 : 190 3237 : if (*__first == __val) 191 632 : return __first; 192 2605 : ++__first; 193 : } 194 : 195 2630 : switch (__last - __first) 196 : { 197 : case 3: 198 107 : if (*__first == __val) 199 0 : return __first; 200 107 : ++__first; 201 : case 2: 202 243 : if (*__first == __val) 203 0 : return __first; 204 243 : ++__first; 205 : case 1: 206 370 : if (*__first == __val) 207 370 : return __first; 208 0 : ++__first; 209 : case 0: 210 : default: 211 2260 : return __last; 212 : } 213 : } 214 : 215 : /// This is an overload used by find_if() for the RAI case. 216 : template<typename _RandomAccessIterator, typename _Predicate> 217 : _RandomAccessIterator 218 : __find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, 219 : _Predicate __pred, random_access_iterator_tag) 220 : { 221 : typename iterator_traits<_RandomAccessIterator>::difference_type 222 : __trip_count = (__last - __first) >> 2; 223 : 224 : for (; __trip_count > 0; --__trip_count) 225 : { 226 : if (__pred(*__first)) 227 : return __first; 228 : ++__first; 229 : 230 : if (__pred(*__first)) 231 : return __first; 232 : ++__first; 233 : 234 : if (__pred(*__first)) 235 : return __first; 236 : ++__first; 237 : 238 : if (__pred(*__first)) 239 : return __first; 240 : ++__first; 241 : } 242 : 243 : switch (__last - __first) 244 : { 245 : case 3: 246 : if (__pred(*__first)) 247 : return __first; 248 : ++__first; 249 : case 2: 250 : if (__pred(*__first)) 251 : return __first; 252 : ++__first; 253 : case 1: 254 : if (__pred(*__first)) 255 : return __first; 256 : ++__first; 257 : case 0: 258 : default: 259 : return __last; 260 : } 261 : } 262 : 263 : // set_difference 264 : // set_intersection 265 : // set_symmetric_difference 266 : // set_union 267 : // for_each 268 : // find 269 : // find_if 270 : // find_first_of 271 : // adjacent_find 272 : // count 273 : // count_if 274 : // search 275 : 276 : /** 277 : * This is an uglified 278 : * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&) 279 : * overloaded for forward iterators. 280 : */ 281 : template<typename _ForwardIterator, typename _Integer, typename _Tp> 282 : _ForwardIterator 283 : __search_n(_ForwardIterator __first, _ForwardIterator __last, 284 : _Integer __count, const _Tp& __val, 285 : std::forward_iterator_tag) 286 : { 287 : __first = _GLIBCXX_STD_P::find(__first, __last, __val); 288 : while (__first != __last) 289 : { 290 : typename iterator_traits<_ForwardIterator>::difference_type 291 : __n = __count; 292 : _ForwardIterator __i = __first; 293 : ++__i; 294 : while (__i != __last && __n != 1 && *__i == __val) 295 : { 296 : ++__i; 297 : --__n; 298 : } 299 : if (__n == 1) 300 : return __first; 301 : if (__i == __last) 302 : return __last; 303 : __first = _GLIBCXX_STD_P::find(++__i, __last, __val); 304 : } 305 : return __last; 306 : } 307 : 308 : /** 309 : * This is an uglified 310 : * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&) 311 : * overloaded for random access iterators. 312 : */ 313 : template<typename _RandomAccessIter, typename _Integer, typename _Tp> 314 : _RandomAccessIter 315 : __search_n(_RandomAccessIter __first, _RandomAccessIter __last, 316 : _Integer __count, const _Tp& __val, 317 : std::random_access_iterator_tag) 318 : { 319 : 320 : typedef typename std::iterator_traits<_RandomAccessIter>::difference_type 321 : _DistanceType; 322 : 323 : _DistanceType __tailSize = __last - __first; 324 : const _DistanceType __pattSize = __count; 325 : 326 : if (__tailSize < __pattSize) 327 : return __last; 328 : 329 : const _DistanceType __skipOffset = __pattSize - 1; 330 : _RandomAccessIter __lookAhead = __first + __skipOffset; 331 : __tailSize -= __pattSize; 332 : 333 : while (1) // the main loop... 334 : { 335 : // __lookAhead here is always pointing to the last element of next 336 : // possible match. 337 : while (!(*__lookAhead == __val)) // the skip loop... 338 : { 339 : if (__tailSize < __pattSize) 340 : return __last; // Failure 341 : __lookAhead += __pattSize; 342 : __tailSize -= __pattSize; 343 : } 344 : _DistanceType __remainder = __skipOffset; 345 : for (_RandomAccessIter __backTrack = __lookAhead - 1; 346 : *__backTrack == __val; --__backTrack) 347 : { 348 : if (--__remainder == 0) 349 : return (__lookAhead - __skipOffset); // Success 350 : } 351 : if (__remainder > __tailSize) 352 : return __last; // Failure 353 : __lookAhead += __remainder; 354 : __tailSize -= __remainder; 355 : } 356 : } 357 : 358 : // search_n 359 : 360 : /** 361 : * This is an uglified 362 : * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&, 363 : * _BinaryPredicate) 364 : * overloaded for forward iterators. 365 : */ 366 : template<typename _ForwardIterator, typename _Integer, typename _Tp, 367 : typename _BinaryPredicate> 368 : _ForwardIterator 369 : __search_n(_ForwardIterator __first, _ForwardIterator __last, 370 : _Integer __count, const _Tp& __val, 371 : _BinaryPredicate __binary_pred, std::forward_iterator_tag) 372 : { 373 : while (__first != __last && !bool(__binary_pred(*__first, __val))) 374 : ++__first; 375 : 376 : while (__first != __last) 377 : { 378 : typename iterator_traits<_ForwardIterator>::difference_type 379 : __n = __count; 380 : _ForwardIterator __i = __first; 381 : ++__i; 382 : while (__i != __last && __n != 1 && bool(__binary_pred(*__i, __val))) 383 : { 384 : ++__i; 385 : --__n; 386 : } 387 : if (__n == 1) 388 : return __first; 389 : if (__i == __last) 390 : return __last; 391 : __first = ++__i; 392 : while (__first != __last 393 : && !bool(__binary_pred(*__first, __val))) 394 : ++__first; 395 : } 396 : return __last; 397 : } 398 : 399 : /** 400 : * This is an uglified 401 : * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&, 402 : * _BinaryPredicate) 403 : * overloaded for random access iterators. 404 : */ 405 : template<typename _RandomAccessIter, typename _Integer, typename _Tp, 406 : typename _BinaryPredicate> 407 : _RandomAccessIter 408 : __search_n(_RandomAccessIter __first, _RandomAccessIter __last, 409 : _Integer __count, const _Tp& __val, 410 : _BinaryPredicate __binary_pred, std::random_access_iterator_tag) 411 : { 412 : 413 : typedef typename std::iterator_traits<_RandomAccessIter>::difference_type 414 : _DistanceType; 415 : 416 : _DistanceType __tailSize = __last - __first; 417 : const _DistanceType __pattSize = __count; 418 : 419 : if (__tailSize < __pattSize) 420 : return __last; 421 : 422 : const _DistanceType __skipOffset = __pattSize - 1; 423 : _RandomAccessIter __lookAhead = __first + __skipOffset; 424 : __tailSize -= __pattSize; 425 : 426 : while (1) // the main loop... 427 : { 428 : // __lookAhead here is always pointing to the last element of next 429 : // possible match. 430 : while (!bool(__binary_pred(*__lookAhead, __val))) // the skip loop... 431 : { 432 : if (__tailSize < __pattSize) 433 : return __last; // Failure 434 : __lookAhead += __pattSize; 435 : __tailSize -= __pattSize; 436 : } 437 : _DistanceType __remainder = __skipOffset; 438 : for (_RandomAccessIter __backTrack = __lookAhead - 1; 439 : __binary_pred(*__backTrack, __val); --__backTrack) 440 : { 441 : if (--__remainder == 0) 442 : return (__lookAhead - __skipOffset); // Success 443 : } 444 : if (__remainder > __tailSize) 445 : return __last; // Failure 446 : __lookAhead += __remainder; 447 : __tailSize -= __remainder; 448 : } 449 : } 450 : 451 : // find_end for forward iterators. 452 : template<typename _ForwardIterator1, typename _ForwardIterator2> 453 : _ForwardIterator1 454 : __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 455 : _ForwardIterator2 __first2, _ForwardIterator2 __last2, 456 : forward_iterator_tag, forward_iterator_tag) 457 : { 458 : if (__first2 == __last2) 459 : return __last1; 460 : else 461 : { 462 : _ForwardIterator1 __result = __last1; 463 : while (1) 464 : { 465 : _ForwardIterator1 __new_result 466 : = _GLIBCXX_STD_P::search(__first1, __last1, __first2, __last2); 467 : if (__new_result == __last1) 468 : return __result; 469 : else 470 : { 471 : __result = __new_result; 472 : __first1 = __new_result; 473 : ++__first1; 474 : } 475 : } 476 : } 477 : } 478 : 479 : template<typename _ForwardIterator1, typename _ForwardIterator2, 480 : typename _BinaryPredicate> 481 : _ForwardIterator1 482 : __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 483 : _ForwardIterator2 __first2, _ForwardIterator2 __last2, 484 : forward_iterator_tag, forward_iterator_tag, 485 : _BinaryPredicate __comp) 486 : { 487 : if (__first2 == __last2) 488 : return __last1; 489 : else 490 : { 491 : _ForwardIterator1 __result = __last1; 492 : while (1) 493 : { 494 : _ForwardIterator1 __new_result 495 : = _GLIBCXX_STD_P::search(__first1, __last1, __first2, 496 : __last2, __comp); 497 : if (__new_result == __last1) 498 : return __result; 499 : else 500 : { 501 : __result = __new_result; 502 : __first1 = __new_result; 503 : ++__first1; 504 : } 505 : } 506 : } 507 : } 508 : 509 : // find_end for bidirectional iterators (much faster). 510 : template<typename _BidirectionalIterator1, typename _BidirectionalIterator2> 511 : _BidirectionalIterator1 512 : __find_end(_BidirectionalIterator1 __first1, 513 : _BidirectionalIterator1 __last1, 514 : _BidirectionalIterator2 __first2, 515 : _BidirectionalIterator2 __last2, 516 : bidirectional_iterator_tag, bidirectional_iterator_tag) 517 : { 518 : // concept requirements 519 : __glibcxx_function_requires(_BidirectionalIteratorConcept< 520 : _BidirectionalIterator1>) 521 : __glibcxx_function_requires(_BidirectionalIteratorConcept< 522 : _BidirectionalIterator2>) 523 : 524 : typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; 525 : typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; 526 : 527 : _RevIterator1 __rlast1(__first1); 528 : _RevIterator2 __rlast2(__first2); 529 : _RevIterator1 __rresult = _GLIBCXX_STD_P::search(_RevIterator1(__last1), 530 : __rlast1, 531 : _RevIterator2(__last2), 532 : __rlast2); 533 : 534 : if (__rresult == __rlast1) 535 : return __last1; 536 : else 537 : { 538 : _BidirectionalIterator1 __result = __rresult.base(); 539 : std::advance(__result, -std::distance(__first2, __last2)); 540 : return __result; 541 : } 542 : } 543 : 544 : template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, 545 : typename _BinaryPredicate> 546 : _BidirectionalIterator1 547 : __find_end(_BidirectionalIterator1 __first1, 548 : _BidirectionalIterator1 __last1, 549 : _BidirectionalIterator2 __first2, 550 : _BidirectionalIterator2 __last2, 551 : bidirectional_iterator_tag, bidirectional_iterator_tag, 552 : _BinaryPredicate __comp) 553 : { 554 : // concept requirements 555 : __glibcxx_function_requires(_BidirectionalIteratorConcept< 556 : _BidirectionalIterator1>) 557 : __glibcxx_function_requires(_BidirectionalIteratorConcept< 558 : _BidirectionalIterator2>) 559 : 560 : typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; 561 : typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; 562 : 563 : _RevIterator1 __rlast1(__first1); 564 : _RevIterator2 __rlast2(__first2); 565 : _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1, 566 : _RevIterator2(__last2), __rlast2, 567 : __comp); 568 : 569 : if (__rresult == __rlast1) 570 : return __last1; 571 : else 572 : { 573 : _BidirectionalIterator1 __result = __rresult.base(); 574 : std::advance(__result, -std::distance(__first2, __last2)); 575 : return __result; 576 : } 577 : } 578 : 579 : /** 580 : * @brief Find last matching subsequence in a sequence. 581 : * @param first1 Start of range to search. 582 : * @param last1 End of range to search. 583 : * @param first2 Start of sequence to match. 584 : * @param last2 End of sequence to match. 585 : * @return The last iterator @c i in the range 586 : * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N) 587 : * for each @c N in the range @p [0,last2-first2), or @p last1 if no 588 : * such iterator exists. 589 : * 590 : * Searches the range @p [first1,last1) for a sub-sequence that compares 591 : * equal value-by-value with the sequence given by @p [first2,last2) and 592 : * returns an iterator to the first element of the sub-sequence, or 593 : * @p last1 if the sub-sequence is not found. The sub-sequence will be the 594 : * last such subsequence contained in [first,last1). 595 : * 596 : * Because the sub-sequence must lie completely within the range 597 : * @p [first1,last1) it must start at a position less than 598 : * @p last1-(last2-first2) where @p last2-first2 is the length of the 599 : * sub-sequence. 600 : * This means that the returned iterator @c i will be in the range 601 : * @p [first1,last1-(last2-first2)) 602 : */ 603 : template<typename _ForwardIterator1, typename _ForwardIterator2> 604 : inline _ForwardIterator1 605 : find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 606 : _ForwardIterator2 __first2, _ForwardIterator2 __last2) 607 : { 608 : // concept requirements 609 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) 610 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) 611 : __glibcxx_function_requires(_EqualOpConcept< 612 : typename iterator_traits<_ForwardIterator1>::value_type, 613 : typename iterator_traits<_ForwardIterator2>::value_type>) 614 : __glibcxx_requires_valid_range(__first1, __last1); 615 : __glibcxx_requires_valid_range(__first2, __last2); 616 : 617 : return std::__find_end(__first1, __last1, __first2, __last2, 618 : std::__iterator_category(__first1), 619 : std::__iterator_category(__first2)); 620 : } 621 : 622 : /** 623 : * @brief Find last matching subsequence in a sequence using a predicate. 624 : * @param first1 Start of range to search. 625 : * @param last1 End of range to search. 626 : * @param first2 Start of sequence to match. 627 : * @param last2 End of sequence to match. 628 : * @param comp The predicate to use. 629 : * @return The last iterator @c i in the range 630 : * @p [first1,last1-(last2-first2)) such that @c predicate(*(i+N), @p 631 : * (first2+N)) is true for each @c N in the range @p [0,last2-first2), or 632 : * @p last1 if no such iterator exists. 633 : * 634 : * Searches the range @p [first1,last1) for a sub-sequence that compares 635 : * equal value-by-value with the sequence given by @p [first2,last2) using 636 : * comp as a predicate and returns an iterator to the first element of the 637 : * sub-sequence, or @p last1 if the sub-sequence is not found. The 638 : * sub-sequence will be the last such subsequence contained in 639 : * [first,last1). 640 : * 641 : * Because the sub-sequence must lie completely within the range 642 : * @p [first1,last1) it must start at a position less than 643 : * @p last1-(last2-first2) where @p last2-first2 is the length of the 644 : * sub-sequence. 645 : * This means that the returned iterator @c i will be in the range 646 : * @p [first1,last1-(last2-first2)) 647 : */ 648 : template<typename _ForwardIterator1, typename _ForwardIterator2, 649 : typename _BinaryPredicate> 650 : inline _ForwardIterator1 651 : find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 652 : _ForwardIterator2 __first2, _ForwardIterator2 __last2, 653 : _BinaryPredicate __comp) 654 : { 655 : // concept requirements 656 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) 657 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) 658 : __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 659 : typename iterator_traits<_ForwardIterator1>::value_type, 660 : typename iterator_traits<_ForwardIterator2>::value_type>) 661 : __glibcxx_requires_valid_range(__first1, __last1); 662 : __glibcxx_requires_valid_range(__first2, __last2); 663 : 664 : return std::__find_end(__first1, __last1, __first2, __last2, 665 : std::__iterator_category(__first1), 666 : std::__iterator_category(__first2), 667 : __comp); 668 : } 669 : 670 : 671 : /** 672 : * @brief Copy a sequence, removing elements of a given value. 673 : * @param first An input iterator. 674 : * @param last An input iterator. 675 : * @param result An output iterator. 676 : * @param value The value to be removed. 677 : * @return An iterator designating the end of the resulting sequence. 678 : * 679 : * Copies each element in the range @p [first,last) not equal to @p value 680 : * to the range beginning at @p result. 681 : * remove_copy() is stable, so the relative order of elements that are 682 : * copied is unchanged. 683 : */ 684 : template<typename _InputIterator, typename _OutputIterator, typename _Tp> 685 : _OutputIterator 686 : remove_copy(_InputIterator __first, _InputIterator __last, 687 : _OutputIterator __result, const _Tp& __value) 688 : { 689 : // concept requirements 690 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 691 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 692 : typename iterator_traits<_InputIterator>::value_type>) 693 : __glibcxx_function_requires(_EqualOpConcept< 694 : typename iterator_traits<_InputIterator>::value_type, _Tp>) 695 : __glibcxx_requires_valid_range(__first, __last); 696 : 697 : for (; __first != __last; ++__first) 698 : if (!(*__first == __value)) 699 : { 700 : *__result = *__first; 701 : ++__result; 702 : } 703 : return __result; 704 : } 705 : 706 : /** 707 : * @brief Copy a sequence, removing elements for which a predicate is true. 708 : * @param first An input iterator. 709 : * @param last An input iterator. 710 : * @param result An output iterator. 711 : * @param pred A predicate. 712 : * @return An iterator designating the end of the resulting sequence. 713 : * 714 : * Copies each element in the range @p [first,last) for which 715 : * @p pred returns false to the range beginning at @p result. 716 : * 717 : * remove_copy_if() is stable, so the relative order of elements that are 718 : * copied is unchanged. 719 : */ 720 : template<typename _InputIterator, typename _OutputIterator, 721 : typename _Predicate> 722 : _OutputIterator 723 : remove_copy_if(_InputIterator __first, _InputIterator __last, 724 16 : _OutputIterator __result, _Predicate __pred) 725 : { 726 : // concept requirements 727 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 728 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 729 : typename iterator_traits<_InputIterator>::value_type>) 730 : __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 731 : typename iterator_traits<_InputIterator>::value_type>) 732 : __glibcxx_requires_valid_range(__first, __last); 733 : 734 80 : for (; __first != __last; ++__first) 735 64 : if (!bool(__pred(*__first))) 736 : { 737 48 : *__result = *__first; 738 48 : ++__result; 739 : } 740 16 : return __result; 741 : } 742 : 743 : /** 744 : * @brief Remove elements from a sequence. 745 : * @param first An input iterator. 746 : * @param last An input iterator. 747 : * @param value The value to be removed. 748 : * @return An iterator designating the end of the resulting sequence. 749 : * 750 : * All elements equal to @p value are removed from the range 751 : * @p [first,last). 752 : * 753 : * remove() is stable, so the relative order of elements that are 754 : * not removed is unchanged. 755 : * 756 : * Elements between the end of the resulting sequence and @p last 757 : * are still present, but their value is unspecified. 758 : */ 759 : template<typename _ForwardIterator, typename _Tp> 760 : _ForwardIterator 761 : remove(_ForwardIterator __first, _ForwardIterator __last, 762 : const _Tp& __value) 763 : { 764 : // concept requirements 765 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 766 : _ForwardIterator>) 767 : __glibcxx_function_requires(_EqualOpConcept< 768 : typename iterator_traits<_ForwardIterator>::value_type, _Tp>) 769 : __glibcxx_requires_valid_range(__first, __last); 770 : 771 : __first = _GLIBCXX_STD_P::find(__first, __last, __value); 772 : if(__first == __last) 773 : return __first; 774 : _ForwardIterator __result = __first; 775 : ++__first; 776 : for(; __first != __last; ++__first) 777 : if(!(*__first == __value)) 778 : { 779 : *__result = _GLIBCXX_MOVE(*__first); 780 : ++__result; 781 : } 782 : return __result; 783 : } 784 : 785 : /** 786 : * @brief Remove elements from a sequence using a predicate. 787 : * @param first A forward iterator. 788 : * @param last A forward iterator. 789 : * @param pred A predicate. 790 : * @return An iterator designating the end of the resulting sequence. 791 : * 792 : * All elements for which @p pred returns true are removed from the range 793 : * @p [first,last). 794 : * 795 : * remove_if() is stable, so the relative order of elements that are 796 : * not removed is unchanged. 797 : * 798 : * Elements between the end of the resulting sequence and @p last 799 : * are still present, but their value is unspecified. 800 : */ 801 : template<typename _ForwardIterator, typename _Predicate> 802 : _ForwardIterator 803 : remove_if(_ForwardIterator __first, _ForwardIterator __last, 804 : _Predicate __pred) 805 : { 806 : // concept requirements 807 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 808 : _ForwardIterator>) 809 : __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 810 : typename iterator_traits<_ForwardIterator>::value_type>) 811 : __glibcxx_requires_valid_range(__first, __last); 812 : 813 : __first = _GLIBCXX_STD_P::find_if(__first, __last, __pred); 814 : if(__first == __last) 815 : return __first; 816 : _ForwardIterator __result = __first; 817 : ++__first; 818 : for(; __first != __last; ++__first) 819 : if(!bool(__pred(*__first))) 820 : { 821 : *__result = _GLIBCXX_MOVE(*__first); 822 : ++__result; 823 : } 824 : return __result; 825 : } 826 : 827 : /** 828 : * @brief Remove consecutive duplicate values from a sequence. 829 : * @param first A forward iterator. 830 : * @param last A forward iterator. 831 : * @return An iterator designating the end of the resulting sequence. 832 : * 833 : * Removes all but the first element from each group of consecutive 834 : * values that compare equal. 835 : * unique() is stable, so the relative order of elements that are 836 : * not removed is unchanged. 837 : * Elements between the end of the resulting sequence and @p last 838 : * are still present, but their value is unspecified. 839 : */ 840 : template<typename _ForwardIterator> 841 : _ForwardIterator 842 : unique(_ForwardIterator __first, _ForwardIterator __last) 843 : { 844 : // concept requirements 845 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 846 : _ForwardIterator>) 847 : __glibcxx_function_requires(_EqualityComparableConcept< 848 : typename iterator_traits<_ForwardIterator>::value_type>) 849 : __glibcxx_requires_valid_range(__first, __last); 850 : 851 : // Skip the beginning, if already unique. 852 : __first = _GLIBCXX_STD_P::adjacent_find(__first, __last); 853 : if (__first == __last) 854 : return __last; 855 : 856 : // Do the real copy work. 857 : _ForwardIterator __dest = __first; 858 : ++__first; 859 : while (++__first != __last) 860 : if (!(*__dest == *__first)) 861 : *++__dest = _GLIBCXX_MOVE(*__first); 862 : return ++__dest; 863 : } 864 : 865 : /** 866 : * @brief Remove consecutive values from a sequence using a predicate. 867 : * @param first A forward iterator. 868 : * @param last A forward iterator. 869 : * @param binary_pred A binary predicate. 870 : * @return An iterator designating the end of the resulting sequence. 871 : * 872 : * Removes all but the first element from each group of consecutive 873 : * values for which @p binary_pred returns true. 874 : * unique() is stable, so the relative order of elements that are 875 : * not removed is unchanged. 876 : * Elements between the end of the resulting sequence and @p last 877 : * are still present, but their value is unspecified. 878 : */ 879 : template<typename _ForwardIterator, typename _BinaryPredicate> 880 : _ForwardIterator 881 : unique(_ForwardIterator __first, _ForwardIterator __last, 882 : _BinaryPredicate __binary_pred) 883 : { 884 : // concept requirements 885 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 886 : _ForwardIterator>) 887 : __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 888 : typename iterator_traits<_ForwardIterator>::value_type, 889 : typename iterator_traits<_ForwardIterator>::value_type>) 890 : __glibcxx_requires_valid_range(__first, __last); 891 : 892 : // Skip the beginning, if already unique. 893 : __first = _GLIBCXX_STD_P::adjacent_find(__first, __last, __binary_pred); 894 : if (__first == __last) 895 : return __last; 896 : 897 : // Do the real copy work. 898 : _ForwardIterator __dest = __first; 899 : ++__first; 900 : while (++__first != __last) 901 : if (!bool(__binary_pred(*__dest, *__first))) 902 : *++__dest = _GLIBCXX_MOVE(*__first); 903 : return ++__dest; 904 : } 905 : 906 : /** 907 : * This is an uglified unique_copy(_InputIterator, _InputIterator, 908 : * _OutputIterator) 909 : * overloaded for forward iterators and output iterator as result. 910 : */ 911 : template<typename _ForwardIterator, typename _OutputIterator> 912 : _OutputIterator 913 : __unique_copy(_ForwardIterator __first, _ForwardIterator __last, 914 : _OutputIterator __result, 915 : forward_iterator_tag, output_iterator_tag) 916 : { 917 : // concept requirements -- taken care of in dispatching function 918 : _ForwardIterator __next = __first; 919 : *__result = *__first; 920 : while (++__next != __last) 921 : if (!(*__first == *__next)) 922 : { 923 : __first = __next; 924 : *++__result = *__first; 925 : } 926 : return ++__result; 927 : } 928 : 929 : /** 930 : * This is an uglified unique_copy(_InputIterator, _InputIterator, 931 : * _OutputIterator) 932 : * overloaded for input iterators and output iterator as result. 933 : */ 934 : template<typename _InputIterator, typename _OutputIterator> 935 : _OutputIterator 936 : __unique_copy(_InputIterator __first, _InputIterator __last, 937 : _OutputIterator __result, 938 : input_iterator_tag, output_iterator_tag) 939 : { 940 : // concept requirements -- taken care of in dispatching function 941 : typename iterator_traits<_InputIterator>::value_type __value = *__first; 942 : *__result = __value; 943 : while (++__first != __last) 944 : if (!(__value == *__first)) 945 : { 946 : __value = *__first; 947 : *++__result = __value; 948 : } 949 : return ++__result; 950 : } 951 : 952 : /** 953 : * This is an uglified unique_copy(_InputIterator, _InputIterator, 954 : * _OutputIterator) 955 : * overloaded for input iterators and forward iterator as result. 956 : */ 957 : template<typename _InputIterator, typename _ForwardIterator> 958 : _ForwardIterator 959 : __unique_copy(_InputIterator __first, _InputIterator __last, 960 : _ForwardIterator __result, 961 : input_iterator_tag, forward_iterator_tag) 962 : { 963 : // concept requirements -- taken care of in dispatching function 964 : *__result = *__first; 965 : while (++__first != __last) 966 : if (!(*__result == *__first)) 967 : *++__result = *__first; 968 : return ++__result; 969 : } 970 : 971 : /** 972 : * This is an uglified 973 : * unique_copy(_InputIterator, _InputIterator, _OutputIterator, 974 : * _BinaryPredicate) 975 : * overloaded for forward iterators and output iterator as result. 976 : */ 977 : template<typename _ForwardIterator, typename _OutputIterator, 978 : typename _BinaryPredicate> 979 : _OutputIterator 980 : __unique_copy(_ForwardIterator __first, _ForwardIterator __last, 981 : _OutputIterator __result, _BinaryPredicate __binary_pred, 982 : forward_iterator_tag, output_iterator_tag) 983 : { 984 : // concept requirements -- iterators already checked 985 : __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 986 : typename iterator_traits<_ForwardIterator>::value_type, 987 : typename iterator_traits<_ForwardIterator>::value_type>) 988 : 989 : _ForwardIterator __next = __first; 990 : *__result = *__first; 991 : while (++__next != __last) 992 : if (!bool(__binary_pred(*__first, *__next))) 993 : { 994 : __first = __next; 995 : *++__result = *__first; 996 : } 997 : return ++__result; 998 : } 999 : 1000 : /** 1001 : * This is an uglified 1002 : * unique_copy(_InputIterator, _InputIterator, _OutputIterator, 1003 : * _BinaryPredicate) 1004 : * overloaded for input iterators and output iterator as result. 1005 : */ 1006 : template<typename _InputIterator, typename _OutputIterator, 1007 : typename _BinaryPredicate> 1008 : _OutputIterator 1009 : __unique_copy(_InputIterator __first, _InputIterator __last, 1010 : _OutputIterator __result, _BinaryPredicate __binary_pred, 1011 : input_iterator_tag, output_iterator_tag) 1012 : { 1013 : // concept requirements -- iterators already checked 1014 : __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 1015 : typename iterator_traits<_InputIterator>::value_type, 1016 : typename iterator_traits<_InputIterator>::value_type>) 1017 : 1018 : typename iterator_traits<_InputIterator>::value_type __value = *__first; 1019 : *__result = __value; 1020 : while (++__first != __last) 1021 : if (!bool(__binary_pred(__value, *__first))) 1022 : { 1023 : __value = *__first; 1024 : *++__result = __value; 1025 : } 1026 : return ++__result; 1027 : } 1028 : 1029 : /** 1030 : * This is an uglified 1031 : * unique_copy(_InputIterator, _InputIterator, _OutputIterator, 1032 : * _BinaryPredicate) 1033 : * overloaded for input iterators and forward iterator as result. 1034 : */ 1035 : template<typename _InputIterator, typename _ForwardIterator, 1036 : typename _BinaryPredicate> 1037 : _ForwardIterator 1038 : __unique_copy(_InputIterator __first, _InputIterator __last, 1039 : _ForwardIterator __result, _BinaryPredicate __binary_pred, 1040 : input_iterator_tag, forward_iterator_tag) 1041 : { 1042 : // concept requirements -- iterators already checked 1043 : __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 1044 : typename iterator_traits<_ForwardIterator>::value_type, 1045 : typename iterator_traits<_InputIterator>::value_type>) 1046 : 1047 : *__result = *__first; 1048 : while (++__first != __last) 1049 : if (!bool(__binary_pred(*__result, *__first))) 1050 : *++__result = *__first; 1051 : return ++__result; 1052 : } 1053 : 1054 : /** 1055 : * This is an uglified reverse(_BidirectionalIterator, 1056 : * _BidirectionalIterator) 1057 : * overloaded for bidirectional iterators. 1058 : */ 1059 : template<typename _BidirectionalIterator> 1060 : void 1061 : __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, 1062 : bidirectional_iterator_tag) 1063 : { 1064 : while (true) 1065 : if (__first == __last || __first == --__last) 1066 : return; 1067 : else 1068 : { 1069 : std::iter_swap(__first, __last); 1070 : ++__first; 1071 : } 1072 : } 1073 : 1074 : /** 1075 : * This is an uglified reverse(_BidirectionalIterator, 1076 : * _BidirectionalIterator) 1077 : * overloaded for random access iterators. 1078 : */ 1079 : template<typename _RandomAccessIterator> 1080 : void 1081 : __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, 1082 : random_access_iterator_tag) 1083 : { 1084 : if (__first == __last) 1085 : return; 1086 : --__last; 1087 : while (__first < __last) 1088 : { 1089 : std::iter_swap(__first, __last); 1090 : ++__first; 1091 : --__last; 1092 : } 1093 : } 1094 : 1095 : /** 1096 : * @brief Reverse a sequence. 1097 : * @param first A bidirectional iterator. 1098 : * @param last A bidirectional iterator. 1099 : * @return reverse() returns no value. 1100 : * 1101 : * Reverses the order of the elements in the range @p [first,last), 1102 : * so that the first element becomes the last etc. 1103 : * For every @c i such that @p 0<=i<=(last-first)/2), @p reverse() 1104 : * swaps @p *(first+i) and @p *(last-(i+1)) 1105 : */ 1106 : template<typename _BidirectionalIterator> 1107 : inline void 1108 : reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) 1109 : { 1110 : // concept requirements 1111 : __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< 1112 : _BidirectionalIterator>) 1113 : __glibcxx_requires_valid_range(__first, __last); 1114 : std::__reverse(__first, __last, std::__iterator_category(__first)); 1115 : } 1116 : 1117 : /** 1118 : * @brief Copy a sequence, reversing its elements. 1119 : * @param first A bidirectional iterator. 1120 : * @param last A bidirectional iterator. 1121 : * @param result An output iterator. 1122 : * @return An iterator designating the end of the resulting sequence. 1123 : * 1124 : * Copies the elements in the range @p [first,last) to the range 1125 : * @p [result,result+(last-first)) such that the order of the 1126 : * elements is reversed. 1127 : * For every @c i such that @p 0<=i<=(last-first), @p reverse_copy() 1128 : * performs the assignment @p *(result+(last-first)-i) = *(first+i). 1129 : * The ranges @p [first,last) and @p [result,result+(last-first)) 1130 : * must not overlap. 1131 : */ 1132 : template<typename _BidirectionalIterator, typename _OutputIterator> 1133 : _OutputIterator 1134 : reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, 1135 : _OutputIterator __result) 1136 : { 1137 : // concept requirements 1138 : __glibcxx_function_requires(_BidirectionalIteratorConcept< 1139 : _BidirectionalIterator>) 1140 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 1141 : typename iterator_traits<_BidirectionalIterator>::value_type>) 1142 : __glibcxx_requires_valid_range(__first, __last); 1143 : 1144 : while (__first != __last) 1145 : { 1146 : --__last; 1147 : *__result = *__last; 1148 : ++__result; 1149 : } 1150 : return __result; 1151 : } 1152 : 1153 : /** 1154 : * This is a helper function for the rotate algorithm specialized on RAIs. 1155 : * It returns the greatest common divisor of two integer values. 1156 : */ 1157 : template<typename _EuclideanRingElement> 1158 : _EuclideanRingElement 1159 : __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n) 1160 : { 1161 : while (__n != 0) 1162 : { 1163 : _EuclideanRingElement __t = __m % __n; 1164 : __m = __n; 1165 : __n = __t; 1166 : } 1167 : return __m; 1168 : } 1169 : 1170 : /// This is a helper function for the rotate algorithm. 1171 : template<typename _ForwardIterator> 1172 : void 1173 : __rotate(_ForwardIterator __first, 1174 : _ForwardIterator __middle, 1175 : _ForwardIterator __last, 1176 : forward_iterator_tag) 1177 : { 1178 : if (__first == __middle || __last == __middle) 1179 : return; 1180 : 1181 : _ForwardIterator __first2 = __middle; 1182 : do 1183 : { 1184 : std::iter_swap(__first, __first2); 1185 : ++__first; 1186 : ++__first2; 1187 : if (__first == __middle) 1188 : __middle = __first2; 1189 : } 1190 : while (__first2 != __last); 1191 : 1192 : __first2 = __middle; 1193 : 1194 : while (__first2 != __last) 1195 : { 1196 : std::iter_swap(__first, __first2); 1197 : ++__first; 1198 : ++__first2; 1199 : if (__first == __middle) 1200 : __middle = __first2; 1201 : else if (__first2 == __last) 1202 : __first2 = __middle; 1203 : } 1204 : } 1205 : 1206 : /// This is a helper function for the rotate algorithm. 1207 : template<typename _BidirectionalIterator> 1208 : void 1209 : __rotate(_BidirectionalIterator __first, 1210 : _BidirectionalIterator __middle, 1211 : _BidirectionalIterator __last, 1212 : bidirectional_iterator_tag) 1213 : { 1214 : // concept requirements 1215 : __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< 1216 : _BidirectionalIterator>) 1217 : 1218 : if (__first == __middle || __last == __middle) 1219 : return; 1220 : 1221 : std::__reverse(__first, __middle, bidirectional_iterator_tag()); 1222 : std::__reverse(__middle, __last, bidirectional_iterator_tag()); 1223 : 1224 : while (__first != __middle && __middle != __last) 1225 : { 1226 : std::iter_swap(__first, --__last); 1227 : ++__first; 1228 : } 1229 : 1230 : if (__first == __middle) 1231 : std::__reverse(__middle, __last, bidirectional_iterator_tag()); 1232 : else 1233 : std::__reverse(__first, __middle, bidirectional_iterator_tag()); 1234 : } 1235 : 1236 : /// This is a helper function for the rotate algorithm. 1237 : template<typename _RandomAccessIterator> 1238 : void 1239 : __rotate(_RandomAccessIterator __first, 1240 : _RandomAccessIterator __middle, 1241 : _RandomAccessIterator __last, 1242 : random_access_iterator_tag) 1243 : { 1244 : // concept requirements 1245 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 1246 : _RandomAccessIterator>) 1247 : 1248 : if (__first == __middle || __last == __middle) 1249 : return; 1250 : 1251 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 1252 : _Distance; 1253 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 1254 : _ValueType; 1255 : 1256 : const _Distance __n = __last - __first; 1257 : const _Distance __k = __middle - __first; 1258 : const _Distance __l = __n - __k; 1259 : 1260 : if (__k == __l) 1261 : { 1262 : std::swap_ranges(__first, __middle, __middle); 1263 : return; 1264 : } 1265 : 1266 : const _Distance __d = std::__gcd(__n, __k); 1267 : 1268 : for (_Distance __i = 0; __i < __d; __i++) 1269 : { 1270 : _ValueType __tmp = _GLIBCXX_MOVE(*__first); 1271 : _RandomAccessIterator __p = __first; 1272 : 1273 : if (__k < __l) 1274 : { 1275 : for (_Distance __j = 0; __j < __l / __d; __j++) 1276 : { 1277 : if (__p > __first + __l) 1278 : { 1279 : *__p = _GLIBCXX_MOVE(*(__p - __l)); 1280 : __p -= __l; 1281 : } 1282 : 1283 : *__p = _GLIBCXX_MOVE(*(__p + __k)); 1284 : __p += __k; 1285 : } 1286 : } 1287 : else 1288 : { 1289 : for (_Distance __j = 0; __j < __k / __d - 1; __j ++) 1290 : { 1291 : if (__p < __last - __k) 1292 : { 1293 : *__p = _GLIBCXX_MOVE(*(__p + __k)); 1294 : __p += __k; 1295 : } 1296 : *__p = _GLIBCXX_MOVE(*(__p - __l)); 1297 : __p -= __l; 1298 : } 1299 : } 1300 : 1301 : *__p = _GLIBCXX_MOVE(__tmp); 1302 : ++__first; 1303 : } 1304 : } 1305 : 1306 : /** 1307 : * @brief Rotate the elements of a sequence. 1308 : * @param first A forward iterator. 1309 : * @param middle A forward iterator. 1310 : * @param last A forward iterator. 1311 : * @return Nothing. 1312 : * 1313 : * Rotates the elements of the range @p [first,last) by @p (middle-first) 1314 : * positions so that the element at @p middle is moved to @p first, the 1315 : * element at @p middle+1 is moved to @first+1 and so on for each element 1316 : * in the range @p [first,last). 1317 : * 1318 : * This effectively swaps the ranges @p [first,middle) and 1319 : * @p [middle,last). 1320 : * 1321 : * Performs @p *(first+(n+(last-middle))%(last-first))=*(first+n) for 1322 : * each @p n in the range @p [0,last-first). 1323 : */ 1324 : template<typename _ForwardIterator> 1325 : inline void 1326 : rotate(_ForwardIterator __first, _ForwardIterator __middle, 1327 : _ForwardIterator __last) 1328 : { 1329 : // concept requirements 1330 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 1331 : _ForwardIterator>) 1332 : __glibcxx_requires_valid_range(__first, __middle); 1333 : __glibcxx_requires_valid_range(__middle, __last); 1334 : 1335 : typedef typename iterator_traits<_ForwardIterator>::iterator_category 1336 : _IterType; 1337 : std::__rotate(__first, __middle, __last, _IterType()); 1338 : } 1339 : 1340 : /** 1341 : * @brief Copy a sequence, rotating its elements. 1342 : * @param first A forward iterator. 1343 : * @param middle A forward iterator. 1344 : * @param last A forward iterator. 1345 : * @param result An output iterator. 1346 : * @return An iterator designating the end of the resulting sequence. 1347 : * 1348 : * Copies the elements of the range @p [first,last) to the range 1349 : * beginning at @result, rotating the copied elements by @p (middle-first) 1350 : * positions so that the element at @p middle is moved to @p result, the 1351 : * element at @p middle+1 is moved to @result+1 and so on for each element 1352 : * in the range @p [first,last). 1353 : * 1354 : * Performs @p *(result+(n+(last-middle))%(last-first))=*(first+n) for 1355 : * each @p n in the range @p [0,last-first). 1356 : */ 1357 : template<typename _ForwardIterator, typename _OutputIterator> 1358 : _OutputIterator 1359 : rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, 1360 : _ForwardIterator __last, _OutputIterator __result) 1361 : { 1362 : // concept requirements 1363 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 1364 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 1365 : typename iterator_traits<_ForwardIterator>::value_type>) 1366 : __glibcxx_requires_valid_range(__first, __middle); 1367 : __glibcxx_requires_valid_range(__middle, __last); 1368 : 1369 : return std::copy(__first, __middle, 1370 : std::copy(__middle, __last, __result)); 1371 : } 1372 : 1373 : /// This is a helper function... 1374 : template<typename _ForwardIterator, typename _Predicate> 1375 : _ForwardIterator 1376 : __partition(_ForwardIterator __first, _ForwardIterator __last, 1377 : _Predicate __pred, forward_iterator_tag) 1378 : { 1379 : if (__first == __last) 1380 : return __first; 1381 : 1382 : while (__pred(*__first)) 1383 : if (++__first == __last) 1384 : return __first; 1385 : 1386 : _ForwardIterator __next = __first; 1387 : 1388 : while (++__next != __last) 1389 : if (__pred(*__next)) 1390 : { 1391 : std::iter_swap(__first, __next); 1392 : ++__first; 1393 : } 1394 : 1395 : return __first; 1396 : } 1397 : 1398 : /// This is a helper function... 1399 : template<typename _BidirectionalIterator, typename _Predicate> 1400 : _BidirectionalIterator 1401 : __partition(_BidirectionalIterator __first, _BidirectionalIterator __last, 1402 : _Predicate __pred, bidirectional_iterator_tag) 1403 : { 1404 : while (true) 1405 : { 1406 : while (true) 1407 : if (__first == __last) 1408 : return __first; 1409 : else if (__pred(*__first)) 1410 : ++__first; 1411 : else 1412 : break; 1413 : --__last; 1414 : while (true) 1415 : if (__first == __last) 1416 : return __first; 1417 : else if (!bool(__pred(*__last))) 1418 : --__last; 1419 : else 1420 : break; 1421 : std::iter_swap(__first, __last); 1422 : ++__first; 1423 : } 1424 : } 1425 : 1426 : // partition 1427 : 1428 : /// This is a helper function... 1429 : template<typename _ForwardIterator, typename _Predicate, typename _Distance> 1430 : _ForwardIterator 1431 : __inplace_stable_partition(_ForwardIterator __first, 1432 : _ForwardIterator __last, 1433 : _Predicate __pred, _Distance __len) 1434 : { 1435 : if (__len == 1) 1436 : return __pred(*__first) ? __last : __first; 1437 : _ForwardIterator __middle = __first; 1438 : std::advance(__middle, __len / 2); 1439 : _ForwardIterator __begin = std::__inplace_stable_partition(__first, 1440 : __middle, 1441 : __pred, 1442 : __len / 2); 1443 : _ForwardIterator __end = std::__inplace_stable_partition(__middle, __last, 1444 : __pred, 1445 : __len 1446 : - __len / 2); 1447 : std::rotate(__begin, __middle, __end); 1448 : std::advance(__begin, std::distance(__middle, __end)); 1449 : return __begin; 1450 : } 1451 : 1452 : /// This is a helper function... 1453 : template<typename _ForwardIterator, typename _Pointer, typename _Predicate, 1454 : typename _Distance> 1455 : _ForwardIterator 1456 : __stable_partition_adaptive(_ForwardIterator __first, 1457 : _ForwardIterator __last, 1458 : _Predicate __pred, _Distance __len, 1459 : _Pointer __buffer, 1460 : _Distance __buffer_size) 1461 : { 1462 : if (__len <= __buffer_size) 1463 : { 1464 : _ForwardIterator __result1 = __first; 1465 : _Pointer __result2 = __buffer; 1466 : for (; __first != __last; ++__first) 1467 : if (__pred(*__first)) 1468 : { 1469 : *__result1 = *__first; 1470 : ++__result1; 1471 : } 1472 : else 1473 : { 1474 : *__result2 = *__first; 1475 : ++__result2; 1476 : } 1477 : std::copy(__buffer, __result2, __result1); 1478 : return __result1; 1479 : } 1480 : else 1481 : { 1482 : _ForwardIterator __middle = __first; 1483 : std::advance(__middle, __len / 2); 1484 : _ForwardIterator __begin = 1485 : std::__stable_partition_adaptive(__first, __middle, __pred, 1486 : __len / 2, __buffer, 1487 : __buffer_size); 1488 : _ForwardIterator __end = 1489 : std::__stable_partition_adaptive(__middle, __last, __pred, 1490 : __len - __len / 2, 1491 : __buffer, __buffer_size); 1492 : std::rotate(__begin, __middle, __end); 1493 : std::advance(__begin, std::distance(__middle, __end)); 1494 : return __begin; 1495 : } 1496 : } 1497 : 1498 : /** 1499 : * @brief Move elements for which a predicate is true to the beginning 1500 : * of a sequence, preserving relative ordering. 1501 : * @param first A forward iterator. 1502 : * @param last A forward iterator. 1503 : * @param pred A predicate functor. 1504 : * @return An iterator @p middle such that @p pred(i) is true for each 1505 : * iterator @p i in the range @p [first,middle) and false for each @p i 1506 : * in the range @p [middle,last). 1507 : * 1508 : * Performs the same function as @p partition() with the additional 1509 : * guarantee that the relative ordering of elements in each group is 1510 : * preserved, so any two elements @p x and @p y in the range 1511 : * @p [first,last) such that @p pred(x)==pred(y) will have the same 1512 : * relative ordering after calling @p stable_partition(). 1513 : */ 1514 : template<typename _ForwardIterator, typename _Predicate> 1515 : _ForwardIterator 1516 : stable_partition(_ForwardIterator __first, _ForwardIterator __last, 1517 : _Predicate __pred) 1518 : { 1519 : // concept requirements 1520 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 1521 : _ForwardIterator>) 1522 : __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 1523 : typename iterator_traits<_ForwardIterator>::value_type>) 1524 : __glibcxx_requires_valid_range(__first, __last); 1525 : 1526 : if (__first == __last) 1527 : return __first; 1528 : else 1529 : { 1530 : typedef typename iterator_traits<_ForwardIterator>::value_type 1531 : _ValueType; 1532 : typedef typename iterator_traits<_ForwardIterator>::difference_type 1533 : _DistanceType; 1534 : 1535 : _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first, 1536 : __last); 1537 : if (__buf.size() > 0) 1538 : return 1539 : std::__stable_partition_adaptive(__first, __last, __pred, 1540 : _DistanceType(__buf.requested_size()), 1541 : __buf.begin(), 1542 : _DistanceType(__buf.size())); 1543 : else 1544 : return 1545 : std::__inplace_stable_partition(__first, __last, __pred, 1546 : _DistanceType(__buf.requested_size())); 1547 : } 1548 : } 1549 : 1550 : /// This is a helper function for the sort routines. 1551 : template<typename _RandomAccessIterator> 1552 : void 1553 : __heap_select(_RandomAccessIterator __first, 1554 : _RandomAccessIterator __middle, 1555 0 : _RandomAccessIterator __last) 1556 : { 1557 0 : std::make_heap(__first, __middle); 1558 0 : for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) 1559 0 : if (*__i < *__first) 1560 0 : std::__pop_heap(__first, __middle, __i); 1561 0 : } 1562 : 1563 : /// This is a helper function for the sort routines. 1564 : template<typename _RandomAccessIterator, typename _Compare> 1565 : void 1566 : __heap_select(_RandomAccessIterator __first, 1567 : _RandomAccessIterator __middle, 1568 0 : _RandomAccessIterator __last, _Compare __comp) 1569 : { 1570 0 : std::make_heap(__first, __middle, __comp); 1571 0 : for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) 1572 0 : if (__comp(*__i, *__first)) 1573 0 : std::__pop_heap(__first, __middle, __i, __comp); 1574 0 : } 1575 : 1576 : // partial_sort 1577 : 1578 : /** 1579 : * @brief Copy the smallest elements of a sequence. 1580 : * @param first An iterator. 1581 : * @param last Another iterator. 1582 : * @param result_first A random-access iterator. 1583 : * @param result_last Another random-access iterator. 1584 : * @return An iterator indicating the end of the resulting sequence. 1585 : * 1586 : * Copies and sorts the smallest N values from the range @p [first,last) 1587 : * to the range beginning at @p result_first, where the number of 1588 : * elements to be copied, @p N, is the smaller of @p (last-first) and 1589 : * @p (result_last-result_first). 1590 : * After the sort if @p i and @j are iterators in the range 1591 : * @p [result_first,result_first+N) such that @i precedes @j then 1592 : * @p *j<*i is false. 1593 : * The value returned is @p result_first+N. 1594 : */ 1595 : template<typename _InputIterator, typename _RandomAccessIterator> 1596 : _RandomAccessIterator 1597 : partial_sort_copy(_InputIterator __first, _InputIterator __last, 1598 : _RandomAccessIterator __result_first, 1599 : _RandomAccessIterator __result_last) 1600 : { 1601 : typedef typename iterator_traits<_InputIterator>::value_type 1602 : _InputValueType; 1603 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 1604 : _OutputValueType; 1605 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 1606 : _DistanceType; 1607 : 1608 : // concept requirements 1609 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 1610 : __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, 1611 : _OutputValueType>) 1612 : __glibcxx_function_requires(_LessThanOpConcept<_InputValueType, 1613 : _OutputValueType>) 1614 : __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>) 1615 : __glibcxx_requires_valid_range(__first, __last); 1616 : __glibcxx_requires_valid_range(__result_first, __result_last); 1617 : 1618 : if (__result_first == __result_last) 1619 : return __result_last; 1620 : _RandomAccessIterator __result_real_last = __result_first; 1621 : while(__first != __last && __result_real_last != __result_last) 1622 : { 1623 : *__result_real_last = *__first; 1624 : ++__result_real_last; 1625 : ++__first; 1626 : } 1627 : std::make_heap(__result_first, __result_real_last); 1628 : while (__first != __last) 1629 : { 1630 : if (*__first < *__result_first) 1631 : std::__adjust_heap(__result_first, _DistanceType(0), 1632 : _DistanceType(__result_real_last 1633 : - __result_first), 1634 : _InputValueType(*__first)); 1635 : ++__first; 1636 : } 1637 : std::sort_heap(__result_first, __result_real_last); 1638 : return __result_real_last; 1639 : } 1640 : 1641 : /** 1642 : * @brief Copy the smallest elements of a sequence using a predicate for 1643 : * comparison. 1644 : * @param first An input iterator. 1645 : * @param last Another input iterator. 1646 : * @param result_first A random-access iterator. 1647 : * @param result_last Another random-access iterator. 1648 : * @param comp A comparison functor. 1649 : * @return An iterator indicating the end of the resulting sequence. 1650 : * 1651 : * Copies and sorts the smallest N values from the range @p [first,last) 1652 : * to the range beginning at @p result_first, where the number of 1653 : * elements to be copied, @p N, is the smaller of @p (last-first) and 1654 : * @p (result_last-result_first). 1655 : * After the sort if @p i and @j are iterators in the range 1656 : * @p [result_first,result_first+N) such that @i precedes @j then 1657 : * @p comp(*j,*i) is false. 1658 : * The value returned is @p result_first+N. 1659 : */ 1660 : template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare> 1661 : _RandomAccessIterator 1662 : partial_sort_copy(_InputIterator __first, _InputIterator __last, 1663 : _RandomAccessIterator __result_first, 1664 : _RandomAccessIterator __result_last, 1665 : _Compare __comp) 1666 : { 1667 : typedef typename iterator_traits<_InputIterator>::value_type 1668 : _InputValueType; 1669 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 1670 : _OutputValueType; 1671 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 1672 : _DistanceType; 1673 : 1674 : // concept requirements 1675 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 1676 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 1677 : _RandomAccessIterator>) 1678 : __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, 1679 : _OutputValueType>) 1680 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 1681 : _InputValueType, _OutputValueType>) 1682 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 1683 : _OutputValueType, _OutputValueType>) 1684 : __glibcxx_requires_valid_range(__first, __last); 1685 : __glibcxx_requires_valid_range(__result_first, __result_last); 1686 : 1687 : if (__result_first == __result_last) 1688 : return __result_last; 1689 : _RandomAccessIterator __result_real_last = __result_first; 1690 : while(__first != __last && __result_real_last != __result_last) 1691 : { 1692 : *__result_real_last = *__first; 1693 : ++__result_real_last; 1694 : ++__first; 1695 : } 1696 : std::make_heap(__result_first, __result_real_last, __comp); 1697 : while (__first != __last) 1698 : { 1699 : if (__comp(*__first, *__result_first)) 1700 : std::__adjust_heap(__result_first, _DistanceType(0), 1701 : _DistanceType(__result_real_last 1702 : - __result_first), 1703 : _InputValueType(*__first), 1704 : __comp); 1705 : ++__first; 1706 : } 1707 : std::sort_heap(__result_first, __result_real_last, __comp); 1708 : return __result_real_last; 1709 : } 1710 : 1711 : /// This is a helper function for the sort routine. 1712 : template<typename _RandomAccessIterator, typename _Tp> 1713 : void 1714 2369 : __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val) 1715 : { 1716 2369 : _RandomAccessIterator __next = __last; 1717 2369 : --__next; 1718 5033 : while (__val < *__next) 1719 : { 1720 295 : *__last = *__next; 1721 295 : __last = __next; 1722 295 : --__next; 1723 : } 1724 2369 : *__last = __val; 1725 2369 : } 1726 : 1727 : /// This is a helper function for the sort routine. 1728 : template<typename _RandomAccessIterator, typename _Tp, typename _Compare> 1729 : void 1730 : __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val, 1731 48163 : _Compare __comp) 1732 : { 1733 48163 : _RandomAccessIterator __next = __last; 1734 48163 : --__next; 1735 273339 : while (__comp(__val, *__next)) 1736 : { 1737 177013 : *__last = *__next; 1738 177013 : __last = __next; 1739 177013 : --__next; 1740 : } 1741 48163 : *__last = __val; 1742 48163 : } 1743 : 1744 : /// This is a helper function for the sort routine. 1745 : template<typename _RandomAccessIterator> 1746 : void 1747 : __insertion_sort(_RandomAccessIterator __first, 1748 81 : _RandomAccessIterator __last) 1749 : { 1750 81 : if (__first == __last) 1751 0 : return; 1752 : 1753 503 : for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) 1754 : { 1755 : typename iterator_traits<_RandomAccessIterator>::value_type 1756 422 : __val = *__i; 1757 422 : if (__val < *__first) 1758 : { 1759 151 : std::copy_backward(__first, __i, __i + 1); 1760 151 : *__first = __val; 1761 : } 1762 : else 1763 271 : std::__unguarded_linear_insert(__i, __val); 1764 : } 1765 : } 1766 : 1767 : /// This is a helper function for the sort routine. 1768 : template<typename _RandomAccessIterator, typename _Compare> 1769 : void 1770 : __insertion_sort(_RandomAccessIterator __first, 1771 3938 : _RandomAccessIterator __last, _Compare __comp) 1772 : { 1773 3938 : if (__first == __last) return; 1774 : 1775 55255 : for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) 1776 : { 1777 : typename iterator_traits<_RandomAccessIterator>::value_type 1778 51317 : __val = *__i; 1779 51317 : if (__comp(__val, *__first)) 1780 : { 1781 7625 : std::copy_backward(__first, __i, __i + 1); 1782 7625 : *__first = __val; 1783 : } 1784 : else 1785 43692 : std::__unguarded_linear_insert(__i, __val, __comp); 1786 : } 1787 : } 1788 : 1789 : /// This is a helper function for the sort routine. 1790 : template<typename _RandomAccessIterator> 1791 : inline void 1792 : __unguarded_insertion_sort(_RandomAccessIterator __first, 1793 3 : _RandomAccessIterator __last) 1794 : { 1795 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 1796 : _ValueType; 1797 : 1798 2101 : for (_RandomAccessIterator __i = __first; __i != __last; ++__i) 1799 2098 : std::__unguarded_linear_insert(__i, _ValueType(*__i)); 1800 3 : } 1801 : 1802 : /// This is a helper function for the sort routine. 1803 : template<typename _RandomAccessIterator, typename _Compare> 1804 : inline void 1805 : __unguarded_insertion_sort(_RandomAccessIterator __first, 1806 261 : _RandomAccessIterator __last, _Compare __comp) 1807 : { 1808 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 1809 : _ValueType; 1810 : 1811 4732 : for (_RandomAccessIterator __i = __first; __i != __last; ++__i) 1812 4471 : std::__unguarded_linear_insert(__i, _ValueType(*__i), __comp); 1813 261 : } 1814 : 1815 : /** 1816 : * @doctodo 1817 : * This controls some aspect of the sort routines. 1818 : */ 1819 : enum { _S_threshold = 16 }; 1820 : 1821 : /// This is a helper function for the sort routine. 1822 : template<typename _RandomAccessIterator> 1823 : void 1824 : __final_insertion_sort(_RandomAccessIterator __first, 1825 81 : _RandomAccessIterator __last) 1826 : { 1827 81 : if (__last - __first > int(_S_threshold)) 1828 : { 1829 3 : std::__insertion_sort(__first, __first + int(_S_threshold)); 1830 3 : std::__unguarded_insertion_sort(__first + int(_S_threshold), __last); 1831 : } 1832 : else 1833 78 : std::__insertion_sort(__first, __last); 1834 81 : } 1835 : 1836 : /// This is a helper function for the sort routine. 1837 : template<typename _RandomAccessIterator, typename _Compare> 1838 : void 1839 : __final_insertion_sort(_RandomAccessIterator __first, 1840 3938 : _RandomAccessIterator __last, _Compare __comp) 1841 : { 1842 3938 : if (__last - __first > int(_S_threshold)) 1843 : { 1844 261 : std::__insertion_sort(__first, __first + int(_S_threshold), __comp); 1845 261 : std::__unguarded_insertion_sort(__first + int(_S_threshold), __last, 1846 : __comp); 1847 : } 1848 : else 1849 3677 : std::__insertion_sort(__first, __last, __comp); 1850 3938 : } 1851 : 1852 : /// This is a helper function... 1853 : template<typename _RandomAccessIterator, typename _Tp> 1854 : _RandomAccessIterator 1855 : __unguarded_partition(_RandomAccessIterator __first, 1856 183 : _RandomAccessIterator __last, _Tp __pivot) 1857 : { 1858 50 : while (true) 1859 : { 1860 6596 : while (*__first < __pivot) 1861 6230 : ++__first; 1862 183 : --__last; 1863 6480 : while (__pivot < *__last) 1864 6114 : --__last; 1865 183 : if (!(__first < __last)) 1866 133 : return __first; 1867 50 : std::iter_swap(__first, __last); 1868 50 : ++__first; 1869 : } 1870 : } 1871 : 1872 : /// This is a helper function... 1873 : template<typename _RandomAccessIterator, typename _Tp, typename _Compare> 1874 : _RandomAccessIterator 1875 : __unguarded_partition(_RandomAccessIterator __first, 1876 : _RandomAccessIterator __last, 1877 7740 : _Tp __pivot, _Compare __comp) 1878 : { 1879 7030 : while (true) 1880 : { 1881 25088 : while (__comp(*__first, __pivot)) 1882 9608 : ++__first; 1883 7740 : --__last; 1884 23207 : while (__comp(__pivot, *__last)) 1885 7727 : --__last; 1886 7740 : if (!(__first < __last)) 1887 710 : return __first; 1888 7030 : std::iter_swap(__first, __last); 1889 7030 : ++__first; 1890 : } 1891 : } 1892 : 1893 : /// This is a helper function for the sort routine. 1894 : template<typename _RandomAccessIterator, typename _Size> 1895 : void 1896 : __introsort_loop(_RandomAccessIterator __first, 1897 : _RandomAccessIterator __last, 1898 214 : _Size __depth_limit) 1899 : { 1900 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 1901 : _ValueType; 1902 : 1903 561 : while (__last - __first > int(_S_threshold)) 1904 : { 1905 133 : if (__depth_limit == 0) 1906 : { 1907 0 : _GLIBCXX_STD_P::partial_sort(__first, __last, __last); 1908 0 : return; 1909 : } 1910 133 : --__depth_limit; 1911 : _RandomAccessIterator __cut = 1912 : std::__unguarded_partition(__first, __last, 1913 : _ValueType(std::__median(*__first, 1914 : *(__first 1915 : + (__last 1916 : - __first) 1917 : / 2), 1918 : *(__last 1919 133 : - 1)))); 1920 133 : std::__introsort_loop(__cut, __last, __depth_limit); 1921 133 : __last = __cut; 1922 : } 1923 : } 1924 : 1925 : /// This is a helper function for the sort routine. 1926 : template<typename _RandomAccessIterator, typename _Size, typename _Compare> 1927 : void 1928 : __introsort_loop(_RandomAccessIterator __first, 1929 : _RandomAccessIterator __last, 1930 4648 : _Size __depth_limit, _Compare __comp) 1931 : { 1932 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 1933 : _ValueType; 1934 : 1935 10006 : while (__last - __first > int(_S_threshold)) 1936 : { 1937 710 : if (__depth_limit == 0) 1938 : { 1939 0 : _GLIBCXX_STD_P::partial_sort(__first, __last, __last, __comp); 1940 0 : return; 1941 : } 1942 710 : --__depth_limit; 1943 : _RandomAccessIterator __cut = 1944 : std::__unguarded_partition(__first, __last, 1945 : _ValueType(std::__median(*__first, 1946 : *(__first 1947 : + (__last 1948 : - __first) 1949 : / 2), 1950 : *(__last - 1), 1951 : __comp)), 1952 710 : __comp); 1953 710 : std::__introsort_loop(__cut, __last, __depth_limit, __comp); 1954 710 : __last = __cut; 1955 : } 1956 : } 1957 : 1958 : /// This is a helper function for the sort routines. Precondition: __n > 0. 1959 : template<typename _Size> 1960 : inline _Size 1961 : __lg(_Size __n) 1962 : { 1963 : _Size __k; 1964 : for (__k = 0; __n != 0; __n >>= 1) 1965 : ++__k; 1966 : return __k - 1; 1967 : } 1968 : 1969 : inline int 1970 3946 : __lg(int __n) 1971 3946 : { return sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(__n); } 1972 : 1973 : inline long 1974 : __lg(long __n) 1975 : { return sizeof(long) * __CHAR_BIT__ - 1 - __builtin_clzl(__n); } 1976 : 1977 : inline long long 1978 : __lg(long long __n) 1979 : { return sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); } 1980 : 1981 : // sort 1982 : 1983 : template<typename _RandomAccessIterator, typename _Size> 1984 : void 1985 : __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth, 1986 : _RandomAccessIterator __last, _Size __depth_limit) 1987 : { 1988 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 1989 : _ValueType; 1990 : 1991 : while (__last - __first > 3) 1992 : { 1993 : if (__depth_limit == 0) 1994 : { 1995 : std::__heap_select(__first, __nth + 1, __last); 1996 : 1997 : // Place the nth largest element in its final position. 1998 : std::iter_swap(__first, __nth); 1999 : return; 2000 : } 2001 : --__depth_limit; 2002 : _RandomAccessIterator __cut = 2003 : std::__unguarded_partition(__first, __last, 2004 : _ValueType(std::__median(*__first, 2005 : *(__first 2006 : + (__last 2007 : - __first) 2008 : / 2), 2009 : *(__last 2010 : - 1)))); 2011 : if (__cut <= __nth) 2012 : __first = __cut; 2013 : else 2014 : __last = __cut; 2015 : } 2016 : std::__insertion_sort(__first, __last); 2017 : } 2018 : 2019 : template<typename _RandomAccessIterator, typename _Size, typename _Compare> 2020 : void 2021 : __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth, 2022 : _RandomAccessIterator __last, _Size __depth_limit, 2023 : _Compare __comp) 2024 : { 2025 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 2026 : _ValueType; 2027 : 2028 : while (__last - __first > 3) 2029 : { 2030 : if (__depth_limit == 0) 2031 : { 2032 : std::__heap_select(__first, __nth + 1, __last, __comp); 2033 : // Place the nth largest element in its final position. 2034 : std::iter_swap(__first, __nth); 2035 : return; 2036 : } 2037 : --__depth_limit; 2038 : _RandomAccessIterator __cut = 2039 : std::__unguarded_partition(__first, __last, 2040 : _ValueType(std::__median(*__first, 2041 : *(__first 2042 : + (__last 2043 : - __first) 2044 : / 2), 2045 : *(__last - 1), 2046 : __comp)), 2047 : __comp); 2048 : if (__cut <= __nth) 2049 : __first = __cut; 2050 : else 2051 : __last = __cut; 2052 : } 2053 : std::__insertion_sort(__first, __last, __comp); 2054 : } 2055 : 2056 : // nth_element 2057 : 2058 : /** 2059 : * @brief Finds the first position in which @a val could be inserted 2060 : * without changing the ordering. 2061 : * @param first An iterator. 2062 : * @param last Another iterator. 2063 : * @param val The search term. 2064 : * @return An iterator pointing to the first element "not less 2065 : * than" @a val, or end() if every element is less than 2066 : * @a val. 2067 : * @ingroup binarysearch 2068 : */ 2069 : template<typename _ForwardIterator, typename _Tp> 2070 : _ForwardIterator 2071 : lower_bound(_ForwardIterator __first, _ForwardIterator __last, 2072 : const _Tp& __val) 2073 : { 2074 : typedef typename iterator_traits<_ForwardIterator>::value_type 2075 : _ValueType; 2076 : typedef typename iterator_traits<_ForwardIterator>::difference_type 2077 : _DistanceType; 2078 : 2079 : // concept requirements 2080 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2081 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>) 2082 : __glibcxx_requires_partitioned_lower(__first, __last, __val); 2083 : 2084 : _DistanceType __len = std::distance(__first, __last); 2085 : _DistanceType __half; 2086 : _ForwardIterator __middle; 2087 : 2088 : while (__len > 0) 2089 : { 2090 : __half = __len >> 1; 2091 : __middle = __first; 2092 : std::advance(__middle, __half); 2093 : if (*__middle < __val) 2094 : { 2095 : __first = __middle; 2096 : ++__first; 2097 : __len = __len - __half - 1; 2098 : } 2099 : else 2100 : __len = __half; 2101 : } 2102 : return __first; 2103 : } 2104 : 2105 : /** 2106 : * @brief Finds the first position in which @a val could be inserted 2107 : * without changing the ordering. 2108 : * @param first An iterator. 2109 : * @param last Another iterator. 2110 : * @param val The search term. 2111 : * @param comp A functor to use for comparisons. 2112 : * @return An iterator pointing to the first element "not less than" @a val, 2113 : * or end() if every element is less than @a val. 2114 : * @ingroup binarysearch 2115 : * 2116 : * The comparison function should have the same effects on ordering as 2117 : * the function used for the initial sort. 2118 : */ 2119 : template<typename _ForwardIterator, typename _Tp, typename _Compare> 2120 : _ForwardIterator 2121 : lower_bound(_ForwardIterator __first, _ForwardIterator __last, 2122 : const _Tp& __val, _Compare __comp) 2123 : { 2124 : typedef typename iterator_traits<_ForwardIterator>::value_type 2125 : _ValueType; 2126 : typedef typename iterator_traits<_ForwardIterator>::difference_type 2127 : _DistanceType; 2128 : 2129 : // concept requirements 2130 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2131 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2132 : _ValueType, _Tp>) 2133 : __glibcxx_requires_partitioned_lower_pred(__first, __last, 2134 : __val, __comp); 2135 : 2136 : _DistanceType __len = std::distance(__first, __last); 2137 : _DistanceType __half; 2138 : _ForwardIterator __middle; 2139 : 2140 : while (__len > 0) 2141 : { 2142 : __half = __len >> 1; 2143 : __middle = __first; 2144 : std::advance(__middle, __half); 2145 : if (__comp(*__middle, __val)) 2146 : { 2147 : __first = __middle; 2148 : ++__first; 2149 : __len = __len - __half - 1; 2150 : } 2151 : else 2152 : __len = __half; 2153 : } 2154 : return __first; 2155 : } 2156 : 2157 : /** 2158 : * @brief Finds the last position in which @a val could be inserted 2159 : * without changing the ordering. 2160 : * @param first An iterator. 2161 : * @param last Another iterator. 2162 : * @param val The search term. 2163 : * @return An iterator pointing to the first element greater than @a val, 2164 : * or end() if no elements are greater than @a val. 2165 : * @ingroup binarysearch 2166 : */ 2167 : template<typename _ForwardIterator, typename _Tp> 2168 : _ForwardIterator 2169 : upper_bound(_ForwardIterator __first, _ForwardIterator __last, 2170 : const _Tp& __val) 2171 : { 2172 : typedef typename iterator_traits<_ForwardIterator>::value_type 2173 : _ValueType; 2174 : typedef typename iterator_traits<_ForwardIterator>::difference_type 2175 : _DistanceType; 2176 : 2177 : // concept requirements 2178 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2179 : __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) 2180 : __glibcxx_requires_partitioned_upper(__first, __last, __val); 2181 : 2182 : _DistanceType __len = std::distance(__first, __last); 2183 : _DistanceType __half; 2184 : _ForwardIterator __middle; 2185 : 2186 : while (__len > 0) 2187 : { 2188 : __half = __len >> 1; 2189 : __middle = __first; 2190 : std::advance(__middle, __half); 2191 : if (__val < *__middle) 2192 : __len = __half; 2193 : else 2194 : { 2195 : __first = __middle; 2196 : ++__first; 2197 : __len = __len - __half - 1; 2198 : } 2199 : } 2200 : return __first; 2201 : } 2202 : 2203 : /** 2204 : * @brief Finds the last position in which @a val could be inserted 2205 : * without changing the ordering. 2206 : * @param first An iterator. 2207 : * @param last Another iterator. 2208 : * @param val The search term. 2209 : * @param comp A functor to use for comparisons. 2210 : * @return An iterator pointing to the first element greater than @a val, 2211 : * or end() if no elements are greater than @a val. 2212 : * @ingroup binarysearch 2213 : * 2214 : * The comparison function should have the same effects on ordering as 2215 : * the function used for the initial sort. 2216 : */ 2217 : template<typename _ForwardIterator, typename _Tp, typename _Compare> 2218 : _ForwardIterator 2219 : upper_bound(_ForwardIterator __first, _ForwardIterator __last, 2220 : const _Tp& __val, _Compare __comp) 2221 : { 2222 : typedef typename iterator_traits<_ForwardIterator>::value_type 2223 : _ValueType; 2224 : typedef typename iterator_traits<_ForwardIterator>::difference_type 2225 : _DistanceType; 2226 : 2227 : // concept requirements 2228 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2229 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2230 : _Tp, _ValueType>) 2231 : __glibcxx_requires_partitioned_upper_pred(__first, __last, 2232 : __val, __comp); 2233 : 2234 : _DistanceType __len = std::distance(__first, __last); 2235 : _DistanceType __half; 2236 : _ForwardIterator __middle; 2237 : 2238 : while (__len > 0) 2239 : { 2240 : __half = __len >> 1; 2241 : __middle = __first; 2242 : std::advance(__middle, __half); 2243 : if (__comp(__val, *__middle)) 2244 : __len = __half; 2245 : else 2246 : { 2247 : __first = __middle; 2248 : ++__first; 2249 : __len = __len - __half - 1; 2250 : } 2251 : } 2252 : return __first; 2253 : } 2254 : 2255 : /** 2256 : * @brief Finds the largest subrange in which @a val could be inserted 2257 : * at any place in it without changing the ordering. 2258 : * @param first An iterator. 2259 : * @param last Another iterator. 2260 : * @param val The search term. 2261 : * @return An pair of iterators defining the subrange. 2262 : * @ingroup binarysearch 2263 : * 2264 : * This is equivalent to 2265 : * @code 2266 : * std::make_pair(lower_bound(first, last, val), 2267 : * upper_bound(first, last, val)) 2268 : * @endcode 2269 : * but does not actually call those functions. 2270 : */ 2271 : template<typename _ForwardIterator, typename _Tp> 2272 : pair<_ForwardIterator, _ForwardIterator> 2273 : equal_range(_ForwardIterator __first, _ForwardIterator __last, 2274 : const _Tp& __val) 2275 : { 2276 : typedef typename iterator_traits<_ForwardIterator>::value_type 2277 : _ValueType; 2278 : typedef typename iterator_traits<_ForwardIterator>::difference_type 2279 : _DistanceType; 2280 : 2281 : // concept requirements 2282 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2283 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>) 2284 : __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) 2285 : __glibcxx_requires_partitioned_lower(__first, __last, __val); 2286 : __glibcxx_requires_partitioned_upper(__first, __last, __val); 2287 : 2288 : _DistanceType __len = std::distance(__first, __last); 2289 : _DistanceType __half; 2290 : _ForwardIterator __middle, __left, __right; 2291 : 2292 : while (__len > 0) 2293 : { 2294 : __half = __len >> 1; 2295 : __middle = __first; 2296 : std::advance(__middle, __half); 2297 : if (*__middle < __val) 2298 : { 2299 : __first = __middle; 2300 : ++__first; 2301 : __len = __len - __half - 1; 2302 : } 2303 : else if (__val < *__middle) 2304 : __len = __half; 2305 : else 2306 : { 2307 : __left = std::lower_bound(__first, __middle, __val); 2308 : std::advance(__first, __len); 2309 : __right = std::upper_bound(++__middle, __first, __val); 2310 : return pair<_ForwardIterator, _ForwardIterator>(__left, __right); 2311 : } 2312 : } 2313 : return pair<_ForwardIterator, _ForwardIterator>(__first, __first); 2314 : } 2315 : 2316 : /** 2317 : * @brief Finds the largest subrange in which @a val could be inserted 2318 : * at any place in it without changing the ordering. 2319 : * @param first An iterator. 2320 : * @param last Another iterator. 2321 : * @param val The search term. 2322 : * @param comp A functor to use for comparisons. 2323 : * @return An pair of iterators defining the subrange. 2324 : * @ingroup binarysearch 2325 : * 2326 : * This is equivalent to 2327 : * @code 2328 : * std::make_pair(lower_bound(first, last, val, comp), 2329 : * upper_bound(first, last, val, comp)) 2330 : * @endcode 2331 : * but does not actually call those functions. 2332 : */ 2333 : template<typename _ForwardIterator, typename _Tp, typename _Compare> 2334 : pair<_ForwardIterator, _ForwardIterator> 2335 : equal_range(_ForwardIterator __first, _ForwardIterator __last, 2336 : const _Tp& __val, 2337 : _Compare __comp) 2338 : { 2339 : typedef typename iterator_traits<_ForwardIterator>::value_type 2340 : _ValueType; 2341 : typedef typename iterator_traits<_ForwardIterator>::difference_type 2342 : _DistanceType; 2343 : 2344 : // concept requirements 2345 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2346 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2347 : _ValueType, _Tp>) 2348 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2349 : _Tp, _ValueType>) 2350 : __glibcxx_requires_partitioned_lower_pred(__first, __last, 2351 : __val, __comp); 2352 : __glibcxx_requires_partitioned_upper_pred(__first, __last, 2353 : __val, __comp); 2354 : 2355 : _DistanceType __len = std::distance(__first, __last); 2356 : _DistanceType __half; 2357 : _ForwardIterator __middle, __left, __right; 2358 : 2359 : while (__len > 0) 2360 : { 2361 : __half = __len >> 1; 2362 : __middle = __first; 2363 : std::advance(__middle, __half); 2364 : if (__comp(*__middle, __val)) 2365 : { 2366 : __first = __middle; 2367 : ++__first; 2368 : __len = __len - __half - 1; 2369 : } 2370 : else if (__comp(__val, *__middle)) 2371 : __len = __half; 2372 : else 2373 : { 2374 : __left = std::lower_bound(__first, __middle, __val, __comp); 2375 : std::advance(__first, __len); 2376 : __right = std::upper_bound(++__middle, __first, __val, __comp); 2377 : return pair<_ForwardIterator, _ForwardIterator>(__left, __right); 2378 : } 2379 : } 2380 : return pair<_ForwardIterator, _ForwardIterator>(__first, __first); 2381 : } 2382 : 2383 : /** 2384 : * @brief Determines whether an element exists in a range. 2385 : * @param first An iterator. 2386 : * @param last Another iterator. 2387 : * @param val The search term. 2388 : * @return True if @a val (or its equivalent) is in [@a first,@a last ]. 2389 : * @ingroup binarysearch 2390 : * 2391 : * Note that this does not actually return an iterator to @a val. For 2392 : * that, use std::find or a container's specialized find member functions. 2393 : */ 2394 : template<typename _ForwardIterator, typename _Tp> 2395 : bool 2396 : binary_search(_ForwardIterator __first, _ForwardIterator __last, 2397 : const _Tp& __val) 2398 : { 2399 : typedef typename iterator_traits<_ForwardIterator>::value_type 2400 : _ValueType; 2401 : 2402 : // concept requirements 2403 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2404 : __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) 2405 : __glibcxx_requires_partitioned_lower(__first, __last, __val); 2406 : __glibcxx_requires_partitioned_upper(__first, __last, __val); 2407 : 2408 : _ForwardIterator __i = std::lower_bound(__first, __last, __val); 2409 : return __i != __last && !(__val < *__i); 2410 : } 2411 : 2412 : /** 2413 : * @brief Determines whether an element exists in a range. 2414 : * @param first An iterator. 2415 : * @param last Another iterator. 2416 : * @param val The search term. 2417 : * @param comp A functor to use for comparisons. 2418 : * @return True if @a val (or its equivalent) is in [@a first,@a last ]. 2419 : * @ingroup binarysearch 2420 : * 2421 : * Note that this does not actually return an iterator to @a val. For 2422 : * that, use std::find or a container's specialized find member functions. 2423 : * 2424 : * The comparison function should have the same effects on ordering as 2425 : * the function used for the initial sort. 2426 : */ 2427 : template<typename _ForwardIterator, typename _Tp, typename _Compare> 2428 : bool 2429 : binary_search(_ForwardIterator __first, _ForwardIterator __last, 2430 : const _Tp& __val, _Compare __comp) 2431 : { 2432 : typedef typename iterator_traits<_ForwardIterator>::value_type 2433 : _ValueType; 2434 : 2435 : // concept requirements 2436 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2437 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2438 : _Tp, _ValueType>) 2439 : __glibcxx_requires_partitioned_lower_pred(__first, __last, 2440 : __val, __comp); 2441 : __glibcxx_requires_partitioned_upper_pred(__first, __last, 2442 : __val, __comp); 2443 : 2444 : _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp); 2445 : return __i != __last && !bool(__comp(__val, *__i)); 2446 : } 2447 : 2448 : // merge 2449 : 2450 : /// This is a helper function for the merge routines. 2451 : template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, 2452 : typename _BidirectionalIterator3> 2453 : _BidirectionalIterator3 2454 : __merge_backward(_BidirectionalIterator1 __first1, 2455 : _BidirectionalIterator1 __last1, 2456 : _BidirectionalIterator2 __first2, 2457 : _BidirectionalIterator2 __last2, 2458 : _BidirectionalIterator3 __result) 2459 : { 2460 : if (__first1 == __last1) 2461 : return std::copy_backward(__first2, __last2, __result); 2462 : if (__first2 == __last2) 2463 : return std::copy_backward(__first1, __last1, __result); 2464 : --__last1; 2465 : --__last2; 2466 : while (true) 2467 : { 2468 : if (*__last2 < *__last1) 2469 : { 2470 : *--__result = *__last1; 2471 : if (__first1 == __last1) 2472 : return std::copy_backward(__first2, ++__last2, __result); 2473 : --__last1; 2474 : } 2475 : else 2476 : { 2477 : *--__result = *__last2; 2478 : if (__first2 == __last2) 2479 : return std::copy_backward(__first1, ++__last1, __result); 2480 : --__last2; 2481 : } 2482 : } 2483 : } 2484 : 2485 : /// This is a helper function for the merge routines. 2486 : template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, 2487 : typename _BidirectionalIterator3, typename _Compare> 2488 : _BidirectionalIterator3 2489 : __merge_backward(_BidirectionalIterator1 __first1, 2490 : _BidirectionalIterator1 __last1, 2491 : _BidirectionalIterator2 __first2, 2492 : _BidirectionalIterator2 __last2, 2493 : _BidirectionalIterator3 __result, 2494 : _Compare __comp) 2495 : { 2496 : if (__first1 == __last1) 2497 : return std::copy_backward(__first2, __last2, __result); 2498 : if (__first2 == __last2) 2499 : return std::copy_backward(__first1, __last1, __result); 2500 : --__last1; 2501 : --__last2; 2502 : while (true) 2503 : { 2504 : if (__comp(*__last2, *__last1)) 2505 : { 2506 : *--__result = *__last1; 2507 : if (__first1 == __last1) 2508 : return std::copy_backward(__first2, ++__last2, __result); 2509 : --__last1; 2510 : } 2511 : else 2512 : { 2513 : *--__result = *__last2; 2514 : if (__first2 == __last2) 2515 : return std::copy_backward(__first1, ++__last1, __result); 2516 : --__last2; 2517 : } 2518 : } 2519 : } 2520 : 2521 : /// This is a helper function for the merge routines. 2522 : template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, 2523 : typename _Distance> 2524 : _BidirectionalIterator1 2525 : __rotate_adaptive(_BidirectionalIterator1 __first, 2526 : _BidirectionalIterator1 __middle, 2527 : _BidirectionalIterator1 __last, 2528 : _Distance __len1, _Distance __len2, 2529 : _BidirectionalIterator2 __buffer, 2530 : _Distance __buffer_size) 2531 : { 2532 : _BidirectionalIterator2 __buffer_end; 2533 : if (__len1 > __len2 && __len2 <= __buffer_size) 2534 : { 2535 : __buffer_end = std::copy(__middle, __last, __buffer); 2536 : std::copy_backward(__first, __middle, __last); 2537 : return std::copy(__buffer, __buffer_end, __first); 2538 : } 2539 : else if (__len1 <= __buffer_size) 2540 : { 2541 : __buffer_end = std::copy(__first, __middle, __buffer); 2542 : std::copy(__middle, __last, __first); 2543 : return std::copy_backward(__buffer, __buffer_end, __last); 2544 : } 2545 : else 2546 : { 2547 : std::rotate(__first, __middle, __last); 2548 : std::advance(__first, std::distance(__middle, __last)); 2549 : return __first; 2550 : } 2551 : } 2552 : 2553 : /// This is a helper function for the merge routines. 2554 : template<typename _BidirectionalIterator, typename _Distance, 2555 : typename _Pointer> 2556 : void 2557 : __merge_adaptive(_BidirectionalIterator __first, 2558 : _BidirectionalIterator __middle, 2559 : _BidirectionalIterator __last, 2560 : _Distance __len1, _Distance __len2, 2561 : _Pointer __buffer, _Distance __buffer_size) 2562 : { 2563 : if (__len1 <= __len2 && __len1 <= __buffer_size) 2564 : { 2565 : _Pointer __buffer_end = std::copy(__first, __middle, __buffer); 2566 : _GLIBCXX_STD_P::merge(__buffer, __buffer_end, __middle, __last, 2567 : __first); 2568 : } 2569 : else if (__len2 <= __buffer_size) 2570 : { 2571 : _Pointer __buffer_end = std::copy(__middle, __last, __buffer); 2572 : std::__merge_backward(__first, __middle, __buffer, 2573 : __buffer_end, __last); 2574 : } 2575 : else 2576 : { 2577 : _BidirectionalIterator __first_cut = __first; 2578 : _BidirectionalIterator __second_cut = __middle; 2579 : _Distance __len11 = 0; 2580 : _Distance __len22 = 0; 2581 : if (__len1 > __len2) 2582 : { 2583 : __len11 = __len1 / 2; 2584 : std::advance(__first_cut, __len11); 2585 : __second_cut = std::lower_bound(__middle, __last, 2586 : *__first_cut); 2587 : __len22 = std::distance(__middle, __second_cut); 2588 : } 2589 : else 2590 : { 2591 : __len22 = __len2 / 2; 2592 : std::advance(__second_cut, __len22); 2593 : __first_cut = std::upper_bound(__first, __middle, 2594 : *__second_cut); 2595 : __len11 = std::distance(__first, __first_cut); 2596 : } 2597 : _BidirectionalIterator __new_middle = 2598 : std::__rotate_adaptive(__first_cut, __middle, __second_cut, 2599 : __len1 - __len11, __len22, __buffer, 2600 : __buffer_size); 2601 : std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, 2602 : __len22, __buffer, __buffer_size); 2603 : std::__merge_adaptive(__new_middle, __second_cut, __last, 2604 : __len1 - __len11, 2605 : __len2 - __len22, __buffer, __buffer_size); 2606 : } 2607 : } 2608 : 2609 : /// This is a helper function for the merge routines. 2610 : template<typename _BidirectionalIterator, typename _Distance, 2611 : typename _Pointer, typename _Compare> 2612 : void 2613 : __merge_adaptive(_BidirectionalIterator __first, 2614 : _BidirectionalIterator __middle, 2615 : _BidirectionalIterator __last, 2616 : _Distance __len1, _Distance __len2, 2617 : _Pointer __buffer, _Distance __buffer_size, 2618 : _Compare __comp) 2619 : { 2620 : if (__len1 <= __len2 && __len1 <= __buffer_size) 2621 : { 2622 : _Pointer __buffer_end = std::copy(__first, __middle, __buffer); 2623 : _GLIBCXX_STD_P::merge(__buffer, __buffer_end, __middle, __last, 2624 : __first, __comp); 2625 : } 2626 : else if (__len2 <= __buffer_size) 2627 : { 2628 : _Pointer __buffer_end = std::copy(__middle, __last, __buffer); 2629 : std::__merge_backward(__first, __middle, __buffer, __buffer_end, 2630 : __last, __comp); 2631 : } 2632 : else 2633 : { 2634 : _BidirectionalIterator __first_cut = __first; 2635 : _BidirectionalIterator __second_cut = __middle; 2636 : _Distance __len11 = 0; 2637 : _Distance __len22 = 0; 2638 : if (__len1 > __len2) 2639 : { 2640 : __len11 = __len1 / 2; 2641 : std::advance(__first_cut, __len11); 2642 : __second_cut = std::lower_bound(__middle, __last, *__first_cut, 2643 : __comp); 2644 : __len22 = std::distance(__middle, __second_cut); 2645 : } 2646 : else 2647 : { 2648 : __len22 = __len2 / 2; 2649 : std::advance(__second_cut, __len22); 2650 : __first_cut = std::upper_bound(__first, __middle, *__second_cut, 2651 : __comp); 2652 : __len11 = std::distance(__first, __first_cut); 2653 : } 2654 : _BidirectionalIterator __new_middle = 2655 : std::__rotate_adaptive(__first_cut, __middle, __second_cut, 2656 : __len1 - __len11, __len22, __buffer, 2657 : __buffer_size); 2658 : std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, 2659 : __len22, __buffer, __buffer_size, __comp); 2660 : std::__merge_adaptive(__new_middle, __second_cut, __last, 2661 : __len1 - __len11, 2662 : __len2 - __len22, __buffer, 2663 : __buffer_size, __comp); 2664 : } 2665 : } 2666 : 2667 : /// This is a helper function for the merge routines. 2668 : template<typename _BidirectionalIterator, typename _Distance> 2669 : void 2670 : __merge_without_buffer(_BidirectionalIterator __first, 2671 : _BidirectionalIterator __middle, 2672 : _BidirectionalIterator __last, 2673 : _Distance __len1, _Distance __len2) 2674 : { 2675 : if (__len1 == 0 || __len2 == 0) 2676 : return; 2677 : if (__len1 + __len2 == 2) 2678 : { 2679 : if (*__middle < *__first) 2680 : std::iter_swap(__first, __middle); 2681 : return; 2682 : } 2683 : _BidirectionalIterator __first_cut = __first; 2684 : _BidirectionalIterator __second_cut = __middle; 2685 : _Distance __len11 = 0; 2686 : _Distance __len22 = 0; 2687 : if (__len1 > __len2) 2688 : { 2689 : __len11 = __len1 / 2; 2690 : std::advance(__first_cut, __len11); 2691 : __second_cut = std::lower_bound(__middle, __last, *__first_cut); 2692 : __len22 = std::distance(__middle, __second_cut); 2693 : } 2694 : else 2695 : { 2696 : __len22 = __len2 / 2; 2697 : std::advance(__second_cut, __len22); 2698 : __first_cut = std::upper_bound(__first, __middle, *__second_cut); 2699 : __len11 = std::distance(__first, __first_cut); 2700 : } 2701 : std::rotate(__first_cut, __middle, __second_cut); 2702 : _BidirectionalIterator __new_middle = __first_cut; 2703 : std::advance(__new_middle, std::distance(__middle, __second_cut)); 2704 : std::__merge_without_buffer(__first, __first_cut, __new_middle, 2705 : __len11, __len22); 2706 : std::__merge_without_buffer(__new_middle, __second_cut, __last, 2707 : __len1 - __len11, __len2 - __len22); 2708 : } 2709 : 2710 : /// This is a helper function for the merge routines. 2711 : template<typename _BidirectionalIterator, typename _Distance, 2712 : typename _Compare> 2713 : void 2714 : __merge_without_buffer(_BidirectionalIterator __first, 2715 : _BidirectionalIterator __middle, 2716 : _BidirectionalIterator __last, 2717 : _Distance __len1, _Distance __len2, 2718 : _Compare __comp) 2719 : { 2720 : if (__len1 == 0 || __len2 == 0) 2721 : return; 2722 : if (__len1 + __len2 == 2) 2723 : { 2724 : if (__comp(*__middle, *__first)) 2725 : std::iter_swap(__first, __middle); 2726 : return; 2727 : } 2728 : _BidirectionalIterator __first_cut = __first; 2729 : _BidirectionalIterator __second_cut = __middle; 2730 : _Distance __len11 = 0; 2731 : _Distance __len22 = 0; 2732 : if (__len1 > __len2) 2733 : { 2734 : __len11 = __len1 / 2; 2735 : std::advance(__first_cut, __len11); 2736 : __second_cut = std::lower_bound(__middle, __last, *__first_cut, 2737 : __comp); 2738 : __len22 = std::distance(__middle, __second_cut); 2739 : } 2740 : else 2741 : { 2742 : __len22 = __len2 / 2; 2743 : std::advance(__second_cut, __len22); 2744 : __first_cut = std::upper_bound(__first, __middle, *__second_cut, 2745 : __comp); 2746 : __len11 = std::distance(__first, __first_cut); 2747 : } 2748 : std::rotate(__first_cut, __middle, __second_cut); 2749 : _BidirectionalIterator __new_middle = __first_cut; 2750 : std::advance(__new_middle, std::distance(__middle, __second_cut)); 2751 : std::__merge_without_buffer(__first, __first_cut, __new_middle, 2752 : __len11, __len22, __comp); 2753 : std::__merge_without_buffer(__new_middle, __second_cut, __last, 2754 : __len1 - __len11, __len2 - __len22, __comp); 2755 : } 2756 : 2757 : /** 2758 : * @brief Merges two sorted ranges in place. 2759 : * @param first An iterator. 2760 : * @param middle Another iterator. 2761 : * @param last Another iterator. 2762 : * @return Nothing. 2763 : * 2764 : * Merges two sorted and consecutive ranges, [first,middle) and 2765 : * [middle,last), and puts the result in [first,last). The output will 2766 : * be sorted. The sort is @e stable, that is, for equivalent 2767 : * elements in the two ranges, elements from the first range will always 2768 : * come before elements from the second. 2769 : * 2770 : * If enough additional memory is available, this takes (last-first)-1 2771 : * comparisons. Otherwise an NlogN algorithm is used, where N is 2772 : * distance(first,last). 2773 : */ 2774 : template<typename _BidirectionalIterator> 2775 : void 2776 : inplace_merge(_BidirectionalIterator __first, 2777 : _BidirectionalIterator __middle, 2778 : _BidirectionalIterator __last) 2779 : { 2780 : typedef typename iterator_traits<_BidirectionalIterator>::value_type 2781 : _ValueType; 2782 : typedef typename iterator_traits<_BidirectionalIterator>::difference_type 2783 : _DistanceType; 2784 : 2785 : // concept requirements 2786 : __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< 2787 : _BidirectionalIterator>) 2788 : __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 2789 : __glibcxx_requires_sorted(__first, __middle); 2790 : __glibcxx_requires_sorted(__middle, __last); 2791 : 2792 : if (__first == __middle || __middle == __last) 2793 : return; 2794 : 2795 : _DistanceType __len1 = std::distance(__first, __middle); 2796 : _DistanceType __len2 = std::distance(__middle, __last); 2797 : 2798 : _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, 2799 : __last); 2800 : if (__buf.begin() == 0) 2801 : std::__merge_without_buffer(__first, __middle, __last, __len1, __len2); 2802 : else 2803 : std::__merge_adaptive(__first, __middle, __last, __len1, __len2, 2804 : __buf.begin(), _DistanceType(__buf.size())); 2805 : } 2806 : 2807 : /** 2808 : * @brief Merges two sorted ranges in place. 2809 : * @param first An iterator. 2810 : * @param middle Another iterator. 2811 : * @param last Another iterator. 2812 : * @param comp A functor to use for comparisons. 2813 : * @return Nothing. 2814 : * 2815 : * Merges two sorted and consecutive ranges, [first,middle) and 2816 : * [middle,last), and puts the result in [first,last). The output will 2817 : * be sorted. The sort is @e stable, that is, for equivalent 2818 : * elements in the two ranges, elements from the first range will always 2819 : * come before elements from the second. 2820 : * 2821 : * If enough additional memory is available, this takes (last-first)-1 2822 : * comparisons. Otherwise an NlogN algorithm is used, where N is 2823 : * distance(first,last). 2824 : * 2825 : * The comparison function should have the same effects on ordering as 2826 : * the function used for the initial sort. 2827 : */ 2828 : template<typename _BidirectionalIterator, typename _Compare> 2829 : void 2830 : inplace_merge(_BidirectionalIterator __first, 2831 : _BidirectionalIterator __middle, 2832 : _BidirectionalIterator __last, 2833 : _Compare __comp) 2834 : { 2835 : typedef typename iterator_traits<_BidirectionalIterator>::value_type 2836 : _ValueType; 2837 : typedef typename iterator_traits<_BidirectionalIterator>::difference_type 2838 : _DistanceType; 2839 : 2840 : // concept requirements 2841 : __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< 2842 : _BidirectionalIterator>) 2843 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 2844 : _ValueType, _ValueType>) 2845 : __glibcxx_requires_sorted_pred(__first, __middle, __comp); 2846 : __glibcxx_requires_sorted_pred(__middle, __last, __comp); 2847 : 2848 : if (__first == __middle || __middle == __last) 2849 : return; 2850 : 2851 : const _DistanceType __len1 = std::distance(__first, __middle); 2852 : const _DistanceType __len2 = std::distance(__middle, __last); 2853 : 2854 : _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, 2855 : __last); 2856 : if (__buf.begin() == 0) 2857 : std::__merge_without_buffer(__first, __middle, __last, __len1, 2858 : __len2, __comp); 2859 : else 2860 : std::__merge_adaptive(__first, __middle, __last, __len1, __len2, 2861 : __buf.begin(), _DistanceType(__buf.size()), 2862 : __comp); 2863 : } 2864 : 2865 : template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, 2866 : typename _Distance> 2867 : void 2868 : __merge_sort_loop(_RandomAccessIterator1 __first, 2869 : _RandomAccessIterator1 __last, 2870 : _RandomAccessIterator2 __result, 2871 : _Distance __step_size) 2872 : { 2873 : const _Distance __two_step = 2 * __step_size; 2874 : 2875 : while (__last - __first >= __two_step) 2876 : { 2877 : __result = _GLIBCXX_STD_P::merge(__first, __first + __step_size, 2878 : __first + __step_size, 2879 : __first + __two_step, 2880 : __result); 2881 : __first += __two_step; 2882 : } 2883 : 2884 : __step_size = std::min(_Distance(__last - __first), __step_size); 2885 : _GLIBCXX_STD_P::merge(__first, __first + __step_size, 2886 : __first + __step_size, __last, 2887 : __result); 2888 : } 2889 : 2890 : template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, 2891 : typename _Distance, typename _Compare> 2892 : void 2893 : __merge_sort_loop(_RandomAccessIterator1 __first, 2894 : _RandomAccessIterator1 __last, 2895 : _RandomAccessIterator2 __result, _Distance __step_size, 2896 : _Compare __comp) 2897 : { 2898 : const _Distance __two_step = 2 * __step_size; 2899 : 2900 : while (__last - __first >= __two_step) 2901 : { 2902 : __result = _GLIBCXX_STD_P::merge(__first, __first + __step_size, 2903 : __first + __step_size, __first + __two_step, 2904 : __result, 2905 : __comp); 2906 : __first += __two_step; 2907 : } 2908 : __step_size = std::min(_Distance(__last - __first), __step_size); 2909 : 2910 : _GLIBCXX_STD_P::merge(__first, __first + __step_size, 2911 : __first + __step_size, __last, __result, __comp); 2912 : } 2913 : 2914 : template<typename _RandomAccessIterator, typename _Distance> 2915 : void 2916 : __chunk_insertion_sort(_RandomAccessIterator __first, 2917 : _RandomAccessIterator __last, 2918 : _Distance __chunk_size) 2919 : { 2920 : while (__last - __first >= __chunk_size) 2921 : { 2922 : std::__insertion_sort(__first, __first + __chunk_size); 2923 : __first += __chunk_size; 2924 : } 2925 : std::__insertion_sort(__first, __last); 2926 : } 2927 : 2928 : template<typename _RandomAccessIterator, typename _Distance, 2929 : typename _Compare> 2930 : void 2931 : __chunk_insertion_sort(_RandomAccessIterator __first, 2932 : _RandomAccessIterator __last, 2933 : _Distance __chunk_size, _Compare __comp) 2934 : { 2935 : while (__last - __first >= __chunk_size) 2936 : { 2937 : std::__insertion_sort(__first, __first + __chunk_size, __comp); 2938 : __first += __chunk_size; 2939 : } 2940 : std::__insertion_sort(__first, __last, __comp); 2941 : } 2942 : 2943 : enum { _S_chunk_size = 7 }; 2944 : 2945 : template<typename _RandomAccessIterator, typename _Pointer> 2946 : void 2947 : __merge_sort_with_buffer(_RandomAccessIterator __first, 2948 : _RandomAccessIterator __last, 2949 : _Pointer __buffer) 2950 : { 2951 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 2952 : _Distance; 2953 : 2954 : const _Distance __len = __last - __first; 2955 : const _Pointer __buffer_last = __buffer + __len; 2956 : 2957 : _Distance __step_size = _S_chunk_size; 2958 : std::__chunk_insertion_sort(__first, __last, __step_size); 2959 : 2960 : while (__step_size < __len) 2961 : { 2962 : std::__merge_sort_loop(__first, __last, __buffer, __step_size); 2963 : __step_size *= 2; 2964 : std::__merge_sort_loop(__buffer, __buffer_last, __first, __step_size); 2965 : __step_size *= 2; 2966 : } 2967 : } 2968 : 2969 : template<typename _RandomAccessIterator, typename _Pointer, typename _Compare> 2970 : void 2971 : __merge_sort_with_buffer(_RandomAccessIterator __first, 2972 : _RandomAccessIterator __last, 2973 : _Pointer __buffer, _Compare __comp) 2974 : { 2975 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 2976 : _Distance; 2977 : 2978 : const _Distance __len = __last - __first; 2979 : const _Pointer __buffer_last = __buffer + __len; 2980 : 2981 : _Distance __step_size = _S_chunk_size; 2982 : std::__chunk_insertion_sort(__first, __last, __step_size, __comp); 2983 : 2984 : while (__step_size < __len) 2985 : { 2986 : std::__merge_sort_loop(__first, __last, __buffer, 2987 : __step_size, __comp); 2988 : __step_size *= 2; 2989 : std::__merge_sort_loop(__buffer, __buffer_last, __first, 2990 : __step_size, __comp); 2991 : __step_size *= 2; 2992 : } 2993 : } 2994 : 2995 : template<typename _RandomAccessIterator, typename _Pointer, 2996 : typename _Distance> 2997 : void 2998 : __stable_sort_adaptive(_RandomAccessIterator __first, 2999 : _RandomAccessIterator __last, 3000 : _Pointer __buffer, _Distance __buffer_size) 3001 : { 3002 : const _Distance __len = (__last - __first + 1) / 2; 3003 : const _RandomAccessIterator __middle = __first + __len; 3004 : if (__len > __buffer_size) 3005 : { 3006 : std::__stable_sort_adaptive(__first, __middle, 3007 : __buffer, __buffer_size); 3008 : std::__stable_sort_adaptive(__middle, __last, 3009 : __buffer, __buffer_size); 3010 : } 3011 : else 3012 : { 3013 : std::__merge_sort_with_buffer(__first, __middle, __buffer); 3014 : std::__merge_sort_with_buffer(__middle, __last, __buffer); 3015 : } 3016 : std::__merge_adaptive(__first, __middle, __last, 3017 : _Distance(__middle - __first), 3018 : _Distance(__last - __middle), 3019 : __buffer, __buffer_size); 3020 : } 3021 : 3022 : template<typename _RandomAccessIterator, typename _Pointer, 3023 : typename _Distance, typename _Compare> 3024 : void 3025 : __stable_sort_adaptive(_RandomAccessIterator __first, 3026 : _RandomAccessIterator __last, 3027 : _Pointer __buffer, _Distance __buffer_size, 3028 : _Compare __comp) 3029 : { 3030 : const _Distance __len = (__last - __first + 1) / 2; 3031 : const _RandomAccessIterator __middle = __first + __len; 3032 : if (__len > __buffer_size) 3033 : { 3034 : std::__stable_sort_adaptive(__first, __middle, __buffer, 3035 : __buffer_size, __comp); 3036 : std::__stable_sort_adaptive(__middle, __last, __buffer, 3037 : __buffer_size, __comp); 3038 : } 3039 : else 3040 : { 3041 : std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp); 3042 : std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp); 3043 : } 3044 : std::__merge_adaptive(__first, __middle, __last, 3045 : _Distance(__middle - __first), 3046 : _Distance(__last - __middle), 3047 : __buffer, __buffer_size, 3048 : __comp); 3049 : } 3050 : 3051 : /// This is a helper function for the stable sorting routines. 3052 : template<typename _RandomAccessIterator> 3053 : void 3054 : __inplace_stable_sort(_RandomAccessIterator __first, 3055 : _RandomAccessIterator __last) 3056 : { 3057 : if (__last - __first < 15) 3058 : { 3059 : std::__insertion_sort(__first, __last); 3060 : return; 3061 : } 3062 : _RandomAccessIterator __middle = __first + (__last - __first) / 2; 3063 : std::__inplace_stable_sort(__first, __middle); 3064 : std::__inplace_stable_sort(__middle, __last); 3065 : std::__merge_without_buffer(__first, __middle, __last, 3066 : __middle - __first, 3067 : __last - __middle); 3068 : } 3069 : 3070 : /// This is a helper function for the stable sorting routines. 3071 : template<typename _RandomAccessIterator, typename _Compare> 3072 : void 3073 : __inplace_stable_sort(_RandomAccessIterator __first, 3074 : _RandomAccessIterator __last, _Compare __comp) 3075 : { 3076 : if (__last - __first < 15) 3077 : { 3078 : std::__insertion_sort(__first, __last, __comp); 3079 : return; 3080 : } 3081 : _RandomAccessIterator __middle = __first + (__last - __first) / 2; 3082 : std::__inplace_stable_sort(__first, __middle, __comp); 3083 : std::__inplace_stable_sort(__middle, __last, __comp); 3084 : std::__merge_without_buffer(__first, __middle, __last, 3085 : __middle - __first, 3086 : __last - __middle, 3087 : __comp); 3088 : } 3089 : 3090 : // stable_sort 3091 : 3092 : // Set algorithms: includes, set_union, set_intersection, set_difference, 3093 : // set_symmetric_difference. All of these algorithms have the precondition 3094 : // that their input ranges are sorted and the postcondition that their output 3095 : // ranges are sorted. 3096 : 3097 : /** 3098 : * @brief Determines whether all elements of a sequence exists in a range. 3099 : * @param first1 Start of search range. 3100 : * @param last1 End of search range. 3101 : * @param first2 Start of sequence 3102 : * @param last2 End of sequence. 3103 : * @return True if each element in [first2,last2) is contained in order 3104 : * within [first1,last1). False otherwise. 3105 : * @ingroup setoperations 3106 : * 3107 : * This operation expects both [first1,last1) and [first2,last2) to be 3108 : * sorted. Searches for the presence of each element in [first2,last2) 3109 : * within [first1,last1). The iterators over each range only move forward, 3110 : * so this is a linear algorithm. If an element in [first2,last2) is not 3111 : * found before the search iterator reaches @a last2, false is returned. 3112 : */ 3113 : template<typename _InputIterator1, typename _InputIterator2> 3114 : bool 3115 : includes(_InputIterator1 __first1, _InputIterator1 __last1, 3116 : _InputIterator2 __first2, _InputIterator2 __last2) 3117 : { 3118 : typedef typename iterator_traits<_InputIterator1>::value_type 3119 : _ValueType1; 3120 : typedef typename iterator_traits<_InputIterator2>::value_type 3121 : _ValueType2; 3122 : 3123 : // concept requirements 3124 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 3125 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 3126 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) 3127 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 3128 : __glibcxx_requires_sorted_set(__first1, __last1, __first2); 3129 : __glibcxx_requires_sorted_set(__first2, __last2, __first1); 3130 : 3131 : while (__first1 != __last1 && __first2 != __last2) 3132 : if (*__first2 < *__first1) 3133 : return false; 3134 : else if(*__first1 < *__first2) 3135 : ++__first1; 3136 : else 3137 : ++__first1, ++__first2; 3138 : 3139 : return __first2 == __last2; 3140 : } 3141 : 3142 : /** 3143 : * @brief Determines whether all elements of a sequence exists in a range 3144 : * using comparison. 3145 : * @param first1 Start of search range. 3146 : * @param last1 End of search range. 3147 : * @param first2 Start of sequence 3148 : * @param last2 End of sequence. 3149 : * @param comp Comparison function to use. 3150 : * @return True if each element in [first2,last2) is contained in order 3151 : * within [first1,last1) according to comp. False otherwise. 3152 : * @ingroup setoperations 3153 : * 3154 : * This operation expects both [first1,last1) and [first2,last2) to be 3155 : * sorted. Searches for the presence of each element in [first2,last2) 3156 : * within [first1,last1), using comp to decide. The iterators over each 3157 : * range only move forward, so this is a linear algorithm. If an element 3158 : * in [first2,last2) is not found before the search iterator reaches @a 3159 : * last2, false is returned. 3160 : */ 3161 : template<typename _InputIterator1, typename _InputIterator2, 3162 : typename _Compare> 3163 : bool 3164 : includes(_InputIterator1 __first1, _InputIterator1 __last1, 3165 : _InputIterator2 __first2, _InputIterator2 __last2, 3166 : _Compare __comp) 3167 : { 3168 : typedef typename iterator_traits<_InputIterator1>::value_type 3169 : _ValueType1; 3170 : typedef typename iterator_traits<_InputIterator2>::value_type 3171 : _ValueType2; 3172 : 3173 : // concept requirements 3174 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 3175 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 3176 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 3177 : _ValueType1, _ValueType2>) 3178 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 3179 : _ValueType2, _ValueType1>) 3180 : __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); 3181 : __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); 3182 : 3183 : while (__first1 != __last1 && __first2 != __last2) 3184 : if (__comp(*__first2, *__first1)) 3185 : return false; 3186 : else if(__comp(*__first1, *__first2)) 3187 : ++__first1; 3188 : else 3189 : ++__first1, ++__first2; 3190 : 3191 : return __first2 == __last2; 3192 : } 3193 : 3194 : // nth_element 3195 : // merge 3196 : // set_difference 3197 : // set_intersection 3198 : // set_union 3199 : // stable_sort 3200 : // set_symmetric_difference 3201 : // min_element 3202 : // max_element 3203 : 3204 : /** 3205 : * @brief Permute range into the next "dictionary" ordering. 3206 : * @param first Start of range. 3207 : * @param last End of range. 3208 : * @return False if wrapped to first permutation, true otherwise. 3209 : * 3210 : * Treats all permutations of the range as a set of "dictionary" sorted 3211 : * sequences. Permutes the current sequence into the next one of this set. 3212 : * Returns true if there are more sequences to generate. If the sequence 3213 : * is the largest of the set, the smallest is generated and false returned. 3214 : */ 3215 : template<typename _BidirectionalIterator> 3216 : bool 3217 : next_permutation(_BidirectionalIterator __first, 3218 : _BidirectionalIterator __last) 3219 : { 3220 : // concept requirements 3221 : __glibcxx_function_requires(_BidirectionalIteratorConcept< 3222 : _BidirectionalIterator>) 3223 : __glibcxx_function_requires(_LessThanComparableConcept< 3224 : typename iterator_traits<_BidirectionalIterator>::value_type>) 3225 : __glibcxx_requires_valid_range(__first, __last); 3226 : 3227 : if (__first == __last) 3228 : return false; 3229 : _BidirectionalIterator __i = __first; 3230 : ++__i; 3231 : if (__i == __last) 3232 : return false; 3233 : __i = __last; 3234 : --__i; 3235 : 3236 : for(;;) 3237 : { 3238 : _BidirectionalIterator __ii = __i; 3239 : --__i; 3240 : if (*__i < *__ii) 3241 : { 3242 : _BidirectionalIterator __j = __last; 3243 : while (!(*__i < *--__j)) 3244 : {} 3245 : std::iter_swap(__i, __j); 3246 : std::reverse(__ii, __last); 3247 : return true; 3248 : } 3249 : if (__i == __first) 3250 : { 3251 : std::reverse(__first, __last); 3252 : return false; 3253 : } 3254 : } 3255 : } 3256 : 3257 : /** 3258 : * @brief Permute range into the next "dictionary" ordering using 3259 : * comparison functor. 3260 : * @param first Start of range. 3261 : * @param last End of range. 3262 : * @param comp A comparison functor. 3263 : * @return False if wrapped to first permutation, true otherwise. 3264 : * 3265 : * Treats all permutations of the range [first,last) as a set of 3266 : * "dictionary" sorted sequences ordered by @a comp. Permutes the current 3267 : * sequence into the next one of this set. Returns true if there are more 3268 : * sequences to generate. If the sequence is the largest of the set, the 3269 : * smallest is generated and false returned. 3270 : */ 3271 : template<typename _BidirectionalIterator, typename _Compare> 3272 : bool 3273 : next_permutation(_BidirectionalIterator __first, 3274 : _BidirectionalIterator __last, _Compare __comp) 3275 : { 3276 : // concept requirements 3277 : __glibcxx_function_requires(_BidirectionalIteratorConcept< 3278 : _BidirectionalIterator>) 3279 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 3280 : typename iterator_traits<_BidirectionalIterator>::value_type, 3281 : typename iterator_traits<_BidirectionalIterator>::value_type>) 3282 : __glibcxx_requires_valid_range(__first, __last); 3283 : 3284 : if (__first == __last) 3285 : return false; 3286 : _BidirectionalIterator __i = __first; 3287 : ++__i; 3288 : if (__i == __last) 3289 : return false; 3290 : __i = __last; 3291 : --__i; 3292 : 3293 : for(;;) 3294 : { 3295 : _BidirectionalIterator __ii = __i; 3296 : --__i; 3297 : if (__comp(*__i, *__ii)) 3298 : { 3299 : _BidirectionalIterator __j = __last; 3300 : while (!bool(__comp(*__i, *--__j))) 3301 : {} 3302 : std::iter_swap(__i, __j); 3303 : std::reverse(__ii, __last); 3304 : return true; 3305 : } 3306 : if (__i == __first) 3307 : { 3308 : std::reverse(__first, __last); 3309 : return false; 3310 : } 3311 : } 3312 : } 3313 : 3314 : /** 3315 : * @brief Permute range into the previous "dictionary" ordering. 3316 : * @param first Start of range. 3317 : * @param last End of range. 3318 : * @return False if wrapped to last permutation, true otherwise. 3319 : * 3320 : * Treats all permutations of the range as a set of "dictionary" sorted 3321 : * sequences. Permutes the current sequence into the previous one of this 3322 : * set. Returns true if there are more sequences to generate. If the 3323 : * sequence is the smallest of the set, the largest is generated and false 3324 : * returned. 3325 : */ 3326 : template<typename _BidirectionalIterator> 3327 : bool 3328 : prev_permutation(_BidirectionalIterator __first, 3329 : _BidirectionalIterator __last) 3330 : { 3331 : // concept requirements 3332 : __glibcxx_function_requires(_BidirectionalIteratorConcept< 3333 : _BidirectionalIterator>) 3334 : __glibcxx_function_requires(_LessThanComparableConcept< 3335 : typename iterator_traits<_BidirectionalIterator>::value_type>) 3336 : __glibcxx_requires_valid_range(__first, __last); 3337 : 3338 : if (__first == __last) 3339 : return false; 3340 : _BidirectionalIterator __i = __first; 3341 : ++__i; 3342 : if (__i == __last) 3343 : return false; 3344 : __i = __last; 3345 : --__i; 3346 : 3347 : for(;;) 3348 : { 3349 : _BidirectionalIterator __ii = __i; 3350 : --__i; 3351 : if (*__ii < *__i) 3352 : { 3353 : _BidirectionalIterator __j = __last; 3354 : while (!(*--__j < *__i)) 3355 : {} 3356 : std::iter_swap(__i, __j); 3357 : std::reverse(__ii, __last); 3358 : return true; 3359 : } 3360 : if (__i == __first) 3361 : { 3362 : std::reverse(__first, __last); 3363 : return false; 3364 : } 3365 : } 3366 : } 3367 : 3368 : /** 3369 : * @brief Permute range into the previous "dictionary" ordering using 3370 : * comparison functor. 3371 : * @param first Start of range. 3372 : * @param last End of range. 3373 : * @param comp A comparison functor. 3374 : * @return False if wrapped to last permutation, true otherwise. 3375 : * 3376 : * Treats all permutations of the range [first,last) as a set of 3377 : * "dictionary" sorted sequences ordered by @a comp. Permutes the current 3378 : * sequence into the previous one of this set. Returns true if there are 3379 : * more sequences to generate. If the sequence is the smallest of the set, 3380 : * the largest is generated and false returned. 3381 : */ 3382 : template<typename _BidirectionalIterator, typename _Compare> 3383 : bool 3384 : prev_permutation(_BidirectionalIterator __first, 3385 : _BidirectionalIterator __last, _Compare __comp) 3386 : { 3387 : // concept requirements 3388 : __glibcxx_function_requires(_BidirectionalIteratorConcept< 3389 : _BidirectionalIterator>) 3390 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 3391 : typename iterator_traits<_BidirectionalIterator>::value_type, 3392 : typename iterator_traits<_BidirectionalIterator>::value_type>) 3393 : __glibcxx_requires_valid_range(__first, __last); 3394 : 3395 : if (__first == __last) 3396 : return false; 3397 : _BidirectionalIterator __i = __first; 3398 : ++__i; 3399 : if (__i == __last) 3400 : return false; 3401 : __i = __last; 3402 : --__i; 3403 : 3404 : for(;;) 3405 : { 3406 : _BidirectionalIterator __ii = __i; 3407 : --__i; 3408 : if (__comp(*__ii, *__i)) 3409 : { 3410 : _BidirectionalIterator __j = __last; 3411 : while (!bool(__comp(*--__j, *__i))) 3412 : {} 3413 : std::iter_swap(__i, __j); 3414 : std::reverse(__ii, __last); 3415 : return true; 3416 : } 3417 : if (__i == __first) 3418 : { 3419 : std::reverse(__first, __last); 3420 : return false; 3421 : } 3422 : } 3423 : } 3424 : 3425 : // replace 3426 : // replace_if 3427 : 3428 : /** 3429 : * @brief Copy a sequence, replacing each element of one value with another 3430 : * value. 3431 : * @param first An input iterator. 3432 : * @param last An input iterator. 3433 : * @param result An output iterator. 3434 : * @param old_value The value to be replaced. 3435 : * @param new_value The replacement value. 3436 : * @return The end of the output sequence, @p result+(last-first). 3437 : * 3438 : * Copies each element in the input range @p [first,last) to the 3439 : * output range @p [result,result+(last-first)) replacing elements 3440 : * equal to @p old_value with @p new_value. 3441 : */ 3442 : template<typename _InputIterator, typename _OutputIterator, typename _Tp> 3443 : _OutputIterator 3444 : replace_copy(_InputIterator __first, _InputIterator __last, 3445 : _OutputIterator __result, 3446 : const _Tp& __old_value, const _Tp& __new_value) 3447 : { 3448 : // concept requirements 3449 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 3450 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 3451 : typename iterator_traits<_InputIterator>::value_type>) 3452 : __glibcxx_function_requires(_EqualOpConcept< 3453 : typename iterator_traits<_InputIterator>::value_type, _Tp>) 3454 : __glibcxx_requires_valid_range(__first, __last); 3455 : 3456 : for (; __first != __last; ++__first, ++__result) 3457 : if (*__first == __old_value) 3458 : *__result = __new_value; 3459 : else 3460 : *__result = *__first; 3461 : return __result; 3462 : } 3463 : 3464 : /** 3465 : * @brief Copy a sequence, replacing each value for which a predicate 3466 : * returns true with another value. 3467 : * @param first An input iterator. 3468 : * @param last An input iterator. 3469 : * @param result An output iterator. 3470 : * @param pred A predicate. 3471 : * @param new_value The replacement value. 3472 : * @return The end of the output sequence, @p result+(last-first). 3473 : * 3474 : * Copies each element in the range @p [first,last) to the range 3475 : * @p [result,result+(last-first)) replacing elements for which 3476 : * @p pred returns true with @p new_value. 3477 : */ 3478 : template<typename _InputIterator, typename _OutputIterator, 3479 : typename _Predicate, typename _Tp> 3480 : _OutputIterator 3481 : replace_copy_if(_InputIterator __first, _InputIterator __last, 3482 : _OutputIterator __result, 3483 : _Predicate __pred, const _Tp& __new_value) 3484 : { 3485 : // concept requirements 3486 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 3487 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 3488 : typename iterator_traits<_InputIterator>::value_type>) 3489 : __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 3490 : typename iterator_traits<_InputIterator>::value_type>) 3491 : __glibcxx_requires_valid_range(__first, __last); 3492 : 3493 : for (; __first != __last; ++__first, ++__result) 3494 : if (__pred(*__first)) 3495 : *__result = __new_value; 3496 : else 3497 : *__result = *__first; 3498 : return __result; 3499 : } 3500 : 3501 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 3502 : /** 3503 : * @brief Determines whether the elements of a sequence are sorted. 3504 : * @param first An iterator. 3505 : * @param last Another iterator. 3506 : * @return True if the elements are sorted, false otherwise. 3507 : */ 3508 : template<typename _ForwardIterator> 3509 : inline bool 3510 : is_sorted(_ForwardIterator __first, _ForwardIterator __last) 3511 : { return std::is_sorted_until(__first, __last) == __last; } 3512 : 3513 : /** 3514 : * @brief Determines whether the elements of a sequence are sorted 3515 : * according to a comparison functor. 3516 : * @param first An iterator. 3517 : * @param last Another iterator. 3518 : * @param comp A comparison functor. 3519 : * @return True if the elements are sorted, false otherwise. 3520 : */ 3521 : template<typename _ForwardIterator, typename _Compare> 3522 : inline bool 3523 : is_sorted(_ForwardIterator __first, _ForwardIterator __last, 3524 : _Compare __comp) 3525 : { return std::is_sorted_until(__first, __last, __comp) == __last; } 3526 : 3527 : /** 3528 : * @brief Determines the end of a sorted sequence. 3529 : * @param first An iterator. 3530 : * @param last Another iterator. 3531 : * @return An iterator pointing to the last iterator i in [first, last) 3532 : * for which the range [first, i) is sorted. 3533 : */ 3534 : template<typename _ForwardIterator> 3535 : _ForwardIterator 3536 : is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) 3537 : { 3538 : // concept requirements 3539 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 3540 : __glibcxx_function_requires(_LessThanComparableConcept< 3541 : typename iterator_traits<_ForwardIterator>::value_type>) 3542 : __glibcxx_requires_valid_range(__first, __last); 3543 : 3544 : if (__first == __last) 3545 : return __last; 3546 : 3547 : _ForwardIterator __next = __first; 3548 : for (++__next; __next != __last; __first = __next, ++__next) 3549 : if (*__next < *__first) 3550 : return __next; 3551 : return __next; 3552 : } 3553 : 3554 : /** 3555 : * @brief Determines the end of a sorted sequence using comparison functor. 3556 : * @param first An iterator. 3557 : * @param last Another iterator. 3558 : * @param comp A comparison functor. 3559 : * @return An iterator pointing to the last iterator i in [first, last) 3560 : * for which the range [first, i) is sorted. 3561 : */ 3562 : template<typename _ForwardIterator, typename _Compare> 3563 : _ForwardIterator 3564 : is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, 3565 : _Compare __comp) 3566 : { 3567 : // concept requirements 3568 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 3569 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 3570 : typename iterator_traits<_ForwardIterator>::value_type, 3571 : typename iterator_traits<_ForwardIterator>::value_type>) 3572 : __glibcxx_requires_valid_range(__first, __last); 3573 : 3574 : if (__first == __last) 3575 : return __last; 3576 : 3577 : _ForwardIterator __next = __first; 3578 : for (++__next; __next != __last; __first = __next, ++__next) 3579 : if (__comp(*__next, *__first)) 3580 : return __next; 3581 : return __next; 3582 : } 3583 : 3584 : /** 3585 : * @brief Determines min and max at once as an ordered pair. 3586 : * @param a A thing of arbitrary type. 3587 : * @param b Another thing of arbitrary type. 3588 : * @return A pair(b, a) if b is smaller than a, pair(a, b) otherwise. 3589 : */ 3590 : template<typename _Tp> 3591 : inline pair<const _Tp&, const _Tp&> 3592 : minmax(const _Tp& __a, const _Tp& __b) 3593 : { 3594 : // concept requirements 3595 : __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) 3596 : 3597 : return __b < __a ? pair<const _Tp&, const _Tp&>(__b, __a) 3598 : : pair<const _Tp&, const _Tp&>(__a, __b); 3599 : } 3600 : 3601 : /** 3602 : * @brief Determines min and max at once as an ordered pair. 3603 : * @param a A thing of arbitrary type. 3604 : * @param b Another thing of arbitrary type. 3605 : * @param comp A @link s20_3_3_comparisons comparison functor@endlink. 3606 : * @return A pair(b, a) if b is smaller than a, pair(a, b) otherwise. 3607 : */ 3608 : template<typename _Tp, typename _Compare> 3609 : inline pair<const _Tp&, const _Tp&> 3610 : minmax(const _Tp& __a, const _Tp& __b, _Compare __comp) 3611 : { 3612 : return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) 3613 : : pair<const _Tp&, const _Tp&>(__a, __b); 3614 : } 3615 : 3616 : /** 3617 : * @brief Return a pair of iterators pointing to the minimum and maximum 3618 : * elements in a range. 3619 : * @param first Start of range. 3620 : * @param last End of range. 3621 : * @return make_pair(m, M), where m is the first iterator i in 3622 : * [first, last) such that no other element in the range is 3623 : * smaller, and where M is the last iterator i in [first, last) 3624 : * such that no other element in the range is larger. 3625 : */ 3626 : template<typename _ForwardIterator> 3627 : pair<_ForwardIterator, _ForwardIterator> 3628 : minmax_element(_ForwardIterator __first, _ForwardIterator __last) 3629 : { 3630 : // concept requirements 3631 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 3632 : __glibcxx_function_requires(_LessThanComparableConcept< 3633 : typename iterator_traits<_ForwardIterator>::value_type>) 3634 : __glibcxx_requires_valid_range(__first, __last); 3635 : 3636 : _ForwardIterator __next = __first; 3637 : if (__first == __last 3638 : || ++__next == __last) 3639 : return std::make_pair(__first, __first); 3640 : 3641 : _ForwardIterator __min, __max; 3642 : if (*__next < *__first) 3643 : { 3644 : __min = __next; 3645 : __max = __first; 3646 : } 3647 : else 3648 : { 3649 : __min = __first; 3650 : __max = __next; 3651 : } 3652 : 3653 : __first = __next; 3654 : ++__first; 3655 : 3656 : while (__first != __last) 3657 : { 3658 : __next = __first; 3659 : if (++__next == __last) 3660 : { 3661 : if (*__first < *__min) 3662 : __min = __first; 3663 : else if (!(*__first < *__max)) 3664 : __max = __first; 3665 : break; 3666 : } 3667 : 3668 : if (*__next < *__first) 3669 : { 3670 : if (*__next < *__min) 3671 : __min = __next; 3672 : if (!(*__first < *__max)) 3673 : __max = __first; 3674 : } 3675 : else 3676 : { 3677 : if (*__first < *__min) 3678 : __min = __first; 3679 : if (!(*__next < *__max)) 3680 : __max = __next; 3681 : } 3682 : 3683 : __first = __next; 3684 : ++__first; 3685 : } 3686 : 3687 : return std::make_pair(__min, __max); 3688 : } 3689 : 3690 : /** 3691 : * @brief Return a pair of iterators pointing to the minimum and maximum 3692 : * elements in a range. 3693 : * @param first Start of range. 3694 : * @param last End of range. 3695 : * @param comp Comparison functor. 3696 : * @return make_pair(m, M), where m is the first iterator i in 3697 : * [first, last) such that no other element in the range is 3698 : * smaller, and where M is the last iterator i in [first, last) 3699 : * such that no other element in the range is larger. 3700 : */ 3701 : template<typename _ForwardIterator, typename _Compare> 3702 : pair<_ForwardIterator, _ForwardIterator> 3703 : minmax_element(_ForwardIterator __first, _ForwardIterator __last, 3704 : _Compare __comp) 3705 : { 3706 : // concept requirements 3707 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 3708 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 3709 : typename iterator_traits<_ForwardIterator>::value_type, 3710 : typename iterator_traits<_ForwardIterator>::value_type>) 3711 : __glibcxx_requires_valid_range(__first, __last); 3712 : 3713 : _ForwardIterator __next = __first; 3714 : if (__first == __last 3715 : || ++__next == __last) 3716 : return std::make_pair(__first, __first); 3717 : 3718 : _ForwardIterator __min, __max; 3719 : if (__comp(*__next, *__first)) 3720 : { 3721 : __min = __next; 3722 : __max = __first; 3723 : } 3724 : else 3725 : { 3726 : __min = __first; 3727 : __max = __next; 3728 : } 3729 : 3730 : __first = __next; 3731 : ++__first; 3732 : 3733 : while (__first != __last) 3734 : { 3735 : __next = __first; 3736 : if (++__next == __last) 3737 : { 3738 : if (__comp(*__first, *__min)) 3739 : __min = __first; 3740 : else if (!__comp(*__first, *__max)) 3741 : __max = __first; 3742 : break; 3743 : } 3744 : 3745 : if (__comp(*__next, *__first)) 3746 : { 3747 : if (__comp(*__next, *__min)) 3748 : __min = __next; 3749 : if (!__comp(*__first, *__max)) 3750 : __max = __first; 3751 : } 3752 : else 3753 : { 3754 : if (__comp(*__first, *__min)) 3755 : __min = __first; 3756 : if (!__comp(*__next, *__max)) 3757 : __max = __next; 3758 : } 3759 : 3760 : __first = __next; 3761 : ++__first; 3762 : } 3763 : 3764 : return std::make_pair(__min, __max); 3765 : } 3766 : #endif // __GXX_EXPERIMENTAL_CXX0X__ 3767 : 3768 : _GLIBCXX_END_NAMESPACE 3769 : 3770 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P) 3771 : 3772 : /** 3773 : * @brief Apply a function to every element of a sequence. 3774 : * @param first An input iterator. 3775 : * @param last An input iterator. 3776 : * @param f A unary function object. 3777 : * @return @p f. 3778 : * 3779 : * Applies the function object @p f to each element in the range 3780 : * @p [first,last). @p f must not modify the order of the sequence. 3781 : * If @p f has a return value it is ignored. 3782 : */ 3783 : template<typename _InputIterator, typename _Function> 3784 : _Function 3785 : for_each(_InputIterator __first, _InputIterator __last, _Function __f) 3786 : { 3787 : // concept requirements 3788 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 3789 : __glibcxx_requires_valid_range(__first, __last); 3790 : for (; __first != __last; ++__first) 3791 : __f(*__first); 3792 : return __f; 3793 : } 3794 : 3795 : /** 3796 : * @brief Find the first occurrence of a value in a sequence. 3797 : * @param first An input iterator. 3798 : * @param last An input iterator. 3799 : * @param val The value to find. 3800 : * @return The first iterator @c i in the range @p [first,last) 3801 : * such that @c *i == @p val, or @p last if no such iterator exists. 3802 : */ 3803 : template<typename _InputIterator, typename _Tp> 3804 : inline _InputIterator 3805 : find(_InputIterator __first, _InputIterator __last, 3806 3362 : const _Tp& __val) 3807 : { 3808 : // concept requirements 3809 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 3810 : __glibcxx_function_requires(_EqualOpConcept< 3811 : typename iterator_traits<_InputIterator>::value_type, _Tp>) 3812 : __glibcxx_requires_valid_range(__first, __last); 3813 : return std::__find(__first, __last, __val, 3814 3362 : std::__iterator_category(__first)); 3815 : } 3816 : 3817 : /** 3818 : * @brief Find the first element in a sequence for which a 3819 : * predicate is true. 3820 : * @param first An input iterator. 3821 : * @param last An input iterator. 3822 : * @param pred A predicate. 3823 : * @return The first iterator @c i in the range @p [first,last) 3824 : * such that @p pred(*i) is true, or @p last if no such iterator exists. 3825 : */ 3826 : template<typename _InputIterator, typename _Predicate> 3827 : inline _InputIterator 3828 : find_if(_InputIterator __first, _InputIterator __last, 3829 3 : _Predicate __pred) 3830 : { 3831 : // concept requirements 3832 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 3833 : __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 3834 : typename iterator_traits<_InputIterator>::value_type>) 3835 : __glibcxx_requires_valid_range(__first, __last); 3836 : return std::__find_if(__first, __last, __pred, 3837 3 : std::__iterator_category(__first)); 3838 : } 3839 : 3840 : /** 3841 : * @brief Find element from a set in a sequence. 3842 : * @param first1 Start of range to search. 3843 : * @param last1 End of range to search. 3844 : * @param first2 Start of match candidates. 3845 : * @param last2 End of match candidates. 3846 : * @return The first iterator @c i in the range 3847 : * @p [first1,last1) such that @c *i == @p *(i2) such that i2 is an 3848 : * iterator in [first2,last2), or @p last1 if no such iterator exists. 3849 : * 3850 : * Searches the range @p [first1,last1) for an element that is equal to 3851 : * some element in the range [first2,last2). If found, returns an iterator 3852 : * in the range [first1,last1), otherwise returns @p last1. 3853 : */ 3854 : template<typename _InputIterator, typename _ForwardIterator> 3855 : _InputIterator 3856 : find_first_of(_InputIterator __first1, _InputIterator __last1, 3857 : _ForwardIterator __first2, _ForwardIterator __last2) 3858 : { 3859 : // concept requirements 3860 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 3861 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 3862 : __glibcxx_function_requires(_EqualOpConcept< 3863 : typename iterator_traits<_InputIterator>::value_type, 3864 : typename iterator_traits<_ForwardIterator>::value_type>) 3865 : __glibcxx_requires_valid_range(__first1, __last1); 3866 : __glibcxx_requires_valid_range(__first2, __last2); 3867 : 3868 : for (; __first1 != __last1; ++__first1) 3869 : for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) 3870 : if (*__first1 == *__iter) 3871 : return __first1; 3872 : return __last1; 3873 : } 3874 : 3875 : /** 3876 : * @brief Find element from a set in a sequence using a predicate. 3877 : * @param first1 Start of range to search. 3878 : * @param last1 End of range to search. 3879 : * @param first2 Start of match candidates. 3880 : * @param last2 End of match candidates. 3881 : * @param comp Predicate to use. 3882 : * @return The first iterator @c i in the range 3883 : * @p [first1,last1) such that @c comp(*i, @p *(i2)) is true and i2 is an 3884 : * iterator in [first2,last2), or @p last1 if no such iterator exists. 3885 : * 3886 : 3887 : * Searches the range @p [first1,last1) for an element that is 3888 : * equal to some element in the range [first2,last2). If found, 3889 : * returns an iterator in the range [first1,last1), otherwise 3890 : * returns @p last1. 3891 : */ 3892 : template<typename _InputIterator, typename _ForwardIterator, 3893 : typename _BinaryPredicate> 3894 : _InputIterator 3895 : find_first_of(_InputIterator __first1, _InputIterator __last1, 3896 : _ForwardIterator __first2, _ForwardIterator __last2, 3897 : _BinaryPredicate __comp) 3898 : { 3899 : // concept requirements 3900 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 3901 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 3902 : __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 3903 : typename iterator_traits<_InputIterator>::value_type, 3904 : typename iterator_traits<_ForwardIterator>::value_type>) 3905 : __glibcxx_requires_valid_range(__first1, __last1); 3906 : __glibcxx_requires_valid_range(__first2, __last2); 3907 : 3908 : for (; __first1 != __last1; ++__first1) 3909 : for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) 3910 : if (__comp(*__first1, *__iter)) 3911 : return __first1; 3912 : return __last1; 3913 : } 3914 : 3915 : /** 3916 : * @brief Find two adjacent values in a sequence that are equal. 3917 : * @param first A forward iterator. 3918 : * @param last A forward iterator. 3919 : * @return The first iterator @c i such that @c i and @c i+1 are both 3920 : * valid iterators in @p [first,last) and such that @c *i == @c *(i+1), 3921 : * or @p last if no such iterator exists. 3922 : */ 3923 : template<typename _ForwardIterator> 3924 : _ForwardIterator 3925 : adjacent_find(_ForwardIterator __first, _ForwardIterator __last) 3926 : { 3927 : // concept requirements 3928 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 3929 : __glibcxx_function_requires(_EqualityComparableConcept< 3930 : typename iterator_traits<_ForwardIterator>::value_type>) 3931 : __glibcxx_requires_valid_range(__first, __last); 3932 : if (__first == __last) 3933 : return __last; 3934 : _ForwardIterator __next = __first; 3935 : while(++__next != __last) 3936 : { 3937 : if (*__first == *__next) 3938 : return __first; 3939 : __first = __next; 3940 : } 3941 : return __last; 3942 : } 3943 : 3944 : /** 3945 : * @brief Find two adjacent values in a sequence using a predicate. 3946 : * @param first A forward iterator. 3947 : * @param last A forward iterator. 3948 : * @param binary_pred A binary predicate. 3949 : * @return The first iterator @c i such that @c i and @c i+1 are both 3950 : * valid iterators in @p [first,last) and such that 3951 : * @p binary_pred(*i,*(i+1)) is true, or @p last if no such iterator 3952 : * exists. 3953 : */ 3954 : template<typename _ForwardIterator, typename _BinaryPredicate> 3955 : _ForwardIterator 3956 : adjacent_find(_ForwardIterator __first, _ForwardIterator __last, 3957 : _BinaryPredicate __binary_pred) 3958 : { 3959 : // concept requirements 3960 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 3961 : __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 3962 : typename iterator_traits<_ForwardIterator>::value_type, 3963 : typename iterator_traits<_ForwardIterator>::value_type>) 3964 : __glibcxx_requires_valid_range(__first, __last); 3965 : if (__first == __last) 3966 : return __last; 3967 : _ForwardIterator __next = __first; 3968 : while(++__next != __last) 3969 : { 3970 : if (__binary_pred(*__first, *__next)) 3971 : return __first; 3972 : __first = __next; 3973 : } 3974 : return __last; 3975 : } 3976 : 3977 : /** 3978 : * @brief Count the number of copies of a value in a sequence. 3979 : * @param first An input iterator. 3980 : * @param last An input iterator. 3981 : * @param value The value to be counted. 3982 : * @return The number of iterators @c i in the range @p [first,last) 3983 : * for which @c *i == @p value 3984 : */ 3985 : template<typename _InputIterator, typename _Tp> 3986 : typename iterator_traits<_InputIterator>::difference_type 3987 : count(_InputIterator __first, _InputIterator __last, const _Tp& __value) 3988 : { 3989 : // concept requirements 3990 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 3991 : __glibcxx_function_requires(_EqualOpConcept< 3992 : typename iterator_traits<_InputIterator>::value_type, _Tp>) 3993 : __glibcxx_requires_valid_range(__first, __last); 3994 : typename iterator_traits<_InputIterator>::difference_type __n = 0; 3995 : for (; __first != __last; ++__first) 3996 : if (*__first == __value) 3997 : ++__n; 3998 : return __n; 3999 : } 4000 : 4001 : /** 4002 : * @brief Count the elements of a sequence for which a predicate is true. 4003 : * @param first An input iterator. 4004 : * @param last An input iterator. 4005 : * @param pred A predicate. 4006 : * @return The number of iterators @c i in the range @p [first,last) 4007 : * for which @p pred(*i) is true. 4008 : */ 4009 : template<typename _InputIterator, typename _Predicate> 4010 : typename iterator_traits<_InputIterator>::difference_type 4011 : count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) 4012 : { 4013 : // concept requirements 4014 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 4015 : __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 4016 : typename iterator_traits<_InputIterator>::value_type>) 4017 : __glibcxx_requires_valid_range(__first, __last); 4018 : typename iterator_traits<_InputIterator>::difference_type __n = 0; 4019 : for (; __first != __last; ++__first) 4020 : if (__pred(*__first)) 4021 : ++__n; 4022 : return __n; 4023 : } 4024 : 4025 : /** 4026 : * @brief Search a sequence for a matching sub-sequence. 4027 : * @param first1 A forward iterator. 4028 : * @param last1 A forward iterator. 4029 : * @param first2 A forward iterator. 4030 : * @param last2 A forward iterator. 4031 : * @return The first iterator @c i in the range 4032 : * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N) 4033 : * for each @c N in the range @p [0,last2-first2), or @p last1 if no 4034 : * such iterator exists. 4035 : * 4036 : * Searches the range @p [first1,last1) for a sub-sequence that compares 4037 : * equal value-by-value with the sequence given by @p [first2,last2) and 4038 : * returns an iterator to the first element of the sub-sequence, or 4039 : * @p last1 if the sub-sequence is not found. 4040 : * 4041 : * Because the sub-sequence must lie completely within the range 4042 : * @p [first1,last1) it must start at a position less than 4043 : * @p last1-(last2-first2) where @p last2-first2 is the length of the 4044 : * sub-sequence. 4045 : * This means that the returned iterator @c i will be in the range 4046 : * @p [first1,last1-(last2-first2)) 4047 : */ 4048 : template<typename _ForwardIterator1, typename _ForwardIterator2> 4049 : _ForwardIterator1 4050 : search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 4051 : _ForwardIterator2 __first2, _ForwardIterator2 __last2) 4052 : { 4053 : // concept requirements 4054 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) 4055 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) 4056 : __glibcxx_function_requires(_EqualOpConcept< 4057 : typename iterator_traits<_ForwardIterator1>::value_type, 4058 : typename iterator_traits<_ForwardIterator2>::value_type>) 4059 : __glibcxx_requires_valid_range(__first1, __last1); 4060 : __glibcxx_requires_valid_range(__first2, __last2); 4061 : 4062 : // Test for empty ranges 4063 : if (__first1 == __last1 || __first2 == __last2) 4064 : return __first1; 4065 : 4066 : // Test for a pattern of length 1. 4067 : _ForwardIterator2 __p1(__first2); 4068 : if (++__p1 == __last2) 4069 : return _GLIBCXX_STD_P::find(__first1, __last1, *__first2); 4070 : 4071 : // General case. 4072 : _ForwardIterator2 __p; 4073 : _ForwardIterator1 __current = __first1; 4074 : 4075 : for (;;) 4076 : { 4077 : __first1 = _GLIBCXX_STD_P::find(__first1, __last1, *__first2); 4078 : if (__first1 == __last1) 4079 : return __last1; 4080 : 4081 : __p = __p1; 4082 : __current = __first1; 4083 : if (++__current == __last1) 4084 : return __last1; 4085 : 4086 : while (*__current == *__p) 4087 : { 4088 : if (++__p == __last2) 4089 : return __first1; 4090 : if (++__current == __last1) 4091 : return __last1; 4092 : } 4093 : ++__first1; 4094 : } 4095 : return __first1; 4096 : } 4097 : 4098 : /** 4099 : * @brief Search a sequence for a matching sub-sequence using a predicate. 4100 : * @param first1 A forward iterator. 4101 : * @param last1 A forward iterator. 4102 : * @param first2 A forward iterator. 4103 : * @param last2 A forward iterator. 4104 : * @param predicate A binary predicate. 4105 : * @return The first iterator @c i in the range 4106 : * @p [first1,last1-(last2-first2)) such that 4107 : * @p predicate(*(i+N),*(first2+N)) is true for each @c N in the range 4108 : * @p [0,last2-first2), or @p last1 if no such iterator exists. 4109 : * 4110 : * Searches the range @p [first1,last1) for a sub-sequence that compares 4111 : * equal value-by-value with the sequence given by @p [first2,last2), 4112 : * using @p predicate to determine equality, and returns an iterator 4113 : * to the first element of the sub-sequence, or @p last1 if no such 4114 : * iterator exists. 4115 : * 4116 : * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2) 4117 : */ 4118 : template<typename _ForwardIterator1, typename _ForwardIterator2, 4119 : typename _BinaryPredicate> 4120 : _ForwardIterator1 4121 : search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, 4122 : _ForwardIterator2 __first2, _ForwardIterator2 __last2, 4123 : _BinaryPredicate __predicate) 4124 : { 4125 : // concept requirements 4126 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) 4127 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) 4128 : __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 4129 : typename iterator_traits<_ForwardIterator1>::value_type, 4130 : typename iterator_traits<_ForwardIterator2>::value_type>) 4131 : __glibcxx_requires_valid_range(__first1, __last1); 4132 : __glibcxx_requires_valid_range(__first2, __last2); 4133 : 4134 : // Test for empty ranges 4135 : if (__first1 == __last1 || __first2 == __last2) 4136 : return __first1; 4137 : 4138 : // Test for a pattern of length 1. 4139 : _ForwardIterator2 __p1(__first2); 4140 : if (++__p1 == __last2) 4141 : { 4142 : while (__first1 != __last1 4143 : && !bool(__predicate(*__first1, *__first2))) 4144 : ++__first1; 4145 : return __first1; 4146 : } 4147 : 4148 : // General case. 4149 : _ForwardIterator2 __p; 4150 : _ForwardIterator1 __current = __first1; 4151 : 4152 : for (;;) 4153 : { 4154 : while (__first1 != __last1 4155 : && !bool(__predicate(*__first1, *__first2))) 4156 : ++__first1; 4157 : if (__first1 == __last1) 4158 : return __last1; 4159 : 4160 : __p = __p1; 4161 : __current = __first1; 4162 : if (++__current == __last1) 4163 : return __last1; 4164 : 4165 : while (__predicate(*__current, *__p)) 4166 : { 4167 : if (++__p == __last2) 4168 : return __first1; 4169 : if (++__current == __last1) 4170 : return __last1; 4171 : } 4172 : ++__first1; 4173 : } 4174 : return __first1; 4175 : } 4176 : 4177 : 4178 : /** 4179 : * @brief Search a sequence for a number of consecutive values. 4180 : * @param first A forward iterator. 4181 : * @param last A forward iterator. 4182 : * @param count The number of consecutive values. 4183 : * @param val The value to find. 4184 : * @return The first iterator @c i in the range @p [first,last-count) 4185 : * such that @c *(i+N) == @p val for each @c N in the range @p [0,count), 4186 : * or @p last if no such iterator exists. 4187 : * 4188 : * Searches the range @p [first,last) for @p count consecutive elements 4189 : * equal to @p val. 4190 : */ 4191 : template<typename _ForwardIterator, typename _Integer, typename _Tp> 4192 : _ForwardIterator 4193 : search_n(_ForwardIterator __first, _ForwardIterator __last, 4194 : _Integer __count, const _Tp& __val) 4195 : { 4196 : // concept requirements 4197 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4198 : __glibcxx_function_requires(_EqualOpConcept< 4199 : typename iterator_traits<_ForwardIterator>::value_type, _Tp>) 4200 : __glibcxx_requires_valid_range(__first, __last); 4201 : 4202 : if (__count <= 0) 4203 : return __first; 4204 : if (__count == 1) 4205 : return _GLIBCXX_STD_P::find(__first, __last, __val); 4206 : return std::__search_n(__first, __last, __count, __val, 4207 : std::__iterator_category(__first)); 4208 : } 4209 : 4210 : 4211 : /** 4212 : * @brief Search a sequence for a number of consecutive values using a 4213 : * predicate. 4214 : * @param first A forward iterator. 4215 : * @param last A forward iterator. 4216 : * @param count The number of consecutive values. 4217 : * @param val The value to find. 4218 : * @param binary_pred A binary predicate. 4219 : * @return The first iterator @c i in the range @p [first,last-count) 4220 : * such that @p binary_pred(*(i+N),val) is true for each @c N in the 4221 : * range @p [0,count), or @p last if no such iterator exists. 4222 : * 4223 : * Searches the range @p [first,last) for @p count consecutive elements 4224 : * for which the predicate returns true. 4225 : */ 4226 : template<typename _ForwardIterator, typename _Integer, typename _Tp, 4227 : typename _BinaryPredicate> 4228 : _ForwardIterator 4229 : search_n(_ForwardIterator __first, _ForwardIterator __last, 4230 : _Integer __count, const _Tp& __val, 4231 : _BinaryPredicate __binary_pred) 4232 : { 4233 : // concept requirements 4234 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4235 : __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, 4236 : typename iterator_traits<_ForwardIterator>::value_type, _Tp>) 4237 : __glibcxx_requires_valid_range(__first, __last); 4238 : 4239 : if (__count <= 0) 4240 : return __first; 4241 : if (__count == 1) 4242 : { 4243 : while (__first != __last && !bool(__binary_pred(*__first, __val))) 4244 : ++__first; 4245 : return __first; 4246 : } 4247 : return std::__search_n(__first, __last, __count, __val, __binary_pred, 4248 : std::__iterator_category(__first)); 4249 : } 4250 : 4251 : 4252 : /** 4253 : * @brief Perform an operation on a sequence. 4254 : * @param first An input iterator. 4255 : * @param last An input iterator. 4256 : * @param result An output iterator. 4257 : * @param unary_op A unary operator. 4258 : * @return An output iterator equal to @p result+(last-first). 4259 : * 4260 : * Applies the operator to each element in the input range and assigns 4261 : * the results to successive elements of the output sequence. 4262 : * Evaluates @p *(result+N)=unary_op(*(first+N)) for each @c N in the 4263 : * range @p [0,last-first). 4264 : * 4265 : * @p unary_op must not alter its argument. 4266 : */ 4267 : template<typename _InputIterator, typename _OutputIterator, 4268 : typename _UnaryOperation> 4269 : _OutputIterator 4270 : transform(_InputIterator __first, _InputIterator __last, 4271 : _OutputIterator __result, _UnaryOperation __unary_op) 4272 : { 4273 : // concept requirements 4274 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 4275 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 4276 : // "the type returned by a _UnaryOperation" 4277 : __typeof__(__unary_op(*__first))>) 4278 : __glibcxx_requires_valid_range(__first, __last); 4279 : 4280 : for (; __first != __last; ++__first, ++__result) 4281 : *__result = __unary_op(*__first); 4282 : return __result; 4283 : } 4284 : 4285 : /** 4286 : * @brief Perform an operation on corresponding elements of two sequences. 4287 : * @param first1 An input iterator. 4288 : * @param last1 An input iterator. 4289 : * @param first2 An input iterator. 4290 : * @param result An output iterator. 4291 : * @param binary_op A binary operator. 4292 : * @return An output iterator equal to @p result+(last-first). 4293 : * 4294 : * Applies the operator to the corresponding elements in the two 4295 : * input ranges and assigns the results to successive elements of the 4296 : * output sequence. 4297 : * Evaluates @p *(result+N)=binary_op(*(first1+N),*(first2+N)) for each 4298 : * @c N in the range @p [0,last1-first1). 4299 : * 4300 : * @p binary_op must not alter either of its arguments. 4301 : */ 4302 : template<typename _InputIterator1, typename _InputIterator2, 4303 : typename _OutputIterator, typename _BinaryOperation> 4304 : _OutputIterator 4305 : transform(_InputIterator1 __first1, _InputIterator1 __last1, 4306 : _InputIterator2 __first2, _OutputIterator __result, 4307 : _BinaryOperation __binary_op) 4308 : { 4309 : // concept requirements 4310 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 4311 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 4312 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 4313 : // "the type returned by a _BinaryOperation" 4314 : __typeof__(__binary_op(*__first1,*__first2))>) 4315 : __glibcxx_requires_valid_range(__first1, __last1); 4316 : 4317 : for (; __first1 != __last1; ++__first1, ++__first2, ++__result) 4318 : *__result = __binary_op(*__first1, *__first2); 4319 : return __result; 4320 : } 4321 : 4322 : /** 4323 : * @brief Replace each occurrence of one value in a sequence with another 4324 : * value. 4325 : * @param first A forward iterator. 4326 : * @param last A forward iterator. 4327 : * @param old_value The value to be replaced. 4328 : * @param new_value The replacement value. 4329 : * @return replace() returns no value. 4330 : * 4331 : * For each iterator @c i in the range @p [first,last) if @c *i == 4332 : * @p old_value then the assignment @c *i = @p new_value is performed. 4333 : */ 4334 : template<typename _ForwardIterator, typename _Tp> 4335 : void 4336 : replace(_ForwardIterator __first, _ForwardIterator __last, 4337 : const _Tp& __old_value, const _Tp& __new_value) 4338 : { 4339 : // concept requirements 4340 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 4341 : _ForwardIterator>) 4342 : __glibcxx_function_requires(_EqualOpConcept< 4343 : typename iterator_traits<_ForwardIterator>::value_type, _Tp>) 4344 : __glibcxx_function_requires(_ConvertibleConcept<_Tp, 4345 : typename iterator_traits<_ForwardIterator>::value_type>) 4346 : __glibcxx_requires_valid_range(__first, __last); 4347 : 4348 : for (; __first != __last; ++__first) 4349 : if (*__first == __old_value) 4350 : *__first = __new_value; 4351 : } 4352 : 4353 : /** 4354 : * @brief Replace each value in a sequence for which a predicate returns 4355 : * true with another value. 4356 : * @param first A forward iterator. 4357 : * @param last A forward iterator. 4358 : * @param pred A predicate. 4359 : * @param new_value The replacement value. 4360 : * @return replace_if() returns no value. 4361 : * 4362 : * For each iterator @c i in the range @p [first,last) if @p pred(*i) 4363 : * is true then the assignment @c *i = @p new_value is performed. 4364 : */ 4365 : template<typename _ForwardIterator, typename _Predicate, typename _Tp> 4366 : void 4367 : replace_if(_ForwardIterator __first, _ForwardIterator __last, 4368 : _Predicate __pred, const _Tp& __new_value) 4369 : { 4370 : // concept requirements 4371 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 4372 : _ForwardIterator>) 4373 : __glibcxx_function_requires(_ConvertibleConcept<_Tp, 4374 : typename iterator_traits<_ForwardIterator>::value_type>) 4375 : __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 4376 : typename iterator_traits<_ForwardIterator>::value_type>) 4377 : __glibcxx_requires_valid_range(__first, __last); 4378 : 4379 : for (; __first != __last; ++__first) 4380 : if (__pred(*__first)) 4381 : *__first = __new_value; 4382 : } 4383 : 4384 : /** 4385 : * @brief Assign the result of a function object to each value in a 4386 : * sequence. 4387 : * @param first A forward iterator. 4388 : * @param last A forward iterator. 4389 : * @param gen A function object taking no arguments and returning 4390 : * std::iterator_traits<_ForwardIterator>::value_type 4391 : * @return generate() returns no value. 4392 : * 4393 : * Performs the assignment @c *i = @p gen() for each @c i in the range 4394 : * @p [first,last). 4395 : */ 4396 : template<typename _ForwardIterator, typename _Generator> 4397 : void 4398 : generate(_ForwardIterator __first, _ForwardIterator __last, 4399 : _Generator __gen) 4400 : { 4401 : // concept requirements 4402 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 4403 : __glibcxx_function_requires(_GeneratorConcept<_Generator, 4404 : typename iterator_traits<_ForwardIterator>::value_type>) 4405 : __glibcxx_requires_valid_range(__first, __last); 4406 : 4407 : for (; __first != __last; ++__first) 4408 : *__first = __gen(); 4409 : } 4410 : 4411 : /** 4412 : * @brief Assign the result of a function object to each value in a 4413 : * sequence. 4414 : * @param first A forward iterator. 4415 : * @param n The length of the sequence. 4416 : * @param gen A function object taking no arguments and returning 4417 : * std::iterator_traits<_ForwardIterator>::value_type 4418 : * @return The end of the sequence, @p first+n 4419 : * 4420 : * Performs the assignment @c *i = @p gen() for each @c i in the range 4421 : * @p [first,first+n). 4422 : */ 4423 : template<typename _OutputIterator, typename _Size, typename _Generator> 4424 : _OutputIterator 4425 : generate_n(_OutputIterator __first, _Size __n, _Generator __gen) 4426 : { 4427 : // concept requirements 4428 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 4429 : // "the type returned by a _Generator" 4430 : __typeof__(__gen())>) 4431 : 4432 : for (; __n > 0; --__n, ++__first) 4433 : *__first = __gen(); 4434 : return __first; 4435 : } 4436 : 4437 : 4438 : /** 4439 : * @brief Copy a sequence, removing consecutive duplicate values. 4440 : * @param first An input iterator. 4441 : * @param last An input iterator. 4442 : * @param result An output iterator. 4443 : * @return An iterator designating the end of the resulting sequence. 4444 : * 4445 : * Copies each element in the range @p [first,last) to the range 4446 : * beginning at @p result, except that only the first element is copied 4447 : * from groups of consecutive elements that compare equal. 4448 : * unique_copy() is stable, so the relative order of elements that are 4449 : * copied is unchanged. 4450 : * 4451 : * _GLIBCXX_RESOLVE_LIB_DEFECTS 4452 : * DR 241. Does unique_copy() require CopyConstructible and Assignable? 4453 : * 4454 : * _GLIBCXX_RESOLVE_LIB_DEFECTS 4455 : * DR 538. 241 again: Does unique_copy() require CopyConstructible and 4456 : * Assignable? 4457 : */ 4458 : template<typename _InputIterator, typename _OutputIterator> 4459 : inline _OutputIterator 4460 : unique_copy(_InputIterator __first, _InputIterator __last, 4461 : _OutputIterator __result) 4462 : { 4463 : // concept requirements 4464 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 4465 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 4466 : typename iterator_traits<_InputIterator>::value_type>) 4467 : __glibcxx_function_requires(_EqualityComparableConcept< 4468 : typename iterator_traits<_InputIterator>::value_type>) 4469 : __glibcxx_requires_valid_range(__first, __last); 4470 : 4471 : if (__first == __last) 4472 : return __result; 4473 : return std::__unique_copy(__first, __last, __result, 4474 : std::__iterator_category(__first), 4475 : std::__iterator_category(__result)); 4476 : } 4477 : 4478 : /** 4479 : * @brief Copy a sequence, removing consecutive values using a predicate. 4480 : * @param first An input iterator. 4481 : * @param last An input iterator. 4482 : * @param result An output iterator. 4483 : * @param binary_pred A binary predicate. 4484 : * @return An iterator designating the end of the resulting sequence. 4485 : * 4486 : * Copies each element in the range @p [first,last) to the range 4487 : * beginning at @p result, except that only the first element is copied 4488 : * from groups of consecutive elements for which @p binary_pred returns 4489 : * true. 4490 : * unique_copy() is stable, so the relative order of elements that are 4491 : * copied is unchanged. 4492 : * 4493 : * _GLIBCXX_RESOLVE_LIB_DEFECTS 4494 : * DR 241. Does unique_copy() require CopyConstructible and Assignable? 4495 : */ 4496 : template<typename _InputIterator, typename _OutputIterator, 4497 : typename _BinaryPredicate> 4498 : inline _OutputIterator 4499 : unique_copy(_InputIterator __first, _InputIterator __last, 4500 : _OutputIterator __result, 4501 : _BinaryPredicate __binary_pred) 4502 : { 4503 : // concept requirements -- predicates checked later 4504 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) 4505 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 4506 : typename iterator_traits<_InputIterator>::value_type>) 4507 : __glibcxx_requires_valid_range(__first, __last); 4508 : 4509 : if (__first == __last) 4510 : return __result; 4511 : return std::__unique_copy(__first, __last, __result, __binary_pred, 4512 : std::__iterator_category(__first), 4513 : std::__iterator_category(__result)); 4514 : } 4515 : 4516 : 4517 : /** 4518 : * @brief Randomly shuffle the elements of a sequence. 4519 : * @param first A forward iterator. 4520 : * @param last A forward iterator. 4521 : * @return Nothing. 4522 : * 4523 : * Reorder the elements in the range @p [first,last) using a random 4524 : * distribution, so that every possible ordering of the sequence is 4525 : * equally likely. 4526 : */ 4527 : template<typename _RandomAccessIterator> 4528 : inline void 4529 : random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) 4530 : { 4531 : // concept requirements 4532 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 4533 : _RandomAccessIterator>) 4534 : __glibcxx_requires_valid_range(__first, __last); 4535 : 4536 : if (__first != __last) 4537 : for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) 4538 : std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1))); 4539 : } 4540 : 4541 : /** 4542 : * @brief Shuffle the elements of a sequence using a random number 4543 : * generator. 4544 : * @param first A forward iterator. 4545 : * @param last A forward iterator. 4546 : * @param rand The RNG functor or function. 4547 : * @return Nothing. 4548 : * 4549 : * Reorders the elements in the range @p [first,last) using @p rand to 4550 : * provide a random distribution. Calling @p rand(N) for a positive 4551 : * integer @p N should return a randomly chosen integer from the 4552 : * range [0,N). 4553 : */ 4554 : template<typename _RandomAccessIterator, typename _RandomNumberGenerator> 4555 : void 4556 : random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, 4557 : _RandomNumberGenerator& __rand) 4558 : { 4559 : // concept requirements 4560 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 4561 : _RandomAccessIterator>) 4562 : __glibcxx_requires_valid_range(__first, __last); 4563 : 4564 : if (__first == __last) 4565 : return; 4566 : for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) 4567 : std::iter_swap(__i, __first + __rand((__i - __first) + 1)); 4568 : } 4569 : 4570 : 4571 : /** 4572 : * @brief Move elements for which a predicate is true to the beginning 4573 : * of a sequence. 4574 : * @param first A forward iterator. 4575 : * @param last A forward iterator. 4576 : * @param pred A predicate functor. 4577 : * @return An iterator @p middle such that @p pred(i) is true for each 4578 : * iterator @p i in the range @p [first,middle) and false for each @p i 4579 : * in the range @p [middle,last). 4580 : * 4581 : * @p pred must not modify its operand. @p partition() does not preserve 4582 : * the relative ordering of elements in each group, use 4583 : * @p stable_partition() if this is needed. 4584 : */ 4585 : template<typename _ForwardIterator, typename _Predicate> 4586 : inline _ForwardIterator 4587 : partition(_ForwardIterator __first, _ForwardIterator __last, 4588 : _Predicate __pred) 4589 : { 4590 : // concept requirements 4591 : __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< 4592 : _ForwardIterator>) 4593 : __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, 4594 : typename iterator_traits<_ForwardIterator>::value_type>) 4595 : __glibcxx_requires_valid_range(__first, __last); 4596 : 4597 : return std::__partition(__first, __last, __pred, 4598 : std::__iterator_category(__first)); 4599 : } 4600 : 4601 : 4602 : 4603 : /** 4604 : * @brief Sort the smallest elements of a sequence. 4605 : * @param first An iterator. 4606 : * @param middle Another iterator. 4607 : * @param last Another iterator. 4608 : * @return Nothing. 4609 : * 4610 : * Sorts the smallest @p (middle-first) elements in the range 4611 : * @p [first,last) and moves them to the range @p [first,middle). The 4612 : * order of the remaining elements in the range @p [middle,last) is 4613 : * undefined. 4614 : * After the sort if @p i and @j are iterators in the range 4615 : * @p [first,middle) such that @i precedes @j and @k is an iterator in 4616 : * the range @p [middle,last) then @p *j<*i and @p *k<*i are both false. 4617 : */ 4618 : template<typename _RandomAccessIterator> 4619 : inline void 4620 : partial_sort(_RandomAccessIterator __first, 4621 : _RandomAccessIterator __middle, 4622 0 : _RandomAccessIterator __last) 4623 : { 4624 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 4625 : _ValueType; 4626 : 4627 : // concept requirements 4628 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 4629 : _RandomAccessIterator>) 4630 : __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 4631 : __glibcxx_requires_valid_range(__first, __middle); 4632 : __glibcxx_requires_valid_range(__middle, __last); 4633 : 4634 0 : std::__heap_select(__first, __middle, __last); 4635 0 : std::sort_heap(__first, __middle); 4636 0 : } 4637 : 4638 : /** 4639 : * @brief Sort the smallest elements of a sequence using a predicate 4640 : * for comparison. 4641 : * @param first An iterator. 4642 : * @param middle Another iterator. 4643 : * @param last Another iterator. 4644 : * @param comp A comparison functor. 4645 : * @return Nothing. 4646 : * 4647 : * Sorts the smallest @p (middle-first) elements in the range 4648 : * @p [first,last) and moves them to the range @p [first,middle). The 4649 : * order of the remaining elements in the range @p [middle,last) is 4650 : * undefined. 4651 : * After the sort if @p i and @j are iterators in the range 4652 : * @p [first,middle) such that @i precedes @j and @k is an iterator in 4653 : * the range @p [middle,last) then @p *comp(j,*i) and @p comp(*k,*i) 4654 : * are both false. 4655 : */ 4656 : template<typename _RandomAccessIterator, typename _Compare> 4657 : inline void 4658 : partial_sort(_RandomAccessIterator __first, 4659 : _RandomAccessIterator __middle, 4660 : _RandomAccessIterator __last, 4661 0 : _Compare __comp) 4662 : { 4663 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 4664 : _ValueType; 4665 : 4666 : // concept requirements 4667 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 4668 : _RandomAccessIterator>) 4669 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 4670 : _ValueType, _ValueType>) 4671 : __glibcxx_requires_valid_range(__first, __middle); 4672 : __glibcxx_requires_valid_range(__middle, __last); 4673 : 4674 0 : std::__heap_select(__first, __middle, __last, __comp); 4675 0 : std::sort_heap(__first, __middle, __comp); 4676 0 : } 4677 : 4678 : /** 4679 : * @brief Sort a sequence just enough to find a particular position. 4680 : * @param first An iterator. 4681 : * @param nth Another iterator. 4682 : * @param last Another iterator. 4683 : * @return Nothing. 4684 : * 4685 : * Rearranges the elements in the range @p [first,last) so that @p *nth 4686 : * is the same element that would have been in that position had the 4687 : * whole sequence been sorted. 4688 : * whole sequence been sorted. The elements either side of @p *nth are 4689 : * not completely sorted, but for any iterator @i in the range 4690 : * @p [first,nth) and any iterator @j in the range @p [nth,last) it 4691 : * holds that @p *j<*i is false. 4692 : */ 4693 : template<typename _RandomAccessIterator> 4694 : inline void 4695 : nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, 4696 : _RandomAccessIterator __last) 4697 : { 4698 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 4699 : _ValueType; 4700 : 4701 : // concept requirements 4702 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 4703 : _RandomAccessIterator>) 4704 : __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 4705 : __glibcxx_requires_valid_range(__first, __nth); 4706 : __glibcxx_requires_valid_range(__nth, __last); 4707 : 4708 : if (__first == __last || __nth == __last) 4709 : return; 4710 : 4711 : std::__introselect(__first, __nth, __last, 4712 : std::__lg(__last - __first) * 2); 4713 : } 4714 : 4715 : /** 4716 : * @brief Sort a sequence just enough to find a particular position 4717 : * using a predicate for comparison. 4718 : * @param first An iterator. 4719 : * @param nth Another iterator. 4720 : * @param last Another iterator. 4721 : * @param comp A comparison functor. 4722 : * @return Nothing. 4723 : * 4724 : * Rearranges the elements in the range @p [first,last) so that @p *nth 4725 : * is the same element that would have been in that position had the 4726 : * whole sequence been sorted. The elements either side of @p *nth are 4727 : * not completely sorted, but for any iterator @i in the range 4728 : * @p [first,nth) and any iterator @j in the range @p [nth,last) it 4729 : * holds that @p comp(*j,*i) is false. 4730 : */ 4731 : template<typename _RandomAccessIterator, typename _Compare> 4732 : inline void 4733 : nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, 4734 : _RandomAccessIterator __last, _Compare __comp) 4735 : { 4736 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 4737 : _ValueType; 4738 : 4739 : // concept requirements 4740 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 4741 : _RandomAccessIterator>) 4742 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 4743 : _ValueType, _ValueType>) 4744 : __glibcxx_requires_valid_range(__first, __nth); 4745 : __glibcxx_requires_valid_range(__nth, __last); 4746 : 4747 : if (__first == __last || __nth == __last) 4748 : return; 4749 : 4750 : std::__introselect(__first, __nth, __last, 4751 : std::__lg(__last - __first) * 2, __comp); 4752 : } 4753 : 4754 : 4755 : /** 4756 : * @brief Sort the elements of a sequence. 4757 : * @param first An iterator. 4758 : * @param last Another iterator. 4759 : * @return Nothing. 4760 : * 4761 : * Sorts the elements in the range @p [first,last) in ascending order, 4762 : * such that @p *(i+1)<*i is false for each iterator @p i in the range 4763 : * @p [first,last-1). 4764 : * 4765 : * The relative ordering of equivalent elements is not preserved, use 4766 : * @p stable_sort() if this is needed. 4767 : */ 4768 : template<typename _RandomAccessIterator> 4769 : inline void 4770 8 : sort(_RandomAccessIterator __first, _RandomAccessIterator __last) 4771 : { 4772 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 4773 : _ValueType; 4774 : 4775 : // concept requirements 4776 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 4777 : _RandomAccessIterator>) 4778 : __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 4779 : __glibcxx_requires_valid_range(__first, __last); 4780 : 4781 8 : if (__first != __last) 4782 : { 4783 8 : std::__introsort_loop(__first, __last, 4784 : std::__lg(__last - __first) * 2); 4785 8 : std::__final_insertion_sort(__first, __last); 4786 : } 4787 8 : } 4788 : 4789 : /** 4790 : * @brief Sort the elements of a sequence using a predicate for comparison. 4791 : * @param first An iterator. 4792 : * @param last Another iterator. 4793 : * @param comp A comparison functor. 4794 : * @return Nothing. 4795 : * 4796 : * Sorts the elements in the range @p [first,last) in ascending order, 4797 : * such that @p comp(*(i+1),*i) is false for every iterator @p i in the 4798 : * range @p [first,last-1). 4799 : * 4800 : * The relative ordering of equivalent elements is not preserved, use 4801 : * @p stable_sort() if this is needed. 4802 : */ 4803 : template<typename _RandomAccessIterator, typename _Compare> 4804 : inline void 4805 : sort(_RandomAccessIterator __first, _RandomAccessIterator __last, 4806 3938 : _Compare __comp) 4807 : { 4808 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 4809 : _ValueType; 4810 : 4811 : // concept requirements 4812 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 4813 : _RandomAccessIterator>) 4814 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, 4815 : _ValueType>) 4816 : __glibcxx_requires_valid_range(__first, __last); 4817 : 4818 3938 : if (__first != __last) 4819 : { 4820 3938 : std::__introsort_loop(__first, __last, 4821 : std::__lg(__last - __first) * 2, __comp); 4822 3938 : std::__final_insertion_sort(__first, __last, __comp); 4823 : } 4824 3938 : } 4825 : 4826 : /** 4827 : * @brief Merges two sorted ranges. 4828 : * @param first1 An iterator. 4829 : * @param first2 Another iterator. 4830 : * @param last1 Another iterator. 4831 : * @param last2 Another iterator. 4832 : * @param result An iterator pointing to the end of the merged range. 4833 : * @return An iterator pointing to the first element "not less 4834 : * than" @a val. 4835 : * 4836 : * Merges the ranges [first1,last1) and [first2,last2) into the sorted range 4837 : * [result, result + (last1-first1) + (last2-first2)). Both input ranges 4838 : * must be sorted, and the output range must not overlap with either of 4839 : * the input ranges. The sort is @e stable, that is, for equivalent 4840 : * elements in the two ranges, elements from the first range will always 4841 : * come before elements from the second. 4842 : */ 4843 : template<typename _InputIterator1, typename _InputIterator2, 4844 : typename _OutputIterator> 4845 : _OutputIterator 4846 : merge(_InputIterator1 __first1, _InputIterator1 __last1, 4847 : _InputIterator2 __first2, _InputIterator2 __last2, 4848 : _OutputIterator __result) 4849 : { 4850 : typedef typename iterator_traits<_InputIterator1>::value_type 4851 : _ValueType1; 4852 : typedef typename iterator_traits<_InputIterator2>::value_type 4853 : _ValueType2; 4854 : 4855 : // concept requirements 4856 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 4857 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 4858 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 4859 : _ValueType1>) 4860 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 4861 : _ValueType2>) 4862 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 4863 : __glibcxx_requires_sorted_set(__first1, __last1, __first2); 4864 : __glibcxx_requires_sorted_set(__first2, __last2, __first1); 4865 : 4866 : while (__first1 != __last1 && __first2 != __last2) 4867 : { 4868 : if (*__first2 < *__first1) 4869 : { 4870 : *__result = *__first2; 4871 : ++__first2; 4872 : } 4873 : else 4874 : { 4875 : *__result = *__first1; 4876 : ++__first1; 4877 : } 4878 : ++__result; 4879 : } 4880 : return std::copy(__first2, __last2, std::copy(__first1, __last1, 4881 : __result)); 4882 : } 4883 : 4884 : /** 4885 : * @brief Merges two sorted ranges. 4886 : * @param first1 An iterator. 4887 : * @param first2 Another iterator. 4888 : * @param last1 Another iterator. 4889 : * @param last2 Another iterator. 4890 : * @param result An iterator pointing to the end of the merged range. 4891 : * @param comp A functor to use for comparisons. 4892 : * @return An iterator pointing to the first element "not less 4893 : * than" @a val. 4894 : * 4895 : * Merges the ranges [first1,last1) and [first2,last2) into the sorted range 4896 : * [result, result + (last1-first1) + (last2-first2)). Both input ranges 4897 : * must be sorted, and the output range must not overlap with either of 4898 : * the input ranges. The sort is @e stable, that is, for equivalent 4899 : * elements in the two ranges, elements from the first range will always 4900 : * come before elements from the second. 4901 : * 4902 : * The comparison function should have the same effects on ordering as 4903 : * the function used for the initial sort. 4904 : */ 4905 : template<typename _InputIterator1, typename _InputIterator2, 4906 : typename _OutputIterator, typename _Compare> 4907 : _OutputIterator 4908 : merge(_InputIterator1 __first1, _InputIterator1 __last1, 4909 : _InputIterator2 __first2, _InputIterator2 __last2, 4910 : _OutputIterator __result, _Compare __comp) 4911 : { 4912 : typedef typename iterator_traits<_InputIterator1>::value_type 4913 : _ValueType1; 4914 : typedef typename iterator_traits<_InputIterator2>::value_type 4915 : _ValueType2; 4916 : 4917 : // concept requirements 4918 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 4919 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 4920 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 4921 : _ValueType1>) 4922 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 4923 : _ValueType2>) 4924 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 4925 : _ValueType2, _ValueType1>) 4926 : __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); 4927 : __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); 4928 : 4929 : while (__first1 != __last1 && __first2 != __last2) 4930 : { 4931 : if (__comp(*__first2, *__first1)) 4932 : { 4933 : *__result = *__first2; 4934 : ++__first2; 4935 : } 4936 : else 4937 : { 4938 : *__result = *__first1; 4939 : ++__first1; 4940 : } 4941 : ++__result; 4942 : } 4943 : return std::copy(__first2, __last2, std::copy(__first1, __last1, 4944 : __result)); 4945 : } 4946 : 4947 : 4948 : /** 4949 : * @brief Sort the elements of a sequence, preserving the relative order 4950 : * of equivalent elements. 4951 : * @param first An iterator. 4952 : * @param last Another iterator. 4953 : * @return Nothing. 4954 : * 4955 : * Sorts the elements in the range @p [first,last) in ascending order, 4956 : * such that @p *(i+1)<*i is false for each iterator @p i in the range 4957 : * @p [first,last-1). 4958 : * 4959 : * The relative ordering of equivalent elements is preserved, so any two 4960 : * elements @p x and @p y in the range @p [first,last) such that 4961 : * @p x<y is false and @p y<x is false will have the same relative 4962 : * ordering after calling @p stable_sort(). 4963 : */ 4964 : template<typename _RandomAccessIterator> 4965 : inline void 4966 : stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) 4967 : { 4968 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 4969 : _ValueType; 4970 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 4971 : _DistanceType; 4972 : 4973 : // concept requirements 4974 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 4975 : _RandomAccessIterator>) 4976 : __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 4977 : __glibcxx_requires_valid_range(__first, __last); 4978 : 4979 : _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first, 4980 : __last); 4981 : if (__buf.begin() == 0) 4982 : std::__inplace_stable_sort(__first, __last); 4983 : else 4984 : std::__stable_sort_adaptive(__first, __last, __buf.begin(), 4985 : _DistanceType(__buf.size())); 4986 : } 4987 : 4988 : /** 4989 : * @brief Sort the elements of a sequence using a predicate for comparison, 4990 : * preserving the relative order of equivalent elements. 4991 : * @param first An iterator. 4992 : * @param last Another iterator. 4993 : * @param comp A comparison functor. 4994 : * @return Nothing. 4995 : * 4996 : * Sorts the elements in the range @p [first,last) in ascending order, 4997 : * such that @p comp(*(i+1),*i) is false for each iterator @p i in the 4998 : * range @p [first,last-1). 4999 : * 5000 : * The relative ordering of equivalent elements is preserved, so any two 5001 : * elements @p x and @p y in the range @p [first,last) such that 5002 : * @p comp(x,y) is false and @p comp(y,x) is false will have the same 5003 : * relative ordering after calling @p stable_sort(). 5004 : */ 5005 : template<typename _RandomAccessIterator, typename _Compare> 5006 : inline void 5007 : stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, 5008 : _Compare __comp) 5009 : { 5010 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 5011 : _ValueType; 5012 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 5013 : _DistanceType; 5014 : 5015 : // concept requirements 5016 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 5017 : _RandomAccessIterator>) 5018 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5019 : _ValueType, 5020 : _ValueType>) 5021 : __glibcxx_requires_valid_range(__first, __last); 5022 : 5023 : _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first, 5024 : __last); 5025 : if (__buf.begin() == 0) 5026 : std::__inplace_stable_sort(__first, __last, __comp); 5027 : else 5028 : std::__stable_sort_adaptive(__first, __last, __buf.begin(), 5029 : _DistanceType(__buf.size()), __comp); 5030 : } 5031 : 5032 : 5033 : /** 5034 : * @brief Return the union of two sorted ranges. 5035 : * @param first1 Start of first range. 5036 : * @param last1 End of first range. 5037 : * @param first2 Start of second range. 5038 : * @param last2 End of second range. 5039 : * @return End of the output range. 5040 : * @ingroup setoperations 5041 : * 5042 : * This operation iterates over both ranges, copying elements present in 5043 : * each range in order to the output range. Iterators increment for each 5044 : * range. When the current element of one range is less than the other, 5045 : * that element is copied and the iterator advanced. If an element is 5046 : * contained in both ranges, the element from the first range is copied and 5047 : * both ranges advance. The output range may not overlap either input 5048 : * range. 5049 : */ 5050 : template<typename _InputIterator1, typename _InputIterator2, 5051 : typename _OutputIterator> 5052 : _OutputIterator 5053 : set_union(_InputIterator1 __first1, _InputIterator1 __last1, 5054 : _InputIterator2 __first2, _InputIterator2 __last2, 5055 21150 : _OutputIterator __result) 5056 : { 5057 : typedef typename iterator_traits<_InputIterator1>::value_type 5058 : _ValueType1; 5059 : typedef typename iterator_traits<_InputIterator2>::value_type 5060 : _ValueType2; 5061 : 5062 : // concept requirements 5063 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5064 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5065 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5066 : _ValueType1>) 5067 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5068 : _ValueType2>) 5069 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) 5070 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 5071 : __glibcxx_requires_sorted_set(__first1, __last1, __first2); 5072 : __glibcxx_requires_sorted_set(__first2, __last2, __first1); 5073 : 5074 42309 : while (__first1 != __last1 && __first2 != __last2) 5075 : { 5076 9 : if (*__first1 < *__first2) 5077 : { 5078 7 : *__result = *__first1; 5079 7 : ++__first1; 5080 : } 5081 2 : else if (*__first2 < *__first1) 5082 : { 5083 1 : *__result = *__first2; 5084 1 : ++__first2; 5085 : } 5086 : else 5087 : { 5088 1 : *__result = *__first1; 5089 1 : ++__first1; 5090 1 : ++__first2; 5091 : } 5092 9 : ++__result; 5093 : } 5094 : return std::copy(__first2, __last2, std::copy(__first1, __last1, 5095 21150 : __result)); 5096 : } 5097 : 5098 : /** 5099 : * @brief Return the union of two sorted ranges using a comparison functor. 5100 : * @param first1 Start of first range. 5101 : * @param last1 End of first range. 5102 : * @param first2 Start of second range. 5103 : * @param last2 End of second range. 5104 : * @param comp The comparison functor. 5105 : * @return End of the output range. 5106 : * @ingroup setoperations 5107 : * 5108 : * This operation iterates over both ranges, copying elements present in 5109 : * each range in order to the output range. Iterators increment for each 5110 : * range. When the current element of one range is less than the other 5111 : * according to @a comp, that element is copied and the iterator advanced. 5112 : * If an equivalent element according to @a comp is contained in both 5113 : * ranges, the element from the first range is copied and both ranges 5114 : * advance. The output range may not overlap either input range. 5115 : */ 5116 : template<typename _InputIterator1, typename _InputIterator2, 5117 : typename _OutputIterator, typename _Compare> 5118 : _OutputIterator 5119 : set_union(_InputIterator1 __first1, _InputIterator1 __last1, 5120 : _InputIterator2 __first2, _InputIterator2 __last2, 5121 : _OutputIterator __result, _Compare __comp) 5122 : { 5123 : typedef typename iterator_traits<_InputIterator1>::value_type 5124 : _ValueType1; 5125 : typedef typename iterator_traits<_InputIterator2>::value_type 5126 : _ValueType2; 5127 : 5128 : // concept requirements 5129 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5130 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5131 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5132 : _ValueType1>) 5133 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5134 : _ValueType2>) 5135 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5136 : _ValueType1, _ValueType2>) 5137 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5138 : _ValueType2, _ValueType1>) 5139 : __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); 5140 : __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); 5141 : 5142 : while (__first1 != __last1 && __first2 != __last2) 5143 : { 5144 : if (__comp(*__first1, *__first2)) 5145 : { 5146 : *__result = *__first1; 5147 : ++__first1; 5148 : } 5149 : else if (__comp(*__first2, *__first1)) 5150 : { 5151 : *__result = *__first2; 5152 : ++__first2; 5153 : } 5154 : else 5155 : { 5156 : *__result = *__first1; 5157 : ++__first1; 5158 : ++__first2; 5159 : } 5160 : ++__result; 5161 : } 5162 : return std::copy(__first2, __last2, std::copy(__first1, __last1, 5163 : __result)); 5164 : } 5165 : 5166 : /** 5167 : * @brief Return the intersection of two sorted ranges. 5168 : * @param first1 Start of first range. 5169 : * @param last1 End of first range. 5170 : * @param first2 Start of second range. 5171 : * @param last2 End of second range. 5172 : * @return End of the output range. 5173 : * @ingroup setoperations 5174 : * 5175 : * This operation iterates over both ranges, copying elements present in 5176 : * both ranges in order to the output range. Iterators increment for each 5177 : * range. When the current element of one range is less than the other, 5178 : * that iterator advances. If an element is contained in both ranges, the 5179 : * element from the first range is copied and both ranges advance. The 5180 : * output range may not overlap either input range. 5181 : */ 5182 : template<typename _InputIterator1, typename _InputIterator2, 5183 : typename _OutputIterator> 5184 : _OutputIterator 5185 : set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 5186 : _InputIterator2 __first2, _InputIterator2 __last2, 5187 2 : _OutputIterator __result) 5188 : { 5189 : typedef typename iterator_traits<_InputIterator1>::value_type 5190 : _ValueType1; 5191 : typedef typename iterator_traits<_InputIterator2>::value_type 5192 : _ValueType2; 5193 : 5194 : // concept requirements 5195 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5196 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5197 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5198 : _ValueType1>) 5199 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) 5200 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 5201 : __glibcxx_requires_sorted_set(__first1, __last1, __first2); 5202 : __glibcxx_requires_sorted_set(__first2, __last2, __first1); 5203 : 5204 8 : while (__first1 != __last1 && __first2 != __last2) 5205 4 : if (*__first1 < *__first2) 5206 1 : ++__first1; 5207 3 : else if (*__first2 < *__first1) 5208 1 : ++__first2; 5209 : else 5210 : { 5211 2 : *__result = *__first1; 5212 2 : ++__first1; 5213 2 : ++__first2; 5214 2 : ++__result; 5215 : } 5216 2 : return __result; 5217 : } 5218 : 5219 : /** 5220 : * @brief Return the intersection of two sorted ranges using comparison 5221 : * functor. 5222 : * @param first1 Start of first range. 5223 : * @param last1 End of first range. 5224 : * @param first2 Start of second range. 5225 : * @param last2 End of second range. 5226 : * @param comp The comparison functor. 5227 : * @return End of the output range. 5228 : * @ingroup setoperations 5229 : * 5230 : * This operation iterates over both ranges, copying elements present in 5231 : * both ranges in order to the output range. Iterators increment for each 5232 : * range. When the current element of one range is less than the other 5233 : * according to @a comp, that iterator advances. If an element is 5234 : * contained in both ranges according to @a comp, the element from the 5235 : * first range is copied and both ranges advance. The output range may not 5236 : * overlap either input range. 5237 : */ 5238 : template<typename _InputIterator1, typename _InputIterator2, 5239 : typename _OutputIterator, typename _Compare> 5240 : _OutputIterator 5241 : set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, 5242 : _InputIterator2 __first2, _InputIterator2 __last2, 5243 : _OutputIterator __result, _Compare __comp) 5244 : { 5245 : typedef typename iterator_traits<_InputIterator1>::value_type 5246 : _ValueType1; 5247 : typedef typename iterator_traits<_InputIterator2>::value_type 5248 : _ValueType2; 5249 : 5250 : // concept requirements 5251 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5252 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5253 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5254 : _ValueType1>) 5255 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5256 : _ValueType1, _ValueType2>) 5257 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5258 : _ValueType2, _ValueType1>) 5259 : __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); 5260 : __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); 5261 : 5262 : while (__first1 != __last1 && __first2 != __last2) 5263 : if (__comp(*__first1, *__first2)) 5264 : ++__first1; 5265 : else if (__comp(*__first2, *__first1)) 5266 : ++__first2; 5267 : else 5268 : { 5269 : *__result = *__first1; 5270 : ++__first1; 5271 : ++__first2; 5272 : ++__result; 5273 : } 5274 : return __result; 5275 : } 5276 : 5277 : /** 5278 : * @brief Return the difference of two sorted ranges. 5279 : * @param first1 Start of first range. 5280 : * @param last1 End of first range. 5281 : * @param first2 Start of second range. 5282 : * @param last2 End of second range. 5283 : * @return End of the output range. 5284 : * @ingroup setoperations 5285 : * 5286 : * This operation iterates over both ranges, copying elements present in 5287 : * the first range but not the second in order to the output range. 5288 : * Iterators increment for each range. When the current element of the 5289 : * first range is less than the second, that element is copied and the 5290 : * iterator advances. If the current element of the second range is less, 5291 : * the iterator advances, but no element is copied. If an element is 5292 : * contained in both ranges, no elements are copied and both ranges 5293 : * advance. The output range may not overlap either input range. 5294 : */ 5295 : template<typename _InputIterator1, typename _InputIterator2, 5296 : typename _OutputIterator> 5297 : _OutputIterator 5298 : set_difference(_InputIterator1 __first1, _InputIterator1 __last1, 5299 : _InputIterator2 __first2, _InputIterator2 __last2, 5300 10 : _OutputIterator __result) 5301 : { 5302 : typedef typename iterator_traits<_InputIterator1>::value_type 5303 : _ValueType1; 5304 : typedef typename iterator_traits<_InputIterator2>::value_type 5305 : _ValueType2; 5306 : 5307 : // concept requirements 5308 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5309 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5310 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5311 : _ValueType1>) 5312 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) 5313 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 5314 : __glibcxx_requires_sorted_set(__first1, __last1, __first2); 5315 : __glibcxx_requires_sorted_set(__first2, __last2, __first1); 5316 : 5317 22 : while (__first1 != __last1 && __first2 != __last2) 5318 2 : if (*__first1 < *__first2) 5319 : { 5320 1 : *__result = *__first1; 5321 1 : ++__first1; 5322 1 : ++__result; 5323 : } 5324 1 : else if (*__first2 < *__first1) 5325 0 : ++__first2; 5326 : else 5327 : { 5328 1 : ++__first1; 5329 1 : ++__first2; 5330 : } 5331 10 : return std::copy(__first1, __last1, __result); 5332 : } 5333 : 5334 : /** 5335 : * @brief Return the difference of two sorted ranges using comparison 5336 : * functor. 5337 : * @param first1 Start of first range. 5338 : * @param last1 End of first range. 5339 : * @param first2 Start of second range. 5340 : * @param last2 End of second range. 5341 : * @param comp The comparison functor. 5342 : * @return End of the output range. 5343 : * @ingroup setoperations 5344 : * 5345 : * This operation iterates over both ranges, copying elements present in 5346 : * the first range but not the second in order to the output range. 5347 : * Iterators increment for each range. When the current element of the 5348 : * first range is less than the second according to @a comp, that element 5349 : * is copied and the iterator advances. If the current element of the 5350 : * second range is less, no element is copied and the iterator advances. 5351 : * If an element is contained in both ranges according to @a comp, no 5352 : * elements are copied and both ranges advance. The output range may not 5353 : * overlap either input range. 5354 : */ 5355 : template<typename _InputIterator1, typename _InputIterator2, 5356 : typename _OutputIterator, typename _Compare> 5357 : _OutputIterator 5358 : set_difference(_InputIterator1 __first1, _InputIterator1 __last1, 5359 : _InputIterator2 __first2, _InputIterator2 __last2, 5360 : _OutputIterator __result, _Compare __comp) 5361 : { 5362 : typedef typename iterator_traits<_InputIterator1>::value_type 5363 : _ValueType1; 5364 : typedef typename iterator_traits<_InputIterator2>::value_type 5365 : _ValueType2; 5366 : 5367 : // concept requirements 5368 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5369 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5370 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5371 : _ValueType1>) 5372 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5373 : _ValueType1, _ValueType2>) 5374 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5375 : _ValueType2, _ValueType1>) 5376 : __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); 5377 : __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); 5378 : 5379 : while (__first1 != __last1 && __first2 != __last2) 5380 : if (__comp(*__first1, *__first2)) 5381 : { 5382 : *__result = *__first1; 5383 : ++__first1; 5384 : ++__result; 5385 : } 5386 : else if (__comp(*__first2, *__first1)) 5387 : ++__first2; 5388 : else 5389 : { 5390 : ++__first1; 5391 : ++__first2; 5392 : } 5393 : return std::copy(__first1, __last1, __result); 5394 : } 5395 : 5396 : /** 5397 : * @brief Return the symmetric difference of two sorted ranges. 5398 : * @param first1 Start of first range. 5399 : * @param last1 End of first range. 5400 : * @param first2 Start of second range. 5401 : * @param last2 End of second range. 5402 : * @return End of the output range. 5403 : * @ingroup setoperations 5404 : * 5405 : * This operation iterates over both ranges, copying elements present in 5406 : * one range but not the other in order to the output range. Iterators 5407 : * increment for each range. When the current element of one range is less 5408 : * than the other, that element is copied and the iterator advances. If an 5409 : * element is contained in both ranges, no elements are copied and both 5410 : * ranges advance. The output range may not overlap either input range. 5411 : */ 5412 : template<typename _InputIterator1, typename _InputIterator2, 5413 : typename _OutputIterator> 5414 : _OutputIterator 5415 : set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 5416 : _InputIterator2 __first2, _InputIterator2 __last2, 5417 : _OutputIterator __result) 5418 : { 5419 : typedef typename iterator_traits<_InputIterator1>::value_type 5420 : _ValueType1; 5421 : typedef typename iterator_traits<_InputIterator2>::value_type 5422 : _ValueType2; 5423 : 5424 : // concept requirements 5425 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5426 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5427 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5428 : _ValueType1>) 5429 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5430 : _ValueType2>) 5431 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) 5432 : __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) 5433 : __glibcxx_requires_sorted_set(__first1, __last1, __first2); 5434 : __glibcxx_requires_sorted_set(__first2, __last2, __first1); 5435 : 5436 : while (__first1 != __last1 && __first2 != __last2) 5437 : if (*__first1 < *__first2) 5438 : { 5439 : *__result = *__first1; 5440 : ++__first1; 5441 : ++__result; 5442 : } 5443 : else if (*__first2 < *__first1) 5444 : { 5445 : *__result = *__first2; 5446 : ++__first2; 5447 : ++__result; 5448 : } 5449 : else 5450 : { 5451 : ++__first1; 5452 : ++__first2; 5453 : } 5454 : return std::copy(__first2, __last2, std::copy(__first1, 5455 : __last1, __result)); 5456 : } 5457 : 5458 : /** 5459 : * @brief Return the symmetric difference of two sorted ranges using 5460 : * comparison functor. 5461 : * @param first1 Start of first range. 5462 : * @param last1 End of first range. 5463 : * @param first2 Start of second range. 5464 : * @param last2 End of second range. 5465 : * @param comp The comparison functor. 5466 : * @return End of the output range. 5467 : * @ingroup setoperations 5468 : * 5469 : * This operation iterates over both ranges, copying elements present in 5470 : * one range but not the other in order to the output range. Iterators 5471 : * increment for each range. When the current element of one range is less 5472 : * than the other according to @a comp, that element is copied and the 5473 : * iterator advances. If an element is contained in both ranges according 5474 : * to @a comp, no elements are copied and both ranges advance. The output 5475 : * range may not overlap either input range. 5476 : */ 5477 : template<typename _InputIterator1, typename _InputIterator2, 5478 : typename _OutputIterator, typename _Compare> 5479 : _OutputIterator 5480 : set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, 5481 : _InputIterator2 __first2, _InputIterator2 __last2, 5482 : _OutputIterator __result, 5483 : _Compare __comp) 5484 : { 5485 : typedef typename iterator_traits<_InputIterator1>::value_type 5486 : _ValueType1; 5487 : typedef typename iterator_traits<_InputIterator2>::value_type 5488 : _ValueType2; 5489 : 5490 : // concept requirements 5491 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) 5492 : __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) 5493 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5494 : _ValueType1>) 5495 : __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, 5496 : _ValueType2>) 5497 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5498 : _ValueType1, _ValueType2>) 5499 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5500 : _ValueType2, _ValueType1>) 5501 : __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); 5502 : __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); 5503 : 5504 : while (__first1 != __last1 && __first2 != __last2) 5505 : if (__comp(*__first1, *__first2)) 5506 : { 5507 : *__result = *__first1; 5508 : ++__first1; 5509 : ++__result; 5510 : } 5511 : else if (__comp(*__first2, *__first1)) 5512 : { 5513 : *__result = *__first2; 5514 : ++__first2; 5515 : ++__result; 5516 : } 5517 : else 5518 : { 5519 : ++__first1; 5520 : ++__first2; 5521 : } 5522 : return std::copy(__first2, __last2, 5523 : std::copy(__first1, __last1, __result)); 5524 : } 5525 : 5526 : 5527 : /** 5528 : * @brief Return the minimum element in a range. 5529 : * @param first Start of range. 5530 : * @param last End of range. 5531 : * @return Iterator referencing the first instance of the smallest value. 5532 : */ 5533 : template<typename _ForwardIterator> 5534 : _ForwardIterator 5535 : min_element(_ForwardIterator __first, _ForwardIterator __last) 5536 : { 5537 : // concept requirements 5538 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 5539 : __glibcxx_function_requires(_LessThanComparableConcept< 5540 : typename iterator_traits<_ForwardIterator>::value_type>) 5541 : __glibcxx_requires_valid_range(__first, __last); 5542 : 5543 : if (__first == __last) 5544 : return __first; 5545 : _ForwardIterator __result = __first; 5546 : while (++__first != __last) 5547 : if (*__first < *__result) 5548 : __result = __first; 5549 : return __result; 5550 : } 5551 : 5552 : /** 5553 : * @brief Return the minimum element in a range using comparison functor. 5554 : * @param first Start of range. 5555 : * @param last End of range. 5556 : * @param comp Comparison functor. 5557 : * @return Iterator referencing the first instance of the smallest value 5558 : * according to comp. 5559 : */ 5560 : template<typename _ForwardIterator, typename _Compare> 5561 : _ForwardIterator 5562 : min_element(_ForwardIterator __first, _ForwardIterator __last, 5563 : _Compare __comp) 5564 : { 5565 : // concept requirements 5566 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 5567 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5568 : typename iterator_traits<_ForwardIterator>::value_type, 5569 : typename iterator_traits<_ForwardIterator>::value_type>) 5570 : __glibcxx_requires_valid_range(__first, __last); 5571 : 5572 : if (__first == __last) 5573 : return __first; 5574 : _ForwardIterator __result = __first; 5575 : while (++__first != __last) 5576 : if (__comp(*__first, *__result)) 5577 : __result = __first; 5578 : return __result; 5579 : } 5580 : 5581 : /** 5582 : * @brief Return the maximum element in a range. 5583 : * @param first Start of range. 5584 : * @param last End of range. 5585 : * @return Iterator referencing the first instance of the largest value. 5586 : */ 5587 : template<typename _ForwardIterator> 5588 : _ForwardIterator 5589 : max_element(_ForwardIterator __first, _ForwardIterator __last) 5590 : { 5591 : // concept requirements 5592 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 5593 : __glibcxx_function_requires(_LessThanComparableConcept< 5594 : typename iterator_traits<_ForwardIterator>::value_type>) 5595 : __glibcxx_requires_valid_range(__first, __last); 5596 : 5597 : if (__first == __last) 5598 : return __first; 5599 : _ForwardIterator __result = __first; 5600 : while (++__first != __last) 5601 : if (*__result < *__first) 5602 : __result = __first; 5603 : return __result; 5604 : } 5605 : 5606 : /** 5607 : * @brief Return the maximum element in a range using comparison functor. 5608 : * @param first Start of range. 5609 : * @param last End of range. 5610 : * @param comp Comparison functor. 5611 : * @return Iterator referencing the first instance of the largest value 5612 : * according to comp. 5613 : */ 5614 : template<typename _ForwardIterator, typename _Compare> 5615 : _ForwardIterator 5616 : max_element(_ForwardIterator __first, _ForwardIterator __last, 5617 : _Compare __comp) 5618 : { 5619 : // concept requirements 5620 : __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 5621 : __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, 5622 : typename iterator_traits<_ForwardIterator>::value_type, 5623 : typename iterator_traits<_ForwardIterator>::value_type>) 5624 : __glibcxx_requires_valid_range(__first, __last); 5625 : 5626 : if (__first == __last) return __first; 5627 : _ForwardIterator __result = __first; 5628 : while (++__first != __last) 5629 : if (__comp(*__result, *__first)) 5630 : __result = __first; 5631 : return __result; 5632 : } 5633 : 5634 : _GLIBCXX_END_NESTED_NAMESPACE 5635 : 5636 : #endif /* _STL_ALGO_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // List implementation (out of line) -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996,1997 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file list.tcc 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _LIST_TCC 63 : #define _LIST_TCC 1 64 : 65 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) 66 : 67 : template<typename _Tp, typename _Alloc> 68 : void 69 : _List_base<_Tp, _Alloc>:: 70 19 : _M_clear() 71 : { 72 : typedef _List_node<_Tp> _Node; 73 19 : _Node* __cur = static_cast<_Node*>(this->_M_impl._M_node._M_next); 74 60 : while (__cur != &this->_M_impl._M_node) 75 : { 76 22 : _Node* __tmp = __cur; 77 22 : __cur = static_cast<_Node*>(__cur->_M_next); 78 22 : _M_get_Tp_allocator().destroy(&__tmp->_M_data); 79 22 : _M_put_node(__tmp); 80 : } 81 19 : } 82 : 83 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 84 : template<typename _Tp, typename _Alloc> 85 : template<typename... _Args> 86 : typename list<_Tp, _Alloc>::iterator 87 : list<_Tp, _Alloc>:: 88 : emplace(iterator __position, _Args&&... __args) 89 : { 90 : _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...); 91 : __tmp->hook(__position._M_node); 92 : return iterator(__tmp); 93 : } 94 : #endif 95 : 96 : template<typename _Tp, typename _Alloc> 97 : typename list<_Tp, _Alloc>::iterator 98 : list<_Tp, _Alloc>:: 99 : insert(iterator __position, const value_type& __x) 100 : { 101 : _Node* __tmp = _M_create_node(__x); 102 : __tmp->hook(__position._M_node); 103 : return iterator(__tmp); 104 : } 105 : 106 : template<typename _Tp, typename _Alloc> 107 : typename list<_Tp, _Alloc>::iterator 108 : list<_Tp, _Alloc>:: 109 25 : erase(iterator __position) 110 : { 111 25 : iterator __ret = iterator(__position._M_node->_M_next); 112 25 : _M_erase(__position); 113 : return __ret; 114 : } 115 : 116 : template<typename _Tp, typename _Alloc> 117 : void 118 : list<_Tp, _Alloc>:: 119 : resize(size_type __new_size, value_type __x) 120 : { 121 : iterator __i = begin(); 122 : size_type __len = 0; 123 : for (; __i != end() && __len < __new_size; ++__i, ++__len) 124 : ; 125 : if (__len == __new_size) 126 : erase(__i, end()); 127 : else // __i == end() 128 : insert(end(), __new_size - __len, __x); 129 : } 130 : 131 : template<typename _Tp, typename _Alloc> 132 : list<_Tp, _Alloc>& 133 : list<_Tp, _Alloc>:: 134 : operator=(const list& __x) 135 : { 136 : if (this != &__x) 137 : { 138 : iterator __first1 = begin(); 139 : iterator __last1 = end(); 140 : const_iterator __first2 = __x.begin(); 141 : const_iterator __last2 = __x.end(); 142 : for (; __first1 != __last1 && __first2 != __last2; 143 : ++__first1, ++__first2) 144 : *__first1 = *__first2; 145 : if (__first2 == __last2) 146 : erase(__first1, __last1); 147 : else 148 : insert(__last1, __first2, __last2); 149 : } 150 : return *this; 151 : } 152 : 153 : template<typename _Tp, typename _Alloc> 154 : void 155 : list<_Tp, _Alloc>:: 156 : _M_fill_assign(size_type __n, const value_type& __val) 157 : { 158 : iterator __i = begin(); 159 : for (; __i != end() && __n > 0; ++__i, --__n) 160 : *__i = __val; 161 : if (__n > 0) 162 : insert(end(), __n, __val); 163 : else 164 : erase(__i, end()); 165 : } 166 : 167 : template<typename _Tp, typename _Alloc> 168 : template <typename _InputIterator> 169 : void 170 : list<_Tp, _Alloc>:: 171 : _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2, 172 : __false_type) 173 : { 174 : iterator __first1 = begin(); 175 : iterator __last1 = end(); 176 : for (; __first1 != __last1 && __first2 != __last2; 177 : ++__first1, ++__first2) 178 : *__first1 = *__first2; 179 : if (__first2 == __last2) 180 : erase(__first1, __last1); 181 : else 182 : insert(__last1, __first2, __last2); 183 : } 184 : 185 : template<typename _Tp, typename _Alloc> 186 : void 187 : list<_Tp, _Alloc>:: 188 : remove(const value_type& __value) 189 : { 190 : iterator __first = begin(); 191 : iterator __last = end(); 192 : iterator __extra = __last; 193 : while (__first != __last) 194 : { 195 : iterator __next = __first; 196 : ++__next; 197 : if (*__first == __value) 198 : { 199 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 200 : // 526. Is it undefined if a function in the standard changes 201 : // in parameters? 202 : if (&*__first != &__value) 203 : _M_erase(__first); 204 : else 205 : __extra = __first; 206 : } 207 : __first = __next; 208 : } 209 : if (__extra != __last) 210 : _M_erase(__extra); 211 : } 212 : 213 : template<typename _Tp, typename _Alloc> 214 : void 215 : list<_Tp, _Alloc>:: 216 : unique() 217 : { 218 : iterator __first = begin(); 219 : iterator __last = end(); 220 : if (__first == __last) 221 : return; 222 : iterator __next = __first; 223 : while (++__next != __last) 224 : { 225 : if (*__first == *__next) 226 : _M_erase(__next); 227 : else 228 : __first = __next; 229 : __next = __first; 230 : } 231 : } 232 : 233 : template<typename _Tp, typename _Alloc> 234 : void 235 : list<_Tp, _Alloc>:: 236 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 237 : merge(list&& __x) 238 : #else 239 : merge(list& __x) 240 : #endif 241 : { 242 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 243 : // 300. list::merge() specification incomplete 244 : if (this != &__x) 245 : { 246 : _M_check_equal_allocators(__x); 247 : 248 : iterator __first1 = begin(); 249 : iterator __last1 = end(); 250 : iterator __first2 = __x.begin(); 251 : iterator __last2 = __x.end(); 252 : while (__first1 != __last1 && __first2 != __last2) 253 : if (*__first2 < *__first1) 254 : { 255 : iterator __next = __first2; 256 : _M_transfer(__first1, __first2, ++__next); 257 : __first2 = __next; 258 : } 259 : else 260 : ++__first1; 261 : if (__first2 != __last2) 262 : _M_transfer(__last1, __first2, __last2); 263 : } 264 : } 265 : 266 : template<typename _Tp, typename _Alloc> 267 : template <typename _StrictWeakOrdering> 268 : void 269 : list<_Tp, _Alloc>:: 270 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 271 : merge(list&& __x, _StrictWeakOrdering __comp) 272 : #else 273 : merge(list& __x, _StrictWeakOrdering __comp) 274 : #endif 275 : { 276 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 277 : // 300. list::merge() specification incomplete 278 : if (this != &__x) 279 : { 280 : _M_check_equal_allocators(__x); 281 : 282 : iterator __first1 = begin(); 283 : iterator __last1 = end(); 284 : iterator __first2 = __x.begin(); 285 : iterator __last2 = __x.end(); 286 : while (__first1 != __last1 && __first2 != __last2) 287 : if (__comp(*__first2, *__first1)) 288 : { 289 : iterator __next = __first2; 290 : _M_transfer(__first1, __first2, ++__next); 291 : __first2 = __next; 292 : } 293 : else 294 : ++__first1; 295 : if (__first2 != __last2) 296 : _M_transfer(__last1, __first2, __last2); 297 : } 298 : } 299 : 300 : template<typename _Tp, typename _Alloc> 301 : void 302 : list<_Tp, _Alloc>:: 303 : sort() 304 : { 305 : // Do nothing if the list has length 0 or 1. 306 : if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node 307 : && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) 308 : { 309 : list __carry; 310 : list __tmp[64]; 311 : list * __fill = &__tmp[0]; 312 : list * __counter; 313 : 314 : do 315 : { 316 : __carry.splice(__carry.begin(), *this, begin()); 317 : 318 : for(__counter = &__tmp[0]; 319 : __counter != __fill && !__counter->empty(); 320 : ++__counter) 321 : { 322 : __counter->merge(__carry); 323 : __carry.swap(*__counter); 324 : } 325 : __carry.swap(*__counter); 326 : if (__counter == __fill) 327 : ++__fill; 328 : } 329 : while ( !empty() ); 330 : 331 : for (__counter = &__tmp[1]; __counter != __fill; ++__counter) 332 : __counter->merge(*(__counter - 1)); 333 : swap( *(__fill - 1) ); 334 : } 335 : } 336 : 337 : template<typename _Tp, typename _Alloc> 338 : template <typename _Predicate> 339 : void 340 : list<_Tp, _Alloc>:: 341 : remove_if(_Predicate __pred) 342 : { 343 : iterator __first = begin(); 344 : iterator __last = end(); 345 : while (__first != __last) 346 : { 347 : iterator __next = __first; 348 : ++__next; 349 : if (__pred(*__first)) 350 : _M_erase(__first); 351 : __first = __next; 352 : } 353 : } 354 : 355 : template<typename _Tp, typename _Alloc> 356 : template <typename _BinaryPredicate> 357 : void 358 : list<_Tp, _Alloc>:: 359 : unique(_BinaryPredicate __binary_pred) 360 : { 361 : iterator __first = begin(); 362 : iterator __last = end(); 363 : if (__first == __last) 364 : return; 365 : iterator __next = __first; 366 : while (++__next != __last) 367 : { 368 : if (__binary_pred(*__first, *__next)) 369 : _M_erase(__next); 370 : else 371 : __first = __next; 372 : __next = __first; 373 : } 374 : } 375 : 376 : template<typename _Tp, typename _Alloc> 377 : template <typename _StrictWeakOrdering> 378 : void 379 : list<_Tp, _Alloc>:: 380 : sort(_StrictWeakOrdering __comp) 381 : { 382 : // Do nothing if the list has length 0 or 1. 383 : if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node 384 : && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) 385 : { 386 : list __carry; 387 : list __tmp[64]; 388 : list * __fill = &__tmp[0]; 389 : list * __counter; 390 : 391 : do 392 : { 393 : __carry.splice(__carry.begin(), *this, begin()); 394 : 395 : for(__counter = &__tmp[0]; 396 : __counter != __fill && !__counter->empty(); 397 : ++__counter) 398 : { 399 : __counter->merge(__carry, __comp); 400 : __carry.swap(*__counter); 401 : } 402 : __carry.swap(*__counter); 403 : if (__counter == __fill) 404 : ++__fill; 405 : } 406 : while ( !empty() ); 407 : 408 : for (__counter = &__tmp[1]; __counter != __fill; ++__counter) 409 : __counter->merge(*(__counter - 1), __comp); 410 : swap(*(__fill - 1)); 411 : } 412 : } 413 : 414 : _GLIBCXX_END_NESTED_NAMESPACE 415 : 416 : #endif /* _LIST_TCC */ 417 : |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Allocators -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * Copyright (c) 1996-1997 33 : * Silicon Graphics Computer Systems, Inc. 34 : * 35 : * Permission to use, copy, modify, distribute and sell this software 36 : * and its documentation for any purpose is hereby granted without fee, 37 : * provided that the above copyright notice appear in all copies and 38 : * that both that copyright notice and this permission notice appear 39 : * in supporting documentation. Silicon Graphics makes no 40 : * representations about the suitability of this software for any 41 : * purpose. It is provided "as is" without express or implied warranty. 42 : */ 43 : 44 : /** @file allocator.h 45 : * This is an internal header file, included by other library headers. 46 : * You should not attempt to use it directly. 47 : */ 48 : 49 : #ifndef _ALLOCATOR_H 50 : #define _ALLOCATOR_H 1 51 : 52 : // Define the base class to std::allocator. 53 : #include <bits/c++allocator.h> 54 : 55 : _GLIBCXX_BEGIN_NAMESPACE(std) 56 : 57 : template<typename _Tp> 58 : class allocator; 59 : 60 : /// allocator<void> specialization. 61 : template<> 62 : class allocator<void> 63 : { 64 : public: 65 : typedef size_t size_type; 66 : typedef ptrdiff_t difference_type; 67 : typedef void* pointer; 68 : typedef const void* const_pointer; 69 : typedef void value_type; 70 : 71 : template<typename _Tp1> 72 : struct rebind 73 : { typedef allocator<_Tp1> other; }; 74 : }; 75 : 76 : /** 77 : * @brief The "standard" allocator, as per [20.4]. 78 : * 79 : * Further details: 80 : * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt04ch11.html 81 : */ 82 : template<typename _Tp> 83 : class allocator: public __glibcxx_base_allocator<_Tp> 84 : { 85 : public: 86 : typedef size_t size_type; 87 : typedef ptrdiff_t difference_type; 88 : typedef _Tp* pointer; 89 : typedef const _Tp* const_pointer; 90 : typedef _Tp& reference; 91 : typedef const _Tp& const_reference; 92 : typedef _Tp value_type; 93 : 94 : template<typename _Tp1> 95 : struct rebind 96 : { typedef allocator<_Tp1> other; }; 97 : 98 285441 : allocator() throw() { } 99 : 100 934618 : allocator(const allocator& __a) throw() 101 934618 : : __glibcxx_base_allocator<_Tp>(__a) { } 102 : 103 : template<typename _Tp1> 104 11289504 : allocator(const allocator<_Tp1>&) throw() { } 105 : 106 12615289 : ~allocator() throw() { } 107 : 108 : // Inherit everything else. 109 : }; 110 : 111 : template<typename _T1, typename _T2> 112 : inline bool 113 : operator==(const allocator<_T1>&, const allocator<_T2>&) 114 : { return true; } 115 : 116 : template<typename _Tp> 117 : inline bool 118 0 : operator==(const allocator<_Tp>&, const allocator<_Tp>&) 119 0 : { return true; } 120 : 121 : template<typename _T1, typename _T2> 122 : inline bool 123 : operator!=(const allocator<_T1>&, const allocator<_T2>&) 124 : { return false; } 125 : 126 : template<typename _Tp> 127 : inline bool 128 : operator!=(const allocator<_Tp>&, const allocator<_Tp>&) 129 : { return false; } 130 : 131 : // Inhibit implicit instantiations for required instantiations, 132 : // which are defined via explicit instantiations elsewhere. 133 : // NB: This syntax is a GNU extension. 134 : #if _GLIBCXX_EXTERN_TEMPLATE 135 : extern template class allocator<char>; 136 : extern template class allocator<wchar_t>; 137 : #endif 138 : 139 : // Undefine. 140 : #undef __glibcxx_base_allocator 141 : 142 : // To implement Option 3 of DR 431. 143 : template<typename _Alloc, bool = __is_empty(_Alloc)> 144 : struct __alloc_swap 145 : { static void _S_do_it(_Alloc&, _Alloc&) { } }; 146 : 147 : template<typename _Alloc> 148 : struct __alloc_swap<_Alloc, false> 149 : { 150 : static void 151 : _S_do_it(_Alloc& __one, _Alloc& __two) 152 : { 153 : // Precondition: swappable allocators. 154 : if (__one != __two) 155 : swap(__one, __two); 156 : } 157 : }; 158 : 159 : // Optimize for stateless allocators. 160 : template<typename _Alloc, bool = __is_empty(_Alloc)> 161 : struct __alloc_neq 162 : { 163 : static bool 164 : _S_do_it(const _Alloc&, const _Alloc&) 165 : { return false; } 166 : }; 167 : 168 : template<typename _Alloc> 169 : struct __alloc_neq<_Alloc, false> 170 : { 171 : static bool 172 : _S_do_it(const _Alloc& __one, const _Alloc& __two) 173 : { return __one != __two; } 174 : }; 175 : 176 : _GLIBCXX_END_NAMESPACE 177 : 178 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Iterators -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996-1998 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_iterator.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : * 61 : * This file implements reverse_iterator, back_insert_iterator, 62 : * front_insert_iterator, insert_iterator, __normal_iterator, and their 63 : * supporting functions and overloaded operators. 64 : */ 65 : 66 : #ifndef _STL_ITERATOR_H 67 : #define _STL_ITERATOR_H 1 68 : 69 : #include <bits/cpp_type_traits.h> 70 : #include <ext/type_traits.h> 71 : #include <bits/stl_move.h> 72 : 73 : _GLIBCXX_BEGIN_NAMESPACE(std) 74 : 75 : // 24.4.1 Reverse iterators 76 : /** 77 : * "Bidirectional and random access iterators have corresponding reverse 78 : * %iterator adaptors that iterate through the data structure in the 79 : * opposite direction. They have the same signatures as the corresponding 80 : * iterators. The fundamental relation between a reverse %iterator and its 81 : * corresponding %iterator @c i is established by the identity: 82 : * @code 83 : * &*(reverse_iterator(i)) == &*(i - 1) 84 : * @endcode 85 : * 86 : * This mapping is dictated by the fact that while there is always a 87 : * pointer past the end of an array, there might not be a valid pointer 88 : * before the beginning of an array." [24.4.1]/1,2 89 : * 90 : * Reverse iterators can be tricky and surprising at first. Their 91 : * semantics make sense, however, and the trickiness is a side effect of 92 : * the requirement that the iterators must be safe. 93 : */ 94 : template<typename _Iterator> 95 : class reverse_iterator 96 : : public iterator<typename iterator_traits<_Iterator>::iterator_category, 97 : typename iterator_traits<_Iterator>::value_type, 98 : typename iterator_traits<_Iterator>::difference_type, 99 : typename iterator_traits<_Iterator>::pointer, 100 : typename iterator_traits<_Iterator>::reference> 101 : { 102 : protected: 103 : _Iterator current; 104 : 105 : public: 106 : typedef _Iterator iterator_type; 107 : typedef typename iterator_traits<_Iterator>::difference_type 108 : difference_type; 109 : typedef typename iterator_traits<_Iterator>::reference reference; 110 : typedef typename iterator_traits<_Iterator>::pointer pointer; 111 : 112 : public: 113 : /** 114 : * The default constructor default-initializes member @p current. 115 : * If it is a pointer, that means it is zero-initialized. 116 : */ 117 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 118 : // 235 No specification of default ctor for reverse_iterator 119 : reverse_iterator() : current() { } 120 : 121 : /** 122 : * This %iterator will move in the opposite direction that @p x does. 123 : */ 124 : explicit 125 34 : reverse_iterator(iterator_type __x) : current(__x) { } 126 : 127 : /** 128 : * The copy constructor is normal. 129 : */ 130 : reverse_iterator(const reverse_iterator& __x) 131 : : current(__x.current) { } 132 : 133 : /** 134 : * A reverse_iterator across other types can be copied in the normal 135 : * fashion. 136 : */ 137 : template<typename _Iter> 138 : reverse_iterator(const reverse_iterator<_Iter>& __x) 139 : : current(__x.base()) { } 140 : 141 : /** 142 : * @return @c current, the %iterator used for underlying work. 143 : */ 144 : iterator_type 145 : base() const 146 : { return current; } 147 : 148 : /** 149 : * @return TODO 150 : * 151 : * @doctodo 152 : */ 153 : reference 154 34 : operator*() const 155 : { 156 34 : _Iterator __tmp = current; 157 34 : return *--__tmp; 158 : } 159 : 160 : /** 161 : * @return TODO 162 : * 163 : * @doctodo 164 : */ 165 : pointer 166 32 : operator->() const 167 32 : { return &(operator*()); } 168 : 169 : /** 170 : * @return TODO 171 : * 172 : * @doctodo 173 : */ 174 : reverse_iterator& 175 : operator++() 176 : { 177 : --current; 178 : return *this; 179 : } 180 : 181 : /** 182 : * @return TODO 183 : * 184 : * @doctodo 185 : */ 186 : reverse_iterator 187 : operator++(int) 188 : { 189 : reverse_iterator __tmp = *this; 190 : --current; 191 : return __tmp; 192 : } 193 : 194 : /** 195 : * @return TODO 196 : * 197 : * @doctodo 198 : */ 199 : reverse_iterator& 200 : operator--() 201 : { 202 : ++current; 203 : return *this; 204 : } 205 : 206 : /** 207 : * @return TODO 208 : * 209 : * @doctodo 210 : */ 211 : reverse_iterator 212 : operator--(int) 213 : { 214 : reverse_iterator __tmp = *this; 215 : ++current; 216 : return __tmp; 217 : } 218 : 219 : /** 220 : * @return TODO 221 : * 222 : * @doctodo 223 : */ 224 : reverse_iterator 225 : operator+(difference_type __n) const 226 : { return reverse_iterator(current - __n); } 227 : 228 : /** 229 : * @return TODO 230 : * 231 : * @doctodo 232 : */ 233 : reverse_iterator& 234 : operator+=(difference_type __n) 235 : { 236 : current -= __n; 237 : return *this; 238 : } 239 : 240 : /** 241 : * @return TODO 242 : * 243 : * @doctodo 244 : */ 245 : reverse_iterator 246 : operator-(difference_type __n) const 247 : { return reverse_iterator(current + __n); } 248 : 249 : /** 250 : * @return TODO 251 : * 252 : * @doctodo 253 : */ 254 : reverse_iterator& 255 : operator-=(difference_type __n) 256 : { 257 : current += __n; 258 : return *this; 259 : } 260 : 261 : /** 262 : * @return TODO 263 : * 264 : * @doctodo 265 : */ 266 : reference 267 : operator[](difference_type __n) const 268 : { return *(*this + __n); } 269 : }; 270 : 271 : //@{ 272 : /** 273 : * @param x A %reverse_iterator. 274 : * @param y A %reverse_iterator. 275 : * @return A simple bool. 276 : * 277 : * Reverse iterators forward many operations to their underlying base() 278 : * iterators. Others are implemented in terms of one another. 279 : * 280 : */ 281 : template<typename _Iterator> 282 : inline bool 283 : operator==(const reverse_iterator<_Iterator>& __x, 284 : const reverse_iterator<_Iterator>& __y) 285 : { return __x.base() == __y.base(); } 286 : 287 : template<typename _Iterator> 288 : inline bool 289 : operator<(const reverse_iterator<_Iterator>& __x, 290 : const reverse_iterator<_Iterator>& __y) 291 : { return __y.base() < __x.base(); } 292 : 293 : template<typename _Iterator> 294 : inline bool 295 : operator!=(const reverse_iterator<_Iterator>& __x, 296 : const reverse_iterator<_Iterator>& __y) 297 : { return !(__x == __y); } 298 : 299 : template<typename _Iterator> 300 : inline bool 301 : operator>(const reverse_iterator<_Iterator>& __x, 302 : const reverse_iterator<_Iterator>& __y) 303 : { return __y < __x; } 304 : 305 : template<typename _Iterator> 306 : inline bool 307 : operator<=(const reverse_iterator<_Iterator>& __x, 308 : const reverse_iterator<_Iterator>& __y) 309 : { return !(__y < __x); } 310 : 311 : template<typename _Iterator> 312 : inline bool 313 : operator>=(const reverse_iterator<_Iterator>& __x, 314 : const reverse_iterator<_Iterator>& __y) 315 : { return !(__x < __y); } 316 : 317 : template<typename _Iterator> 318 : inline typename reverse_iterator<_Iterator>::difference_type 319 : operator-(const reverse_iterator<_Iterator>& __x, 320 : const reverse_iterator<_Iterator>& __y) 321 : { return __y.base() - __x.base(); } 322 : 323 : template<typename _Iterator> 324 : inline reverse_iterator<_Iterator> 325 : operator+(typename reverse_iterator<_Iterator>::difference_type __n, 326 : const reverse_iterator<_Iterator>& __x) 327 : { return reverse_iterator<_Iterator>(__x.base() - __n); } 328 : 329 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 330 : // DR 280. Comparison of reverse_iterator to const reverse_iterator. 331 : template<typename _IteratorL, typename _IteratorR> 332 : inline bool 333 : operator==(const reverse_iterator<_IteratorL>& __x, 334 : const reverse_iterator<_IteratorR>& __y) 335 : { return __x.base() == __y.base(); } 336 : 337 : template<typename _IteratorL, typename _IteratorR> 338 : inline bool 339 : operator<(const reverse_iterator<_IteratorL>& __x, 340 : const reverse_iterator<_IteratorR>& __y) 341 : { return __y.base() < __x.base(); } 342 : 343 : template<typename _IteratorL, typename _IteratorR> 344 : inline bool 345 : operator!=(const reverse_iterator<_IteratorL>& __x, 346 : const reverse_iterator<_IteratorR>& __y) 347 : { return !(__x == __y); } 348 : 349 : template<typename _IteratorL, typename _IteratorR> 350 : inline bool 351 : operator>(const reverse_iterator<_IteratorL>& __x, 352 : const reverse_iterator<_IteratorR>& __y) 353 : { return __y < __x; } 354 : 355 : template<typename _IteratorL, typename _IteratorR> 356 : inline bool 357 : operator<=(const reverse_iterator<_IteratorL>& __x, 358 : const reverse_iterator<_IteratorR>& __y) 359 : { return !(__y < __x); } 360 : 361 : template<typename _IteratorL, typename _IteratorR> 362 : inline bool 363 : operator>=(const reverse_iterator<_IteratorL>& __x, 364 : const reverse_iterator<_IteratorR>& __y) 365 : { return !(__x < __y); } 366 : 367 : template<typename _IteratorL, typename _IteratorR> 368 : inline typename reverse_iterator<_IteratorL>::difference_type 369 : operator-(const reverse_iterator<_IteratorL>& __x, 370 : const reverse_iterator<_IteratorR>& __y) 371 : { return __y.base() - __x.base(); } 372 : //@} 373 : 374 : // 24.4.2.2.1 back_insert_iterator 375 : /** 376 : * @brief Turns assignment into insertion. 377 : * 378 : * These are output iterators, constructed from a container-of-T. 379 : * Assigning a T to the iterator appends it to the container using 380 : * push_back. 381 : * 382 : * Tip: Using the back_inserter function to create these iterators can 383 : * save typing. 384 : */ 385 : template<typename _Container> 386 : class back_insert_iterator 387 : : public iterator<output_iterator_tag, void, void, void, void> 388 : { 389 : protected: 390 : _Container* container; 391 : 392 : public: 393 : /// A nested typedef for the type of whatever container you used. 394 : typedef _Container container_type; 395 : 396 : /// The only way to create this %iterator is with a container. 397 : explicit 398 946 : back_insert_iterator(_Container& __x) : container(&__x) { } 399 : 400 : /** 401 : * @param value An instance of whatever type 402 : * container_type::const_reference is; presumably a 403 : * reference-to-const T for container<T>. 404 : * @return This %iterator, for chained operations. 405 : * 406 : * This kind of %iterator doesn't really have a "position" in the 407 : * container (you can think of the position as being permanently at 408 : * the end, if you like). Assigning a value to the %iterator will 409 : * always append the value to the end of the container. 410 : */ 411 : back_insert_iterator& 412 17415 : operator=(typename _Container::const_reference __value) 413 : { 414 17415 : container->push_back(__value); 415 17415 : return *this; 416 : } 417 : 418 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 419 : back_insert_iterator& 420 : operator=(typename _Container::value_type&& __value) 421 : { 422 : container->push_back(std::move(__value)); 423 : return *this; 424 : } 425 : #endif 426 : 427 : /// Simply returns *this. 428 : back_insert_iterator& 429 17419 : operator*() 430 17419 : { return *this; } 431 : 432 : /// Simply returns *this. (This %iterator does not "move".) 433 : back_insert_iterator& 434 17405 : operator++() 435 17405 : { return *this; } 436 : 437 : /// Simply returns *this. (This %iterator does not "move".) 438 : back_insert_iterator 439 10 : operator++(int) 440 10 : { return *this; } 441 : }; 442 : 443 : /** 444 : * @param x A container of arbitrary type. 445 : * @return An instance of back_insert_iterator working on @p x. 446 : * 447 : * This wrapper function helps in creating back_insert_iterator instances. 448 : * Typing the name of the %iterator requires knowing the precise full 449 : * type of the container, which can be tedious and impedes generic 450 : * programming. Using this function lets you take advantage of automatic 451 : * template parameter deduction, making the compiler match the correct 452 : * types for you. 453 : */ 454 : template<typename _Container> 455 : inline back_insert_iterator<_Container> 456 946 : back_inserter(_Container& __x) 457 946 : { return back_insert_iterator<_Container>(__x); } 458 : 459 : /** 460 : * @brief Turns assignment into insertion. 461 : * 462 : * These are output iterators, constructed from a container-of-T. 463 : * Assigning a T to the iterator prepends it to the container using 464 : * push_front. 465 : * 466 : * Tip: Using the front_inserter function to create these iterators can 467 : * save typing. 468 : */ 469 : template<typename _Container> 470 : class front_insert_iterator 471 : : public iterator<output_iterator_tag, void, void, void, void> 472 : { 473 : protected: 474 : _Container* container; 475 : 476 : public: 477 : /// A nested typedef for the type of whatever container you used. 478 : typedef _Container container_type; 479 : 480 : /// The only way to create this %iterator is with a container. 481 : explicit front_insert_iterator(_Container& __x) : container(&__x) { } 482 : 483 : /** 484 : * @param value An instance of whatever type 485 : * container_type::const_reference is; presumably a 486 : * reference-to-const T for container<T>. 487 : * @return This %iterator, for chained operations. 488 : * 489 : * This kind of %iterator doesn't really have a "position" in the 490 : * container (you can think of the position as being permanently at 491 : * the front, if you like). Assigning a value to the %iterator will 492 : * always prepend the value to the front of the container. 493 : */ 494 : front_insert_iterator& 495 : operator=(typename _Container::const_reference __value) 496 : { 497 : container->push_front(__value); 498 : return *this; 499 : } 500 : 501 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 502 : front_insert_iterator& 503 : operator=(typename _Container::value_type&& __value) 504 : { 505 : container->push_front(std::move(__value)); 506 : return *this; 507 : } 508 : #endif 509 : 510 : /// Simply returns *this. 511 : front_insert_iterator& 512 : operator*() 513 : { return *this; } 514 : 515 : /// Simply returns *this. (This %iterator does not "move".) 516 : front_insert_iterator& 517 : operator++() 518 : { return *this; } 519 : 520 : /// Simply returns *this. (This %iterator does not "move".) 521 : front_insert_iterator 522 : operator++(int) 523 : { return *this; } 524 : }; 525 : 526 : /** 527 : * @param x A container of arbitrary type. 528 : * @return An instance of front_insert_iterator working on @p x. 529 : * 530 : * This wrapper function helps in creating front_insert_iterator instances. 531 : * Typing the name of the %iterator requires knowing the precise full 532 : * type of the container, which can be tedious and impedes generic 533 : * programming. Using this function lets you take advantage of automatic 534 : * template parameter deduction, making the compiler match the correct 535 : * types for you. 536 : */ 537 : template<typename _Container> 538 : inline front_insert_iterator<_Container> 539 : front_inserter(_Container& __x) 540 : { return front_insert_iterator<_Container>(__x); } 541 : 542 : /** 543 : * @brief Turns assignment into insertion. 544 : * 545 : * These are output iterators, constructed from a container-of-T. 546 : * Assigning a T to the iterator inserts it in the container at the 547 : * %iterator's position, rather than overwriting the value at that 548 : * position. 549 : * 550 : * (Sequences will actually insert a @e copy of the value before the 551 : * %iterator's position.) 552 : * 553 : * Tip: Using the inserter function to create these iterators can 554 : * save typing. 555 : */ 556 : template<typename _Container> 557 : class insert_iterator 558 : : public iterator<output_iterator_tag, void, void, void, void> 559 : { 560 : protected: 561 : _Container* container; 562 : typename _Container::iterator iter; 563 : 564 : public: 565 : /// A nested typedef for the type of whatever container you used. 566 : typedef _Container container_type; 567 : 568 : /** 569 : * The only way to create this %iterator is with a container and an 570 : * initial position (a normal %iterator into the container). 571 : */ 572 21203 : insert_iterator(_Container& __x, typename _Container::iterator __i) 573 21203 : : container(&__x), iter(__i) {} 574 : 575 : /** 576 : * @param value An instance of whatever type 577 : * container_type::const_reference is; presumably a 578 : * reference-to-const T for container<T>. 579 : * @return This %iterator, for chained operations. 580 : * 581 : * This kind of %iterator maintains its own position in the 582 : * container. Assigning a value to the %iterator will insert the 583 : * value into the container at the place before the %iterator. 584 : * 585 : * The position is maintained such that subsequent assignments will 586 : * insert values immediately after one another. For example, 587 : * @code 588 : * // vector v contains A and Z 589 : * 590 : * insert_iterator i (v, ++v.begin()); 591 : * i = 1; 592 : * i = 2; 593 : * i = 3; 594 : * 595 : * // vector v contains A, 1, 2, 3, and Z 596 : * @endcode 597 : */ 598 : insert_iterator& 599 107622 : operator=(typename _Container::const_reference __value) 600 : { 601 107622 : iter = container->insert(iter, __value); 602 107622 : ++iter; 603 107622 : return *this; 604 : } 605 : 606 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 607 : insert_iterator& 608 : operator=(typename _Container::value_type&& __value) 609 : { 610 : iter = container->insert(iter, std::move(__value)); 611 : ++iter; 612 : return *this; 613 : } 614 : #endif 615 : 616 : /// Simply returns *this. 617 : insert_iterator& 618 107650 : operator*() 619 107650 : { return *this; } 620 : 621 : /// Simply returns *this. (This %iterator does not "move".) 622 : insert_iterator& 623 107622 : operator++() 624 107622 : { return *this; } 625 : 626 : /// Simply returns *this. (This %iterator does not "move".) 627 : insert_iterator& 628 0 : operator++(int) 629 0 : { return *this; } 630 : }; 631 : 632 : /** 633 : * @param x A container of arbitrary type. 634 : * @return An instance of insert_iterator working on @p x. 635 : * 636 : * This wrapper function helps in creating insert_iterator instances. 637 : * Typing the name of the %iterator requires knowing the precise full 638 : * type of the container, which can be tedious and impedes generic 639 : * programming. Using this function lets you take advantage of automatic 640 : * template parameter deduction, making the compiler match the correct 641 : * types for you. 642 : */ 643 : template<typename _Container, typename _Iterator> 644 : inline insert_iterator<_Container> 645 21203 : inserter(_Container& __x, _Iterator __i) 646 : { 647 : return insert_iterator<_Container>(__x, 648 21203 : typename _Container::iterator(__i)); 649 : } 650 : 651 : _GLIBCXX_END_NAMESPACE 652 : 653 : _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 654 : 655 : // This iterator adapter is 'normal' in the sense that it does not 656 : // change the semantics of any of the operators of its iterator 657 : // parameter. Its primary purpose is to convert an iterator that is 658 : // not a class, e.g. a pointer, into an iterator that is a class. 659 : // The _Container parameter exists solely so that different containers 660 : // using this template can instantiate different types, even if the 661 : // _Iterator parameter is the same. 662 : using std::iterator_traits; 663 : using std::iterator; 664 : template<typename _Iterator, typename _Container> 665 : class __normal_iterator 666 : { 667 : protected: 668 : _Iterator _M_current; 669 : 670 : public: 671 : typedef _Iterator iterator_type; 672 : typedef typename iterator_traits<_Iterator>::iterator_category 673 : iterator_category; 674 : typedef typename iterator_traits<_Iterator>::value_type value_type; 675 : typedef typename iterator_traits<_Iterator>::difference_type 676 : difference_type; 677 : typedef typename iterator_traits<_Iterator>::reference reference; 678 : typedef typename iterator_traits<_Iterator>::pointer pointer; 679 : 680 3 : __normal_iterator() : _M_current(_Iterator()) { } 681 : 682 : explicit 683 150393 : __normal_iterator(const _Iterator& __i) : _M_current(__i) { } 684 : 685 : // Allow iterator to const_iterator conversion 686 : template<typename _Iter> 687 : __normal_iterator(const __normal_iterator<_Iter, 688 : typename __enable_if< 689 : (std::__are_same<_Iter, typename _Container::pointer>::__value), 690 28 : _Container>::__type>& __i) 691 28 : : _M_current(__i.base()) { } 692 : 693 : // Forward iterator requirements 694 : reference 695 925025 : operator*() const 696 925025 : { return *_M_current; } 697 : 698 : pointer 699 3 : operator->() const 700 3 : { return _M_current; } 701 : 702 : __normal_iterator& 703 81617 : operator++() 704 : { 705 81617 : ++_M_current; 706 81617 : return *this; 707 : } 708 : 709 : __normal_iterator 710 54836 : operator++(int) 711 54836 : { return __normal_iterator(_M_current++); } 712 : 713 : // Bidirectional iterator requirements 714 : __normal_iterator& 715 249605 : operator--() 716 : { 717 249605 : --_M_current; 718 249605 : return *this; 719 : } 720 : 721 : __normal_iterator 722 0 : operator--(int) 723 0 : { return __normal_iterator(_M_current--); } 724 : 725 : // Random access iterator requirements 726 : reference 727 : operator[](const difference_type& __n) const 728 : { return _M_current[__n]; } 729 : 730 : __normal_iterator& 731 : operator+=(const difference_type& __n) 732 : { _M_current += __n; return *this; } 733 : 734 : __normal_iterator 735 13455 : operator+(const difference_type& __n) const 736 13455 : { return __normal_iterator(_M_current + __n); } 737 : 738 : __normal_iterator& 739 : operator-=(const difference_type& __n) 740 : { _M_current -= __n; return *this; } 741 : 742 : __normal_iterator 743 846 : operator-(const difference_type& __n) const 744 846 : { return __normal_iterator(_M_current - __n); } 745 : 746 : const _Iterator& 747 455202 : base() const 748 455202 : { return _M_current; } 749 : }; 750 : 751 : // Note: In what follows, the left- and right-hand-side iterators are 752 : // allowed to vary in types (conceptually in cv-qualification) so that 753 : // comparison between cv-qualified and non-cv-qualified iterators be 754 : // valid. However, the greedy and unfriendly operators in std::rel_ops 755 : // will make overload resolution ambiguous (when in scope) if we don't 756 : // provide overloads whose operands are of the same type. Can someone 757 : // remind me what generic programming is about? -- Gaby 758 : 759 : // Forward iterator requirements 760 : template<typename _IteratorL, typename _IteratorR, typename _Container> 761 : inline bool 762 : operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, 763 : const __normal_iterator<_IteratorR, _Container>& __rhs) 764 : { return __lhs.base() == __rhs.base(); } 765 : 766 : template<typename _Iterator, typename _Container> 767 : inline bool 768 : operator==(const __normal_iterator<_Iterator, _Container>& __lhs, 769 4368 : const __normal_iterator<_Iterator, _Container>& __rhs) 770 4368 : { return __lhs.base() == __rhs.base(); } 771 : 772 : template<typename _IteratorL, typename _IteratorR, typename _Container> 773 : inline bool 774 : operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, 775 38 : const __normal_iterator<_IteratorR, _Container>& __rhs) 776 38 : { return __lhs.base() != __rhs.base(); } 777 : 778 : template<typename _Iterator, typename _Container> 779 : inline bool 780 : operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, 781 123290 : const __normal_iterator<_Iterator, _Container>& __rhs) 782 123290 : { return __lhs.base() != __rhs.base(); } 783 : 784 : // Random access iterator requirements 785 : template<typename _IteratorL, typename _IteratorR, typename _Container> 786 : inline bool 787 : operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, 788 : const __normal_iterator<_IteratorR, _Container>& __rhs) 789 : { return __lhs.base() < __rhs.base(); } 790 : 791 : template<typename _Iterator, typename _Container> 792 : inline bool 793 : operator<(const __normal_iterator<_Iterator, _Container>& __lhs, 794 7923 : const __normal_iterator<_Iterator, _Container>& __rhs) 795 7923 : { return __lhs.base() < __rhs.base(); } 796 : 797 : template<typename _IteratorL, typename _IteratorR, typename _Container> 798 : inline bool 799 : operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, 800 : const __normal_iterator<_IteratorR, _Container>& __rhs) 801 : { return __lhs.base() > __rhs.base(); } 802 : 803 : template<typename _Iterator, typename _Container> 804 : inline bool 805 : operator>(const __normal_iterator<_Iterator, _Container>& __lhs, 806 : const __normal_iterator<_Iterator, _Container>& __rhs) 807 : { return __lhs.base() > __rhs.base(); } 808 : 809 : template<typename _IteratorL, typename _IteratorR, typename _Container> 810 : inline bool 811 : operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, 812 : const __normal_iterator<_IteratorR, _Container>& __rhs) 813 : { return __lhs.base() <= __rhs.base(); } 814 : 815 : template<typename _Iterator, typename _Container> 816 : inline bool 817 : operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, 818 : const __normal_iterator<_Iterator, _Container>& __rhs) 819 : { return __lhs.base() <= __rhs.base(); } 820 : 821 : template<typename _IteratorL, typename _IteratorR, typename _Container> 822 : inline bool 823 : operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, 824 : const __normal_iterator<_IteratorR, _Container>& __rhs) 825 : { return __lhs.base() >= __rhs.base(); } 826 : 827 : template<typename _Iterator, typename _Container> 828 : inline bool 829 : operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, 830 : const __normal_iterator<_Iterator, _Container>& __rhs) 831 : { return __lhs.base() >= __rhs.base(); } 832 : 833 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 834 : // According to the resolution of DR179 not only the various comparison 835 : // operators but also operator- must accept mixed iterator/const_iterator 836 : // parameters. 837 : template<typename _IteratorL, typename _IteratorR, typename _Container> 838 : inline typename __normal_iterator<_IteratorL, _Container>::difference_type 839 : operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, 840 : const __normal_iterator<_IteratorR, _Container>& __rhs) 841 : { return __lhs.base() - __rhs.base(); } 842 : 843 : template<typename _Iterator, typename _Container> 844 : inline typename __normal_iterator<_Iterator, _Container>::difference_type 845 : operator-(const __normal_iterator<_Iterator, _Container>& __lhs, 846 37193 : const __normal_iterator<_Iterator, _Container>& __rhs) 847 37193 : { return __lhs.base() - __rhs.base(); } 848 : 849 : template<typename _Iterator, typename _Container> 850 : inline __normal_iterator<_Iterator, _Container> 851 : operator+(typename __normal_iterator<_Iterator, _Container>::difference_type 852 : __n, const __normal_iterator<_Iterator, _Container>& __i) 853 : { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } 854 : 855 : _GLIBCXX_END_NAMESPACE 856 : 857 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 858 : 859 : _GLIBCXX_BEGIN_NAMESPACE(std) 860 : 861 : // 24.4.3 Move iterators 862 : /** 863 : * Class template move_iterator is an iterator adapter with the same 864 : * behavior as the underlying iterator except that its dereference 865 : * operator implicitly converts the value returned by the underlying 866 : * iterator's dereference operator to an rvalue reference. Some 867 : * generic algorithms can be called with move iterators to replace 868 : * copying with moving. 869 : */ 870 : template<typename _Iterator> 871 : class move_iterator 872 : { 873 : protected: 874 : _Iterator _M_current; 875 : 876 : public: 877 : typedef _Iterator iterator_type; 878 : typedef typename iterator_traits<_Iterator>::difference_type 879 : difference_type; 880 : // NB: DR 680. 881 : typedef _Iterator pointer; 882 : typedef typename iterator_traits<_Iterator>::value_type value_type; 883 : typedef typename iterator_traits<_Iterator>::iterator_category 884 : iterator_category; 885 : typedef value_type&& reference; 886 : 887 : public: 888 : move_iterator() 889 : : _M_current() { } 890 : 891 : explicit 892 : move_iterator(iterator_type __i) 893 : : _M_current(__i) { } 894 : 895 : template<typename _Iter> 896 : move_iterator(const move_iterator<_Iter>& __i) 897 : : _M_current(__i.base()) { } 898 : 899 : iterator_type 900 : base() const 901 : { return _M_current; } 902 : 903 : reference 904 : operator*() const 905 : { return *_M_current; } 906 : 907 : pointer 908 : operator->() const 909 : { return _M_current; } 910 : 911 : move_iterator& 912 : operator++() 913 : { 914 : ++_M_current; 915 : return *this; 916 : } 917 : 918 : move_iterator 919 : operator++(int) 920 : { 921 : move_iterator __tmp = *this; 922 : ++_M_current; 923 : return __tmp; 924 : } 925 : 926 : move_iterator& 927 : operator--() 928 : { 929 : --_M_current; 930 : return *this; 931 : } 932 : 933 : move_iterator 934 : operator--(int) 935 : { 936 : move_iterator __tmp = *this; 937 : --_M_current; 938 : return __tmp; 939 : } 940 : 941 : move_iterator 942 : operator+(difference_type __n) const 943 : { return move_iterator(_M_current + __n); } 944 : 945 : move_iterator& 946 : operator+=(difference_type __n) 947 : { 948 : _M_current += __n; 949 : return *this; 950 : } 951 : 952 : move_iterator 953 : operator-(difference_type __n) const 954 : { return move_iterator(_M_current - __n); } 955 : 956 : move_iterator& 957 : operator-=(difference_type __n) 958 : { 959 : _M_current -= __n; 960 : return *this; 961 : } 962 : 963 : reference 964 : operator[](difference_type __n) const 965 : { return _M_current[__n]; } 966 : }; 967 : 968 : template<typename _IteratorL, typename _IteratorR> 969 : inline bool 970 : operator==(const move_iterator<_IteratorL>& __x, 971 : const move_iterator<_IteratorR>& __y) 972 : { return __x.base() == __y.base(); } 973 : 974 : template<typename _IteratorL, typename _IteratorR> 975 : inline bool 976 : operator!=(const move_iterator<_IteratorL>& __x, 977 : const move_iterator<_IteratorR>& __y) 978 : { return !(__x == __y); } 979 : 980 : template<typename _IteratorL, typename _IteratorR> 981 : inline bool 982 : operator<(const move_iterator<_IteratorL>& __x, 983 : const move_iterator<_IteratorR>& __y) 984 : { return __x.base() < __y.base(); } 985 : 986 : template<typename _IteratorL, typename _IteratorR> 987 : inline bool 988 : operator<=(const move_iterator<_IteratorL>& __x, 989 : const move_iterator<_IteratorR>& __y) 990 : { return !(__y < __x); } 991 : 992 : template<typename _IteratorL, typename _IteratorR> 993 : inline bool 994 : operator>(const move_iterator<_IteratorL>& __x, 995 : const move_iterator<_IteratorR>& __y) 996 : { return __y < __x; } 997 : 998 : template<typename _IteratorL, typename _IteratorR> 999 : inline bool 1000 : operator>=(const move_iterator<_IteratorL>& __x, 1001 : const move_iterator<_IteratorR>& __y) 1002 : { return !(__x < __y); } 1003 : 1004 : template<typename _IteratorL, typename _IteratorR> 1005 : inline typename move_iterator<_IteratorL>::difference_type 1006 : operator-(const move_iterator<_IteratorL>& __x, 1007 : const move_iterator<_IteratorR>& __y) 1008 : { return __x.base() - __y.base(); } 1009 : 1010 : template<typename _Iterator> 1011 : inline move_iterator<_Iterator> 1012 : operator+(typename move_iterator<_Iterator>::difference_type __n, 1013 : const move_iterator<_Iterator>& __x) 1014 : { return __x + __n; } 1015 : 1016 : template<typename _Iterator> 1017 : inline move_iterator<_Iterator> 1018 : make_move_iterator(const _Iterator& __i) 1019 : { return move_iterator<_Iterator>(__i); } 1020 : 1021 : _GLIBCXX_END_NAMESPACE 1022 : 1023 : #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) std::make_move_iterator(_Iter) 1024 : #else 1025 : #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) (_Iter) 1026 : #endif // __GXX_EXPERIMENTAL_CXX0X__ 1027 : 1028 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Stream iterators 2 : 3 : // Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc. 4 : // 5 : // This file is part of the GNU ISO C++ Library. This library is free 6 : // software; you can redistribute it and/or modify it under the 7 : // terms of the GNU General Public License as published by the 8 : // Free Software Foundation; either version 2, or (at your option) 9 : // any later version. 10 : 11 : // This library is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : 16 : // You should have received a copy of the GNU General Public License along 17 : // with this library; see the file COPYING. If not, write to the Free 18 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19 : // USA. 20 : 21 : // As a special exception, you may use this file as part of a free software 22 : // library without restriction. Specifically, if other files instantiate 23 : // templates or use macros or inline functions from this file, or you compile 24 : // this file and link it with other files to produce an executable, this 25 : // file does not by itself cause the resulting executable to be covered by 26 : // the GNU General Public License. This exception does not however 27 : // invalidate any other reasons why the executable file might be covered by 28 : // the GNU General Public License. 29 : 30 : /** @file stream_iterator.h 31 : * This is an internal header file, included by other library headers. 32 : * You should not attempt to use it directly. 33 : */ 34 : 35 : #ifndef _STREAM_ITERATOR_H 36 : #define _STREAM_ITERATOR_H 1 37 : 38 : #pragma GCC system_header 39 : 40 : #include <debug/debug.h> 41 : 42 : _GLIBCXX_BEGIN_NAMESPACE(std) 43 : 44 : /// Provides input iterator semantics for streams. 45 : template<typename _Tp, typename _CharT = char, 46 : typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t> 47 : class istream_iterator 48 : : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&> 49 32 : { 50 : public: 51 : typedef _CharT char_type; 52 : typedef _Traits traits_type; 53 : typedef basic_istream<_CharT, _Traits> istream_type; 54 : 55 : private: 56 : istream_type* _M_stream; 57 : _Tp _M_value; 58 : bool _M_ok; 59 : 60 : public: 61 : /// Construct end of input stream iterator. 62 16 : istream_iterator() 63 16 : : _M_stream(0), _M_value(), _M_ok(false) {} 64 : 65 : /// Construct start of input stream iterator. 66 16 : istream_iterator(istream_type& __s) 67 16 : : _M_stream(&__s) 68 16 : { _M_read(); } 69 : 70 : istream_iterator(const istream_iterator& __obj) 71 : : _M_stream(__obj._M_stream), _M_value(__obj._M_value), 72 : _M_ok(__obj._M_ok) 73 : { } 74 : 75 : const _Tp& 76 112 : operator*() const 77 : { 78 : __glibcxx_requires_cond(_M_ok, 79 : _M_message(__gnu_debug::__msg_deref_istream) 80 : ._M_iterator(*this)); 81 112 : return _M_value; 82 : } 83 : 84 : const _Tp* 85 : operator->() const { return &(operator*()); } 86 : 87 : istream_iterator& 88 64 : operator++() 89 : { 90 : __glibcxx_requires_cond(_M_ok, 91 : _M_message(__gnu_debug::__msg_inc_istream) 92 : ._M_iterator(*this)); 93 64 : _M_read(); 94 64 : return *this; 95 : } 96 : 97 : istream_iterator 98 : operator++(int) 99 : { 100 : __glibcxx_requires_cond(_M_ok, 101 : _M_message(__gnu_debug::__msg_inc_istream) 102 : ._M_iterator(*this)); 103 : istream_iterator __tmp = *this; 104 : _M_read(); 105 : return __tmp; 106 : } 107 : 108 : bool 109 80 : _M_equal(const istream_iterator& __x) const 110 80 : { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); } 111 : 112 : private: 113 : void 114 80 : _M_read() 115 : { 116 80 : _M_ok = (_M_stream && *_M_stream) ? true : false; 117 80 : if (_M_ok) 118 : { 119 80 : *_M_stream >> _M_value; 120 80 : _M_ok = *_M_stream ? true : false; 121 : } 122 80 : } 123 : }; 124 : 125 : /// Return true if x and y are both end or not end, or x and y are the same. 126 : template<typename _Tp, typename _CharT, typename _Traits, typename _Dist> 127 : inline bool 128 : operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, 129 : const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) 130 : { return __x._M_equal(__y); } 131 : 132 : /// Return false if x and y are both end or not end, or x and y are the same. 133 : template <class _Tp, class _CharT, class _Traits, class _Dist> 134 : inline bool 135 : operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, 136 80 : const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) 137 80 : { return !__x._M_equal(__y); } 138 : 139 : /** 140 : * @brief Provides output iterator semantics for streams. 141 : * 142 : * This class provides an iterator to write to an ostream. The type Tp is 143 : * the only type written by this iterator and there must be an 144 : * operator<<(Tp) defined. 145 : * 146 : * @param Tp The type to write to the ostream. 147 : * @param CharT The ostream char_type. 148 : * @param Traits The ostream char_traits. 149 : */ 150 : template<typename _Tp, typename _CharT = char, 151 : typename _Traits = char_traits<_CharT> > 152 : class ostream_iterator 153 : : public iterator<output_iterator_tag, void, void, void, void> 154 : { 155 : public: 156 : //@{ 157 : /// Public typedef 158 : typedef _CharT char_type; 159 : typedef _Traits traits_type; 160 : typedef basic_ostream<_CharT, _Traits> ostream_type; 161 : //@} 162 : 163 : private: 164 : ostream_type* _M_stream; 165 : const _CharT* _M_string; 166 : 167 : public: 168 : /// Construct from an ostream. 169 : ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {} 170 : 171 : /** 172 : * Construct from an ostream. 173 : * 174 : * The delimiter string @a c is written to the stream after every Tp 175 : * written to the stream. The delimiter is not copied, and thus must 176 : * not be destroyed while this iterator is in use. 177 : * 178 : * @param s Underlying ostream to write to. 179 : * @param c CharT delimiter string to insert. 180 : */ 181 5 : ostream_iterator(ostream_type& __s, const _CharT* __c) 182 5 : : _M_stream(&__s), _M_string(__c) { } 183 : 184 : /// Copy constructor. 185 25 : ostream_iterator(const ostream_iterator& __obj) 186 25 : : _M_stream(__obj._M_stream), _M_string(__obj._M_string) { } 187 : 188 : /// Writes @a value to underlying ostream using operator<<. If 189 : /// constructed with delimiter string, writes delimiter to ostream. 190 : ostream_iterator& 191 8 : operator=(const _Tp& __value) 192 : { 193 : __glibcxx_requires_cond(_M_stream != 0, 194 : _M_message(__gnu_debug::__msg_output_ostream) 195 : ._M_iterator(*this)); 196 8 : *_M_stream << __value; 197 8 : if (_M_string) *_M_stream << _M_string; 198 8 : return *this; 199 : } 200 : 201 : ostream_iterator& 202 8 : operator*() 203 8 : { return *this; } 204 : 205 : ostream_iterator& 206 8 : operator++() 207 8 : { return *this; } 208 : 209 : ostream_iterator& 210 : operator++(int) 211 : { return *this; } 212 : }; 213 : 214 : _GLIBCXX_END_NAMESPACE 215 : 216 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Map implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996,1997 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_map.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_MAP_H 63 : #define _STL_MAP_H 1 64 : 65 : #include <bits/functexcept.h> 66 : #include <bits/concept_check.h> 67 : 68 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) 69 : 70 : /** 71 : * @brief A standard container made up of (key,value) pairs, which can be 72 : * retrieved based on a key, in logarithmic time. 73 : * 74 : * @ingroup Containers 75 : * @ingroup Assoc_containers 76 : * 77 : * Meets the requirements of a <a href="tables.html#65">container</a>, a 78 : * <a href="tables.html#66">reversible container</a>, and an 79 : * <a href="tables.html#69">associative container</a> (using unique keys). 80 : * For a @c map<Key,T> the key_type is Key, the mapped_type is T, and the 81 : * value_type is std::pair<const Key,T>. 82 : * 83 : * Maps support bidirectional iterators. 84 : * 85 : * The private tree data is declared exactly the same way for map and 86 : * multimap; the distinction is made entirely in how the tree functions are 87 : * called (*_unique versus *_equal, same as the standard). 88 : */ 89 : template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>, 90 : typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > 91 : class map 92 12304 : { 93 : public: 94 : typedef _Key key_type; 95 : typedef _Tp mapped_type; 96 : typedef std::pair<const _Key, _Tp> value_type; 97 : typedef _Compare key_compare; 98 : typedef _Alloc allocator_type; 99 : 100 : private: 101 : // concept requirements 102 : typedef typename _Alloc::value_type _Alloc_value_type; 103 : __glibcxx_class_requires(_Tp, _SGIAssignableConcept) 104 : __glibcxx_class_requires4(_Compare, bool, _Key, _Key, 105 : _BinaryFunctionConcept) 106 : __glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept) 107 : 108 : public: 109 : class value_compare 110 : : public std::binary_function<value_type, value_type, bool> 111 : { 112 : friend class map<_Key, _Tp, _Compare, _Alloc>; 113 : protected: 114 : _Compare comp; 115 : 116 : value_compare(_Compare __c) 117 : : comp(__c) { } 118 : 119 : public: 120 : bool operator()(const value_type& __x, const value_type& __y) const 121 : { return comp(__x.first, __y.first); } 122 : }; 123 : 124 : private: 125 : /// This turns a red-black tree into a [multi]map. 126 : typedef typename _Alloc::template rebind<value_type>::other 127 : _Pair_alloc_type; 128 : 129 : typedef _Rb_tree<key_type, value_type, _Select1st<value_type>, 130 : key_compare, _Pair_alloc_type> _Rep_type; 131 : 132 : /// The actual tree structure. 133 : _Rep_type _M_t; 134 : 135 : public: 136 : // many of these are specified differently in ISO, but the following are 137 : // "functionally equivalent" 138 : typedef typename _Pair_alloc_type::pointer pointer; 139 : typedef typename _Pair_alloc_type::const_pointer const_pointer; 140 : typedef typename _Pair_alloc_type::reference reference; 141 : typedef typename _Pair_alloc_type::const_reference const_reference; 142 : typedef typename _Rep_type::iterator iterator; 143 : typedef typename _Rep_type::const_iterator const_iterator; 144 : typedef typename _Rep_type::size_type size_type; 145 : typedef typename _Rep_type::difference_type difference_type; 146 : typedef typename _Rep_type::reverse_iterator reverse_iterator; 147 : typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; 148 : 149 : // [23.3.1.1] construct/copy/destroy 150 : // (get_allocator() is normally listed in this section, but seems to have 151 : // been accidentally omitted in the printed standard) 152 : /** 153 : * @brief Default constructor creates no elements. 154 : */ 155 2859 : map() 156 2859 : : _M_t() { } 157 : 158 : /** 159 : * @brief Creates a %map with no elements. 160 : * @param comp A comparison object. 161 : * @param a An allocator object. 162 : */ 163 : explicit 164 : map(const _Compare& __comp, 165 : const allocator_type& __a = allocator_type()) 166 : : _M_t(__comp, __a) { } 167 : 168 : /** 169 : * @brief %Map copy constructor. 170 : * @param x A %map of identical element and allocator types. 171 : * 172 : * The newly-created %map uses a copy of the allocation object 173 : * used by @a x. 174 : */ 175 9445 : map(const map& __x) 176 9445 : : _M_t(__x._M_t) { } 177 : 178 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 179 : /** 180 : * @brief %Map move constructor. 181 : * @param x A %map of identical element and allocator types. 182 : * 183 : * The newly-created %map contains the exact contents of @a x. 184 : * The contents of @a x are a valid, but unspecified %map. 185 : */ 186 : map(map&& __x) 187 : : _M_t(std::forward<_Rep_type>(__x._M_t)) { } 188 : #endif 189 : 190 : /** 191 : * @brief Builds a %map from a range. 192 : * @param first An input iterator. 193 : * @param last An input iterator. 194 : * 195 : * Create a %map consisting of copies of the elements from [first,last). 196 : * This is linear in N if the range is already sorted, and NlogN 197 : * otherwise (where N is distance(first,last)). 198 : */ 199 : template<typename _InputIterator> 200 : map(_InputIterator __first, _InputIterator __last) 201 : : _M_t() 202 : { _M_t._M_insert_unique(__first, __last); } 203 : 204 : /** 205 : * @brief Builds a %map from a range. 206 : * @param first An input iterator. 207 : * @param last An input iterator. 208 : * @param comp A comparison functor. 209 : * @param a An allocator object. 210 : * 211 : * Create a %map consisting of copies of the elements from [first,last). 212 : * This is linear in N if the range is already sorted, and NlogN 213 : * otherwise (where N is distance(first,last)). 214 : */ 215 : template<typename _InputIterator> 216 : map(_InputIterator __first, _InputIterator __last, 217 : const _Compare& __comp, 218 : const allocator_type& __a = allocator_type()) 219 : : _M_t(__comp, __a) 220 : { _M_t._M_insert_unique(__first, __last); } 221 : 222 : // FIXME There is no dtor declared, but we should have something 223 : // generated by Doxygen. I don't know what tags to add to this 224 : // paragraph to make that happen: 225 : /** 226 : * The dtor only erases the elements, and note that if the elements 227 : * themselves are pointers, the pointed-to memory is not touched in any 228 : * way. Managing the pointer is the user's responsibility. 229 : */ 230 : 231 : /** 232 : * @brief %Map assignment operator. 233 : * @param x A %map of identical element and allocator types. 234 : * 235 : * All the elements of @a x are copied, but unlike the copy constructor, 236 : * the allocator object is not copied. 237 : */ 238 : map& 239 17 : operator=(const map& __x) 240 : { 241 17 : _M_t = __x._M_t; 242 17 : return *this; 243 : } 244 : 245 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 246 : /** 247 : * @brief %Map move assignment operator. 248 : * @param x A %map of identical element and allocator types. 249 : * 250 : * The contents of @a x are moved into this map (without copying). 251 : * @a x is a valid, but unspecified %map. 252 : */ 253 : map& 254 : operator=(map&& __x) 255 : { 256 : // NB: DR 675. 257 : this->clear(); 258 : this->swap(__x); 259 : return *this; 260 : } 261 : #endif 262 : 263 : /// Get a copy of the memory allocation object. 264 : allocator_type 265 : get_allocator() const 266 : { return _M_t.get_allocator(); } 267 : 268 : // iterators 269 : /** 270 : * Returns a read/write iterator that points to the first pair in the 271 : * %map. 272 : * Iteration is done in ascending order according to the keys. 273 : */ 274 : iterator 275 2681 : begin() 276 2681 : { return _M_t.begin(); } 277 : 278 : /** 279 : * Returns a read-only (constant) iterator that points to the first pair 280 : * in the %map. Iteration is done in ascending order according to the 281 : * keys. 282 : */ 283 : const_iterator 284 154 : begin() const 285 154 : { return _M_t.begin(); } 286 : 287 : /** 288 : * Returns a read/write iterator that points one past the last 289 : * pair in the %map. Iteration is done in ascending order 290 : * according to the keys. 291 : */ 292 : iterator 293 155879 : end() 294 155879 : { return _M_t.end(); } 295 : 296 : /** 297 : * Returns a read-only (constant) iterator that points one past the last 298 : * pair in the %map. Iteration is done in ascending order according to 299 : * the keys. 300 : */ 301 : const_iterator 302 441802 : end() const 303 441802 : { return _M_t.end(); } 304 : 305 : /** 306 : * Returns a read/write reverse iterator that points to the last pair in 307 : * the %map. Iteration is done in descending order according to the 308 : * keys. 309 : */ 310 : reverse_iterator 311 : rbegin() 312 : { return _M_t.rbegin(); } 313 : 314 : /** 315 : * Returns a read-only (constant) reverse iterator that points to the 316 : * last pair in the %map. Iteration is done in descending order 317 : * according to the keys. 318 : */ 319 : const_reverse_iterator 320 32 : rbegin() const 321 32 : { return _M_t.rbegin(); } 322 : 323 : /** 324 : * Returns a read/write reverse iterator that points to one before the 325 : * first pair in the %map. Iteration is done in descending order 326 : * according to the keys. 327 : */ 328 : reverse_iterator 329 : rend() 330 : { return _M_t.rend(); } 331 : 332 : /** 333 : * Returns a read-only (constant) reverse iterator that points to one 334 : * before the first pair in the %map. Iteration is done in descending 335 : * order according to the keys. 336 : */ 337 : const_reverse_iterator 338 : rend() const 339 : { return _M_t.rend(); } 340 : 341 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 342 : /** 343 : * Returns a read-only (constant) iterator that points to the first pair 344 : * in the %map. Iteration is done in ascending order according to the 345 : * keys. 346 : */ 347 : const_iterator 348 : cbegin() const 349 : { return _M_t.begin(); } 350 : 351 : /** 352 : * Returns a read-only (constant) iterator that points one past the last 353 : * pair in the %map. Iteration is done in ascending order according to 354 : * the keys. 355 : */ 356 : const_iterator 357 : cend() const 358 : { return _M_t.end(); } 359 : 360 : /** 361 : * Returns a read-only (constant) reverse iterator that points to the 362 : * last pair in the %map. Iteration is done in descending order 363 : * according to the keys. 364 : */ 365 : const_reverse_iterator 366 : crbegin() const 367 : { return _M_t.rbegin(); } 368 : 369 : /** 370 : * Returns a read-only (constant) reverse iterator that points to one 371 : * before the first pair in the %map. Iteration is done in descending 372 : * order according to the keys. 373 : */ 374 : const_reverse_iterator 375 : crend() const 376 : { return _M_t.rend(); } 377 : #endif 378 : 379 : // capacity 380 : /** Returns true if the %map is empty. (Thus begin() would equal 381 : * end().) 382 : */ 383 : bool 384 3939 : empty() const 385 3939 : { return _M_t.empty(); } 386 : 387 : /** Returns the size of the %map. */ 388 : size_type 389 20 : size() const 390 20 : { return _M_t.size(); } 391 : 392 : /** Returns the maximum size of the %map. */ 393 : size_type 394 : max_size() const 395 : { return _M_t.max_size(); } 396 : 397 : // [23.3.1.2] element access 398 : /** 399 : * @brief Subscript ( @c [] ) access to %map data. 400 : * @param k The key for which data should be retrieved. 401 : * @return A reference to the data of the (key,data) %pair. 402 : * 403 : * Allows for easy lookup with the subscript ( @c [] ) 404 : * operator. Returns data associated with the key specified in 405 : * subscript. If the key does not exist, a pair with that key 406 : * is created using default values, which is then returned. 407 : * 408 : * Lookup requires logarithmic time. 409 : */ 410 : mapped_type& 411 6297 : operator[](const key_type& __k) 412 : { 413 : // concept requirements 414 : __glibcxx_function_requires(_DefaultConstructibleConcept<mapped_type>) 415 : 416 6297 : iterator __i = lower_bound(__k); 417 : // __i->first is greater than or equivalent to __k. 418 6297 : if (__i == end() || key_comp()(__k, (*__i).first)) 419 4149 : __i = insert(__i, value_type(__k, mapped_type())); 420 6297 : return (*__i).second; 421 : } 422 : 423 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 424 : // DR 464. Suggestion for new member functions in standard containers. 425 : /** 426 : * @brief Access to %map data. 427 : * @param k The key for which data should be retrieved. 428 : * @return A reference to the data whose key is equivalent to @a k, if 429 : * such a data is present in the %map. 430 : * @throw std::out_of_range If no such data is present. 431 : */ 432 : mapped_type& 433 : at(const key_type& __k) 434 : { 435 : iterator __i = lower_bound(__k); 436 : if (__i == end() || key_comp()(__k, (*__i).first)) 437 : __throw_out_of_range(__N("map::at")); 438 : return (*__i).second; 439 : } 440 : 441 : const mapped_type& 442 : at(const key_type& __k) const 443 : { 444 : const_iterator __i = lower_bound(__k); 445 : if (__i == end() || key_comp()(__k, (*__i).first)) 446 : __throw_out_of_range(__N("map::at")); 447 : return (*__i).second; 448 : } 449 : 450 : // modifiers 451 : /** 452 : * @brief Attempts to insert a std::pair into the %map. 453 : 454 : * @param x Pair to be inserted (see std::make_pair for easy creation 455 : * of pairs). 456 : 457 : * @return A pair, of which the first element is an iterator that 458 : * points to the possibly inserted pair, and the second is 459 : * a bool that is true if the pair was actually inserted. 460 : * 461 : * This function attempts to insert a (key, value) %pair into the %map. 462 : * A %map relies on unique keys and thus a %pair is only inserted if its 463 : * first element (the key) is not already present in the %map. 464 : * 465 : * Insertion requires logarithmic time. 466 : */ 467 : std::pair<iterator, bool> 468 101375 : insert(const value_type& __x) 469 101375 : { return _M_t._M_insert_unique(__x); } 470 : 471 : /** 472 : * @brief Attempts to insert a std::pair into the %map. 473 : * @param position An iterator that serves as a hint as to where the 474 : * pair should be inserted. 475 : * @param x Pair to be inserted (see std::make_pair for easy creation 476 : * of pairs). 477 : * @return An iterator that points to the element with key of @a x (may 478 : * or may not be the %pair passed in). 479 : * 480 : 481 : * This function is not concerned about whether the insertion 482 : * took place, and thus does not return a boolean like the 483 : * single-argument insert() does. Note that the first 484 : * parameter is only a hint and can potentially improve the 485 : * performance of the insertion process. A bad hint would 486 : * cause no gains in efficiency. 487 : * 488 : * See 489 : * http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 490 : * for more on "hinting". 491 : * 492 : * Insertion requires logarithmic time (if the hint is not taken). 493 : */ 494 : iterator 495 4149 : insert(iterator __position, const value_type& __x) 496 4149 : { return _M_t._M_insert_unique_(__position, __x); } 497 : 498 : /** 499 : * @brief Template function that attempts to insert a range of elements. 500 : * @param first Iterator pointing to the start of the range to be 501 : * inserted. 502 : * @param last Iterator pointing to the end of the range. 503 : * 504 : * Complexity similar to that of the range constructor. 505 : */ 506 : template<typename _InputIterator> 507 : void 508 : insert(_InputIterator __first, _InputIterator __last) 509 : { _M_t._M_insert_unique(__first, __last); } 510 : 511 : /** 512 : * @brief Erases an element from a %map. 513 : * @param position An iterator pointing to the element to be erased. 514 : * 515 : * This function erases an element, pointed to by the given 516 : * iterator, from a %map. Note that this function only erases 517 : * the element, and that if the element is itself a pointer, 518 : * the pointed-to memory is not touched in any way. Managing 519 : * the pointer is the user's responsibility. 520 : */ 521 : void 522 : erase(iterator __position) 523 : { _M_t.erase(__position); } 524 : 525 : /** 526 : * @brief Erases elements according to the provided key. 527 : * @param x Key of element to be erased. 528 : * @return The number of elements erased. 529 : * 530 : * This function erases all the elements located by the given key from 531 : * a %map. 532 : * Note that this function only erases the element, and that if 533 : * the element is itself a pointer, the pointed-to memory is not touched 534 : * in any way. Managing the pointer is the user's responsibility. 535 : */ 536 : size_type 537 : erase(const key_type& __x) 538 : { return _M_t.erase(__x); } 539 : 540 : /** 541 : * @brief Erases a [first,last) range of elements from a %map. 542 : * @param first Iterator pointing to the start of the range to be 543 : * erased. 544 : * @param last Iterator pointing to the end of the range to be erased. 545 : * 546 : * This function erases a sequence of elements from a %map. 547 : * Note that this function only erases the element, and that if 548 : * the element is itself a pointer, the pointed-to memory is not touched 549 : * in any way. Managing the pointer is the user's responsibility. 550 : */ 551 : void 552 : erase(iterator __first, iterator __last) 553 : { _M_t.erase(__first, __last); } 554 : 555 : /** 556 : * @brief Swaps data with another %map. 557 : * @param x A %map of the same element and allocator types. 558 : * 559 : * This exchanges the elements between two maps in constant 560 : * time. (It is only swapping a pointer, an integer, and an 561 : * instance of the @c Compare type (which itself is often 562 : * stateless and empty), so it should be quite fast.) Note 563 : * that the global std::swap() function is specialized such 564 : * that std::swap(m1,m2) will feed to this function. 565 : */ 566 : void 567 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 568 : swap(map&& __x) 569 : #else 570 : swap(map& __x) 571 : #endif 572 : { _M_t.swap(__x._M_t); } 573 : 574 : /** 575 : * Erases all elements in a %map. Note that this function only 576 : * erases the elements, and that if the elements themselves are 577 : * pointers, the pointed-to memory is not touched in any way. 578 : * Managing the pointer is the user's responsibility. 579 : */ 580 : void 581 3288 : clear() 582 3288 : { _M_t.clear(); } 583 : 584 : // observers 585 : /** 586 : * Returns the key comparison object out of which the %map was 587 : * constructed. 588 : */ 589 : key_compare 590 3296 : key_comp() const 591 3296 : { return _M_t.key_comp(); } 592 : 593 : /** 594 : * Returns a value comparison object, built from the key comparison 595 : * object out of which the %map was constructed. 596 : */ 597 : value_compare 598 : value_comp() const 599 : { return value_compare(_M_t.key_comp()); } 600 : 601 : // [23.3.1.3] map operations 602 : /** 603 : * @brief Tries to locate an element in a %map. 604 : * @param x Key of (key, value) %pair to be located. 605 : * @return Iterator pointing to sought-after element, or end() if not 606 : * found. 607 : * 608 : * This function takes a key and tries to locate the element with which 609 : * the key matches. If successful the function returns an iterator 610 : * pointing to the sought after %pair. If unsuccessful it returns the 611 : * past-the-end ( @c end() ) iterator. 612 : */ 613 : iterator 614 50117 : find(const key_type& __x) 615 50117 : { return _M_t.find(__x); } 616 : 617 : /** 618 : * @brief Tries to locate an element in a %map. 619 : * @param x Key of (key, value) %pair to be located. 620 : * @return Read-only (constant) iterator pointing to sought-after 621 : * element, or end() if not found. 622 : * 623 : * This function takes a key and tries to locate the element with which 624 : * the key matches. If successful the function returns a constant 625 : * iterator pointing to the sought after %pair. If unsuccessful it 626 : * returns the past-the-end ( @c end() ) iterator. 627 : */ 628 : const_iterator 629 3916 : find(const key_type& __x) const 630 3916 : { return _M_t.find(__x); } 631 : 632 : /** 633 : * @brief Finds the number of elements with given key. 634 : * @param x Key of (key, value) pairs to be located. 635 : * @return Number of elements with specified key. 636 : * 637 : * This function only makes sense for multimaps; for map the result will 638 : * either be 0 (not present) or 1 (present). 639 : */ 640 : size_type 641 : count(const key_type& __x) const 642 : { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } 643 : 644 : /** 645 : * @brief Finds the beginning of a subsequence matching given key. 646 : * @param x Key of (key, value) pair to be located. 647 : * @return Iterator pointing to first element equal to or greater 648 : * than key, or end(). 649 : * 650 : * This function returns the first element of a subsequence of elements 651 : * that matches the given key. If unsuccessful it returns an iterator 652 : * pointing to the first element that has a greater value than given key 653 : * or end() if no such element exists. 654 : */ 655 : iterator 656 6297 : lower_bound(const key_type& __x) 657 6297 : { return _M_t.lower_bound(__x); } 658 : 659 : /** 660 : * @brief Finds the beginning of a subsequence matching given key. 661 : * @param x Key of (key, value) pair to be located. 662 : * @return Read-only (constant) iterator pointing to first element 663 : * equal to or greater than key, or end(). 664 : * 665 : * This function returns the first element of a subsequence of elements 666 : * that matches the given key. If unsuccessful it returns an iterator 667 : * pointing to the first element that has a greater value than given key 668 : * or end() if no such element exists. 669 : */ 670 : const_iterator 671 : lower_bound(const key_type& __x) const 672 : { return _M_t.lower_bound(__x); } 673 : 674 : /** 675 : * @brief Finds the end of a subsequence matching given key. 676 : * @param x Key of (key, value) pair to be located. 677 : * @return Iterator pointing to the first element 678 : * greater than key, or end(). 679 : */ 680 : iterator 681 : upper_bound(const key_type& __x) 682 : { return _M_t.upper_bound(__x); } 683 : 684 : /** 685 : * @brief Finds the end of a subsequence matching given key. 686 : * @param x Key of (key, value) pair to be located. 687 : * @return Read-only (constant) iterator pointing to first iterator 688 : * greater than key, or end(). 689 : */ 690 : const_iterator 691 : upper_bound(const key_type& __x) const 692 : { return _M_t.upper_bound(__x); } 693 : 694 : /** 695 : * @brief Finds a subsequence matching given key. 696 : * @param x Key of (key, value) pairs to be located. 697 : * @return Pair of iterators that possibly points to the subsequence 698 : * matching given key. 699 : * 700 : * This function is equivalent to 701 : * @code 702 : * std::make_pair(c.lower_bound(val), 703 : * c.upper_bound(val)) 704 : * @endcode 705 : * (but is faster than making the calls separately). 706 : * 707 : * This function probably only makes sense for multimaps. 708 : */ 709 : std::pair<iterator, iterator> 710 : equal_range(const key_type& __x) 711 : { return _M_t.equal_range(__x); } 712 : 713 : /** 714 : * @brief Finds a subsequence matching given key. 715 : * @param x Key of (key, value) pairs to be located. 716 : * @return Pair of read-only (constant) iterators that possibly points 717 : * to the subsequence matching given key. 718 : * 719 : * This function is equivalent to 720 : * @code 721 : * std::make_pair(c.lower_bound(val), 722 : * c.upper_bound(val)) 723 : * @endcode 724 : * (but is faster than making the calls separately). 725 : * 726 : * This function probably only makes sense for multimaps. 727 : */ 728 : std::pair<const_iterator, const_iterator> 729 : equal_range(const key_type& __x) const 730 : { return _M_t.equal_range(__x); } 731 : 732 : template<typename _K1, typename _T1, typename _C1, typename _A1> 733 : friend bool 734 : operator==(const map<_K1, _T1, _C1, _A1>&, 735 : const map<_K1, _T1, _C1, _A1>&); 736 : 737 : template<typename _K1, typename _T1, typename _C1, typename _A1> 738 : friend bool 739 : operator<(const map<_K1, _T1, _C1, _A1>&, 740 : const map<_K1, _T1, _C1, _A1>&); 741 : }; 742 : 743 : /** 744 : * @brief Map equality comparison. 745 : * @param x A %map. 746 : * @param y A %map of the same type as @a x. 747 : * @return True iff the size and elements of the maps are equal. 748 : * 749 : * This is an equivalence relation. It is linear in the size of the 750 : * maps. Maps are considered equivalent if their sizes are equal, 751 : * and if corresponding elements compare equal. 752 : */ 753 : template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> 754 : inline bool 755 : operator==(const map<_Key, _Tp, _Compare, _Alloc>& __x, 756 : const map<_Key, _Tp, _Compare, _Alloc>& __y) 757 : { return __x._M_t == __y._M_t; } 758 : 759 : /** 760 : * @brief Map ordering relation. 761 : * @param x A %map. 762 : * @param y A %map of the same type as @a x. 763 : * @return True iff @a x is lexicographically less than @a y. 764 : * 765 : * This is a total ordering relation. It is linear in the size of the 766 : * maps. The elements must be comparable with @c <. 767 : * 768 : * See std::lexicographical_compare() for how the determination is made. 769 : */ 770 : template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> 771 : inline bool 772 : operator<(const map<_Key, _Tp, _Compare, _Alloc>& __x, 773 : const map<_Key, _Tp, _Compare, _Alloc>& __y) 774 : { return __x._M_t < __y._M_t; } 775 : 776 : /// Based on operator== 777 : template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> 778 : inline bool 779 : operator!=(const map<_Key, _Tp, _Compare, _Alloc>& __x, 780 : const map<_Key, _Tp, _Compare, _Alloc>& __y) 781 : { return !(__x == __y); } 782 : 783 : /// Based on operator< 784 : template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> 785 : inline bool 786 : operator>(const map<_Key, _Tp, _Compare, _Alloc>& __x, 787 : const map<_Key, _Tp, _Compare, _Alloc>& __y) 788 : { return __y < __x; } 789 : 790 : /// Based on operator< 791 : template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> 792 : inline bool 793 : operator<=(const map<_Key, _Tp, _Compare, _Alloc>& __x, 794 : const map<_Key, _Tp, _Compare, _Alloc>& __y) 795 : { return !(__y < __x); } 796 : 797 : /// Based on operator< 798 : template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> 799 : inline bool 800 : operator>=(const map<_Key, _Tp, _Compare, _Alloc>& __x, 801 : const map<_Key, _Tp, _Compare, _Alloc>& __y) 802 : { return !(__x < __y); } 803 : 804 : /// See std::map::swap(). 805 : template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> 806 : inline void 807 : swap(map<_Key, _Tp, _Compare, _Alloc>& __x, 808 : map<_Key, _Tp, _Compare, _Alloc>& __y) 809 : { __x.swap(__y); } 810 : 811 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 812 : template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> 813 : inline void 814 : swap(map<_Key, _Tp, _Compare, _Alloc>&& __x, 815 : map<_Key, _Tp, _Compare, _Alloc>& __y) 816 : { __x.swap(__y); } 817 : 818 : template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> 819 : inline void 820 : swap(map<_Key, _Tp, _Compare, _Alloc>& __x, 821 : map<_Key, _Tp, _Compare, _Alloc>&& __y) 822 : { __x.swap(__y); } 823 : #endif 824 : 825 : _GLIBCXX_END_NESTED_NAMESPACE 826 : 827 : #endif /* _STL_MAP_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Character Traits for use by standard string and iostream -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License along 19 : // with this library; see the file COPYING. If not, write to the Free 20 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 21 : // USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file char_traits.h 33 : * This is an internal header file, included by other library headers. 34 : * You should not attempt to use it directly. 35 : */ 36 : 37 : // 38 : // ISO C++ 14882: 21 Strings library 39 : // 40 : 41 : #ifndef _CHAR_TRAITS_H 42 : #define _CHAR_TRAITS_H 1 43 : 44 : #pragma GCC system_header 45 : 46 : #include <bits/stl_algobase.h> // std::copy, std::fill_n 47 : #include <bits/postypes.h> // For streampos 48 : #include <cstdio> // For EOF 49 : #include <cwchar> // For WEOF, wmemmove, wmemset, etc. 50 : 51 : _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 52 : 53 : /** 54 : * @brief Mapping from character type to associated types. 55 : * 56 : * @note This is an implementation class for the generic version 57 : * of char_traits. It defines int_type, off_type, pos_type, and 58 : * state_type. By default these are unsigned long, streamoff, 59 : * streampos, and mbstate_t. Users who need a different set of 60 : * types, but who don't need to change the definitions of any function 61 : * defined in char_traits, can specialize __gnu_cxx::_Char_types 62 : * while leaving __gnu_cxx::char_traits alone. */ 63 : template<typename _CharT> 64 : struct _Char_types 65 : { 66 : typedef unsigned long int_type; 67 : typedef std::streampos pos_type; 68 : typedef std::streamoff off_type; 69 : typedef std::mbstate_t state_type; 70 : }; 71 : 72 : 73 : /** 74 : * @brief Base class used to implement std::char_traits. 75 : * 76 : * @note For any given actual character type, this definition is 77 : * probably wrong. (Most of the member functions are likely to be 78 : * right, but the int_type and state_type typedefs, and the eof() 79 : * member function, are likely to be wrong.) The reason this class 80 : * exists is so users can specialize it. Classes in namespace std 81 : * may not be specialized for fundamental types, but classes in 82 : * namespace __gnu_cxx may be. 83 : * 84 : * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 85 : * for advice on how to make use of this class for "unusual" character 86 : * types. Also, check out include/ext/pod_char_traits.h. 87 : */ 88 : template<typename _CharT> 89 : struct char_traits 90 : { 91 : typedef _CharT char_type; 92 : typedef typename _Char_types<_CharT>::int_type int_type; 93 : typedef typename _Char_types<_CharT>::pos_type pos_type; 94 : typedef typename _Char_types<_CharT>::off_type off_type; 95 : typedef typename _Char_types<_CharT>::state_type state_type; 96 : 97 : static void 98 : assign(char_type& __c1, const char_type& __c2) 99 : { __c1 = __c2; } 100 : 101 : static bool 102 : eq(const char_type& __c1, const char_type& __c2) 103 : { return __c1 == __c2; } 104 : 105 : static bool 106 : lt(const char_type& __c1, const char_type& __c2) 107 : { return __c1 < __c2; } 108 : 109 : static int 110 : compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 111 : 112 : static std::size_t 113 : length(const char_type* __s); 114 : 115 : static const char_type* 116 : find(const char_type* __s, std::size_t __n, const char_type& __a); 117 : 118 : static char_type* 119 : move(char_type* __s1, const char_type* __s2, std::size_t __n); 120 : 121 : static char_type* 122 : copy(char_type* __s1, const char_type* __s2, std::size_t __n); 123 : 124 : static char_type* 125 : assign(char_type* __s, std::size_t __n, char_type __a); 126 : 127 : static char_type 128 : to_char_type(const int_type& __c) 129 : { return static_cast<char_type>(__c); } 130 : 131 : static int_type 132 : to_int_type(const char_type& __c) 133 : { return static_cast<int_type>(__c); } 134 : 135 : static bool 136 : eq_int_type(const int_type& __c1, const int_type& __c2) 137 : { return __c1 == __c2; } 138 : 139 : static int_type 140 : eof() 141 : { return static_cast<int_type>(EOF); } 142 : 143 : static int_type 144 : not_eof(const int_type& __c) 145 : { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } 146 : }; 147 : 148 : template<typename _CharT> 149 : int 150 : char_traits<_CharT>:: 151 : compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 152 : { 153 : for (std::size_t __i = 0; __i < __n; ++__i) 154 : if (lt(__s1[__i], __s2[__i])) 155 : return -1; 156 : else if (lt(__s2[__i], __s1[__i])) 157 : return 1; 158 : return 0; 159 : } 160 : 161 : template<typename _CharT> 162 : std::size_t 163 : char_traits<_CharT>:: 164 : length(const char_type* __p) 165 : { 166 : std::size_t __i = 0; 167 : while (!eq(__p[__i], char_type())) 168 : ++__i; 169 : return __i; 170 : } 171 : 172 : template<typename _CharT> 173 : const typename char_traits<_CharT>::char_type* 174 : char_traits<_CharT>:: 175 : find(const char_type* __s, std::size_t __n, const char_type& __a) 176 : { 177 : for (std::size_t __i = 0; __i < __n; ++__i) 178 : if (eq(__s[__i], __a)) 179 : return __s + __i; 180 : return 0; 181 : } 182 : 183 : template<typename _CharT> 184 : typename char_traits<_CharT>::char_type* 185 : char_traits<_CharT>:: 186 : move(char_type* __s1, const char_type* __s2, std::size_t __n) 187 : { 188 : return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, 189 : __n * sizeof(char_type))); 190 : } 191 : 192 : template<typename _CharT> 193 : typename char_traits<_CharT>::char_type* 194 : char_traits<_CharT>:: 195 : copy(char_type* __s1, const char_type* __s2, std::size_t __n) 196 : { 197 : // NB: Inline std::copy so no recursive dependencies. 198 : std::copy(__s2, __s2 + __n, __s1); 199 : return __s1; 200 : } 201 : 202 : template<typename _CharT> 203 : typename char_traits<_CharT>::char_type* 204 : char_traits<_CharT>:: 205 : assign(char_type* __s, std::size_t __n, char_type __a) 206 : { 207 : // NB: Inline std::fill_n so no recursive dependencies. 208 : std::fill_n(__s, __n, __a); 209 : return __s; 210 : } 211 : 212 : _GLIBCXX_END_NAMESPACE 213 : 214 : _GLIBCXX_BEGIN_NAMESPACE(std) 215 : 216 : // 21.1 217 : /** 218 : * @brief Basis for explicit traits specializations. 219 : * 220 : * @note For any given actual character type, this definition is 221 : * probably wrong. Since this is just a thin wrapper around 222 : * __gnu_cxx::char_traits, it is possible to achieve a more 223 : * appropriate definition by specializing __gnu_cxx::char_traits. 224 : * 225 : * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 226 : * for advice on how to make use of this class for "unusual" character 227 : * types. Also, check out include/ext/pod_char_traits.h. 228 : */ 229 : template<class _CharT> 230 : struct char_traits : public __gnu_cxx::char_traits<_CharT> 231 : { }; 232 : 233 : 234 : /// 21.1.3.1 char_traits specializations 235 : template<> 236 : struct char_traits<char> 237 : { 238 : typedef char char_type; 239 : typedef int int_type; 240 : typedef streampos pos_type; 241 : typedef streamoff off_type; 242 : typedef mbstate_t state_type; 243 : 244 : static void 245 10976 : assign(char_type& __c1, const char_type& __c2) 246 10976 : { __c1 = __c2; } 247 : 248 : static bool 249 : eq(const char_type& __c1, const char_type& __c2) 250 : { return __c1 == __c2; } 251 : 252 : static bool 253 : lt(const char_type& __c1, const char_type& __c2) 254 : { return __c1 < __c2; } 255 : 256 : static int 257 115296 : compare(const char_type* __s1, const char_type* __s2, size_t __n) 258 115296 : { return __builtin_memcmp(__s1, __s2, __n); } 259 : 260 : static size_t 261 2633 : length(const char_type* __s) 262 2633 : { return __builtin_strlen(__s); } 263 : 264 : static const char_type* 265 : find(const char_type* __s, size_t __n, const char_type& __a) 266 : { return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); } 267 : 268 : static char_type* 269 : move(char_type* __s1, const char_type* __s2, size_t __n) 270 : { return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); } 271 : 272 : static char_type* 273 0 : copy(char_type* __s1, const char_type* __s2, size_t __n) 274 0 : { return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); } 275 : 276 : static char_type* 277 : assign(char_type* __s, size_t __n, char_type __a) 278 : { return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); } 279 : 280 : static char_type 281 : to_char_type(const int_type& __c) 282 : { return static_cast<char_type>(__c); } 283 : 284 : // To keep both the byte 0xff and the eof symbol 0xffffffff 285 : // from ending up as 0xffffffff. 286 : static int_type 287 0 : to_int_type(const char_type& __c) 288 0 : { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 289 : 290 : static bool 291 0 : eq_int_type(const int_type& __c1, const int_type& __c2) 292 0 : { return __c1 == __c2; } 293 : 294 : static int_type 295 0 : eof() { return static_cast<int_type>(EOF); } 296 : 297 : static int_type 298 : not_eof(const int_type& __c) 299 : { return (__c == eof()) ? 0 : __c; } 300 : }; 301 : 302 : 303 : #ifdef _GLIBCXX_USE_WCHAR_T 304 : /// 21.1.3.2 char_traits specializations 305 : template<> 306 : struct char_traits<wchar_t> 307 : { 308 : typedef wchar_t char_type; 309 : typedef wint_t int_type; 310 : typedef streamoff off_type; 311 : typedef wstreampos pos_type; 312 : typedef mbstate_t state_type; 313 : 314 : static void 315 : assign(char_type& __c1, const char_type& __c2) 316 : { __c1 = __c2; } 317 : 318 : static bool 319 : eq(const char_type& __c1, const char_type& __c2) 320 : { return __c1 == __c2; } 321 : 322 : static bool 323 : lt(const char_type& __c1, const char_type& __c2) 324 : { return __c1 < __c2; } 325 : 326 : static int 327 : compare(const char_type* __s1, const char_type* __s2, size_t __n) 328 : { return wmemcmp(__s1, __s2, __n); } 329 : 330 : static size_t 331 : length(const char_type* __s) 332 : { return wcslen(__s); } 333 : 334 : static const char_type* 335 : find(const char_type* __s, size_t __n, const char_type& __a) 336 : { return wmemchr(__s, __a, __n); } 337 : 338 : static char_type* 339 : move(char_type* __s1, const char_type* __s2, size_t __n) 340 : { return wmemmove(__s1, __s2, __n); } 341 : 342 : static char_type* 343 : copy(char_type* __s1, const char_type* __s2, size_t __n) 344 : { return wmemcpy(__s1, __s2, __n); } 345 : 346 : static char_type* 347 : assign(char_type* __s, size_t __n, char_type __a) 348 : { return wmemset(__s, __a, __n); } 349 : 350 : static char_type 351 : to_char_type(const int_type& __c) { return char_type(__c); } 352 : 353 : static int_type 354 : to_int_type(const char_type& __c) { return int_type(__c); } 355 : 356 : static bool 357 : eq_int_type(const int_type& __c1, const int_type& __c2) 358 : { return __c1 == __c2; } 359 : 360 : static int_type 361 : eof() { return static_cast<int_type>(WEOF); } 362 : 363 : static int_type 364 : not_eof(const int_type& __c) 365 : { return eq_int_type(__c, eof()) ? 0 : __c; } 366 : }; 367 : #endif //_GLIBCXX_USE_WCHAR_T 368 : 369 : _GLIBCXX_END_NAMESPACE 370 : 371 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Stack implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996,1997 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_stack.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_STACK_H 63 : #define _STL_STACK_H 1 64 : 65 : #include <bits/concept_check.h> 66 : #include <debug/debug.h> 67 : 68 : _GLIBCXX_BEGIN_NAMESPACE(std) 69 : 70 : /** 71 : * @brief A standard container giving FILO behavior. 72 : * 73 : * @ingroup Containers 74 : * @ingroup Sequences 75 : * 76 : * Meets many of the requirements of a 77 : * <a href="tables.html#65">container</a>, 78 : * but does not define anything to do with iterators. Very few of the 79 : * other standard container interfaces are defined. 80 : * 81 : * This is not a true container, but an @e adaptor. It holds 82 : * another container, and provides a wrapper interface to that 83 : * container. The wrapper is what enforces strict 84 : * first-in-last-out %stack behavior. 85 : * 86 : * The second template parameter defines the type of the underlying 87 : * sequence/container. It defaults to std::deque, but it can be 88 : * any type that supports @c back, @c push_back, and @c pop_front, 89 : * such as std::list, std::vector, or an appropriate user-defined 90 : * type. 91 : * 92 : * Members not found in "normal" containers are @c container_type, 93 : * which is a typedef for the second Sequence parameter, and @c 94 : * push, @c pop, and @c top, which are standard %stack/FILO 95 : * operations. 96 : */ 97 : template<typename _Tp, typename _Sequence = deque<_Tp> > 98 : class stack 99 13 : { 100 : // concept requirements 101 : typedef typename _Sequence::value_type _Sequence_value_type; 102 : __glibcxx_class_requires(_Tp, _SGIAssignableConcept) 103 : __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) 104 : __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) 105 : 106 : template<typename _Tp1, typename _Seq1> 107 : friend bool 108 : operator==(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); 109 : 110 : template<typename _Tp1, typename _Seq1> 111 : friend bool 112 : operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); 113 : 114 : public: 115 : typedef typename _Sequence::value_type value_type; 116 : typedef typename _Sequence::reference reference; 117 : typedef typename _Sequence::const_reference const_reference; 118 : typedef typename _Sequence::size_type size_type; 119 : typedef _Sequence container_type; 120 : 121 : protected: 122 : // See queue::c for notes on this name. 123 : _Sequence c; 124 : 125 : public: 126 : // XXX removed old def ctor, added def arg to this one to match 14882 127 : /** 128 : * @brief Default constructor creates no elements. 129 : */ 130 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 131 : explicit 132 13 : stack(const _Sequence& __c = _Sequence()) 133 13 : : c(__c) { } 134 : #else 135 : explicit 136 : stack(const _Sequence& __c) 137 : : c(__c) { } 138 : 139 : explicit 140 : stack(_Sequence&& __c = _Sequence()) 141 : : c(std::move(__c)) { } 142 : #endif 143 : 144 : /** 145 : * Returns true if the %stack is empty. 146 : */ 147 : bool 148 32 : empty() const 149 32 : { return c.empty(); } 150 : 151 : /** Returns the number of elements in the %stack. */ 152 : size_type 153 : size() const 154 : { return c.size(); } 155 : 156 : /** 157 : * Returns a read/write reference to the data at the first 158 : * element of the %stack. 159 : */ 160 : reference 161 39 : top() 162 : { 163 : __glibcxx_requires_nonempty(); 164 39 : return c.back(); 165 : } 166 : 167 : /** 168 : * Returns a read-only (constant) reference to the data at the first 169 : * element of the %stack. 170 : */ 171 : const_reference 172 : top() const 173 : { 174 : __glibcxx_requires_nonempty(); 175 : return c.back(); 176 : } 177 : 178 : /** 179 : * @brief Add data to the top of the %stack. 180 : * @param x Data to be added. 181 : * 182 : * This is a typical %stack operation. The function creates an 183 : * element at the top of the %stack and assigns the given data 184 : * to it. The time complexity of the operation depends on the 185 : * underlying sequence. 186 : */ 187 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 188 : void 189 24 : push(const value_type& __x) 190 24 : { c.push_back(__x); } 191 : #else 192 : // NB: DR 756. 193 : template<typename... _Args> 194 : void 195 : push(_Args&&... __args) 196 : { c.push_back(std::forward<_Args>(__args)...); } 197 : #endif 198 : 199 : /** 200 : * @brief Removes first element. 201 : * 202 : * This is a typical %stack operation. It shrinks the %stack 203 : * by one. The time complexity of the operation depends on the 204 : * underlying sequence. 205 : * 206 : * Note that no data is returned, and if the first element's 207 : * data is needed, it should be retrieved before pop() is 208 : * called. 209 : */ 210 : void 211 24 : pop() 212 : { 213 : __glibcxx_requires_nonempty(); 214 24 : c.pop_back(); 215 24 : } 216 : 217 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 218 : void 219 : swap(stack&& __s) 220 : { c.swap(__s.c); } 221 : #endif 222 : }; 223 : 224 : /** 225 : * @brief Stack equality comparison. 226 : * @param x A %stack. 227 : * @param y A %stack of the same type as @a x. 228 : * @return True iff the size and elements of the stacks are equal. 229 : * 230 : * This is an equivalence relation. Complexity and semantics 231 : * depend on the underlying sequence type, but the expected rules 232 : * are: this relation is linear in the size of the sequences, and 233 : * stacks are considered equivalent if their sequences compare 234 : * equal. 235 : */ 236 : template<typename _Tp, typename _Seq> 237 : inline bool 238 : operator==(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) 239 : { return __x.c == __y.c; } 240 : 241 : /** 242 : * @brief Stack ordering relation. 243 : * @param x A %stack. 244 : * @param y A %stack of the same type as @a x. 245 : * @return True iff @a x is lexicographically less than @a y. 246 : * 247 : * This is an total ordering relation. Complexity and semantics 248 : * depend on the underlying sequence type, but the expected rules 249 : * are: this relation is linear in the size of the sequences, the 250 : * elements must be comparable with @c <, and 251 : * std::lexicographical_compare() is usually used to make the 252 : * determination. 253 : */ 254 : template<typename _Tp, typename _Seq> 255 : inline bool 256 : operator<(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) 257 : { return __x.c < __y.c; } 258 : 259 : /// Based on operator== 260 : template<typename _Tp, typename _Seq> 261 : inline bool 262 : operator!=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) 263 : { return !(__x == __y); } 264 : 265 : /// Based on operator< 266 : template<typename _Tp, typename _Seq> 267 : inline bool 268 : operator>(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) 269 : { return __y < __x; } 270 : 271 : /// Based on operator< 272 : template<typename _Tp, typename _Seq> 273 : inline bool 274 : operator<=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) 275 : { return !(__y < __x); } 276 : 277 : /// Based on operator< 278 : template<typename _Tp, typename _Seq> 279 : inline bool 280 : operator>=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) 281 : { return !(__x < __y); } 282 : 283 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 284 : template<typename _Tp, typename _Seq> 285 : inline void 286 : swap(stack<_Tp, _Seq>& __x, stack<_Tp, _Seq>& __y) 287 : { __x.swap(__y); } 288 : 289 : template<typename _Tp, typename _Seq> 290 : inline void 291 : swap(stack<_Tp, _Seq>&& __x, stack<_Tp, _Seq>& __y) 292 : { __x.swap(__y); } 293 : 294 : template<typename _Tp, typename _Seq> 295 : inline void 296 : swap(stack<_Tp, _Seq>& __x, stack<_Tp, _Seq>&& __y) 297 : { __x.swap(__y); } 298 : #endif 299 : 300 : _GLIBCXX_END_NAMESPACE 301 : 302 : #endif /* _STL_STACK_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Iostreams base classes -*- C++ -*- 2 : 3 : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 : // 2006, 2007, 2008 5 : // Free Software Foundation, Inc. 6 : // 7 : // This file is part of the GNU ISO C++ Library. This library is free 8 : // software; you can redistribute it and/or modify it under the 9 : // terms of the GNU General Public License as published by the 10 : // Free Software Foundation; either version 2, or (at your option) 11 : // any later version. 12 : 13 : // This library is distributed in the hope that it will be useful, 14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : // GNU General Public License for more details. 17 : 18 : // You should have received a copy of the GNU General Public License along 19 : // with this library; see the file COPYING. If not, write to the Free 20 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 21 : // USA. 22 : 23 : // As a special exception, you may use this file as part of a free software 24 : // library without restriction. Specifically, if other files instantiate 25 : // templates or use macros or inline functions from this file, or you compile 26 : // this file and link it with other files to produce an executable, this 27 : // file does not by itself cause the resulting executable to be covered by 28 : // the GNU General Public License. This exception does not however 29 : // invalidate any other reasons why the executable file might be covered by 30 : // the GNU General Public License. 31 : 32 : /** @file basic_ios.h 33 : * This is an internal header file, included by other library headers. 34 : * You should not attempt to use it directly. 35 : */ 36 : 37 : #ifndef _BASIC_IOS_H 38 : #define _BASIC_IOS_H 1 39 : 40 : #pragma GCC system_header 41 : 42 : #include <bits/localefwd.h> 43 : #include <bits/locale_classes.h> 44 : #include <bits/locale_facets.h> 45 : #include <bits/streambuf_iterator.h> 46 : 47 : _GLIBCXX_BEGIN_NAMESPACE(std) 48 : 49 : template<typename _Facet> 50 : inline const _Facet& 51 0 : __check_facet(const _Facet* __f) 52 : { 53 0 : if (!__f) 54 0 : __throw_bad_cast(); 55 0 : return *__f; 56 : } 57 : 58 : // 27.4.5 Template class basic_ios 59 : /** 60 : * @brief Virtual base class for all stream classes. 61 : * 62 : * Most of the member functions called dispatched on stream objects 63 : * (e.g., @c std::cout.foo(bar);) are consolidated in this class. 64 : */ 65 : template<typename _CharT, typename _Traits> 66 : class basic_ios : public ios_base 67 : { 68 : public: 69 : //@{ 70 : /** 71 : * These are standard types. They permit a standardized way of 72 : * referring to names of (or names dependant on) the template 73 : * parameters, which are specific to the implementation. 74 : */ 75 : typedef _CharT char_type; 76 : typedef typename _Traits::int_type int_type; 77 : typedef typename _Traits::pos_type pos_type; 78 : typedef typename _Traits::off_type off_type; 79 : typedef _Traits traits_type; 80 : //@} 81 : 82 : //@{ 83 : /** 84 : * These are non-standard types. 85 : */ 86 : typedef ctype<_CharT> __ctype_type; 87 : typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > 88 : __num_put_type; 89 : typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > 90 : __num_get_type; 91 : //@} 92 : 93 : // Data members: 94 : protected: 95 : basic_ostream<_CharT, _Traits>* _M_tie; 96 : mutable char_type _M_fill; 97 : mutable bool _M_fill_init; 98 : basic_streambuf<_CharT, _Traits>* _M_streambuf; 99 : 100 : // Cached use_facet<ctype>, which is based on the current locale info. 101 : const __ctype_type* _M_ctype; 102 : // For ostream. 103 : const __num_put_type* _M_num_put; 104 : // For istream. 105 : const __num_get_type* _M_num_get; 106 : 107 : public: 108 : //@{ 109 : /** 110 : * @brief The quick-and-easy status check. 111 : * 112 : * This allows you to write constructs such as 113 : * "if (!a_stream) ..." and "while (a_stream) ..." 114 : */ 115 0 : operator void*() const 116 0 : { return this->fail() ? 0 : const_cast<basic_ios*>(this); } 117 : 118 : bool 119 0 : operator!() const 120 0 : { return this->fail(); } 121 : //@} 122 : 123 : /** 124 : * @brief Returns the error state of the stream buffer. 125 : * @return A bit pattern (well, isn't everything?) 126 : * 127 : * See std::ios_base::iostate for the possible bit values. Most 128 : * users will call one of the interpreting wrappers, e.g., good(). 129 : */ 130 : iostate 131 0 : rdstate() const 132 0 : { return _M_streambuf_state; } 133 : 134 : /** 135 : * @brief [Re]sets the error state. 136 : * @param state The new state flag(s) to set. 137 : * 138 : * See std::ios_base::iostate for the possible bit values. Most 139 : * users will not need to pass an argument. 140 : */ 141 : void 142 : clear(iostate __state = goodbit); 143 : 144 : /** 145 : * @brief Sets additional flags in the error state. 146 : * @param state The additional state flag(s) to set. 147 : * 148 : * See std::ios_base::iostate for the possible bit values. 149 : */ 150 : void 151 0 : setstate(iostate __state) 152 0 : { this->clear(this->rdstate() | __state); } 153 : 154 : // Flip the internal state on for the proper state bits, then re 155 : // throws the propagated exception if bit also set in 156 : // exceptions(). 157 : void 158 : _M_setstate(iostate __state) 159 : { 160 : // 27.6.1.2.1 Common requirements. 161 : // Turn this on without causing an ios::failure to be thrown. 162 : _M_streambuf_state |= __state; 163 : if (this->exceptions() & __state) 164 : __throw_exception_again; 165 : } 166 : 167 : /** 168 : * @brief Fast error checking. 169 : * @return True if no error flags are set. 170 : * 171 : * A wrapper around rdstate. 172 : */ 173 : bool 174 0 : good() const 175 0 : { return this->rdstate() == 0; } 176 : 177 : /** 178 : * @brief Fast error checking. 179 : * @return True if the eofbit is set. 180 : * 181 : * Note that other iostate flags may also be set. 182 : */ 183 : bool 184 0 : eof() const 185 0 : { return (this->rdstate() & eofbit) != 0; } 186 : 187 : /** 188 : * @brief Fast error checking. 189 : * @return True if either the badbit or the failbit is set. 190 : * 191 : * Checking the badbit in fail() is historical practice. 192 : * Note that other iostate flags may also be set. 193 : */ 194 : bool 195 0 : fail() const 196 0 : { return (this->rdstate() & (badbit | failbit)) != 0; } 197 : 198 : /** 199 : * @brief Fast error checking. 200 : * @return True if the badbit is set. 201 : * 202 : * Note that other iostate flags may also be set. 203 : */ 204 : bool 205 : bad() const 206 : { return (this->rdstate() & badbit) != 0; } 207 : 208 : /** 209 : * @brief Throwing exceptions on errors. 210 : * @return The current exceptions mask. 211 : * 212 : * This changes nothing in the stream. See the one-argument version 213 : * of exceptions(iostate) for the meaning of the return value. 214 : */ 215 : iostate 216 : exceptions() const 217 : { return _M_exception; } 218 : 219 : /** 220 : * @brief Throwing exceptions on errors. 221 : * @param except The new exceptions mask. 222 : * 223 : * By default, error flags are set silently. You can set an 224 : * exceptions mask for each stream; if a bit in the mask becomes set 225 : * in the error flags, then an exception of type 226 : * std::ios_base::failure is thrown. 227 : * 228 : * If the error flag is already set when the exceptions mask is 229 : * added, the exception is immediately thrown. Try running the 230 : * following under GCC 3.1 or later: 231 : * @code 232 : * #include <iostream> 233 : * #include <fstream> 234 : * #include <exception> 235 : * 236 : * int main() 237 : * { 238 : * std::set_terminate (__gnu_cxx::__verbose_terminate_handler); 239 : * 240 : * std::ifstream f ("/etc/motd"); 241 : * 242 : * std::cerr << "Setting badbit\n"; 243 : * f.setstate (std::ios_base::badbit); 244 : * 245 : * std::cerr << "Setting exception mask\n"; 246 : * f.exceptions (std::ios_base::badbit); 247 : * } 248 : * @endcode 249 : */ 250 : void 251 : exceptions(iostate __except) 252 : { 253 : _M_exception = __except; 254 : this->clear(_M_streambuf_state); 255 : } 256 : 257 : // Constructor/destructor: 258 : /** 259 : * @brief Constructor performs initialization. 260 : * 261 : * The parameter is passed by derived streams. 262 : */ 263 : explicit 264 : basic_ios(basic_streambuf<_CharT, _Traits>* __sb) 265 : : ios_base(), _M_tie(0), _M_fill(), _M_fill_init(false), _M_streambuf(0), 266 : _M_ctype(0), _M_num_put(0), _M_num_get(0) 267 : { this->init(__sb); } 268 : 269 : /** 270 : * @brief Empty. 271 : * 272 : * The destructor does nothing. More specifically, it does not 273 : * destroy the streambuf held by rdbuf(). 274 : */ 275 : virtual 276 0 : ~basic_ios() { } 277 : 278 : // Members: 279 : /** 280 : * @brief Fetches the current @e tied stream. 281 : * @return A pointer to the tied stream, or NULL if the stream is 282 : * not tied. 283 : * 284 : * A stream may be @e tied (or synchronized) to a second output 285 : * stream. When this stream performs any I/O, the tied stream is 286 : * first flushed. For example, @c std::cin is tied to @c std::cout. 287 : */ 288 : basic_ostream<_CharT, _Traits>* 289 : tie() const 290 : { return _M_tie; } 291 : 292 : /** 293 : * @brief Ties this stream to an output stream. 294 : * @param tiestr The output stream. 295 : * @return The previously tied output stream, or NULL if the stream 296 : * was not tied. 297 : * 298 : * This sets up a new tie; see tie() for more. 299 : */ 300 : basic_ostream<_CharT, _Traits>* 301 : tie(basic_ostream<_CharT, _Traits>* __tiestr) 302 : { 303 : basic_ostream<_CharT, _Traits>* __old = _M_tie; 304 : _M_tie = __tiestr; 305 : return __old; 306 : } 307 : 308 : /** 309 : * @brief Accessing the underlying buffer. 310 : * @return The current stream buffer. 311 : * 312 : * This does not change the state of the stream. 313 : */ 314 : basic_streambuf<_CharT, _Traits>* 315 0 : rdbuf() const 316 0 : { return _M_streambuf; } 317 : 318 : /** 319 : * @brief Changing the underlying buffer. 320 : * @param sb The new stream buffer. 321 : * @return The previous stream buffer. 322 : * 323 : * Associates a new buffer with the current stream, and clears the 324 : * error state. 325 : * 326 : * Due to historical accidents which the LWG refuses to correct, the 327 : * I/O library suffers from a design error: this function is hidden 328 : * in derived classes by overrides of the zero-argument @c rdbuf(), 329 : * which is non-virtual for hysterical raisins. As a result, you 330 : * must use explicit qualifications to access this function via any 331 : * derived class. For example: 332 : * 333 : * @code 334 : * std::fstream foo; // or some other derived type 335 : * std::streambuf* p = .....; 336 : * 337 : * foo.ios::rdbuf(p); // ios == basic_ios<char> 338 : * @endcode 339 : */ 340 : basic_streambuf<_CharT, _Traits>* 341 : rdbuf(basic_streambuf<_CharT, _Traits>* __sb); 342 : 343 : /** 344 : * @brief Copies fields of __rhs into this. 345 : * @param __rhs The source values for the copies. 346 : * @return Reference to this object. 347 : * 348 : * All fields of __rhs are copied into this object except that rdbuf() 349 : * and rdstate() remain unchanged. All values in the pword and iword 350 : * arrays are copied. Before copying, each callback is invoked with 351 : * erase_event. After copying, each (new) callback is invoked with 352 : * copyfmt_event. The final step is to copy exceptions(). 353 : */ 354 : basic_ios& 355 : copyfmt(const basic_ios& __rhs); 356 : 357 : /** 358 : * @brief Retrieves the "empty" character. 359 : * @return The current fill character. 360 : * 361 : * It defaults to a space (' ') in the current locale. 362 : */ 363 : char_type 364 0 : fill() const 365 : { 366 0 : if (!_M_fill_init) 367 : { 368 0 : _M_fill = this->widen(' '); 369 0 : _M_fill_init = true; 370 : } 371 0 : return _M_fill; 372 : } 373 : 374 : /** 375 : * @brief Sets a new "empty" character. 376 : * @param ch The new character. 377 : * @return The previous fill character. 378 : * 379 : * The fill character is used to fill out space when P+ characters 380 : * have been requested (e.g., via setw), Q characters are actually 381 : * used, and Q<P. It defaults to a space (' ') in the current locale. 382 : */ 383 : char_type 384 0 : fill(char_type __ch) 385 : { 386 0 : char_type __old = this->fill(); 387 0 : _M_fill = __ch; 388 0 : return __old; 389 : } 390 : 391 : // Locales: 392 : /** 393 : * @brief Moves to a new locale. 394 : * @param loc The new locale. 395 : * @return The previous locale. 396 : * 397 : * Calls @c ios_base::imbue(loc), and if a stream buffer is associated 398 : * with this stream, calls that buffer's @c pubimbue(loc). 399 : * 400 : * Additional l10n notes are at 401 : * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html 402 : */ 403 : locale 404 : imbue(const locale& __loc); 405 : 406 : /** 407 : * @brief Squeezes characters. 408 : * @param c The character to narrow. 409 : * @param dfault The character to narrow. 410 : * @return The narrowed character. 411 : * 412 : * Maps a character of @c char_type to a character of @c char, 413 : * if possible. 414 : * 415 : * Returns the result of 416 : * @code 417 : * std::use_facet<ctype<char_type> >(getloc()).narrow(c,dfault) 418 : * @endcode 419 : * 420 : * Additional l10n notes are at 421 : * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html 422 : */ 423 : char 424 : narrow(char_type __c, char __dfault) const 425 : { return __check_facet(_M_ctype).narrow(__c, __dfault); } 426 : 427 : /** 428 : * @brief Widens characters. 429 : * @param c The character to widen. 430 : * @return The widened character. 431 : * 432 : * Maps a character of @c char to a character of @c char_type. 433 : * 434 : * Returns the result of 435 : * @code 436 : * std::use_facet<ctype<char_type> >(getloc()).widen(c) 437 : * @endcode 438 : * 439 : * Additional l10n notes are at 440 : * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html 441 : */ 442 : char_type 443 0 : widen(char __c) const 444 0 : { return __check_facet(_M_ctype).widen(__c); } 445 : 446 : protected: 447 : // 27.4.5.1 basic_ios constructors 448 : /** 449 : * @brief Empty. 450 : * 451 : * The default constructor does nothing and is not normally 452 : * accessible to users. 453 : */ 454 0 : basic_ios() 455 : : ios_base(), _M_tie(0), _M_fill(char_type()), _M_fill_init(false), 456 0 : _M_streambuf(0), _M_ctype(0), _M_num_put(0), _M_num_get(0) 457 0 : { } 458 : 459 : /** 460 : * @brief All setup is performed here. 461 : * 462 : * This is called from the public constructor. It is not virtual and 463 : * cannot be redefined. 464 : */ 465 : void 466 : init(basic_streambuf<_CharT, _Traits>* __sb); 467 : 468 : void 469 : _M_cache_locale(const locale& __loc); 470 : }; 471 : 472 : _GLIBCXX_END_NAMESPACE 473 : 474 : #ifndef _GLIBCXX_EXPORT_TEMPLATE 475 : #include <bits/basic_ios.tcc> 476 : #endif 477 : 478 : #endif /* _BASIC_IOS_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // List implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * 45 : * Copyright (c) 1996,1997 46 : * Silicon Graphics Computer Systems, Inc. 47 : * 48 : * Permission to use, copy, modify, distribute and sell this software 49 : * and its documentation for any purpose is hereby granted without fee, 50 : * provided that the above copyright notice appear in all copies and 51 : * that both that copyright notice and this permission notice appear 52 : * in supporting documentation. Silicon Graphics makes no 53 : * representations about the suitability of this software for any 54 : * purpose. It is provided "as is" without express or implied warranty. 55 : */ 56 : 57 : /** @file stl_list.h 58 : * This is an internal header file, included by other library headers. 59 : * You should not attempt to use it directly. 60 : */ 61 : 62 : #ifndef _STL_LIST_H 63 : #define _STL_LIST_H 1 64 : 65 : #include <bits/concept_check.h> 66 : 67 : _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) 68 : 69 : // Supporting structures are split into common and templated types; the 70 : // latter publicly inherits from the former in an effort to reduce code 71 : // duplication. This results in some "needless" static_cast'ing later on, 72 : // but it's all safe downcasting. 73 : 74 : /// Common part of a node in the %list. 75 : struct _List_node_base 76 : { 77 : _List_node_base* _M_next; 78 : _List_node_base* _M_prev; 79 : 80 : static void 81 : swap(_List_node_base& __x, _List_node_base& __y); 82 : 83 : void 84 : transfer(_List_node_base * const __first, 85 : _List_node_base * const __last); 86 : 87 : void 88 : reverse(); 89 : 90 : void 91 : hook(_List_node_base * const __position); 92 : 93 : void 94 : unhook(); 95 : }; 96 : 97 : /// An actual node in the %list. 98 : template<typename _Tp> 99 : struct _List_node : public _List_node_base 100 : { 101 : ///< User's data. 102 : _Tp _M_data; 103 : }; 104 : 105 : /** 106 : * @brief A list::iterator. 107 : * 108 : * All the functions are op overloads. 109 : */ 110 : template<typename _Tp> 111 : struct _List_iterator 112 : { 113 : typedef _List_iterator<_Tp> _Self; 114 : typedef _List_node<_Tp> _Node; 115 : 116 : typedef ptrdiff_t difference_type; 117 : typedef std::bidirectional_iterator_tag iterator_category; 118 : typedef _Tp value_type; 119 : typedef _Tp* pointer; 120 : typedef _Tp& reference; 121 : 122 : _List_iterator() 123 : : _M_node() { } 124 : 125 : explicit 126 206 : _List_iterator(_List_node_base* __x) 127 206 : : _M_node(__x) { } 128 : 129 : // Must downcast from List_node_base to _List_node to get to _M_data. 130 : reference 131 99 : operator*() const 132 99 : { return static_cast<_Node*>(_M_node)->_M_data; } 133 : 134 : pointer 135 : operator->() const 136 : { return &static_cast<_Node*>(_M_node)->_M_data; } 137 : 138 : _Self& 139 63 : operator++() 140 : { 141 63 : _M_node = _M_node->_M_next; 142 63 : return *this; 143 : } 144 : 145 : _Self 146 0 : operator++(int) 147 : { 148 0 : _Self __tmp = *this; 149 0 : _M_node = _M_node->_M_next; 150 : return __tmp; 151 : } 152 : 153 : _Self& 154 1 : operator--() 155 : { 156 1 : _M_node = _M_node->_M_prev; 157 1 : return *this; 158 : } 159 : 160 : _Self 161 : operator--(int) 162 : { 163 : _Self __tmp = *this; 164 : _M_node = _M_node->_M_prev; 165 : return __tmp; 166 : } 167 : 168 : bool 169 108 : operator==(const _Self& __x) const 170 108 : { return _M_node == __x._M_node; } 171 : 172 : bool 173 42 : operator!=(const _Self& __x) const 174 42 : { return _M_node != __x._M_node; } 175 : 176 : // The only member points to the %list element. 177 : _List_node_base* _M_node; 178 : }; 179 : 180 : /** 181 : * @brief A list::const_iterator. 182 : * 183 : * All the functions are op overloads. 184 : */ 185 : template<typename _Tp> 186 : struct _List_const_iterator 187 : { 188 : typedef _List_const_iterator<_Tp> _Self; 189 : typedef const _List_node<_Tp> _Node; 190 : typedef _List_iterator<_Tp> iterator; 191 : 192 : typedef ptrdiff_t difference_type; 193 : typedef std::bidirectional_iterator_tag iterator_category; 194 : typedef _Tp value_type; 195 : typedef const _Tp* pointer; 196 : typedef const _Tp& reference; 197 : 198 : _List_const_iterator() 199 : : _M_node() { } 200 : 201 : explicit 202 42 : _List_const_iterator(const _List_node_base* __x) 203 42 : : _M_node(__x) { } 204 : 205 : _List_const_iterator(const iterator& __x) 206 : : _M_node(__x._M_node) { } 207 : 208 : // Must downcast from List_node_base to _List_node to get to 209 : // _M_data. 210 : reference 211 8 : operator*() const 212 8 : { return static_cast<_Node*>(_M_node)->_M_data; } 213 : 214 : pointer 215 : operator->() const 216 : { return &static_cast<_Node*>(_M_node)->_M_data; } 217 : 218 : _Self& 219 19 : operator++() 220 : { 221 19 : _M_node = _M_node->_M_next; 222 19 : return *this; 223 : } 224 : 225 : _Self 226 : operator++(int) 227 : { 228 : _Self __tmp = *this; 229 : _M_node = _M_node->_M_next; 230 : return __tmp; 231 : } 232 : 233 : _Self& 234 : operator--() 235 : { 236 : _M_node = _M_node->_M_prev; 237 : return *this; 238 : } 239 : 240 : _Self 241 : operator--(int) 242 : { 243 : _Self __tmp = *this; 244 : _M_node = _M_node->_M_prev; 245 : return __tmp; 246 : } 247 : 248 : bool 249 6 : operator==(const _Self& __x) const 250 6 : { return _M_node == __x._M_node; } 251 : 252 : bool 253 38 : operator!=(const _Self& __x) const 254 38 : { return _M_node != __x._M_node; } 255 : 256 : // The only member points to the %list element. 257 : const _List_node_base* _M_node; 258 : }; 259 : 260 : template<typename _Val> 261 : inline bool 262 : operator==(const _List_iterator<_Val>& __x, 263 : const _List_const_iterator<_Val>& __y) 264 : { return __x._M_node == __y._M_node; } 265 : 266 : template<typename _Val> 267 : inline bool 268 : operator!=(const _List_iterator<_Val>& __x, 269 : const _List_const_iterator<_Val>& __y) 270 : { return __x._M_node != __y._M_node; } 271 : 272 : 273 : /// See bits/stl_deque.h's _Deque_base for an explanation. 274 : template<typename _Tp, typename _Alloc> 275 : class _List_base 276 : { 277 : protected: 278 : // NOTA BENE 279 : // The stored instance is not actually of "allocator_type"'s 280 : // type. Instead we rebind the type to 281 : // Allocator<List_node<Tp>>, which according to [20.1.5]/4 282 : // should probably be the same. List_node<Tp> is not the same 283 : // size as Tp (it's two pointers larger), and specializations on 284 : // Tp may go unused because List_node<Tp> is being bound 285 : // instead. 286 : // 287 : // We put this to the test in the constructors and in 288 : // get_allocator, where we use conversions between 289 : // allocator_type and _Node_alloc_type. The conversion is 290 : // required by table 32 in [20.1.5]. 291 : typedef typename _Alloc::template rebind<_List_node<_Tp> >::other 292 : _Node_alloc_type; 293 : 294 : typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; 295 : 296 : struct _List_impl 297 : : public _Node_alloc_type 298 19 : { 299 : _List_node_base _M_node; 300 : 301 19 : _List_impl() 302 19 : : _Node_alloc_type(), _M_node() 303 19 : { } 304 : 305 : _List_impl(const _Node_alloc_type& __a) 306 : : _Node_alloc_type(__a), _M_node() 307 : { } 308 : }; 309 : 310 : _List_impl _M_impl; 311 : 312 : _List_node<_Tp>* 313 47 : _M_get_node() 314 47 : { return _M_impl._Node_alloc_type::allocate(1); } 315 : 316 : void 317 47 : _M_put_node(_List_node<_Tp>* __p) 318 47 : { _M_impl._Node_alloc_type::deallocate(__p, 1); } 319 : 320 : public: 321 : typedef _Alloc allocator_type; 322 : 323 : _Node_alloc_type& 324 : _M_get_Node_allocator() 325 : { return *static_cast<_Node_alloc_type*>(&this->_M_impl); } 326 : 327 : const _Node_alloc_type& 328 94 : _M_get_Node_allocator() const 329 94 : { return *static_cast<const _Node_alloc_type*>(&this->_M_impl); } 330 : 331 : _Tp_alloc_type 332 94 : _M_get_Tp_allocator() const 333 94 : { return _Tp_alloc_type(_M_get_Node_allocator()); } 334 : 335 : allocator_type 336 : get_allocator() const 337 : { return allocator_type(_M_get_Node_allocator()); } 338 : 339 19 : _List_base() 340 19 : : _M_impl() 341 19 : { _M_init(); } 342 : 343 : _List_base(const allocator_type& __a) 344 : : _M_impl(__a) 345 : { _M_init(); } 346 : 347 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 348 : _List_base(_List_base&& __x) 349 : : _M_impl(__x._M_get_Node_allocator()) 350 : { 351 : _M_init(); 352 : _List_node_base::swap(this->_M_impl._M_node, __x._M_impl._M_node); 353 : } 354 : #endif 355 : 356 : // This is what actually destroys the list. 357 19 : ~_List_base() 358 19 : { _M_clear(); } 359 : 360 : void 361 : _M_clear(); 362 : 363 : void 364 19 : _M_init() 365 : { 366 19 : this->_M_impl._M_node._M_next = &this->_M_impl._M_node; 367 19 : this->_M_impl._M_node._M_prev = &this->_M_impl._M_node; 368 19 : } 369 : }; 370 : 371 : /** 372 : * @brief A standard container with linear time access to elements, 373 : * and fixed time insertion/deletion at any point in the sequence. 374 : * 375 : * @ingroup Containers 376 : * @ingroup Sequences 377 : * 378 : * Meets the requirements of a <a href="tables.html#65">container</a>, a 379 : * <a href="tables.html#66">reversible container</a>, and a 380 : * <a href="tables.html#67">sequence</a>, including the 381 : * <a href="tables.html#68">optional sequence requirements</a> with the 382 : * %exception of @c at and @c operator[]. 383 : * 384 : * This is a @e doubly @e linked %list. Traversal up and down the 385 : * %list requires linear time, but adding and removing elements (or 386 : * @e nodes) is done in constant time, regardless of where the 387 : * change takes place. Unlike std::vector and std::deque, 388 : * random-access iterators are not provided, so subscripting ( @c 389 : * [] ) access is not allowed. For algorithms which only need 390 : * sequential access, this lack makes no difference. 391 : * 392 : * Also unlike the other standard containers, std::list provides 393 : * specialized algorithms %unique to linked lists, such as 394 : * splicing, sorting, and in-place reversal. 395 : * 396 : * A couple points on memory allocation for list<Tp>: 397 : * 398 : * First, we never actually allocate a Tp, we allocate 399 : * List_node<Tp>'s and trust [20.1.5]/4 to DTRT. This is to ensure 400 : * that after elements from %list<X,Alloc1> are spliced into 401 : * %list<X,Alloc2>, destroying the memory of the second %list is a 402 : * valid operation, i.e., Alloc1 giveth and Alloc2 taketh away. 403 : * 404 : * Second, a %list conceptually represented as 405 : * @code 406 : * A <---> B <---> C <---> D 407 : * @endcode 408 : * is actually circular; a link exists between A and D. The %list 409 : * class holds (as its only data member) a private list::iterator 410 : * pointing to @e D, not to @e A! To get to the head of the %list, 411 : * we start at the tail and move forward by one. When this member 412 : * iterator's next/previous pointers refer to itself, the %list is 413 : * %empty. 414 : */ 415 : template<typename _Tp, typename _Alloc = std::allocator<_Tp> > 416 : class list : protected _List_base<_Tp, _Alloc> 417 19 : { 418 : // concept requirements 419 : typedef typename _Alloc::value_type _Alloc_value_type; 420 : __glibcxx_class_requires(_Tp, _SGIAssignableConcept) 421 : __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) 422 : 423 : typedef _List_base<_Tp, _Alloc> _Base; 424 : typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; 425 : 426 : public: 427 : typedef _Tp value_type; 428 : typedef typename _Tp_alloc_type::pointer pointer; 429 : typedef typename _Tp_alloc_type::const_pointer const_pointer; 430 : typedef typename _Tp_alloc_type::reference reference; 431 : typedef typename _Tp_alloc_type::const_reference const_reference; 432 : typedef _List_iterator<_Tp> iterator; 433 : typedef _List_const_iterator<_Tp> const_iterator; 434 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 435 : typedef std::reverse_iterator<iterator> reverse_iterator; 436 : typedef size_t size_type; 437 : typedef ptrdiff_t difference_type; 438 : typedef _Alloc allocator_type; 439 : 440 : protected: 441 : // Note that pointers-to-_Node's can be ctor-converted to 442 : // iterator types. 443 : typedef _List_node<_Tp> _Node; 444 : 445 : using _Base::_M_impl; 446 : using _Base::_M_put_node; 447 : using _Base::_M_get_node; 448 : using _Base::_M_get_Tp_allocator; 449 : using _Base::_M_get_Node_allocator; 450 : 451 : /** 452 : * @param x An instance of user data. 453 : * 454 : * Allocates space for a new node and constructs a copy of @a x in it. 455 : */ 456 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 457 : _Node* 458 47 : _M_create_node(const value_type& __x) 459 : { 460 47 : _Node* __p = this->_M_get_node(); 461 : try 462 : { 463 47 : _M_get_Tp_allocator().construct(&__p->_M_data, __x); 464 : } 465 0 : catch(...) 466 : { 467 0 : _M_put_node(__p); 468 0 : __throw_exception_again; 469 : } 470 47 : return __p; 471 : } 472 : #else 473 : template<typename... _Args> 474 : _Node* 475 : _M_create_node(_Args&&... __args) 476 : { 477 : _Node* __p = this->_M_get_node(); 478 : try 479 : { 480 : _M_get_Tp_allocator().construct(&__p->_M_data, 481 : std::forward<_Args>(__args)...); 482 : } 483 : catch(...) 484 : { 485 : _M_put_node(__p); 486 : __throw_exception_again; 487 : } 488 : return __p; 489 : } 490 : #endif 491 : 492 : public: 493 : // [23.2.2.1] construct/copy/destroy 494 : // (assign() and get_allocator() are also listed in this section) 495 : /** 496 : * @brief Default constructor creates no elements. 497 : */ 498 19 : list() 499 19 : : _Base() { } 500 : 501 : /** 502 : * @brief Creates a %list with no elements. 503 : * @param a An allocator object. 504 : */ 505 : explicit 506 : list(const allocator_type& __a) 507 : : _Base(__a) { } 508 : 509 : /** 510 : * @brief Creates a %list with copies of an exemplar element. 511 : * @param n The number of elements to initially create. 512 : * @param value An element to copy. 513 : * @param a An allocator object. 514 : * 515 : * This constructor fills the %list with @a n copies of @a value. 516 : */ 517 : explicit 518 : list(size_type __n, const value_type& __value = value_type(), 519 : const allocator_type& __a = allocator_type()) 520 : : _Base(__a) 521 : { _M_fill_initialize(__n, __value); } 522 : 523 : /** 524 : * @brief %List copy constructor. 525 : * @param x A %list of identical element and allocator types. 526 : * 527 : * The newly-created %list uses a copy of the allocation object used 528 : * by @a x. 529 : */ 530 : list(const list& __x) 531 : : _Base(__x._M_get_Node_allocator()) 532 : { _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); } 533 : 534 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 535 : /** 536 : * @brief %List move constructor. 537 : * @param x A %list of identical element and allocator types. 538 : * 539 : * The newly-created %list contains the exact contents of @a x. 540 : * The contents of @a x are a valid, but unspecified %list. 541 : */ 542 : list(list&& __x) 543 : : _Base(std::forward<_Base>(__x)) { } 544 : #endif 545 : 546 : /** 547 : * @brief Builds a %list from a range. 548 : * @param first An input iterator. 549 : * @param last An input iterator. 550 : * @param a An allocator object. 551 : * 552 : * Create a %list consisting of copies of the elements from 553 : * [@a first,@a last). This is linear in N (where N is 554 : * distance(@a first,@a last)). 555 : */ 556 : template<typename _InputIterator> 557 : list(_InputIterator __first, _InputIterator __last, 558 : const allocator_type& __a = allocator_type()) 559 : : _Base(__a) 560 : { 561 : // Check whether it's an integral type. If so, it's not an iterator. 562 : typedef typename std::__is_integer<_InputIterator>::__type _Integral; 563 : _M_initialize_dispatch(__first, __last, _Integral()); 564 : } 565 : 566 : /** 567 : * No explicit dtor needed as the _Base dtor takes care of 568 : * things. The _Base dtor only erases the elements, and note 569 : * that if the elements themselves are pointers, the pointed-to 570 : * memory is not touched in any way. Managing the pointer is 571 : * the user's responsibility. 572 : */ 573 : 574 : /** 575 : * @brief %List assignment operator. 576 : * @param x A %list of identical element and allocator types. 577 : * 578 : * All the elements of @a x are copied, but unlike the copy 579 : * constructor, the allocator object is not copied. 580 : */ 581 : list& 582 : operator=(const list& __x); 583 : 584 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 585 : /** 586 : * @brief %List move assignment operator. 587 : * @param x A %list of identical element and allocator types. 588 : * 589 : * The contents of @a x are moved into this %list (without copying). 590 : * @a x is a valid, but unspecified %list 591 : */ 592 : list& 593 : operator=(list&& __x) 594 : { 595 : // NB: DR 675. 596 : this->clear(); 597 : this->swap(__x); 598 : return *this; 599 : } 600 : #endif 601 : 602 : /** 603 : * @brief Assigns a given value to a %list. 604 : * @param n Number of elements to be assigned. 605 : * @param val Value to be assigned. 606 : * 607 : * This function fills a %list with @a n copies of the given 608 : * value. Note that the assignment completely changes the %list 609 : * and that the resulting %list's size is the same as the number 610 : * of elements assigned. Old data may be lost. 611 : */ 612 : void 613 : assign(size_type __n, const value_type& __val) 614 : { _M_fill_assign(__n, __val); } 615 : 616 : /** 617 : * @brief Assigns a range to a %list. 618 : * @param first An input iterator. 619 : * @param last An input iterator. 620 : * 621 : * This function fills a %list with copies of the elements in the 622 : * range [@a first,@a last). 623 : * 624 : * Note that the assignment completely changes the %list and 625 : * that the resulting %list's size is the same as the number of 626 : * elements assigned. Old data may be lost. 627 : */ 628 : template<typename _InputIterator> 629 : void 630 : assign(_InputIterator __first, _InputIterator __last) 631 : { 632 : // Check whether it's an integral type. If so, it's not an iterator. 633 : typedef typename std::__is_integer<_InputIterator>::__type _Integral; 634 : _M_assign_dispatch(__first, __last, _Integral()); 635 : } 636 : 637 : /// Get a copy of the memory allocation object. 638 : allocator_type 639 : get_allocator() const 640 : { return _Base::get_allocator(); } 641 : 642 : // iterators 643 : /** 644 : * Returns a read/write iterator that points to the first element in the 645 : * %list. Iteration is done in ordinary element order. 646 : */ 647 : iterator 648 27 : begin() 649 27 : { return iterator(this->_M_impl._M_node._M_next); } 650 : 651 : /** 652 : * Returns a read-only (constant) iterator that points to the 653 : * first element in the %list. Iteration is done in ordinary 654 : * element order. 655 : */ 656 : const_iterator 657 21 : begin() const 658 21 : { return const_iterator(this->_M_impl._M_node._M_next); } 659 : 660 : /** 661 : * Returns a read/write iterator that points one past the last 662 : * element in the %list. Iteration is done in ordinary element 663 : * order. 664 : */ 665 : iterator 666 154 : end() 667 154 : { return iterator(&this->_M_impl._M_node); } 668 : 669 : /** 670 : * Returns a read-only (constant) iterator that points one past 671 : * the last element in the %list. Iteration is done in ordinary 672 : * element order. 673 : */ 674 : const_iterator 675 21 : end() const 676 21 : { return const_iterator(&this->_M_impl._M_node); } 677 : 678 : /** 679 : * Returns a read/write reverse iterator that points to the last 680 : * element in the %list. Iteration is done in reverse element 681 : * order. 682 : */ 683 : reverse_iterator 684 1 : rbegin() 685 1 : { return reverse_iterator(end()); } 686 : 687 : /** 688 : * Returns a read-only (constant) reverse iterator that points to 689 : * the last element in the %list. Iteration is done in reverse 690 : * element order. 691 : */ 692 : const_reverse_iterator 693 : rbegin() const 694 : { return const_reverse_iterator(end()); } 695 : 696 : /** 697 : * Returns a read/write reverse iterator that points to one 698 : * before the first element in the %list. Iteration is done in 699 : * reverse element order. 700 : */ 701 : reverse_iterator 702 : rend() 703 : { return reverse_iterator(begin()); } 704 : 705 : /** 706 : * Returns a read-only (constant) reverse iterator that points to one 707 : * before the first element in the %list. Iteration is done in reverse 708 : * element order. 709 : */ 710 : const_reverse_iterator 711 : rend() const 712 : { return const_reverse_iterator(begin()); } 713 : 714 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 715 : /** 716 : * Returns a read-only (constant) iterator that points to the 717 : * first element in the %list. Iteration is done in ordinary 718 : * element order. 719 : */ 720 : const_iterator 721 : cbegin() const 722 : { return const_iterator(this->_M_impl._M_node._M_next); } 723 : 724 : /** 725 : * Returns a read-only (constant) iterator that points one past 726 : * the last element in the %list. Iteration is done in ordinary 727 : * element order. 728 : */ 729 : const_iterator 730 : cend() const 731 : { return const_iterator(&this->_M_impl._M_node); } 732 : 733 : /** 734 : * Returns a read-only (constant) reverse iterator that points to 735 : * the last element in the %list. Iteration is done in reverse 736 : * element order. 737 : */ 738 : const_reverse_iterator 739 : crbegin() const 740 : { return const_reverse_iterator(end()); } 741 : 742 : /** 743 : * Returns a read-only (constant) reverse iterator that points to one 744 : * before the first element in the %list. Iteration is done in reverse 745 : * element order. 746 : */ 747 : const_reverse_iterator 748 : crend() const 749 : { return const_reverse_iterator(begin()); } 750 : #endif 751 : 752 : // [23.2.2.2] capacity 753 : /** 754 : * Returns true if the %list is empty. (Thus begin() would equal 755 : * end().) 756 : */ 757 : bool 758 : empty() const 759 : { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; } 760 : 761 : /** Returns the number of elements in the %list. */ 762 : size_type 763 13 : size() const 764 13 : { return std::distance(begin(), end()); } 765 : 766 : /** Returns the size() of the largest possible %list. */ 767 : size_type 768 : max_size() const 769 : { return _M_get_Tp_allocator().max_size(); } 770 : 771 : /** 772 : * @brief Resizes the %list to the specified number of elements. 773 : * @param new_size Number of elements the %list should contain. 774 : * @param x Data with which new elements should be populated. 775 : * 776 : * This function will %resize the %list to the specified number 777 : * of elements. If the number is smaller than the %list's 778 : * current size the %list is truncated, otherwise the %list is 779 : * extended and new elements are populated with given data. 780 : */ 781 : void 782 : resize(size_type __new_size, value_type __x = value_type()); 783 : 784 : // element access 785 : /** 786 : * Returns a read/write reference to the data at the first 787 : * element of the %list. 788 : */ 789 : reference 790 : front() 791 : { return *begin(); } 792 : 793 : /** 794 : * Returns a read-only (constant) reference to the data at the first 795 : * element of the %list. 796 : */ 797 : const_reference 798 : front() const 799 : { return *begin(); } 800 : 801 : /** 802 : * Returns a read/write reference to the data at the last element 803 : * of the %list. 804 : */ 805 : reference 806 : back() 807 : { 808 : iterator __tmp = end(); 809 : --__tmp; 810 : return *__tmp; 811 : } 812 : 813 : /** 814 : * Returns a read-only (constant) reference to the data at the last 815 : * element of the %list. 816 : */ 817 : const_reference 818 : back() const 819 : { 820 : const_iterator __tmp = end(); 821 : --__tmp; 822 : return *__tmp; 823 : } 824 : 825 : // [23.2.2.3] modifiers 826 : /** 827 : * @brief Add data to the front of the %list. 828 : * @param x Data to be added. 829 : * 830 : * This is a typical stack operation. The function creates an 831 : * element at the front of the %list and assigns the given data 832 : * to it. Due to the nature of a %list this operation can be 833 : * done in constant time, and does not invalidate iterators and 834 : * references. 835 : */ 836 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 837 : void 838 : push_front(const value_type& __x) 839 : { this->_M_insert(begin(), __x); } 840 : #else 841 : template<typename... _Args> 842 : void 843 : push_front(_Args&&... __args) 844 : { this->_M_insert(begin(), std::forward<_Args>(__args)...); } 845 : #endif 846 : 847 : /** 848 : * @brief Removes first element. 849 : * 850 : * This is a typical stack operation. It shrinks the %list by 851 : * one. Due to the nature of a %list this operation can be done 852 : * in constant time, and only invalidates iterators/references to 853 : * the element being removed. 854 : * 855 : * Note that no data is returned, and if the first element's data 856 : * is needed, it should be retrieved before pop_front() is 857 : * called. 858 : */ 859 : void 860 : pop_front() 861 : { this->_M_erase(begin()); } 862 : 863 : /** 864 : * @brief Add data to the end of the %list. 865 : * @param x Data to be added. 866 : * 867 : * This is a typical stack operation. The function creates an 868 : * element at the end of the %list and assigns the given data to 869 : * it. Due to the nature of a %list this operation can be done 870 : * in constant time, and does not invalidate iterators and 871 : * references. 872 : */ 873 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 874 : void 875 47 : push_back(const value_type& __x) 876 47 : { this->_M_insert(end(), __x); } 877 : #else 878 : template<typename... _Args> 879 : void 880 : push_back(_Args&&... __args) 881 : { this->_M_insert(end(), std::forward<_Args>(__args)...); } 882 : #endif 883 : 884 : /** 885 : * @brief Removes last element. 886 : * 887 : * This is a typical stack operation. It shrinks the %list by 888 : * one. Due to the nature of a %list this operation can be done 889 : * in constant time, and only invalidates iterators/references to 890 : * the element being removed. 891 : * 892 : * Note that no data is returned, and if the last element's data 893 : * is needed, it should be retrieved before pop_back() is called. 894 : */ 895 : void 896 : pop_back() 897 : { this->_M_erase(iterator(this->_M_impl._M_node._M_prev)); } 898 : 899 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 900 : /** 901 : * @brief Constructs object in %list before specified iterator. 902 : * @param position A const_iterator into the %list. 903 : * @param args Arguments. 904 : * @return An iterator that points to the inserted data. 905 : * 906 : * This function will insert an object of type T constructed 907 : * with T(std::forward<Args>(args)...) before the specified 908 : * location. Due to the nature of a %list this operation can 909 : * be done in constant time, and does not invalidate iterators 910 : * and references. 911 : */ 912 : template<typename... _Args> 913 : iterator 914 : emplace(iterator __position, _Args&&... __args); 915 : #endif 916 : 917 : /** 918 : * @brief Inserts given value into %list before specified iterator. 919 : * @param position An iterator into the %list. 920 : * @param x Data to be inserted. 921 : * @return An iterator that points to the inserted data. 922 : * 923 : * This function will insert a copy of the given value before 924 : * the specified location. Due to the nature of a %list this 925 : * operation can be done in constant time, and does not 926 : * invalidate iterators and references. 927 : */ 928 : iterator 929 : insert(iterator __position, const value_type& __x); 930 : 931 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 932 : /** 933 : * @brief Inserts given rvalue into %list before specified iterator. 934 : * @param position An iterator into the %list. 935 : * @param x Data to be inserted. 936 : * @return An iterator that points to the inserted data. 937 : * 938 : * This function will insert a copy of the given rvalue before 939 : * the specified location. Due to the nature of a %list this 940 : * operation can be done in constant time, and does not 941 : * invalidate iterators and references. 942 : */ 943 : iterator 944 : insert(iterator __position, value_type&& __x) 945 : { return emplace(__position, std::move(__x)); } 946 : #endif 947 : 948 : /** 949 : * @brief Inserts a number of copies of given data into the %list. 950 : * @param position An iterator into the %list. 951 : * @param n Number of elements to be inserted. 952 : * @param x Data to be inserted. 953 : * 954 : * This function will insert a specified number of copies of the 955 : * given data before the location specified by @a position. 956 : * 957 : * This operation is linear in the number of elements inserted and 958 : * does not invalidate iterators and references. 959 : */ 960 : void 961 : insert(iterator __position, size_type __n, const value_type& __x) 962 : { 963 : list __tmp(__n, __x, _M_get_Node_allocator()); 964 : splice(__position, __tmp); 965 : } 966 : 967 : /** 968 : * @brief Inserts a range into the %list. 969 : * @param position An iterator into the %list. 970 : * @param first An input iterator. 971 : * @param last An input iterator. 972 : * 973 : * This function will insert copies of the data in the range [@a 974 : * first,@a last) into the %list before the location specified by 975 : * @a position. 976 : * 977 : * This operation is linear in the number of elements inserted and 978 : * does not invalidate iterators and references. 979 : */ 980 : template<typename _InputIterator> 981 : void 982 : insert(iterator __position, _InputIterator __first, 983 : _InputIterator __last) 984 : { 985 : list __tmp(__first, __last, _M_get_Node_allocator()); 986 : splice(__position, __tmp); 987 : } 988 : 989 : /** 990 : * @brief Remove element at given position. 991 : * @param position Iterator pointing to element to be erased. 992 : * @return An iterator pointing to the next element (or end()). 993 : * 994 : * This function will erase the element at the given position and thus 995 : * shorten the %list by one. 996 : * 997 : * Due to the nature of a %list this operation can be done in 998 : * constant time, and only invalidates iterators/references to 999 : * the element being removed. The user is also cautioned that 1000 : * this function only erases the element, and that if the element 1001 : * is itself a pointer, the pointed-to memory is not touched in 1002 : * any way. Managing the pointer is the user's responsibility. 1003 : */ 1004 : iterator 1005 : erase(iterator __position); 1006 : 1007 : /** 1008 : * @brief Remove a range of elements. 1009 : * @param first Iterator pointing to the first element to be erased. 1010 : * @param last Iterator pointing to one past the last element to be 1011 : * erased. 1012 : * @return An iterator pointing to the element pointed to by @a last 1013 : * prior to erasing (or end()). 1014 : * 1015 : * This function will erase the elements in the range @a 1016 : * [first,last) and shorten the %list accordingly. 1017 : * 1018 : * This operation is linear time in the size of the range and only 1019 : * invalidates iterators/references to the element being removed. 1020 : * The user is also cautioned that this function only erases the 1021 : * elements, and that if the elements themselves are pointers, the 1022 : * pointed-to memory is not touched in any way. Managing the pointer 1023 : * is the user's responsibility. 1024 : */ 1025 : iterator 1026 : erase(iterator __first, iterator __last) 1027 : { 1028 : while (__first != __last) 1029 : __first = erase(__first); 1030 : return __last; 1031 : } 1032 : 1033 : /** 1034 : * @brief Swaps data with another %list. 1035 : * @param x A %list of the same element and allocator types. 1036 : * 1037 : * This exchanges the elements between two lists in constant 1038 : * time. Note that the global std::swap() function is 1039 : * specialized such that std::swap(l1,l2) will feed to this 1040 : * function. 1041 : */ 1042 : void 1043 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1044 : swap(list&& __x) 1045 : #else 1046 : swap(list& __x) 1047 : #endif 1048 : { 1049 : _List_node_base::swap(this->_M_impl._M_node, __x._M_impl._M_node); 1050 : 1051 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1052 : // 431. Swapping containers with unequal allocators. 1053 : std::__alloc_swap<typename _Base::_Node_alloc_type>:: 1054 : _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator()); 1055 : } 1056 : 1057 : /** 1058 : * Erases all the elements. Note that this function only erases 1059 : * the elements, and that if the elements themselves are 1060 : * pointers, the pointed-to memory is not touched in any way. 1061 : * Managing the pointer is the user's responsibility. 1062 : */ 1063 : void 1064 : clear() 1065 : { 1066 : _Base::_M_clear(); 1067 : _Base::_M_init(); 1068 : } 1069 : 1070 : // [23.2.2.4] list operations 1071 : /** 1072 : * @brief Insert contents of another %list. 1073 : * @param position Iterator referencing the element to insert before. 1074 : * @param x Source list. 1075 : * 1076 : * The elements of @a x are inserted in constant time in front of 1077 : * the element referenced by @a position. @a x becomes an empty 1078 : * list. 1079 : * 1080 : * Requires this != @a x. 1081 : */ 1082 : void 1083 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1084 : splice(iterator __position, list&& __x) 1085 : #else 1086 : splice(iterator __position, list& __x) 1087 : #endif 1088 : { 1089 : if (!__x.empty()) 1090 : { 1091 : _M_check_equal_allocators(__x); 1092 : 1093 : this->_M_transfer(__position, __x.begin(), __x.end()); 1094 : } 1095 : } 1096 : 1097 : /** 1098 : * @brief Insert element from another %list. 1099 : * @param position Iterator referencing the element to insert before. 1100 : * @param x Source list. 1101 : * @param i Iterator referencing the element to move. 1102 : * 1103 : * Removes the element in list @a x referenced by @a i and 1104 : * inserts it into the current list before @a position. 1105 : */ 1106 : void 1107 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1108 : splice(iterator __position, list&& __x, iterator __i) 1109 : #else 1110 : splice(iterator __position, list& __x, iterator __i) 1111 : #endif 1112 : { 1113 : iterator __j = __i; 1114 : ++__j; 1115 : if (__position == __i || __position == __j) 1116 : return; 1117 : 1118 : if (this != &__x) 1119 : _M_check_equal_allocators(__x); 1120 : 1121 : this->_M_transfer(__position, __i, __j); 1122 : } 1123 : 1124 : /** 1125 : * @brief Insert range from another %list. 1126 : * @param position Iterator referencing the element to insert before. 1127 : * @param x Source list. 1128 : * @param first Iterator referencing the start of range in x. 1129 : * @param last Iterator referencing the end of range in x. 1130 : * 1131 : * Removes elements in the range [first,last) and inserts them 1132 : * before @a position in constant time. 1133 : * 1134 : * Undefined if @a position is in [first,last). 1135 : */ 1136 : void 1137 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1138 : splice(iterator __position, list&& __x, iterator __first, 1139 : iterator __last) 1140 : #else 1141 : splice(iterator __position, list& __x, iterator __first, 1142 : iterator __last) 1143 : #endif 1144 : { 1145 : if (__first != __last) 1146 : { 1147 : if (this != &__x) 1148 : _M_check_equal_allocators(__x); 1149 : 1150 : this->_M_transfer(__position, __first, __last); 1151 : } 1152 : } 1153 : 1154 : /** 1155 : * @brief Remove all elements equal to value. 1156 : * @param value The value to remove. 1157 : * 1158 : * Removes every element in the list equal to @a value. 1159 : * Remaining elements stay in list order. Note that this 1160 : * function only erases the elements, and that if the elements 1161 : * themselves are pointers, the pointed-to memory is not 1162 : * touched in any way. Managing the pointer is the user's 1163 : * responsibility. 1164 : */ 1165 : void 1166 : remove(const _Tp& __value); 1167 : 1168 : /** 1169 : * @brief Remove all elements satisfying a predicate. 1170 : * @param Predicate Unary predicate function or object. 1171 : * 1172 : * Removes every element in the list for which the predicate 1173 : * returns true. Remaining elements stay in list order. Note 1174 : * that this function only erases the elements, and that if the 1175 : * elements themselves are pointers, the pointed-to memory is 1176 : * not touched in any way. Managing the pointer is the user's 1177 : * responsibility. 1178 : */ 1179 : template<typename _Predicate> 1180 : void 1181 : remove_if(_Predicate); 1182 : 1183 : /** 1184 : * @brief Remove consecutive duplicate elements. 1185 : * 1186 : * For each consecutive set of elements with the same value, 1187 : * remove all but the first one. Remaining elements stay in 1188 : * list order. Note that this function only erases the 1189 : * elements, and that if the elements themselves are pointers, 1190 : * the pointed-to memory is not touched in any way. Managing 1191 : * the pointer is the user's responsibility. 1192 : */ 1193 : void 1194 : unique(); 1195 : 1196 : /** 1197 : * @brief Remove consecutive elements satisfying a predicate. 1198 : * @param BinaryPredicate Binary predicate function or object. 1199 : * 1200 : * For each consecutive set of elements [first,last) that 1201 : * satisfy predicate(first,i) where i is an iterator in 1202 : * [first,last), remove all but the first one. Remaining 1203 : * elements stay in list order. Note that this function only 1204 : * erases the elements, and that if the elements themselves are 1205 : * pointers, the pointed-to memory is not touched in any way. 1206 : * Managing the pointer is the user's responsibility. 1207 : */ 1208 : template<typename _BinaryPredicate> 1209 : void 1210 : unique(_BinaryPredicate); 1211 : 1212 : /** 1213 : * @brief Merge sorted lists. 1214 : * @param x Sorted list to merge. 1215 : * 1216 : * Assumes that both @a x and this list are sorted according to 1217 : * operator<(). Merges elements of @a x into this list in 1218 : * sorted order, leaving @a x empty when complete. Elements in 1219 : * this list precede elements in @a x that are equal. 1220 : */ 1221 : void 1222 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1223 : merge(list&& __x); 1224 : #else 1225 : merge(list& __x); 1226 : #endif 1227 : 1228 : /** 1229 : * @brief Merge sorted lists according to comparison function. 1230 : * @param x Sorted list to merge. 1231 : * @param StrictWeakOrdering Comparison function defining 1232 : * sort order. 1233 : * 1234 : * Assumes that both @a x and this list are sorted according to 1235 : * StrictWeakOrdering. Merges elements of @a x into this list 1236 : * in sorted order, leaving @a x empty when complete. Elements 1237 : * in this list precede elements in @a x that are equivalent 1238 : * according to StrictWeakOrdering(). 1239 : */ 1240 : template<typename _StrictWeakOrdering> 1241 : void 1242 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1243 : merge(list&&, _StrictWeakOrdering); 1244 : #else 1245 : merge(list&, _StrictWeakOrdering); 1246 : #endif 1247 : 1248 : /** 1249 : * @brief Reverse the elements in list. 1250 : * 1251 : * Reverse the order of elements in the list in linear time. 1252 : */ 1253 : void 1254 : reverse() 1255 : { this->_M_impl._M_node.reverse(); } 1256 : 1257 : /** 1258 : * @brief Sort the elements. 1259 : * 1260 : * Sorts the elements of this list in NlogN time. Equivalent 1261 : * elements remain in list order. 1262 : */ 1263 : void 1264 : sort(); 1265 : 1266 : /** 1267 : * @brief Sort the elements according to comparison function. 1268 : * 1269 : * Sorts the elements of this list in NlogN time. Equivalent 1270 : * elements remain in list order. 1271 : */ 1272 : template<typename _StrictWeakOrdering> 1273 : void 1274 : sort(_StrictWeakOrdering); 1275 : 1276 : protected: 1277 : // Internal constructor functions follow. 1278 : 1279 : // Called by the range constructor to implement [23.1.1]/9 1280 : 1281 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1282 : // 438. Ambiguity in the "do the right thing" clause 1283 : template<typename _Integer> 1284 : void 1285 : _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) 1286 : { _M_fill_initialize(static_cast<size_type>(__n), __x); } 1287 : 1288 : // Called by the range constructor to implement [23.1.1]/9 1289 : template<typename _InputIterator> 1290 : void 1291 : _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, 1292 : __false_type) 1293 : { 1294 : for (; __first != __last; ++__first) 1295 : push_back(*__first); 1296 : } 1297 : 1298 : // Called by list(n,v,a), and the range constructor when it turns out 1299 : // to be the same thing. 1300 : void 1301 : _M_fill_initialize(size_type __n, const value_type& __x) 1302 : { 1303 : for (; __n > 0; --__n) 1304 : push_back(__x); 1305 : } 1306 : 1307 : 1308 : // Internal assign functions follow. 1309 : 1310 : // Called by the range assign to implement [23.1.1]/9 1311 : 1312 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1313 : // 438. Ambiguity in the "do the right thing" clause 1314 : template<typename _Integer> 1315 : void 1316 : _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) 1317 : { _M_fill_assign(__n, __val); } 1318 : 1319 : // Called by the range assign to implement [23.1.1]/9 1320 : template<typename _InputIterator> 1321 : void 1322 : _M_assign_dispatch(_InputIterator __first, _InputIterator __last, 1323 : __false_type); 1324 : 1325 : // Called by assign(n,t), and the range assign when it turns out 1326 : // to be the same thing. 1327 : void 1328 : _M_fill_assign(size_type __n, const value_type& __val); 1329 : 1330 : 1331 : // Moves the elements from [first,last) before position. 1332 : void 1333 : _M_transfer(iterator __position, iterator __first, iterator __last) 1334 : { __position._M_node->transfer(__first._M_node, __last._M_node); } 1335 : 1336 : // Inserts new element at position given and with value given. 1337 : #ifndef __GXX_EXPERIMENTAL_CXX0X__ 1338 : void 1339 47 : _M_insert(iterator __position, const value_type& __x) 1340 : { 1341 47 : _Node* __tmp = _M_create_node(__x); 1342 47 : __tmp->hook(__position._M_node); 1343 47 : } 1344 : #else 1345 : template<typename... _Args> 1346 : void 1347 : _M_insert(iterator __position, _Args&&... __args) 1348 : { 1349 : _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...); 1350 : __tmp->hook(__position._M_node); 1351 : } 1352 : #endif 1353 : 1354 : // Erases element at position given. 1355 : void 1356 25 : _M_erase(iterator __position) 1357 : { 1358 25 : __position._M_node->unhook(); 1359 25 : _Node* __n = static_cast<_Node*>(__position._M_node); 1360 25 : _M_get_Tp_allocator().destroy(&__n->_M_data); 1361 25 : _M_put_node(__n); 1362 25 : } 1363 : 1364 : // To implement the splice (and merge) bits of N1599. 1365 : void 1366 : _M_check_equal_allocators(list& __x) 1367 : { 1368 : if (std::__alloc_neq<typename _Base::_Node_alloc_type>:: 1369 : _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator())) 1370 : __throw_runtime_error(__N("list::_M_check_equal_allocators")); 1371 : } 1372 : }; 1373 : 1374 : /** 1375 : * @brief List equality comparison. 1376 : * @param x A %list. 1377 : * @param y A %list of the same type as @a x. 1378 : * @return True iff the size and elements of the lists are equal. 1379 : * 1380 : * This is an equivalence relation. It is linear in the size of 1381 : * the lists. Lists are considered equivalent if their sizes are 1382 : * equal, and if corresponding elements compare equal. 1383 : */ 1384 : template<typename _Tp, typename _Alloc> 1385 : inline bool 1386 4 : operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) 1387 : { 1388 : typedef typename list<_Tp, _Alloc>::const_iterator const_iterator; 1389 4 : const_iterator __end1 = __x.end(); 1390 4 : const_iterator __end2 = __y.end(); 1391 : 1392 4 : const_iterator __i1 = __x.begin(); 1393 4 : const_iterator __i2 = __y.begin(); 1394 12 : while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) 1395 : { 1396 4 : ++__i1; 1397 4 : ++__i2; 1398 : } 1399 4 : return __i1 == __end1 && __i2 == __end2; 1400 : } 1401 : 1402 : /** 1403 : * @brief List ordering relation. 1404 : * @param x A %list. 1405 : * @param y A %list of the same type as @a x. 1406 : * @return True iff @a x is lexicographically less than @a y. 1407 : * 1408 : * This is a total ordering relation. It is linear in the size of the 1409 : * lists. The elements must be comparable with @c <. 1410 : * 1411 : * See std::lexicographical_compare() for how the determination is made. 1412 : */ 1413 : template<typename _Tp, typename _Alloc> 1414 : inline bool 1415 : operator<(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) 1416 : { return std::lexicographical_compare(__x.begin(), __x.end(), 1417 : __y.begin(), __y.end()); } 1418 : 1419 : /// Based on operator== 1420 : template<typename _Tp, typename _Alloc> 1421 : inline bool 1422 2 : operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) 1423 2 : { return !(__x == __y); } 1424 : 1425 : /// Based on operator< 1426 : template<typename _Tp, typename _Alloc> 1427 : inline bool 1428 : operator>(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) 1429 : { return __y < __x; } 1430 : 1431 : /// Based on operator< 1432 : template<typename _Tp, typename _Alloc> 1433 : inline bool 1434 : operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) 1435 : { return !(__y < __x); } 1436 : 1437 : /// Based on operator< 1438 : template<typename _Tp, typename _Alloc> 1439 : inline bool 1440 : operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) 1441 : { return !(__x < __y); } 1442 : 1443 : /// See std::list::swap(). 1444 : template<typename _Tp, typename _Alloc> 1445 : inline void 1446 : swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) 1447 : { __x.swap(__y); } 1448 : 1449 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 1450 : template<typename _Tp, typename _Alloc> 1451 : inline void 1452 : swap(list<_Tp, _Alloc>&& __x, list<_Tp, _Alloc>& __y) 1453 : { __x.swap(__y); } 1454 : 1455 : template<typename _Tp, typename _Alloc> 1456 : inline void 1457 : swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>&& __y) 1458 : { __x.swap(__y); } 1459 : #endif 1460 : 1461 : _GLIBCXX_END_NESTED_NAMESPACE 1462 : 1463 : #endif /* _STL_LIST_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // Heap implementation -*- C++ -*- 2 : 3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 : // Free Software Foundation, Inc. 5 : // 6 : // This file is part of the GNU ISO C++ Library. This library is free 7 : // software; you can redistribute it and/or modify it under the 8 : // terms of the GNU General Public License as published by the 9 : // Free Software Foundation; either version 2, or (at your option) 10 : // any later version. 11 : 12 : // This library is distributed in the hope that it will be useful, 13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : // GNU General Public License for more details. 16 : 17 : // You should have received a copy of the GNU General Public License along 18 : // with this library; see the file COPYING. If not, write to the Free 19 : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 : // USA. 21 : 22 : // As a special exception, you may use this file as part of a free software 23 : // library without restriction. Specifically, if other files instantiate 24 : // templates or use macros or inline functions from this file, or you compile 25 : // this file and link it with other files to produce an executable, this 26 : // file does not by itself cause the resulting executable to be covered by 27 : // the GNU General Public License. This exception does not however 28 : // invalidate any other reasons why the executable file might be covered by 29 : // the GNU General Public License. 30 : 31 : /* 32 : * 33 : * Copyright (c) 1994 34 : * Hewlett-Packard Company 35 : * 36 : * Permission to use, copy, modify, distribute and sell this software 37 : * and its documentation for any purpose is hereby granted without fee, 38 : * provided that the above copyright notice appear in all copies and 39 : * that both that copyright notice and this permission notice appear 40 : * in supporting documentation. Hewlett-Packard Company makes no 41 : * representations about the suitability of this software for any 42 : * purpose. It is provided "as is" without express or implied warranty. 43 : * 44 : * Copyright (c) 1997 45 : * Silicon Graphics Computer Systems, Inc. 46 : * 47 : * Permission to use, copy, modify, distribute and sell this software 48 : * and its documentation for any purpose is hereby granted without fee, 49 : * provided that the above copyright notice appear in all copies and 50 : * that both that copyright notice and this permission notice appear 51 : * in supporting documentation. Silicon Graphics makes no 52 : * representations about the suitability of this software for any 53 : * purpose. It is provided "as is" without express or implied warranty. 54 : */ 55 : 56 : /** @file stl_heap.h 57 : * This is an internal header file, included by other library headers. 58 : * You should not attempt to use it directly. 59 : */ 60 : 61 : #ifndef _STL_HEAP_H 62 : #define _STL_HEAP_H 1 63 : 64 : #include <debug/debug.h> 65 : #include <bits/stl_move.h> 66 : 67 : _GLIBCXX_BEGIN_NAMESPACE(std) 68 : 69 : template<typename _RandomAccessIterator, typename _Distance> 70 : _Distance 71 : __is_heap_until(_RandomAccessIterator __first, _Distance __n) 72 : { 73 : _Distance __parent = 0; 74 : for (_Distance __child = 1; __child < __n; ++__child) 75 : { 76 : if (__first[__parent] < __first[__child]) 77 : return __child; 78 : if ((__child & 1) == 0) 79 : ++__parent; 80 : } 81 : return __n; 82 : } 83 : 84 : template<typename _RandomAccessIterator, typename _Distance, 85 : typename _Compare> 86 : _Distance 87 : __is_heap_until(_RandomAccessIterator __first, _Distance __n, 88 : _Compare __comp) 89 : { 90 : _Distance __parent = 0; 91 : for (_Distance __child = 1; __child < __n; ++__child) 92 : { 93 : if (__comp(__first[__parent], __first[__child])) 94 : return __child; 95 : if ((__child & 1) == 0) 96 : ++__parent; 97 : } 98 : return __n; 99 : } 100 : 101 : // __is_heap, a predicate testing whether or not a range is a heap. 102 : // This function is an extension, not part of the C++ standard. 103 : template<typename _RandomAccessIterator, typename _Distance> 104 : inline bool 105 : __is_heap(_RandomAccessIterator __first, _Distance __n) 106 : { return std::__is_heap_until(__first, __n) == __n; } 107 : 108 : template<typename _RandomAccessIterator, typename _Compare, 109 : typename _Distance> 110 : inline bool 111 : __is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n) 112 : { return std::__is_heap_until(__first, __n, __comp) == __n; } 113 : 114 : template<typename _RandomAccessIterator> 115 : inline bool 116 : __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 117 : { return std::__is_heap(__first, std::distance(__first, __last)); } 118 : 119 : template<typename _RandomAccessIterator, typename _Compare> 120 : inline bool 121 : __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 122 : _Compare __comp) 123 : { return std::__is_heap(__first, __comp, std::distance(__first, __last)); } 124 : 125 : // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap, 126 : // + is_heap and is_heap_until in C++0x. 127 : 128 : template<typename _RandomAccessIterator, typename _Distance, typename _Tp> 129 : void 130 : __push_heap(_RandomAccessIterator __first, 131 0 : _Distance __holeIndex, _Distance __topIndex, _Tp __value) 132 : { 133 0 : _Distance __parent = (__holeIndex - 1) / 2; 134 0 : while (__holeIndex > __topIndex && *(__first + __parent) < __value) 135 : { 136 0 : *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent)); 137 0 : __holeIndex = __parent; 138 0 : __parent = (__holeIndex - 1) / 2; 139 : } 140 0 : *(__first + __holeIndex) = _GLIBCXX_MOVE(__value); 141 0 : } 142 : 143 : /** 144 : * @brief Push an element onto a heap. 145 : * @param first Start of heap. 146 : * @param last End of heap + element. 147 : * @ingroup heap 148 : * 149 : * This operation pushes the element at last-1 onto the valid heap over the 150 : * range [first,last-1). After completion, [first,last) is a valid heap. 151 : */ 152 : template<typename _RandomAccessIterator> 153 : inline void 154 : push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 155 : { 156 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 157 : _ValueType; 158 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 159 : _DistanceType; 160 : 161 : // concept requirements 162 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 163 : _RandomAccessIterator>) 164 : __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 165 : __glibcxx_requires_valid_range(__first, __last); 166 : __glibcxx_requires_heap(__first, __last - 1); 167 : 168 : _ValueType __value = _GLIBCXX_MOVE(*(__last - 1)); 169 : std::__push_heap(__first, _DistanceType((__last - __first) - 1), 170 : _DistanceType(0), _GLIBCXX_MOVE(__value)); 171 : } 172 : 173 : template<typename _RandomAccessIterator, typename _Distance, typename _Tp, 174 : typename _Compare> 175 : void 176 : __push_heap(_RandomAccessIterator __first, _Distance __holeIndex, 177 0 : _Distance __topIndex, _Tp __value, _Compare __comp) 178 : { 179 0 : _Distance __parent = (__holeIndex - 1) / 2; 180 0 : while (__holeIndex > __topIndex 181 : && __comp(*(__first + __parent), __value)) 182 : { 183 0 : *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent)); 184 0 : __holeIndex = __parent; 185 0 : __parent = (__holeIndex - 1) / 2; 186 : } 187 0 : *(__first + __holeIndex) = _GLIBCXX_MOVE(__value); 188 0 : } 189 : 190 : /** 191 : * @brief Push an element onto a heap using comparison functor. 192 : * @param first Start of heap. 193 : * @param last End of heap + element. 194 : * @param comp Comparison functor. 195 : * @ingroup heap 196 : * 197 : * This operation pushes the element at last-1 onto the valid heap over the 198 : * range [first,last-1). After completion, [first,last) is a valid heap. 199 : * Compare operations are performed using comp. 200 : */ 201 : template<typename _RandomAccessIterator, typename _Compare> 202 : inline void 203 : push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 204 : _Compare __comp) 205 : { 206 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 207 : _ValueType; 208 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 209 : _DistanceType; 210 : 211 : // concept requirements 212 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 213 : _RandomAccessIterator>) 214 : __glibcxx_requires_valid_range(__first, __last); 215 : __glibcxx_requires_heap_pred(__first, __last - 1, __comp); 216 : 217 : _ValueType __value = _GLIBCXX_MOVE(*(__last - 1)); 218 : std::__push_heap(__first, _DistanceType((__last - __first) - 1), 219 : _DistanceType(0), _GLIBCXX_MOVE(__value), __comp); 220 : } 221 : 222 : template<typename _RandomAccessIterator, typename _Distance, typename _Tp> 223 : void 224 : __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, 225 0 : _Distance __len, _Tp __value) 226 : { 227 0 : const _Distance __topIndex = __holeIndex; 228 0 : _Distance __secondChild = __holeIndex; 229 0 : while (__secondChild < (__len - 1) / 2) 230 : { 231 0 : __secondChild = 2 * (__secondChild + 1); 232 0 : if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) 233 0 : __secondChild--; 234 0 : *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild)); 235 0 : __holeIndex = __secondChild; 236 : } 237 0 : if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2) 238 : { 239 0 : __secondChild = 2 * (__secondChild + 1); 240 0 : *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first 241 : + (__secondChild - 1))); 242 0 : __holeIndex = __secondChild - 1; 243 : } 244 0 : std::__push_heap(__first, __holeIndex, __topIndex, 245 : _GLIBCXX_MOVE(__value)); 246 0 : } 247 : 248 : template<typename _RandomAccessIterator> 249 : inline void 250 : __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 251 0 : _RandomAccessIterator __result) 252 : { 253 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 254 : _ValueType; 255 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 256 : _DistanceType; 257 : 258 0 : _ValueType __value = _GLIBCXX_MOVE(*__result); 259 0 : *__result = _GLIBCXX_MOVE(*__first); 260 0 : std::__adjust_heap(__first, _DistanceType(0), 261 : _DistanceType(__last - __first), 262 : _GLIBCXX_MOVE(__value)); 263 0 : } 264 : 265 : /** 266 : * @brief Pop an element off a heap. 267 : * @param first Start of heap. 268 : * @param last End of heap. 269 : * @ingroup heap 270 : * 271 : * This operation pops the top of the heap. The elements first and last-1 272 : * are swapped and [first,last-1) is made into a heap. 273 : */ 274 : template<typename _RandomAccessIterator> 275 : inline void 276 0 : pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 277 : { 278 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 279 : _ValueType; 280 : 281 : // concept requirements 282 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 283 : _RandomAccessIterator>) 284 : __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 285 : __glibcxx_requires_valid_range(__first, __last); 286 : __glibcxx_requires_heap(__first, __last); 287 : 288 0 : std::__pop_heap(__first, __last - 1, __last - 1); 289 0 : } 290 : 291 : template<typename _RandomAccessIterator, typename _Distance, 292 : typename _Tp, typename _Compare> 293 : void 294 : __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, 295 0 : _Distance __len, _Tp __value, _Compare __comp) 296 : { 297 0 : const _Distance __topIndex = __holeIndex; 298 0 : _Distance __secondChild = __holeIndex; 299 0 : while (__secondChild < (__len - 1) / 2) 300 : { 301 0 : __secondChild = 2 * (__secondChild + 1); 302 0 : if (__comp(*(__first + __secondChild), 303 : *(__first + (__secondChild - 1)))) 304 0 : __secondChild--; 305 0 : *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild)); 306 0 : __holeIndex = __secondChild; 307 : } 308 0 : if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2) 309 : { 310 0 : __secondChild = 2 * (__secondChild + 1); 311 0 : *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first 312 : + (__secondChild - 1))); 313 0 : __holeIndex = __secondChild - 1; 314 : } 315 0 : std::__push_heap(__first, __holeIndex, __topIndex, 316 : _GLIBCXX_MOVE(__value), __comp); 317 0 : } 318 : 319 : template<typename _RandomAccessIterator, typename _Compare> 320 : inline void 321 : __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 322 0 : _RandomAccessIterator __result, _Compare __comp) 323 : { 324 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 325 : _ValueType; 326 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 327 : _DistanceType; 328 : 329 0 : _ValueType __value = _GLIBCXX_MOVE(*__result); 330 0 : *__result = _GLIBCXX_MOVE(*__first); 331 0 : std::__adjust_heap(__first, _DistanceType(0), 332 : _DistanceType(__last - __first), 333 : _GLIBCXX_MOVE(__value), __comp); 334 0 : } 335 : 336 : /** 337 : * @brief Pop an element off a heap using comparison functor. 338 : * @param first Start of heap. 339 : * @param last End of heap. 340 : * @param comp Comparison functor to use. 341 : * @ingroup heap 342 : * 343 : * This operation pops the top of the heap. The elements first and last-1 344 : * are swapped and [first,last-1) is made into a heap. Comparisons are 345 : * made using comp. 346 : */ 347 : template<typename _RandomAccessIterator, typename _Compare> 348 : inline void 349 : pop_heap(_RandomAccessIterator __first, 350 0 : _RandomAccessIterator __last, _Compare __comp) 351 : { 352 : // concept requirements 353 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 354 : _RandomAccessIterator>) 355 : __glibcxx_requires_valid_range(__first, __last); 356 : __glibcxx_requires_heap_pred(__first, __last, __comp); 357 : 358 0 : std::__pop_heap(__first, __last - 1, __last - 1, __comp); 359 0 : } 360 : 361 : /** 362 : * @brief Construct a heap over a range. 363 : * @param first Start of heap. 364 : * @param last End of heap. 365 : * @ingroup heap 366 : * 367 : * This operation makes the elements in [first,last) into a heap. 368 : */ 369 : template<typename _RandomAccessIterator> 370 : void 371 0 : make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 372 : { 373 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 374 : _ValueType; 375 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 376 : _DistanceType; 377 : 378 : // concept requirements 379 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 380 : _RandomAccessIterator>) 381 : __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) 382 : __glibcxx_requires_valid_range(__first, __last); 383 : 384 0 : if (__last - __first < 2) 385 0 : return; 386 : 387 0 : const _DistanceType __len = __last - __first; 388 0 : _DistanceType __parent = (__len - 2) / 2; 389 0 : while (true) 390 : { 391 0 : _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent)); 392 0 : std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value)); 393 0 : if (__parent == 0) 394 0 : return; 395 0 : __parent--; 396 : } 397 : } 398 : 399 : /** 400 : * @brief Construct a heap over a range using comparison functor. 401 : * @param first Start of heap. 402 : * @param last End of heap. 403 : * @param comp Comparison functor to use. 404 : * @ingroup heap 405 : * 406 : * This operation makes the elements in [first,last) into a heap. 407 : * Comparisons are made using comp. 408 : */ 409 : template<typename _RandomAccessIterator, typename _Compare> 410 : void 411 : make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 412 0 : _Compare __comp) 413 : { 414 : typedef typename iterator_traits<_RandomAccessIterator>::value_type 415 : _ValueType; 416 : typedef typename iterator_traits<_RandomAccessIterator>::difference_type 417 : _DistanceType; 418 : 419 : // concept requirements 420 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 421 : _RandomAccessIterator>) 422 : __glibcxx_requires_valid_range(__first, __last); 423 : 424 0 : if (__last - __first < 2) 425 0 : return; 426 : 427 0 : const _DistanceType __len = __last - __first; 428 0 : _DistanceType __parent = (__len - 2) / 2; 429 0 : while (true) 430 : { 431 0 : _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent)); 432 0 : std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value), 433 : __comp); 434 0 : if (__parent == 0) 435 0 : return; 436 0 : __parent--; 437 : } 438 : } 439 : 440 : /** 441 : * @brief Sort a heap. 442 : * @param first Start of heap. 443 : * @param last End of heap. 444 : * @ingroup heap 445 : * 446 : * This operation sorts the valid heap in the range [first,last). 447 : */ 448 : template<typename _RandomAccessIterator> 449 : void 450 0 : sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 451 : { 452 : // concept requirements 453 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 454 : _RandomAccessIterator>) 455 : __glibcxx_function_requires(_LessThanComparableConcept< 456 : typename iterator_traits<_RandomAccessIterator>::value_type>) 457 : __glibcxx_requires_valid_range(__first, __last); 458 : __glibcxx_requires_heap(__first, __last); 459 : 460 0 : while (__last - __first > 1) 461 0 : std::pop_heap(__first, _RandomAccessIterator(__last--)); 462 0 : } 463 : 464 : /** 465 : * @brief Sort a heap using comparison functor. 466 : * @param first Start of heap. 467 : * @param last End of heap. 468 : * @param comp Comparison functor to use. 469 : * @ingroup heap 470 : * 471 : * This operation sorts the valid heap in the range [first,last). 472 : * Comparisons are made using comp. 473 : */ 474 : template<typename _RandomAccessIterator, typename _Compare> 475 : void 476 : sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 477 0 : _Compare __comp) 478 : { 479 : // concept requirements 480 : __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< 481 : _RandomAccessIterator>) 482 : __glibcxx_requires_valid_range(__first, __last); 483 : __glibcxx_requires_heap_pred(__first, __last, __comp); 484 : 485 0 : while (__last - __first > 1) 486 0 : std::pop_heap(__first, _RandomAccessIterator(__last--), __comp); 487 0 : } 488 : 489 : #ifdef __GXX_EXPERIMENTAL_CXX0X__ 490 : /** 491 : * @brief Search the end of a heap. 492 : * @param first Start of range. 493 : * @param last End of range. 494 : * @return An iterator pointing to the first element not in the heap. 495 : * @ingroup heap 496 : * 497 : * This operation returns the last iterator i in [first, last) for which 498 : * the range [first, i) is a heap. 499 : */ 500 : template<typename _RandomAccessIterator> 501 : inline _RandomAccessIterator 502 : is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) 503 : { 504 : // concept requirements 505 : __glibcxx_function_requires(_RandomAccessIteratorConcept< 506 : _RandomAccessIterator>) 507 : __glibcxx_function_requires(_LessThanComparableConcept< 508 : typename iterator_traits<_RandomAccessIterator>::value_type>) 509 : __glibcxx_requires_valid_range(__first, __last); 510 : 511 : return __first + std::__is_heap_until(__first, std::distance(__first, 512 : __last)); 513 : } 514 : 515 : /** 516 : * @brief Search the end of a heap using comparison functor. 517 : * @param first Start of range. 518 : * @param last End of range. 519 : * @param comp Comparison functor to use. 520 : * @return An iterator pointing to the first element not in the heap. 521 : * @ingroup heap 522 : * 523 : * This operation returns the last iterator i in [first, last) for which 524 : * the range [first, i) is a heap. Comparisons are made using comp. 525 : */ 526 : template<typename _RandomAccessIterator, typename _Compare> 527 : inline _RandomAccessIterator 528 : is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, 529 : _Compare __comp) 530 : { 531 : // concept requirements 532 : __glibcxx_function_requires(_RandomAccessIteratorConcept< 533 : _RandomAccessIterator>) 534 : __glibcxx_requires_valid_range(__first, __last); 535 : 536 : return __first + std::__is_heap_until(__first, std::distance(__first, 537 : __last), 538 : __comp); 539 : } 540 : 541 : /** 542 : * @brief Determines whether a range is a heap. 543 : * @param first Start of range. 544 : * @param last End of range. 545 : * @return True if range is a heap, false otherwise. 546 : * @ingroup heap 547 : */ 548 : template<typename _RandomAccessIterator> 549 : inline bool 550 : is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 551 : { return std::is_heap_until(__first, __last) == __last; } 552 : 553 : /** 554 : * @brief Determines whether a range is a heap using comparison functor. 555 : * @param first Start of range. 556 : * @param last End of range. 557 : * @param comp Comparison functor to use. 558 : * @return True if range is a heap, false otherwise. 559 : * @ingroup heap 560 : */ 561 : template<typename _RandomAccessIterator, typename _Compare> 562 : inline bool 563 : is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, 564 : _Compare __comp) 565 : { return std::is_heap_until(__first, __last, __comp) == __last; } 566 : #endif 567 : 568 : _GLIBCXX_END_NAMESPACE 569 : 570 : #endif /* _STL_HEAP_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Serialize a tagged collection to a text file 3 : * 4 : * Copyright (C) 2003--2008 Enrico Zini <enrico@debian.org> 5 : * 6 : * This library is free software; you can redistribute it and/or 7 : * modify it under the terms of the GNU Lesser General Public 8 : * License as published by the Free Software Foundation; either 9 : * version 2.1 of the License, or (at your option) any later version. 10 : * 11 : * This library is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 : * Lesser General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU Lesser General Public 17 : * License along with this library; if not, write to the Free Software 18 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : */ 20 : 21 : #ifndef TAGCOLL_TEXTFORMAT_TCC 22 : #define TAGCOLL_TEXTFORMAT_TCC 23 : 24 : #include <tagcoll/TextFormat.h> 25 : #include <tagcoll/patch.h> 26 : 27 : #include <wibble/exception.h> 28 : #include <wibble/empty.h> 29 : #include <wibble/operators.h> 30 : 31 : #include <ostream> 32 : 33 : using namespace std; 34 : using namespace wibble; 35 : using namespace wibble::operators; 36 : 37 0 : static void printTagset(const std::set<string>& ts, FILE* out) 38 : { 39 0 : for (std::set<string>::const_iterator i = ts.begin(); 40 : i != ts.end(); i++) 41 0 : if (i == ts.begin()) 42 : { 43 0 : if (fprintf(out, "%s", i->c_str()) < 0) 44 0 : throw wibble::exception::System("writing tagset"); 45 : } 46 : else 47 : { 48 0 : if (fprintf(out, ", %s", i->c_str()) < 0) 49 0 : throw wibble::exception::System("writing tagset"); 50 : } 51 0 : } 52 : 53 : namespace tagcoll { 54 : namespace textformat { 55 : 56 126871 : inline static void outString(const std::string& str, FILE* out, const char* what) 57 : { 58 126871 : if (fwrite(str.data(), str.size(), 1, out) != 1) 59 0 : throw wibble::exception::System(string("writing ") + what); 60 126871 : } 61 : 62 : template<typename Items, typename Tags> 63 21145 : StdioWriter& StdioWriter::operator=(const std::pair<Items, Tags>& data) 64 : { 65 42290 : for (typename Items::const_iterator i = data.first.begin(); 66 : i != data.first.end(); ++i) 67 : { 68 21145 : if (i != data.first.begin()) 69 0 : if (fputs(", ", out) == EOF) 70 0 : throw wibble::exception::System("writing comma after item"); 71 21145 : outString(*i, out, "item"); 72 : } 73 21145 : if (data.second.begin() != data.second.end()) 74 : { 75 21145 : if (fputs(": ", out) == EOF) 76 0 : throw wibble::exception::System("writing colon after items"); 77 126871 : for (typename Tags::const_iterator i = data.second.begin(); 78 : i != data.second.end(); ++i) 79 : { 80 105726 : if (i != data.second.begin()) 81 84581 : if (fputs(", ", out) == EOF) 82 0 : throw wibble::exception::System("writing comma after tag"); 83 105726 : outString(*i, out, "tag"); 84 : } 85 : } 86 21145 : if (fputc('\n', out) == EOF) 87 0 : throw wibble::exception::System("writing newline after tagset"); 88 21145 : return *this; 89 : } 90 : 91 : template<typename Items, typename Tags> 92 : OstreamWriter& OstreamWriter::operator=(const std::pair<Items, Tags>& data) 93 : { 94 : for (typename Items::const_iterator i = data.first.begin(); 95 : i != data.first.end(); ++i) 96 : { 97 : if (i != data.first.begin()) 98 : out << ", "; 99 : out << *i; 100 : } 101 : if (data.second.begin() != data.second.end()) 102 : { 103 : out << ": "; 104 : for (typename Tags::const_iterator i = data.second.begin(); 105 : i != data.second.end(); ++i) 106 : { 107 : if (i != data.second.begin()) 108 : out << ", "; 109 : out << *i; 110 : } 111 : } 112 : out << endl; 113 : return *this; 114 : } 115 : 116 : 117 : 118 : // item1, item2, item3: tag1, tag2, tag3 119 : 120 : //#define TRACE_PARSE 121 : template<typename OUT> 122 2 : void parse(input::Input& in, OUT out) 123 : { 124 2 : string item; 125 : 126 2 : std::set<string> itemset; 127 2 : std::set<string> tagset; 128 : int sep; 129 2 : enum {ITEMS, TAGS} state = ITEMS; 130 2 : int line = 1; 131 253744 : do 132 : { 133 : try { 134 253744 : sep = parseElement(in, item); 135 0 : } catch (tagcoll::exception::Parser& e) { 136 : // Add the line number and propagate 137 0 : e.line(line); 138 0 : throw e; 139 : } 140 : 141 507488 : if (item.size() != 0) 142 : { 143 253742 : if (state == ITEMS) 144 42290 : itemset |= item; 145 : else 146 211452 : tagset |= item; 147 : } 148 : 149 253744 : switch (sep) 150 : { 151 : case '\n': 152 42290 : line++; 153 : case input::Input::Eof: 154 42292 : if (!(itemset.empty() && tagset.empty())) 155 : { 156 42290 : if (itemset.empty()) 157 0 : throw tagcoll::exception::Input(line, "no elements before `:' separator"); 158 42290 : if (tagset.empty()) 159 0 : *out = make_pair(itemset, wibble::Empty<std::string>()); 160 : else 161 42290 : *out = make_pair(itemset, tagset); 162 42290 : ++out; 163 : } 164 42292 : itemset.clear(); 165 42292 : tagset.clear(); 166 42292 : state = ITEMS; 167 42292 : break; 168 : case ':': 169 42290 : if (state == TAGS) 170 0 : throw tagcoll::exception::Input(line, "separator `:' appears twice"); 171 42290 : state = TAGS; 172 : break; 173 : default: 174 2 : break; 175 : } 176 : } while (sep != input::Input::Eof); 177 2 : } 178 : 179 : template<typename OUT> template<typename ITEMS, typename TAGS> 180 0 : PatchAssembler<OUT>& PatchAssembler<OUT>::operator=(const std::pair<ITEMS, TAGS>& data) 181 : { 182 0 : std::set<std::string> added; 183 0 : std::set<std::string> removed; 184 : 185 0 : for (typename TAGS::const_iterator i = data.second.begin(); 186 : i != data.second.end(); ++i) 187 : { 188 0 : std::string tag = i->substr(1); 189 0 : if (!tag.empty()) 190 : { 191 0 : if ((*i)[0] == '-') 192 0 : removed.insert(tag); 193 0 : else if ((*i)[0] == '+') 194 0 : added.insert(tag); 195 : } 196 : } 197 : 198 0 : for (typename ITEMS::const_iterator i = data.first.begin(); 199 : i != data.first.end(); ++i) 200 : { 201 0 : std::string it = *i; 202 0 : if (!it.empty()) 203 : { 204 0 : *out = Patch<std::string, std::string>(it, added, removed); 205 0 : ++out; 206 : } 207 : } 208 0 : return *this; 209 : } 210 : 211 : 212 : 213 : template<typename ITEM, typename TAG, typename ITEMSER, typename TAGSER> 214 : void outputPatch( 215 : ITEMSER& itemconv, 216 : TAGSER& tagconv, 217 : const PatchList<ITEM, TAG>& patch, 218 : FILE* out) 219 : { 220 : for (typename PatchList<ITEM, TAG>::const_iterator i = patch.begin(); 221 : i != patch.end(); i++) 222 : { 223 : string sitem = itemconv(i->first); 224 : if (fprintf(out, "%s: ", sitem.c_str()) < 0) 225 : throw wibble::exception::System("writing item"); 226 : 227 : std::set<string> stags; 228 : for (typename std::set<TAG>::const_iterator j = i->second.added.begin(); 229 : j != i->second.added.end(); j++) 230 : stags |= "+"+tagconv(*j); 231 : for (typename std::set<TAG>::const_iterator j = i->second.removed.begin(); 232 : j != i->second.removed.end(); j++) 233 : stags |= "-"+tagconv(*j); 234 : 235 : printTagset(stags, out); 236 : if (fprintf(out, "\n") < 0) 237 : throw wibble::exception::System("writing newline after tagset"); 238 : } 239 : } 240 : 241 : template<typename ITEM, typename TAG, typename ITEMSER, typename TAGSER> 242 : template<typename ITEMS, typename TAGS> 243 : PatchBuilder<ITEM, TAG, ITEMSER, TAGSER>& PatchBuilder<ITEM, TAG, ITEMSER, TAGSER>::operator=(const std::pair<ITEMS, TAGS>& data) 244 : { 245 : std::set<TAG> added; 246 : std::set<TAG> removed; 247 : 248 : for (typename TAGS::const_iterator i = data.second.begin(); 249 : i != data.second.end(); ++i) 250 : { 251 : TAG tag = tagconv(i->substr(1)); 252 : if (tag != TAG()) 253 : { 254 : if ((*i)[0] == '-') 255 : removed.insert(tag); 256 : else if ((*i)[0] == '+') 257 : added.insert(tag); 258 : } 259 : } 260 : 261 : for (typename ITEMS::const_iterator i = data.first.begin(); 262 : i != data.first.end(); ++i) 263 : { 264 : ITEM it = itemconv(*i); 265 : if (it != ITEM()) 266 : patch.addPatch(Patch<ITEM, TAG>(it, added, removed)); 267 : } 268 : return *this; 269 : } 270 : 271 : 272 : template<typename ITEM, typename TAG, typename ITEMSER, typename TAGSER> 273 : PatchList<ITEM, TAG> parsePatch( 274 : ITEMSER& itemconv, 275 : TAGSER& tagconv, 276 : input::Input& in) 277 : { 278 : PatchList<ITEM, TAG> patch; 279 : parse(in, patchBuilder(patch, itemconv, tagconv)); 280 : return patch; 281 : } 282 : 283 : } 284 6 : } 285 : 286 : #include <tagcoll/patch.tcc> 287 : 288 : #endif 289 : 290 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_INPUT_BASE_H 2 : #define TAGCOLL_INPUT_BASE_H 3 : 4 : /** \file 5 : * Base class for parsers 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2003,2004,2005,2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <string> 27 : #include <wibble/exception.h> 28 : 29 : namespace tagcoll { 30 : 31 : namespace input { 32 : class Input; 33 : } 34 : 35 : namespace exception { 36 : 37 : /** 38 : * Base exception for parser errors 39 : */ 40 : class Input : public wibble::exception::Consistency 41 0 : { 42 : protected: 43 : std::string _file; 44 : int _line; 45 : 46 : std::string makeContext(const std::string& file, int line); 47 : 48 : public: 49 : Input(const tagcoll::input::Input& input, const std::string& message) throw (); 50 : Input(const std::string& file, int line, const std::string& message) throw () 51 : : wibble::exception::Consistency(makeContext(file, line), message), 52 : _file(file), _line(line) {} 53 0 : Input(int line, const std::string& message) throw () 54 0 : : wibble::exception::Consistency(makeContext(std::string(), line), message), 55 0 : _line(line) {} 56 : Input(const std::string& message) throw () 57 : : wibble::exception::Consistency(makeContext(std::string(), -1), message), 58 : _line(-1) {} 59 0 : virtual ~Input() throw () {} 60 : 61 : int line() const throw () { return _line; } 62 0 : int line(int line) throw () { return _line = line; } 63 : 64 : const std::string& file() const throw () { return _file; } 65 : std::string file() throw () { return _file; } 66 : std::string file(const std::string file) throw () { return _file = file; } 67 : 68 0 : virtual const char* type() const throw () { return "Input"; } 69 : }; 70 : 71 : /** 72 : * Exception thrown in case of problems accessing the input of the parser 73 : */ 74 : class Parser : public Input 75 0 : { 76 : public: 77 0 : Parser(const tagcoll::input::Input& input, const std::string& message) throw () 78 0 : : Input(input, message) {} 79 0 : virtual ~Parser() throw () {} 80 : 81 0 : virtual const char* type() const throw () 82 : { 83 0 : return "Parser"; 84 : } 85 : }; 86 : 87 : } 88 : 89 : namespace input { 90 : 91 : /** 92 : * Generic interface for parser input readers. 93 : * 94 : * It encapsulates and hides the reading machinery. It can be implemented as a 95 : * file read, a stream read, a decompressing file read, a network read or 96 : * whatever else is needed. 97 : */ 98 : class Input 99 : { 100 : public: 101 : static const int Eof = -1; 102 : 103 : Input() {} 104 1305 : virtual ~Input() {} 105 : 106 : virtual const std::string& fileName() const = 0; 107 : virtual int lineNumber() const = 0; 108 : virtual int nextChar() = 0; 109 : virtual void pushChar(int c) = 0; 110 : }; 111 : 112 : } 113 : 114 : } 115 : 116 : // vim:set ts=4 sw=4: 117 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_INPUT_STRING_H 2 : #define TAGCOLL_INPUT_STRING_H 3 : 4 : /** \file 5 : * Parser input using a std::string as input 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2003--2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <tagcoll/input/base.h> 27 : #include <string> 28 : 29 : namespace tagcoll { 30 : namespace input { 31 : 32 : /** 33 : * Parser input using a std::string as input 34 : */ 35 : class String : public Input 36 : { 37 : protected: 38 : static const std::string fname; 39 : std::string _str; 40 : std::string::const_iterator _s; 41 : int _line; 42 : 43 : public: 44 : String(const std::string& str); 45 4 : virtual ~String() {} 46 : 47 : virtual const std::string& fileName() const throw () { return fname; } 48 : virtual int lineNumber() const throw () { return _line; } 49 : 50 : virtual int nextChar(); 51 : virtual void pushChar(int c); 52 : }; 53 : 54 : } 55 : } 56 : 57 : // vim:set ts=4 sw=4: 58 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_INPUT_MEMORY_H 2 : #define TAGCOLL_INPUT_MEMORY_H 3 : 4 : /** \file 5 : * Parser input using a buffer as input 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2003-2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <tagcoll/input/base.h> 27 : #include <string> 28 : 29 : namespace tagcoll { 30 : namespace input { 31 : 32 : /** 33 : * Parser input using a std::string as input 34 : */ 35 : class Memory : public Input 36 : { 37 : protected: 38 : const std::string fname; 39 : const char* buf; 40 : int pos; 41 : int len; 42 : int _line; 43 : 44 : public: 45 : Memory(const std::string& fname, const char* buf, int len) throw (); 46 : Memory(const char* buf, int len) throw (); 47 1301 : virtual ~Memory() throw () {} 48 : 49 : virtual const std::string& fileName() const throw () { return fname; } 50 : virtual int lineNumber() const throw () { return _line; } 51 : 52 : virtual int nextChar() throw (); 53 : virtual void pushChar(int c) throw (); 54 : }; 55 : 56 : } 57 : } 58 : 59 : // vim:set ts=4 sw=4: 60 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
base.h |
|
7.1 % | 1 / 14 lines | |
memory.h |
|
100.0 % | 1 / 1 lines | |
string.h |
|
100.0 % | 1 / 1 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_DISKINDEX_MMAP_H 2 : #define TAGCOLL_DISKINDEX_MMAP_H 3 : 4 : /** \file 5 : * Basic infrastructure for implementing mmapped indexes 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This program is free software; you can redistribute it and/or modify 12 : * it under the terms of the GNU General Public License as published by 13 : * the Free Software Foundation; either version 2 of the License, or 14 : * (at your option) any later version. 15 : * 16 : * This program is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 : * GNU General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU General Public License 22 : * along with this program; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <string> 27 : 28 : namespace tagcoll { 29 : namespace diskindex { 30 : 31 : class mmap; 32 : 33 : /** 34 : * Performs the memory management and mmapping tasks for mmapped indexes. 35 : * 36 : * One MMap can contain many indexes. Indexes come chained one after the 37 : * other, prefixed by an int that specifies their length: 38 : * 39 : * [size of index 1][index1][size of index 2][index]... 40 : * 41 : * Every index must make sure that its size is int-aligned, otherwise accessing 42 : * it would cause a bus error in many architectures. 43 : */ 44 : class MasterMMap 45 : { 46 : protected: 47 : std::string m_filename; 48 : size_t m_size; 49 : int m_fd; 50 : const char* m_buf; 51 : 52 : public: 53 : MasterMMap(); 54 : MasterMMap(const std::string& filename); 55 : ~MasterMMap(); 56 : 57 : void init(const std::string& filename); 58 : 59 : friend class MMap; 60 : }; 61 : 62 : class MMap 63 : { 64 : protected: 65 : const MasterMMap* m_master; 66 : const char* m_buf; 67 : size_t m_size; 68 : 69 : public: 70 : MMap(); 71 : MMap(const char* buf, int size); 72 : MMap(const MasterMMap& master, size_t idx); 73 : 74 : void init(const char* buf, int size); 75 : void init(const MasterMMap& master, size_t idx); 76 : 77 : /// Round a value to the next word size in the current architecture 78 : template<class INT> 79 12 : static inline INT align(INT val) 80 : { 81 12 : return (val + sizeof(int) - 1) & ~(sizeof(int) - 1); 82 : } 83 : }; 84 : 85 : /** 86 : * Interface for indexers. 87 : */ 88 : class MMapIndexer 89 20 : { 90 : public: 91 20 : virtual ~MMapIndexer() {} 92 : 93 : /// Return the size of the encoded index data (in bytes) 94 : virtual int encodedSize() const = 0; 95 : 96 : /// Write the index data in the given buffer, which should be at least 97 : /// encodedSize bytes 98 : virtual void encode(char* buf) const = 0; 99 : }; 100 : 101 : /** 102 : * Master index writer. It allows to write many indexes in the same file, 103 : * atomically: the file will be created as a tempfile and atomically renamed to 104 : * the destination filename on class destruction. 105 : */ 106 : class MasterMMapIndexer 107 : { 108 : protected: 109 : std::string finalname; 110 : std::string tmpname; 111 : int fd; 112 : 113 : public: 114 : MasterMMapIndexer(const std::string& filename); 115 : ~MasterMMapIndexer(); 116 : 117 : /// Close the file and perform the final rename 118 : void commit(); 119 : 120 : /// Append one subindex 121 : void append(const MMapIndexer& idx); 122 : }; 123 : 124 : 125 : } 126 : } 127 : 128 : // vim:set ts=4 sw=4: 129 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_DISKINDEX_INT_H 2 : #define TAGCOLL_DISKINDEX_INT_H 3 : 4 : /** \file 5 : * Fast index for tag data, based on integer indexes 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This program is free software; you can redistribute it and/or modify 12 : * it under the terms of the GNU General Public License as published by 13 : * the Free Software Foundation; either version 2 of the License, or 14 : * (at your option) any later version. 15 : * 16 : * This program is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 : * GNU General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU General Public License 22 : * along with this program; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <tagcoll/diskindex/mmap.h> 27 : #include <vector> 28 : #include <set> 29 : 30 : namespace tagcoll { 31 : namespace diskindex { 32 : 33 : /** 34 : * MMap-based index of a -> [x1, x2, x3] mappings 35 : * 36 : * The layout is: 37 : * 38 : * [offset of mapping for item 0, offset of mapping for item 1...] 39 : * [size of array][sorted array of ints pointed by index 0] 40 : * [size of array][sorted array of ints pointed by index 1] 41 : * [size of array][sorted array of ints pointed by index 2] 42 : * [...] 43 : * [number of items in the mapping] 44 : * 45 : * This allows fast lookups, as well as fast lookups of unions or intersections 46 : * of mapped arrays. 47 : * 48 : * The number of items for an ID not present in the index is assumed to be 0. 49 : */ 50 : class Int : public MMap 51 : { 52 : protected: 53 274890 : inline int* buf() const { return (int*)m_buf; } 54 274890 : inline size_t ofs(int val) const { return buf()[val]; } 55 : 56 : public: 57 20 : Int() {} 58 : Int(const MasterMMap& master, int idx) : MMap(master, idx) {} 59 : 60 : const int* data(int val) const { return (val >= 0 && (unsigned)val < size()) ? buf() + ofs(val) + 1 : 0; } 61 0 : size_t size(int val) const { return (val >= 0 && (unsigned)val < size()) ? buf()[ofs(val)] : 0; } 62 274893 : size_t size() const { return m_buf ? ofs(0) : 0; } 63 : }; 64 : 65 : /** 66 : * Creates an on-disk index to use for IntIndex 67 : */ 68 : class IntIndexer : public MMapIndexer, public std::vector<std::set<int> > 69 4 : { 70 : public: 71 : /// Store the key->val mapping into the indexer 72 211196 : void map(unsigned int key, int val) 73 : { 74 211196 : if (size() <= key) 75 21142 : resize(key + 1); 76 211196 : (*this)[key].insert(val); 77 211196 : } 78 : 79 : /// Return the size of the encoded index data 80 : virtual int encodedSize() const; 81 : 82 : /// Write the index data in the given buffer, which should be at least 83 : /// encodedSize bytes 84 : virtual void encode(char* buf) const; 85 : }; 86 : 87 : } 88 : } 89 : 90 : // vim:set ts=4 sw=4: 91 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
int.h |
|
90.9 % | 10 / 11 lines | |
mmap.h |
|
100.0 % | 4 / 4 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_EXPRESSION_H 2 : #define TAGCOLL_EXPRESSION_H 3 : 4 : /* 5 : * Expression that can match tagsets 6 : * 7 : * Copyright (C) 2003,2004,2005,2006 Enrico Zini <enrico@debian.org> 8 : * 9 : * This library is free software; you can redistribute it and/or 10 : * modify it under the terms of the GNU Lesser General Public 11 : * License as published by the Free Software Foundation; either 12 : * version 2.1 of the License, or (at your option) any later version. 13 : * 14 : * This library is distributed in the hope that it will be useful, 15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 : * Lesser General Public License for more details. 18 : * 19 : * You should have received a copy of the GNU Lesser General Public 20 : * License along with this library; if not, write to the Free Software 21 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 : */ 23 : 24 : #include <string> 25 : #include <set> 26 : #include <map> 27 : #include <wibble/singleton.h> 28 : #include <wibble/mixin.h> 29 : 30 : namespace tagcoll 31 : { 32 : 33 : class TagexprContext; 34 : 35 : /** 36 : * Interface for parsed tag expressions 37 : */ 38 : class ExpressionImpl 39 : { 40 : protected: 41 : int _ref; 42 : 43 : public: 44 : ExpressionImpl() : _ref(0) {} 45 : virtual ~ExpressionImpl() {} 46 : 47 : /// Increment the reference count for this object 48 10 : void ref() throw () { ++_ref; } 49 : 50 : /// Decrement the reference count for this object, returning true when it 51 : /// reaches 0 52 22 : bool unref() throw () { return --_ref == 0; } 53 : 54 : /** 55 : * Provide a string representation of this expression 56 : */ 57 : virtual std::string format() const = 0; 58 : 59 : /** 60 : * Evaluates the expression on a recursive context 61 : * 62 : * \see TagexprContext 63 : */ 64 : virtual bool eval(const TagexprContext& context) const = 0; 65 : 66 : /** 67 : * Evaluates the expression on a set of tags 68 : * 69 : * \return 70 : * true if the expression matches the tags, false otherwise 71 : */ 72 : virtual bool eval(const std::set<std::string>& tags) const = 0; 73 : 74 : /** 75 : * Return a clone of this tag expression 76 : */ 77 : //virtual Tagexpr* clone() const = 0; 78 : }; 79 : 80 : class Expression 81 : { 82 : protected: 83 : ExpressionImpl* m_impl; 84 : 85 : Expression(ExpressionImpl* impl) : m_impl(impl) { m_impl->ref(); } 86 : 87 : const ExpressionImpl* impl() const { return m_impl; } 88 : ExpressionImpl* impl() { return m_impl; } 89 : 90 : public: 91 : Expression(); 92 : Expression(const std::string& expr); 93 : 94 : Expression(const Expression& e) 95 : { 96 : if (e.m_impl) 97 : e.m_impl->ref(); 98 : m_impl = e.m_impl; 99 : } 100 12 : ~Expression() { if (m_impl->unref()) delete m_impl; } 101 : 102 10 : Expression& operator=(const Expression& e) 103 : { 104 10 : if (e.m_impl) 105 10 : e.m_impl->ref(); // Do it early to correctly handle the case of x = x; 106 10 : if (m_impl && m_impl->unref()) 107 10 : delete m_impl; 108 10 : m_impl = e.m_impl; 109 10 : return *this; 110 : } 111 : 112 : Expression operator and (const Expression& e); 113 : Expression operator or (const Expression& e); 114 : Expression operator not (); 115 : 116 : template<typename Tags> 117 : bool operator()(const Tags& tags) const 118 : { 119 : std::set<std::string> stags; 120 : for (typename Tags::const_iterator i = tags.begin(); 121 : i != tags.end(); ++i) 122 : stags.insert(*i); 123 : return m_impl->eval(stags); 124 : } 125 : bool operator()(const std::set<std::string>& tags) const { return m_impl->eval(tags); } 126 : 127 : bool operator()(const TagexprContext& context) const { return m_impl->eval(context); } 128 : 129 : std::string format() const { return m_impl->format(); } 130 : 131 : static Expression matchTag(const std::string& pattern); 132 : }; 133 : 134 : /** 135 : * Context for evaluating expressions of derived tags. 136 : * 137 : * A derived tag is a tag which is automatically inferred when a tag expression 138 : * is matched on a tagset. 139 : * 140 : * TagexprContext allows the inference engine to distinguish between a normal 141 : * tag or a derived tag. 142 : * 143 : * This class is mainly used to support DerivedTags and has probably little 144 : * applications elsewhere. 145 : */ 146 : class TagexprContext 147 : { 148 : protected: 149 : const std::set<std::string>& tags; 150 : const std::map<std::string, Expression>& derivedTags; 151 : // Tags "visited" during tag evaluation: used to break circular loops 152 : mutable std::set<std::string> seen; 153 : 154 : public: 155 : /** 156 : * Create a context for recursive tagset evaluation 157 : * 158 : * Evaluation happens using a derivation table, which can list a tag as an 159 : * alias for another tag expression. Whenever a tag is matched for 160 : * equality with a derived tag, the match is performed with the derived tag 161 : * expression instead. 162 : * 163 : * \param tags 164 : * The tags to evaluate 165 : * \param derivedTags 166 : * The table of derived tags to use in the evaluation 167 : */ 168 : TagexprContext(const std::set<std::string>& tags, const std::map<std::string, Expression>& derivedTags) 169 : : tags(tags), derivedTags(derivedTags) {} 170 : 171 : /** 172 : * Evaluates the input tags on the contents to see if they contain the 173 : * given tag, or if they match its associated tag expression if tag is a 174 : * derived tag 175 : */ 176 : bool eval(const std::string& tag) const; 177 : }; 178 : 179 : }; 180 : 181 : // vim:set ts=4 sw=4: 182 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_PATCHES_H 2 : #define TAGCOLL_PATCHES_H 3 : 4 : /** \file 5 : * Classes handling tag patches 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2003,2004,2005,2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <wibble/operators.h> 27 : #include <wibble/mixin.h> 28 : #include <map> 29 : #include <string> 30 : 31 : namespace tagcoll 32 : { 33 : 34 : /** 35 : * Patch for the tagset of a specific item 36 : */ 37 : template <typename ITEM, typename TAG> 38 : struct Patch 39 : { 40 : ITEM item; 41 : std::set<TAG> added; 42 : std::set<TAG> removed; 43 : 44 55 : Patch(const Patch<ITEM, TAG>& p) : item(p.item), added(p.added), removed(p.removed) {} 45 5 : Patch(const ITEM& item) : item(item) {} 46 2 : Patch(const ITEM& item, const std::set<TAG>& added, const std::set<TAG>& removed); 47 : template<typename CONTA, typename CONTB> 48 2 : Patch(const ITEM& item, const CONTA& added, const CONTB& removed); 49 66 : ~Patch() {} 50 : 51 5 : void add(const TAG& tag) 52 : { 53 : using namespace wibble::operators; 54 5 : added |= tag; removed -= tag; 55 5 : } 56 2 : void add(const std::set<TAG>& tags) 57 : { 58 : using namespace wibble::operators; 59 2 : added |= tags; removed -= tags; 60 2 : } 61 2 : void remove(const TAG& tag) 62 : { 63 : using namespace wibble::operators; 64 2 : removed |= tag; added -= tag; 65 2 : } 66 2 : void remove(const std::set<TAG>& tags) 67 : { 68 : using namespace wibble::operators; 69 2 : removed |= tags; added -= tags; 70 2 : } 71 : 72 : Patch<ITEM, TAG> getReverse() const 73 : { 74 : return Patch<ITEM, TAG>(item, removed, added); 75 : } 76 : 77 2 : void mergeWith(const Patch<ITEM, TAG>& patch) 78 : { 79 2 : add(patch.added); 80 2 : remove(patch.removed); 81 2 : } 82 : 83 1 : std::set<TAG> apply(const std::set<TAG>& ts) const 84 : { 85 : using namespace wibble::operators; 86 1 : return (ts | added) - removed; 87 : } 88 : 89 : template<typename TAGS> 90 : std::set<TAG> apply(const TAGS& tags) const 91 : { 92 : using namespace wibble::operators; 93 : std::set<TAG> ts; 94 : for (typename TAGS::const_iterator i = tags.begin(); 95 : i != tags.end(); ++i) 96 : ts.insert(*i); 97 : return (ts | added) - removed; 98 : } 99 : 100 4 : void removeRedundant(const std::set<TAG> ts) 101 : { 102 : using namespace wibble::operators; 103 : // Don't add what already exists 104 4 : added -= ts; 105 : // Don't remove what does not exist 106 4 : removed -= (removed - ts); 107 4 : } 108 : 109 : bool operator==(const Patch<ITEM, TAG>& p) const 110 : { 111 : return p.item == item && p.added == added && p.removed == removed; 112 : } 113 : bool operator!=(const Patch<ITEM, TAG>& p) const 114 : { 115 : return p.item != item || p.added != added || p.removed != removed; 116 : } 117 : }; 118 : 119 : /** 120 : * List of patches that can be applied to a TaggedCollection 121 : */ 122 : template <class ITEM, class TAG> 123 : class PatchList : public std::map<ITEM, Patch<ITEM, TAG> > 124 36 : { 125 : public: 126 32 : PatchList() {} 127 3 : PatchList(const PatchList& pl) : std::map<ITEM, Patch<ITEM, TAG> >(pl) {} 128 : 129 : typedef typename std::map<ITEM, Patch<ITEM, TAG> >::const_iterator const_iterator; 130 : typedef typename std::map<ITEM, Patch<ITEM, TAG> >::iterator iterator; 131 : 132 : /** 133 : * Add to this patchlist the patches needed to transform `im1' in `im2' 134 : */ 135 : template<typename COLL1, typename COLL2> 136 : void addPatch(const COLL1& im1, const COLL2& im2); 137 : 138 : /** 139 : * Add `patch' to this PatchList 140 : */ 141 15 : void addPatch(const Patch<ITEM, TAG>& patch); 142 : 143 : /** 144 : * Add `patches' to this PatchList 145 : */ 146 : void addPatch(const PatchList<ITEM, TAG>& patches); 147 : 148 : /** 149 : * Add 'patch' to this PatchList, as tag: +/- package rather than package 150 : * +/- tag 151 : */ 152 2 : void addPatchInverted(const Patch<TAG, ITEM>& patch); 153 : 154 : /** 155 : * Add 'patches' to this PatchList, as tag: +/- package rather than package 156 : * +/- tag 157 : */ 158 2 : void addPatchInverted(const PatchList<TAG, ITEM>& patches); 159 : 160 : /** 161 : * If the PatchList contains the give item, invoke 162 : * Patch::removeRedundant(tags) on its patch 163 : */ 164 4 : void removeRedundant(const ITEM& item, const std::set<TAG>& tags); 165 : 166 : /** 167 : * Patch a tagged item 168 : * 169 : * @return 170 : * The new (patched) set of tags 171 : */ 172 14 : std::set<TAG> patch(const ITEM& item, const std::set<TAG>& tagset) const; 173 : 174 : // Output the patch list to a TagcollConsumer 175 : template<typename OUT> 176 3 : void output(OUT out) const; 177 : 178 : PatchList<ITEM, TAG> getReverse() const; 179 : }; 180 : 181 : template<typename ITEM, typename TAG> 182 : class Inserter : public wibble::mixin::OutputIterator< Inserter<ITEM, TAG> > 183 : { 184 : PatchList<ITEM, TAG>& patches; 185 : public: 186 3 : Inserter(PatchList<ITEM, TAG>& patches) : patches(patches) {} 187 : 188 3 : Inserter<ITEM, TAG>& operator=(const Patch<ITEM, TAG>& patch) 189 : { 190 3 : patches.addPatch(patch); 191 3 : return *this; 192 : } 193 : }; 194 : 195 : template<typename ITEM, typename TAG> 196 3 : Inserter<ITEM, TAG> inserter(PatchList<ITEM, TAG>& patches) 197 : { 198 3 : return Inserter<ITEM, TAG>(patches); 199 : } 200 : 201 : } 202 : 203 : // vim:set ts=4 sw=4: 204 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
TextFormat.h |
|
14.3 % | 1 / 7 lines | |
TextFormat.tcc |
|
54.4 % | 43 / 79 lines | |
expression.h |
|
100.0 % | 10 / 10 lines | |
patch.h |
|
100.0 % | 42 / 42 lines | |
patch.tcc |
|
88.6 % | 31 / 35 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_UTILS_SET_H 2 : #define TAGCOLL_UTILS_SET_H 3 : 4 : /** \file 5 : * Extra useful set operations 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2003,2004,2005,2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <wibble/operators.h> 27 : #include <set> 28 : 29 : namespace tagcoll { 30 : namespace utils { 31 : 32 : template<typename T> 33 : int set_distance(const std::set<T>& set1, const std::set<T>& set2) 34 : { 35 : int res = 0; 36 : int intCount = 0; 37 : 38 : typename std::set<T>::const_iterator a = set1.begin(); 39 : typename std::set<T>::const_iterator b = set2.begin(); 40 : 41 : while (a != set1.end() || b != set2.end()) 42 : if ((b == set2.end()) || (a != set1.end() && *a < *b)) 43 : { 44 : res++; 45 : a++; 46 : } 47 : else if ((a == set1.end()) || (b != set2.end() && *b < *a)) 48 : { 49 : res++; 50 : b++; 51 : } 52 : else 53 : { 54 : a++; 55 : b++; 56 : intCount++; 57 : } 58 : 59 : return intCount ? res : -1; 60 : } 61 : 62 : template<typename T> 63 1 : bool set_contains(const std::set<T>& set1, const std::set<T>& set2) 64 : { 65 1 : typename std::set<T>::const_iterator b = set2.begin(); 66 : 67 574 : for (typename std::set<T>::const_iterator a = set1.begin(); a != set1.end(); ++a) 68 574 : if (b == set2.end()) 69 1 : return true; 70 573 : else if (*a == *b) 71 31 : b++; 72 542 : else if (*b < *a) 73 0 : return false; 74 : 75 0 : return b == set2.end(); 76 : } 77 : 78 : template<typename T> 79 4 : bool set_contains(const std::set<T>& set1, const T& item) 80 : { 81 4 : return set1.find(item) != set1.end(); 82 : } 83 : 84 : } 85 : } 86 : 87 : // vim:set ts=4 sw=4: 88 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
set.h |
|
83.3 % | 10 / 12 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_STREAM_SINK_H 2 : #define TAGCOLL_STREAM_SINK_H 3 : 4 : /** \file 5 : * Consumer interface for a stream of tagged items 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2003,2004,2005,2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <wibble/mixin.h> 27 : #include <utility> 28 : 29 : namespace tagcoll { 30 : namespace stream { 31 : 32 : /** 33 : * Consumer that discards its input 34 : */ 35 : class Sink : public wibble::mixin::OutputIterator<Sink> 36 : { 37 : public: 38 : template<typename Data> 39 : const Sink& operator=(const Data&) const { return *this; } 40 : }; 41 : 42 : inline Sink sink() 43 : { 44 : return Sink(); 45 : } 46 : 47 : 48 : /** 49 : * Consumer that discards its input 50 : */ 51 : template<typename COUNTER> 52 : class CountingSink : public wibble::mixin::OutputIterator< CountingSink<COUNTER> > 53 : { 54 : COUNTER& countItems; 55 : COUNTER& countTags; 56 : 57 : public: 58 2 : CountingSink(COUNTER& countItems, COUNTER& countTags) : 59 2 : countItems(countItems), countTags(countTags) {} 60 : 61 : // TODO: see if there's a way of implementing the count using size() when 62 : // the method actually exists 63 : template<typename ITEMS, typename TAGS> 64 42266 : CountingSink& operator=(const std::pair<ITEMS, TAGS>& data) 65 : { 66 42266 : countItems += data.first.size(); 67 42266 : countTags += data.second.size(); 68 42266 : return *this; 69 : } 70 : }; 71 : 72 : template<typename COUNTER> 73 2 : inline CountingSink<COUNTER> countingSink(COUNTER& countItems, COUNTER& countTags) 74 : { 75 2 : return CountingSink<COUNTER>(countItems, countTags); 76 : } 77 : 78 : 79 : } 80 : } 81 : 82 : // vim:set ts=4 sw=4: 83 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
sink.h |
|
100.0 % | 8 / 8 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_TEXTFORMAT_H 2 : #define TAGCOLL_TEXTFORMAT_H 3 : 4 : /** \file 5 : * Serialize and deserialize a tagged collection to a text file 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2003--2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <wibble/mixin.h> 27 : #include <wibble/empty.h> 28 : #include <wibble/singleton.h> 29 : #include <tagcoll/input/base.h> 30 : 31 : #include <stdio.h> 32 : 33 : //#define TRACE_PARSE 34 : 35 : namespace tagcoll 36 : { 37 : template<class ITEM, class TAG> 38 : class PatchList; 39 : template<class ITEM, class TAG> 40 : class Patch; 41 : 42 : namespace textformat 43 : { 44 : 45 : /** 46 : * TagcollConsumer that serializes its input to an output stream 47 : * 48 : * The format of the output is: 49 : * lines of "comma+space"-separated items, followed by "colon+space", 50 : * followed by the corresponding "comma+space"-separated tags. 51 : * Examples: 52 : * ITEM: 53 : * ITEM: TAG 54 : * ITEM: TAG1, TAG2, TAG3 55 : * ITEM1, ITEM2, ITEM3: 56 : * ITEM1, ITEM2, ITEM3: TAG1, TAG2, TAG3 57 : */ 58 : class StdioWriter : public wibble::mixin::OutputIterator<StdioWriter> 59 : { 60 : protected: 61 : FILE* out; 62 : 63 : public: 64 1 : StdioWriter(FILE* out) : out(out) {} 65 : 66 : template<typename Items, typename Tags> 67 : StdioWriter& operator=(const std::pair<Items, Tags>& data); 68 : }; 69 : 70 : class OstreamWriter : public wibble::mixin::OutputIterator<OstreamWriter> 71 : { 72 : protected: 73 : std::ostream& out; 74 : 75 : public: 76 : OstreamWriter(std::ostream& out) : out(out) {} 77 : 78 : template<typename Items, typename Tags> 79 : OstreamWriter& operator=(const std::pair<Items, Tags>& data); 80 : }; 81 : 82 : /** 83 : * Parse an element from input 84 : * 85 : * @retval item 86 : * The item found on input 87 : * @return 88 : * the trailing separating char, that can be: 89 : * \li input::Input::Eof 90 : * \li '\n' 91 : * \li ':' 92 : * \li ',' 93 : */ 94 : int parseElement(input::Input& in, std::string& item); 95 : 96 : 97 : /** 98 : * Serialize a patch 99 : */ 100 : template<typename ITEM, typename TAG, typename ITEMSER, typename TAGSER> 101 : void outputPatch( 102 : ITEMSER& itemconv, 103 : TAGSER& tagconv, 104 : const PatchList<ITEM, TAG>& patch, 105 : FILE* out); 106 : 107 : void outputPatch( 108 : const PatchList<std::string, std::string>& patch, 109 : FILE* out); 110 : 111 : 112 : /* 113 : * Parse a tagged collection, sending the results to out. 114 : * 115 : * @param out 116 : * An output iterator accepting a std::pair<string, string> 117 : */ 118 : template<typename OUT> 119 : void parse(input::Input& in, OUT out); 120 : 121 : /** 122 : * Assemble a patch from a stream of "item: +added, -removed" items and tags 123 : */ 124 : template<typename OUT> 125 : class PatchAssembler : public wibble::mixin::OutputIterator< PatchAssembler<OUT> > 126 : { 127 : OUT out; 128 : public: 129 0 : PatchAssembler(const OUT& out) : out(out) {} 130 : 131 : template<typename ITEMS, typename TAGS> 132 : PatchAssembler& operator=(const std::pair<ITEMS, TAGS>& data); 133 : }; 134 : 135 : template<typename OUT> 136 0 : PatchAssembler<OUT> patchAssembler(const OUT& out) 137 : { 138 0 : return PatchAssembler<OUT>(out); 139 : } 140 : 141 : template<typename OUT> 142 0 : void parsePatch(input::Input& in, OUT out) 143 : { 144 0 : parse(in, patchAssembler(out)); 145 0 : } 146 : 147 : /** 148 : * Parse a tagcoll patch 149 : */ 150 : template<typename ITEM, typename TAG, typename ITEMSER, typename TAGSER> 151 : PatchList<ITEM, TAG> parsePatch( 152 : ITEMSER& itemconv, 153 : TAGSER& tagconv, 154 : input::Input& in); 155 : 156 : PatchList<std::string, std::string> parsePatch(input::Input& in); 157 : 158 : 159 : 160 : template<typename ITEM, typename TAG, typename ITEMSER, typename TAGSER> 161 : class PatchBuilder : public wibble::mixin::OutputIterator< PatchBuilder<ITEM, TAG, ITEMSER, TAGSER> > 162 : { 163 : protected: 164 : PatchList<ITEM, TAG>& patch; 165 : const ITEMSER& itemconv; 166 : const TAGSER& tagconv; 167 : 168 : public: 169 : PatchBuilder( 170 : PatchList<ITEM, TAG>& patch, 171 : const ITEMSER& itemconv, 172 : const TAGSER& tagconv) 173 : : patch(patch), itemconv(itemconv), tagconv(tagconv) {} 174 : 175 : template<typename ITEMS, typename TAGS> 176 : PatchBuilder<ITEM, TAG, ITEMSER, TAGSER>& operator=(const std::pair<ITEMS, TAGS>& data); 177 : 178 : const PatchList<ITEM, TAG>& getPatch() const throw () { return patch; } 179 : }; 180 : 181 : template<typename ITEM, typename TAG, typename ITEMSER, typename TAGSER> 182 : PatchBuilder<ITEM, TAG, ITEMSER, TAGSER> patchBuilder( 183 : PatchList<ITEM, TAG>& patch, 184 : const ITEMSER& itemconv, 185 : const TAGSER& tagconv) 186 : { 187 : return PatchBuilder<ITEM, TAG, ITEMSER, TAGSER>(patch, itemconv, tagconv); 188 : } 189 : 190 : } 191 : } 192 : 193 : // vim:set ts=4 sw=4: 194 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Classes handling tag patches 3 : * 4 : * Copyright (C) 2003--2006 Enrico Zini <enrico@debian.org> 5 : * 6 : * This library is free software; you can redistribute it and/or 7 : * modify it under the terms of the GNU Lesser General Public 8 : * License as published by the Free Software Foundation; either 9 : * version 2.1 of the License, or (at your option) any later version. 10 : * 11 : * This library is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 : * Lesser General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU Lesser General Public 17 : * License along with this library; if not, write to the Free Software 18 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : */ 20 : 21 : #ifndef TAGCOLL_PATCHES_TCC 22 : #define TAGCOLL_PATCHES_TCC 23 : 24 : #include <tagcoll/patch.h> 25 : #include <wibble/singleton.h> 26 : #include <wibble/empty.h> 27 : 28 : using namespace std; 29 : using namespace wibble::operators; 30 : 31 : namespace tagcoll { 32 : 33 : template <typename ITEM, typename TAG> 34 : Patch<ITEM, TAG>::Patch(const ITEM& item, const std::set<TAG>& added, const std::set<TAG>& removed) 35 2 : : item(item), added(added-removed), removed(removed-added) 36 0 : { 37 2 : } 38 : 39 : template <typename ITEM, typename TAG> template<typename CONTA, typename CONTB> 40 2 : Patch<ITEM, TAG>::Patch(const ITEM& item, const CONTA& added, const CONTB& removed) 41 4 : : item(item) 42 : { 43 4 : std::copy(added.begin(), added.end(), inserter(this->added, this->added.begin())); 44 4 : std::copy(removed.begin(), removed.end(), inserter(this->removed, this->removed.begin())); 45 4 : } 46 : 47 : template <class ITEM, class TAG> 48 : void PatchList<ITEM, TAG>::addPatch(const Patch<ITEM, TAG>& patch) 49 : { 50 : // Filter out empty patches 51 15 : if (patch.added.empty() && patch.removed.empty()) 52 0 : return; 53 : 54 15 : iterator i = this->find(patch.item); 55 15 : if (i == this->end()) 56 13 : insert(make_pair<ITEM, Patch<ITEM, TAG> >(patch.item, patch)); 57 : else 58 2 : i->second.mergeWith(patch); 59 : } 60 : 61 : template <class ITEM, class TAG> 62 : void PatchList<ITEM, TAG>::addPatch(const PatchList<ITEM, TAG>& patches) 63 : { 64 : for (typename PatchList<ITEM, TAG>::const_iterator i = patches.begin(); 65 : i != patches.end(); i++) 66 : addPatch(i->second); 67 : } 68 : 69 : template <class ITEM, class TAG> 70 : void PatchList<ITEM, TAG>::addPatchInverted(const Patch<TAG, ITEM>& patch) 71 : { 72 : // Filter out empty patches 73 2 : if (patch.added.empty() && patch.removed.empty()) 74 0 : return; 75 : 76 8 : for (typename std::set<ITEM>::const_iterator i = patch.added.begin(); 77 : i != patch.added.end(); ++i) 78 2 : addPatch(Patch<ITEM, TAG>(*i, wibble::singleton(patch.item), wibble::Empty<TAG>())); 79 4 : for (typename std::set<ITEM>::const_iterator i = patch.removed.begin(); 80 : i != patch.removed.end(); ++i) 81 0 : addPatch(Patch<ITEM, TAG>(*i, wibble::Empty<TAG>(), wibble::singleton(patch.item))); 82 : } 83 : 84 : template <class ITEM, class TAG> 85 : void PatchList<ITEM, TAG>::addPatchInverted(const PatchList<TAG, ITEM>& patches) 86 : { 87 4 : for (typename PatchList<TAG, ITEM>::const_iterator i = patches.begin(); 88 : i != patches.end(); i++) 89 2 : addPatchInverted(i->second); 90 2 : } 91 : 92 : 93 : template <class ITEM, class TAG> template<typename COLL1, typename COLL2> 94 : void PatchList<ITEM, TAG>::addPatch(const COLL1& im1, const COLL2& im2) 95 : { 96 : // FIXME: if I could implement the guarantee that the collection iterators 97 : // iterate in sorted item order, then I wouldn't need to extract all the 98 : // items of im2 99 : std::set<ITEM> im2items = im2.getTaggedItems(); 100 : for (typename COLL1::const_iterator i1 = im1.begin(); 101 : i1 != im1.end(); ++i1) 102 : { 103 : im2items.erase(i1->first); 104 : std::set<TAG> ts2 = im2.getTagsOfItem(i1->first); 105 : std::set<TAG> added = ts2 - i1->second; 106 : std::set<TAG> removed = i1->second - ts2; 107 : if (!added.empty() || !removed.empty()) 108 : addPatch(Patch<ITEM, TAG>(i1->first, added, removed)); 109 : } 110 : for (typename std::set<ITEM>::const_iterator i = im2items.begin(); 111 : i != im2items.end(); ++i) 112 : { 113 : addPatch(Patch<ITEM, TAG>(*i, im2.getTagsOfItem(*i), wibble::Empty<TAG>())); 114 : } 115 : } 116 : 117 : template <class ITEM, class TAG> 118 : void PatchList<ITEM, TAG>::removeRedundant(const ITEM& item, const std::set<TAG>& tags) 119 : { 120 4 : iterator i = this->find(item); 121 4 : if (i == this->end()) return; 122 4 : i->second.removeRedundant(tags); 123 : } 124 : 125 : template <class ITEM, class TAG> 126 : std::set<TAG> PatchList<ITEM, TAG>::patch(const ITEM& item, const std::set<TAG>& tagset) const 127 : { 128 : // Find the patch record for this item 129 14 : const_iterator p = this->find(item); 130 14 : if (p == this->end()) 131 : // If there are no patches, return the tagset unchanged 132 13 : return tagset; 133 : 134 : // There are patches: apply them: 135 1 : return p->second.apply(tagset); 136 : } 137 : 138 : template <class ITEM, class TAG> 139 : PatchList<ITEM, TAG> PatchList<ITEM, TAG>::getReverse() const 140 : { 141 : PatchList<ITEM, TAG> res; 142 : for (typename PatchList<ITEM, TAG>::const_iterator i = this->begin(); 143 : i != this->end(); i++) 144 : res.addPatch(i->second.getReverse()); 145 : return res; 146 : } 147 : 148 : template<typename ITEM, typename TAG> template<typename OUT> 149 : void PatchList<ITEM, TAG>::output(OUT out) const 150 : { 151 6 : for (typename PatchList<ITEM, TAG>::const_iterator i = this->begin(); 152 : i != this->end(); ++i) 153 : { 154 3 : *out = i->second; 155 3 : ++out; 156 : } 157 3 : } 158 : 159 : 160 6 : } 161 : 162 : #endif 163 : 164 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Merge tags of items appearing multiple times in a stream of tagged items 3 : * 4 : * Copyright (C) 2003--2006 Enrico Zini <enrico@debian.org> 5 : * 6 : * This library is free software; you can redistribute it and/or 7 : * modify it under the terms of the GNU Lesser General Public 8 : * License as published by the Free Software Foundation; either 9 : * version 2.1 of the License, or (at your option) any later version. 10 : * 11 : * This library is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 : * Lesser General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU Lesser General Public 17 : * License along with this library; if not, write to the Free Software 18 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : */ 20 : 21 : #ifndef TAGCOLL_COLL_SIMPLE_TCC 22 : #define TAGCOLL_COLL_SIMPLE_TCC 23 : 24 : #include <tagcoll/utils/set.h> 25 : #include <tagcoll/coll/simple.h> 26 : #include <tagcoll/patch.h> 27 : 28 : #include <wibble/operators.h> 29 : 30 : using namespace std; 31 : using namespace wibble::operators; 32 : 33 : namespace tagcoll { 34 : namespace coll { 35 : 36 : 37 : template<class ITEM, class TAG> template<typename ITEMS, typename TAGS> 38 42293 : void Simple<ITEM, TAG>::insert(const ITEMS& items, const TAGS& tags) 39 : { 40 : using namespace wibble::operators; 41 : 42 42295 : if (tags.empty()) 43 0 : return; 44 84590 : for (typename ITEMS::const_iterator i = items.begin(); 45 : i != items.end(); ++i) 46 : { 47 42295 : typename std::map< ITEM, std::set<TAG> >::iterator iter = coll.find(*i); 48 42295 : if (iter == coll.end()) 49 21149 : coll.insert(std::make_pair(*i, std::set<TAG>() | tags)); 50 : else 51 21146 : iter->second |= tags; 52 : } 53 : } 54 : 55 : template<class ITEM, class TAG> 56 : std::set<TAG> Simple<ITEM, TAG>::getTagsOfItem(const ITEM& item) const 57 : { 58 2 : typename map< ITEM, std::set<TAG> >::const_iterator i = coll.find(item); 59 : 60 2 : if (i == coll.end()) 61 0 : return std::set<TAG>(); 62 : else 63 2 : return i->second; 64 : } 65 : 66 : template<class ITEM, class TAG> 67 : std::set<ITEM> Simple<ITEM, TAG>::getItemsHavingTag(const TAG& tag) const 68 : { 69 : std::set<ITEM> res; 70 : for (typename map< ITEM, std::set<TAG> >::const_iterator i = coll.begin(); 71 : i != coll.end(); i++) 72 : if (i->second.find(tag) != i->second.end()) 73 : res |= i->first; 74 : return res; 75 : } 76 : 77 : template<class ITEM, class TAG> template<typename TAGS> 78 : std::set<ITEM> Simple<ITEM, TAG>::getItemsHavingTags(const TAGS& tags) const 79 : { 80 : std::set<ITEM> res; 81 : for (typename map< ITEM, std::set<TAG> >::const_iterator i = coll.begin(); 82 : i != coll.end(); i++) 83 : if (utils::set_contains(i->second, tags)) 84 : res |= i->first; 85 : return res; 86 : } 87 : 88 : #if 0 89 : template<class T, class Tag> 90 : void Simple<T, Tag>::outputReversed(Consumer<Tag, T>& consumer) const 91 : { 92 : for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin(); 93 : i != coll.end(); i++) 94 : { 95 : std::set<T> items; 96 : items |= i->first; 97 : consumer.consume(i->second, items); 98 : } 99 : } 100 : #endif 101 : 102 : template<class ITEM, class TAG> template<typename TAGS, typename OUT> 103 : void Simple<ITEM, TAG>::outputHavingTags(const TAGS& ts, OUT out) const 104 : { 105 : for (typename map< ITEM, std::set<TAG> >::const_iterator i = coll.begin(); 106 : i != coll.end(); ++i) 107 : if (utils::set_contains(i->second, ts)) 108 : { 109 : *out = *i; 110 : ++out; 111 : } 112 : } 113 : 114 : 115 : 116 : template<class T, class Tag> 117 : void Simple<T, Tag>::applyChange(const PatchList<T, Tag>& change) 118 : { 119 : for (typename PatchList<T, Tag>::const_iterator i = change.begin(); i != change.end(); i++) 120 : { 121 : typename map< T, std::set<Tag> >::iterator it = coll.find(i->first); 122 : if (it == coll.end()) 123 : { 124 : // If the item doesn't exist, create it 125 : coll.insert(make_pair(i->first, i->second.added)); 126 : } else { 127 : it->second = i->second.apply(it->second); 128 : } 129 : } 130 : } 131 : 132 : template<typename ITEM, typename TAG> 133 : std::set<ITEM> Simple<ITEM, TAG>::getTaggedItems() const 134 : { 135 : std::set<ITEM> res; 136 : for (typename std::map< ITEM, std::set<TAG> >::const_iterator i = coll.begin(); 137 : i != coll.end(); i++) 138 : res.insert(i->first); 139 : return res; 140 : } 141 : 142 : template<class T, class Tag> 143 : std::set<Tag> Simple<T, Tag>::getAllTags() const 144 : { 145 3 : std::set<Tag> tags; 146 : 147 6 : for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin(); 148 : i != coll.end(); i++) 149 3 : tags |= i->second; 150 : 151 0 : return tags; 152 : } 153 : 154 : template<class T, class Tag> 155 : std::set<Tag> Simple<T, Tag>::getCompanionTags(const std::set<Tag>& ts) const 156 : { 157 : std::set<Tag> tags; 158 : 159 : for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin(); 160 : i != coll.end(); i++) 161 : if (utils::set_contains(i->second, (ts))) 162 : tags |= i->second - ts; 163 : 164 : return tags; 165 : } 166 : 167 : template<class T, class Tag> 168 : std::set<T> Simple<T, Tag>::getRelatedItems(const std::set<Tag>& tags, int maxdistance) const 169 : { 170 : std::set<T> res; 171 : 172 : for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin(); 173 : i != coll.end(); i++) 174 : { 175 : int dist = utils::set_distance(tags, i->second); 176 : if (dist >= 0 && dist <= maxdistance) 177 : res |= i->first; 178 : } 179 : 180 : return res; 181 : } 182 : 183 : template<class T, class Tag> 184 : unsigned int Simple<T, Tag>::itemCount() const 185 : { 186 5 : return coll.size(); 187 : } 188 : 189 : } 190 : } 191 : 192 : #include <tagcoll/coll/base.tcc> 193 : 194 : #endif 195 : 196 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_COLL_BASE_H 2 : #define TAGCOLL_COLL_BASE_H 3 : 4 : /** \file 5 : * Base mixins for tagged collections 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2003,2004,2005,2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <wibble/mixin.h> 27 : #include <vector> 28 : 29 : namespace std { 30 : template<typename A, typename B> class pair; 31 : } 32 : 33 : namespace tagcoll { 34 : namespace coll { 35 : 36 : template<typename T> 37 : class coll_traits; 38 : 39 : /** 40 : * Interface for all collections of tagged items. 41 : * 42 : * \note The point of a collection is to track the tags attached to items, and 43 : * not to store the items themselves. This means that collections are not 44 : * required to keep track of items with no tags. 45 : */ 46 : template<typename Self> 47 : class ReadonlyCollection 48 37 : { 49 84611 : const Self& self() const { return *static_cast<const Self*>(this); } 50 : 51 : class CardinalityOrder 52 : { 53 : const Self& coll; 54 : public: 55 : CardinalityOrder(const Self& coll) : coll(coll) {} 56 : bool operator()(const typename coll_traits<Self>::tag_type& t1, const typename coll_traits<Self>::tag_type& t2) 57 : { 58 : // Returns true if t1 precedes t2, and false otherwise 59 : return coll.getCardinality(t1) < coll.getCardinality(t2); 60 : } 61 : }; 62 : 63 : class DiscriminanceOrder 64 : { 65 : const Self& coll; 66 : public: 67 : DiscriminanceOrder(const Self& coll) : coll(coll) {} 68 : bool operator()(const typename coll_traits<Self>::tag_type& t1, const typename coll_traits<Self>::tag_type& t2) 69 : { 70 : // Returns true if t1 precedes t2, and false otherwise 71 : return coll.getDiscriminance(t1) < coll.getDiscriminance(t2); 72 : } 73 : }; 74 : 75 : template<typename COLL> 76 : class RelevanceOrder 77 : { 78 : const COLL& first; 79 : const Self& second; 80 : public: 81 : RelevanceOrder(const COLL& first, const Self& second) 82 : : first(first), second(second) {} 83 : bool operator()(const typename coll_traits<Self>::tag_type& t1, const typename coll_traits<Self>::tag_type& t2); 84 : }; 85 : 86 : /** 87 : * Get the items which are tagged with at least the tag `tag' 88 : * 89 : * \return 90 : * The items found, or an empty set if no items have that tag 91 : */ 92 : //virtual std::set<ITEM> getItemsHavingTag(const TAG& tag) const = 0; 93 : 94 : /** 95 : * Get the tags attached to an item. 96 : * 97 : * \param item 98 : * The item to query 99 : * \return 100 : * The set of tags, or an empty set if the item has no tags or it does 101 : * not exist. 102 : */ 103 : //virtual std::set<TAG> getTagsOfItem(const ITEM& item) const = 0; 104 : 105 : public: 106 : /** 107 : * Check if the collection contains a tag 108 : * 109 : * \param tag 110 : * The tag to look for 111 : * \return 112 : * true if the collection contains tag, false otherwise 113 : */ 114 : bool hasTag(const typename coll_traits<Self>::tag_type& tag) const; 115 : 116 : /** 117 : * Get the tags of item `item'. Return an empty set if `item' does not exist 118 : */ 119 : //std::set<Self::tag_type> getTags(const typename Self::item_type& item) const = 0; 120 : 121 : /** 122 : * Get all the tags attached to the items in a set. 123 : * 124 : * \param items 125 : * The items to query 126 : * \return 127 : * The set of tags, or an empty set if the items have no tags or do not 128 : * exist. 129 : */ 130 : template<typename ITEMS> 131 : typename coll_traits<Self>::tagset_type getTagsOfItems(const ITEMS& items) const; 132 : 133 : /** 134 : * Get the items with tag `tag'. Return an empty set if `tag' does not exist 135 : */ 136 : //std::set<typename Self::item_type> getItems(const TAG& tag) const { return getItemsHavingTag(tag); } 137 : 138 : /** 139 : * Get the items which are tagged with at least the tags `tags' 140 : * 141 : * \return 142 : * The items found, or an empty set if no items have that tag 143 : */ 144 : template<typename TAGS> 145 2 : typename coll_traits<Self>::itemset_type getItemsHavingTags(const TAGS& tags) const; 146 : 147 : /** 148 : * Get the set of all the items that have tags according to this collection 149 : */ 150 : //virtual std::set<Self::item_type> getTaggedItems() const = 0; 151 : 152 : /** 153 : * Get the set of all the tags in this collection 154 : */ 155 : //virtual std::set<Self::tag_type> getAllTags() const = 0; 156 : 157 : /** 158 : * Get all the tags in the collectin, as a vector 159 : */ 160 : std::vector<typename coll_traits<Self>::tag_type> getAllTagsAsVector() const; 161 : 162 : /** 163 : * Get the cardinality of tag `tag' (that is, the number of items who have it) 164 : */ 165 : unsigned int getCardinality(const typename coll_traits<Self>::tag_type& tag) const; 166 : 167 : /** 168 : * Return the discriminance value for this tag, that is, the minimum number 169 : * of packages that would be eliminated by selecting only those tagged with 170 : * this tag or only those not tagged with this tag. 171 : */ 172 : unsigned int getDiscriminance(const typename coll_traits<Self>::tag_type& tag) const 173 : { 174 : return self().getCardinality(tag) < self().tagCount() - self().getCardinality(tag) ? 175 : self().getCardinality(tag) : 176 : self().tagCount() - self().getCardinality(tag); 177 : } 178 : 179 : /** 180 : * Get the set of all tags in this collection that appear in tagsets 181 : * containing `tags' 182 : * 183 : * Example: 184 : * \code 185 : * void refineSelection(const std::set<Tag>& selection) 186 : * { 187 : * std::set<Tag> extraTags = collection.getCompanionTags(selection); 188 : * tagMenu.setAvailableOptions(extraTags); 189 : * } 190 : * \endcode 191 : */ 192 : template<typename TAGS> 193 : typename coll_traits<Self>::tagset_type getCompanionTags(const TAGS& tags) const; 194 : 195 : /** 196 : * Get the related items at the given maximum distance 197 : * 198 : * Examples: 199 : * \code 200 : * // Get the items related to a given one, at the given distance 201 : * std::set<Item> getRelated(const Item& item, int distance) 202 : * { 203 : * std::set<Item> res = collection.getRelatedItems(collection.getTags(item), distance); 204 : * return res - item; 205 : * } 206 : * 207 : * // Get the items related to the given ones, at the given distance 208 : * std::set<Item> getRelated(const std::set<Item>& items, int distance) 209 : * { 210 : * std::set<Item> res = collection.getRelatedItems(collection.getTags(items), distance); 211 : * return res - items; 212 : * } 213 : * 214 : * // Get the related items, increasing the distance until it finds at 215 : * // least 'minimum' items 216 : * std::set<Item> getRelated(const Item& item, int minimum) 217 : * { 218 : * std::set<Tag> tags = collection.getTags(item); 219 : * std::set<Item> res; 220 : * for (int i = 0; i < tags.size() && res.size() < minimum; i++) 221 : * res += collection.getRelatedItems(tags, i); 222 : * return res - item; 223 : * } 224 : * \endcode 225 : */ 226 : template<typename TAGS> 227 : typename coll_traits<Self>::itemset_type getRelatedItems(const TAGS& tags, int maxdistance = 1) const; 228 : 229 : /** 230 : * Output all the contents of the collection to an output iterator 231 : */ 232 : template<typename OUT> 233 5 : void output(OUT out) const; 234 : 235 : /** 236 : * Send to a consumer all the items which are tagged with at least the 237 : * given tags 238 : */ 239 : template<typename TAGS, typename OUT> 240 : void outputHavingTags(const TAGS& tags, OUT out) const; 241 : 242 : /** 243 : * Get a vector containing all tags in this collection, sorted by 244 : * increasing cardinality 245 : */ 246 : std::vector<typename coll_traits<Self>::tag_type> tagsInCardinalityOrder() const; 247 : 248 : /** 249 : * Get a vector containing all tags in this collection, sorted by 250 : * increasing discriminance value (@see getDiscriminance) 251 : */ 252 : std::vector<typename coll_traits<Self>::tag_type> tagsInDiscriminanceOrder() const; 253 : 254 : /** 255 : * Get a vector containing all tags in this collection, sorted by 256 : * increasing relevance to the filtering applied between coll and this 257 : * collection 258 : */ 259 : template<typename COLL> 260 : std::vector<typename coll_traits<Self>::tag_type> tagsInRelevanceOrder(const COLL& coll) const; 261 : }; 262 : 263 : 264 : /** 265 : * Interface for all collections of tagged items. 266 : * 267 : * \note The point of a collection is to track the tags attached to items, and 268 : * not to store the items themselves. This means that collections are not 269 : * required to keep track of items with no tags. 270 : */ 271 : template<typename Self> 272 : class Collection : public ReadonlyCollection<Self> 273 27 : { 274 : //protected: 275 : /* 276 : * Implementation note: to avoid problems with classes implementing only 277 : * some of the virtual methods, they are given different names. The common 278 : * 'comsume' methods are just inlined calls to the right virtual functions, 279 : * and are a way of keeping the unoverridden methods from being hidden. 280 : */ 281 : 282 : //void consumeItemUntagged(const ITEM&) {} 283 : //void consumeItemsUntagged(const std::set<ITEM>&) {} 284 : 285 : public: 286 : //virtual ~Collection() {} 287 : 288 : /** 289 : * Apply a patch to the collection 290 : * 291 : * Example: 292 : * \code 293 : * void perform(const PatchList<ITEM, TAG>& change) 294 : * { 295 : * collection.applyChange(change); 296 : * undo.push_back(change.getReverse()); 297 : * } 298 : * \endcode 299 : */ 300 : // void applyChange( 301 : // const PatchList< 302 : // typename coll_traits<Self>::item_type, 303 : // typename coll_traits<Self>::tag_type>& change); 304 : }; 305 : 306 : 307 : template<typename COLL> 308 : class Inserter : public wibble::mixin::OutputIterator< Inserter<COLL> > 309 : { 310 : COLL& coll; 311 : 312 : public: 313 10 : Inserter(COLL& coll) : coll(coll) {} 314 : 315 : template<typename Items, typename Tags> 316 63426 : Inserter<COLL>& operator=(const std::pair<Items, Tags>& data) 317 : { 318 63426 : coll.insert(data.first, data.second); 319 63426 : return *this; 320 : } 321 : }; 322 : 323 : template<typename COLL> 324 10 : Inserter<COLL> inserter(COLL& target) 325 : { 326 10 : return Inserter<COLL>(target); 327 : } 328 : 329 : } 330 : } 331 : 332 : // vim:set ts=4 sw=4: 333 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* 2 : * Wrap a Collection, preserving modifications as patches 3 : * 4 : * Copyright (C) 2005,2006 Enrico Zini <enrico@debian.org> 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 2 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, write to the Free Software 18 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : */ 20 : 21 : #ifndef TAGCOLL_COLL_PATCHED_TCC 22 : #define TAGCOLL_COLL_PATCHED_TCC 23 : 24 : #include <tagcoll/coll/patched.h> 25 : #include <tagcoll/utils/set.h> 26 : 27 : #include <wibble/operators.h> 28 : 29 : using namespace std; 30 : using namespace wibble::operators; 31 : 32 : namespace tagcoll { 33 : namespace coll { 34 : 35 : template<typename ROCOLL> template<typename ITEMS, typename TAGS> 36 : void Patched<ROCOLL>::insert(const ITEMS& items, const TAGS& tags) 37 : { 38 : Patches changes; 39 : for (typename ITEMS::const_iterator i = items.begin(); 40 : i != items.end(); ++i) 41 : changes.addPatch(Patch(*i, tags, TagSet())); 42 : addChanges(changes); 43 : } 44 : 45 : 46 : template<typename ROCOLL> 47 : void Patched<ROCOLL>::clear() 48 : { 49 : // Remove all patches 50 : m_changes.clear(); 51 : m_rchanges.clear(); 52 : 53 : // Add all tagsets of the underlying collection as removed tags in the patch 54 : for (typename ROCOLL::const_iterator i = coll.begin(); 55 : i != coll.end(); ++i) 56 : { 57 : m_changes.addPatch(Patch(i->first, std::set<Tag>(), i->second)); 58 : 59 : for (typename TagSet::const_iterator j = i->second.begin(); 60 : j != i->second.end(); ++j) 61 : m_rchanges.addPatch(Patch(*j, wibble::Empty<Tag>(), wibble::singleton(i->first))); 62 : } 63 : } 64 : 65 : template<typename ROCOLL> 66 : void Patched<ROCOLL>::setChanges(const Patches& changes) 67 : { 68 0 : this->m_changes.clear(); 69 0 : this->m_rchanges.clear(); 70 : 71 0 : addChanges(changes); 72 0 : } 73 : 74 : template<typename ROCOLL> 75 : void Patched<ROCOLL>::addChanges(const Patches& changes) 76 : { 77 : // Simplify the patch against the contents of `coll' before adding it. 78 4 : for (typename Patches::const_iterator i = changes.begin(); i != changes.end(); ++i) 79 : // Consider only valid items 80 2 : if (i->first != Item()) 81 : { 82 : // Merge with existing patches 83 2 : this->m_changes.addPatch(i->second); 84 : // Simplify the result 85 2 : this->m_changes.removeRedundant(i->first, coll.getTagsOfItem(i->first)); 86 : } 87 : 88 2 : RPatches rchanges; 89 2 : rchanges.addPatchInverted(changes); 90 4 : for (typename RPatches::const_iterator i = rchanges.begin(); i != rchanges.end(); ++i) 91 : // Consider only valid tags 92 2 : if (i->first != Tag()) 93 : { 94 : // Merge with existing patches 95 2 : this->m_rchanges.addPatch(i->second); 96 : // Simplify the result 97 4 : this->m_rchanges.removeRedundant(i->first, coll.getItemsHavingTag(i->first)); 98 : } 99 2 : } 100 : 101 : template<typename ROCOLL> 102 : bool Patched<ROCOLL>::hasTag(const Tag& tag) const 103 : { 104 : typename RPatches::const_iterator i = m_rchanges.find(tag); 105 : if (i == m_rchanges.end()) 106 : return coll.hasTag(tag); 107 : if (! i->second.added.empty()) 108 : return true; 109 : return !this->getItemsHavingTag(tag).empty(); 110 : } 111 : 112 : template<typename ROCOLL> 113 : typename coll_traits<ROCOLL>::itemset_type Patched<ROCOLL>::getTaggedItems() const 114 : { 115 : ItemSet res(coll.getTaggedItems()); 116 : for (typename Patches::const_iterator i = m_changes.begin(); 117 : i != m_changes.end(); ++i) 118 : if (!i->second.added.empty()) 119 : // Add packages for which tags are added 120 : res |= i->first; 121 : else if (getTagsOfItem(i->first).empty()) 122 : // Remove the packages to which the patch removes all tags 123 : res -= i->first; 124 : return res; 125 : } 126 : 127 : template<typename ROCOLL> 128 : typename coll_traits<ROCOLL>::tagset_type Patched<ROCOLL>::getAllTags() const 129 : { 130 1 : TagSet res(coll.getAllTags()); 131 1 : for (typename RPatches::const_iterator i = m_rchanges.begin(); 132 : i != m_rchanges.end(); ++i) 133 0 : if (!i->second.added.empty()) 134 : // Add tags for which packages are added 135 0 : res |= i->first; 136 0 : else if (coll.getCardinality(i->first) - i->second.removed.size() <= 0) 137 : // Remove the tags to which the patch removes all items 138 0 : res -= i->first; 139 0 : return res; 140 : } 141 : 142 : #if 0 143 : template<typename ITEM, typename TAG, typename OUT> 144 : class UnpatchedOnly : public wibble::mixin::OutputIterator< UnpatchedOnly<ITEM, TAG, OUT> > 145 : { 146 : protected: 147 : OUT out; 148 : const PatchList<ITEM, TAG>& changes; 149 : 150 : public: 151 : UnpatchedOnly(const PatchList<ITEM, TAG>& changes, const OUT& out) : out(out), changes(changes) {} 152 : 153 : UnpatchedOnly<ITEM, TAG, OUT>& operator++() { return *this; } 154 : 155 : template<typename Items, typename Tags> 156 : UnpatchedOnly<ITEM, TAG, OUT>& operator=(const std::pair<Items, Tags>& data) 157 : { 158 : for (typename Items::const_iterator i = data.first.begin(); 159 : i != data.first.end(); ++i) 160 : if (changes.find(*i) == changes.end()) 161 : { 162 : *out = data; 163 : ++out; 164 : } 165 : return *this; 166 : } 167 : }; 168 : 169 : template<typename ITEM, typename TAG, typename OUT> 170 : UnpatchedOnly<ITEM, TAG, OUT> unpatchedOnly(const PatchList<ITEM, TAG>& changes, const OUT& out) 171 : { 172 : return UnpatchedOnly<ITEM, TAG, OUT>(changes, out); 173 : } 174 : 175 : template<class ITEM, class TAG> 176 : void Patched<ITEM, TAG>::output(Consumer<ITEM, TAG>& cons) const 177 : { 178 : // First, only pass the unpatched items 179 : coll.outputToIterator(unpatchedOnly(changes, consumer(cons))); 180 : 181 : // Then output the items in the patch 182 : for (typename PatchList<ITEM, TAG>::const_iterator i = changes.begin(); 183 : i != changes.end(); i++) 184 : cons.consume(i->first, 185 : changes.patch(i->first, coll.getTags(i->first))); 186 : } 187 : #endif 188 : 189 : template<typename ROCOLL> 190 : unsigned int Patched<ROCOLL>::getCardinality(const Tag& tag) const 191 : { 192 : typename RPatches::const_iterator i = m_rchanges.find(tag); 193 : if (i == m_rchanges.end()) 194 : return coll.getCardinality(tag); 195 : else 196 : return coll.getCardinality(tag) + i->second.added.size() - i->second.removed.size(); 197 : } 198 : 199 : } 200 : } 201 : 202 : #include <tagcoll/coll/base.tcc> 203 : #include <tagcoll/patch.tcc> 204 : 205 : #endif 206 : 207 : // vim:set ts=4 sw=4: |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_COLL_PATCHED_H 2 : #define TAGCOLL_COLL_PATCHED_H 3 : 4 : /** \file 5 : * Wrap a Collection, preserving modifications as patches 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2005,2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This program is free software; you can redistribute it and/or modify 12 : * it under the terms of the GNU General Public License as published by 13 : * the Free Software Foundation; either version 2 of the License, or 14 : * (at your option) any later version. 15 : * 16 : * This program is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 : * GNU General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU General Public License 22 : * along with this program; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <tagcoll/coll/base.h> 27 : #include <tagcoll/patch.h> 28 : 29 : namespace tagcoll { 30 : template<typename T1, typename T2> class PatchList; 31 : 32 : namespace coll { 33 : template<typename ROCOLL> 34 : class Patched; 35 : 36 : template<typename ROCOLL> 37 : struct coll_traits< Patched<ROCOLL> > 38 : { 39 : typedef typename coll_traits<ROCOLL>::item_type item_type; 40 : typedef typename coll_traits<ROCOLL>::tag_type tag_type; 41 : typedef typename coll_traits<ROCOLL>::tagset_type tagset_type; 42 : typedef typename coll_traits<ROCOLL>::itemset_type itemset_type; 43 : }; 44 : 45 : /** 46 : * Wraps a collection by intercepting all changes to it and preserving them as 47 : * a PatchList. 48 : */ 49 : template<typename ROCOLL> 50 : class Patched : public coll::Collection< Patched<ROCOLL> > 51 10 : { 52 : public: 53 : typedef tagcoll::Patch< 54 : typename coll_traits<ROCOLL>::item_type, 55 : typename coll_traits<ROCOLL>::tag_type> Patch; 56 : typedef tagcoll::PatchList< 57 : typename coll_traits<ROCOLL>::item_type, 58 : typename coll_traits<ROCOLL>::tag_type> Patches; 59 : typedef tagcoll::Patch< 60 : typename coll_traits<ROCOLL>::tag_type, 61 : typename coll_traits<ROCOLL>::item_type> RPatch; 62 : typedef tagcoll::PatchList< 63 : typename coll_traits<ROCOLL>::tag_type, 64 : typename coll_traits<ROCOLL>::item_type> RPatches; 65 : 66 : protected: 67 : typedef typename coll_traits<ROCOLL>::item_type Item; 68 : typedef typename coll_traits<ROCOLL>::tag_type Tag; 69 : typedef typename coll_traits<ROCOLL>::itemset_type ItemSet; 70 : typedef typename coll_traits<ROCOLL>::tagset_type TagSet; 71 : 72 : const ROCOLL& coll; 73 : Patches m_changes; 74 : RPatches m_rchanges; 75 : 76 : #if 0 77 : virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags); 78 : 79 : virtual std::set<ITEM> getItemsHavingTag(const TAG& tag) const; 80 : virtual std::set<TAG> getTagsOfItem(const ITEM& item) const; 81 : #endif 82 : 83 : public: 84 : typedef std::pair<Item, TagSet> value_type; 85 : 86 : class const_iterator 87 : { 88 : const Patched<ROCOLL>& coll; 89 : typename ROCOLL::const_iterator ci; 90 : typename Patches::const_iterator pi; 91 : mutable typename Patched<ROCOLL>::value_type* cached_val; 92 : 93 : protected: 94 : const_iterator(const Patched<ROCOLL>& coll, 95 : const typename ROCOLL::const_iterator& ci, 96 84592 : const typename Patches::const_iterator& pi) 97 84592 : : coll(coll), ci(ci), pi(pi), cached_val(0) {} 98 : 99 : public: 100 148035 : ~const_iterator() 101 : { 102 148035 : if (cached_val) 103 0 : delete cached_val; 104 148035 : } 105 84580 : const typename Patched<ROCOLL>::value_type operator*() const 106 : { 107 84580 : if (cached_val) 108 0 : return *cached_val; 109 : 110 84580 : if (ci == coll.coll.end() && pi == coll.m_changes.end()) 111 0 : return *(typename Patched<ROCOLL>::value_type*)0; 112 84580 : else if (pi == coll.m_changes.end()) 113 84580 : return *ci; 114 0 : else if (ci == coll.coll.end()) 115 0 : return make_pair(pi->first, pi->second.added); 116 0 : else if (ci->first < pi->first) 117 0 : return *ci; 118 0 : else if (ci->first > pi->first) 119 0 : return make_pair(pi->first, pi->second.added); 120 : else 121 0 : return make_pair(ci->first, pi->second.apply(ci->second)); 122 : } 123 211450 : const typename Patched<ROCOLL>::value_type* operator->() const 124 : { 125 211450 : if (cached_val) 126 126870 : return cached_val; 127 84580 : return cached_val = new typename Patched<ROCOLL>::value_type(*(*this)); 128 : } 129 84580 : const_iterator& operator++() 130 : { 131 84580 : if (ci == coll.coll.end() && pi == coll.m_changes.end()) 132 : ; 133 84580 : else if (pi == coll.m_changes.end()) 134 84580 : ++ci; 135 0 : else if (ci == coll.coll.end()) 136 0 : ++pi; 137 0 : else if (ci->first < pi->first) 138 0 : ++ci; 139 0 : else if (ci->first > pi->first) 140 0 : ++pi; 141 : else 142 : { 143 0 : ++ci; 144 0 : ++pi; 145 : } 146 84580 : if (cached_val) 147 : { 148 84580 : delete cached_val; 149 84580 : cached_val = 0; 150 : } 151 84580 : return *this; 152 : } 153 1 : bool operator==(const const_iterator& iter) const 154 : { 155 1 : return ci == iter.ci && pi == iter.pi; 156 : } 157 84585 : bool operator!=(const const_iterator& iter) const 158 : { 159 84585 : return ci != iter.ci || pi != iter.pi; 160 : } 161 : 162 : friend class Patched<ROCOLL>; 163 : }; 164 6 : const_iterator begin() const { return const_iterator(*this, coll.begin(), m_changes.begin()); } 165 84586 : const_iterator end() const { return const_iterator(*this, coll.end(), m_changes.end()); } 166 : 167 10 : Patched(const ROCOLL& coll) : coll(coll) {} 168 : 169 : template<typename ITEMS, typename TAGS> 170 : void insert(const ITEMS& items, const TAGS& tags); 171 : 172 : template<typename ITEMS> 173 : void insert(const ITEMS& items, const wibble::Empty<Tag>& tags) 174 : { 175 : // Nothing to do in this case 176 : } 177 : 178 : /** 179 : * Removes all items from the collection 180 : */ 181 : void clear(); 182 : 183 : /** 184 : * Get the changes that have been applied to this collection 185 : */ 186 4 : const Patches& changes() const { return m_changes; } 187 : 188 : /** 189 : * Throw away all changes previously applied to this collection 190 : */ 191 : void resetChanges() { m_changes.clear(); m_rchanges.clear(); } 192 : 193 : /** 194 : * Set the changes list to a specific patch list 195 : */ 196 0 : void setChanges(const Patches& changes); 197 : 198 : /** 199 : * Add a specific patch list to the changes list 200 : */ 201 2 : void addChanges(const Patches& changes); 202 : 203 : bool hasTag(const Tag& tag) const; 204 : 205 5 : TagSet getTagsOfItem(const Item& item) const 206 : { 207 5 : return m_changes.patch(item, coll.getTagsOfItem(item)); 208 : } 209 9 : ItemSet getItemsHavingTag(const typename coll_traits<ROCOLL>::tag_type& tag) const 210 : { 211 9 : return m_rchanges.patch(tag, coll.getItemsHavingTag(tag)); 212 : } 213 : 214 : ItemSet getTaggedItems() const; 215 1 : TagSet getAllTags() const; 216 : 217 : unsigned int tagCount() const { return getAllTags().size(); } 218 : 219 : unsigned int getCardinality(const Tag& tag) const; 220 : 221 2 : void applyChange(const Patches& change) { this->addChanges(change); } 222 : 223 : #if 0 224 : template<typename OUT> 225 : void output(OUT out) const 226 : { 227 : for (const_iterator i = begin(); i != end(); ++i) 228 : { 229 : *out = *i; 230 : ++out; 231 : } 232 : } 233 : #endif 234 : }; 235 : 236 : } 237 : } 238 : 239 : // vim:set ts=4 sw=4: 240 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_COLL_INT_DISK_INDEX_H 2 : #define TAGCOLL_COLL_INT_DISK_INDEX_H 3 : 4 : /** \file 5 : * Fast on-disk index for tag data 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This program is free software; you can redistribute it and/or modify 12 : * it under the terms of the GNU General Public License as published by 13 : * the Free Software Foundation; either version 2 of the License, or 14 : * (at your option) any later version. 15 : * 16 : * This program is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 : * GNU General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU General Public License 22 : * along with this program; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <tagcoll/coll/base.h> 27 : #include <tagcoll/diskindex/int.h> 28 : 29 : namespace tagcoll { 30 : template<typename ITEM, typename TAG> 31 : class PatchList; 32 : 33 : namespace coll { 34 : 35 : class IntDiskIndex; 36 : 37 : template<> 38 : struct coll_traits< IntDiskIndex > 39 : { 40 : typedef int item_type; 41 : typedef int tag_type; 42 : typedef std::set<int> tagset_type; 43 : typedef std::set<int> itemset_type; 44 : }; 45 : 46 : /** 47 : * Full TaggedCollection implementation on top of a persistent on-disk TDB 48 : * database. 49 : * 50 : * It allows to efficiently query a collection without having to store it all 51 : * into memory. 52 : * 53 : * If used for heavy modifications, the performance is slower compared to other 54 : * in-memory collections. If database writes are mainly used for populating 55 : * the index, then TDBIndexer should be used to create the index and 56 : * TDBDiskIndex to access it afterwards. 57 : */ 58 : class IntDiskIndex : public coll::ReadonlyCollection< IntDiskIndex > 59 : 60 : { 61 : protected: 62 : diskindex::Int pkgidx; 63 : diskindex::Int tagidx; 64 : 65 : public: 66 : class const_iterator 67 : { 68 : const IntDiskIndex& index; 69 : int idx; 70 : mutable std::pair< int, std::set<int> >* cached; 71 : 72 : public: 73 : // Builds an iterator 74 8 : const_iterator(const IntDiskIndex& index, int idx) 75 8 : : index(index), idx(idx), cached(0) {} 76 : // Builds the end iterator 77 274893 : const_iterator(const IntDiskIndex& index) 78 274893 : : index(index), idx(index.pkgidx.size()), cached(0) {} 79 528661 : ~const_iterator() { if (cached) delete cached; } 80 : 81 105725 : std::pair< int, std::set<int> > operator*() const 82 : { 83 105725 : return std::make_pair(idx, index.getTagsOfItem(idx)); 84 : } 85 42290 : std::pair< int, std::set<int> >* operator->() const 86 : { 87 42290 : if (!cached) 88 21145 : cached = new std::pair< int, std::set<int> >(operator*()); 89 42290 : return cached; 90 : } 91 : 92 105725 : const_iterator operator++() 93 : { 94 105725 : ++idx; 95 105725 : if (cached) { delete cached; cached = 0; } 96 105725 : return *this; 97 : } 98 169161 : bool operator==(const const_iterator& iter) const 99 : { 100 169161 : return idx == iter.idx; 101 : } 102 105732 : bool operator!=(const const_iterator& iter) const 103 : { 104 105732 : return idx != iter.idx; 105 : } 106 : }; 107 8 : const_iterator begin() const { return const_iterator(*this, 0); } 108 274893 : const_iterator end() const { return const_iterator(*this); } 109 : 110 : /** 111 : * Create a new IntDiskIndex 112 : * 113 : * @param filename 114 : * The file name of the package index 115 : * @param tagidx 116 : * The file name of the tag index 117 : * @param fromitem, fromtag, toitem, totag 118 : * The Converter-s used to convert int and int to and from strings. 119 : * If 0 is passed, this TDBDiskIndex will only be able to work with 120 : * string items and string tags. 121 : * @param write 122 : * Set to false if the index should be opened in read-only mode. If 123 : * opened in read-only mode, all non-const methods of this class will 124 : * throw an exception if invoked. 125 : * It defaults to true. 126 : */ 127 10 : IntDiskIndex() {} 128 : IntDiskIndex( 129 : const diskindex::MasterMMap& master, 130 : int pkgindex, int tagindex) 131 : : pkgidx(master, pkgindex), tagidx(master, tagindex) {} 132 : 133 9 : void init(const diskindex::MasterMMap& master, int pkgindex, int tagindex) 134 : { 135 9 : pkgidx.init(master, pkgindex); 136 9 : tagidx.init(master, tagindex); 137 9 : } 138 : 139 : std::set<int> getItemsHavingTag(const int& tag) const; 140 : std::set<int> getItemsHavingTags(const std::set<int>& tags) const; 141 : std::set<int> getTagsOfItem(const int& item) const; 142 : std::set<int> getTagsOfItems(const std::set<int>& items) const; 143 : 144 : bool hasTag(const int& tag) const 145 : { 146 : return tagidx.size(tag) > 0; 147 : } 148 : 149 : std::set<int> getTaggedItems() const; 150 : 151 : std::set<int> getAllTags() const; 152 : std::vector<int> getAllTagsAsVector() const; 153 : 154 : unsigned int itemCount() const { return pkgidx.size(); } 155 : unsigned int tagCount() const { return tagidx.size(); } 156 : 157 0 : unsigned int getCardinality(const int& tag) const 158 : { 159 0 : return tagidx.size(tag); 160 : } 161 : 162 : std::set<int> getCompanionTags(const std::set<int>& tags) const; 163 : 164 : //void output(Consumer<int, int>& consumer) const; 165 : }; 166 : 167 : class IntDiskIndexer 168 2 : { 169 : protected: 170 : diskindex::IntIndexer pkgidx; 171 : diskindex::IntIndexer tagidx; 172 : 173 : public: 174 1 : const diskindex::MMapIndexer& pkgIndexer() const { return pkgidx; } 175 1 : const diskindex::MMapIndexer& tagIndexer() const { return tagidx; } 176 : 177 : template<typename ITEMS, typename TAGS> 178 21133 : void insert(const ITEMS& items, const TAGS& tags) 179 : { 180 21133 : if (tags.empty()) 181 0 : return; 182 42266 : for (typename ITEMS::const_iterator it = items.begin(); 183 : it != items.end(); ++it) 184 126731 : for (typename TAGS::const_iterator ta = tags.begin(); 185 : ta != tags.end(); ++ta) 186 : { 187 105598 : pkgidx.map(*it, *ta); 188 105598 : tagidx.map(*ta, *it); 189 : } 190 : } 191 : }; 192 : 193 : 194 : } 195 : } 196 : 197 : // vim:set ts=4 sw=4: 198 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
base.h |
|
100.0 % | 11 / 11 lines | |
base.tcc |
|
88.9 % | 16 / 18 lines | |
intdiskindex.h |
|
92.1 % | 35 / 38 lines | |
patched.h |
|
66.7 % | 38 / 57 lines | |
patched.tcc |
|
59.1 % | 13 / 22 lines | |
simple.h |
|
100.0 % | 14 / 14 lines | |
simple.tcc |
|
82.4 % | 14 / 17 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_COLL_BASE_TCC 2 : #define TAGCOLL_COLL_BASE_TCC 3 : 4 : /** \file 5 : * Base mixins for tagged collections 6 : */ 7 : 8 : /* 9 : * Copyright (C) 2003,2004,2005,2006 Enrico Zini <enrico@debian.org> 10 : * 11 : * This library is free software; you can redistribute it and/or 12 : * modify it under the terms of the GNU Lesser General Public 13 : * License as published by the Free Software Foundation; either 14 : * version 2.1 of the License, or (at your option) any later version. 15 : * 16 : * This library is distributed in the hope that it will be useful, 17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 : * Lesser General Public License for more details. 20 : * 21 : * You should have received a copy of the GNU Lesser General Public 22 : * License along with this library; if not, write to the Free Software 23 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 : */ 25 : 26 : #include <tagcoll/coll/base.h> 27 : #include <tagcoll/utils/set.h> 28 : #include <algorithm> 29 : 30 : namespace tagcoll { 31 : namespace coll { 32 : 33 : template<typename T> 34 : class coll_traits; 35 : 36 : template<typename Self> template<typename COLL> 37 : bool ReadonlyCollection<Self>::RelevanceOrder<COLL>::operator()( 38 : const typename coll_traits<Self>::tag_type& t1, 39 : const typename coll_traits<Self>::tag_type& t2) 40 : { 41 : // New cardinality divided by the square root of the old cardinality. 42 : // The square root is used to downplay the very common tags a bit 43 : int csub1 = second.getCardinality(t1); 44 : float cfull1 = first.getCardinality(t1); 45 : int csub2 = second.getCardinality(t2); 46 : float cfull2 = first.getCardinality(t2); 47 : float rel1 = (float)(csub1 * csub1) / cfull1; 48 : float rel2 = (float)(csub2 * csub2) / cfull2; 49 : 50 : return rel1 < rel2; 51 : // return 10000 * second.getCardinality(t1) / first.getCardinality(t1) 52 : // < 10000 * second.getCardinality(t2) / first.getCardinality(t2); 53 : } 54 : 55 : 56 : template<typename Self> 57 : bool ReadonlyCollection<Self>::hasTag(const typename coll_traits<Self>::tag_type& tag) const 58 : { 59 : return !self().getItemsHavingTag(tag).empty(); 60 : } 61 : 62 : template<typename Self> template<typename ITEMS> 63 1 : typename coll_traits<Self>::tagset_type ReadonlyCollection<Self>::getTagsOfItems(const ITEMS& items) const 64 : { 65 : using namespace wibble::operators; 66 1 : typename coll_traits<Self>::tagset_type res; 67 2 : for (typename ITEMS::const_iterator i = items.begin(); 68 : i != items.end(); i++) 69 1 : res |= self().getTagsOfItem(*i); 70 0 : return res; 71 : } 72 : 73 : template<typename Self> template<typename TAGS> 74 : typename coll_traits<Self>::itemset_type ReadonlyCollection<Self>::getItemsHavingTags(const TAGS& tags) const 75 : { 76 : using namespace wibble::operators; 77 2 : if (tags.empty()) 78 0 : return typename coll_traits<Self>::itemset_type(); 79 : 80 2 : typename TAGS::const_iterator i = tags.begin(); 81 2 : typename coll_traits<Self>::itemset_type res = self().getItemsHavingTag(*i); 82 : 83 9 : for (++i ; i != tags.end(); ++i) 84 7 : res &= self().getItemsHavingTag(*i); 85 : 86 2 : return res; 87 : } 88 : 89 : template<typename Self> 90 : std::vector<typename coll_traits<Self>::tag_type> ReadonlyCollection<Self>::getAllTagsAsVector() const 91 : { 92 : std::set<typename coll_traits<Self>::tag_type> asSet = self().getAllTags(); 93 : std::vector<typename coll_traits<Self>::tag_type> res; 94 : res.reserve(asSet.size()); 95 : std::copy(asSet.begin(), asSet.end(), back_inserter(res)); 96 : return res; 97 : } 98 : 99 : template<typename Self> 100 : unsigned int ReadonlyCollection<Self>::getCardinality(const typename coll_traits<Self>::tag_type& tag) const 101 : { 102 : return self().getItemsHavingTag(tag).size(); 103 : } 104 : 105 : template<typename Self> template<typename TAGS> 106 : typename coll_traits<Self>::tagset_type ReadonlyCollection<Self>::getCompanionTags(const TAGS& tags) const 107 : { 108 : using namespace wibble::operators; 109 : return self().getTagsOfItems(self().getItemsHavingTags(tags)) - tags; 110 : } 111 : 112 : template<typename Self> template<typename TAGS> 113 : typename coll_traits<Self>::itemset_type ReadonlyCollection<Self>::getRelatedItems(const TAGS& tags, int maxdistance) const 114 : { 115 : using namespace wibble::operators; 116 : 117 : typename coll_traits<Self>::itemset_type packages; 118 : typename coll_traits<Self>::itemset_type res; 119 : 120 : // First get a list of packages that have a non-empty intersection with `tags' 121 : for (typename TAGS::const_iterator i = tags.begin(); i != tags.end(); i++) 122 : packages |= self().getItemsHavingTag(*i); 123 : 124 : // Then keep only those within the given distance 125 : for (typename coll_traits<Self>::itemset_type::const_iterator i = packages.begin(); i != packages.end(); i++) 126 : { 127 : int dist = utils::set_distance(tags, self().getTagsOfItem(*i)); 128 : if (dist >= 0 && dist <= maxdistance) 129 : res |= *i; 130 : } 131 : 132 : return res; 133 : } 134 : 135 : template<typename Self> template<typename OUT> 136 4 : void ReadonlyCollection<Self>::output(OUT out) const 137 : { 138 126890 : for (typename Self::const_iterator i = self().begin(); 139 : i != self().end(); ++i) 140 : { 141 84583 : *out = make_pair(wibble::singleton(i->first), i->second); 142 84587 : ++out; 143 : } 144 9 : } 145 : 146 : template<typename Self> template<typename TAGS, typename OUT> 147 : void ReadonlyCollection<Self>::outputHavingTags(const TAGS& tags, OUT out) const 148 : { 149 : typename coll_traits<Self>::itemset_type items = self().getItemsHavingTags(tags); 150 : for (typename coll_traits<Self>::itemset_type::const_iterator i = items.begin(); 151 : i != items.end(); ++i) 152 : { 153 : *out = std::make_pair(wibble::singleton(*i), self().getTagsOfItem(*i)); 154 : ++out; 155 : } 156 : } 157 : 158 : template<typename Self> 159 : std::vector<typename coll_traits<Self>::tag_type> ReadonlyCollection<Self>::tagsInCardinalityOrder() const 160 : { 161 : std::vector<typename coll_traits<Self>::tag_type> res = self().getAllTagsAsVector(); 162 : std::sort(res.begin(), res.end(), CardinalityOrder(self())); 163 : return res; 164 : } 165 : 166 : template<typename Self> 167 : std::vector<typename coll_traits<Self>::tag_type> ReadonlyCollection<Self>::tagsInDiscriminanceOrder() const 168 : { 169 : std::vector<typename coll_traits<Self>::tag_type> res = self().getAllTagsAsVector(); 170 : std::sort(res.begin(), res.end(), DiscriminanceOrder(self())); 171 : return res; 172 : } 173 : 174 : /** 175 : * Get a vector containing all tags in this collection, sorted by 176 : * increasing relevance to the filtering applied between coll and this 177 : * collection 178 : */ 179 : template<typename Self> template<typename COLL> 180 : std::vector<typename coll_traits<Self>::tag_type> ReadonlyCollection<Self>::tagsInRelevanceOrder(const COLL& coll) const 181 : { 182 : std::vector<typename coll_traits<Self>::tag_type> res = self().getAllTagsAsVector(); 183 : std::sort(res.begin(), res.end(), RelevanceOrder<COLL>(coll, self())); 184 : return res; 185 : } 186 : 187 : } 188 6 : } 189 : 190 : // vim:set ts=4 sw=4: 191 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #ifndef TAGCOLL_COLL_SIMPLE_H 2 : #define TAGCOLL_COLL_SIMPLE_H 3 : 4 : /** \file 5 : * Simple tagged collection. 6 : * 7 : * Also used for merging tags of items appearing multiple times in a stream of 8 : * tagged items 9 : */ 10 : 11 : /* 12 : * Copyright (C) 2003,2004,2005,2006 Enrico Zini <enrico@debian.org> 13 : * 14 : * This library is free software; you can redistribute it and/or 15 : * modify it under the terms of the GNU Lesser General Public 16 : * License as published by the Free Software Foundation; either 17 : * version 2.1 of the License, or (at your option) any later version. 18 : * 19 : * This library is distributed in the hope that it will be useful, 20 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 : * Lesser General Public License for more details. 23 : * 24 : * You should have received a copy of the GNU Lesser General Public 25 : * License along with this library; if not, write to the Free Software 26 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27 : */ 28 : 29 : #include <tagcoll/coll/base.h> 30 : #include <set> 31 : #include <map> 32 : 33 : namespace tagcoll { 34 : template<typename ITEM, typename TAG> 35 : class PatchList; 36 : 37 : namespace coll { 38 : 39 : template<typename ITEM, typename TAG> 40 : class Simple; 41 : 42 : template<typename ITEM, typename TAG> 43 : struct coll_traits< Simple<ITEM, TAG> > 44 : { 45 : typedef ITEM item_type; 46 : typedef TAG tag_type; 47 : typedef std::set<ITEM> tagset_type; 48 : typedef std::set<TAG> itemset_type; 49 : }; 50 : 51 : 52 : /** 53 : * Simple Collection. 54 : * 55 : * It can be used to merge input values: if an item is added multiple times, 56 : * its various tagsets are merged in a single one. 57 : * 58 : * It is also a full-featured collection, although not very optimized. 59 : */ 60 : template<typename ITEM, typename TAG> 61 : class Simple : public coll::Collection< Simple<ITEM, TAG> > 62 14 : { 63 : protected: 64 : std::map< ITEM, std::set<TAG> > coll; 65 : 66 : #if 0 67 : virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags); 68 : 69 : virtual std::set<ITEM> getItemsHavingTags(const std::set<TAG>& tags) const; 70 : #endif 71 : 72 : public: 73 : typedef typename std::map< ITEM, std::set<TAG> >::const_iterator const_iterator; 74 : typedef typename std::map< ITEM, std::set<TAG> >::iterator iterator; 75 : typedef typename std::map< ITEM, std::set<TAG> >::value_type value_type; 76 : 77 5 : const_iterator begin() const { return coll.begin(); } 78 42298 : const_iterator end() const { return coll.end(); } 79 1 : iterator begin() { return coll.begin(); } 80 21146 : iterator end() { return coll.end(); } 81 : 82 2 : bool empty() const { return coll.empty(); } 83 : 84 : template<typename ITEMS, typename TAGS> 85 2 : void insert(const ITEMS& items, const TAGS& tags); 86 : 87 : bool hasItem(const ITEM& item) const { return coll.find(item) != coll.end(); } 88 : 89 2 : std::set<TAG> getTagsOfItem(const ITEM& item) const; 90 : std::set<ITEM> getItemsHavingTag(const TAG& tag) const; 91 : template<typename TAGS> 92 : std::set<ITEM> getItemsHavingTags(const TAGS& tag) const; 93 : 94 : template<typename TAGS, typename OUT> 95 : void outputHavingTags(const TAGS& tags, OUT out) const; 96 : 97 : #if 0 98 : void output(Consumer<ITEM, TAG>& consumer) const; 99 : void outputHavingTags(const std::set<TAG>& ts, Consumer<ITEM, TAG>& consumer) const; 100 : 101 : /** 102 : * Send the merged data to a consumer, but reversed: the tag become items, 103 : * and they are tagged with the items that had them 104 : */ 105 : void outputReversed(Consumer<TAG, ITEM>& consumer) const; 106 : #endif 107 : 108 : void applyChange(const PatchList<ITEM, TAG>& change); 109 : 110 : std::set<ITEM> getTaggedItems() const; 111 : 112 3 : std::set<TAG> getAllTags() const; 113 : 114 : std::set<TAG> getCompanionTags(const std::set<TAG>& ts) const; 115 : 116 : std::set<ITEM> getRelatedItems(const std::set<TAG>& ts, int maxdistance = 1) const; 117 : 118 : /** 119 : * Count the number of items 120 : */ 121 5 : unsigned int itemCount() const; 122 : 123 3 : unsigned int tagCount() const { return getAllTags().size(); } 124 : 125 : /** 126 : * Empty the collection 127 : */ 128 1 : void clear() 129 : { 130 1 : coll.clear(); 131 1 : } 132 : }; 133 : 134 : } 135 : } 136 : 137 : // vim:set ts=4 sw=4: 138 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: cpp; mode: fold -*- 2 : // Description /*{{{*/ 3 : // $Id: algorithms.h,v 1.10 2001/05/22 04:17:41 jgg Exp $ 4 : /* ###################################################################### 5 : 6 : Algorithms - A set of misc algorithms 7 : 8 : This simulate class displays what the ordering code has done and 9 : analyses it with a fresh new dependency cache. In this way we can 10 : see all of the effects of an upgrade run. 11 : 12 : pkgDistUpgrade computes an upgrade that causes as many packages as 13 : possible to move to the newest verison. 14 : 15 : pkgApplyStatus sets the target state based on the content of the status 16 : field in the status file. It is important to get proper crash recovery. 17 : 18 : pkgFixBroken corrects a broken system so that it is in a sane state. 19 : 20 : pkgAllUpgrade attempts to upgade as many packages as possible but 21 : without installing new packages. 22 : 23 : The problem resolver class contains a number of complex algorithms 24 : to try to best-guess an upgrade state. It solves the problem of 25 : maximizing the number of install state packages while having no broken 26 : packages. 27 : 28 : ##################################################################### */ 29 : /*}}}*/ 30 : #ifndef PKGLIB_ALGORITHMS_H 31 : #define PKGLIB_ALGORITHMS_H 32 : 33 : 34 : #include <apt-pkg/packagemanager.h> 35 : #include <apt-pkg/depcache.h> 36 : #include <apt-pkg/acquire.h> 37 : 38 : #include <iostream> 39 : 40 : using std::ostream; 41 : 42 : class pkgSimulate : public pkgPackageManager 43 : { 44 : protected: 45 : 46 : class Policy : public pkgDepCache::Policy 47 : { 48 : pkgDepCache *Cache; 49 : public: 50 : 51 : virtual VerIterator GetCandidateVer(PkgIterator Pkg) 52 : { 53 : return (*Cache)[Pkg].CandidateVerIter(*Cache); 54 : } 55 : 56 : Policy(pkgDepCache *Cache) : Cache(Cache) {}; 57 : }; 58 : 59 : unsigned char *Flags; 60 : 61 : Policy iPolicy; 62 : pkgDepCache Sim; 63 : 64 : // The Actuall installation implementation 65 : virtual bool Install(PkgIterator Pkg,string File); 66 : virtual bool Configure(PkgIterator Pkg); 67 : virtual bool Remove(PkgIterator Pkg,bool Purge); 68 : 69 : private: 70 : void ShortBreaks(); 71 : void Describe(PkgIterator iPkg,ostream &out,bool Current,bool Candidate); 72 : 73 : public: 74 : 75 : pkgSimulate(pkgDepCache *Cache); 76 : }; 77 : 78 : class pkgProblemResolver 79 : { 80 : pkgDepCache &Cache; 81 : typedef pkgCache::PkgIterator PkgIterator; 82 : typedef pkgCache::VerIterator VerIterator; 83 : typedef pkgCache::DepIterator DepIterator; 84 : typedef pkgCache::PrvIterator PrvIterator; 85 : typedef pkgCache::Version Version; 86 : typedef pkgCache::Package Package; 87 : 88 : enum Flags {Protected = (1 << 0), PreInstalled = (1 << 1), 89 : Upgradable = (1 << 2), ReInstateTried = (1 << 3), 90 : ToRemove = (1 << 4)}; 91 : signed short *Scores; 92 : unsigned char *Flags; 93 : bool Debug; 94 : 95 : // Sort stuff 96 : static pkgProblemResolver *This; 97 : static int ScoreSort(const void *a,const void *b); 98 : 99 : struct PackageKill 100 : { 101 : PkgIterator Pkg; 102 : DepIterator Dep; 103 : }; 104 : 105 : void MakeScores(); 106 : bool DoUpgrade(pkgCache::PkgIterator Pkg); 107 : 108 : public: 109 : 110 4 : inline void Protect(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] |= Protected;}; 111 0 : inline void Remove(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] |= ToRemove;}; 112 4 : inline void Clear(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] &= ~(Protected | ToRemove);}; 113 : 114 : // Try to intelligently resolve problems by installing and removing packages 115 : bool Resolve(bool BrokenFix = false); 116 : 117 : // Try to resolve problems only by using keep 118 : bool ResolveByKeep(); 119 : 120 : // Install all protected packages 121 : void InstallProtect(); 122 : 123 : pkgProblemResolver(pkgDepCache *Cache); 124 : ~pkgProblemResolver(); 125 : }; 126 : 127 : bool pkgDistUpgrade(pkgDepCache &Cache); 128 : bool pkgApplyStatus(pkgDepCache &Cache); 129 : bool pkgFixBroken(pkgDepCache &Cache); 130 : bool pkgAllUpgrade(pkgDepCache &Cache); 131 : bool pkgMinimizeUpgrade(pkgDepCache &Cache); 132 : 133 : void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List); 134 : 135 : bool ListUpdate(pkgAcquireStatus &progress, pkgSourceList &List, int PulseInterval=0); 136 : 137 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: cpp; mode: fold -*- 2 : // Description /*{{{*/ 3 : // $Id: cacheiterators.h,v 1.18.2.1 2004/05/08 22:44:27 mdz Exp $ 4 : /* ###################################################################### 5 : 6 : Cache Iterators - Iterators for navigating the cache structure 7 : 8 : The iterators all provides ++,==,!=,->,* and end for their type. 9 : The end function can be used to tell if the list has been fully 10 : traversed. 11 : 12 : Unlike STL iterators these contain helper functions to access the data 13 : that is being iterated over. This is because the data structures can't 14 : be formed in a manner that is intuitive to use and also mmapable. 15 : 16 : For each variable in the target structure that would need a translation 17 : to be accessed correctly a translating function of the same name is 18 : present in the iterator. If applicable the translating function will 19 : return an iterator. 20 : 21 : The DepIterator can iterate over two lists, a list of 'version depends' 22 : or a list of 'package reverse depends'. The type is determined by the 23 : structure passed to the constructor, which should be the structure 24 : that has the depends pointer as a member. The provide iterator has the 25 : same system. 26 : 27 : This header is not user includable, please use apt-pkg/pkgcache.h 28 : 29 : ##################################################################### */ 30 : /*}}}*/ 31 : #ifndef PKGLIB_CACHEITERATORS_H 32 : #define PKGLIB_CACHEITERATORS_H 33 : 34 : 35 : // Package Iterator 36 : class pkgCache::PkgIterator 37 : { 38 : friend class pkgCache; 39 : Package *Pkg; 40 : pkgCache *Owner; 41 : long HashIndex; 42 : 43 : protected: 44 : 45 : // This constructor is the 'begin' constructor, never use it. 46 19 : inline PkgIterator(pkgCache &Owner) : Owner(&Owner), HashIndex(-1) 47 : { 48 19 : Pkg = Owner.PkgP; 49 19 : operator ++(0); 50 19 : }; 51 : 52 : public: 53 : 54 : enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure}; 55 : 56 : // Iteration 57 : void operator ++(int); 58 52878 : inline void operator ++() {operator ++(0);}; 59 89241 : inline bool end() const {return Owner == 0 || Pkg == Owner->PkgP?true:false;}; 60 : 61 : // Comparison 62 0 : inline bool operator ==(const PkgIterator &B) const {return Pkg == B.Pkg;}; 63 0 : inline bool operator !=(const PkgIterator &B) const {return Pkg != B.Pkg;}; 64 : 65 : // Accessors 66 67369 : inline Package *operator ->() {return Pkg;}; 67 3787 : inline Package const *operator ->() const {return Pkg;}; 68 : inline Package const &operator *() const {return *Pkg;}; 69 : inline operator Package *() {return Pkg == Owner->PkgP?0:Pkg;}; 70 : inline operator Package const *() const {return Pkg == Owner->PkgP?0:Pkg;}; 71 : inline pkgCache *Cache() {return Owner;}; 72 : 73 18343 : inline const char *Name() const {return Pkg->Name == 0?0:Owner->StrP + Pkg->Name;}; 74 : inline const char *Section() const {return Pkg->Section == 0?0:Owner->StrP + Pkg->Section;}; 75 : inline bool Purge() const {return Pkg->CurrentState == pkgCache::State::Purge || 76 : (Pkg->CurrentVer == 0 && Pkg->CurrentState == pkgCache::State::NotInstalled);}; 77 : inline VerIterator VersionList() const; 78 : inline VerIterator CurrentVer() const; 79 : inline DepIterator RevDependsList() const; 80 : inline PrvIterator ProvidesList() const; 81 : inline unsigned long Index() const {return Pkg - Owner->PkgP;}; 82 : OkState State() const; 83 : 84 : // Constructors 85 5424 : inline PkgIterator(pkgCache &Owner,Package *Trg) : Pkg(Trg), Owner(&Owner), 86 5424 : HashIndex(0) 87 : { 88 5424 : if (Pkg == 0) 89 0 : Pkg = Owner.PkgP; 90 5424 : }; 91 29 : inline PkgIterator() : Pkg(0), Owner(0), HashIndex(0) {}; 92 : }; 93 : 94 : // Version Iterator 95 : class pkgCache::VerIterator 96 : { 97 : Version *Ver; 98 : pkgCache *Owner; 99 : 100 : void _dummy(); 101 : 102 : public: 103 : 104 : // Iteration 105 15767 : void operator ++(int) {if (Ver != Owner->VerP) Ver = Owner->VerP + Ver->NextVer;}; 106 1808 : inline void operator ++() {operator ++(0);}; 107 58053 : inline bool end() const {return Owner == NULL || (Ver == Owner->VerP?true:false);}; 108 11172 : inline void operator =(const VerIterator &B) {Ver = B.Ver; Owner = B.Owner;}; 109 : 110 : // Comparison 111 : inline bool operator ==(const VerIterator &B) const {return Ver == B.Ver;}; 112 1433 : inline bool operator !=(const VerIterator &B) const {return Ver != B.Ver;}; 113 : int CompareVer(const VerIterator &B) const; 114 : 115 : // Accessors 116 : inline Version *operator ->() {return Ver;}; 117 : inline Version const *operator ->() const {return Ver;}; 118 : inline Version &operator *() {return *Ver;}; 119 : inline Version const &operator *() const {return *Ver;}; 120 : inline operator Version *() {return Ver == Owner->VerP?0:Ver;}; 121 : inline operator Version const *() const {return Ver == Owner->VerP?0:Ver;}; 122 : inline pkgCache *Cache() {return Owner;}; 123 : 124 1830 : inline const char *VerStr() const {return Ver->VerStr == 0?0:Owner->StrP + Ver->VerStr;}; 125 : inline const char *Section() const {return Ver->Section == 0?0:Owner->StrP + Ver->Section;}; 126 : inline const char *Arch() const {return Ver->Arch == 0?0:Owner->StrP + Ver->Arch;}; 127 5424 : inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Ver->ParentPkg);}; 128 : inline DescIterator DescriptionList() const; 129 : DescIterator TranslatedDescription() const; 130 : inline DepIterator DependsList() const; 131 : inline PrvIterator ProvidesList() const; 132 : inline VerFileIterator FileList() const; 133 : inline unsigned long Index() const {return Ver - Owner->VerP;}; 134 : bool Downloadable() const; 135 : inline const char *PriorityType() {return Owner->Priority(Ver->Priority);}; 136 : string RelStr(); 137 : 138 : bool Automatic() const; 139 : VerFileIterator NewestFile() const; 140 : 141 15 : inline VerIterator() : Ver(0), Owner(0) {}; 142 21130 : inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Ver(Trg), 143 21130 : Owner(&Owner) 144 : { 145 21130 : if (Ver == 0) 146 0 : Ver = Owner.VerP; 147 21130 : }; 148 : }; 149 : 150 : // Description Iterator 151 : class pkgCache::DescIterator 152 : { 153 : Description *Desc; 154 : pkgCache *Owner; 155 : 156 : void _dummy(); 157 : 158 : public: 159 : 160 : // Iteration 161 : void operator ++(int) {if (Desc != Owner->DescP) Desc = Owner->DescP + Desc->NextDesc;}; 162 : inline void operator ++() {operator ++(0);}; 163 : inline bool end() const {return Desc == Owner->DescP?true:false;}; 164 : inline void operator =(const DescIterator &B) {Desc = B.Desc; Owner = B.Owner;}; 165 : 166 : // Comparison 167 : inline bool operator ==(const DescIterator &B) const {return Desc == B.Desc;}; 168 : inline bool operator !=(const DescIterator &B) const {return Desc != B.Desc;}; 169 : int CompareDesc(const DescIterator &B) const; 170 : 171 : // Accessors 172 : inline Description *operator ->() {return Desc;}; 173 : inline Description const *operator ->() const {return Desc;}; 174 : inline Description &operator *() {return *Desc;}; 175 : inline Description const &operator *() const {return *Desc;}; 176 : inline operator Description *() {return Desc == Owner->DescP?0:Desc;}; 177 : inline operator Description const *() const {return Desc == Owner->DescP?0:Desc;}; 178 : inline pkgCache *Cache() {return Owner;}; 179 : 180 : inline const char *LanguageCode() const {return Owner->StrP + Desc->language_code;}; 181 : inline const char *md5() const {return Owner->StrP + Desc->md5sum;}; 182 : inline DescFileIterator FileList() const; 183 : inline unsigned long Index() const {return Desc - Owner->DescP;}; 184 : 185 : inline DescIterator() : Desc(0), Owner(0) {}; 186 : inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Desc(Trg), 187 : Owner(&Owner) 188 : { 189 : if (Desc == 0) 190 : Desc = Owner.DescP; 191 : }; 192 : }; 193 : 194 : // Dependency iterator 195 : class pkgCache::DepIterator 196 : { 197 : Dependency *Dep; 198 : enum {DepVer, DepRev} Type; 199 : pkgCache *Owner; 200 : 201 : void _dummy(); 202 : 203 : public: 204 : 205 : // Iteration 206 : void operator ++(int) {if (Dep != Owner->DepP) Dep = Owner->DepP + 207 : (Type == DepVer?Dep->NextDepends:Dep->NextRevDepends);}; 208 : inline void operator ++() {operator ++(0);}; 209 : inline bool end() const {return Owner == 0 || Dep == Owner->DepP?true:false;}; 210 : 211 : // Comparison 212 : inline bool operator ==(const DepIterator &B) const {return Dep == B.Dep;}; 213 : inline bool operator !=(const DepIterator &B) const {return Dep != B.Dep;}; 214 : 215 : // Accessors 216 : inline Dependency *operator ->() {return Dep;}; 217 : inline Dependency const *operator ->() const {return Dep;}; 218 : inline Dependency &operator *() {return *Dep;}; 219 : inline Dependency const &operator *() const {return *Dep;}; 220 : inline operator Dependency *() {return Dep == Owner->DepP?0:Dep;}; 221 : inline operator Dependency const *() const {return Dep == Owner->DepP?0:Dep;}; 222 : inline pkgCache *Cache() {return Owner;}; 223 : 224 : inline const char *TargetVer() const {return Dep->Version == 0?0:Owner->StrP + Dep->Version;}; 225 : inline PkgIterator TargetPkg() {return PkgIterator(*Owner,Owner->PkgP + Dep->Package);}; 226 : inline PkgIterator SmartTargetPkg() {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;}; 227 : inline VerIterator ParentVer() {return VerIterator(*Owner,Owner->VerP + Dep->ParentVer);}; 228 : inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Dep->ParentVer].ParentPkg);}; 229 : inline bool Reverse() {return Type == DepRev;}; 230 : inline unsigned long Index() const {return Dep - Owner->DepP;}; 231 : bool IsCritical(); 232 : void GlobOr(DepIterator &Start,DepIterator &End); 233 : Version **AllTargets(); 234 : bool SmartTargetPkg(PkgIterator &Result); 235 : inline const char *CompType() {return Owner->CompType(Dep->CompareOp);}; 236 : inline const char *DepType() {return Owner->DepType(Dep->Type);}; 237 : 238 : inline DepIterator(pkgCache &Owner,Dependency *Trg,Version * = 0) : 239 : Dep(Trg), Type(DepVer), Owner(&Owner) 240 : { 241 : if (Dep == 0) 242 : Dep = Owner.DepP; 243 : }; 244 : inline DepIterator(pkgCache &Owner,Dependency *Trg,Package *) : 245 : Dep(Trg), Type(DepRev), Owner(&Owner) 246 : { 247 : if (Dep == 0) 248 : Dep = Owner.DepP; 249 : }; 250 : inline DepIterator() : Dep(0), Type(DepVer), Owner(0) {}; 251 : }; 252 : 253 : // Provides iterator 254 : class pkgCache::PrvIterator 255 : { 256 : Provides *Prv; 257 : enum {PrvVer, PrvPkg} Type; 258 : pkgCache *Owner; 259 : 260 : void _dummy(); 261 : 262 : public: 263 : 264 : // Iteration 265 : void operator ++(int) {if (Prv != Owner->ProvideP) Prv = Owner->ProvideP + 266 : (Type == PrvVer?Prv->NextPkgProv:Prv->NextProvides);}; 267 : inline void operator ++() {operator ++(0);}; 268 : inline bool end() const {return Owner == 0 || Prv == Owner->ProvideP?true:false;}; 269 : 270 : // Comparison 271 : inline bool operator ==(const PrvIterator &B) const {return Prv == B.Prv;}; 272 : inline bool operator !=(const PrvIterator &B) const {return Prv != B.Prv;}; 273 : 274 : // Accessors 275 : inline Provides *operator ->() {return Prv;}; 276 : inline Provides const *operator ->() const {return Prv;}; 277 : inline Provides &operator *() {return *Prv;}; 278 : inline Provides const &operator *() const {return *Prv;}; 279 : inline operator Provides *() {return Prv == Owner->ProvideP?0:Prv;}; 280 : inline operator Provides const *() const {return Prv == Owner->ProvideP?0:Prv;}; 281 : inline pkgCache *Cache() {return Owner;}; 282 : 283 : inline const char *Name() const {return Owner->StrP + Owner->PkgP[Prv->ParentPkg].Name;}; 284 : inline const char *ProvideVersion() const {return Prv->ProvideVersion == 0?0:Owner->StrP + Prv->ProvideVersion;}; 285 : inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Prv->ParentPkg);}; 286 : inline VerIterator OwnerVer() {return VerIterator(*Owner,Owner->VerP + Prv->Version);}; 287 : inline PkgIterator OwnerPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Prv->Version].ParentPkg);}; 288 : inline unsigned long Index() const {return Prv - Owner->ProvideP;}; 289 : 290 : inline PrvIterator() : Prv(0), Type(PrvVer), Owner(0) {}; 291 : 292 : inline PrvIterator(pkgCache &Owner,Provides *Trg,Version *) : 293 : Prv(Trg), Type(PrvVer), Owner(&Owner) 294 : { 295 : if (Prv == 0) 296 : Prv = Owner.ProvideP; 297 : }; 298 : inline PrvIterator(pkgCache &Owner,Provides *Trg,Package *) : 299 : Prv(Trg), Type(PrvPkg), Owner(&Owner) 300 : { 301 : if (Prv == 0) 302 : Prv = Owner.ProvideP; 303 : }; 304 : }; 305 : 306 : // Package file 307 : class pkgCache::PkgFileIterator 308 : { 309 : pkgCache *Owner; 310 : PackageFile *File; 311 : 312 : public: 313 : 314 : // Iteration 315 : void operator ++(int) {if (File!= Owner->PkgFileP) File = Owner->PkgFileP + File->NextFile;}; 316 : inline void operator ++() {operator ++(0);}; 317 : inline bool end() const {return File == Owner->PkgFileP?true:false;}; 318 : 319 : // Comparison 320 : inline bool operator ==(const PkgFileIterator &B) const {return File == B.File;}; 321 : inline bool operator !=(const PkgFileIterator &B) const {return File != B.File;}; 322 : 323 : // Accessors 324 26403 : inline PackageFile *operator ->() {return File;}; 325 : inline PackageFile const *operator ->() const {return File;}; 326 : inline PackageFile const &operator *() const {return *File;}; 327 5202 : inline operator PackageFile *() {return File == Owner->PkgFileP?0:File;}; 328 : inline operator PackageFile const *() const {return File == Owner->PkgFileP?0:File;}; 329 5216 : inline pkgCache *Cache() {return Owner;}; 330 : 331 26 : inline const char *FileName() const {return File->FileName == 0?0:Owner->StrP + File->FileName;}; 332 : inline const char *Archive() const {return File->Archive == 0?0:Owner->StrP + File->Archive;}; 333 : inline const char *Component() const {return File->Component == 0?0:Owner->StrP + File->Component;}; 334 : inline const char *Version() const {return File->Version == 0?0:Owner->StrP + File->Version;}; 335 : inline const char *Origin() const {return File->Origin == 0?0:Owner->StrP + File->Origin;}; 336 : inline const char *Label() const {return File->Label == 0?0:Owner->StrP + File->Label;}; 337 : inline const char *Site() const {return File->Site == 0?0:Owner->StrP + File->Site;}; 338 : inline const char *Architecture() const {return File->Architecture == 0?0:Owner->StrP + File->Architecture;}; 339 : inline const char *IndexType() const {return File->IndexType == 0?0:Owner->StrP + File->IndexType;}; 340 : 341 : inline unsigned long Index() const {return File - Owner->PkgFileP;}; 342 : 343 : bool IsOk(); 344 : string RelStr(); 345 : 346 : // Constructors 347 15 : inline PkgFileIterator() : Owner(0), File(0) {}; 348 : inline PkgFileIterator(pkgCache &Owner) : Owner(&Owner), File(Owner.PkgFileP) {}; 349 26429 : inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Owner(&Owner), File(Trg) {}; 350 : }; 351 : 352 : // Version File 353 : class pkgCache::VerFileIterator 354 : { 355 : pkgCache *Owner; 356 : VerFile *FileP; 357 : 358 : public: 359 : 360 : // Iteration 361 22055 : void operator ++(int) {if (FileP != Owner->VerFileP) FileP = Owner->VerFileP + FileP->NextFile;}; 362 11714 : inline void operator ++() {operator ++(0);}; 363 90338 : inline bool end() const {return FileP == Owner->VerFileP?true:false;}; 364 : 365 : // Comparison 366 : inline bool operator ==(const VerFileIterator &B) const {return FileP == B.FileP;}; 367 : inline bool operator !=(const VerFileIterator &B) const {return FileP != B.FileP;}; 368 : 369 : // Accessors 370 10056 : inline VerFile *operator ->() {return FileP;}; 371 : inline VerFile const *operator ->() const {return FileP;}; 372 : inline VerFile const &operator *() const {return *FileP;}; 373 4341 : inline operator VerFile *() {return FileP == Owner->VerFileP?0:FileP;}; 374 : inline operator VerFile const *() const {return FileP == Owner->VerFileP?0:FileP;}; 375 1311 : inline pkgCache *Cache() {return Owner;}; 376 : 377 26406 : inline PkgFileIterator File() const {return PkgFileIterator(*Owner,FileP->File + Owner->PkgFileP);}; 378 : inline unsigned long Index() const {return FileP - Owner->VerFileP;}; 379 : 380 7 : inline VerFileIterator() : Owner(0), FileP(0) {}; 381 27354 : inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Owner(&Owner), FileP(Trg) {}; 382 : }; 383 : 384 : // Description File 385 : class pkgCache::DescFileIterator 386 : { 387 : pkgCache *Owner; 388 : DescFile *FileP; 389 : 390 : public: 391 : 392 : // Iteration 393 : void operator ++(int) {if (FileP != Owner->DescFileP) FileP = Owner->DescFileP + FileP->NextFile;}; 394 : inline void operator ++() {operator ++(0);}; 395 : inline bool end() const {return FileP == Owner->DescFileP?true:false;}; 396 : 397 : // Comparison 398 : inline bool operator ==(const DescFileIterator &B) const {return FileP == B.FileP;}; 399 : inline bool operator !=(const DescFileIterator &B) const {return FileP != B.FileP;}; 400 : 401 : // Accessors 402 : inline DescFile *operator ->() {return FileP;}; 403 : inline DescFile const *operator ->() const {return FileP;}; 404 : inline DescFile const &operator *() const {return *FileP;}; 405 : inline operator DescFile *() {return FileP == Owner->DescFileP?0:FileP;}; 406 : inline operator DescFile const *() const {return FileP == Owner->DescFileP?0:FileP;}; 407 : inline pkgCache *Cache() {return Owner;}; 408 : 409 : inline PkgFileIterator File() const {return PkgFileIterator(*Owner,FileP->File + Owner->PkgFileP);}; 410 : inline unsigned long Index() const {return FileP - Owner->DescFileP;}; 411 : 412 : inline DescFileIterator() : Owner(0), FileP(0) {}; 413 : inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Owner(&Owner), FileP(Trg) {}; 414 : }; 415 : 416 : // Inlined Begin functions cant be in the class because of order problems 417 19696 : inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const 418 19696 : {return VerIterator(*Owner,Owner->VerP + Pkg->VersionList);}; 419 2 : inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const 420 2 : {return VerIterator(*Owner,Owner->VerP + Pkg->CurrentVer);}; 421 : inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const 422 : {return DepIterator(*Owner,Owner->DepP + Pkg->RevDepends,Pkg);}; 423 : inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const 424 : {return PrvIterator(*Owner,Owner->ProvideP + Pkg->ProvidesList,Pkg);}; 425 : inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const 426 : {return DescIterator(*Owner,Owner->DescP + Ver->DescriptionList);}; 427 : inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const 428 : {return PrvIterator(*Owner,Owner->ProvideP + Ver->ProvidesList,Ver);}; 429 : inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const 430 : {return DepIterator(*Owner,Owner->DepP + Ver->DependsList,Ver);}; 431 26484 : inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const 432 26484 : {return VerFileIterator(*Owner,Owner->VerFileP + Ver->FileList);}; 433 : inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const 434 : {return DescFileIterator(*Owner,Owner->DescFileP + Desc->FileList);}; 435 : 436 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: cpp; mode: fold -*- 2 : // Description /*{{{*/ 3 : // $Id: cachefile.h,v 1.5 2002/04/27 04:28:04 jgg Exp $ 4 : /* ###################################################################### 5 : 6 : CacheFile - Simple wrapper class for opening, generating and whatnot 7 : 8 : This class implements a simple 2 line mechanism to open various sorts 9 : of caches. It can operate as root, as not root, show progress and so on, 10 : it transparently handles everything necessary. 11 : 12 : This means it can rebuild caches from the source list and instantiates 13 : and prepares the standard policy mechanism. 14 : 15 : ##################################################################### */ 16 : /*}}}*/ 17 : #ifndef PKGLIB_CACHEFILE_H 18 : #define PKGLIB_CACHEFILE_H 19 : 20 : 21 : #include <apt-pkg/depcache.h> 22 : #include <apt-pkg/acquire.h> 23 : #include <apt-pkg/sourcelist.h> 24 : 25 : class pkgPolicy; 26 : class pkgCacheFile 27 : { 28 : protected: 29 : 30 : MMap *Map; 31 : pkgCache *Cache; 32 : pkgDepCache *DCache; 33 : 34 : public: 35 : 36 : pkgPolicy *Policy; 37 : 38 : // We look pretty much exactly like a pointer to a dep cache 39 : inline operator pkgCache &() {return *Cache;}; 40 : inline operator pkgCache *() {return Cache;}; 41 : inline operator pkgDepCache &() {return *DCache;}; 42 : inline operator pkgDepCache *() {return DCache;}; 43 : inline pkgDepCache *operator ->() {return DCache;}; 44 : inline pkgDepCache &operator *() {return *DCache;}; 45 1 : inline pkgDepCache::StateCache &operator [](pkgCache::PkgIterator const &I) {return (*DCache)[I];}; 46 : inline unsigned char &operator [](pkgCache::DepIterator const &I) {return (*DCache)[I];}; 47 : 48 : bool BuildCaches(OpProgress &Progress,bool WithLock = true); 49 : bool Open(OpProgress &Progress,bool WithLock = true); 50 : void Close(); 51 : 52 : pkgCacheFile(); 53 : ~pkgCacheFile(); 54 : }; 55 : 56 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: cpp; mode: fold -*- 2 : // Description /*{{{*/ 3 : // $Id: fileutl.h,v 1.26 2001/05/07 05:06:52 jgg Exp $ 4 : /* ###################################################################### 5 : 6 : File Utilities 7 : 8 : CopyFile - Buffered copy of a single file 9 : GetLock - dpkg compatible lock file manipulation (fcntl) 10 : FileExists - Returns true if the file exists 11 : SafeGetCWD - Returns the CWD in a string with overrun protection 12 : 13 : The file class is a handy abstraction for various functions+classes 14 : that need to accept filenames. 15 : 16 : This source is placed in the Public Domain, do with it what you will 17 : It was originally written by Jason Gunthorpe. 18 : 19 : ##################################################################### */ 20 : /*}}}*/ 21 : #ifndef PKGLIB_FILEUTL_H 22 : #define PKGLIB_FILEUTL_H 23 : 24 : 25 : #include <string> 26 : 27 : using std::string; 28 : 29 : class FileFd 30 : { 31 : protected: 32 : int iFd; 33 : 34 : enum LocalFlags {AutoClose = (1<<0),Fail = (1<<1),DelOnFail = (1<<2), 35 : HitEof = (1<<3)}; 36 : unsigned long Flags; 37 : string FileName; 38 : 39 : public: 40 : enum OpenMode {ReadOnly,WriteEmpty,WriteExists,WriteAny,WriteTemp}; 41 : 42 : inline bool Read(void *To,unsigned long Size,bool AllowEof) 43 : { 44 : unsigned long Jnk; 45 : if (AllowEof) 46 : return Read(To,Size,&Jnk); 47 : return Read(To,Size); 48 : } 49 : bool Read(void *To,unsigned long Size,unsigned long *Actual = 0); 50 : bool Write(const void *From,unsigned long Size); 51 : bool Seek(unsigned long To); 52 : bool Skip(unsigned long To); 53 : bool Truncate(unsigned long To); 54 : unsigned long Tell(); 55 : unsigned long Size(); 56 : bool Open(string FileName,OpenMode Mode,unsigned long Perms = 0666); 57 : bool Close(); 58 : bool Sync(); 59 : 60 : // Simple manipulators 61 : inline int Fd() {return iFd;}; 62 : inline void Fd(int fd) {iFd = fd;}; 63 32 : inline bool IsOpen() {return iFd >= 0;}; 64 : inline bool Failed() {return (Flags & Fail) == Fail;}; 65 : inline void EraseOnFailure() {Flags |= DelOnFail;}; 66 : inline void OpFail() {Flags |= Fail;}; 67 : inline bool Eof() {return (Flags & HitEof) == HitEof;}; 68 : inline string &Name() {return FileName;}; 69 : 70 53 : FileFd(string FileName,OpenMode Mode,unsigned long Perms = 0666) : iFd(-1), 71 53 : Flags(0) 72 : { 73 53 : Open(FileName,Mode,Perms); 74 53 : }; 75 15 : FileFd(int Fd = -1) : iFd(Fd), Flags(AutoClose) {}; 76 : FileFd(int Fd,bool) : iFd(Fd), Flags(0) {}; 77 : virtual ~FileFd(); 78 : }; 79 : 80 : bool RunScripts(const char *Cnf); 81 : bool CopyFile(FileFd &From,FileFd &To); 82 : int GetLock(string File,bool Errors = true); 83 : bool FileExists(string File); 84 : string SafeGetCWD(); 85 : void SetCloseExec(int Fd,bool Close); 86 : void SetNonBlock(int Fd,bool Block); 87 : bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0); 88 : pid_t ExecFork(); 89 : bool ExecWait(pid_t Pid,const char *Name,bool Reap = false); 90 : 91 : // File string manipulators 92 : string flNotDir(string File); 93 : string flNotFile(string File); 94 : string flNoLink(string File); 95 : string flExtension(string File); 96 : string flCombine(string Dir,string File); 97 : 98 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: cpp; mode: fold -*- 2 : // Description /*{{{*/ 3 : // $Id: acquire.h,v 1.29.2.1 2003/12/24 23:09:17 mdz Exp $ 4 : /* ###################################################################### 5 : 6 : Acquire - File Acquiration 7 : 8 : This module contians the Acquire system. It is responsible for bringing 9 : files into the local pathname space. It deals with URIs for files and 10 : URI handlers responsible for downloading or finding the URIs. 11 : 12 : Each file to download is represented by an Acquire::Item class subclassed 13 : into a specialization. The Item class can add itself to several URI 14 : acquire queues each prioritized by the download scheduler. When the 15 : system is run the proper URI handlers are spawned and the the acquire 16 : queues are fed into the handlers by the schedular until the queues are 17 : empty. This allows for an Item to be downloaded from an alternate source 18 : if the first try turns out to fail. It also alows concurrent downloading 19 : of multiple items from multiple sources as well as dynamic balancing 20 : of load between the sources. 21 : 22 : Schedualing of downloads is done on a first ask first get basis. This 23 : preserves the order of the download as much as possible. And means the 24 : fastest source will tend to process the largest number of files. 25 : 26 : Internal methods and queues for performing gzip decompression, 27 : md5sum hashing and file copying are provided to allow items to apply 28 : a number of transformations to the data files they are working with. 29 : 30 : ##################################################################### */ 31 : /*}}}*/ 32 : 33 : /** \defgroup acquire Acquire system 34 : * 35 : * \brief The Acquire system is responsible for retrieving files from 36 : * local or remote URIs and postprocessing them (for instance, 37 : * verifying their authenticity). The core class in this system is 38 : * pkgAcquire, which is responsible for managing the download queues 39 : * during the download. There is at least one download queue for 40 : * each supported protocol; protocols such as http may provide one 41 : * queue per host. 42 : * 43 : * Each file to download is represented by a subclass of 44 : * pkgAcquire::Item. The files add themselves to the download 45 : * queue(s) by providing their URI information to 46 : * pkgAcquire::Item::QueueURI, which calls pkgAcquire::Enqueue. 47 : * 48 : * Once the system is set up, the Run method will spawn subprocesses 49 : * to handle the enqueued URIs; the scheduler will then take items 50 : * from the queues and feed them into the handlers until the queues 51 : * are empty. 52 : * 53 : * \todo Acquire supports inserting an object into several queues at 54 : * once, but it is not clear what its behavior in this case is, and 55 : * no subclass of pkgAcquire::Item seems to actually use this 56 : * capability. 57 : */ 58 : 59 : /** \addtogroup acquire 60 : * 61 : * @{ 62 : * 63 : * \file acquire.h 64 : */ 65 : 66 : #ifndef PKGLIB_ACQUIRE_H 67 : #define PKGLIB_ACQUIRE_H 68 : 69 : #include <vector> 70 : #include <string> 71 : 72 : using std::vector; 73 : using std::string; 74 : 75 : 76 : #include <sys/time.h> 77 : #include <unistd.h> 78 : 79 : class pkgAcquireStatus; 80 : 81 : /** \brief The core download scheduler. 82 : * 83 : * This class represents an ongoing download. It manages the lists 84 : * of active and pending downloads and handles setting up and tearing 85 : * down download-related structures. 86 : * 87 : * \todo Why all the protected data items and methods? 88 : */ 89 : class pkgAcquire 90 : { 91 : public: 92 : 93 : class Item; 94 : class Queue; 95 : class Worker; 96 : struct MethodConfig; 97 : struct ItemDesc; 98 : friend class Item; 99 : friend class Queue; 100 : 101 : typedef vector<Item *>::iterator ItemIterator; 102 : typedef vector<Item *>::const_iterator ItemCIterator; 103 : 104 : protected: 105 : 106 : /** \brief A list of items to download. 107 : * 108 : * This is built monotonically as items are created and only 109 : * emptied when the download shuts down. 110 : */ 111 : vector<Item *> Items; 112 : 113 : /** \brief The head of the list of active queues. 114 : * 115 : * \todo why a hand-managed list of queues instead of std::list or 116 : * std::set? 117 : */ 118 : Queue *Queues; 119 : 120 : /** \brief The head of the list of active workers. 121 : * 122 : * \todo why a hand-managed list of workers instead of std::list 123 : * or std::set? 124 : */ 125 : Worker *Workers; 126 : 127 : /** \brief The head of the list of acquire method configurations. 128 : * 129 : * Each protocol (http, ftp, gzip, etc) via which files can be 130 : * fetched can have a representation in this list. The 131 : * configuration data is filled in by parsing the 100 Capabilities 132 : * string output by a method on startup (see 133 : * pkgAcqMethod::pkgAcqMethod and pkgAcquire::GetConfig). 134 : * 135 : * \todo why a hand-managed config dictionary instead of std::map? 136 : */ 137 : MethodConfig *Configs; 138 : 139 : /** \brief The progress indicator for this download. */ 140 : pkgAcquireStatus *Log; 141 : 142 : /** \brief The total size of the files which are to be fetched. 143 : * 144 : * This is not necessarily the total number of bytes to download 145 : * when, e.g., download resumption and list updates via patches 146 : * are taken into account. 147 : */ 148 : unsigned long ToFetch; 149 : 150 : // Configurable parameters for the scheduler 151 : 152 : /** \brief Represents the queuing strategy for remote URIs. */ 153 : enum QueueStrategy { 154 : /** \brief Generate one queue for each protocol/host combination; downloads from 155 : * multiple hosts can proceed in parallel. 156 : */ 157 : QueueHost, 158 : /** \brief Generate a single queue for each protocol; serialize 159 : * downloads from multiple hosts. 160 : */ 161 : QueueAccess} QueueMode; 162 : 163 : /** \brief If \b true, debugging information will be dumped to std::clog. */ 164 : bool Debug; 165 : /** \brief If \b true, a download is currently in progress. */ 166 : bool Running; 167 : 168 : /** \brief Add the given item to the list of items. */ 169 : void Add(Item *Item); 170 : 171 : /** \brief Remove the given item from the list of items. */ 172 : void Remove(Item *Item); 173 : 174 : /** \brief Add the given worker to the list of workers. */ 175 : void Add(Worker *Work); 176 : 177 : /** \brief Remove the given worker from the list of workers. */ 178 : void Remove(Worker *Work); 179 : 180 : /** \brief Insert the given fetch request into the appropriate queue. 181 : * 182 : * \param Item The URI to download and the item to download it 183 : * for. Copied by value into the queue; no reference to Item is 184 : * retained. 185 : */ 186 : void Enqueue(ItemDesc &Item); 187 : 188 : /** \brief Remove all fetch requests for this item from all queues. */ 189 : void Dequeue(Item *Item); 190 : 191 : /** \brief Determine the fetch method and queue of a URI. 192 : * 193 : * \param URI The URI to fetch. 194 : * 195 : * \param[out] Config A location in which to place the method via 196 : * which the URI is to be fetched. 197 : * 198 : * \return the string-name of the queue in which a fetch request 199 : * for the given URI should be placed. 200 : */ 201 : string QueueName(string URI,MethodConfig const *&Config); 202 : 203 : /** \brief Build up the set of file descriptors upon which select() should 204 : * block. 205 : * 206 : * The default implementation inserts the file descriptors 207 : * corresponding to active downloads. 208 : * 209 : * \param[out] Fd The largest file descriptor in the generated sets. 210 : * 211 : * \param[out] RSet The set of file descriptors that should be 212 : * watched for input. 213 : * 214 : * \param[out] WSet The set of file descriptors that should be 215 : * watched for output. 216 : */ 217 : virtual void SetFds(int &Fd,fd_set *RSet,fd_set *WSet); 218 : 219 : /** Handle input from and output to file descriptors which select() 220 : * has determined are ready. The default implementation 221 : * dispatches to all active downloads. 222 : * 223 : * \param RSet The set of file descriptors that are ready for 224 : * input. 225 : * 226 : * \param WSet The set of file descriptors that are ready for 227 : * output. 228 : */ 229 : virtual void RunFds(fd_set *RSet,fd_set *WSet); 230 : 231 : /** \brief Check for idle queues with ready-to-fetch items. 232 : * 233 : * Called by pkgAcquire::Queue::Done each time an item is dequeued 234 : * but remains on some queues; i.e., another queue should start 235 : * fetching it. 236 : */ 237 : void Bump(); 238 : 239 : public: 240 : 241 : /** \brief Retrieve information about a fetch method by name. 242 : * 243 : * \param Access The name of the method to look up. 244 : * 245 : * \return the method whose name is Access, or \b NULL if no such method exists. 246 : */ 247 : MethodConfig *GetConfig(string Access); 248 : 249 : /** \brief Provides information on how a download terminated. */ 250 : enum RunResult { 251 : /** \brief All files were fetched successfully. */ 252 : Continue, 253 : 254 : /** \brief Some files failed to download. */ 255 : Failed, 256 : 257 : /** \brief The download was cancelled by the user (i.e., #Log's 258 : * pkgAcquireStatus::Pulse() method returned \b false). 259 : */ 260 : Cancelled}; 261 : 262 : /** \brief Download all the items that have been Add()ed to this 263 : * download process. 264 : * 265 : * This method will block until the download completes, invoking 266 : * methods on #Log to report on the progress of the download. 267 : * 268 : * \param PulseInterval The method pkgAcquireStatus::Pulse will be 269 : * invoked on #Log at intervals of PulseInterval milliseconds. 270 : * 271 : * \return the result of the download. 272 : */ 273 : RunResult Run(int PulseInterval=500000); 274 : 275 : /** \brief Remove all items from this download process, terminate 276 : * all download workers, and empty all queues. 277 : */ 278 : void Shutdown(); 279 : 280 : /** \brief Get the first #Worker object. 281 : * 282 : * \return the first active worker in this download process. 283 : */ 284 : inline Worker *WorkersBegin() {return Workers;}; 285 : 286 : /** \brief Advance to the next #Worker object. 287 : * 288 : * \return the worker immediately following I, or \b NULL if none 289 : * exists. 290 : */ 291 : Worker *WorkerStep(Worker *I); 292 : 293 : /** \brief Get the head of the list of items. */ 294 : inline ItemIterator ItemsBegin() {return Items.begin();}; 295 : 296 : /** \brief Get the end iterator of the list of items. */ 297 : inline ItemIterator ItemsEnd() {return Items.end();}; 298 : 299 : // Iterate over queued Item URIs 300 : class UriIterator; 301 : /** \brief Get the head of the list of enqueued item URIs. 302 : * 303 : * This iterator will step over every element of every active 304 : * queue. 305 : */ 306 : UriIterator UriBegin(); 307 : /** \brief Get the end iterator of the list of enqueued item URIs. */ 308 : UriIterator UriEnd(); 309 : 310 : /** Deletes each entry in the given directory that is not being 311 : * downloaded by this object. For instance, when downloading new 312 : * list files, calling Clean() will delete the old ones. 313 : * 314 : * \param Dir The directory to be cleaned out. 315 : * 316 : * \return \b true if the directory exists and is readable. 317 : */ 318 : bool Clean(string Dir); 319 : 320 : /** \return the total size in bytes of all the items included in 321 : * this download. 322 : */ 323 : double TotalNeeded(); 324 : 325 : /** \return the size in bytes of all non-local items included in 326 : * this download. 327 : */ 328 : double FetchNeeded(); 329 : 330 : /** \return the amount of data to be fetched that is already 331 : * present on the filesystem. 332 : */ 333 : double PartialPresent(); 334 : 335 : /** \brief Construct a new pkgAcquire. 336 : * 337 : * \param Log The progress indicator associated with this 338 : * download, or \b NULL for none. This object is not owned by the 339 : * download process and will not be deleted when the pkgAcquire 340 : * object is destroyed. Naturally, it should live for at least as 341 : * long as the pkgAcquire object does. 342 : */ 343 : pkgAcquire(pkgAcquireStatus *Log = 0); 344 : 345 : /** \brief Destroy this pkgAcquire object. 346 : * 347 : * Destroys all queue, method, and item objects associated with 348 : * this download. 349 : */ 350 : virtual ~pkgAcquire(); 351 : }; 352 : 353 : /** \brief Represents a single download source from which an item 354 : * should be downloaded. 355 : * 356 : * An item may have several assocated ItemDescs over its lifetime. 357 : */ 358 : struct pkgAcquire::ItemDesc 359 : { 360 : /** \brief The URI from which to download this item. */ 361 : string URI; 362 : /** brief A description of this item. */ 363 : string Description; 364 : /** brief A shorter description of this item. */ 365 : string ShortDesc; 366 : /** brief The underlying item which is to be downloaded. */ 367 : Item *Owner; 368 : }; 369 : 370 : /** \brief A single download queue in a pkgAcquire object. 371 : * 372 : * \todo Why so many protected values? 373 : */ 374 : class pkgAcquire::Queue 375 : { 376 : friend class pkgAcquire; 377 : friend class pkgAcquire::UriIterator; 378 : friend class pkgAcquire::Worker; 379 : 380 : /** \brief The next queue in the pkgAcquire object's list of queues. */ 381 : Queue *Next; 382 : 383 : protected: 384 : 385 : /** \brief A single item placed in this queue. */ 386 : struct QItem : pkgAcquire::ItemDesc 387 : { 388 : /** \brief The next item in the queue. */ 389 : QItem *Next; 390 : /** \brief The worker associated with this item, if any. */ 391 : pkgAcquire::Worker *Worker; 392 : 393 : /** \brief Assign the ItemDesc portion of this QItem from 394 : * another ItemDesc 395 : */ 396 : void operator =(pkgAcquire::ItemDesc const &I) 397 : { 398 : URI = I.URI; 399 : Description = I.Description; 400 : ShortDesc = I.ShortDesc; 401 : Owner = I.Owner; 402 : }; 403 : }; 404 : 405 : /** \brief The name of this queue. */ 406 : string Name; 407 : 408 : /** \brief The head of the list of items contained in this queue. 409 : * 410 : * \todo why a by-hand list instead of an STL structure? 411 : */ 412 : QItem *Items; 413 : 414 : /** \brief The head of the list of workers associated with this queue. 415 : * 416 : * \todo This is plural because support exists in Queue for 417 : * multiple workers. However, it does not appear that there is 418 : * any way to actually associate more than one worker with a 419 : * queue. 420 : * 421 : * \todo Why not just use a std::set? 422 : */ 423 : pkgAcquire::Worker *Workers; 424 : 425 : /** \brief the download scheduler with which this queue is associated. */ 426 : pkgAcquire *Owner; 427 : 428 : /** \brief The number of entries in this queue that are currently 429 : * being downloaded. 430 : */ 431 : signed long PipeDepth; 432 : 433 : /** \brief The maximum number of entries that this queue will 434 : * attempt to download at once. 435 : */ 436 : unsigned long MaxPipeDepth; 437 : 438 : public: 439 : 440 : /** \brief Insert the given fetch request into this queue. 441 : * 442 : * \return \b true if the queuing was successful. May return 443 : * \b false if the Item is already in the queue 444 : */ 445 : bool Enqueue(ItemDesc &Item); 446 : 447 : /** \brief Remove all fetch requests for the given item from this queue. 448 : * 449 : * \return \b true if at least one request was removed from the queue. 450 : */ 451 : bool Dequeue(Item *Owner); 452 : 453 : /** \brief Locate an item in this queue. 454 : * 455 : * \param URI A URI to match against. 456 : * \param Owner A pkgAcquire::Worker to match against. 457 : * 458 : * \return the first item in the queue whose URI is #URI and that 459 : * is being downloaded by #Owner. 460 : */ 461 : QItem *FindItem(string URI,pkgAcquire::Worker *Owner); 462 : 463 : /** Presumably this should start downloading an item? 464 : * 465 : * \todo Unimplemented. Implement it or remove? 466 : */ 467 : bool ItemStart(QItem *Itm,unsigned long Size); 468 : 469 : /** \brief Remove the given item from this queue and set its state 470 : * to pkgAcquire::Item::StatDone. 471 : * 472 : * If this is the only queue containing the item, the item is also 473 : * removed from the main queue by calling pkgAcquire::Dequeue. 474 : * 475 : * \param Itm The item to remove. 476 : * 477 : * \return \b true if no errors are encountered. 478 : */ 479 : bool ItemDone(QItem *Itm); 480 : 481 : /** \brief Start the worker process associated with this queue. 482 : * 483 : * If a worker process is already associated with this queue, 484 : * this is equivalent to calling Cycle(). 485 : * 486 : * \return \b true if the startup was successful. 487 : */ 488 : bool Startup(); 489 : 490 : /** \brief Shut down the worker process associated with this queue. 491 : * 492 : * \param Final If \b true, then the process is stopped unconditionally. 493 : * Otherwise, it is only stopped if it does not need cleanup 494 : * as indicated by the pkgAcqMethod::NeedsCleanup member of 495 : * its configuration. 496 : * 497 : * \return \b true. 498 : */ 499 : bool Shutdown(bool Final); 500 : 501 : /** \brief Send idle items to the worker process. 502 : * 503 : * Fills up the pipeline by inserting idle items into the worker's queue. 504 : */ 505 : bool Cycle(); 506 : 507 : /** \brief Check for items that could be enqueued. 508 : * 509 : * Call this after an item placed in multiple queues has gone from 510 : * the pkgAcquire::Item::StatFetching state to the 511 : * pkgAcquire::Item::StatIdle state, to possibly refill an empty queue. 512 : * This is an alias for Cycle(). 513 : * 514 : * \todo Why both this and Cycle()? Are they expected to be 515 : * different someday? 516 : */ 517 : void Bump(); 518 : 519 : /** \brief Create a new Queue. 520 : * 521 : * \param Name The name of the new queue. 522 : * \param Owner The download process that owns the new queue. 523 : */ 524 : Queue(string Name,pkgAcquire *Owner); 525 : 526 : /** Shut down all the worker processes associated with this queue 527 : * and empty the queue. 528 : */ 529 : ~Queue(); 530 : }; 531 : 532 : /** \brief Iterates over all the URIs being fetched by a pkgAcquire object. */ 533 : class pkgAcquire::UriIterator 534 : { 535 : /** The next queue to iterate over. */ 536 : pkgAcquire::Queue *CurQ; 537 : /** The item that we currently point at. */ 538 : pkgAcquire::Queue::QItem *CurItem; 539 : 540 : public: 541 : 542 : inline void operator ++() {operator ++();}; 543 : 544 : void operator ++(int) 545 : { 546 : CurItem = CurItem->Next; 547 : while (CurItem == 0 && CurQ != 0) 548 : { 549 : CurItem = CurQ->Items; 550 : CurQ = CurQ->Next; 551 : } 552 : }; 553 : 554 : inline pkgAcquire::ItemDesc const *operator ->() const {return CurItem;}; 555 : inline bool operator !=(UriIterator const &rhs) const {return rhs.CurQ != CurQ || rhs.CurItem != CurItem;}; 556 : inline bool operator ==(UriIterator const &rhs) const {return rhs.CurQ == CurQ && rhs.CurItem == CurItem;}; 557 : 558 : /** \brief Create a new UriIterator. 559 : * 560 : * \param Q The queue over which this UriIterator should iterate. 561 : */ 562 : UriIterator(pkgAcquire::Queue *Q) : CurQ(Q), CurItem(0) 563 : { 564 : while (CurItem == 0 && CurQ != 0) 565 : { 566 : CurItem = CurQ->Items; 567 : CurQ = CurQ->Next; 568 : } 569 : } 570 : }; 571 : 572 : /** \brief Information about the properties of a single acquire method. */ 573 : struct pkgAcquire::MethodConfig 574 : { 575 : /** \brief The next link on the acquire method list. 576 : * 577 : * \todo Why not an STL container? 578 : */ 579 : MethodConfig *Next; 580 : 581 : /** \brief The name of this acquire method (e.g., http). */ 582 : string Access; 583 : 584 : /** \brief The implementation version of this acquire method. */ 585 : string Version; 586 : 587 : /** \brief If \b true, only one download queue should be created for this 588 : * method. 589 : */ 590 : bool SingleInstance; 591 : 592 : /** \brief If \b true, this method supports pipelined downloading. */ 593 : bool Pipeline; 594 : 595 : /** \brief If \b true, the worker process should send the entire 596 : * APT configuration tree to the fetch subprocess when it starts 597 : * up. 598 : */ 599 : bool SendConfig; 600 : 601 : /** \brief If \b true, this fetch method does not require network access; 602 : * all files are to be acquired from the local disk. 603 : */ 604 : bool LocalOnly; 605 : 606 : /** \brief If \b true, the subprocess has to carry out some cleanup 607 : * actions before shutting down. 608 : * 609 : * For instance, the cdrom method needs to unmount the CD after it 610 : * finishes. 611 : */ 612 : bool NeedsCleanup; 613 : 614 : /** \brief If \b true, this fetch method acquires files from removable media. */ 615 : bool Removable; 616 : 617 : /** \brief Set up the default method parameters. 618 : * 619 : * All fields are initialized to NULL, "", or \b false as 620 : * appropriate. 621 : */ 622 : MethodConfig(); 623 : }; 624 : 625 : /** \brief A monitor object for downloads controlled by the pkgAcquire class. 626 : * 627 : * \todo Why protected members? 628 : * 629 : * \todo Should the double members be uint64_t? 630 : */ 631 : class pkgAcquireStatus 632 : { 633 : protected: 634 : 635 : /** \brief The last time at which this monitor object was updated. */ 636 : struct timeval Time; 637 : 638 : /** \brief The time at which the download started. */ 639 : struct timeval StartTime; 640 : 641 : /** \brief The number of bytes fetched as of the previous call to 642 : * pkgAcquireStatus::Pulse, including local items. 643 : */ 644 : double LastBytes; 645 : 646 : /** \brief The current rate of download as of the most recent call 647 : * to pkgAcquireStatus::Pulse, in bytes per second. 648 : */ 649 : double CurrentCPS; 650 : 651 : /** \brief The number of bytes fetched as of the most recent call 652 : * to pkgAcquireStatus::Pulse, including local items. 653 : */ 654 : double CurrentBytes; 655 : 656 : /** \brief The total number of bytes that need to be fetched. 657 : * 658 : * \warning This member is inaccurate, as new items might be 659 : * enqueued while the download is in progress! 660 : */ 661 : double TotalBytes; 662 : 663 : /** \brief The total number of bytes accounted for by items that 664 : * were successfully fetched. 665 : */ 666 : double FetchedBytes; 667 : 668 : /** \brief The amount of time that has elapsed since the download 669 : * started. 670 : */ 671 : unsigned long ElapsedTime; 672 : 673 : /** \brief The total number of items that need to be fetched. 674 : * 675 : * \warning This member is inaccurate, as new items might be 676 : * enqueued while the download is in progress! 677 : */ 678 : unsigned long TotalItems; 679 : 680 : /** \brief The number of items that have been successfully downloaded. */ 681 : unsigned long CurrentItems; 682 : 683 : public: 684 : 685 : /** \brief If \b true, the download scheduler should call Pulse() 686 : * at the next available opportunity. 687 : */ 688 : bool Update; 689 : 690 : /** \brief If \b true, extra Pulse() invocations will be performed. 691 : * 692 : * With this option set, Pulse() will be called every time that a 693 : * download item starts downloading, finishes downloading, or 694 : * terminates with an error. 695 : */ 696 : bool MorePulses; 697 : 698 : /** \brief Invoked when a local or remote file has been completely fetched. 699 : * 700 : * \param Size The size of the file fetched. 701 : * 702 : * \param ResumePoint How much of the file was already fetched. 703 : */ 704 : virtual void Fetched(unsigned long Size,unsigned long ResumePoint); 705 : 706 : /** \brief Invoked when the user should be prompted to change the 707 : * inserted removable media. 708 : * 709 : * This method should not return until the user has confirmed to 710 : * the user interface that the media change is complete. 711 : * 712 : * \param Media The name of the media type that should be changed. 713 : * 714 : * \param Drive The identifying name of the drive whose media 715 : * should be changed. 716 : * 717 : * \return \b true if the user confirms the media change, \b 718 : * false if it is cancelled. 719 : * 720 : * \todo This is a horrible blocking monster; it should be CPSed 721 : * with prejudice. 722 : */ 723 : virtual bool MediaChange(string Media,string Drive) = 0; 724 : 725 : /** \brief Invoked when an item is confirmed to be up-to-date. 726 : 727 : * For instance, when an HTTP download is informed that the file on 728 : * the server was not modified. 729 : */ 730 0 : virtual void IMSHit(pkgAcquire::ItemDesc &/*Itm*/) {}; 731 : 732 : /** \brief Invoked when some of an item's data is fetched. */ 733 0 : virtual void Fetch(pkgAcquire::ItemDesc &/*Itm*/) {}; 734 : 735 : /** \brief Invoked when an item is successfully and completely fetched. */ 736 0 : virtual void Done(pkgAcquire::ItemDesc &/*Itm*/) {}; 737 : 738 : /** \brief Invoked when the process of fetching an item encounters 739 : * a fatal error. 740 : */ 741 0 : virtual void Fail(pkgAcquire::ItemDesc &/*Itm*/) {}; 742 : 743 : /** \brief Periodically invoked while the Acquire process is underway. 744 : * 745 : * Subclasses should first call pkgAcquireStatus::Pulse(), then 746 : * update their status output. The download process is blocked 747 : * while Pulse() is being called. 748 : * 749 : * \return \b false if the user asked to cancel the whole Acquire process. 750 : * 751 : * \see pkgAcquire::Run 752 : */ 753 : virtual bool Pulse(pkgAcquire *Owner); 754 : 755 : /** \brief Invoked when the Acquire process starts running. */ 756 : virtual void Start(); 757 : 758 : /** \brief Invoked when the Acquire process stops running. */ 759 : virtual void Stop(); 760 : 761 : /** \brief Initialize all counters to 0 and the time to the current time. */ 762 : pkgAcquireStatus(); 763 0 : virtual ~pkgAcquireStatus() {}; 764 : }; 765 : 766 : /** @} */ 767 : 768 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: cpp; mode: fold -*- 2 : // Description /*{{{*/ 3 : // $Id: version.h,v 1.8 2001/05/27 05:55:27 jgg Exp $ 4 : /* ###################################################################### 5 : 6 : Version - Versioning system.. 7 : 8 : The versioning system represents how versions are compared, represented 9 : and how dependencies are evaluated. As a general rule versioning 10 : systems are not compatible unless specifically allowed by the 11 : TestCompatibility query. 12 : 13 : The versions are stored in a global list of versions, but that is just 14 : so that they can be queried when someone does 'apt-get -v'. 15 : pkgSystem provides the proper means to access the VS for the active 16 : system. 17 : 18 : ##################################################################### */ 19 : /*}}}*/ 20 : #ifndef PKGLIB_VERSION_H 21 : #define PKGLIB_VERSION_H 22 : 23 : 24 : #include <apt-pkg/strutl.h> 25 : #include <string> 26 : 27 : using std::string; 28 : 29 : class pkgVersioningSystem 30 : { 31 : public: 32 : // Global list of VS's 33 : static pkgVersioningSystem **GlobalList; 34 : static unsigned long GlobalListLen; 35 : static pkgVersioningSystem *GetVS(const char *Label); 36 : 37 : const char *Label; 38 : 39 : // Compare versions.. 40 : virtual int DoCmpVersion(const char *A,const char *Aend, 41 : const char *B,const char *Bend) = 0; 42 : 43 : virtual bool CheckDep(const char *PkgVer,int Op,const char *DepVer) = 0; 44 : virtual int DoCmpReleaseVer(const char *A,const char *Aend, 45 : const char *B,const char *Bend) = 0; 46 : virtual string UpstreamVersion(const char *A) = 0; 47 : 48 : // See if the given VS is compatible with this one.. 49 : virtual bool TestCompatibility(pkgVersioningSystem const &Against) 50 : {return this == &Against;}; 51 : 52 : // Shortcuts 53 14 : APT_MKSTRCMP(CmpVersion,DoCmpVersion); 54 : APT_MKSTRCMP(CmpReleaseVer,DoCmpReleaseVer); 55 : 56 : pkgVersioningSystem(); 57 : virtual ~pkgVersioningSystem() {}; 58 : }; 59 : 60 : #ifdef APT_COMPATIBILITY 61 : #include <apt-pkg/debversion.h> 62 : #endif 63 : 64 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
acquire.h |
|
0.0 % | 0 / 5 lines | |
algorithms.h |
|
66.7 % | 2 / 3 lines | |
cachefile.h |
|
100.0 % | 1 / 1 lines | |
cacheiterators.h |
|
92.2 % | 47 / 51 lines | |
depcache.h |
|
100.0 % | 6 / 6 lines | |
error.h |
|
50.0 % | 1 / 2 lines | |
fileutl.h |
|
100.0 % | 6 / 6 lines | |
pkgcache.h |
|
100.0 % | 2 / 2 lines | |
progress.h |
|
100.0 % | 3 / 3 lines | |
version.h |
|
100.0 % | 1 / 1 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: cpp; mode: fold -*- 2 : // Description /*{{{*/ 3 : // $Id: error.h,v 1.8 2001/05/07 05:06:52 jgg Exp $ 4 : /* ###################################################################### 5 : 6 : Global Erorr Class - Global error mechanism 7 : 8 : This class has a single global instance. When a function needs to 9 : generate an error condition, such as a read error, it calls a member 10 : in this class to add the error to a stack of errors. 11 : 12 : By using a stack the problem with a scheme like errno is removed and 13 : it allows a very detailed account of what went wrong to be transmitted 14 : to the UI for display. (Errno has problems because each function sets 15 : errno to 0 if it didn't have an error thus eraseing erno in the process 16 : of cleanup) 17 : 18 : Several predefined error generators are provided to handle common 19 : things like errno. The general idea is that all methods return a bool. 20 : If the bool is true then things are OK, if it is false then things 21 : should start being undone and the stack should unwind under program 22 : control. 23 : 24 : A Warning should not force the return of false. Things did not fail, but 25 : they might have had unexpected problems. Errors are stored in a FIFO 26 : so Pop will return the first item.. 27 : 28 : I have some thoughts about extending this into a more general UI<-> 29 : Engine interface, ie allowing the Engine to say 'The disk is full' in 30 : a dialog that says 'Panic' and 'Retry'.. The error generator functions 31 : like errno, Warning and Error return false always so this is normal: 32 : if (open(..)) 33 : return _error->Errno(..); 34 : 35 : This source is placed in the Public Domain, do with it what you will 36 : It was originally written by Jason Gunthorpe. 37 : 38 : ##################################################################### */ 39 : /*}}}*/ 40 : #ifndef PKGLIB_ERROR_H 41 : #define PKGLIB_ERROR_H 42 : 43 : 44 : 45 : #ifdef __GNUG__ 46 : // Methods have a hidden this parameter that is visible to this attribute 47 : #define APT_MFORMAT1 __attribute__ ((format (printf, 2, 3))) 48 : #define APT_MFORMAT2 __attribute__ ((format (printf, 3, 4))) 49 : #else 50 : #define APT_MFORMAT1 51 : #define APT_MFORMAT2 52 : #endif 53 : 54 : #include <string> 55 : 56 : using std::string; 57 : 58 : class GlobalError 59 : { 60 : struct Item 61 : { 62 : string Text; 63 : bool Error; 64 : Item *Next; 65 : }; 66 : 67 : Item *List; 68 : bool PendingFlag; 69 : void Insert(Item *I); 70 : 71 : public: 72 : 73 : // Call to generate an error from a library call. 74 : bool Errno(const char *Function,const char *Description,...) APT_MFORMAT2; 75 : bool WarningE(const char *Function,const char *Description,...) APT_MFORMAT2; 76 : 77 : /* A warning should be considered less severe than an error, and may be 78 : ignored by the client. */ 79 : bool Error(const char *Description,...) APT_MFORMAT1; 80 : bool Warning(const char *Description,...) APT_MFORMAT1; 81 : 82 : // Simple accessors 83 3 : inline bool PendingError() {return PendingFlag;}; 84 0 : inline bool empty() {return List == 0;}; 85 : bool PopMessage(string &Text); 86 : void Discard(); 87 : 88 : // Usefull routine to dump to cerr 89 : void DumpErrors(); 90 : 91 : GlobalError(); 92 : }; 93 : 94 : // The 'extra-ansi' syntax is used to help with collisions. 95 : GlobalError *_GetErrorObj(); 96 : #define _error _GetErrorObj() 97 : 98 : #undef APT_MFORMAT1 99 : #undef APT_MFORMAT2 100 : 101 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: cpp; mode: fold -*- 2 : // Description /*{{{*/ 3 : // $Id: progress.h,v 1.6 2001/05/07 05:06:52 jgg Exp $ 4 : /* ###################################################################### 5 : 6 : OpProgress - Operation Progress 7 : 8 : This class allows lengthy operations to communicate their progress 9 : to the GUI. The progress model is simple and is not designed to handle 10 : the complex case of the multi-activity aquire class. 11 : 12 : The model is based on the concept of an overall operation consisting 13 : of a series of small sub operations. Each sub operation has it's own 14 : completion status and the overall operation has it's completion status. 15 : The units of the two are not mixed and are completely independent. 16 : 17 : The UI is expected to subclass this to provide the visuals to the user. 18 : 19 : ##################################################################### */ 20 : /*}}}*/ 21 : #ifndef PKGLIB_PROGRESS_H 22 : #define PKGLIB_PROGRESS_H 23 : 24 : 25 : #include <string> 26 : #include <sys/time.h> 27 : 28 : using std::string; 29 : 30 : class Configuration; 31 : class OpProgress 32 : { 33 : unsigned long Current; 34 : unsigned long Total; 35 : unsigned long Size; 36 : unsigned long SubTotal; 37 : float LastPercent; 38 : 39 : // Change reduction code 40 : struct timeval LastTime; 41 : string LastOp; 42 : string LastSubOp; 43 : 44 : protected: 45 : 46 : string Op; 47 : string SubOp; 48 : float Percent; 49 : 50 : bool MajorChange; 51 : 52 : bool CheckChange(float Interval = 0.7); 53 24433 : virtual void Update() {}; 54 : 55 : public: 56 : 57 : void Progress(unsigned long Current); 58 : void SubProgress(unsigned long SubTotal); 59 : void SubProgress(unsigned long SubTotal,const string &Op); 60 : void OverallProgress(unsigned long Current,unsigned long Total, 61 : unsigned long Size,const string &Op); 62 62 : virtual void Done() {}; 63 : 64 : OpProgress(); 65 29 : virtual ~OpProgress() {}; 66 : }; 67 : 68 : class OpTextProgress : public OpProgress 69 : { 70 : protected: 71 : 72 : string OldOp; 73 : bool NoUpdate; 74 : bool NoDisplay; 75 : unsigned long LastLen; 76 : virtual void Update(); 77 : void Write(const char *S); 78 : 79 : public: 80 : 81 : virtual void Done(); 82 : 83 : OpTextProgress(bool NoUpdate = false) : NoUpdate(NoUpdate), 84 : NoDisplay(false), LastLen(0) {}; 85 : OpTextProgress(Configuration &Config); 86 : virtual ~OpTextProgress() {Done();}; 87 : }; 88 : 89 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: cpp; mode: fold -*- 2 : // Description /*{{{*/ 3 : // $Id: pkgcache.h,v 1.25 2001/07/01 22:28:24 jgg Exp $ 4 : /* ###################################################################### 5 : 6 : Cache - Structure definitions for the cache file 7 : 8 : Please see doc/apt-pkg/cache.sgml for a more detailed description of 9 : this format. Also be sure to keep that file up-to-date!! 10 : 11 : Clients should always use the CacheIterators classes for access to the 12 : cache. They provide a simple STL-like method for traversing the links 13 : of the datastructure. 14 : 15 : See pkgcachegen.h for information about generating cache structures. 16 : 17 : ##################################################################### */ 18 : /*}}}*/ 19 : #ifndef PKGLIB_PKGCACHE_H 20 : #define PKGLIB_PKGCACHE_H 21 : 22 : 23 : #include <string> 24 : #include <time.h> 25 : #include <apt-pkg/mmap.h> 26 : 27 : using std::string; 28 : 29 : class pkgVersioningSystem; 30 : class pkgCache 31 : { 32 : public: 33 : // Cache element predeclarations 34 : struct Header; 35 : struct Package; 36 : struct PackageFile; 37 : struct Version; 38 : struct Description; 39 : struct Provides; 40 : struct Dependency; 41 : struct StringItem; 42 : struct VerFile; 43 : struct DescFile; 44 : 45 : // Iterators 46 : class PkgIterator; 47 : class VerIterator; 48 : class DescIterator; 49 : class DepIterator; 50 : class PrvIterator; 51 : class PkgFileIterator; 52 : class VerFileIterator; 53 : class DescFileIterator; 54 : friend class PkgIterator; 55 : friend class VerIterator; 56 : friend class DescInterator; 57 : friend class DepIterator; 58 : friend class PrvIterator; 59 : friend class PkgFileIterator; 60 : friend class VerFileIterator; 61 : friend class DescFileIterator; 62 : 63 : class Namespace; 64 : 65 : // These are all the constants used in the cache structures 66 : 67 : // WARNING - if you change these lists you must also edit 68 : // the stringification in pkgcache.cc and also consider whether 69 : // the cache file will become incompatible. 70 : struct Dep 71 : { 72 : enum DepType {Depends=1,PreDepends=2,Suggests=3,Recommends=4, 73 : Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8}; 74 : enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3, 75 : Greater=0x4,Equals=0x5,NotEquals=0x6}; 76 : }; 77 : 78 : struct State 79 : { 80 : enum VerPriority {Important=1,Required=2,Standard=3,Optional=4,Extra=5}; 81 : enum PkgSelectedState {Unknown=0,Install=1,Hold=2,DeInstall=3,Purge=4}; 82 : enum PkgInstState {Ok=0,ReInstReq=1,HoldInst=2,HoldReInstReq=3}; 83 : enum PkgCurrentState {NotInstalled=0,UnPacked=1,HalfConfigured=2, 84 : HalfInstalled=4,ConfigFiles=5,Installed=6, 85 : TriggersAwaited=7,TriggersPending=8}; 86 : }; 87 : 88 : struct Flag 89 : { 90 : enum PkgFlags {Auto=(1<<0),Essential=(1<<3),Important=(1<<4)}; 91 : enum PkgFFlags {NotSource=(1<<0),NotAutomatic=(1<<1)}; 92 : }; 93 : 94 : protected: 95 : 96 : // Memory mapped cache file 97 : string CacheFile; 98 : MMap ⤅ 99 : 100 : unsigned long sHash(const string &S) const; 101 : unsigned long sHash(const char *S) const; 102 : 103 : public: 104 : 105 : // Pointers to the arrays of items 106 : Header *HeaderP; 107 : Package *PkgP; 108 : VerFile *VerFileP; 109 : DescFile *DescFileP; 110 : PackageFile *PkgFileP; 111 : Version *VerP; 112 : Description *DescP; 113 : Provides *ProvideP; 114 : Dependency *DepP; 115 : StringItem *StringItemP; 116 : char *StrP; 117 : 118 : virtual bool ReMap(); 119 : inline bool Sync() {return Map.Sync();}; 120 : inline MMap &GetMap() {return Map;}; 121 : inline void *DataEnd() {return ((unsigned char *)Map.Data()) + Map.Size();}; 122 : 123 : // String hashing function (512 range) 124 : inline unsigned long Hash(const string &S) const {return sHash(S);}; 125 : inline unsigned long Hash(const char *S) const {return sHash(S);}; 126 : 127 : // Usefull transformation things 128 : const char *Priority(unsigned char Priority); 129 : 130 : // Accessors 131 : PkgIterator FindPkg(const string &Name); 132 : Header &Head() {return *HeaderP;}; 133 : inline PkgIterator PkgBegin(); 134 : inline PkgIterator PkgEnd(); 135 : inline PkgFileIterator FileBegin(); 136 : inline PkgFileIterator FileEnd(); 137 : 138 : // Make me a function 139 : pkgVersioningSystem *VS; 140 : 141 : // Converters 142 : static const char *CompTypeDeb(unsigned char Comp); 143 : static const char *CompType(unsigned char Comp); 144 : static const char *DepType(unsigned char Dep); 145 : 146 : pkgCache(MMap *Map,bool DoMap = true); 147 : virtual ~pkgCache() {}; 148 : }; 149 : 150 : // Header structure 151 : struct pkgCache::Header 152 : { 153 : // Signature information 154 : unsigned long Signature; 155 : short MajorVersion; 156 : short MinorVersion; 157 : bool Dirty; 158 : 159 : // Size of structure values 160 : unsigned short HeaderSz; 161 : unsigned short PackageSz; 162 : unsigned short PackageFileSz; 163 : unsigned short VersionSz; 164 : unsigned short DescriptionSz; 165 : unsigned short DependencySz; 166 : unsigned short ProvidesSz; 167 : unsigned short VerFileSz; 168 : unsigned short DescFileSz; 169 : 170 : // Structure counts 171 : unsigned long PackageCount; 172 : unsigned long VersionCount; 173 : unsigned long DescriptionCount; 174 : unsigned long DependsCount; 175 : unsigned long PackageFileCount; 176 : unsigned long VerFileCount; 177 : unsigned long DescFileCount; 178 : unsigned long ProvidesCount; 179 : 180 : // Offsets 181 : map_ptrloc FileList; // struct PackageFile 182 : map_ptrloc StringList; // struct StringItem 183 : map_ptrloc VerSysName; // StringTable 184 : map_ptrloc Architecture; // StringTable 185 : unsigned long MaxVerFileSize; 186 : unsigned long MaxDescFileSize; 187 : 188 : /* Allocation pools, there should be one of these for each structure 189 : excluding the header */ 190 : DynamicMMap::Pool Pools[8]; 191 : 192 : // Rapid package name lookup 193 : map_ptrloc HashTable[2*1048]; 194 : 195 : bool CheckSizes(Header &Against) const; 196 : Header(); 197 : }; 198 : 199 : struct pkgCache::Package 200 : { 201 : // Pointers 202 : map_ptrloc Name; // Stringtable 203 : map_ptrloc VersionList; // Version 204 : map_ptrloc CurrentVer; // Version 205 : map_ptrloc Section; // StringTable (StringItem) 206 : 207 : // Linked list 208 : map_ptrloc NextPackage; // Package 209 : map_ptrloc RevDepends; // Dependency 210 : map_ptrloc ProvidesList; // Provides 211 : 212 : // Install/Remove/Purge etc 213 : unsigned char SelectedState; // What 214 : unsigned char InstState; // Flags 215 : unsigned char CurrentState; // State 216 : 217 : unsigned short ID; 218 : unsigned long Flags; 219 : }; 220 : 221 : struct pkgCache::PackageFile 222 : { 223 : // Names 224 : map_ptrloc FileName; // Stringtable 225 : map_ptrloc Archive; // Stringtable 226 : map_ptrloc Component; // Stringtable 227 : map_ptrloc Version; // Stringtable 228 : map_ptrloc Origin; // Stringtable 229 : map_ptrloc Label; // Stringtable 230 : map_ptrloc Architecture; // Stringtable 231 : map_ptrloc Site; // Stringtable 232 : map_ptrloc IndexType; // Stringtable 233 : unsigned long Size; 234 : unsigned long Flags; 235 : 236 : // Linked list 237 : map_ptrloc NextFile; // PackageFile 238 : unsigned short ID; 239 : time_t mtime; // Modification time for the file 240 : }; 241 : 242 : struct pkgCache::VerFile 243 : { 244 : map_ptrloc File; // PackageFile 245 : map_ptrloc NextFile; // PkgVerFile 246 : map_ptrloc Offset; // File offset 247 : unsigned short Size; 248 : }; 249 : 250 : struct pkgCache::DescFile 251 : { 252 : map_ptrloc File; // PackageFile 253 : map_ptrloc NextFile; // PkgVerFile 254 : map_ptrloc Offset; // File offset 255 : unsigned short Size; 256 : }; 257 : 258 : struct pkgCache::Version 259 : { 260 : map_ptrloc VerStr; // Stringtable 261 : map_ptrloc Section; // StringTable (StringItem) 262 : map_ptrloc Arch; // StringTable 263 : 264 : // Lists 265 : map_ptrloc FileList; // VerFile 266 : map_ptrloc NextVer; // Version 267 : map_ptrloc DescriptionList; // Description 268 : map_ptrloc DependsList; // Dependency 269 : map_ptrloc ParentPkg; // Package 270 : map_ptrloc ProvidesList; // Provides 271 : 272 : map_ptrloc Size; // These are the .deb size 273 : map_ptrloc InstalledSize; 274 : unsigned short Hash; 275 : unsigned short ID; 276 : unsigned char Priority; 277 : }; 278 : 279 : struct pkgCache::Description 280 : { 281 : // Language Code store the description translation language code. If 282 : // the value has a 0 lenght then this is readed using the Package 283 : // file else the Translation-CODE are used. 284 : map_ptrloc language_code; // StringTable 285 : map_ptrloc md5sum; // StringTable 286 : 287 : // Linked list 288 : map_ptrloc FileList; // DescFile 289 : map_ptrloc NextDesc; // Description 290 : map_ptrloc ParentPkg; // Package 291 : 292 : unsigned short ID; 293 : }; 294 : 295 : struct pkgCache::Dependency 296 : { 297 : map_ptrloc Version; // Stringtable 298 : map_ptrloc Package; // Package 299 : map_ptrloc NextDepends; // Dependency 300 : map_ptrloc NextRevDepends; // Dependency 301 : map_ptrloc ParentVer; // Version 302 : 303 : // Specific types of depends 304 : map_ptrloc ID; 305 : unsigned char Type; 306 : unsigned char CompareOp; 307 : }; 308 : 309 : struct pkgCache::Provides 310 : { 311 : map_ptrloc ParentPkg; // Pacakge 312 : map_ptrloc Version; // Version 313 : map_ptrloc ProvideVersion; // Stringtable 314 : map_ptrloc NextProvides; // Provides 315 : map_ptrloc NextPkgProv; // Provides 316 : }; 317 : 318 : struct pkgCache::StringItem 319 : { 320 : map_ptrloc String; // Stringtable 321 : map_ptrloc NextItem; // StringItem 322 : }; 323 : 324 : #include <apt-pkg/cacheiterators.h> 325 : 326 19 : inline pkgCache::PkgIterator pkgCache::PkgBegin() 327 19 : {return PkgIterator(*this);}; 328 : inline pkgCache::PkgIterator pkgCache::PkgEnd() 329 : {return PkgIterator(*this,PkgP);}; 330 : inline pkgCache::PkgFileIterator pkgCache::FileBegin() 331 : {return PkgFileIterator(*this,PkgFileP + HeaderP->FileList);}; 332 : inline pkgCache::PkgFileIterator pkgCache::FileEnd() 333 : {return PkgFileIterator(*this,PkgFileP);}; 334 : 335 : // Oh I wish for Real Name Space Support 336 : class pkgCache::Namespace 337 : { 338 : public: 339 : 340 : typedef pkgCache::PkgIterator PkgIterator; 341 : typedef pkgCache::VerIterator VerIterator; 342 : typedef pkgCache::DescIterator DescIterator; 343 : typedef pkgCache::DepIterator DepIterator; 344 : typedef pkgCache::PrvIterator PrvIterator; 345 : typedef pkgCache::PkgFileIterator PkgFileIterator; 346 : typedef pkgCache::VerFileIterator VerFileIterator; 347 : typedef pkgCache::Version Version; 348 : typedef pkgCache::Description Description; 349 : typedef pkgCache::Package Package; 350 : typedef pkgCache::Header Header; 351 : typedef pkgCache::Dep Dep; 352 : typedef pkgCache::Flag Flag; 353 : }; 354 : 355 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : // -*- mode: c++; mode: fold -*- 2 : // Description /*{{{*/ 3 : // $Id: depcache.h,v 1.14 2001/02/20 07:03:17 jgg Exp $ 4 : /* ###################################################################### 5 : 6 : DepCache - Dependency Extension data for the cache 7 : 8 : This class stores the cache data and a set of extension structures for 9 : monitoring the current state of all the packages. It also generates and 10 : caches the 'install' state of many things. This refers to the state of the 11 : package after an install has been run. 12 : 13 : The StateCache::State field can be -1,0,1,2 which is <,=,>,no current. 14 : StateCache::Mode is which of the 3 fields is active. 15 : 16 : This structure is important to support the readonly status of the cache 17 : file. When the data is saved the cache will be refereshed from our 18 : internal rep and written to disk. Then the actual persistant data 19 : files will be put on the disk. 20 : 21 : Each dependency is compared against 3 target versions to produce to 22 : 3 dependency results. 23 : Now - Compared using the Currently install version 24 : Install - Compared using the install version (final state) 25 : CVer - (Candidate Verion) Compared using the Candidate Version 26 : The candidate and now results are used to decide wheather a package 27 : should be automatically installed or if it should be left alone. 28 : 29 : Remember, the Candidate Version is selected based on the distribution 30 : settings for the Package. The Install Version is selected based on the 31 : state (Delete, Keep, Install) field and can be either the Current Version 32 : or the Candidate version. 33 : 34 : The Candidate version is what is shown the 'Install Version' field. 35 : 36 : ##################################################################### */ 37 : /*}}}*/ 38 : #ifndef PKGLIB_DEPCACHE_H 39 : #define PKGLIB_DEPCACHE_H 40 : 41 : 42 : #include <apt-pkg/pkgcache.h> 43 : #include <apt-pkg/progress.h> 44 : 45 : #include <regex.h> 46 : 47 : #include <vector> 48 : #include <memory> 49 : 50 : class pkgDepCache : protected pkgCache::Namespace 51 : { 52 : public: 53 : 54 : /** \brief An arbitrary predicate on packages. */ 55 : class InRootSetFunc 56 : { 57 : public: 58 : virtual bool InRootSet(const pkgCache::PkgIterator &pkg) {return false;}; 59 : virtual ~InRootSetFunc() {}; 60 : }; 61 : 62 : private: 63 : /** \brief Mark a single package and all its unmarked important 64 : * dependencies during mark-and-sweep. 65 : * 66 : * Recursively invokes itself to mark all dependencies of the 67 : * package. 68 : * 69 : * \param pkg The package to mark. 70 : * 71 : * \param ver The version of the package that is to be marked. 72 : * 73 : * \param follow_recommends If \b true, recommendations of the 74 : * package will be recursively marked. 75 : * 76 : * \param follow_suggests If \b true, suggestions of the package 77 : * will be recursively marked. 78 : */ 79 : void MarkPackage(const pkgCache::PkgIterator &pkg, 80 : const pkgCache::VerIterator &ver, 81 : bool follow_recommends, 82 : bool follow_suggests); 83 : 84 : /** \brief Update the Marked field of all packages. 85 : * 86 : * Each package's StateCache::Marked field will be set to \b true 87 : * if and only if it can be reached from the root set. By 88 : * default, the root set consists of the set of manually installed 89 : * or essential packages, but it can be extended using the 90 : * parameter #rootFunc. 91 : * 92 : * \param rootFunc A callback that can be used to add extra 93 : * packages to the root set. 94 : * 95 : * \return \b false if an error occurred. 96 : */ 97 : bool MarkRequired(InRootSetFunc &rootFunc); 98 : 99 : /** \brief Set the StateCache::Garbage flag on all packages that 100 : * should be removed. 101 : * 102 : * Packages that were not marked by the last call to #MarkRequired 103 : * are tested to see whether they are actually garbage. If so, 104 : * they are marked as such. 105 : * 106 : * \return \b false if an error occurred. 107 : */ 108 : bool Sweep(); 109 : 110 : public: 111 : 112 : // These flags are used in DepState 113 : enum DepFlags {DepNow = (1 << 0),DepInstall = (1 << 1),DepCVer = (1 << 2), 114 : DepGNow = (1 << 3),DepGInstall = (1 << 4),DepGCVer = (1 << 5)}; 115 : 116 : // These flags are used in StateCache::DepState 117 : enum DepStateFlags {DepNowPolicy = (1 << 0), DepNowMin = (1 << 1), 118 : DepInstPolicy = (1 << 2), DepInstMin = (1 << 3), 119 : DepCandPolicy = (1 << 4), DepCandMin = (1 << 5)}; 120 : 121 : // These flags are used in StateCache::iFlags 122 : enum InternalFlags {AutoKept = (1 << 0), Purge = (1 << 1), ReInstall = (1 << 2)}; 123 : 124 : enum VersionTypes {NowVersion, InstallVersion, CandidateVersion}; 125 : enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2}; 126 : 127 : /** \brief Represents an active action group. 128 : * 129 : * An action group is a group of actions that are currently being 130 : * performed. While an active group is active, certain routine 131 : * clean-up actions that would normally be performed after every 132 : * cache operation are delayed until the action group is 133 : * completed. This is necessary primarily to avoid inefficiencies 134 : * when modifying a large number of packages at once. 135 : * 136 : * This class represents an active action group. Creating an 137 : * instance will create an action group; destroying one will 138 : * destroy the corresponding action group. 139 : * 140 : * The following operations are suppressed by this class: 141 : * 142 : * - Keeping the Marked and Garbage flags up to date. 143 : * 144 : * \note This can be used in the future to easily accumulate 145 : * atomic actions for undo or to display "what apt did anyway"; 146 : * e.g., change the counter of how many action groups are active 147 : * to a std::set of pointers to them and use those to store 148 : * information about what happened in a group in the group. 149 : */ 150 : class ActionGroup 151 : { 152 : pkgDepCache &cache; 153 : 154 : bool released; 155 : 156 : /** Action groups are noncopyable. */ 157 : ActionGroup(const ActionGroup &other); 158 : public: 159 : /** \brief Create a new ActionGroup. 160 : * 161 : * \param cache The cache that this ActionGroup should 162 : * manipulate. 163 : * 164 : * As long as this object exists, no automatic cleanup 165 : * operations will be undertaken. 166 : */ 167 : ActionGroup(pkgDepCache &cache); 168 : 169 : /** \brief Clean up the action group before it is destroyed. 170 : * 171 : * If it is destroyed later, no second cleanup wil be run. 172 : */ 173 : void release(); 174 : 175 : /** \brief Destroy the action group. 176 : * 177 : * If this is the last action group, the automatic cache 178 : * cleanup operations will be undertaken. 179 : */ 180 : ~ActionGroup(); 181 : }; 182 : 183 : /** \brief Returns \b true for packages matching a regular 184 : * expression in APT::NeverAutoRemove. 185 : */ 186 : class DefaultRootSetFunc : public InRootSetFunc 187 : { 188 : std::vector<regex_t *> rootSetRegexp; 189 : bool constructedSuccessfully; 190 : 191 : public: 192 : DefaultRootSetFunc(); 193 : ~DefaultRootSetFunc(); 194 : 195 : /** \return \b true if the class initialized successfully, \b 196 : * false otherwise. Used to avoid throwing an exception, since 197 : * APT classes generally don't. 198 : */ 199 : bool wasConstructedSuccessfully() const { return constructedSuccessfully; } 200 : 201 : bool InRootSet(const pkgCache::PkgIterator &pkg); 202 : }; 203 : 204 : struct StateCache 205 : { 206 : // Epoch stripped text versions of the two version fields 207 : const char *CandVersion; 208 : const char *CurVersion; 209 : 210 : // Pointer to the candidate install version. 211 : Version *CandidateVer; 212 : 213 : // Pointer to the install version. 214 : Version *InstallVer; 215 : 216 : // Copy of Package::Flags 217 : unsigned short Flags; 218 : unsigned short iFlags; // Internal flags 219 : 220 : /** \brief \b true if this package can be reached from the root set. */ 221 : bool Marked; 222 : 223 : /** \brief \b true if this package is unused and should be removed. 224 : * 225 : * This differs from !#Marked, because it is possible that some 226 : * unreachable packages will be protected from becoming 227 : * garbage. 228 : */ 229 : bool Garbage; 230 : 231 : // Various tree indicators 232 : signed char Status; // -1,0,1,2 233 : unsigned char Mode; // ModeList 234 : unsigned char DepState; // DepState Flags 235 : 236 : // Update of candidate version 237 : const char *StripEpoch(const char *Ver); 238 : void Update(PkgIterator Pkg,pkgCache &Cache); 239 : 240 : // Various test members for the current status of the package 241 : inline bool NewInstall() const {return Status == 2 && Mode == ModeInstall;}; 242 3785 : inline bool Delete() const {return Mode == ModeDelete;}; 243 3785 : inline bool Keep() const {return Mode == ModeKeep;}; 244 : inline bool Upgrade() const {return Status > 0 && Mode == ModeInstall;}; 245 : inline bool Upgradable() const {return Status >= 1;}; 246 : inline bool Downgrade() const {return Status < 0 && Mode == ModeInstall;}; 247 : inline bool Held() const {return Status != 0 && Keep();}; 248 3785 : inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;}; 249 : inline bool NowPolicyBroken() const {return (DepState & DepNowPolicy) != DepNowPolicy;}; 250 3785 : inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;}; 251 : inline bool InstPolicyBroken() const {return (DepState & DepInstPolicy) != DepInstPolicy;}; 252 3785 : inline bool Install() const {return Mode == ModeInstall;}; 253 : inline VerIterator InstVerIter(pkgCache &Cache) 254 : {return VerIterator(Cache,InstallVer);}; 255 : inline VerIterator CandidateVerIter(pkgCache &Cache) 256 : {return VerIterator(Cache,CandidateVer);}; 257 : }; 258 : 259 : // Helper functions 260 : void BuildGroupOrs(VerIterator const &V); 261 : void UpdateVerState(PkgIterator Pkg); 262 : 263 : // User Policy control 264 : class Policy 265 : { 266 : public: 267 : 268 : virtual VerIterator GetCandidateVer(PkgIterator Pkg); 269 : virtual bool IsImportantDep(DepIterator Dep); 270 : 271 : virtual ~Policy() {}; 272 : }; 273 : 274 : private: 275 : /** The number of open "action groups"; certain post-action 276 : * operations are suppressed if this number is > 0. 277 : */ 278 : int group_level; 279 : 280 : friend class ActionGroup; 281 : 282 : protected: 283 : 284 : // State information 285 : pkgCache *Cache; 286 : StateCache *PkgState; 287 : unsigned char *DepState; 288 : 289 : double iUsrSize; 290 : double iDownloadSize; 291 : unsigned long iInstCount; 292 : unsigned long iDelCount; 293 : unsigned long iKeepCount; 294 : unsigned long iBrokenCount; 295 : unsigned long iPolicyBrokenCount; 296 : unsigned long iBadCount; 297 : 298 : Policy *delLocalPolicy; // For memory clean up.. 299 : Policy *LocalPolicy; 300 : 301 : // Check for a matching provides 302 : bool CheckDep(DepIterator Dep,int Type,PkgIterator &Res); 303 : inline bool CheckDep(DepIterator Dep,int Type) 304 : { 305 : PkgIterator Res(*this,0); 306 : return CheckDep(Dep,Type,Res); 307 : } 308 : 309 : // Computes state information for deps and versions (w/o storing) 310 : unsigned char DependencyState(DepIterator &D); 311 : unsigned char VersionState(DepIterator D,unsigned char Check, 312 : unsigned char SetMin, 313 : unsigned char SetPolicy); 314 : 315 : // Recalculates various portions of the cache, call after changing something 316 : void Update(DepIterator Dep); // Mostly internal 317 : void Update(PkgIterator const &P); 318 : 319 : // Count manipulators 320 : void AddSizes(const PkgIterator &Pkg,signed long Mult = 1); 321 : inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg,-1);}; 322 : void AddStates(const PkgIterator &Pkg,int Add = 1); 323 : inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,-1);}; 324 : 325 : public: 326 : 327 : // Legacy.. We look like a pkgCache 328 : inline operator pkgCache &() {return *Cache;}; 329 : inline Header &Head() {return *Cache->HeaderP;}; 330 : inline PkgIterator PkgBegin() {return Cache->PkgBegin();}; 331 : inline PkgIterator FindPkg(string const &Name) {return Cache->FindPkg(Name);}; 332 : 333 : inline pkgCache &GetCache() {return *Cache;}; 334 : inline pkgVersioningSystem &VS() {return *Cache->VS;}; 335 : 336 : // Policy implementation 337 : inline VerIterator GetCandidateVer(PkgIterator Pkg) {return LocalPolicy->GetCandidateVer(Pkg);}; 338 : inline bool IsImportantDep(DepIterator Dep) {return LocalPolicy->IsImportantDep(Dep);}; 339 : inline Policy &GetPolicy() {return *LocalPolicy;}; 340 : 341 : // Accessors 342 3787 : inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];}; 343 : inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];}; 344 : 345 : /** \return A function identifying packages in the root set other 346 : * than manually installed packages and essential packages, or \b 347 : * NULL if an error occurs. 348 : * 349 : * \todo Is this the best place for this function? Perhaps the 350 : * settings for mark-and-sweep should be stored in a single 351 : * external class? 352 : */ 353 : virtual InRootSetFunc *GetRootSetFunc(); 354 : 355 : /** \return \b true if the garbage collector should follow recommendations. 356 : */ 357 : virtual bool MarkFollowsRecommends(); 358 : 359 : /** \return \b true if the garbage collector should follow suggestions. 360 : */ 361 : virtual bool MarkFollowsSuggests(); 362 : 363 : /** \brief Update the Marked and Garbage fields of all packages. 364 : * 365 : * This routine is implicitly invoked after all state manipulators 366 : * and when an ActionGroup is destroyed. It invokes #MarkRequired 367 : * and #Sweep to do its dirty work. 368 : * 369 : * \param rootFunc A predicate that returns \b true for packages 370 : * that should be added to the root set. 371 : */ 372 : bool MarkAndSweep(InRootSetFunc &rootFunc) 373 : { 374 : return MarkRequired(rootFunc) && Sweep(); 375 : } 376 : 377 : bool MarkAndSweep() 378 : { 379 : std::auto_ptr<InRootSetFunc> f(GetRootSetFunc()); 380 : if(f.get() != NULL) 381 : return MarkAndSweep(*f.get()); 382 : else 383 : return false; 384 : } 385 : 386 : /** \name State Manipulators 387 : */ 388 : // @{ 389 : void MarkKeep(PkgIterator const &Pkg, bool Soft = false, 390 : bool FromUser = true); 391 : void MarkDelete(PkgIterator const &Pkg,bool Purge = false); 392 : void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true, 393 : unsigned long Depth = 0, bool FromUser = true, 394 : bool ForceImportantDeps = false); 395 : void SetReInstall(PkgIterator const &Pkg,bool To); 396 : void SetCandidateVersion(VerIterator TargetVer); 397 : 398 : /** Set the "is automatically installed" flag of Pkg. */ 399 : void MarkAuto(const PkgIterator &Pkg, bool Auto); 400 : // @} 401 : 402 : // This is for debuging 403 : void Update(OpProgress *Prog = 0); 404 : 405 : // read persistent states 406 : bool readStateFile(OpProgress *prog); 407 : bool writeStateFile(OpProgress *prog, bool InstalledOnly=false); 408 : 409 : // Size queries 410 : inline double UsrSize() {return iUsrSize;}; 411 : inline double DebSize() {return iDownloadSize;}; 412 : inline unsigned long DelCount() {return iDelCount;}; 413 : inline unsigned long KeepCount() {return iKeepCount;}; 414 : inline unsigned long InstCount() {return iInstCount;}; 415 : inline unsigned long BrokenCount() {return iBrokenCount;}; 416 : inline unsigned long PolicyBrokenCount() {return iPolicyBrokenCount;}; 417 : inline unsigned long BadCount() {return iBadCount;}; 418 : 419 : bool Init(OpProgress *Prog); 420 : 421 : pkgDepCache(pkgCache *Cache,Policy *Plcy = 0); 422 : virtual ~pkgDepCache(); 423 : }; 424 : 425 : #endif |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** \file database.h 2 : * \brief API for working with Xapian databases 3 : */ 4 : /* Copyright 1999,2000,2001 BrightStation PLC 5 : * Copyright 2002 Ananova Ltd 6 : * Copyright 2002,2003,2004,2005,2006,2007 Olly Betts 7 : * Copyright 2006 Richard Boulton 8 : * 9 : * This program is free software; you can redistribute it and/or 10 : * modify it under the terms of the GNU General Public License as 11 : * published by the Free Software Foundation; either version 2 of the 12 : * License, or (at your option) any later version. 13 : * 14 : * This program is distributed in the hope that it will be useful, 15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : * GNU General Public License for more details. 18 : * 19 : * You should have received a copy of the GNU General Public License 20 : * along with this program; if not, write to the Free Software 21 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 22 : * USA 23 : */ 24 : 25 : #ifndef XAPIAN_INCLUDED_DATABASE_H 26 : #define XAPIAN_INCLUDED_DATABASE_H 27 : 28 : #include <string> 29 : #include <vector> 30 : 31 : #include <xapian/base.h> 32 : #include <xapian/types.h> 33 : #include <xapian/positioniterator.h> 34 : #include <xapian/postingiterator.h> 35 : #include <xapian/termiterator.h> 36 : #include <xapian/visibility.h> 37 : 38 : /// The Xapian library lives in the Xapian namespace. 39 : namespace Xapian { 40 : 41 : class Document; 42 : 43 : /** This class is used to access a database, or a group of databases. 44 : * 45 : * For searching, this class is used in conjunction with an Enquire object. 46 : * 47 : * @exception InvalidArgumentError will be thrown if an invalid 48 : * argument is supplied, for example, an unknown database type. 49 : * 50 : * @exception DatabaseOpeningError may be thrown if the database cannot 51 : * be opened (for example, a required file cannot be found). 52 : * 53 : * @exception DatabaseVersionError may be thrown if the database is in an 54 : * unsupported format (for example, created by a newer version of Xapian 55 : * which uses an incompatible format). 56 : */ 57 : class XAPIAN_VISIBILITY_DEFAULT Database { 58 : public: 59 : class Internal; 60 : /// @private @internal Reference counted internals. 61 : std::vector<Xapian::Internal::RefCntPtr<Internal> > internal; 62 : 63 : /** Add an existing database (or group of databases) to those 64 : * accessed by this object. 65 : * 66 : * @param database the database(s) to add. 67 : */ 68 : void add_database(const Database & database); 69 : 70 : /** Create a Database with no databases in. 71 : */ 72 : Database(); 73 : 74 : /** Open a Database, automatically determining the database 75 : * backend to use. 76 : * 77 : * @param path directory that the database is stored in. 78 : */ 79 : explicit Database(const std::string &path); 80 : 81 : /** @private @internal Create a Database from its internals. 82 : */ 83 : explicit Database(Internal *internal); 84 : 85 : /** Destroy this handle on the database. 86 : * 87 : * If there are no copies of this object remaining, the database(s) 88 : * will be closed. 89 : */ 90 : virtual ~Database(); 91 : 92 : /** Copying is allowed. The internals are reference counted, so 93 : * copying is cheap. 94 : */ 95 : Database(const Database &other); 96 : 97 : /** Assignment is allowed. The internals are reference counted, 98 : * so assignment is cheap. 99 : */ 100 : void operator=(const Database &other); 101 : 102 : /** Re-open the database. 103 : * This re-opens the database(s) to the latest available version(s). 104 : * It can be used either to make sure the latest results are 105 : * returned, or to recover from a Xapian::DatabaseModifiedError. 106 : */ 107 : void reopen(); 108 : 109 : /// Return a string describing this object. 110 : virtual std::string get_description() const; 111 : 112 : /** An iterator pointing to the start of the postlist 113 : * for a given term. 114 : * 115 : * If the term name is the empty string, the iterator returned 116 : * will list all the documents in the database. Such an iterator 117 : * will always return a WDF value of 1, since there is no obvious 118 : * meaning for this quantity in this case. 119 : */ 120 : PostingIterator postlist_begin(const std::string &tname) const; 121 : 122 : /** Corresponding end iterator to postlist_begin(). 123 : */ 124 10 : PostingIterator postlist_end(const std::string &) const { 125 10 : return PostingIterator(NULL); 126 : } 127 : 128 : /** An iterator pointing to the start of the termlist 129 : * for a given document. 130 : */ 131 : TermIterator termlist_begin(Xapian::docid did) const; 132 : 133 : /** Corresponding end iterator to termlist_begin(). 134 : */ 135 : TermIterator termlist_end(Xapian::docid) const { 136 : return TermIterator(NULL); 137 : } 138 : 139 : /** Does this database have any positional information? */ 140 : bool has_positions() const; 141 : 142 : /** An iterator pointing to the start of the position list 143 : * for a given term in a given document. 144 : */ 145 : PositionIterator positionlist_begin(Xapian::docid did, const std::string &tname) const; 146 : 147 : /** Corresponding end iterator to positionlist_begin(). 148 : */ 149 : PositionIterator positionlist_end(Xapian::docid, const std::string &) const { 150 : return PositionIterator(NULL); 151 : } 152 : 153 : /** An iterator which runs across all terms in the database. 154 : */ 155 : TermIterator allterms_begin() const; 156 : 157 : /** Corresponding end iterator to allterms_begin(). 158 : */ 159 : TermIterator allterms_end() const { 160 : return TermIterator(NULL); 161 : } 162 : 163 : /** An iterator which runs across all terms with a given prefix. 164 : * 165 : * This is functionally similar to getting an iterator with 166 : * allterms_begin() and then calling skip_to(prefix) on that iterator 167 : * to move to the start of the prefix, but is more convenient (because 168 : * it detects the end of the prefixed terms), and may be more 169 : * efficient than simply calling skip_to() after opening the iterator, 170 : * particularly for network databases. 171 : * 172 : * @param prefix The prefix to restrict the returned terms to. 173 : */ 174 : TermIterator allterms_begin(const std::string & prefix) const; 175 : 176 : /** Corresponding end iterator to allterms_begin(prefix). 177 : */ 178 1 : TermIterator allterms_end(const std::string &) const { 179 1 : return TermIterator(NULL); 180 : } 181 : 182 : /// Get the number of documents in the database. 183 : Xapian::doccount get_doccount() const; 184 : 185 : /// Get the highest document id which has been used in the database. 186 : Xapian::docid get_lastdocid() const; 187 : 188 : /// Get the average length of the documents in the database. 189 : Xapian::doclength get_avlength() const; 190 : 191 : /// Get the number of documents in the database indexed by a given term. 192 : Xapian::doccount get_termfreq(const std::string & tname) const; 193 : 194 : /** Check if a given term exists in the database. 195 : * 196 : * Return true if and only if the term exists in the database. 197 : * This is the same as (get_termfreq(tname) != 0), but will often be 198 : * more efficient. 199 : */ 200 : bool term_exists(const std::string & tname) const; 201 : 202 : /** Return the total number of occurrences of the given term. 203 : * 204 : * This is the sum of the number of occurrences of the term in each 205 : * document it indexes: i.e., the sum of the within document 206 : * frequencies of the term. 207 : * 208 : * @param tname The term whose collection frequency is being 209 : * requested. 210 : */ 211 : Xapian::termcount get_collection_freq(const std::string & tname) const; 212 : 213 : /** Get the length of a document. 214 : */ 215 : Xapian::doclength get_doclength(Xapian::docid did) const; 216 : 217 : /** Send a "keep-alive" to remote databases to stop them timing 218 : * out. 219 : */ 220 : void keep_alive(); 221 : 222 : /** Get a document from the database, given its document id. 223 : * 224 : * This method returns a Xapian::Document object which provides the 225 : * information about a document. 226 : * 227 : * @param did The document id for which to retrieve the data. 228 : * 229 : * @return A Xapian::Document object containing the document data 230 : * 231 : * @exception Xapian::DocNotFoundError The document specified 232 : * could not be found in the database. 233 : */ 234 : Xapian::Document get_document(Xapian::docid did) const; 235 : 236 : /** Suggest a spelling correction. 237 : * 238 : * @param word The potentially misspelled word. 239 : * @param max_edit_distance Only consider words which are at most 240 : * @a max_edit_distance edits from @a word. An edit is a 241 : * character insertion, deletion, or the transposition of two 242 : * adjacent characters (default is 2). 243 : */ 244 : std::string get_spelling_suggestion(const std::string &word, 245 : unsigned max_edit_distance = 2) const; 246 : 247 : /** An iterator which returns all the spelling correction targets. 248 : * 249 : * This returns all the words which are considered as targets for the 250 : * spelling correction algorithm. The frequency of each word is 251 : * available as the term frequency of each entry in the returned 252 : * iterator. 253 : */ 254 : Xapian::TermIterator spellings_begin() const; 255 : 256 : /// Corresponding end iterator to spellings_begin(). 257 : Xapian::TermIterator spellings_end() const { 258 : return Xapian::TermIterator(NULL); 259 : } 260 : 261 : /** An iterator which returns all the synonyms for a given term. 262 : * 263 : * @param term The term to return synonyms for. 264 : */ 265 : Xapian::TermIterator synonyms_begin(const std::string &term) const; 266 : 267 : /// Corresponding end iterator to synonyms_begin(term). 268 : Xapian::TermIterator synonyms_end(const std::string &) const { 269 : return Xapian::TermIterator(NULL); 270 : } 271 : 272 : /** An iterator which returns all terms which have synonyms. 273 : * 274 : * @param prefix If non-empty, only terms with this prefix are 275 : * returned. 276 : */ 277 : Xapian::TermIterator synonym_keys_begin(const std::string &prefix = "") const; 278 : 279 : /// Corresponding end iterator to synonym_keys_begin(prefix). 280 : Xapian::TermIterator synonym_keys_end(const std::string & = "") const { 281 : return Xapian::TermIterator(NULL); 282 : } 283 : 284 : /** Get the user-specified metadata associated with a given key. 285 : * 286 : * User-specified metadata allows you to store arbitrary information 287 : * in the form of (key,tag) pairs. See @a 288 : * WritableDatabase::set_metadata() for more information. 289 : * 290 : * When invoked on a Xapian::Database object representing multiple 291 : * databases, currently only the metadata for the first is considered 292 : * but this behaviour may change in the future. 293 : * 294 : * If there is no piece of metadata associated with the specified 295 : * key, an empty string is returned (this applies even for backends 296 : * which don't support metadata). 297 : * 298 : * Empty keys are not valid, and specifying one will cause an 299 : * exception. 300 : * 301 : * @param key The key of the metadata item to access. 302 : * 303 : * @return The retrieved metadata item's value. 304 : * 305 : * @exception Xapian::InvalidArgumentError will be thrown if the 306 : * key supplied is empty. 307 : * 308 : * @exception Xapian::UnimplementedError will be thrown if the 309 : * database backend in use doesn't support user-specified 310 : * metadata. 311 : */ 312 : std::string get_metadata(const std::string & key) const; 313 : }; 314 : 315 : /** This class provides read/write access to a database. 316 : */ 317 : class XAPIAN_VISIBILITY_DEFAULT WritableDatabase : public Database { 318 : public: 319 : /** Destroy this handle on the database. 320 : * 321 : * If there are no copies of this object remaining, the database 322 : * will be closed. If there are any transactions in progress 323 : * these will be aborted as if cancel_transaction had been called. 324 : */ 325 : virtual ~WritableDatabase(); 326 : 327 : /** Create an empty WritableDatabase. 328 : */ 329 : WritableDatabase(); 330 : 331 : /** Open a database for update, automatically determining the database 332 : * backend to use. 333 : * 334 : * If the database is to be created, Xapian will try 335 : * to create the directory indicated by path if it doesn't already 336 : * exist (but only the leaf directory, not recursively). 337 : * 338 : * @param path directory that the database is stored in. 339 : * @param action one of: 340 : * - Xapian::DB_CREATE_OR_OPEN open for read/write; create if no db 341 : * exists 342 : * - Xapian::DB_CREATE create new database; fail if db exists 343 : * - Xapian::DB_CREATE_OR_OVERWRITE overwrite existing db; create if 344 : * none exists 345 : * - Xapian::DB_OPEN open for read/write; fail if no db exists 346 : */ 347 : WritableDatabase(const std::string &path, int action); 348 : 349 : /** @private @internal Create an WritableDatabase given its internals. 350 : */ 351 : explicit WritableDatabase(Database::Internal *internal); 352 : 353 : /** Copying is allowed. The internals are reference counted, so 354 : * copying is cheap. 355 : */ 356 : WritableDatabase(const WritableDatabase &other); 357 : 358 : /** Assignment is allowed. The internals are reference counted, 359 : * so assignment is cheap. 360 : * 361 : * Note that only an WritableDatabase may be assigned to an 362 : * WritableDatabase: an attempt to assign a Database is caught 363 : * at compile-time. 364 : */ 365 : void operator=(const WritableDatabase &other); 366 : 367 : /** Flush to disk any modifications made to the database. 368 : * 369 : * For efficiency reasons, when performing multiple updates to a 370 : * database it is best (indeed, almost essential) to make as many 371 : * modifications as memory will permit in a single pass through 372 : * the database. To ensure this, Xapian batches up modifications. 373 : * 374 : * Flush may be called at any time to 375 : * ensure that the modifications which have been made are written to 376 : * disk: if the flush succeeds, all the preceding modifications will 377 : * have been written to disk. 378 : * 379 : * If any of the modifications fail, an exception will be thrown and 380 : * the database will be left in a state in which each separate 381 : * addition, replacement or deletion operation has either been fully 382 : * performed or not performed at all: it is then up to the 383 : * application to work out which operations need to be repeated. 384 : * 385 : * It's not valid to call flush within a transaction. 386 : * 387 : * Beware of calling flush too frequently: this will have a severe 388 : * performance cost. 389 : * 390 : * Note that flush need not be called explicitly: it will be called 391 : * automatically when the database is closed, or when a sufficient 392 : * number of modifications have been made. 393 : * 394 : * @exception Xapian::DatabaseError will be thrown if a problem occurs 395 : * while modifying the database. 396 : * 397 : * @exception Xapian::DatabaseCorruptError will be thrown if the 398 : * database is in a corrupt state. 399 : * 400 : * @exception Xapian::DatabaseLockError will be thrown if a lock 401 : * couldn't be acquired on the database. 402 : */ 403 : void flush(); 404 : 405 : /** Begin a transaction. 406 : * 407 : * In Xapian a transaction is a group of modifications to the database 408 : * which are linked such that either all will be applied 409 : * simultaneously or none will be applied at all. Even in the case of 410 : * a power failure, this characteristic should be preserved (as long 411 : * as the filesystem isn't corrupted, etc). 412 : * 413 : * A transaction is started with begin_transaction() and can 414 : * either be committed by calling commit_transaction() or aborted 415 : * by calling cancel_transaction(). 416 : * 417 : * By default, a transaction implicitly calls flush before and after 418 : * so that the modifications stand and fall without affecting 419 : * modifications before or after. 420 : * 421 : * The downside of this flushing is that small transactions cause 422 : * modifications to be frequently flushed which can harm indexing 423 : * performance in the same way that explicitly calling flush 424 : * frequently can. 425 : * 426 : * If you're applying atomic groups of changes and only wish to 427 : * ensure that each group is either applied or not applied, then 428 : * you can prevent the automatic flush before and after the 429 : * transaction by starting the transaction with 430 : * begin_transaction(false). However, if cancel_transaction is 431 : * called (or if commit_transaction isn't called before the 432 : * WritableDatabase object is destroyed) then any changes which 433 : * were pending before the transaction began will also be discarded. 434 : * 435 : * Transactions aren't currently supported by the InMemory backend. 436 : * 437 : * @exception Xapian::UnimplementedError will be thrown if transactions 438 : * are not available for this database type. 439 : * 440 : * @exception Xapian::InvalidOperationError will be thrown if this is 441 : * called at an invalid time, such as when a transaction 442 : * is already in progress. 443 : */ 444 : void begin_transaction(bool flushed=true); 445 : 446 : /** Complete the transaction currently in progress. 447 : * 448 : * If this method completes successfully and this is a flushed 449 : * transaction, all the database modifications 450 : * made during the transaction will have been committed to the 451 : * database. 452 : * 453 : * If an error occurs, an exception will be thrown, and none of 454 : * the modifications made to the database during the transaction 455 : * will have been applied to the database. 456 : * 457 : * In all cases the transaction will no longer be in progress. 458 : * 459 : * @exception Xapian::DatabaseError will be thrown if a problem occurs 460 : * while modifying the database. 461 : * 462 : * @exception Xapian::DatabaseCorruptError will be thrown if the 463 : * database is in a corrupt state. 464 : * 465 : * @exception Xapian::InvalidOperationError will be thrown if a 466 : * transaction is not currently in progress. 467 : * 468 : * @exception Xapian::UnimplementedError will be thrown if transactions 469 : * are not available for this database type. 470 : */ 471 : void commit_transaction(); 472 : 473 : /** Abort the transaction currently in progress, discarding the 474 : * potential modifications made to the database. 475 : * 476 : * If an error occurs in this method, an exception will be thrown, 477 : * but the transaction will be cancelled anyway. 478 : * 479 : * @exception Xapian::DatabaseError will be thrown if a problem occurs 480 : * while modifying the database. 481 : * 482 : * @exception Xapian::DatabaseCorruptError will be thrown if the 483 : * database is in a corrupt state. 484 : * 485 : * @exception Xapian::InvalidOperationError will be thrown if a 486 : * transaction is not currently in progress. 487 : * 488 : * @exception Xapian::UnimplementedError will be thrown if transactions 489 : * are not available for this database type. 490 : */ 491 : void cancel_transaction(); 492 : 493 : /** Add a new document to the database. 494 : * 495 : * This method adds the specified document to the database, 496 : * returning a newly allocated document ID. Automatically allocated 497 : * document IDs come from a per-database monotonically increasing 498 : * counter, so IDs from deleted documents won't be reused. 499 : * 500 : * If you want to specify the document ID to be used, you should 501 : * call replace_document() instead. 502 : * 503 : * Note that changes to the database won't be immediately committed to 504 : * disk; see flush() for more details. 505 : * 506 : * As with all database modification operations, the effect is 507 : * atomic: the document will either be fully added, or the document 508 : * fails to be added and an exception is thrown (possibly at a 509 : * later time when flush is called or the database is closed). 510 : * 511 : * @param document The new document to be added. 512 : * 513 : * @return The document ID of the newly added document. 514 : * 515 : * @exception Xapian::DatabaseError will be thrown if a problem occurs 516 : * while writing to the database. 517 : * 518 : * @exception Xapian::DatabaseCorruptError will be thrown if the 519 : * database is in a corrupt state. 520 : */ 521 : Xapian::docid add_document(const Xapian::Document & document); 522 : 523 : /** Delete a document from the database. 524 : * 525 : * This method removes the document with the specified document ID 526 : * from the database. 527 : * 528 : * Note that changes to the database won't be immediately committed to 529 : * disk; see flush() for more details. 530 : * 531 : * As with all database modification operations, the effect is 532 : * atomic: the document will either be fully removed, or the document 533 : * fails to be removed and an exception is thrown (possibly at a 534 : * later time when flush is called or the database is closed). 535 : * 536 : * @param did The document ID of the document to be removed. 537 : * 538 : * @exception Xapian::DatabaseError will be thrown if a problem occurs 539 : * while writing to the database. 540 : * 541 : * @exception Xapian::DatabaseCorruptError will be thrown if the 542 : * database is in a corrupt state. 543 : */ 544 : void delete_document(Xapian::docid did); 545 : 546 : /** Delete any documents indexed by a term from the database. 547 : * 548 : * This method removes any documents indexed by the specified term 549 : * from the database. 550 : * 551 : * A major use is for convenience when UIDs from another system are 552 : * mapped to terms in Xapian, although this method has other uses 553 : * (for example, you could add a "deletion date" term to documents at 554 : * index time and use this method to delete all documents due for 555 : * deletion on a particular date). 556 : * 557 : * @param unique_term The term to remove references to. 558 : * 559 : * @exception Xapian::DatabaseError will be thrown if a problem occurs 560 : * while writing to the database. 561 : * 562 : * @exception Xapian::DatabaseCorruptError will be thrown if the 563 : * database is in a corrupt state. 564 : */ 565 : void delete_document(const std::string & unique_term); 566 : 567 : /** Replace a given document in the database. 568 : * 569 : * This method replaces the document with the specified document ID. 570 : * If document ID @a did isn't currently used, the document will be 571 : * added with document ID @a did. 572 : * 573 : * The monotonic counter used for automatically allocating document 574 : * IDs is increased so that the next automatically allocated document 575 : * ID will be did + 1. Be aware that if you use this method to 576 : * specify a high document ID for a new document, and also use 577 : * WritableDatabase::add_document(), Xapian may get to a state where 578 : * this counter wraps around and will be unable to automatically 579 : * allocate document IDs! 580 : * 581 : * Note that changes to the database won't be immediately committed to 582 : * disk; see flush() for more details. 583 : * 584 : * As with all database modification operations, the effect is 585 : * atomic: the document will either be fully replaced, or the document 586 : * fails to be replaced and an exception is thrown (possibly at a 587 : * later time when flush is called or the database is closed). 588 : * 589 : * @param did The document ID of the document to be replaced. 590 : * @param document The new document. 591 : * 592 : * @exception Xapian::DatabaseError will be thrown if a problem occurs 593 : * while writing to the database. 594 : * 595 : * @exception Xapian::DatabaseCorruptError will be thrown if the 596 : * database is in a corrupt state. 597 : */ 598 : void replace_document(Xapian::docid did, 599 : const Xapian::Document & document); 600 : 601 : /** Replace any documents matching a term. 602 : * 603 : * This method replaces any documents indexed by the specified term 604 : * with the specified document. If any documents are indexed by the 605 : * term, the lowest document ID will be used for the document, 606 : * otherwise a new document ID will be generated as for add_document. 607 : * 608 : * The intended use is to allow UIDs from another system to easily 609 : * be mapped to terms in Xapian, although this method probably has 610 : * other uses. 611 : * 612 : * Note that changes to the database won't be immediately committed to 613 : * disk; see flush() for more details. 614 : * 615 : * As with all database modification operations, the effect is 616 : * atomic: the document(s) will either be fully replaced, or the 617 : * document(s) fail to be replaced and an exception is thrown 618 : * (possibly at a 619 : * later time when flush is called or the database is closed). 620 : * 621 : * @param unique_term The "unique" term. 622 : * @param document The new document. 623 : * 624 : * @return The document ID that document was given. 625 : * 626 : * @exception Xapian::DatabaseError will be thrown if a problem occurs 627 : * while writing to the database. 628 : * 629 : * @exception Xapian::DatabaseCorruptError will be thrown if the 630 : * database is in a corrupt state. 631 : */ 632 : Xapian::docid replace_document(const std::string & unique_term, 633 : const Xapian::Document & document); 634 : 635 : /** Add a word to the spelling dictionary. 636 : * 637 : * If the word is already present, its frequency is increased. 638 : * 639 : * @param word The word to add. 640 : * @param freqinc How much to increase its frequency by (default 1). 641 : */ 642 : void add_spelling(const std::string & word, 643 : Xapian::termcount freqinc = 1) const; 644 : 645 : /** Remove a word from the spelling dictionary. 646 : * 647 : * The word's frequency is decreased, and if would become zero or less 648 : * then the word is removed completely. 649 : * 650 : * @param word The word to remove. 651 : * @param freqdec How much to decrease its frequency by (default 1). 652 : */ 653 : void remove_spelling(const std::string & word, 654 : Xapian::termcount freqdec = 1) const; 655 : 656 : /** Add a synonym for a term. 657 : * 658 : * If @a synonym is already a synonym for @a term, then no action is 659 : * taken. 660 : */ 661 : void add_synonym(const std::string & term, 662 : const std::string & synonym) const; 663 : 664 : /** Remove a synonym for a term. 665 : * 666 : * If @a synonym isn't a synonym for @a term, then no action is taken. 667 : */ 668 : void remove_synonym(const std::string & term, 669 : const std::string & synonym) const; 670 : 671 : /** Remove all synonyms for a term. 672 : * 673 : * If @a term has no synonyms, no action is taken. 674 : */ 675 : void clear_synonyms(const std::string & term) const; 676 : 677 : /** Set the user-specified metadata associated with a given key. 678 : * 679 : * This method sets the metadata value associated with a given key. 680 : * If there is already a metadata value stored in the database with 681 : * the same key, the old value is replaced. If you want to delete an 682 : * existing item of metadata, just set its value to the empty string. 683 : * 684 : * User-specified metadata allows you to store arbitrary information 685 : * in the form of (key,tag) pairs. 686 : * 687 : * There's no hard limit on the number of metadata items, or the size 688 : * of the metadata values. Metadata keys have a limited length, which 689 : * depends on the backend. We recommend limiting them to 200 bytes. 690 : * Empty keys are not valid, and specifying one will cause an 691 : * exception. 692 : * 693 : * Metadata modifications are committed to disk in the same way as 694 : * modifications to the documents in the database are: i.e., 695 : * modifications are atomic, and won't be committed to disk 696 : * immediately (see flush() for more details). This allows metadata 697 : * to be used to link databases with versioned external resources 698 : * by storing the appropriate version number in a metadata item. 699 : * 700 : * You can also use the metadata to store arbitrary extra information 701 : * associated with terms, documents, or postings by encoding the 702 : * termname and/or document id into the metadata key. 703 : * 704 : * @param key The key of the metadata item to set. 705 : * 706 : * @param value The value of the metadata item to set. 707 : * 708 : * @exception Xapian::DatabaseError will be thrown if a problem occurs 709 : * while writing to the database. 710 : * 711 : * @exception Xapian::DatabaseCorruptError will be thrown if the 712 : * database is in a corrupt state. 713 : * 714 : * @exception Xapian::InvalidArgumentError will be thrown if the 715 : * key supplied is empty. 716 : */ 717 : void set_metadata(const std::string & key, const std::string & value); 718 : 719 : /// Return a string describing this object. 720 : std::string get_description() const; 721 : }; 722 : 723 : /** Open for read/write; create if no db exists. */ 724 : const int DB_CREATE_OR_OPEN = 1; 725 : /** Create a new database; fail if db exists. */ 726 : const int DB_CREATE = 2; 727 : /** Overwrite existing db; create if none exists. */ 728 : const int DB_CREATE_OR_OVERWRITE = 3; 729 : /** Open for read/write; fail if no db exists. */ 730 : const int DB_OPEN = 4; 731 : // Can't see any sensible use for this one 732 : // const int DB_OVERWRITE = XXX; 733 : 734 : } 735 : 736 : #endif /* XAPIAN_INCLUDED_DATABASE_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /* base.h: Reference-counted pointers 2 : * 3 : * Copyright 1999,2000,2001 BrightStation PLC 4 : * Copyright 2002 Ananova Ltd 5 : * Copyright 2002,2003,2004,2007 Olly Betts 6 : * 7 : * This program is free software; you can redistribute it and/or 8 : * modify it under the terms of the GNU General Public License as 9 : * published by the Free Software Foundation; either version 2 of the 10 : * License, or (at your option) any later version. 11 : * 12 : * This program is distributed in the hope that it will be useful, 13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : * GNU General Public License for more details. 16 : * 17 : * You should have received a copy of the GNU General Public License 18 : * along with this program; if not, write to the Free Software 19 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 20 : * USA 21 : */ 22 : 23 : #ifndef XAPIAN_INCLUDED_BASE_H 24 : #define XAPIAN_INCLUDED_BASE_H 25 : 26 : #include <xapian/deprecated.h> 27 : 28 : namespace Xapian { 29 : namespace Internal { 30 : 31 : /** @internal Reference counted internal classes should inherit from RefCntBase. 32 : * 33 : * This gives the object a reference count used by RefCntPtr. 34 : */ 35 : class RefCntBase { 36 : /* Note: We never delete a pointer to a subclass of RefCntBase using 37 : * a RefCntBase *, so we don't need a virtual destructor here. 38 : */ 39 : protected: 40 : /** The copy constructor. 41 : * 42 : * This is protected since it'll only be used by derived classes, 43 : * which should only rarely need copying (this is, after all, a 44 : * refcount implementation). Sometimes it's needed, though, 45 : * since we need to zero ref_count in the copy. 46 : */ 47 : RefCntBase(const RefCntBase &) : ref_count(0) { } 48 : 49 : public: 50 : /// The constructor, which initialises the ref_count to 0. 51 : RefCntBase() : ref_count(0) { } 52 : 53 : typedef unsigned int ref_count_t; 54 : 55 : /** The actual reference count. It's mutable so we can have reference 56 : * counting work with const pointers. 57 : */ 58 : mutable ref_count_t ref_count; 59 : }; 60 : 61 : /** @internal A reference-counted pointer. Can be used with any 62 : * class derived from RefCntBase, as long as it is allocated 63 : * on the heap by new (not new[]!). 64 : */ 65 : template <class T> 66 : class RefCntPtr { 67 : private: 68 : T *dest; 69 : 70 : public: 71 : T *operator->() const; 72 : T &operator*() const; 73 : T *get() const; 74 : /** Make a RefCntPtr for an object which may already 75 : * have reference counted pointers. 76 : * 77 : * You usually pass in a newly created object, or an object may pass 78 : * in "this" to get a RefCntPtr to itself to pass to other classes. 79 : * (e.g. a database might pass a newly created postlist a reference 80 : * counted pointer to itself.) 81 : */ 82 : RefCntPtr(T *dest_); 83 : RefCntPtr(); 84 : RefCntPtr(const RefCntPtr &other); 85 : void operator=(const RefCntPtr &other); 86 : void operator=(T *dest_); 87 : ~RefCntPtr(); 88 : 89 : template <class U> 90 : RefCntPtr(const RefCntPtr<U> &other); 91 : }; 92 : 93 : template <class T> 94 19 : inline RefCntPtr<T>::RefCntPtr(T *dest_) : dest(dest_) 95 : { 96 19 : if (dest) ++dest->ref_count; 97 19 : } 98 : 99 : template <class T> 100 : inline RefCntPtr<T>::RefCntPtr() : dest(0) 101 : { 102 : } 103 : 104 : template <class T> 105 : inline RefCntPtr<T>::RefCntPtr(const RefCntPtr &other) : dest(other.dest) 106 : { 107 : if (dest) ++dest->ref_count; 108 : } 109 : 110 : template <class T> 111 : inline void RefCntPtr<T>::operator=(const RefCntPtr &other) { 112 : operator=(other.dest); 113 : } 114 : 115 : template <class T> 116 : inline void RefCntPtr<T>::operator=(T *dest_) { 117 : // check if we're assigning a pointer to itself 118 : if (dest == dest_) return; 119 : 120 : // copy the new dest in before we delete the old to avoid a small 121 : // window in which dest points to a deleted object 122 : // FIXME: if pointer assignment isn't atomic, we ought to use locking... 123 : T *old_dest = dest; 124 : dest = dest_; 125 : if (dest) ++dest->ref_count; 126 : if (old_dest && --old_dest->ref_count == 0) delete old_dest; 127 : } 128 : 129 : template <class T> 130 0 : inline RefCntPtr<T>::~RefCntPtr() 131 : { 132 0 : if (dest && --dest->ref_count == 0) { 133 : // zero before we delete to avoid a small window in which dest points 134 : // to a deleted object 135 : // FIXME: if pointer assignment isn't atomic, we ought to use locking... 136 0 : T * condemned = dest; 137 0 : dest = 0; 138 0 : delete condemned; 139 : } 140 0 : } 141 : 142 : template <class T> 143 : template <class U> 144 : inline 145 : RefCntPtr<T>::RefCntPtr(const RefCntPtr<U> &other) 146 : : dest(other.get()) 147 : { 148 : if (dest) ++dest->ref_count; 149 : } 150 : 151 : template <class T> 152 : inline T *RefCntPtr<T>::operator->() const 153 : { 154 : return dest; 155 : } 156 : 157 : template <class T> 158 : inline T &RefCntPtr<T>::operator*() const 159 : { 160 : return *dest; 161 : } 162 : 163 : template <class T> 164 30 : inline T *RefCntPtr<T>::get() const 165 : { 166 30 : return dest; 167 : } 168 : 169 : } 170 : } 171 : 172 : #endif /* XAPIAN_INCLUDED_BASE_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** \file termiterator.h 2 : * \brief Classes for iterating through term lists 3 : */ 4 : /* Copyright 1999,2000,2001 BrightStation PLC 5 : * Copyright 2002 Ananova Ltd 6 : * Copyright 2003,2004,2005,2006,2007 Olly Betts 7 : * 8 : * This program is free software; you can redistribute it and/or 9 : * modify it under the terms of the GNU General Public License as 10 : * published by the Free Software Foundation; either version 2 of the 11 : * License, or (at your option) any later version. 12 : * 13 : * This program is distributed in the hope that it will be useful, 14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : * GNU General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU General Public License 19 : * along with this program; if not, write to the Free Software 20 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 21 : * USA 22 : */ 23 : 24 : #ifndef XAPIAN_INCLUDED_TERMITERATOR_H 25 : #define XAPIAN_INCLUDED_TERMITERATOR_H 26 : 27 : #include <iterator> 28 : #include <string> 29 : 30 : #include <xapian/base.h> 31 : #include <xapian/types.h> 32 : #include <xapian/positioniterator.h> 33 : #include <xapian/visibility.h> 34 : 35 : namespace Xapian { 36 : 37 : class Database; 38 : 39 : /** @internal A wrapper class for a termname which returns the termname if 40 : * dereferenced with *. We need this to implement input_iterator semantics. 41 : */ 42 : class TermNameWrapper { 43 : private: 44 : std::string tname; 45 : public: 46 : explicit TermNameWrapper(const std::string & tname_) : tname(tname_) { } 47 : const std::string & operator*() const { return tname; } 48 : }; 49 : 50 : /** An iterator pointing to items in a list of terms. 51 : */ 52 : class XAPIAN_VISIBILITY_DEFAULT TermIterator { 53 : public: 54 : class Internal; 55 : /// @internal Reference counted internals. 56 : Xapian::Internal::RefCntPtr<Internal> internal; 57 : 58 : /// @internal Reference counted internals. 59 : explicit TermIterator(Internal *internal_); 60 : 61 : /// Default constructor - for declaring an uninitialised iterator. 62 : TermIterator(); 63 : 64 : /// Destructor. 65 : ~TermIterator(); 66 : 67 : /** Copying is allowed. The internals are reference counted, so 68 : * copying is also cheap. 69 : */ 70 : TermIterator(const TermIterator &other); 71 : 72 : /** Assignment is allowed. The internals are reference counted, 73 : * so assignment is also cheap. 74 : */ 75 : void operator=(const TermIterator &other); 76 : 77 : /// Return the current term. 78 : std::string operator *() const; 79 : 80 : TermIterator & operator++(); 81 : 82 : TermNameWrapper operator++(int) { 83 : std::string tmp = **this; 84 : operator++(); 85 : return TermNameWrapper(tmp); 86 : } 87 : 88 : /** Skip the iterator to term tname, or the first term after tname 89 : * if tname isn't in the list of terms being iterated. 90 : */ 91 : void skip_to(const std::string & tname); 92 : 93 : /** Return the wdf of the current term (if meaningful). 94 : * 95 : * The wdf (within document frequency) is the number of occurences 96 : * of a term in a particular document. 97 : */ 98 : Xapian::termcount get_wdf() const; 99 : 100 : /** Return the term frequency of the current term (if meaningful). 101 : * 102 : * The term frequency is the number of documents which a term indexes. 103 : */ 104 : Xapian::doccount get_termfreq() const; 105 : 106 : /** Return length of positionlist for current term. 107 : */ 108 : Xapian::termcount positionlist_count() const; 109 : 110 : /** Return PositionIterator pointing to start of positionlist for 111 : * current term. 112 : */ 113 : PositionIterator positionlist_begin() const; 114 : 115 : /** Return PositionIterator pointing to end of positionlist for 116 : * current term. 117 : */ 118 : PositionIterator positionlist_end() const { 119 : return PositionIterator(NULL); 120 : } 121 : 122 : /// Return a string describing this object. 123 : std::string get_description() const; 124 : 125 : /// Allow use as an STL iterator 126 : //@{ 127 : typedef std::input_iterator_tag iterator_category; 128 : typedef std::string value_type; 129 : typedef Xapian::termcount_diff difference_type; 130 : typedef std::string * pointer; 131 : typedef std::string & reference; 132 : //@} 133 : }; 134 : 135 : inline bool 136 5 : operator==(const TermIterator &a, const TermIterator &b) 137 : { 138 5 : return (a.internal.get() == b.internal.get()); 139 : } 140 : 141 : inline bool 142 5 : operator!=(const TermIterator &a, const TermIterator &b) 143 : { 144 5 : return !(a == b); 145 : } 146 : 147 : } 148 : 149 : #endif /* XAPIAN_INCLUDED_TERMITERATOR_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** @file unicode.h 2 : * @brief Unicode and UTF-8 related classes and functions. 3 : */ 4 : /* Copyright (C) 2006,2007,2008 Olly Betts 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 2 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, write to the Free Software 18 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 : */ 20 : 21 : #ifndef XAPIAN_INCLUDED_UNICODE_H 22 : #define XAPIAN_INCLUDED_UNICODE_H 23 : 24 : #include <xapian/visibility.h> 25 : 26 : #include <string> 27 : 28 : namespace Xapian { 29 : 30 : /** An iterator which returns unicode character values from a UTF-8 encoded 31 : * string. 32 : */ 33 : class XAPIAN_VISIBILITY_DEFAULT Utf8Iterator { 34 : const unsigned char *p; 35 : const unsigned char *end; 36 : mutable unsigned seqlen; 37 : 38 : void calculate_sequence_length() const; 39 : 40 : unsigned get_char() const; 41 : 42 : Utf8Iterator(const unsigned char *p_, const unsigned char *end_, unsigned seqlen_) 43 : : p(p_), end(end_), seqlen(seqlen_) { } 44 : 45 : public: 46 : /** Return the raw const char * pointer for the current position. */ 47 : const char * raw() const { 48 : return reinterpret_cast<const char *>(p ? p : end); 49 : } 50 : 51 : /** Return the number of bytes left in the iterator's buffer. */ 52 : size_t left() const { return p ? end - p : 0; } 53 : 54 : /** Assign a new string to the iterator. 55 : * 56 : * The iterator will forget the string it was iterating through, and 57 : * return characters from the start of the new string when next called. 58 : * The string is not copied into the iterator, so it must remain valid 59 : * while the iteration is in progress. 60 : * 61 : * @param p A pointer to the start of the string to read. 62 : * 63 : * @param len The length of the string to read. 64 : */ 65 5208 : void assign(const char *p_, size_t len) { 66 5208 : if (len) { 67 5208 : p = reinterpret_cast<const unsigned char*>(p_); 68 5208 : end = p + len; 69 5208 : seqlen = 0; 70 : } else { 71 0 : p = NULL; 72 : } 73 5208 : } 74 : 75 : /** Assign a new string to the iterator. 76 : * 77 : * The iterator will forget the string it was iterating through, and 78 : * return characters from the start of the new string when next called. 79 : * The string is not copied into the iterator, so it must remain valid 80 : * while the iteration is in progress. 81 : * 82 : * @param s The string to read. Must not be modified while the iteration 83 : * is in progress. 84 : */ 85 : void assign(const std::string &s) { assign(s.data(), s.size()); } 86 : 87 : /** Create an iterator given a pointer to a null terminated string. 88 : * 89 : * The iterator will return characters from the start of the string when 90 : * next called. The string is not copied into the iterator, so it must 91 : * remain valid while the iteration is in progress. 92 : * 93 : * @param p A pointer to the start of the null terminated string to read. 94 : */ 95 : explicit Utf8Iterator(const char *p_); 96 : 97 : /** Create an iterator given a pointer and a length. 98 : * 99 : * The iterator will return characters from the start of the string when 100 : * next called. The string is not copied into the iterator, so it must 101 : * remain valid while the iteration is in progress. 102 : * 103 : * @param p A pointer to the start of the string to read. 104 : * 105 : * @param len The length of the string to read. 106 : */ 107 : Utf8Iterator(const char *p_, size_t len) { assign(p_, len); } 108 : 109 : /** Create an iterator given a string. 110 : * 111 : * The iterator will return characters from the start of the string when 112 : * next called. The string is not copied into the iterator, so it must 113 : * remain valid while the iteration is in progress. 114 : * 115 : * @param s The string to read. Must not be modified while the iteration 116 : * is in progress. 117 : */ 118 5208 : Utf8Iterator(const std::string &s) { assign(s.data(), s.size()); } 119 : 120 : /** Create an iterator which is at the end of its iteration. 121 : * 122 : * This can be compared to another iterator to check if the other iterator 123 : * has reached its end. 124 : */ 125 : Utf8Iterator() : p(NULL), end(0), seqlen(0) { } 126 : 127 : /** Get the current unicode character value pointed to by the iterator. 128 : * 129 : * Returns unsigned(-1) if the iterator has reached the end of its buffer. 130 : */ 131 : unsigned operator*() const; 132 : 133 : /** Move forward to the next unicode character. 134 : * 135 : * @return An iterator pointing to the position before the move. 136 : */ 137 : Utf8Iterator operator++(int) { 138 : // If we've not calculated seqlen yet, do so. 139 : if (seqlen == 0) calculate_sequence_length(); 140 : const unsigned char *old_p = p; 141 : unsigned old_seqlen = seqlen; 142 : p += seqlen; 143 : if (p == end) p = NULL; 144 : seqlen = 0; 145 : return Utf8Iterator(old_p, end, old_seqlen); 146 : } 147 : 148 : /** Move forward to the next unicode character. 149 : * 150 : * @return A reference to this object. 151 : */ 152 : Utf8Iterator & operator++() { 153 : if (seqlen == 0) calculate_sequence_length(); 154 : p += seqlen; 155 : if (p == end) p = NULL; 156 : seqlen = 0; 157 : return *this; 158 : } 159 : 160 : /** Test two Utf8Iterators for equality. 161 : * 162 : * @return true iff the iterators point to the same position. 163 : */ 164 : bool operator==(const Utf8Iterator &other) const { return p == other.p; } 165 : 166 : /** Test two Utf8Iterators for inequality. 167 : * 168 : * @return true iff the iterators do not point to the same position. 169 : */ 170 : bool operator!=(const Utf8Iterator &other) const { return p != other.p; } 171 : 172 : /// We implement the semantics of an STL input_iterator. 173 : //@{ 174 : typedef std::input_iterator_tag iterator_category; 175 : typedef unsigned value_type; 176 : typedef size_t difference_type; 177 : typedef const unsigned * pointer; 178 : typedef const unsigned & reference; 179 : //@} 180 : }; 181 : 182 : namespace Unicode { 183 : 184 : /** Each unicode character is in one of these categories. */ 185 : typedef enum { 186 : UNASSIGNED, 187 : UPPERCASE_LETTER, 188 : LOWERCASE_LETTER, 189 : TITLECASE_LETTER, 190 : MODIFIER_LETTER, 191 : OTHER_LETTER, 192 : NON_SPACING_MARK, 193 : ENCLOSING_MARK, 194 : COMBINING_SPACING_MARK, 195 : DECIMAL_DIGIT_NUMBER, 196 : LETTER_NUMBER, 197 : OTHER_NUMBER, 198 : SPACE_SEPARATOR, 199 : LINE_SEPARATOR, 200 : PARAGRAPH_SEPARATOR, 201 : CONTROL, 202 : FORMAT, 203 : PRIVATE_USE, 204 : SURROGATE, 205 : CONNECTOR_PUNCTUATION, 206 : DASH_PUNCTUATION, 207 : OPEN_PUNCTUATION, 208 : CLOSE_PUNCTUATION, 209 : INITIAL_QUOTE_PUNCTUATION, 210 : FINAL_QUOTE_PUNCTUATION, 211 : OTHER_PUNCTUATION, 212 : MATH_SYMBOL, 213 : CURRENCY_SYMBOL, 214 : MODIFIER_SYMBOL, 215 : OTHER_SYMBOL 216 : } category; 217 : 218 : namespace Internal { 219 : /** @internal Extract the information about a character from the Unicode 220 : * character tables. 221 : * 222 : * ch must be a valid Unicode character value (i.e. < 0x110000) 223 : */ 224 : XAPIAN_VISIBILITY_DEFAULT 225 : int get_character_info(unsigned ch); 226 : 227 : /** @internal Extract how to convert the case of a unicode character from 228 : * its info. 229 : */ 230 : inline int get_case_type(int info) { return ((info & 0xe0) >> 5); } 231 : 232 : /// @internal Extract the category of a unicode character from its info. 233 : inline category get_category(int info) { return static_cast<category>(info & 0x1f); } 234 : 235 : /** @internal Extract the delta to use for case conversion of a character 236 : * from its info. 237 : */ 238 : inline int get_delta(int info) { 239 : /* It's implementation defined if sign extension happens on right shift 240 : * of a signed int, hence the conditional (hopefully the compiler will 241 : * spot this and optimise it to a sign-extending shift on architectures 242 : * with a suitable instruction). 243 : */ 244 : return (info >= 0) ? (info >> 15) : (~(~info >> 15)); 245 : } 246 : } 247 : 248 : /** Convert a single non-ASCII unicode character to UTF-8. 249 : * 250 : * This is intended mainly as a helper method for to_utf8(). 251 : * 252 : * The character @a ch (which must be > 128) is written to the buffer @a buf 253 : * and the length of the resultant UTF-8 character is returned. 254 : * 255 : * NB buf must have space for (at least) 4 bytes. 256 : */ 257 : XAPIAN_VISIBILITY_DEFAULT 258 : unsigned nonascii_to_utf8(unsigned ch, char * buf); 259 : 260 : /** Convert a single unicode character to UTF-8. 261 : * 262 : * The character @a ch is written to the buffer @a buf and the length of the 263 : * resultant UTF-8 character is returned. 264 : * 265 : * NB buf must have space for (at least) 4 bytes. 266 : */ 267 : inline unsigned to_utf8(unsigned ch, char *buf) { 268 : if (ch < 128) { 269 : *buf = static_cast<unsigned char>(ch); 270 : return 1; 271 : } 272 : return Xapian::Unicode::nonascii_to_utf8(ch, buf); 273 : } 274 : 275 : /** Append the UTF-8 representation of a single unicode character to a 276 : * std::string. 277 : */ 278 : inline void append_utf8(std::string &s, unsigned ch) { 279 : char buf[4]; 280 : s.append(buf, to_utf8(ch, buf)); 281 : } 282 : 283 : /// Return the category which a given unicode character falls into. 284 : inline category get_category(unsigned ch) { 285 : // Categorise non-Unicode values as UNASSIGNED. 286 : if (ch >= 0x110000) return Xapian::Unicode::UNASSIGNED; 287 : return Internal::get_category(Internal::get_character_info(ch)); 288 : } 289 : 290 : /// Test is a given unicode character is a letter or number. 291 : inline bool is_wordchar(unsigned ch) { 292 : const unsigned int WORDCHAR_MASK = 293 : (1 << Xapian::Unicode::UPPERCASE_LETTER) | 294 : (1 << Xapian::Unicode::LOWERCASE_LETTER) | 295 : (1 << Xapian::Unicode::TITLECASE_LETTER) | 296 : (1 << Xapian::Unicode::MODIFIER_LETTER) | 297 : (1 << Xapian::Unicode::OTHER_LETTER) | 298 : (1 << Xapian::Unicode::DECIMAL_DIGIT_NUMBER) | 299 : (1 << Xapian::Unicode::LETTER_NUMBER) | 300 : (1 << Xapian::Unicode::OTHER_NUMBER) | 301 : (1 << Xapian::Unicode::CONNECTOR_PUNCTUATION); 302 : return ((WORDCHAR_MASK >> get_category(ch)) & 1); 303 : } 304 : 305 : /// Test is a given unicode character is a whitespace character. 306 : inline bool is_whitespace(unsigned ch) { 307 : const unsigned int WHITESPACE_MASK = 308 : (1 << Xapian::Unicode::CONTROL) | // For TAB, CR, LF, FF. 309 : (1 << Xapian::Unicode::SPACE_SEPARATOR) | 310 : (1 << Xapian::Unicode::LINE_SEPARATOR) | 311 : (1 << Xapian::Unicode::PARAGRAPH_SEPARATOR); 312 : return ((WHITESPACE_MASK >> get_category(ch)) & 1); 313 : } 314 : 315 : /// Test is a given unicode character is a currency symbol. 316 : inline bool is_currency(unsigned ch) { 317 : return (get_category(ch) == Xapian::Unicode::CURRENCY_SYMBOL); 318 : } 319 : 320 : /// Convert a unicode character to lowercase. 321 : inline unsigned tolower(unsigned ch) { 322 : int info; 323 : // Leave non-Unicode values unchanged. 324 : if (ch >= 0x110000 || !(Internal::get_case_type((info = Xapian::Unicode::Internal::get_character_info(ch))) & 2)) 325 : return ch; 326 : return ch + Internal::get_delta(info); 327 : } 328 : 329 : /// Convert a unicode character to uppercase. 330 : inline unsigned toupper(unsigned ch) { 331 : int info; 332 : // Leave non-Unicode values unchanged. 333 : if (ch >= 0x110000 || !(Internal::get_case_type((info = Xapian::Unicode::Internal::get_character_info(ch))) & 4)) 334 : return ch; 335 : return ch - Internal::get_delta(info); 336 : } 337 : 338 : /// Convert a UTF-8 std::string to lowercase. 339 : inline std::string 340 : tolower(const std::string &term) 341 : { 342 : std::string result; 343 : result.reserve(term.size()); 344 : for (Utf8Iterator i(term); i != Utf8Iterator(); ++i) { 345 : append_utf8(result, tolower(*i)); 346 : } 347 : return result; 348 : } 349 : 350 : /// Convert a UTF-8 std::string to uppercase. 351 : inline std::string 352 : toupper(const std::string &term) 353 : { 354 : std::string result; 355 : result.reserve(term.size()); 356 : for (Utf8Iterator i(term); i != Utf8Iterator(); ++i) { 357 : append_utf8(result, toupper(*i)); 358 : } 359 : return result; 360 : } 361 : 362 : } 363 : 364 : } 365 : 366 : #endif // XAPIAN_INCLUDED_UNICODE_H |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** @file expanddecider.h 2 : * @brief Allow rejection of terms during ESet generation. 3 : */ 4 : /* Copyright (C) 2007 Olly Betts 5 : * 6 : * This program is free software; you can redistribute it and/or 7 : * modify it under the terms of the GNU General Public License as 8 : * published by the Free Software Foundation; either version 2 of the 9 : * License, or (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, write to the Free Software 18 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 : */ 20 : 21 : #ifndef XAPIAN_INCLUDED_EXPANDDECIDER_H 22 : #define XAPIAN_INCLUDED_EXPANDDECIDER_H 23 : 24 : #include <set> 25 : #include <string> 26 : 27 : #include <xapian/visibility.h> 28 : 29 : namespace Xapian { 30 : 31 : /** Virtual base class for expand decider functor. */ 32 5 : class XAPIAN_VISIBILITY_DEFAULT ExpandDecider { 33 : public: 34 : /** Do we want this term in the ESet? */ 35 : virtual bool operator()(const std::string &term) const = 0; 36 : 37 : /** Virtual destructor, because we have virtual methods. */ 38 : virtual ~ExpandDecider(); 39 : }; 40 : 41 : /** ExpandDecider subclass which rejects terms using two ExpandDeciders. 42 : * 43 : * Terms are only accepted if they are accepted by both of the specified 44 : * ExpandDecider objects. 45 : */ 46 : class XAPIAN_VISIBILITY_DEFAULT ExpandDeciderAnd : public ExpandDecider { 47 : const ExpandDecider &first, &second; 48 : 49 : public: 50 : /** Terms will be checked with @a first, and if accepted, then checked 51 : * with @a second. 52 : */ 53 : ExpandDeciderAnd(const ExpandDecider &first_, 54 : const ExpandDecider &second_) 55 : : first(first_), second(second_) { } 56 : 57 : /** Compatibility method. */ 58 : ExpandDeciderAnd(const ExpandDecider *first_, 59 : const ExpandDecider *second_) 60 : : first(*first_), second(*second_) { } 61 : 62 : virtual bool operator()(const std::string &term) const; 63 : }; 64 : 65 : /** ExpandDecider subclass which rejects terms in a specified list. 66 : * 67 : * ExpandDeciderFilterTerms provides an easy way to filter out terms from 68 : * a fixed list when generating an ESet. 69 : */ 70 : class XAPIAN_VISIBILITY_DEFAULT ExpandDeciderFilterTerms : public ExpandDecider { 71 : std::set<std::string> rejects; 72 : 73 : public: 74 : /** The two iterators specify a list of terms to be rejected. 75 : * 76 : * @a reject_begin and @a reject_end can be any input_iterator type 77 : * which returns std::string or char * (e.g. TermIterator or char **). 78 : */ 79 : template <class Iterator> 80 : ExpandDeciderFilterTerms(Iterator reject_begin, Iterator reject_end) 81 : : rejects(reject_begin, reject_end) { } 82 : 83 : virtual bool operator()(const std::string &term) const; 84 : }; 85 : 86 : } 87 : 88 : #endif // XAPIAN_INCLUDED_EXPANDDECIDER_H |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** \file document.h 2 : * \brief API for working with documents 3 : */ 4 : /* Copyright 1999,2000,2001 BrightStation PLC 5 : * Copyright 2002 Ananova Ltd 6 : * Copyright 2002,2003,2004,2006,2007 Olly Betts 7 : * 8 : * This program is free software; you can redistribute it and/or 9 : * modify it under the terms of the GNU General Public License as 10 : * published by the Free Software Foundation; either version 2 of the 11 : * License, or (at your option) any later version. 12 : * 13 : * This program is distributed in the hope that it will be useful, 14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : * GNU General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU General Public License 19 : * along with this program; if not, write to the Free Software 20 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 21 : * USA 22 : */ 23 : 24 : #ifndef XAPIAN_INCLUDED_DOCUMENT_H 25 : #define XAPIAN_INCLUDED_DOCUMENT_H 26 : 27 : #include <string> 28 : 29 : #include <xapian/base.h> 30 : #include <xapian/types.h> 31 : #include <xapian/termiterator.h> 32 : #include <xapian/visibility.h> 33 : 34 : namespace Xapian { 35 : 36 : class ValueIterator; 37 : 38 : /// A document in the database - holds data, values, terms, and postings 39 : class XAPIAN_VISIBILITY_DEFAULT Document { 40 : public: 41 : class Internal; 42 : /// @private @internal Reference counted internals. 43 : Xapian::Internal::RefCntPtr<Internal> internal; 44 : 45 : /** @private @internal Constructor is only used by internal classes. 46 : * 47 : * @param internal_ pointer to internal opaque class 48 : */ 49 : explicit Document(Internal *internal_); 50 : 51 : /** Copying is allowed. The internals are reference counted, so 52 : * copying is cheap. 53 : */ 54 : Document(const Document &other); 55 : 56 : /** Assignment is allowed. The internals are reference counted, 57 : * so assignment is cheap. 58 : */ 59 : void operator=(const Document &other); 60 : 61 : /// Make a new empty Document 62 : Document(); 63 : 64 : /// Destructor 65 : ~Document(); 66 : 67 : /** Get value by number. 68 : * 69 : * Returns an empty string if no value with the given number is present 70 : * in the document. 71 : * 72 : * @param valueno The number of the value. 73 : */ 74 : std::string get_value(Xapian::valueno valueno) const; 75 : 76 : /** Add a new value. It will replace any existing value with the 77 : * same number. 78 : */ 79 : void add_value(Xapian::valueno valueno, const std::string &value); 80 : 81 : /// Remove any value with the given number. 82 : void remove_value(Xapian::valueno valueno); 83 : 84 : /// Remove all values associated with the document. 85 : void clear_values(); 86 : 87 : /** Get data stored in the document. 88 : * This is a potentially expensive operation, and shouldn't normally 89 : * be used in a match decider functor. Put data for use by match 90 : * deciders in a value instead. 91 : */ 92 : std::string get_data() const; 93 : 94 : /// Set data stored in the document. 95 : void set_data(const std::string &data); 96 : 97 : /** Add an occurrence of a term at a particular position. 98 : * 99 : * Multiple occurrences of the term at the same position are 100 : * represented only once in the positional information, but do 101 : * increase the wdf. 102 : * 103 : * If the term is not already in the document, it will be added to 104 : * it. 105 : * 106 : * @param tname The name of the term. 107 : * @param tpos The position of the term. 108 : * @param wdfinc The increment that will be applied to the wdf 109 : * for this term. 110 : */ 111 : void add_posting(const std::string & tname, 112 : Xapian::termpos tpos, 113 : Xapian::termcount wdfinc = 1); 114 : 115 : /** Add a term to the document, without positional information. 116 : * 117 : * Any existing positional information for the term will be left 118 : * unmodified. 119 : * 120 : * @param tname The name of the term. 121 : * @param wdfinc The increment that will be applied to the wdf 122 : * for this term. 123 : */ 124 : void add_term(const std::string & tname, Xapian::termcount wdfinc = 1); 125 : 126 : /** Remove a posting of a term from the document. 127 : * 128 : * Note that the term will still index the document even if all 129 : * occurrences are removed. To remove a term from a document 130 : * completely, use remove_term(). 131 : * 132 : * @param tname The name of the term. 133 : * @param tpos The position of the term. 134 : * @param wdfdec The decrement that will be applied to the wdf 135 : * when removing this posting. The wdf will not go 136 : * below the value of 0. 137 : * 138 : * @exception Xapian::InvalidArgumentError will be thrown if the term 139 : * is not at the position specified in the position list for this term 140 : * in this document. 141 : * 142 : * @exception Xapian::InvalidArgumentError will be thrown if the term 143 : * is not in the document 144 : */ 145 : void remove_posting(const std::string & tname, 146 : Xapian::termpos tpos, 147 : Xapian::termcount wdfdec = 1); 148 : 149 : /** Remove a term and all postings associated with it. 150 : * 151 : * @param tname The name of the term. 152 : * 153 : * @exception Xapian::InvalidArgumentError will be thrown if the term 154 : * is not in the document 155 : */ 156 : void remove_term(const std::string & tname); 157 : 158 : /// Remove all terms (and postings) from the document. 159 : void clear_terms(); 160 : 161 : /** The length of the termlist - i.e. the number of different terms 162 : * which index this document. 163 : */ 164 : Xapian::termcount termlist_count() const; 165 : 166 : /// Iterator for the terms in this document. 167 : TermIterator termlist_begin() const; 168 : 169 : /// Equivalent end iterator for termlist_begin(). 170 0 : TermIterator termlist_end() const { 171 0 : return TermIterator(NULL); 172 : } 173 : 174 : /// Count the values in this document. 175 : Xapian::termcount values_count() const; 176 : 177 : /// Iterator for the values in this document. 178 : ValueIterator values_begin() const; 179 : 180 : /// Equivalent end iterator for values_begin(). 181 : ValueIterator values_end() const; 182 : 183 : /** Get the document id which is associated with this document (if any). 184 : * 185 : * NB If multiple databases are being searched together, then this 186 : * will be the document id in the individual database, not the merged 187 : * database! 188 : * 189 : * @return If this document came from a database, return the document 190 : * id in that database. Otherwise, return 0. 191 : */ 192 : docid get_docid() const; 193 : 194 : /// Return a string describing this object. 195 : std::string get_description() const; 196 : }; 197 : 198 : } 199 : 200 : #endif // XAPIAN_INCLUDED_DOCUMENT_H |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Filename | Coverage | |||
base.h |
|
45.5 % | 5 / 11 lines | |
database.h |
|
100.0 % | 4 / 4 lines | |
document.h |
|
0.0 % | 0 / 2 lines | |
enquire.h |
|
89.7 % | 26 / 29 lines | |
error.h |
|
0.0 % | 0 / 3 lines | |
expanddecider.h |
|
100.0 % | 1 / 1 lines | |
postingiterator.h |
|
100.0 % | 2 / 2 lines | |
query.h |
|
72.7 % | 8 / 11 lines | |
termgenerator.h |
|
100.0 % | 2 / 2 lines | |
termiterator.h |
|
100.0 % | 4 / 4 lines | |
unicode.h |
|
87.5 % | 7 / 8 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** \file query.h 2 : * \brief Classes for representing a query 3 : */ 4 : /* Copyright 1999,2000,2001 BrightStation PLC 5 : * Copyright 2002 Ananova Ltd 6 : * Copyright 2003,2004,2005,2006,2007 Olly Betts 7 : * Copyright 2006,2007,2008 Lemur Consulting Ltd 8 : * 9 : * This program is free software; you can redistribute it and/or 10 : * modify it under the terms of the GNU General Public License as 11 : * published by the Free Software Foundation; either version 2 of the 12 : * License, or (at your option) any later version. 13 : * 14 : * This program is distributed in the hope that it will be useful, 15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : * GNU General Public License for more details. 18 : * 19 : * You should have received a copy of the GNU General Public License 20 : * along with this program; if not, write to the Free Software 21 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 22 : * USA 23 : */ 24 : 25 : #ifndef XAPIAN_INCLUDED_QUERY_H 26 : #define XAPIAN_INCLUDED_QUERY_H 27 : 28 : #include <string> 29 : #include <vector> 30 : 31 : #include <xapian/base.h> 32 : #include <xapian/deprecated.h> 33 : #include <xapian/types.h> 34 : #include <xapian/termiterator.h> 35 : #include <xapian/visibility.h> 36 : 37 : // FIXME: sort this out so we avoid exposing Xapian::Query::Internal 38 : // - we need to at present so that the Xapian::Query's template ctors 39 : // compile. 40 : class LocalSubMatch; 41 : class MultiMatch; 42 : class QueryOptimiser; 43 : struct SortPosName; 44 : 45 : namespace Xapian { 46 : 47 : /** Class representing a query. 48 : * 49 : * Queries are represented as a tree of objects. 50 : */ 51 : class XAPIAN_VISIBILITY_DEFAULT Query { 52 : public: 53 : /// Class holding details of the query 54 : class Internal; 55 : /// @private @internal Reference counted internals. 56 : Xapian::Internal::RefCntPtr<Internal> internal; 57 : 58 : /// Enum of possible query operations 59 : typedef enum { 60 : /// Return iff both subqueries are satisfied 61 : OP_AND, 62 : 63 : /// Return if either subquery is satisfied 64 : OP_OR, 65 : 66 : /// Return if left but not right satisfied 67 : OP_AND_NOT, 68 : 69 : /// Return if one query satisfied, but not both 70 : OP_XOR, 71 : 72 : /// Return iff left satisfied, but use weights from both 73 : OP_AND_MAYBE, 74 : 75 : /// As AND, but use only weights from left subquery 76 : OP_FILTER, 77 : 78 : /** Find occurrences of a list of terms with all the terms 79 : * occurring within a specified window of positions. 80 : * Each occurrence of a term must be at a different position, 81 : * but the order they appear in is irrelevant. 82 : * 83 : * The window parameter should be specified for this operation, 84 : * but will default to the number of terms in the list. 85 : */ 86 : OP_NEAR, 87 : 88 : /** Find occurrences of a list of terms with all the terms 89 : * occurring within a specified window of positions, and all 90 : * the terms appearing in the order specified. Each occurrence 91 : * of a term must be at a different position. 92 : * 93 : * The window parameter should be specified for this operation, 94 : * but will default to the number of terms in the list. 95 : */ 96 : OP_PHRASE, 97 : 98 : /** Filter by a range test on a document value. */ 99 : OP_VALUE_RANGE, 100 : 101 : /** Scale the weight of a subquery by the specified factor. 102 : * 103 : * A factor of 0 means this subquery will contribute no weight to 104 : * the query - it will act as a purely boolean subquery. 105 : * 106 : * If the factor is negative, Xapian::InvalidArgumentError will 107 : * be thrown. 108 : */ 109 : OP_SCALE_WEIGHT, 110 : 111 : /** Select an elite set from the subqueries, and perform 112 : * a query with these combined as an OR query. 113 : */ 114 : OP_ELITE_SET, 115 : 116 : /** Filter by a greater-than-or-equal test on a document value. */ 117 : OP_VALUE_GE, 118 : 119 : /** Filter by a less-than-or-equal test on a document value. */ 120 : OP_VALUE_LE 121 : } op; 122 : 123 : /** Copy constructor. */ 124 : Query(const Query & copyme); 125 : 126 : /** Assignment. */ 127 : Query & operator=(const Query & copyme); 128 : 129 : /** Default constructor: makes an empty query which matches no 130 : * documents. 131 : * 132 : * Also useful for defining a Query object to be assigned to later. 133 : * 134 : * An exception will be thrown if an attempt is made to use an 135 : * undefined query when building up a composite query. 136 : */ 137 : Query(); 138 : 139 : /** Destructor. */ 140 : ~Query(); 141 : 142 : /** A query consisting of a single term. */ 143 : Query(const std::string & tname_, Xapian::termcount wqf_ = 1, 144 : Xapian::termpos pos_ = 0); 145 : 146 : /** A query consisting of two subqueries, opp-ed together. */ 147 : Query(Query::op op_, const Query & left, const Query & right); 148 : 149 : /** A query consisting of two termnames opp-ed together. */ 150 : Query(Query::op op_, 151 : const std::string & left, const std::string & right); 152 : 153 : /** Combine a number of Xapian::Query-s with the specified operator. 154 : * 155 : * The Xapian::Query objects are specified with begin and end 156 : * iterators. 157 : * 158 : * AND, OR, NEAR and PHRASE can take any number of subqueries. 159 : * Other operators take exactly two subqueries. 160 : * 161 : * The iterators may be to Xapian::Query objects, pointers to 162 : * Xapian::Query objects, or termnames (std::string-s). 163 : * 164 : * For NEAR and PHRASE, a window size can be specified in parameter. 165 : * 166 : * For ELITE_SET, the elite set size can be specified in parameter. 167 : */ 168 : template <class Iterator> 169 : Query(Query::op op_, Iterator qbegin, Iterator qend, 170 : Xapian::termcount parameter = 0); 171 : 172 : /** Apply the specified operator to a single Xapian::Query object. 173 : * 174 : * @deprecated This method is deprecated because it isn't useful, 175 : * since none of the current query operators can be usefully 176 : * applied to a single subquery with a parameter value. 177 : */ 178 : XAPIAN_DEPRECATED(Query(Query::op op_, Xapian::Query q)); 179 : 180 : /** Apply the specified operator to a single Xapian::Query object, with 181 : * a double parameter. 182 : */ 183 : Query(Query::op op_, Xapian::Query q, double parameter); 184 : 185 : /** Construct a value range query on a document value. 186 : * 187 : * A value range query matches those documents which have a value 188 : * stored in the slot given by @a valno which is in the range 189 : * specified by @a begin and @a end (in lexicographical 190 : * order), including the endpoints. 191 : * 192 : * @param op_ The operator to use for the query. Currently, must 193 : * be OP_VALUE_RANGE. 194 : * @param valno The slot number to get the value from. 195 : * @param begin The start of the range. 196 : * @param end The end of the range. 197 : */ 198 : Query(Query::op op_, Xapian::valueno valno, 199 : const std::string &begin, const std::string &end); 200 : 201 : /** Construct a value comparison query on a document value. 202 : * 203 : * This query matches those documents which have a value stored in the 204 : * slot given by @a valno which compares, as specified by the 205 : * operator, to @a value. 206 : * 207 : * @param op_ The operator to use for the query. Currently, must 208 : * be OP_VALUE_GE or OP_VALUE_LE. 209 : * @param valno The slot number to get the value from. 210 : * @param value The value to compare. 211 : */ 212 : Query(Query::op op_, Xapian::valueno valno, const std::string &value); 213 : 214 : /** A query which matches all documents in the database. */ 215 : static Xapian::Query MatchAll; 216 : 217 : /** A query which matches no documents. */ 218 : static Xapian::Query MatchNothing; 219 : 220 : /** Get the length of the query, used by some ranking formulae. 221 : * This value is calculated automatically - if you want to override 222 : * it you can pass a different value to Enquire::set_query(). 223 : */ 224 : Xapian::termcount get_length() const; 225 : 226 : /** Return a Xapian::TermIterator returning all the terms in the query, 227 : * in order of termpos. If multiple terms have the same term 228 : * position, their order is unspecified. Duplicates (same term and 229 : * termpos) will be removed. 230 : */ 231 : TermIterator get_terms_begin() const; 232 : 233 : /** Return a Xapian::TermIterator to the end of the list of terms in the 234 : * query. 235 : */ 236 : TermIterator get_terms_end() const { 237 : return TermIterator(NULL); 238 : } 239 : 240 : /** Test if the query is empty (i.e. was constructed using 241 : * the default ctor or with an empty iterator ctor). 242 : */ 243 : bool empty() const; 244 : 245 : /// Return a string describing this object. 246 : std::string get_description() const; 247 : 248 : private: 249 : void add_subquery(const Query & subq); 250 : void add_subquery(const Query * subq); 251 : void add_subquery(const std::string & tname); 252 : void start_construction(Query::op op_, Xapian::termcount parameter); 253 : void end_construction(); 254 : void abort_construction(); 255 : }; 256 : 257 : template <class Iterator> 258 19 : Query::Query(Query::op op_, Iterator qbegin, Iterator qend, termcount parameter) 259 19 : : internal(0) 260 : { 261 : try { 262 19 : start_construction(op_, parameter); 263 : 264 : /* Add all the elements */ 265 61 : while (qbegin != qend) { 266 23 : add_subquery(*qbegin); 267 23 : ++qbegin; 268 : } 269 : 270 19 : end_construction(); 271 0 : } catch (...) { 272 0 : abort_construction(); 273 0 : throw; 274 : } 275 19 : } 276 : 277 : /// @internal Internal class, implementing most of Xapian::Query. 278 : class XAPIAN_VISIBILITY_DEFAULT Query::Internal : public Xapian::Internal::RefCntBase { 279 : friend class ::LocalSubMatch; 280 : friend class ::MultiMatch; 281 : friend class ::QueryOptimiser; 282 : friend struct ::SortPosName; 283 : friend class Query; 284 : public: 285 : static const int OP_LEAF = -1; 286 : 287 : /// The container type for storing pointers to subqueries 288 : typedef std::vector<Internal *> subquery_list; 289 : 290 : /// Type storing the operation 291 : typedef int op_t; 292 : 293 : private: 294 : /// Operation to be performed at this node 295 : Xapian::Query::Internal::op_t op; 296 : 297 : /// Sub queries on which to perform operation 298 : subquery_list subqs; 299 : 300 : /** For NEAR or PHRASE, how close terms must be to match: all terms 301 : * within the operation must occur in a window of this size. 302 : * 303 : * For ELITE_SET, the number of terms to select from those specified. 304 : * 305 : * For RANGE, the value number to apply the range test to. 306 : */ 307 : Xapian::termcount parameter; 308 : 309 : /** Term that this node represents, or start of a range query. 310 : * 311 : * For a leaf node, this holds the term name. For an OP_VALUE_RANGE 312 : * query this holds the start of the range. For an OP_VALUE_GE or 313 : * OP_VALUE_LE query this holds the value to compare against. 314 : */ 315 : std::string tname; 316 : 317 : /** Used to store the end of a range query. */ 318 : std::string str_parameter; 319 : 320 : /// Position in query of this term - leaf node only 321 : Xapian::termpos term_pos; 322 : 323 : /// Within query frequency of this term - leaf node only 324 : Xapian::termcount wqf; 325 : 326 : /** swap the contents of this with another Xapian::Query::Internal, 327 : * in a way which is guaranteed not to throw. This is 328 : * used with the assignment operator to make it exception 329 : * safe. 330 : * It's important to adjust swap with any addition of 331 : * member variables! 332 : */ 333 : void swap(Query::Internal &other); 334 : 335 : /// Copy another Xapian::Query::Internal into self. 336 : void initialise_from_copy(const Query::Internal & copyme); 337 : 338 : void accumulate_terms( 339 : std::vector<std::pair<std::string, Xapian::termpos> > &terms) const; 340 : 341 : /** Simplify the query. 342 : * For example, an AND query with only one subquery would become the 343 : * subquery itself. 344 : */ 345 : Internal * simplify_query(); 346 : 347 : /** Perform checks that query is valid. (eg, has correct number of 348 : * sub queries.) Throw an exception if not. This is initially called 349 : * on the query before any simplifications have been made, and after 350 : * simplications. 351 : */ 352 : void validate_query() const; 353 : 354 : /** Simplify any matchnothing subqueries, either eliminating them, 355 : * or setting this query to matchnothing, depending on the query 356 : * operator. Returns true if simplification resulted in a 357 : * matchnothing query. 358 : */ 359 : bool simplify_matchnothing(); 360 : 361 : /** Get a string describing the given query type. 362 : */ 363 : static std::string get_op_name(Xapian::Query::Internal::op_t op); 364 : 365 : /** Collapse the subqueries together if appropriate. 366 : */ 367 : void collapse_subqs(); 368 : 369 : /** Flatten a query structure, by changing, for example, 370 : * "A NEAR (B AND C)" to "(A NEAR B) AND (A NEAR C)" 371 : */ 372 : void flatten_subqs(); 373 : 374 : /** Implementation of serialisation; called recursively. 375 : */ 376 : std::string serialise(Xapian::termpos & curpos) const; 377 : 378 : public: 379 : /** Copy constructor. */ 380 : Internal(const Query::Internal & copyme); 381 : 382 : /** Assignment. */ 383 : void operator=(const Query::Internal & copyme); 384 : 385 : /** A query consisting of a single term. */ 386 : explicit Internal(const std::string & tname_, Xapian::termcount wqf_ = 1, 387 : Xapian::termpos term_pos_ = 0); 388 : 389 : /** Create internals given only the operator and a parameter. */ 390 : Internal(op_t op_, Xapian::termcount parameter); 391 : 392 : /** Construct a range query on a document value. */ 393 : Internal(op_t op_, Xapian::valueno valno, 394 : const std::string &begin, const std::string &end); 395 : 396 : /** Construct a value greater-than-or-equal query on a document value. 397 : */ 398 : Internal(op_t op_, Xapian::valueno valno, const std::string &value); 399 : 400 : /** Destructor. */ 401 : ~Internal(); 402 : 403 : static Xapian::Query::Internal * unserialise(const std::string &s); 404 : 405 : /** Add a subquery. 406 : */ 407 : void add_subquery(const Query::Internal * subq); 408 : 409 : void set_dbl_parameter(double dbl_parameter_); 410 : 411 : double get_dbl_parameter() const; 412 : 413 : /** Finish off the construction. 414 : */ 415 : Query::Internal * end_construction(); 416 : 417 : /** Return a string in an easily parsed form 418 : * which contains all the information in a query. 419 : */ 420 : std::string serialise() const { 421 : Xapian::termpos curpos = 1; 422 : return serialise(curpos); 423 : } 424 : 425 : /// Return a string describing this object. 426 : std::string get_description() const; 427 : 428 : /** Get the numeric parameter used in this query. 429 : * 430 : * This is used by the QueryParser to get the value number for 431 : * VALUE_RANGE queries. It should be replaced by a public method on 432 : * the Query class at some point, but the API which should be used for 433 : * that is unclear, so this is a temporary workaround. 434 : */ 435 : Xapian::termcount get_parameter() const { return parameter; } 436 : 437 : /** Get the length of the query, used by some ranking formulae. 438 : * This value is calculated automatically - if you want to override 439 : * it you can pass a different value to Enquire::set_query(). 440 : */ 441 : Xapian::termcount get_length() const; 442 : 443 : /** Return an iterator over all the terms in the query, 444 : * in order of termpos. If multiple terms have the same term 445 : * position, their order is unspecified. Duplicates (same term and 446 : * termpos) will be removed. 447 : */ 448 : TermIterator get_terms() const; 449 : }; 450 : 451 : } 452 : 453 : #endif /* XAPIAN_INCLUDED_QUERY_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** @file termgenerator.h 2 : * @brief parse free text and generate terms 3 : */ 4 : /* Copyright (C) 2007 Olly Betts 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 2 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, write to the Free Software 18 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 : */ 20 : 21 : #ifndef XAPIAN_INCLUDED_TERMGENERATOR_H 22 : #define XAPIAN_INCLUDED_TERMGENERATOR_H 23 : 24 : #include <xapian/base.h> 25 : #include <xapian/types.h> 26 : #include <xapian/unicode.h> 27 : #include <xapian/visibility.h> 28 : 29 : #include <string> 30 : 31 : namespace Xapian { 32 : 33 : class Document; 34 : class Stem; 35 : class Stopper; 36 : class WritableDatabase; 37 : 38 : /** Parses a piece of text and generate terms. 39 : * 40 : * This module takes a piece of text and parses it to produce words which are 41 : * then used to generate suitable terms for indexing. The terms generated are 42 : * suitable for use with Query objects produced by the QueryParser class. 43 : */ 44 : class XAPIAN_VISIBILITY_DEFAULT TermGenerator { 45 : public: 46 : /// @private @internal Class representing the TermGenerator internals. 47 : class Internal; 48 : /// @private @internal Reference counted internals. 49 : Xapian::Internal::RefCntPtr<Internal> internal; 50 : 51 : /// Copy constructor. 52 : TermGenerator(const TermGenerator & o); 53 : 54 : /// Assignment. 55 : TermGenerator & operator=(const TermGenerator & o); 56 : 57 : /// Default constructor. 58 : TermGenerator(); 59 : 60 : /// Destructor. 61 : ~TermGenerator(); 62 : 63 : /// Set the Xapian::Stem object to be used for generating stemmed terms. 64 : void set_stemmer(const Xapian::Stem & stemmer); 65 : 66 : /// Set the Xapian::Stopper object to be used for identifying stopwords. 67 : void set_stopper(const Xapian::Stopper *stop = NULL); 68 : 69 : /// Set the current document. 70 : void set_document(const Xapian::Document & doc); 71 : 72 : /// Get the current document. 73 : const Xapian::Document & get_document() const; 74 : 75 : /// Set the database to index spelling data to. 76 : void set_database(const Xapian::WritableDatabase &db); 77 : 78 : /// Flags to OR together and pass to TermGenerator::set_flags(). 79 : enum flags { 80 : /// Index data required for spelling correction. 81 : FLAG_SPELLING = 128 // Value matches QueryParser flag. 82 : }; 83 : 84 : /** Set flags. 85 : * 86 : * The new value of flags is: (flags & mask) ^ toggle 87 : * 88 : * To just set the flags, pass the new flags in toggle and the 89 : * default value for mask. 90 : * 91 : * @param toggle Flags to XOR. 92 : * @param mask Flags to AND with first. 93 : * 94 : * @return The old flags setting. 95 : */ 96 : flags set_flags(flags toggle, flags mask = flags(0)); 97 : 98 : /** Index some text. 99 : * 100 : * @param weight The wdf increment (default 1). 101 : * @param prefix The term prefix to use (default is no prefix). 102 : */ 103 : void index_text(const Xapian::Utf8Iterator & itor, 104 : Xapian::termcount weight = 1, 105 : const std::string & prefix = ""); 106 : 107 : /** Index some text in a std::string. 108 : * 109 : * @param weight The wdf increment (default 1). 110 : * @param prefix The term prefix to use (default is no prefix). 111 : */ 112 : void index_text(const std::string & text, 113 : Xapian::termcount weight = 1, 114 : const std::string & prefix = "") { 115 : return index_text(Utf8Iterator(text), weight, prefix); 116 : } 117 : 118 : /** Index some text without positional information. 119 : * 120 : * Just like index_text, but no positional information is generated. This 121 : * means that the database will be significantly smaller, but that phrase 122 : * searching and NEAR won't be supported. 123 : */ 124 : void index_text_without_positions(const Xapian::Utf8Iterator & itor, 125 : Xapian::termcount weight = 1, 126 : const std::string & prefix = ""); 127 : 128 : /** Index some text in a std::string without positional information. 129 : * 130 : * Just like index_text, but no positional information is generated. This 131 : * means that the database will be significantly smaller, but that phrase 132 : * searching and NEAR won't be supported. 133 : */ 134 : void index_text_without_positions(const std::string & text, 135 : Xapian::termcount weight = 1, 136 5208 : const std::string & prefix = "") { 137 5208 : return index_text_without_positions(Utf8Iterator(text), weight, prefix); 138 : } 139 : 140 : /** Increase the termpos used by index_text by @a delta. 141 : * 142 : * This can be used to prevent phrase searches from spanning two 143 : * unconnected blocks of text (e.g. the title and body text). 144 : */ 145 : void increase_termpos(Xapian::termcount delta = 100); 146 : 147 : /// Get the current term position. 148 : Xapian::termcount get_termpos() const; 149 : 150 : /// Set the current term position. 151 : void set_termpos(Xapian::termcount termpos); 152 : 153 : /// Return a string describing this object. 154 : std::string get_description() const; 155 : }; 156 : 157 : } 158 : 159 : #endif // XAPIAN_INCLUDED_TERMGENERATOR_H |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** \file postingiterator.h 2 : * \brief Classes for iterating through posting lists 3 : */ 4 : /* Copyright 1999,2000,2001 BrightStation PLC 5 : * Copyright 2002 Ananova Ltd 6 : * Copyright 2003,2004,2005,2007 Olly Betts 7 : * 8 : * This program is free software; you can redistribute it and/or 9 : * modify it under the terms of the GNU General Public License as 10 : * published by the Free Software Foundation; either version 2 of the 11 : * License, or (at your option) any later version. 12 : * 13 : * This program is distributed in the hope that it will be useful, 14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : * GNU General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU General Public License 19 : * along with this program; if not, write to the Free Software 20 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 21 : * USA 22 : */ 23 : 24 : #ifndef XAPIAN_INCLUDED_POSTINGITERATOR_H 25 : #define XAPIAN_INCLUDED_POSTINGITERATOR_H 26 : 27 : #include <iterator> 28 : #include <string> 29 : 30 : #include <xapian/base.h> 31 : #include <xapian/types.h> 32 : #include <xapian/positioniterator.h> 33 : #include <xapian/visibility.h> 34 : 35 : namespace Xapian { 36 : 37 : class Database; 38 : 39 : /** @internal A wrapper class for a docid which returns the docid if 40 : * dereferenced with *. We need this to implement input_iterator semantics. 41 : */ 42 : class DocIDWrapper { 43 : private: 44 : docid did; 45 : public: 46 : explicit DocIDWrapper(docid did_) : did(did_) { } 47 : docid operator*() const { return did; } 48 : }; 49 : 50 : /** An iterator pointing to items in a list of postings. 51 : */ 52 : class XAPIAN_VISIBILITY_DEFAULT PostingIterator { 53 : public: 54 : class Internal; 55 : /// @private @internal Reference counted internals. 56 : Xapian::Internal::RefCntPtr<Internal> internal; 57 : 58 : private: 59 : friend class Database; // So Database can construct us 60 : 61 : explicit PostingIterator(Internal *internal_); 62 : 63 : public: 64 : friend bool operator==(const PostingIterator &a, 65 : const PostingIterator &b); 66 : 67 : /// Default constructor - for declaring an uninitialised iterator 68 : PostingIterator(); 69 : 70 : /// Destructor 71 : ~PostingIterator(); 72 : 73 : /** Copying is allowed. The internals are reference counted, so 74 : * copying is also cheap. 75 : */ 76 : PostingIterator(const PostingIterator &other); 77 : 78 : /** Assignment is allowed. The internals are reference counted, 79 : * so assignment is also cheap. 80 : */ 81 : void operator=(const PostingIterator &other); 82 : 83 : PostingIterator & operator++(); 84 : 85 : DocIDWrapper operator++(int) { 86 : Xapian::docid tmp = **this; 87 : operator++(); 88 : return DocIDWrapper(tmp); 89 : } 90 : 91 : /** Skip the iterator to document did, or the first document after did 92 : * if did isn't in the list of documents being iterated. 93 : */ 94 : void skip_to(Xapian::docid did); 95 : 96 : // Get the weight of the posting at the current position: will 97 : // need to set a weight object for this to work. 98 : // Xapian::weight get_weight() const; 99 : 100 : /// Get the document id at the current position in the postlist. 101 : Xapian::docid operator *() const; 102 : 103 : /** Get the length of the document at the current position in the 104 : * postlist. 105 : * 106 : * This information may be stored in the postlist, in which case 107 : * this lookup should be extremely fast (indeed, not require further 108 : * disk access). If the information is not present in the postlist, 109 : * it will be retrieved from the database, at a greater performance 110 : * cost. 111 : */ 112 : Xapian::doclength get_doclength() const; 113 : 114 : /** Get the within document frequency of the document at the 115 : * current position in the postlist. 116 : */ 117 : Xapian::termcount get_wdf() const; 118 : 119 : /** Return PositionIterator pointing to start of positionlist for 120 : * current document. 121 : */ 122 : PositionIterator positionlist_begin() const; 123 : 124 : /** Return PositionIterator pointing to end of positionlist for 125 : * current document. 126 : */ 127 : PositionIterator positionlist_end() const { 128 : return PositionIterator(NULL); 129 : } 130 : 131 : // Don't expose these methods here. A container iterator doesn't 132 : // provide a method to find the size of the container... 133 : // Xapian::doccount get_termfreq() const; 134 : // Xapian::termcount get_collection_freq() const; 135 : 136 : /// Return a string describing this object. 137 : std::string get_description() const; 138 : 139 : /// Allow use as an STL iterator 140 : //@{ 141 : typedef std::input_iterator_tag iterator_category; 142 : typedef Xapian::docid value_type; 143 : typedef Xapian::doccount_diff difference_type; 144 : typedef Xapian::docid * pointer; 145 : typedef Xapian::docid & reference; 146 : //@} 147 : }; 148 : 149 : /// Test equality of two PostingIterators 150 10 : inline bool operator==(const PostingIterator &a, const PostingIterator &b) 151 : { 152 10 : return (a.internal.get() == b.internal.get()); 153 : } 154 : 155 : /// Test inequality of two PostingIterators 156 : inline bool operator!=(const PostingIterator &a, const PostingIterator &b) 157 : { 158 : return !(a == b); 159 : } 160 : 161 : } 162 : 163 : #endif /* XAPIAN_INCLUDED_POSTINGITERATOR_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** @file error.h 2 : * @brief Hierarchy of classes which Xapian can throw as exceptions. 3 : */ 4 : /* Warning: This file is generated by ./generate-exceptions - do not modify directly! */ 5 : /* Copyright (C) 2003,2004,2006,2007 Olly Betts 6 : * 7 : * This program is free software; you can redistribute it and/or 8 : * modify it under the terms of the GNU General Public License as 9 : * published by the Free Software Foundation; either version 2 of the 10 : * License, or (at your option) any later version. 11 : * 12 : * This program is distributed in the hope that it will be useful, 13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : * GNU General Public License for more details. 16 : * 17 : * You should have received a copy of the GNU General Public License 18 : * along with this program; if not, write to the Free Software 19 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 : */ 21 : 22 : #ifndef XAPIAN_INCLUDED_ERROR_H 23 : #define XAPIAN_INCLUDED_ERROR_H 24 : 25 : #include <string> 26 : #include <xapian/deprecated.h> 27 : #include <xapian/visibility.h> 28 : 29 : namespace Xapian { 30 : 31 : class ErrorHandler; 32 : 33 : /** All exceptions thrown by Xapian are subclasses of Xapian::Error. 34 : * 35 : * This class can not be instantiated directly - instead a subclass should 36 : * be used. 37 : */ 38 : class XAPIAN_VISIBILITY_DEFAULT Error { 39 : // ErrorHandler needs to be able to access Error::already_handled. 40 : friend class ErrorHandler; 41 : 42 : /// Message giving details of the error, intended for human consumption. 43 : std::string msg; 44 : 45 : /** Optional context information. 46 : * 47 : * This context is intended for use by Xapian::ErrorHandler (for example 48 : * so it can know which remote server is unreliable and report the problem 49 : * and remove that server from those being searched). But it's typically 50 : * a plain-text string, and so also fit for human consumption. 51 : */ 52 : std::string context; 53 : 54 : /// The type of this error (e.g. DocNotFoundError.) 55 : const char * type; 56 : 57 : /** Optional value of 'errno' associated with this error. 58 : * 59 : * If no value is associated, this member variable will be 0. 60 : * 61 : * On UNIX, if this value is < 0, it's a negated h_errno value (giving 62 : * an error from gethostbyname() or similar). 63 : * 64 : * On Windows, if this value is < 0, it's a negated Windows error code 65 : * (as given by GetLastError() or WSAGetLastError()). 66 : * 67 : * NB We don't just call this member "errno" to avoid problems on 68 : * platforms where errno is a preprocessor macro. 69 : */ 70 : int my_errno; 71 : 72 : /** The error string derived from my_errno. 73 : * 74 : * This string is generated from my_errno lazily. 75 : */ 76 : mutable std::string error_string; 77 : 78 : /// True if this error has already been passed to an ErrorHandler. 79 : bool already_handled; 80 : 81 : /// Don't allow assignment of the base class. 82 : void operator=(const Error &o); 83 : 84 : protected: 85 : /** @private @internal 86 : * @brief Constructor for use by constructors of derived classes. 87 : */ 88 : Error(const std::string &msg_, const std::string &context_, 89 : const char * type_, const char * error_string_); 90 : 91 : /** @private @internal 92 : * @brief Constructor for use by constructors of derived classes. 93 : */ 94 : Error(const std::string &msg_, const std::string &context_, 95 : const char * type_, int errno_) 96 : : msg(msg_), context(context_), type(type_), my_errno(errno_), 97 : error_string(), already_handled(false) { } 98 : 99 : public: 100 : /// The type of this error (e.g. "DocNotFoundError".) 101 0 : const char * get_type() const { return type; } 102 : 103 : /// Message giving details of the error, intended for human consumption. 104 0 : const std::string & get_msg() const { return msg; } 105 : 106 : /** Optional context information. 107 : * 108 : * This context is intended for use by Xapian::ErrorHandler (for example 109 : * so it can know which remote server is unreliable and report the problem 110 : * and remove that server from those being searched). But it's typically 111 : * a plain-text string, and so also fit for human consumption. 112 : */ 113 0 : const std::string & get_context() const { return context; } 114 : 115 : /** Returns any system error string associated with this exception. 116 : * 117 : * The system error string may come from errno, h_errno (on UNIX), or 118 : * GetLastError() (on MS Windows). If there is no associated system 119 : * error string, NULL is returned. 120 : */ 121 : const char * get_error_string() const; 122 : 123 : /** Optional value of 'errno' associated with this error. 124 : * 125 : * If no 'errno' value is associated, returns 0. If the returned value 126 : * is negative, it's a platform-specific error code (on UNIX, -h_errno; 127 : * on MS Windows, -GetLastError()). 128 : * 129 : * @deprecated This method is deprecated, because errno values aren't 130 : * portable between platforms, so we can't serialise them when passing 131 : * exceptions from a remote server to a client. Use the 132 : * get_error_string() method instead. 133 : */ 134 : XAPIAN_DEPRECATED(int get_errno() const); 135 : 136 : /// Return a string describing this object. 137 : std::string get_description() const; 138 : }; 139 : 140 : inline int Xapian::Error::get_errno() const { return my_errno; } 141 : 142 : /** The base class for exceptions indicating errors in the program logic. 143 : * 144 : * A subclass of LogicError will be thrown if Xapian detects a violation 145 : * of a class invariant or a logical precondition or postcondition, etc. 146 : */ 147 : class XAPIAN_VISIBILITY_DEFAULT LogicError : public Error { 148 : protected: 149 : /** @private @internal 150 : * @brief Constructor for use by constructors of derived classes. 151 : */ 152 : LogicError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 153 : : Error(msg_, context_, type_, error_string_) {} 154 : 155 : /** @private @internal 156 : * @brief Constructor for use by constructors of derived classes. 157 : */ 158 : LogicError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 159 : : Error(msg_, context_, type_, errno_) {} 160 : }; 161 : 162 : /** The base class for exceptions indicating errors only detectable at runtime. 163 : * 164 : * A subclass of RuntimeError will be thrown if Xapian detects an error 165 : * which is exception derived from RuntimeError is thrown when an 166 : * error is caused by problems with the data or environment rather 167 : * than a programming mistake. 168 : */ 169 : class XAPIAN_VISIBILITY_DEFAULT RuntimeError : public Error { 170 : protected: 171 : /** @private @internal 172 : * @brief Constructor for use by constructors of derived classes. 173 : */ 174 : RuntimeError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 175 : : Error(msg_, context_, type_, error_string_) {} 176 : 177 : /** @private @internal 178 : * @brief Constructor for use by constructors of derived classes. 179 : */ 180 : RuntimeError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 181 : : Error(msg_, context_, type_, errno_) {} 182 : }; 183 : 184 : /** AssertionError is thrown if a logical assertion inside Xapian fails. 185 : * 186 : * In a debug build of Xapian, a failed assertion in the core library code 187 : * will cause AssertionError to be thrown. 188 : * 189 : * This represents a bug in Xapian (either an invariant, precondition, etc 190 : * has been violated, or the assertion is incorrect!) 191 : */ 192 : class XAPIAN_VISIBILITY_DEFAULT AssertionError : public LogicError { 193 : public: 194 : /** @private @internal 195 : * @brief Private constructor for use by remote backend. 196 : * 197 : * @param error_string_ Optional string describing error. May be NULL. 198 : */ 199 : AssertionError(const std::string &msg_, const std::string &context_, const char * error_string_) 200 : : LogicError(msg_, context_, "AssertionError", error_string_) {} 201 : /** General purpose constructor which allows setting errno. */ 202 : explicit AssertionError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 203 : : LogicError(msg_, context_, "AssertionError", errno_) {} 204 : /** Construct from message and errno value. */ 205 : AssertionError(const std::string &msg_, int errno_) 206 : : LogicError(msg_, "", "AssertionError", errno_) {} 207 : protected: 208 : /** @private @internal 209 : * @brief Constructor for use by constructors of derived classes. 210 : */ 211 : AssertionError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 212 : : LogicError(msg_, context_, type_, error_string_) {} 213 : 214 : /** @private @internal 215 : * @brief Constructor for use by constructors of derived classes. 216 : */ 217 : AssertionError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 218 : : LogicError(msg_, context_, type_, errno_) {} 219 : }; 220 : 221 : /** InvalidArgumentError indicates an invalid parameter value was passed to the API. 222 : */ 223 : class XAPIAN_VISIBILITY_DEFAULT InvalidArgumentError : public LogicError { 224 : public: 225 : /** @private @internal 226 : * @brief Private constructor for use by remote backend. 227 : * 228 : * @param error_string_ Optional string describing error. May be NULL. 229 : */ 230 : InvalidArgumentError(const std::string &msg_, const std::string &context_, const char * error_string_) 231 : : LogicError(msg_, context_, "InvalidArgumentError", error_string_) {} 232 : /** General purpose constructor which allows setting errno. */ 233 : explicit InvalidArgumentError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 234 : : LogicError(msg_, context_, "InvalidArgumentError", errno_) {} 235 : /** Construct from message and errno value. */ 236 : InvalidArgumentError(const std::string &msg_, int errno_) 237 : : LogicError(msg_, "", "InvalidArgumentError", errno_) {} 238 : protected: 239 : /** @private @internal 240 : * @brief Constructor for use by constructors of derived classes. 241 : */ 242 : InvalidArgumentError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 243 : : LogicError(msg_, context_, type_, error_string_) {} 244 : 245 : /** @private @internal 246 : * @brief Constructor for use by constructors of derived classes. 247 : */ 248 : InvalidArgumentError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 249 : : LogicError(msg_, context_, type_, errno_) {} 250 : }; 251 : 252 : /** InvalidOperationError indicates the API was used in an invalid way. 253 : */ 254 : class XAPIAN_VISIBILITY_DEFAULT InvalidOperationError : public LogicError { 255 : public: 256 : /** @private @internal 257 : * @brief Private constructor for use by remote backend. 258 : * 259 : * @param error_string_ Optional string describing error. May be NULL. 260 : */ 261 : InvalidOperationError(const std::string &msg_, const std::string &context_, const char * error_string_) 262 : : LogicError(msg_, context_, "InvalidOperationError", error_string_) {} 263 : /** General purpose constructor which allows setting errno. */ 264 : explicit InvalidOperationError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 265 : : LogicError(msg_, context_, "InvalidOperationError", errno_) {} 266 : /** Construct from message and errno value. */ 267 : InvalidOperationError(const std::string &msg_, int errno_) 268 : : LogicError(msg_, "", "InvalidOperationError", errno_) {} 269 : protected: 270 : /** @private @internal 271 : * @brief Constructor for use by constructors of derived classes. 272 : */ 273 : InvalidOperationError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 274 : : LogicError(msg_, context_, type_, error_string_) {} 275 : 276 : /** @private @internal 277 : * @brief Constructor for use by constructors of derived classes. 278 : */ 279 : InvalidOperationError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 280 : : LogicError(msg_, context_, type_, errno_) {} 281 : }; 282 : 283 : /** UnimplementedError indicates an attempt to use an unimplemented feature. */ 284 : class XAPIAN_VISIBILITY_DEFAULT UnimplementedError : public LogicError { 285 : public: 286 : /** @private @internal 287 : * @brief Private constructor for use by remote backend. 288 : * 289 : * @param error_string_ Optional string describing error. May be NULL. 290 : */ 291 : UnimplementedError(const std::string &msg_, const std::string &context_, const char * error_string_) 292 : : LogicError(msg_, context_, "UnimplementedError", error_string_) {} 293 : /** General purpose constructor which allows setting errno. */ 294 : explicit UnimplementedError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 295 : : LogicError(msg_, context_, "UnimplementedError", errno_) {} 296 : /** Construct from message and errno value. */ 297 : UnimplementedError(const std::string &msg_, int errno_) 298 : : LogicError(msg_, "", "UnimplementedError", errno_) {} 299 : protected: 300 : /** @private @internal 301 : * @brief Constructor for use by constructors of derived classes. 302 : */ 303 : UnimplementedError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 304 : : LogicError(msg_, context_, type_, error_string_) {} 305 : 306 : /** @private @internal 307 : * @brief Constructor for use by constructors of derived classes. 308 : */ 309 : UnimplementedError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 310 : : LogicError(msg_, context_, type_, errno_) {} 311 : }; 312 : 313 : /** DatabaseError indicates some sort of database related error. */ 314 : class XAPIAN_VISIBILITY_DEFAULT DatabaseError : public RuntimeError { 315 : public: 316 : /** @private @internal 317 : * @brief Private constructor for use by remote backend. 318 : * 319 : * @param error_string_ Optional string describing error. May be NULL. 320 : */ 321 : DatabaseError(const std::string &msg_, const std::string &context_, const char * error_string_) 322 : : RuntimeError(msg_, context_, "DatabaseError", error_string_) {} 323 : /** General purpose constructor which allows setting errno. */ 324 : explicit DatabaseError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 325 : : RuntimeError(msg_, context_, "DatabaseError", errno_) {} 326 : /** Construct from message and errno value. */ 327 : DatabaseError(const std::string &msg_, int errno_) 328 : : RuntimeError(msg_, "", "DatabaseError", errno_) {} 329 : protected: 330 : /** @private @internal 331 : * @brief Constructor for use by constructors of derived classes. 332 : */ 333 : DatabaseError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 334 : : RuntimeError(msg_, context_, type_, error_string_) {} 335 : 336 : /** @private @internal 337 : * @brief Constructor for use by constructors of derived classes. 338 : */ 339 : DatabaseError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 340 : : RuntimeError(msg_, context_, type_, errno_) {} 341 : }; 342 : 343 : /** DatabaseCorruptError indicates database corruption was detected. */ 344 : class XAPIAN_VISIBILITY_DEFAULT DatabaseCorruptError : public DatabaseError { 345 : public: 346 : /** @private @internal 347 : * @brief Private constructor for use by remote backend. 348 : * 349 : * @param error_string_ Optional string describing error. May be NULL. 350 : */ 351 : DatabaseCorruptError(const std::string &msg_, const std::string &context_, const char * error_string_) 352 : : DatabaseError(msg_, context_, "DatabaseCorruptError", error_string_) {} 353 : /** General purpose constructor which allows setting errno. */ 354 : explicit DatabaseCorruptError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 355 : : DatabaseError(msg_, context_, "DatabaseCorruptError", errno_) {} 356 : /** Construct from message and errno value. */ 357 : DatabaseCorruptError(const std::string &msg_, int errno_) 358 : : DatabaseError(msg_, "", "DatabaseCorruptError", errno_) {} 359 : protected: 360 : /** @private @internal 361 : * @brief Constructor for use by constructors of derived classes. 362 : */ 363 : DatabaseCorruptError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 364 : : DatabaseError(msg_, context_, type_, error_string_) {} 365 : 366 : /** @private @internal 367 : * @brief Constructor for use by constructors of derived classes. 368 : */ 369 : DatabaseCorruptError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 370 : : DatabaseError(msg_, context_, type_, errno_) {} 371 : }; 372 : 373 : /** DatabaseCreateError indicates a failure to create a database. */ 374 : class XAPIAN_VISIBILITY_DEFAULT DatabaseCreateError : public DatabaseError { 375 : public: 376 : /** @private @internal 377 : * @brief Private constructor for use by remote backend. 378 : * 379 : * @param error_string_ Optional string describing error. May be NULL. 380 : */ 381 : DatabaseCreateError(const std::string &msg_, const std::string &context_, const char * error_string_) 382 : : DatabaseError(msg_, context_, "DatabaseCreateError", error_string_) {} 383 : /** General purpose constructor which allows setting errno. */ 384 : explicit DatabaseCreateError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 385 : : DatabaseError(msg_, context_, "DatabaseCreateError", errno_) {} 386 : /** Construct from message and errno value. */ 387 : DatabaseCreateError(const std::string &msg_, int errno_) 388 : : DatabaseError(msg_, "", "DatabaseCreateError", errno_) {} 389 : protected: 390 : /** @private @internal 391 : * @brief Constructor for use by constructors of derived classes. 392 : */ 393 : DatabaseCreateError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 394 : : DatabaseError(msg_, context_, type_, error_string_) {} 395 : 396 : /** @private @internal 397 : * @brief Constructor for use by constructors of derived classes. 398 : */ 399 : DatabaseCreateError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 400 : : DatabaseError(msg_, context_, type_, errno_) {} 401 : }; 402 : 403 : /** DatabaseLockError indicates failure to lock a database. */ 404 : class XAPIAN_VISIBILITY_DEFAULT DatabaseLockError : public DatabaseError { 405 : public: 406 : /** @private @internal 407 : * @brief Private constructor for use by remote backend. 408 : * 409 : * @param error_string_ Optional string describing error. May be NULL. 410 : */ 411 : DatabaseLockError(const std::string &msg_, const std::string &context_, const char * error_string_) 412 : : DatabaseError(msg_, context_, "DatabaseLockError", error_string_) {} 413 : /** General purpose constructor which allows setting errno. */ 414 : explicit DatabaseLockError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 415 : : DatabaseError(msg_, context_, "DatabaseLockError", errno_) {} 416 : /** Construct from message and errno value. */ 417 : DatabaseLockError(const std::string &msg_, int errno_) 418 : : DatabaseError(msg_, "", "DatabaseLockError", errno_) {} 419 : protected: 420 : /** @private @internal 421 : * @brief Constructor for use by constructors of derived classes. 422 : */ 423 : DatabaseLockError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 424 : : DatabaseError(msg_, context_, type_, error_string_) {} 425 : 426 : /** @private @internal 427 : * @brief Constructor for use by constructors of derived classes. 428 : */ 429 : DatabaseLockError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 430 : : DatabaseError(msg_, context_, type_, errno_) {} 431 : }; 432 : 433 : /** DatabaseModifiedError indicates a database was modified. 434 : * 435 : * To recover after catching this error, you need to call 436 : * Xapian::Database::reopen() on the Database and repeat the operation 437 : * which failed. 438 : */ 439 : class XAPIAN_VISIBILITY_DEFAULT DatabaseModifiedError : public DatabaseError { 440 : public: 441 : /** @private @internal 442 : * @brief Private constructor for use by remote backend. 443 : * 444 : * @param error_string_ Optional string describing error. May be NULL. 445 : */ 446 : DatabaseModifiedError(const std::string &msg_, const std::string &context_, const char * error_string_) 447 : : DatabaseError(msg_, context_, "DatabaseModifiedError", error_string_) {} 448 : /** General purpose constructor which allows setting errno. */ 449 : explicit DatabaseModifiedError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 450 : : DatabaseError(msg_, context_, "DatabaseModifiedError", errno_) {} 451 : /** Construct from message and errno value. */ 452 : DatabaseModifiedError(const std::string &msg_, int errno_) 453 : : DatabaseError(msg_, "", "DatabaseModifiedError", errno_) {} 454 : protected: 455 : /** @private @internal 456 : * @brief Constructor for use by constructors of derived classes. 457 : */ 458 : DatabaseModifiedError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 459 : : DatabaseError(msg_, context_, type_, error_string_) {} 460 : 461 : /** @private @internal 462 : * @brief Constructor for use by constructors of derived classes. 463 : */ 464 : DatabaseModifiedError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 465 : : DatabaseError(msg_, context_, type_, errno_) {} 466 : }; 467 : 468 : /** DatabaseOpeningError indicates failure to open a database. */ 469 : class XAPIAN_VISIBILITY_DEFAULT DatabaseOpeningError : public DatabaseError { 470 : public: 471 : /** @private @internal 472 : * @brief Private constructor for use by remote backend. 473 : * 474 : * @param error_string_ Optional string describing error. May be NULL. 475 : */ 476 : DatabaseOpeningError(const std::string &msg_, const std::string &context_, const char * error_string_) 477 : : DatabaseError(msg_, context_, "DatabaseOpeningError", error_string_) {} 478 : /** General purpose constructor which allows setting errno. */ 479 : explicit DatabaseOpeningError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 480 : : DatabaseError(msg_, context_, "DatabaseOpeningError", errno_) {} 481 : /** Construct from message and errno value. */ 482 : DatabaseOpeningError(const std::string &msg_, int errno_) 483 : : DatabaseError(msg_, "", "DatabaseOpeningError", errno_) {} 484 : protected: 485 : /** @private @internal 486 : * @brief Constructor for use by constructors of derived classes. 487 : */ 488 : DatabaseOpeningError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 489 : : DatabaseError(msg_, context_, type_, error_string_) {} 490 : 491 : /** @private @internal 492 : * @brief Constructor for use by constructors of derived classes. 493 : */ 494 : DatabaseOpeningError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 495 : : DatabaseError(msg_, context_, type_, errno_) {} 496 : }; 497 : 498 : /** DatabaseVersionError indicates that a database is in an unsupported format. 499 : * 500 : * From time to time, new versions of Xapian will require the database format 501 : * to be changed, to allow new information to be stored or new optimisations 502 : * to be performed. Backwards compatibility will sometimes be maintained, so 503 : * that new versions of Xapian can open old databases, but in some cases 504 : * Xapian will be unable to open a database because it is in too old (or new) 505 : * a format. This can be resolved either be upgrading or downgrading the 506 : * version of Xapian in use, or by rebuilding the database from scratch with 507 : * the current version of Xapian. 508 : */ 509 : class XAPIAN_VISIBILITY_DEFAULT DatabaseVersionError : public DatabaseOpeningError { 510 : public: 511 : /** @private @internal 512 : * @brief Private constructor for use by remote backend. 513 : * 514 : * @param error_string_ Optional string describing error. May be NULL. 515 : */ 516 : DatabaseVersionError(const std::string &msg_, const std::string &context_, const char * error_string_) 517 : : DatabaseOpeningError(msg_, context_, "DatabaseVersionError", error_string_) {} 518 : /** General purpose constructor which allows setting errno. */ 519 : explicit DatabaseVersionError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 520 : : DatabaseOpeningError(msg_, context_, "DatabaseVersionError", errno_) {} 521 : /** Construct from message and errno value. */ 522 : DatabaseVersionError(const std::string &msg_, int errno_) 523 : : DatabaseOpeningError(msg_, "", "DatabaseVersionError", errno_) {} 524 : protected: 525 : /** @private @internal 526 : * @brief Constructor for use by constructors of derived classes. 527 : */ 528 : DatabaseVersionError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 529 : : DatabaseOpeningError(msg_, context_, type_, error_string_) {} 530 : 531 : /** @private @internal 532 : * @brief Constructor for use by constructors of derived classes. 533 : */ 534 : DatabaseVersionError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 535 : : DatabaseOpeningError(msg_, context_, type_, errno_) {} 536 : }; 537 : 538 : /** Indicates an attempt to access a document not present in the database. */ 539 : class XAPIAN_VISIBILITY_DEFAULT DocNotFoundError : public RuntimeError { 540 : public: 541 : /** @private @internal 542 : * @brief Private constructor for use by remote backend. 543 : * 544 : * @param error_string_ Optional string describing error. May be NULL. 545 : */ 546 : DocNotFoundError(const std::string &msg_, const std::string &context_, const char * error_string_) 547 : : RuntimeError(msg_, context_, "DocNotFoundError", error_string_) {} 548 : /** General purpose constructor which allows setting errno. */ 549 : explicit DocNotFoundError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 550 : : RuntimeError(msg_, context_, "DocNotFoundError", errno_) {} 551 : /** Construct from message and errno value. */ 552 : DocNotFoundError(const std::string &msg_, int errno_) 553 : : RuntimeError(msg_, "", "DocNotFoundError", errno_) {} 554 : protected: 555 : /** @private @internal 556 : * @brief Constructor for use by constructors of derived classes. 557 : */ 558 : DocNotFoundError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 559 : : RuntimeError(msg_, context_, type_, error_string_) {} 560 : 561 : /** @private @internal 562 : * @brief Constructor for use by constructors of derived classes. 563 : */ 564 : DocNotFoundError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 565 : : RuntimeError(msg_, context_, type_, errno_) {} 566 : }; 567 : 568 : /** Indicates an attempt to use a feature which is unavailable. 569 : * 570 : * Typically a feature is unavailable because it wasn't compiled in, or 571 : * because it requires other software or facilities which aren't available. 572 : */ 573 : class XAPIAN_VISIBILITY_DEFAULT FeatureUnavailableError : public RuntimeError { 574 : public: 575 : /** @private @internal 576 : * @brief Private constructor for use by remote backend. 577 : * 578 : * @param error_string_ Optional string describing error. May be NULL. 579 : */ 580 : FeatureUnavailableError(const std::string &msg_, const std::string &context_, const char * error_string_) 581 : : RuntimeError(msg_, context_, "FeatureUnavailableError", error_string_) {} 582 : /** General purpose constructor which allows setting errno. */ 583 : explicit FeatureUnavailableError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 584 : : RuntimeError(msg_, context_, "FeatureUnavailableError", errno_) {} 585 : /** Construct from message and errno value. */ 586 : FeatureUnavailableError(const std::string &msg_, int errno_) 587 : : RuntimeError(msg_, "", "FeatureUnavailableError", errno_) {} 588 : protected: 589 : /** @private @internal 590 : * @brief Constructor for use by constructors of derived classes. 591 : */ 592 : FeatureUnavailableError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 593 : : RuntimeError(msg_, context_, type_, error_string_) {} 594 : 595 : /** @private @internal 596 : * @brief Constructor for use by constructors of derived classes. 597 : */ 598 : FeatureUnavailableError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 599 : : RuntimeError(msg_, context_, type_, errno_) {} 600 : }; 601 : 602 : /** InternalError indicates a runtime problem of some sort. */ 603 : class XAPIAN_VISIBILITY_DEFAULT InternalError : public RuntimeError { 604 : public: 605 : /** @private @internal 606 : * @brief Private constructor for use by remote backend. 607 : * 608 : * @param error_string_ Optional string describing error. May be NULL. 609 : */ 610 : InternalError(const std::string &msg_, const std::string &context_, const char * error_string_) 611 : : RuntimeError(msg_, context_, "InternalError", error_string_) {} 612 : /** General purpose constructor which allows setting errno. */ 613 : explicit InternalError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 614 : : RuntimeError(msg_, context_, "InternalError", errno_) {} 615 : /** Construct from message and errno value. */ 616 : InternalError(const std::string &msg_, int errno_) 617 : : RuntimeError(msg_, "", "InternalError", errno_) {} 618 : protected: 619 : /** @private @internal 620 : * @brief Constructor for use by constructors of derived classes. 621 : */ 622 : InternalError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 623 : : RuntimeError(msg_, context_, type_, error_string_) {} 624 : 625 : /** @private @internal 626 : * @brief Constructor for use by constructors of derived classes. 627 : */ 628 : InternalError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 629 : : RuntimeError(msg_, context_, type_, errno_) {} 630 : }; 631 : 632 : /** Indicates a problem communicating with a remote database. */ 633 : class XAPIAN_VISIBILITY_DEFAULT NetworkError : public RuntimeError { 634 : public: 635 : /** @private @internal 636 : * @brief Private constructor for use by remote backend. 637 : * 638 : * @param error_string_ Optional string describing error. May be NULL. 639 : */ 640 : NetworkError(const std::string &msg_, const std::string &context_, const char * error_string_) 641 : : RuntimeError(msg_, context_, "NetworkError", error_string_) {} 642 : /** General purpose constructor which allows setting errno. */ 643 : explicit NetworkError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 644 : : RuntimeError(msg_, context_, "NetworkError", errno_) {} 645 : /** Construct from message and errno value. */ 646 : NetworkError(const std::string &msg_, int errno_) 647 : : RuntimeError(msg_, "", "NetworkError", errno_) {} 648 : protected: 649 : /** @private @internal 650 : * @brief Constructor for use by constructors of derived classes. 651 : */ 652 : NetworkError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 653 : : RuntimeError(msg_, context_, type_, error_string_) {} 654 : 655 : /** @private @internal 656 : * @brief Constructor for use by constructors of derived classes. 657 : */ 658 : NetworkError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 659 : : RuntimeError(msg_, context_, type_, errno_) {} 660 : }; 661 : 662 : /** Indicates a timeout expired while communicating with a remote database. */ 663 : class XAPIAN_VISIBILITY_DEFAULT NetworkTimeoutError : public NetworkError { 664 : public: 665 : /** @private @internal 666 : * @brief Private constructor for use by remote backend. 667 : * 668 : * @param error_string_ Optional string describing error. May be NULL. 669 : */ 670 : NetworkTimeoutError(const std::string &msg_, const std::string &context_, const char * error_string_) 671 : : NetworkError(msg_, context_, "NetworkTimeoutError", error_string_) {} 672 : /** General purpose constructor which allows setting errno. */ 673 : explicit NetworkTimeoutError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 674 : : NetworkError(msg_, context_, "NetworkTimeoutError", errno_) {} 675 : /** Construct from message and errno value. */ 676 : NetworkTimeoutError(const std::string &msg_, int errno_) 677 : : NetworkError(msg_, "", "NetworkTimeoutError", errno_) {} 678 : protected: 679 : /** @private @internal 680 : * @brief Constructor for use by constructors of derived classes. 681 : */ 682 : NetworkTimeoutError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 683 : : NetworkError(msg_, context_, type_, error_string_) {} 684 : 685 : /** @private @internal 686 : * @brief Constructor for use by constructors of derived classes. 687 : */ 688 : NetworkTimeoutError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 689 : : NetworkError(msg_, context_, type_, errno_) {} 690 : }; 691 : 692 : /** Indicates a query string can't be parsed. */ 693 : class XAPIAN_VISIBILITY_DEFAULT QueryParserError : public RuntimeError { 694 : public: 695 : /** @private @internal 696 : * @brief Private constructor for use by remote backend. 697 : * 698 : * @param error_string_ Optional string describing error. May be NULL. 699 : */ 700 : QueryParserError(const std::string &msg_, const std::string &context_, const char * error_string_) 701 : : RuntimeError(msg_, context_, "QueryParserError", error_string_) {} 702 : /** General purpose constructor which allows setting errno. */ 703 : explicit QueryParserError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 704 : : RuntimeError(msg_, context_, "QueryParserError", errno_) {} 705 : /** Construct from message and errno value. */ 706 : QueryParserError(const std::string &msg_, int errno_) 707 : : RuntimeError(msg_, "", "QueryParserError", errno_) {} 708 : protected: 709 : /** @private @internal 710 : * @brief Constructor for use by constructors of derived classes. 711 : */ 712 : QueryParserError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 713 : : RuntimeError(msg_, context_, type_, error_string_) {} 714 : 715 : /** @private @internal 716 : * @brief Constructor for use by constructors of derived classes. 717 : */ 718 : QueryParserError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 719 : : RuntimeError(msg_, context_, type_, errno_) {} 720 : }; 721 : 722 : /** RangeError indicates an attempt to access outside the bounds of a container. 723 : */ 724 : class XAPIAN_VISIBILITY_DEFAULT RangeError : public RuntimeError { 725 : public: 726 : /** @private @internal 727 : * @brief Private constructor for use by remote backend. 728 : * 729 : * @param error_string_ Optional string describing error. May be NULL. 730 : */ 731 : RangeError(const std::string &msg_, const std::string &context_, const char * error_string_) 732 : : RuntimeError(msg_, context_, "RangeError", error_string_) {} 733 : /** General purpose constructor which allows setting errno. */ 734 : explicit RangeError(const std::string &msg_, const std::string &context_ = "", int errno_ = 0) 735 : : RuntimeError(msg_, context_, "RangeError", errno_) {} 736 : /** Construct from message and errno value. */ 737 : RangeError(const std::string &msg_, int errno_) 738 : : RuntimeError(msg_, "", "RangeError", errno_) {} 739 : protected: 740 : /** @private @internal 741 : * @brief Constructor for use by constructors of derived classes. 742 : */ 743 : RangeError(const std::string &msg_, const std::string &context_, const char * type_, const char * error_string_) 744 : : RuntimeError(msg_, context_, type_, error_string_) {} 745 : 746 : /** @private @internal 747 : * @brief Constructor for use by constructors of derived classes. 748 : */ 749 : RangeError(const std::string &msg_, const std::string &context_, const char * type_, int errno_) 750 : : RuntimeError(msg_, context_, type_, errno_) {} 751 : }; 752 : 753 : } 754 : 755 : #endif /* XAPIAN_INCLUDED_ERROR_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : /** \file enquire.h 2 : * \brief API for running queries 3 : */ 4 : /* Copyright 1999,2000,2001 BrightStation PLC 5 : * Copyright 2001,2002 Ananova Ltd 6 : * Copyright 2002,2003,2004,2005,2006,2007 Olly Betts 7 : * 8 : * This program is free software; you can redistribute it and/or 9 : * modify it under the terms of the GNU General Public License as 10 : * published by the Free Software Foundation; either version 2 of the 11 : * License, or (at your option) any later version. 12 : * 13 : * This program is distributed in the hope that it will be useful, 14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : * GNU General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU General Public License 19 : * along with this program; if not, write to the Free Software 20 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 21 : * USA 22 : */ 23 : 24 : #ifndef XAPIAN_INCLUDED_ENQUIRE_H 25 : #define XAPIAN_INCLUDED_ENQUIRE_H 26 : 27 : #include <string> 28 : 29 : #include <xapian/base.h> 30 : #include <xapian/deprecated.h> 31 : #include <xapian/sorter.h> 32 : #include <xapian/types.h> 33 : #include <xapian/termiterator.h> 34 : #include <xapian/visibility.h> 35 : 36 : namespace Xapian { 37 : 38 : class Database; 39 : class Document; 40 : class ErrorHandler; 41 : class ExpandDecider; 42 : class MSetIterator; 43 : class Query; 44 : class Weight; 45 : 46 : /** A match set (MSet). 47 : * This class represents (a portion of) the results of a query. 48 : */ 49 : class XAPIAN_VISIBILITY_DEFAULT MSet { 50 : public: 51 : class Internal; 52 : /// @internal Reference counted internals. 53 : Xapian::Internal::RefCntPtr<Internal> internal; 54 : 55 : /// @internal Constructor for internal use. 56 : explicit MSet(MSet::Internal * internal_); 57 : 58 : /// Create an empty Xapian::MSet. 59 : MSet(); 60 : 61 : /// Destroy a Xapian::MSet. 62 : ~MSet(); 63 : 64 : /// Copying is allowed (and is cheap). 65 : MSet(const MSet & other); 66 : 67 : /// Assignment is allowed (and is cheap). 68 : void operator=(const MSet &other); 69 : 70 : /** Fetch the document info for a set of items in the MSet. 71 : * 72 : * This method causes the documents in the range specified by the 73 : * iterators to be fetched from the database, and cached in the 74 : * Xapian::MSet object. This has little effect when performing a 75 : * search across a local database, but will greatly speed up 76 : * subsequent access to the document contents when the documents are 77 : * stored in a remote database. 78 : * 79 : * The iterators must be over this Xapian::MSet - undefined behaviour 80 : * will result otherwise. 81 : * 82 : * @param begin MSetIterator for first item to fetch. 83 : * @param end MSetIterator for item after last item to fetch. 84 : */ 85 : void fetch(const MSetIterator &begin, const MSetIterator &end) const; 86 : 87 : /** Fetch the single item specified. 88 : */ 89 : void fetch(const MSetIterator &item) const; 90 : 91 : /** Fetch all the items in the MSet. 92 : */ 93 : void fetch() const; 94 : 95 : /** This converts the weight supplied to a percentage score. 96 : * The return value will be in the range 0 to 100, and will be 0 if 97 : * and only if the item did not match the query at all. 98 : */ 99 : Xapian::percent convert_to_percent(Xapian::weight wt) const; 100 : 101 : /// Return the percentage score for a particular item. 102 : Xapian::percent convert_to_percent(const MSetIterator &it) const; 103 : 104 : /** Return the term frequency of the given query term. 105 : * 106 : * @param tname The term to look for. 107 : * 108 : * @exception Xapian::InvalidArgumentError is thrown if the term was 109 : * not in the query. 110 : */ 111 : Xapian::doccount get_termfreq(const std::string &tname) const; 112 : 113 : /** Return the term weight of the given query term. 114 : * 115 : * @param tname The term to look for. 116 : * 117 : * @exception Xapian::InvalidArgumentError is thrown if the term was 118 : * not in the query. 119 : */ 120 : Xapian::weight get_termweight(const std::string &tname) const; 121 : 122 : /** The index of the first item in the result which was put into the 123 : * MSet. 124 : * 125 : * This corresponds to the parameter "first" specified in 126 : * Xapian::Enquire::get_mset(). A value of 0 corresponds to the 127 : * highest result being the first item in the MSet. 128 : */ 129 : Xapian::doccount get_firstitem() const; 130 : 131 : /** A lower bound on the number of documents in the database which 132 : * match the query. 133 : * 134 : * This figure takes into account collapsing of duplicates, 135 : * and weighting cutoff values. 136 : * 137 : * This number is usually considerably less than the actual number 138 : * of documents which match the query. 139 : */ 140 : Xapian::doccount get_matches_lower_bound() const; 141 : 142 : /** An estimate for the number of documents in the database which 143 : * match the query. 144 : * 145 : * This figure takes into account collapsing of duplicates, 146 : * and weighting cutoff values. 147 : * 148 : * This value is returned because there is sometimes a request to 149 : * display such information. However, our experience is that 150 : * presenting this value to users causes them to worry about the 151 : * large number of results, rather than how useful those at the top 152 : * of the result set are, and is thus undesirable. 153 : */ 154 : Xapian::doccount get_matches_estimated() const; 155 : 156 : /** An upper bound on the number of documents in the database which 157 : * match the query. 158 : * 159 : * This figure takes into account collapsing of duplicates, 160 : * and weighting cutoff values. 161 : * 162 : * This number is usually considerably greater than the actual 163 : * number of documents which match the query. 164 : */ 165 : Xapian::doccount get_matches_upper_bound() const; 166 : 167 : /** The maximum possible weight in the MSet. 168 : * This weight is likely not to be attained in the set of results, 169 : * but represents an upper bound on the weight which a document 170 : * could attain for the given query. 171 : */ 172 : Xapian::weight get_max_possible() const; 173 : 174 : /** The greatest weight which is attained by any document in the 175 : * database. 176 : * 177 : * If firstitem == 0, this is the weight of the first entry in 178 : * items. 179 : * 180 : * If no documents are found by the query, this will be 0. 181 : * 182 : * Note that calculation of max_attained requires calculation 183 : * of at least one result item - therefore, if no items were 184 : * requested when the query was performed (by specifying 185 : * maxitems = 0 in Xapian::Enquire::get_mset()), this value will be 0. 186 : */ 187 : Xapian::weight get_max_attained() const; 188 : 189 : /** The number of items in this MSet */ 190 : Xapian::doccount size() const; 191 : 192 : /** Required to allow use as an STL container. */ 193 : Xapian::doccount max_size() const { return size(); } 194 : 195 : /** Test if this MSet is empty */ 196 : bool empty() const; 197 : 198 : /** Swap the MSet we point to with another */ 199 : void swap(MSet & other); 200 : 201 : /** Iterator for the terms in this MSet */ 202 : MSetIterator begin() const; 203 : 204 : /** End iterator corresponding to begin() */ 205 : MSetIterator end() const; 206 : 207 : /** Iterator pointing to the last element of this MSet */ 208 : MSetIterator back() const; 209 : 210 : /** This returns the document at position i in this MSet object. 211 : * 212 : * Note that this is not the same as the document at rank i in the 213 : * query, unless the "first" parameter to Xapian::Enquire::get_mset 214 : * was 0. Rather, it is the document at rank i + first. 215 : * 216 : * In other words, the offset is into the documents represented by 217 : * this object, not into the set of documents matching the query. 218 : */ 219 : MSetIterator operator[](Xapian::doccount i) const; 220 : 221 : /// Allow use as an STL container 222 : //@{ 223 : typedef MSetIterator value_type; // FIXME: not assignable... 224 : typedef MSetIterator iterator; 225 : typedef MSetIterator const_iterator; 226 : typedef MSetIterator & reference; // Hmm 227 : typedef MSetIterator & const_reference; 228 : typedef MSetIterator * pointer; // Hmm 229 : typedef Xapian::doccount_diff difference_type; 230 : typedef Xapian::doccount size_type; 231 : //@} 232 : 233 : /// Return a string describing this object. 234 : std::string get_description() const; 235 : }; 236 : 237 : /** An iterator pointing to items in an MSet. 238 : * This is used for access to individual results of a match. 239 : */ 240 : class XAPIAN_VISIBILITY_DEFAULT MSetIterator { 241 : private: 242 : friend class MSet; 243 : friend bool operator==(const MSetIterator &a, const MSetIterator &b); 244 : friend bool operator!=(const MSetIterator &a, const MSetIterator &b); 245 : 246 : MSetIterator(Xapian::doccount index_, const MSet & mset_) 247 : : index(index_), mset(mset_) { } 248 : 249 : Xapian::doccount index; 250 : MSet mset; 251 : 252 : public: 253 : /** Create an uninitialised iterator; this cannot be used, but is 254 : * convenient syntactically. 255 : */ 256 3 : MSetIterator() : index(0), mset() { } 257 : 258 165 : ~MSetIterator() { } 259 : 260 : /// Copying is allowed (and is cheap). 261 58 : MSetIterator(const MSetIterator &other) { 262 58 : index = other.index; 263 58 : mset = other.mset; 264 58 : } 265 : 266 : /// Assignment is allowed (and is cheap). 267 31 : void operator=(const MSetIterator &other) { 268 31 : index = other.index; 269 31 : mset = other.mset; 270 31 : } 271 : 272 : /// Advance the iterator. 273 61 : MSetIterator & operator++() { 274 61 : ++index; 275 61 : return *this; 276 : } 277 : 278 : /// Advance the iterator (postfix variant). 279 28 : MSetIterator operator++(int) { 280 28 : MSetIterator tmp = *this; 281 28 : ++index; 282 : return tmp; 283 : } 284 : 285 : /// Decrement the iterator. 286 : MSetIterator & operator--() { 287 : --index; 288 : return *this; 289 : } 290 : 291 : /// Decrement the iterator (postfix variant). 292 : MSetIterator operator--(int) { 293 : MSetIterator tmp = *this; 294 : --index; 295 : return tmp; 296 : } 297 : 298 : /// Get the document ID for the current position. 299 : Xapian::docid operator*() const; 300 : 301 : /** Get a Xapian::Document object for the current position. 302 : * 303 : * This method returns a Xapian::Document object which provides the 304 : * information about the document pointed to by the MSetIterator. 305 : * 306 : * If the underlying database has suitable support, using this call 307 : * (rather than asking the database for a document based on its 308 : * document ID) will enable the system to ensure that the correct 309 : * data is returned, and that the document has not been deleted 310 : * or changed since the query was performed. 311 : * 312 : * @return A Xapian::Document object containing the document data. 313 : * 314 : * @exception Xapian::DocNotFoundError The document specified could not 315 : * be found in the database. 316 : */ 317 : Xapian::Document get_document() const; 318 : 319 : /** Get the rank of the document at the current position. 320 : * 321 : * The rank is the position that this document is at in the ordered 322 : * list of results of the query. The result is 0-based - i.e. the 323 : * top-ranked document has a rank of 0. 324 : */ 325 : Xapian::doccount get_rank() const { 326 : return mset.get_firstitem() + index; 327 : } 328 : 329 : /// Get the weight of the document at the current position 330 : Xapian::weight get_weight() const; 331 : 332 : /** Get the collapse key for this document. 333 : */ 334 : std::string get_collapse_key() const; 335 : 336 : /** Get an estimate of the number of documents that have been collapsed 337 : * into this one. 338 : * 339 : * The estimate will always be less than or equal to the actual 340 : * number of other documents satisfying the match criteria with the 341 : * same collapse key as this document. 342 : * 343 : * This method may return 0 even though there are other documents with 344 : * the same collapse key which satisfying the match criteria. However 345 : * if this method returns non-zero, there definitely are other such 346 : * documents. So this method may be used to inform the user that 347 : * there are "at least N other matches in this group", or to control 348 : * whether to offer a "show other documents in this group" feature 349 : * (but note that it may not offer it in every case where it would 350 : * show other documents). 351 : */ 352 : Xapian::doccount get_collapse_count() const; 353 : 354 : /** This returns the weight of the document as a percentage score. 355 : * 356 : * The return value will be in the range 0 to 100: 0 meaning 357 : * that the item did not match the query at all. 358 : */ 359 : Xapian::percent get_percent() const; 360 : 361 : /// Return a string describing this object. 362 : std::string get_description() const; 363 : 364 : /// Allow use as an STL iterator 365 : //@{ 366 : typedef std::bidirectional_iterator_tag iterator_category; // FIXME: could enhance to be a randomaccess_iterator 367 : typedef Xapian::docid value_type; 368 : typedef Xapian::doccount_diff difference_type; 369 : typedef Xapian::docid * pointer; 370 : typedef Xapian::docid & reference; 371 : //@} 372 : }; 373 : 374 30 : inline bool operator==(const MSetIterator &a, const MSetIterator &b) 375 : { 376 30 : return (a.index == b.index); 377 : } 378 : 379 58 : inline bool operator!=(const MSetIterator &a, const MSetIterator &b) 380 : { 381 58 : return (a.index != b.index); 382 : } 383 : 384 : class ESetIterator; 385 : 386 : /** Class representing an ordered set of expand terms (an ESet). 387 : * This set represents the results of an expand operation, which is 388 : * performed by Xapian::Enquire::get_eset(). 389 : */ 390 : class XAPIAN_VISIBILITY_DEFAULT ESet { 391 : public: 392 : class Internal; 393 : /// @internal Reference counted internals. 394 : Xapian::Internal::RefCntPtr<Internal> internal; 395 : 396 : /// Construct an empty ESet 397 : ESet(); 398 : 399 : /// Destructor. 400 : ~ESet(); 401 : 402 : /// Copying is allowed (and is cheap). 403 : ESet(const ESet & other); 404 : 405 : /// Assignment is allowed (and is cheap). 406 : void operator=(const ESet &other); 407 : 408 : /** A lower bound on the number of terms which are in the full 409 : * set of results of the expand. This will be greater than or 410 : * equal to size() 411 : */ 412 : Xapian::termcount get_ebound() const; 413 : 414 : /** The number of terms in this E-Set */ 415 : Xapian::termcount size() const; 416 : 417 : /** Required to allow use as an STL container. */ 418 : Xapian::termcount max_size() const { return size(); } 419 : 420 : /** Test if this E-Set is empty */ 421 : bool empty() const; 422 : 423 : /** Swap the E-Set we point to with another */ 424 : void swap(ESet & other); 425 : 426 : /** Iterator for the terms in this E-Set */ 427 : ESetIterator begin() const; 428 : 429 : /** End iterator corresponding to begin() */ 430 : ESetIterator end() const; 431 : 432 : /** Iterator pointing to the last element of this E-Set */ 433 : ESetIterator back() const; 434 : 435 : /** This returns the term at position i in this E-Set. */ 436 : ESetIterator operator[](Xapian::termcount i) const; 437 : 438 : /// Return a string describing this object. 439 : std::string get_description() const; 440 : }; 441 : 442 : /** Iterate through terms in the ESet */ 443 : class XAPIAN_VISIBILITY_DEFAULT ESetIterator { 444 : private: 445 : friend class ESet; 446 : friend bool operator==(const ESetIterator &a, const ESetIterator &b); 447 : friend bool operator!=(const ESetIterator &a, const ESetIterator &b); 448 : 449 : ESetIterator(Xapian::termcount index_, const ESet & eset_) 450 : : index(index_), eset(eset_) { } 451 : 452 : Xapian::termcount index; 453 : ESet eset; 454 : 455 : public: 456 : /** Create an uninitialised iterator; this cannot be used, but is 457 : * convenient syntactically. 458 : */ 459 : ESetIterator() : index(0), eset() { } 460 : 461 8 : ~ESetIterator() { } 462 : 463 : /// Copying is allowed (and is cheap). 464 : ESetIterator(const ESetIterator &other) { 465 : index = other.index; 466 : eset = other.eset; 467 : } 468 : 469 : /// Assignment is allowed (and is cheap). 470 : void operator=(const ESetIterator &other) { 471 : index = other.index; 472 : eset = other.eset; 473 : } 474 : 475 : /// Advance the iterator. 476 0 : ESetIterator & operator++() { 477 0 : ++index; 478 0 : return *this; 479 : } 480 : 481 : /// Advance the iterator (postfix variant). 482 : ESetIterator operator++(int) { 483 : ESetIterator tmp = *this; 484 : ++index; 485 : return tmp; 486 : } 487 : 488 : /// Decrement the iterator. 489 : ESetIterator & operator--() { 490 : --index; 491 : return *this; 492 : } 493 : 494 : /// Decrement the iterator (postfix variant). 495 : ESetIterator operator--(int) { 496 : ESetIterator tmp = *this; 497 : --index; 498 : return tmp; 499 : } 500 : 501 : /// Get the term for the current position 502 : const std::string & operator *() const; 503 : 504 : /// Get the weight of the term at the current position 505 : Xapian::weight get_weight() const; 506 : 507 : /// Return a string describing this object. 508 : std::string get_description() const; 509 : 510 : /// Allow use as an STL iterator 511 : //@{ 512 : typedef std::bidirectional_iterator_tag iterator_category; // FIXME: go for randomaccess_iterator! 513 : typedef std::string value_type; 514 : typedef Xapian::termcount_diff difference_type; 515 : typedef std::string * pointer; 516 : typedef std::string & reference; 517 : //@} 518 : }; 519 : 520 : inline bool operator==(const ESetIterator &a, const ESetIterator &b) 521 : { 522 : return (a.index == b.index); 523 : } 524 : 525 4 : inline bool operator!=(const ESetIterator &a, const ESetIterator &b) 526 : { 527 4 : return (a.index != b.index); 528 : } 529 : 530 : /** A relevance set (R-Set). 531 : * This is the set of documents which are marked as relevant, for use 532 : * in modifying the term weights, and in performing query expansion. 533 : */ 534 : class XAPIAN_VISIBILITY_DEFAULT RSet { 535 : public: 536 : /// Class holding details of RSet 537 : class Internal; 538 : 539 : /// @internal Reference counted internals. 540 : Xapian::Internal::RefCntPtr<Internal> internal; 541 : 542 : /// Copy constructor 543 : RSet(const RSet &rset); 544 : 545 : /// Assignment operator 546 : void operator=(const RSet &rset); 547 : 548 : /// Default constructor 549 : RSet(); 550 : 551 : /// Destructor 552 : ~RSet(); 553 : 554 : /** The number of documents in this R-Set */ 555 : Xapian::doccount size() const; 556 : 557 : /** Test if this R-Set is empty */ 558 : bool empty() const; 559 : 560 : /// Add a document to the relevance set. 561 : void add_document(Xapian::docid did); 562 : 563 : /// Add a document to the relevance set. 564 20 : void add_document(const Xapian::MSetIterator & i) { add_document(*i); } 565 : 566 : /// Remove a document from the relevance set. 567 : void remove_document(Xapian::docid did); 568 : 569 : /// Remove a document from the relevance set. 570 : void remove_document(const Xapian::MSetIterator & i) { remove_document(*i); } 571 : 572 : /// Test if a given document in the relevance set. 573 : bool contains(Xapian::docid did) const; 574 : 575 : /// Test if a given document in the relevance set. 576 : bool contains(const Xapian::MSetIterator & i) const { return contains(*i); } 577 : 578 : /// Return a string describing this object. 579 : std::string get_description() const; 580 : }; 581 : 582 : /** Base class for matcher decision functor. 583 : */ 584 : class XAPIAN_VISIBILITY_DEFAULT MatchDecider { 585 : public: 586 : /** Decide whether we want this document to be in the MSet. 587 : * 588 : * Return true if the document is acceptable, or false if the document 589 : * should be excluded from the MSet. 590 : */ 591 : virtual bool operator()(const Xapian::Document &doc) const = 0; 592 : 593 : /// Destructor. 594 : virtual ~MatchDecider(); 595 : }; 596 : 597 : /** This class provides an interface to the information retrieval 598 : * system for the purpose of searching. 599 : * 600 : * Databases are usually opened lazily, so exceptions may not be 601 : * thrown where you would expect them to be. You should catch 602 : * Xapian::Error exceptions when calling any method in Xapian::Enquire. 603 : * 604 : * @exception Xapian::InvalidArgumentError will be thrown if an invalid 605 : * argument is supplied, for example, an unknown database type. 606 : */ 607 : class XAPIAN_VISIBILITY_DEFAULT Enquire { 608 : public: 609 : /// Copying is allowed (and is cheap). 610 : Enquire(const Enquire & other); 611 : 612 : /// Assignment is allowed (and is cheap). 613 : void operator=(const Enquire & other); 614 : 615 : class Internal; 616 : /// @internal Reference counted internals. 617 : Xapian::Internal::RefCntPtr<Internal> internal; 618 : 619 : /** Create a Xapian::Enquire object. 620 : * 621 : * This specification cannot be changed once the Xapian::Enquire is 622 : * opened: you must create a new Xapian::Enquire object to access a 623 : * different database, or set of databases. 624 : * 625 : * The database supplied must have been initialised (ie, must not be 626 : * the result of calling the Database::Database() constructor). If 627 : * you need to handle a situation where you have no index gracefully, 628 : * a database created with InMemory::open() can be passed here, 629 : * which represents a completely empty database. 630 : * 631 : * @param database Specification of the database or databases to 632 : * use. 633 : * @param errorhandler_ A pointer to the error handler to use. 634 : * Ownership of the object pointed to is not assumed by the 635 : * Xapian::Enquire object - the user should delete the 636 : * Xapian::ErrorHandler object after the Xapian::Enquire object 637 : * is deleted. To use no error handler, this parameter 638 : * should be 0. 639 : * 640 : * @exception Xapian::InvalidArgumentError will be thrown if an 641 : * initialised Database object is supplied. 642 : */ 643 : explicit Enquire(const Database &database, ErrorHandler * errorhandler_ = 0); 644 : 645 : /** Close the Xapian::Enquire object. 646 : */ 647 : ~Enquire(); 648 : 649 : /** Set the query to run. 650 : * 651 : * @param query the new query to run. 652 : * @param qlen the query length to use in weight calculations - 653 : * by default the sum of the wqf of all terms is used. 654 : */ 655 : void set_query(const Xapian::Query & query, Xapian::termcount qlen = 0); 656 : 657 : /** Get the query which has been set. 658 : * This is only valid after set_query() has been called. 659 : * 660 : * @exception Xapian::InvalidArgumentError will be thrown if query has 661 : * not yet been set. 662 : */ 663 : const Xapian::Query & get_query() const; 664 : 665 : /** Set the weighting scheme to use for queries. 666 : * 667 : * @param weight_ the new weighting scheme. If no weighting scheme 668 : * is specified, the default is BM25 with the 669 : * default parameters. 670 : */ 671 : void set_weighting_scheme(const Weight &weight_); 672 : 673 : /** Set the collapse key to use for queries. 674 : * 675 : * @param collapse_key value number to collapse on - at most one MSet 676 : * entry with each particular value will be returned. 677 : * 678 : * The entry returned will be the best entry with that particular 679 : * value (highest weight or highest sorting key). 680 : * 681 : * An example use might be to create a value for each document 682 : * containing an MD5 hash of the document contents. Then 683 : * duplicate documents from different sources can be eliminated at 684 : * search time (it's better to eliminate duplicates at index time, 685 : * but this may not be always be possible - for example the search 686 : * may be over more than one Xapian database). 687 : * 688 : * Another use is to group matches in a particular category (e.g. 689 : * you might collapse a mailing list search on the Subject: so 690 : * that there's only one result per discussion thread). In this 691 : * case you can use get_collapse_count() to give the user some 692 : * idea how many other results there are. And if you index the 693 : * Subject: as a boolean term as well as putting it in a value, 694 : * you can offer a link to a non-collapsed search restricted to 695 : * that thread using a boolean filter. 696 : * 697 : * (default is Xapian::BAD_VALUENO which means no collapsing). 698 : */ 699 : void set_collapse_key(Xapian::valueno collapse_key); 700 : 701 : typedef enum { 702 : ASCENDING = 1, 703 : DESCENDING = 0, 704 : DONT_CARE = 2 705 : } docid_order; 706 : 707 : /** Set the direction in which documents are ordered by document id 708 : * in the returned MSet. 709 : * 710 : * This order only has an effect on documents which would otherwise 711 : * have equal rank. For a weighted probabilistic match with no sort 712 : * value, this means documents with equal weight. For a boolean match, 713 : * with no sort value, this means all documents. And if a sort value 714 : * is used, this means documents with equal sort value (and also equal 715 : * weight if ordering on relevance after the sort). 716 : * 717 : * @param order This can be: 718 : * - Xapian::Enquire::ASCENDING 719 : * docids sort in ascending order (default) 720 : * - Xapian::Enquire::DESCENDING 721 : * docids sort in descending order 722 : * - Xapian::Enquire::DONT_CARE 723 : * docids sort in whatever order is most efficient for the backend 724 : * 725 : * Note: If you add documents in strict date order, then a boolean 726 : * search - i.e. set_weighting_scheme(Xapian::BoolWeight()) - with 727 : * set_docid_order(Xapian::Enquire::DESCENDING) is a very efficient 728 : * way to perform "sort by date, newest first". 729 : */ 730 : void set_docid_order(docid_order order); 731 : 732 : /** Set the percentage and/or weight cutoffs. 733 : * 734 : * @param percent_cutoff Minimum percentage score for returned 735 : * documents. If a document has a lower percentage score than this, 736 : * it will not appear in the MSet. If your intention is to return 737 : * only matches which contain all the terms in the query, then 738 : * it's more efficient to use Xapian::Query::OP_AND instead of 739 : * Xapian::Query::OP_OR in the query than to use set_cutoff(100). 740 : * (default 0 => no percentage cut-off). 741 : * @param weight_cutoff Minimum weight for a document to be returned. 742 : * If a document has a lower score that this, it will not appear 743 : * in the MSet. It is usually only possible to choose an 744 : * appropriate weight for cutoff based on the results of a 745 : * previous run of the same query; this is thus mainly useful for 746 : * alerting operations. The other potential use is with a user 747 : * specified weighting scheme. 748 : * (default 0 => no weight cut-off). 749 : */ 750 : void set_cutoff(Xapian::percent percent_cutoff, Xapian::weight weight_cutoff = 0); 751 : 752 : /** Set the sorting to be by relevance only. 753 : * 754 : * This is the default. 755 : */ 756 : void set_sort_by_relevance(); 757 : 758 : /** Set the sorting to be by value only. 759 : * 760 : * NB sorting of values uses a string comparison, so you'll need to 761 : * store numbers padded with leading zeros or spaces, or with the 762 : * number of digits prepended. 763 : * 764 : * @param sort_key value number to sort on. 765 : * 766 : * @param ascending If true, documents values which sort higher by 767 : * string compare are better. If false, the sort order 768 : * is reversed. (default true) 769 : */ 770 : void set_sort_by_value(Xapian::valueno sort_key, bool ascending = true); 771 : 772 : /** Set the sorting to be by key generated from values only. 773 : * 774 : * @param sorter The functor to use for generating keys. 775 : * 776 : * @param ascending If true, documents values which sort higher by 777 : * string compare are better. If false, the sort order 778 : * is reversed. (default true) 779 : */ 780 : void set_sort_by_key(Xapian::Sorter * sorter, bool ascending = true); 781 : 782 : /** Set the sorting to be by value, then by relevance for documents 783 : * with the same value. 784 : * 785 : * NB sorting of values uses a string comparison, so you'll need to 786 : * store numbers padded with leading zeros or spaces, or with the 787 : * number of digits prepended. 788 : * 789 : * @param sort_key value number to sort on. 790 : * 791 : * @param ascending If true, documents values which sort higher by 792 : * string compare are better. If false, the sort order 793 : * is reversed. (default true) 794 : */ 795 : void set_sort_by_value_then_relevance(Xapian::valueno sort_key, 796 : bool ascending = true); 797 : 798 : /** Set the sorting to be by keys generated from values, then by 799 : * relevance for documents with identical keys. 800 : * 801 : * @param sorter The functor to use for generating keys. 802 : * 803 : * @param ascending If true, keys which sort higher by 804 : * string compare are better. If false, the sort order 805 : * is reversed. (default true) 806 : */ 807 : void set_sort_by_key_then_relevance(Xapian::Sorter * sorter, 808 : bool ascending = true); 809 : 810 : /** Set the sorting to be by relevance then value. 811 : * 812 : * NB sorting of values uses a string comparison, so you'll need to 813 : * store numbers padded with leading zeros or spaces, or with the 814 : * number of digits prepended. 815 : * 816 : * Note that with the default BM25 weighting scheme parameters, 817 : * non-identical documents will rarely have the same weight, so 818 : * this setting will give very similar results to 819 : * set_sort_by_relevance(). It becomes more useful with particular 820 : * BM25 parameter settings (e.g. BM25Weight(1,0,1,0,0)) or custom 821 : * weighting schemes. 822 : * 823 : * @param sort_key value number to sort on. 824 : * 825 : * @param ascending If true, documents values which sort higher by 826 : * string compare are better. If false, the sort order 827 : * is reversed. (default true) 828 : */ 829 : void set_sort_by_relevance_then_value(Xapian::valueno sort_key, 830 : bool ascending = true); 831 : 832 : /** Set the sorting to be by relevance, then by keys generated from 833 : * values. 834 : * 835 : * Note that with the default BM25 weighting scheme parameters, 836 : * non-identical documents will rarely have the same weight, so 837 : * this setting will give very similar results to 838 : * set_sort_by_relevance(). It becomes more useful with particular 839 : * BM25 parameter settings (e.g. BM25Weight(1,0,1,0,0)) or custom 840 : * weighting schemes. 841 : * 842 : * @param sorter The functor to use for generating keys. 843 : * 844 : * @param ascending If true, keys which sort higher by 845 : * string compare are better. If false, the sort order 846 : * is reversed. (default true) 847 : */ 848 : void set_sort_by_relevance_then_key(Xapian::Sorter * sorter, 849 : bool ascending = true); 850 : 851 : /** Get (a portion of) the match set for the current query. 852 : * 853 : * @param first the first item in the result set to return. 854 : * A value of zero corresponds to the first item 855 : * returned being that with the highest score. 856 : * A value of 10 corresponds to the first 10 items 857 : * being ignored, and the returned items starting 858 : * at the eleventh. 859 : * @param maxitems the maximum number of items to return. 860 : * @param checkatleast the minimum number of items to check. Because 861 : * the matcher optimises, it won't consider every 862 : * document which might match, so the total number 863 : * of matches is estimated. Setting checkatleast 864 : * forces it to consider at least this many matches 865 : * and so allows for reliable paging links. 866 : * @param omrset the relevance set to use when performing the query. 867 : * @param mdecider a decision functor to use to decide whether a 868 : * given document should be put in the MSet. 869 : * @param matchspy a decision functor to use to decide whether a 870 : * given document should be put in the MSet. The 871 : * matchspy is applied to every document which is 872 : * a potential candidate for the MSet, so if there are 873 : * checkatleast or more such documents, the matchspy 874 : * will see at least checkatleast. The mdecider is 875 : * assumed to be a relatively expensive test so may 876 : * be applied in a lazier fashion. 877 : * 878 : * @return A Xapian::MSet object containing the results of the 879 : * query. 880 : * 881 : * @exception Xapian::InvalidArgumentError See class documentation. 882 : */ 883 : MSet get_mset(Xapian::doccount first, Xapian::doccount maxitems, 884 : Xapian::doccount checkatleast = 0, 885 : const RSet * omrset = 0, 886 : const MatchDecider * mdecider = 0) const; 887 : MSet get_mset(Xapian::doccount first, Xapian::doccount maxitems, 888 : Xapian::doccount checkatleast, 889 : const RSet * omrset, 890 : const MatchDecider * mdecider, 891 : const MatchDecider * matchspy) const; 892 : MSet get_mset(Xapian::doccount first, Xapian::doccount maxitems, 893 : const RSet * omrset, 894 : const MatchDecider * mdecider = 0) const { 895 : return get_mset(first, maxitems, 0, omrset, mdecider); 896 : } 897 : 898 : static const int INCLUDE_QUERY_TERMS = 1; 899 : static const int USE_EXACT_TERMFREQ = 2; 900 : #ifndef _MSC_VER 901 : /// Deprecated in Xapian 1.0.0, use INCLUDE_QUERY_TERMS instead. 902 : XAPIAN_DEPRECATED(static const int include_query_terms) = 1; 903 : /// Deprecated in Xapian 1.0.0, use USE_EXACT_TERMFREQ instead. 904 : XAPIAN_DEPRECATED(static const int use_exact_termfreq) = 2; 905 : #else 906 : // Work around MSVC stupidity (you get a warning for deprecating a 907 : // declaration). 908 : static const int include_query_terms = 1; 909 : static const int use_exact_termfreq = 2; 910 : #pragma deprecated("Xapian::Enquire::include_query_terms", "Xapian::Enquire::use_exact_termfreq") 911 : #endif 912 : 913 : /** Get the expand set for the given rset. 914 : * 915 : * @param maxitems the maximum number of items to return. 916 : * @param omrset the relevance set to use when performing 917 : * the expand operation. 918 : * @param flags zero or more of these values |-ed together: 919 : * - Xapian::Enquire::INCLUDE_QUERY_TERMS query 920 : * terms may be returned from expand 921 : * - Xapian::Enquire::USE_EXACT_TERMFREQ for multi 922 : * dbs, calculate the exact termfreq; otherwise an 923 : * approximation is used which can greatly improve 924 : * efficiency, but still returns good results. 925 : * @param k the parameter k in the query expansion algorithm 926 : * (default is 1.0) 927 : * @param edecider a decision functor to use to decide whether a 928 : * given term should be put in the ESet 929 : * 930 : * @return An ESet object containing the results of the 931 : * expand. 932 : * 933 : * @exception Xapian::InvalidArgumentError See class documentation. 934 : */ 935 : ESet get_eset(Xapian::termcount maxitems, 936 : const RSet & omrset, 937 : int flags = 0, 938 : double k = 1.0, 939 : const Xapian::ExpandDecider * edecider = 0) const; 940 : 941 : /** Get the expand set for the given rset. 942 : * 943 : * @param maxitems the maximum number of items to return. 944 : * @param omrset the relevance set to use when performing 945 : * the expand operation. 946 : * @param edecider a decision functor to use to decide whether a 947 : * given term should be put in the ESet 948 : * 949 : * @return An ESet object containing the results of the 950 : * expand. 951 : * 952 : * @exception Xapian::InvalidArgumentError See class documentation. 953 : */ 954 : inline ESet get_eset(Xapian::termcount maxitems, const RSet & omrset, 955 4 : const Xapian::ExpandDecider * edecider) const { 956 4 : return get_eset(maxitems, omrset, 0, 1.0, edecider); 957 : } 958 : 959 : /** Get terms which match a given document, by document id. 960 : * 961 : * This method returns the terms in the current query which match 962 : * the given document. 963 : * 964 : * It is possible for the document to have been removed from the 965 : * database between the time it is returned in an MSet, and the 966 : * time that this call is made. If possible, you should specify 967 : * an MSetIterator instead of a Xapian::docid, since this will enable 968 : * database backends with suitable support to prevent this 969 : * occurring. 970 : * 971 : * Note that a query does not need to have been run in order to 972 : * make this call. 973 : * 974 : * @param did The document id for which to retrieve the matching 975 : * terms. 976 : * 977 : * @return An iterator returning the terms which match the 978 : * document. The terms will be returned (as far as this 979 : * makes any sense) in the same order as the terms 980 : * in the query. Terms will not occur more than once, 981 : * even if they do in the query. 982 : * 983 : * @exception Xapian::InvalidArgumentError See class documentation. 984 : * @exception Xapian::DocNotFoundError The document specified 985 : * could not be found in the database. 986 : */ 987 : TermIterator get_matching_terms_begin(Xapian::docid did) const; 988 : 989 : /** End iterator corresponding to get_matching_terms_begin() */ 990 : TermIterator get_matching_terms_end(Xapian::docid /*did*/) const { 991 : return TermIterator(NULL); 992 : } 993 : 994 : /** Get terms which match a given document, by match set item. 995 : * 996 : * This method returns the terms in the current query which match 997 : * the given document. 998 : * 999 : * If the underlying database has suitable support, using this call 1000 : * (rather than passing a Xapian::docid) will enable the system to 1001 : * ensure that the correct data is returned, and that the document 1002 : * has not been deleted or changed since the query was performed. 1003 : * 1004 : * @param it The iterator for which to retrieve the matching terms. 1005 : * 1006 : * @return An iterator returning the terms which match the 1007 : * document. The terms will be returned (as far as this 1008 : * makes any sense) in the same order as the terms 1009 : * in the query. Terms will not occur more than once, 1010 : * even if they do in the query. 1011 : * 1012 : * @exception Xapian::InvalidArgumentError See class documentation. 1013 : * @exception Xapian::DocNotFoundError The document specified 1014 : * could not be found in the database. 1015 : */ 1016 : TermIterator get_matching_terms_begin(const MSetIterator &it) const; 1017 : 1018 : /** End iterator corresponding to get_matching_terms_begin() */ 1019 : TermIterator get_matching_terms_end(const MSetIterator &/*it*/) const { 1020 : return TermIterator(NULL); 1021 : } 1022 : 1023 : /** Register a MatchDecider. 1024 : * 1025 : * This is used to associate a name with a matchdecider. 1026 : * 1027 : * @deprecated This method is deprecated. It was added long ago with 1028 : * the intention that it would allow the remote backend to support 1029 : * use of MatchDecider objects, but there's a better approach. 1030 : * 1031 : * @param name The name to register this matchdecider as. 1032 : * @param mdecider The matchdecider. If omitted, then remove 1033 : * any matchdecider registered with this name. 1034 : */ 1035 : XAPIAN_DEPRECATED( 1036 : void register_match_decider(const std::string &name, 1037 : const MatchDecider *mdecider = NULL)); 1038 : 1039 : /// Return a string describing this object. 1040 : std::string get_description() const; 1041 : }; 1042 : 1043 : } 1044 : 1045 : class RemoteServer; 1046 : class ScaleWeight; 1047 : 1048 : namespace Xapian { 1049 : 1050 : /// Abstract base class for weighting schemes 1051 : class XAPIAN_VISIBILITY_DEFAULT Weight { 1052 : friend class Enquire; // So Enquire can clone us 1053 : friend class ::RemoteServer; // So RemoteServer can clone us - FIXME 1054 : friend class ::ScaleWeight; 1055 : public: 1056 : class Internal; 1057 : protected: 1058 : Weight(const Weight &); 1059 : private: 1060 : void operator=(Weight &); 1061 : 1062 : /** Return a new weight object of this type. 1063 : * 1064 : * A subclass called FooWeight taking parameters param1 and param2 1065 : * should implement this as: 1066 : * 1067 : * virtual FooWeight * clone() const { 1068 : * return new FooWeight(param1, param2); 1069 : * } 1070 : */ 1071 : virtual Weight * clone() const = 0; 1072 : 1073 : protected: 1074 : const Internal * internal; // Weight::Internal == Stats 1075 : Xapian::doclength querysize; 1076 : Xapian::termcount wqf; 1077 : std::string tname; 1078 : 1079 : public: 1080 : // FIXME:1.1: initialise internal to NULL here 1081 : Weight() { } 1082 : virtual ~Weight(); 1083 : 1084 : /** Create a new weight object of the same type as this and initialise 1085 : * it with the specified statistics. 1086 : * 1087 : * You shouldn't call this method yourself - it's called by 1088 : * Enquire. 1089 : * 1090 : * @param internal_ Object to ask for collection statistics. 1091 : * @param querysize_ Query size. 1092 : * @param wqf_ Within query frequency of term this object is 1093 : * associated with. 1094 : * @param tname_ Term which this object is associated with. 1095 : */ 1096 : Weight * create(const Internal * internal_, Xapian::doclength querysize_, 1097 : Xapian::termcount wqf_, const std::string & tname_) const; 1098 : 1099 : /** Name of the weighting scheme. 1100 : * 1101 : * If the subclass is called FooWeight, this should return "Foo". 1102 : */ 1103 : virtual std::string name() const = 0; 1104 : 1105 : /// Serialise object parameters into a string. 1106 : virtual std::string serialise() const = 0; 1107 : 1108 : /// Create object given string serialisation returned by serialise(). 1109 : virtual Weight * unserialise(const std::string &s) const = 0; 1110 : 1111 : /** Get a weight which is part of the sum over terms being performed. 1112 : * This returns a weight for a given term and document. These 1113 : * weights are summed to give a total weight for the document. 1114 : * 1115 : * @param wdf the within document frequency of the term. 1116 : * @param len the (unnormalised) document length. 1117 : */ 1118 : virtual Xapian::weight get_sumpart(Xapian::termcount wdf, 1119 : Xapian::doclength len) const = 0; 1120 : 1121 : /** Gets the maximum value that get_sumpart() may return. This 1122 : * is used in optimising searches, by having the postlist tree 1123 : * decay appropriately when parts of it can have limited, or no, 1124 : * further effect. 1125 : */ 1126 : virtual Xapian::weight get_maxpart() const = 0; 1127 : 1128 : /** Get an extra weight for a document to add to the sum calculated 1129 : * over the query terms. 1130 : * This returns a weight for a given document, and is used by some 1131 : * weighting schemes to account for influence such as document 1132 : * length. 1133 : * 1134 : * @param len the (unnormalised) document length. 1135 : */ 1136 : virtual Xapian::weight get_sumextra(Xapian::doclength len) const = 0; 1137 : 1138 : /** Gets the maximum value that get_sumextra() may return. This 1139 : * is used in optimising searches. 1140 : */ 1141 : virtual Xapian::weight get_maxextra() const = 0; 1142 : 1143 : /// return false if the weight object doesn't need doclength 1144 : virtual bool get_sumpart_needs_doclength() const; /* { return true; } */ 1145 : }; 1146 : 1147 : /// Boolean weighting scheme (everything gets 0) 1148 : class XAPIAN_VISIBILITY_DEFAULT BoolWeight : public Weight { 1149 : public: 1150 : BoolWeight * clone() const; 1151 : BoolWeight() { } 1152 : ~BoolWeight(); 1153 : std::string name() const; 1154 : std::string serialise() const; 1155 : BoolWeight * unserialise(const std::string & s) const; 1156 : Xapian::weight get_sumpart(Xapian::termcount wdf, Xapian::doclength len) const; 1157 : Xapian::weight get_maxpart() const; 1158 : 1159 : Xapian::weight get_sumextra(Xapian::doclength len) const; 1160 : Xapian::weight get_maxextra() const; 1161 : 1162 : bool get_sumpart_needs_doclength() const; 1163 : }; 1164 : 1165 : /** BM25 weighting scheme 1166 : * 1167 : * BM25 weighting options : The BM25 formula is \f[ 1168 : * \frac{k_{2}.n_{q}}{1+L_{d}}+\sum_{t}\frac{(k_{3}+1)q_{t}}{k_{3}+q_{t}}.\frac{(k_{1}+1)f_{t,d}}{k_{1}((1-b)+bL_{d})+f_{t,d}}.w_{t} 1169 : * \f] where 1170 : * - \f$w_{t}\f$ is the termweight of term t 1171 : * - \f$f_{t,d}\f$ is the within document frequency of term t in document d 1172 : * - \f$q_{t}\f$ is the within query frequency of term t 1173 : * - \f$L_{d}\f$ is the normalised length of document d 1174 : * - \f$n_{q}\f$ is the size of the query 1175 : * - \f$k_{1}\f$, \f$k_{2}\f$, \f$k_{3}\f$ and \f$b\f$ are user specified parameters 1176 : */ 1177 : class XAPIAN_VISIBILITY_DEFAULT BM25Weight : public Weight { 1178 : private: 1179 : mutable Xapian::weight termweight; 1180 : mutable Xapian::doclength lenpart; 1181 : 1182 : double k1, k2, k3, b; 1183 : Xapian::doclength min_normlen; 1184 : 1185 : mutable bool weight_calculated; 1186 : 1187 : void calc_termweight() const; 1188 : 1189 : public: 1190 : /** Construct a BM25 weight. 1191 : * 1192 : * @param k1 governs the importance of within document frequency. 1193 : * Must be >= 0. 0 means ignore wdf. Default is 1. 1194 : * @param k2 compensation factor for the high wdf values in 1195 : * large documents. Must be >= 0. 0 means no 1196 : * compensation. Default is 0. 1197 : * @param k3 governs the importance of within query frequency. 1198 : * Must be >= 0. 0 means ignore wqf. Default is 1. 1199 : * @param b Relative importance of within document frequency and 1200 : * document length. Must be >= 0 and <= 1. Default 1201 : * is 0.5. 1202 : * @param min_normlen specifies a cutoff on the minimum value that 1203 : * can be used for a normalised document length - 1204 : * smaller values will be forced up to this cutoff. 1205 : * This prevents very small documents getting a huge 1206 : * bonus weight. Default is 0.5. 1207 : */ 1208 : BM25Weight(double k1_, double k2_, double k3_, double b_, 1209 : double min_normlen_) 1210 : : k1(k1_), k2(k2_), k3(k3_), b(b_), min_normlen(min_normlen_), 1211 : weight_calculated(false) 1212 : { 1213 : if (k1 < 0) k1 = 0; 1214 : if (k2 < 0) k2 = 0; 1215 : if (k3 < 0) k3 = 0; 1216 : if (b < 0) b = 0; else if (b > 1) b = 1; 1217 : } 1218 : BM25Weight() : k1(1), k2(0), k3(1), b(0.5), min_normlen(0.5), 1219 : weight_calculated(false) { } 1220 : 1221 : BM25Weight * clone() const; 1222 : ~BM25Weight() { } 1223 : std::string name() const; 1224 : std::string serialise() const; 1225 : BM25Weight * unserialise(const std::string & s) const; 1226 : Xapian::weight get_sumpart(Xapian::termcount wdf, Xapian::doclength len) const; 1227 : Xapian::weight get_maxpart() const; 1228 : 1229 : Xapian::weight get_sumextra(Xapian::doclength len) const; 1230 : Xapian::weight get_maxextra() const; 1231 : 1232 : bool get_sumpart_needs_doclength() const; 1233 : }; 1234 : 1235 : /** Traditional probabilistic weighting scheme. 1236 : * 1237 : * This class implements the Traditional Probabilistic Weighting scheme, as 1238 : * described by the early papers on Probabilistic Retrieval. BM25 generally 1239 : * gives better results. 1240 : * 1241 : * The Traditional weighting scheme formula is \f[ 1242 : * \sum_{t}\frac{f_{t,d}}{k.L_{d}+f_{t,d}}.w_{t} 1243 : * \f] where 1244 : * - \f$w_{t}\f$ is the termweight of term t 1245 : * - \f$f_{t,d}\f$ is the within document frequency of term t in document d 1246 : * - \f$L_{d}\f$ is the normalised length of document d 1247 : * - \f$k\f$ is a user specifiable parameter 1248 : * 1249 : * TradWeight(k) is equivalent to BM25Weight(k, 0, 0, 1, 0), except that 1250 : * the latter returns weights (k+1) times larger. 1251 : */ 1252 : class XAPIAN_VISIBILITY_DEFAULT TradWeight : public Weight { 1253 : private: 1254 : mutable Xapian::weight termweight; 1255 : mutable Xapian::doclength lenpart; 1256 : 1257 : double param_k; 1258 : 1259 : mutable bool weight_calculated; 1260 : 1261 : void calc_termweight() const; 1262 : 1263 : public: 1264 : /** Construct a TradWeight 1265 : * 1266 : * @param k parameter governing the importance of within 1267 : * document frequency and document length - any non-negative 1268 : * number (0 meaning to ignore wdf and doc length when 1269 : * calculating weights). Default is 1. 1270 : */ 1271 : explicit TradWeight(double k) : param_k(k), weight_calculated(false) { 1272 : if (param_k < 0) param_k = 0; 1273 : } 1274 : 1275 : TradWeight() : param_k(1.0), weight_calculated(false) { } 1276 : 1277 : TradWeight * clone() const; 1278 : ~TradWeight() { } 1279 : std::string name() const; 1280 : std::string serialise() const; 1281 : TradWeight * unserialise(const std::string & s) const; 1282 : 1283 : Xapian::weight get_sumpart(Xapian::termcount wdf, Xapian::doclength len) const; 1284 : Xapian::weight get_maxpart() const; 1285 : 1286 : Xapian::weight get_sumextra(Xapian::doclength len) const; 1287 : Xapian::weight get_maxextra() const; 1288 : 1289 : bool get_sumpart_needs_doclength() const; 1290 : }; 1291 : 1292 : } 1293 : 1294 : #endif /* XAPIAN_INCLUDED_ENQUIRE_H */ |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
Directory name | Coverage | |||
/srv/build/pkg/ept-work/default/ept |
|
100.0 % | 107 / 107 lines | |
/srv/build/pkg/ept-work/default/wibble |
|
100.0 % | 125 / 125 lines | |
/usr/include/apt-pkg |
|
86.2 % | 69 / 80 lines | |
/usr/include/c++/4.3 |
|
6.6 % | 12 / 181 lines | |
/usr/include/c++/4.3/backward |
|
100.0 % | 22 / 22 lines | |
/usr/include/c++/4.3/bits |
|
69.1 % | 1418 / 2051 lines | |
/usr/include/c++/4.3/ext |
|
53.6 % | 15 / 28 lines | |
/usr/include/c++/4.3/i486-linux-gnu/bits |
|
0.0 % | 0 / 2 lines | |
/usr/include/tagcoll-2.0.11/tagcoll |
|
73.4 % | 127 / 173 lines | |
/usr/include/tagcoll-2.0.11/tagcoll/coll |
|
79.7 % | 141 / 177 lines | |
/usr/include/tagcoll-2.0.11/tagcoll/diskindex |
|
93.3 % | 14 / 15 lines | |
/usr/include/tagcoll-2.0.11/tagcoll/input |
|
18.8 % | 3 / 16 lines | |
/usr/include/tagcoll-2.0.11/tagcoll/stream |
|
100.0 % | 8 / 8 lines | |
/usr/include/tagcoll-2.0.11/tagcoll/utils |
|
83.3 % | 10 / 12 lines | |
/usr/include/xapian |
|
76.6 % | 59 / 77 lines | |
ept |
|
73.7 % | 28 / 38 lines | |
ept/apt |
|
89.2 % | 785 / 880 lines | |
ept/core |
|
82.8 % | 570 / 688 lines | |
ept/core/apt |
|
91.9 % | 307 / 334 lines | |
ept/debtags |
|
89.2 % | 626 / 702 lines | |
ept/debtags/maint |
|
84.9 % | 718 / 846 lines | |
ept/popcon |
|
83.2 % | 134 / 161 lines | |
ept/popcon/maint |
|
88.4 % | 228 / 258 lines | |
ept/textsearch |
|
77.3 % | 167 / 216 lines | |
ept/textsearch/maint |
|
85.3 % | 29 / 34 lines | |
wibble |
|
89.9 % | 1954 / 2173 lines | |
wibble/commandline |
|
83.9 % | 559 / 666 lines | |
wibble/grcal |
|
81.9 % | 308 / 376 lines | |
wibble/log |
|
93.0 % | 53 / 57 lines | |
wibble/stream |
|
81.0 % | 34 / 42 lines | |
wibble/sys |
|
60.1 % | 597 / 994 lines |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/debtags/maint/vocabularymerger.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_VocabularyMerger__1() { RUN( TestVocabularyMerger, _1 ); } 4 1 : void run_VocabularyMerger__2() { RUN( TestVocabularyMerger, _2 ); } 5 4 : void run_VocabularyMerger__3() { RUN( TestVocabularyMerger, _3 ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #undef NDEBUG 2 : #include <wibble/test.h> 3 : #include <wibble/test-runner.h> 4 : void run_AptRecord_checkLookup(); 5 : void run_AptRecord_checkLookupValue(); 6 : void run_AptRecord_checkLookupNumeric(); 7 : void run_AptRecord_checkShortDescription(); 8 : void run_AptRecord_checkList(); 9 : void run_AptRecord_nonexistent(); 10 : RunTest run_AptRecord[] = { 11 : { "checkLookup", run_AptRecord_checkLookup }, 12 : { "checkLookupValue", run_AptRecord_checkLookupValue }, 13 : { "checkLookupNumeric", run_AptRecord_checkLookupNumeric }, 14 : { "checkShortDescription", run_AptRecord_checkShortDescription }, 15 : { "checkList", run_AptRecord_checkList }, 16 : { "nonexistent", run_AptRecord_nonexistent }, 17 : }; 18 : void run_Expression__1(); 19 : RunTest run_Expression[] = { 20 : { "_1", run_Expression__1 }, 21 : }; 22 : void run_Textsearch_empty(); 23 : void run_Textsearch_basicAccess(); 24 : void run_Textsearch_queryAccess(); 25 : void run_Textsearch_partialOrQuery(); 26 : void run_Textsearch_docidByName(); 27 : void run_Textsearch_values(); 28 : RunTest run_Textsearch[] = { 29 : { "empty", run_Textsearch_empty }, 30 : { "basicAccess", run_Textsearch_basicAccess }, 31 : { "queryAccess", run_Textsearch_queryAccess }, 32 : { "partialOrQuery", run_Textsearch_partialOrQuery }, 33 : { "docidByName", run_Textsearch_docidByName }, 34 : { "values", run_Textsearch_values }, 35 : }; 36 : void run_VocabularyMerger__1(); 37 : void run_VocabularyMerger__2(); 38 : void run_VocabularyMerger__3(); 39 : RunTest run_VocabularyMerger[] = { 40 : { "_1", run_VocabularyMerger__1 }, 41 : { "_2", run_VocabularyMerger__2 }, 42 : { "_3", run_VocabularyMerger__3 }, 43 : }; 44 : void run_AptAction_basic(); 45 : void run_AptAction_revert(); 46 : void run_AptAction_keep(); 47 : RunTest run_AptAction[] = { 48 : { "basic", run_AptAction_basic }, 49 : { "revert", run_AptAction_revert }, 50 : { "keep", run_AptAction_keep }, 51 : }; 52 : void run_AptPackagerecord_supportedFields(); 53 : RunTest run_AptPackagerecord[] = { 54 : { "supportedFields", run_AptPackagerecord_supportedFields }, 55 : }; 56 : void run_Pkgid__1(); 57 : void run_Pkgid__2(); 58 : RunTest run_Pkgid[] = { 59 : { "_1", run_Pkgid__1 }, 60 : { "_2", run_Pkgid__2 }, 61 : }; 62 : void run_Xapian_enquire(); 63 : void run_Xapian_listCount(); 64 : void run_Xapian_list(); 65 : void run_Xapian_checkQuery(); 66 : RunTest run_Xapian[] = { 67 : { "enquire", run_Xapian_enquire }, 68 : { "listCount", run_Xapian_listCount }, 69 : { "list", run_Xapian_list }, 70 : { "checkQuery", run_Xapian_checkQuery }, 71 : }; 72 : void run_AptVersion_invalid(); 73 : void run_AptVersion_basic(); 74 : void run_AptVersion_comparison(); 75 : void run_AptVersion_valueCopy(); 76 : void run_AptVersion_upstreamVersion(); 77 : void run_AptVersion_policyComparison(); 78 : RunTest run_AptVersion[] = { 79 : { "invalid", run_AptVersion_invalid }, 80 : { "basic", run_AptVersion_basic }, 81 : { "comparison", run_AptVersion_comparison }, 82 : { "valueCopy", run_AptVersion_valueCopy }, 83 : { "upstreamVersion", run_AptVersion_upstreamVersion }, 84 : { "policyComparison", run_AptVersion_policyComparison }, 85 : }; 86 : void run_Vocabulary__1(); 87 : void run_Vocabulary__2(); 88 : void run_Vocabulary__3(); 89 : void run_Vocabulary__4(); 90 : void run_Vocabulary__5(); 91 : void run_Vocabulary__6(); 92 : void run_Vocabulary__7(); 93 : void run_Vocabulary__8(); 94 : void run_Vocabulary__9(); 95 : void run_Vocabulary__11(); 96 : void run_Vocabulary__12(); 97 : void run_Vocabulary__13(); 98 : void run_Vocabulary__14(); 99 : void run_Vocabulary__15(); 100 : void run_Vocabulary__16(); 101 : void run_Vocabulary__17(); 102 : void run_Vocabulary__18(); 103 : void run_Vocabulary__19(); 104 : void run_Vocabulary__21(); 105 : RunTest run_Vocabulary[] = { 106 : { "_1", run_Vocabulary__1 }, 107 : { "_2", run_Vocabulary__2 }, 108 : { "_3", run_Vocabulary__3 }, 109 : { "_4", run_Vocabulary__4 }, 110 : { "_5", run_Vocabulary__5 }, 111 : { "_6", run_Vocabulary__6 }, 112 : { "_7", run_Vocabulary__7 }, 113 : { "_8", run_Vocabulary__8 }, 114 : { "_9", run_Vocabulary__9 }, 115 : { "_11", run_Vocabulary__11 }, 116 : { "_12", run_Vocabulary__12 }, 117 : { "_13", run_Vocabulary__13 }, 118 : { "_14", run_Vocabulary__14 }, 119 : { "_15", run_Vocabulary__15 }, 120 : { "_16", run_Vocabulary__16 }, 121 : { "_17", run_Vocabulary__17 }, 122 : { "_18", run_Vocabulary__18 }, 123 : { "_19", run_Vocabulary__19 }, 124 : { "_21", run_Vocabulary__21 }, 125 : }; 126 : void run_CoreApt_token(); 127 : void run_CoreApt_tokenVersion(); 128 : void run_CoreApt_packageName(); 129 : void run_CoreApt_packageCount(); 130 : void run_CoreApt_packageNameList(); 131 : void run_CoreApt_versionCount(); 132 : void run_CoreApt_versionPackage(); 133 : void run_CoreApt_validate(); 134 : void run_CoreApt_packageState(); 135 : void run_CoreApt_packageState2(); 136 : void run_CoreApt_exists(); 137 : void run_CoreApt_invalidate(); 138 : RunTest run_CoreApt[] = { 139 : { "token", run_CoreApt_token }, 140 : { "tokenVersion", run_CoreApt_tokenVersion }, 141 : { "packageName", run_CoreApt_packageName }, 142 : { "packageCount", run_CoreApt_packageCount }, 143 : { "packageNameList", run_CoreApt_packageNameList }, 144 : { "versionCount", run_CoreApt_versionCount }, 145 : { "versionPackage", run_CoreApt_versionPackage }, 146 : { "validate", run_CoreApt_validate }, 147 : { "packageState", run_CoreApt_packageState }, 148 : { "packageState2", run_CoreApt_packageState2 }, 149 : { "exists", run_CoreApt_exists }, 150 : { "invalidate", run_CoreApt_invalidate }, 151 : }; 152 : void run_Popcon_basicAccess(); 153 : void run_Popcon_accessibility(); 154 : void run_Popcon_haveScores(); 155 : void run_Popcon_validScores(); 156 : void run_Popcon_fallbackValues(); 157 : RunTest run_Popcon[] = { 158 : { "basicAccess", run_Popcon_basicAccess }, 159 : { "accessibility", run_Popcon_accessibility }, 160 : { "haveScores", run_Popcon_haveScores }, 161 : { "validScores", run_Popcon_validScores }, 162 : { "fallbackValues", run_Popcon_fallbackValues }, 163 : }; 164 : void run_Apt_iterators(); 165 : void run_Apt_aptExists(); 166 : void run_Apt_timestamp(); 167 : void run_Apt_validity(); 168 : void run_Apt_versions(); 169 : void run_Apt_versionValidity(); 170 : void run_Apt_rawRecord(); 171 : void run_Apt_state(); 172 : void run_Apt_recordIteration(); 173 : void run_Apt_recordIteration2(); 174 : void run_Apt_stlIteration(); 175 : void run_Apt_stlRecordIteration(); 176 : void run_Apt_checkUpdates(); 177 : RunTest run_Apt[] = { 178 : { "iterators", run_Apt_iterators }, 179 : { "aptExists", run_Apt_aptExists }, 180 : { "timestamp", run_Apt_timestamp }, 181 : { "validity", run_Apt_validity }, 182 : { "versions", run_Apt_versions }, 183 : { "versionValidity", run_Apt_versionValidity }, 184 : { "rawRecord", run_Apt_rawRecord }, 185 : { "state", run_Apt_state }, 186 : { "recordIteration", run_Apt_recordIteration }, 187 : { "recordIteration2", run_Apt_recordIteration2 }, 188 : { "stlIteration", run_Apt_stlIteration }, 189 : { "stlRecordIteration", run_Apt_stlRecordIteration }, 190 : { "checkUpdates", run_Apt_checkUpdates }, 191 : }; 192 : void run_Desktop_iteration(); 193 : void run_Desktop_groupProperty(); 194 : void run_Desktop_groups(); 195 : void run_Desktop_groupList(); 196 : void run_Desktop_emptyGroupList(); 197 : RunTest run_Desktop[] = { 198 : { "iteration", run_Desktop_iteration }, 199 : { "groupProperty", run_Desktop_groupProperty }, 200 : { "groups", run_Desktop_groups }, 201 : { "groupList", run_Desktop_groupList }, 202 : { "emptyGroupList", run_Desktop_emptyGroupList }, 203 : }; 204 : void run_Debtags__1(); 205 : void run_Debtags__2(); 206 : void run_Debtags__3(); 207 : void run_Debtags__4(); 208 : void run_Debtags__5(); 209 : RunTest run_Debtags[] = { 210 : { "_1", run_Debtags__1 }, 211 : { "_2", run_Debtags__2 }, 212 : { "_3", run_Debtags__3 }, 213 : { "_4", run_Debtags__4 }, 214 : { "_5", run_Debtags__5 }, 215 : }; 216 : void run_AptRecordparser_parsing(); 217 : void run_AptRecordparser_fieldTuples(); 218 : void run_AptRecordparser_fieldKeys(); 219 : void run_AptRecordparser_fieldValues(); 220 : void run_AptRecordparser_findByName(); 221 : void run_AptRecordparser_indexing(); 222 : void run_AptRecordparser_missingBehaviour(); 223 : void run_AptRecordparser_rescan(); 224 : void run_AptRecordparser_realLife(); 225 : void run_AptRecordparser_bufferTermination(); 226 : void run_AptRecordparser_bufferTermination2(); 227 : void run_AptRecordparser_bufferTermination3(); 228 : RunTest run_AptRecordparser[] = { 229 : { "parsing", run_AptRecordparser_parsing }, 230 : { "fieldTuples", run_AptRecordparser_fieldTuples }, 231 : { "fieldKeys", run_AptRecordparser_fieldKeys }, 232 : { "fieldValues", run_AptRecordparser_fieldValues }, 233 : { "findByName", run_AptRecordparser_findByName }, 234 : { "indexing", run_AptRecordparser_indexing }, 235 : { "missingBehaviour", run_AptRecordparser_missingBehaviour }, 236 : { "rescan", run_AptRecordparser_rescan }, 237 : { "realLife", run_AptRecordparser_realLife }, 238 : { "bufferTermination", run_AptRecordparser_bufferTermination }, 239 : { "bufferTermination2", run_AptRecordparser_bufferTermination2 }, 240 : { "bufferTermination3", run_AptRecordparser_bufferTermination3 }, 241 : }; 242 : void run_PopconLocal_basicAccess(); 243 : RunTest run_PopconLocal[] = { 244 : { "basicAccess", run_PopconLocal_basicAccess }, 245 : }; 246 : void run_Serializer__1(); 247 : void run_Serializer__2(); 248 : RunTest run_Serializer[] = { 249 : { "_1", run_Serializer__1 }, 250 : { "_2", run_Serializer__2 }, 251 : }; 252 : RunSuite suites[] = { 253 : { "AptRecord", run_AptRecord, 6 }, 254 : { "Expression", run_Expression, 1 }, 255 : { "Textsearch", run_Textsearch, 6 }, 256 : { "VocabularyMerger", run_VocabularyMerger, 3 }, 257 : { "AptAction", run_AptAction, 3 }, 258 : { "AptPackagerecord", run_AptPackagerecord, 1 }, 259 : { "Pkgid", run_Pkgid, 2 }, 260 : { "Xapian", run_Xapian, 4 }, 261 : { "AptVersion", run_AptVersion, 6 }, 262 : { "Vocabulary", run_Vocabulary, 19 }, 263 : { "CoreApt", run_CoreApt, 12 }, 264 : { "Popcon", run_Popcon, 5 }, 265 : { "Apt", run_Apt, 13 }, 266 : { "Desktop", run_Desktop, 5 }, 267 : { "Debtags", run_Debtags, 5 }, 268 : { "AptRecordparser", run_AptRecordparser, 12 }, 269 : { "PopconLocal", run_PopconLocal, 1 }, 270 : { "Serializer", run_Serializer, 2 }, 271 : }; 272 : #include <wibble/test-main.h> 273 3 : int assertFailure = 0; |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/debtags/vocabulary.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_Vocabulary__1() { RUN( TestVocabulary, _1 ); } 4 1 : void run_Vocabulary__2() { RUN( TestVocabulary, _2 ); } 5 1 : void run_Vocabulary__3() { RUN( TestVocabulary, _3 ); } 6 1 : void run_Vocabulary__4() { RUN( TestVocabulary, _4 ); } 7 1 : void run_Vocabulary__5() { RUN( TestVocabulary, _5 ); } 8 1 : void run_Vocabulary__6() { RUN( TestVocabulary, _6 ); } 9 1 : void run_Vocabulary__7() { RUN( TestVocabulary, _7 ); } 10 1 : void run_Vocabulary__8() { RUN( TestVocabulary, _8 ); } 11 1 : void run_Vocabulary__9() { RUN( TestVocabulary, _9 ); } 12 1 : void run_Vocabulary__11() { RUN( TestVocabulary, _11 ); } 13 1 : void run_Vocabulary__12() { RUN( TestVocabulary, _12 ); } 14 1 : void run_Vocabulary__13() { RUN( TestVocabulary, _13 ); } 15 1 : void run_Vocabulary__14() { RUN( TestVocabulary, _14 ); } 16 1 : void run_Vocabulary__15() { RUN( TestVocabulary, _15 ); } 17 1 : void run_Vocabulary__16() { RUN( TestVocabulary, _16 ); } 18 1 : void run_Vocabulary__17() { RUN( TestVocabulary, _17 ); } 19 1 : void run_Vocabulary__18() { RUN( TestVocabulary, _18 ); } 20 1 : void run_Vocabulary__19() { RUN( TestVocabulary, _19 ); } 21 4 : void run_Vocabulary__21() { RUN( TestVocabulary, _21 ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/popcon/local.test.h" 2 : #define RUN(x,y) x().y() 3 4 : void run_PopconLocal_basicAccess() { RUN( TestPopconLocal, basicAccess ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/core/apt/action.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_AptAction_basic() { RUN( TestAptAction, basic ); } 4 1 : void run_AptAction_revert() { RUN( TestAptAction, revert ); } 5 4 : void run_AptAction_keep() { RUN( TestAptAction, keep ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/debtags/maint/pkgid.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_Pkgid__1() { RUN( TestPkgid, _1 ); } 4 4 : void run_Pkgid__2() { RUN( TestPkgid, _2 ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/debtags/maint/serializer.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_Serializer__1() { RUN( TestSerializer, _1 ); } 4 4 : void run_Serializer__2() { RUN( TestSerializer, _2 ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/core/desktop.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_Desktop_iteration() { RUN( TestDesktop, iteration ); } 4 1 : void run_Desktop_groupProperty() { RUN( TestDesktop, groupProperty ); } 5 1 : void run_Desktop_groups() { RUN( TestDesktop, groups ); } 6 1 : void run_Desktop_groupList() { RUN( TestDesktop, groupList ); } 7 4 : void run_Desktop_emptyGroupList() { RUN( TestDesktop, emptyGroupList ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/core/apt.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_CoreApt_token() { RUN( TestCoreApt, token ); } 4 1 : void run_CoreApt_tokenVersion() { RUN( TestCoreApt, tokenVersion ); } 5 1 : void run_CoreApt_packageName() { RUN( TestCoreApt, packageName ); } 6 1 : void run_CoreApt_packageCount() { RUN( TestCoreApt, packageCount ); } 7 1 : void run_CoreApt_packageNameList() { RUN( TestCoreApt, packageNameList ); } 8 1 : void run_CoreApt_versionCount() { RUN( TestCoreApt, versionCount ); } 9 1 : void run_CoreApt_versionPackage() { RUN( TestCoreApt, versionPackage ); } 10 1 : void run_CoreApt_validate() { RUN( TestCoreApt, validate ); } 11 1 : void run_CoreApt_packageState() { RUN( TestCoreApt, packageState ); } 12 1 : void run_CoreApt_packageState2() { RUN( TestCoreApt, packageState2 ); } 13 1 : void run_CoreApt_exists() { RUN( TestCoreApt, exists ); } 14 4 : void run_CoreApt_invalidate() { RUN( TestCoreApt, invalidate ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/apt/recordparser.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_AptRecordparser_parsing() { RUN( TestAptRecordparser, parsing ); } 4 1 : void run_AptRecordparser_fieldTuples() { RUN( TestAptRecordparser, fieldTuples ); } 5 1 : void run_AptRecordparser_fieldKeys() { RUN( TestAptRecordparser, fieldKeys ); } 6 1 : void run_AptRecordparser_fieldValues() { RUN( TestAptRecordparser, fieldValues ); } 7 1 : void run_AptRecordparser_findByName() { RUN( TestAptRecordparser, findByName ); } 8 1 : void run_AptRecordparser_indexing() { RUN( TestAptRecordparser, indexing ); } 9 1 : void run_AptRecordparser_missingBehaviour() { RUN( TestAptRecordparser, missingBehaviour ); } 10 1 : void run_AptRecordparser_rescan() { RUN( TestAptRecordparser, rescan ); } 11 1 : void run_AptRecordparser_realLife() { RUN( TestAptRecordparser, realLife ); } 12 1 : void run_AptRecordparser_bufferTermination() { RUN( TestAptRecordparser, bufferTermination ); } 13 1 : void run_AptRecordparser_bufferTermination2() { RUN( TestAptRecordparser, bufferTermination2 ); } 14 4 : void run_AptRecordparser_bufferTermination3() { RUN( TestAptRecordparser, bufferTermination3 ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/textsearch/textsearch.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_Textsearch_empty() { RUN( TestTextsearch, empty ); } 4 1 : void run_Textsearch_basicAccess() { RUN( TestTextsearch, basicAccess ); } 5 1 : void run_Textsearch_queryAccess() { RUN( TestTextsearch, queryAccess ); } 6 1 : void run_Textsearch_partialOrQuery() { RUN( TestTextsearch, partialOrQuery ); } 7 1 : void run_Textsearch_docidByName() { RUN( TestTextsearch, docidByName ); } 8 4 : void run_Textsearch_values() { RUN( TestTextsearch, values ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/apt/version.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_AptVersion_invalid() { RUN( TestAptVersion, invalid ); } 4 1 : void run_AptVersion_basic() { RUN( TestAptVersion, basic ); } 5 1 : void run_AptVersion_comparison() { RUN( TestAptVersion, comparison ); } 6 1 : void run_AptVersion_valueCopy() { RUN( TestAptVersion, valueCopy ); } 7 1 : void run_AptVersion_upstreamVersion() { RUN( TestAptVersion, upstreamVersion ); } 8 4 : void run_AptVersion_policyComparison() { RUN( TestAptVersion, policyComparison ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/apt/packagerecord.test.h" 2 : #define RUN(x,y) x().y() 3 4 : void run_AptPackagerecord_supportedFields() { RUN( TestAptPackagerecord, supportedFields ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/debtags/debtags.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_Debtags__1() { RUN( TestDebtags, _1 ); } 4 1 : void run_Debtags__2() { RUN( TestDebtags, _2 ); } 5 1 : void run_Debtags__3() { RUN( TestDebtags, _3 ); } 6 1 : void run_Debtags__4() { RUN( TestDebtags, _4 ); } 7 4 : void run_Debtags__5() { RUN( TestDebtags, _5 ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/apt/apt.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_Apt_iterators() { RUN( TestApt, iterators ); } 4 1 : void run_Apt_aptExists() { RUN( TestApt, aptExists ); } 5 1 : void run_Apt_timestamp() { RUN( TestApt, timestamp ); } 6 1 : void run_Apt_validity() { RUN( TestApt, validity ); } 7 1 : void run_Apt_versions() { RUN( TestApt, versions ); } 8 1 : void run_Apt_versionValidity() { RUN( TestApt, versionValidity ); } 9 1 : void run_Apt_rawRecord() { RUN( TestApt, rawRecord ); } 10 1 : void run_Apt_state() { RUN( TestApt, state ); } 11 1 : void run_Apt_recordIteration() { RUN( TestApt, recordIteration ); } 12 1 : void run_Apt_recordIteration2() { RUN( TestApt, recordIteration2 ); } 13 1 : void run_Apt_stlIteration() { RUN( TestApt, stlIteration ); } 14 1 : void run_Apt_stlRecordIteration() { RUN( TestApt, stlRecordIteration ); } 15 4 : void run_Apt_checkUpdates() { RUN( TestApt, checkUpdates ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/core/xapian.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_Xapian_enquire() { RUN( TestXapian, enquire ); } 4 1 : void run_Xapian_listCount() { RUN( TestXapian, listCount ); } 5 1 : void run_Xapian_list() { RUN( TestXapian, list ); } 6 4 : void run_Xapian_checkQuery() { RUN( TestXapian, checkQuery ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/debtags/expression.test.h" 2 : #define RUN(x,y) x().y() 3 4 : void run_Expression__1() { RUN( TestExpression, _1 ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/popcon/popcon.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_Popcon_basicAccess() { RUN( TestPopcon, basicAccess ); } 4 1 : void run_Popcon_accessibility() { RUN( TestPopcon, accessibility ); } 5 1 : void run_Popcon_haveScores() { RUN( TestPopcon, haveScores ); } 6 1 : void run_Popcon_validScores() { RUN( TestPopcon, validScores ); } 7 4 : void run_Popcon_fallbackValues() { RUN( TestPopcon, fallbackValues ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |
LTP GCOV extension - code coverage report | ||||||||||||||||||||
![]() | ||||||||||||||||||||
|
||||||||||||||||||||
![]() |
1 : #include "/home/mornfall/dev/pkg/ept-work/ept/core/apt/record.test.h" 2 : #define RUN(x,y) x().y() 3 1 : void run_AptRecord_checkLookup() { RUN( TestAptRecord, checkLookup ); } 4 1 : void run_AptRecord_checkLookupValue() { RUN( TestAptRecord, checkLookupValue ); } 5 1 : void run_AptRecord_checkLookupNumeric() { RUN( TestAptRecord, checkLookupNumeric ); } 6 1 : void run_AptRecord_checkShortDescription() { RUN( TestAptRecord, checkShortDescription ); } 7 1 : void run_AptRecord_checkList() { RUN( TestAptRecord, checkList ); } 8 4 : void run_AptRecord_nonexistent() { RUN( TestAptRecord, nonexistent ); } |
![]() |
Generated by: LTP GCOV extension version 1.6 |