2883 |
03 Dec 12 |
peter |
// $Id$ |
2883 |
03 Dec 12 |
peter |
2 |
|
2993 |
03 Mar 13 |
peter |
3 |
/* |
4359 |
23 Aug 23 |
peter |
Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2023 Peter Johansson |
2993 |
03 Mar 13 |
peter |
5 |
|
2993 |
03 Mar 13 |
peter |
This file is part of the yat library, http://dev.thep.lu.se/yat |
2993 |
03 Mar 13 |
peter |
7 |
|
2993 |
03 Mar 13 |
peter |
The yat library is free software; you can redistribute it and/or |
2993 |
03 Mar 13 |
peter |
modify it under the terms of the GNU General Public License as |
2993 |
03 Mar 13 |
peter |
published by the Free Software Foundation; either version 3 of the |
2993 |
03 Mar 13 |
peter |
License, or (at your option) any later version. |
2993 |
03 Mar 13 |
peter |
12 |
|
2993 |
03 Mar 13 |
peter |
The yat library is distributed in the hope that it will be useful, |
2993 |
03 Mar 13 |
peter |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
2993 |
03 Mar 13 |
peter |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2993 |
03 Mar 13 |
peter |
General Public License for more details. |
2993 |
03 Mar 13 |
peter |
17 |
|
2993 |
03 Mar 13 |
peter |
You should have received a copy of the GNU General Public License |
3752 |
17 Oct 18 |
peter |
along with yat. If not, see <http://www.gnu.org/licenses/>. |
2993 |
03 Mar 13 |
peter |
20 |
*/ |
2993 |
03 Mar 13 |
peter |
21 |
|
2883 |
03 Dec 12 |
peter |
22 |
#include <config.h> |
2883 |
03 Dec 12 |
peter |
23 |
|
2883 |
03 Dec 12 |
peter |
24 |
#include "BamHeader.h" |
2883 |
03 Dec 12 |
peter |
25 |
|
2999 |
14 Mar 13 |
peter |
26 |
#include "yat/utility/Exception.h" |
3410 |
21 Apr 15 |
peter |
27 |
#include "yat/utility/split.h" |
3412 |
22 Apr 15 |
peter |
28 |
#include "yat/utility/stl_utility.h" |
2999 |
14 Mar 13 |
peter |
29 |
|
2883 |
03 Dec 12 |
peter |
30 |
#include <cassert> |
3408 |
16 Apr 15 |
peter |
31 |
#include <cstdlib> |
3408 |
16 Apr 15 |
peter |
32 |
#include <cstring> |
2999 |
14 Mar 13 |
peter |
33 |
#include <string> |
2999 |
14 Mar 13 |
peter |
34 |
#include <sstream> |
3408 |
16 Apr 15 |
peter |
35 |
#include <utility> |
2883 |
03 Dec 12 |
peter |
36 |
|
2883 |
03 Dec 12 |
peter |
37 |
namespace theplu { |
2883 |
03 Dec 12 |
peter |
38 |
namespace yat { |
2883 |
03 Dec 12 |
peter |
39 |
namespace omic { |
2883 |
03 Dec 12 |
peter |
40 |
|
2883 |
03 Dec 12 |
peter |
41 |
BamHeader::BamHeader(void) |
2883 |
03 Dec 12 |
peter |
42 |
: header_(NULL) |
2883 |
03 Dec 12 |
peter |
43 |
{ |
2883 |
03 Dec 12 |
peter |
44 |
} |
2883 |
03 Dec 12 |
peter |
45 |
|
2883 |
03 Dec 12 |
peter |
46 |
|
3408 |
16 Apr 15 |
peter |
47 |
BamHeader::~BamHeader(void) |
3408 |
16 Apr 15 |
peter |
48 |
{ |
3408 |
16 Apr 15 |
peter |
49 |
bam_hdr_destroy(header_); |
3408 |
16 Apr 15 |
peter |
50 |
} |
3408 |
16 Apr 15 |
peter |
51 |
|
3408 |
16 Apr 15 |
peter |
52 |
|
3408 |
16 Apr 15 |
peter |
53 |
BamHeader::BamHeader(const BamHeader& other) |
3410 |
21 Apr 15 |
peter |
54 |
: read_group_(other.read_group_), program_group_(other.program_group_) |
3408 |
16 Apr 15 |
peter |
55 |
{ |
3408 |
16 Apr 15 |
peter |
56 |
header_ = bam_hdr_dup(other.header_); |
4265 |
13 Jan 23 |
peter |
57 |
if (other.header_ && !header_) |
4265 |
13 Jan 23 |
peter |
58 |
throw utility::runtime_error("BamHeader: bam_hdr_dup failed"); |
3408 |
16 Apr 15 |
peter |
59 |
} |
3408 |
16 Apr 15 |
peter |
60 |
|
3408 |
16 Apr 15 |
peter |
61 |
|
3691 |
14 Sep 17 |
peter |
62 |
BamHeader::BamHeader(BamHeader&& other) noexcept |
3600 |
22 Jan 17 |
peter |
63 |
: header_(NULL) |
3600 |
22 Jan 17 |
peter |
64 |
{ |
3600 |
22 Jan 17 |
peter |
65 |
swap(other); |
3600 |
22 Jan 17 |
peter |
66 |
} |
3600 |
22 Jan 17 |
peter |
67 |
|
3600 |
22 Jan 17 |
peter |
68 |
|
4290 |
03 Feb 23 |
peter |
69 |
const std::map<std::string, std::string>& |
4290 |
03 Feb 23 |
peter |
70 |
BamHeader::group(strMap2& map, const std::string& type, |
4290 |
03 Feb 23 |
peter |
71 |
const std::string& id) const |
4290 |
03 Feb 23 |
peter |
72 |
{ |
4290 |
03 Feb 23 |
peter |
73 |
update_group(map, type); |
4290 |
03 Feb 23 |
peter |
74 |
strMap2::const_iterator line_table = map.find(id); |
4290 |
03 Feb 23 |
peter |
75 |
if (line_table == map.end()) { |
4290 |
03 Feb 23 |
peter |
76 |
std::string msg = "@" + type + ": unknown ID: '" + id + "'"; |
4290 |
03 Feb 23 |
peter |
77 |
throw utility::runtime_error(msg); |
4290 |
03 Feb 23 |
peter |
78 |
} |
4290 |
03 Feb 23 |
peter |
79 |
return line_table->second; |
4290 |
03 Feb 23 |
peter |
80 |
} |
4290 |
03 Feb 23 |
peter |
81 |
|
4290 |
03 Feb 23 |
peter |
82 |
|
4290 |
03 Feb 23 |
peter |
83 |
BamHeader::read_group_iterator |
4290 |
03 Feb 23 |
peter |
84 |
BamHeader::group_begin(strMap2& group, const std::string& type) const |
4290 |
03 Feb 23 |
peter |
85 |
{ |
4290 |
03 Feb 23 |
peter |
86 |
update_group(group, type); |
4290 |
03 Feb 23 |
peter |
87 |
BamHeader::strMap2::const_iterator it(group.begin()); |
4290 |
03 Feb 23 |
peter |
88 |
return utility::pair_first_iterator(it); |
4290 |
03 Feb 23 |
peter |
89 |
} |
4290 |
03 Feb 23 |
peter |
90 |
|
4290 |
03 Feb 23 |
peter |
91 |
|
4290 |
03 Feb 23 |
peter |
92 |
BamHeader::read_group_iterator |
4290 |
03 Feb 23 |
peter |
93 |
BamHeader::group_end(strMap2& group, const std::string& type) const |
4290 |
03 Feb 23 |
peter |
94 |
{ |
4290 |
03 Feb 23 |
peter |
95 |
update_group(group, type); |
4290 |
03 Feb 23 |
peter |
96 |
BamHeader::strMap2::const_iterator it(group.end()); |
4290 |
03 Feb 23 |
peter |
97 |
return utility::pair_first_iterator(it); |
4290 |
03 Feb 23 |
peter |
98 |
} |
4290 |
03 Feb 23 |
peter |
99 |
|
4290 |
03 Feb 23 |
peter |
100 |
|
3410 |
21 Apr 15 |
peter |
101 |
const std::string& BamHeader::group(strMap2& table,const std::string& type, |
3410 |
21 Apr 15 |
peter |
102 |
const std::string& id, |
3410 |
21 Apr 15 |
peter |
103 |
const std::string& key) const |
3410 |
21 Apr 15 |
peter |
104 |
{ |
4290 |
03 Feb 23 |
peter |
105 |
const std::map<std::string, std::string>& m = group(table, type, id); |
4290 |
03 Feb 23 |
peter |
106 |
strMap::const_iterator it = m.find(key); |
4290 |
03 Feb 23 |
peter |
107 |
if (it == m.end()) { |
3477 |
09 Mar 16 |
peter |
108 |
std::string msg = "@" + type + ": unknown KEY: '" + key + "'"; |
3477 |
09 Mar 16 |
peter |
109 |
throw utility::runtime_error(msg); |
3477 |
09 Mar 16 |
peter |
110 |
} |
3477 |
09 Mar 16 |
peter |
111 |
return it->second; |
3477 |
09 Mar 16 |
peter |
112 |
} |
3477 |
09 Mar 16 |
peter |
113 |
|
3477 |
09 Mar 16 |
peter |
114 |
|
3477 |
09 Mar 16 |
peter |
115 |
void BamHeader::update_group(strMap2& table, const std::string& type) const |
3477 |
09 Mar 16 |
peter |
116 |
{ |
3410 |
21 Apr 15 |
peter |
117 |
assert(type.size()==2); |
3410 |
21 Apr 15 |
peter |
118 |
if (table.empty()) { // parse header |
3410 |
21 Apr 15 |
peter |
119 |
std::istringstream ss(text()); |
3410 |
21 Apr 15 |
peter |
120 |
std::string line; |
3410 |
21 Apr 15 |
peter |
121 |
while (getline(ss, line)) { |
3410 |
21 Apr 15 |
peter |
122 |
if (line.substr(1,2)!=type) |
3410 |
21 Apr 15 |
peter |
123 |
continue; |
3410 |
21 Apr 15 |
peter |
// find ID value |
3410 |
21 Apr 15 |
peter |
125 |
size_t pos = line.find("\tID:", 3); |
3410 |
21 Apr 15 |
peter |
126 |
size_t end = line.find('\t', pos+4); |
3410 |
21 Apr 15 |
peter |
127 |
std::string id_val = line.substr(pos+4, end-(pos+4)); |
3410 |
21 Apr 15 |
peter |
128 |
std::vector<std::string> vec; |
3410 |
21 Apr 15 |
peter |
129 |
utility::split(vec, line, '\t'); |
3410 |
21 Apr 15 |
peter |
130 |
strMap& m = table[id_val]; |
3410 |
21 Apr 15 |
peter |
131 |
for (size_t i=1; i<vec.size(); ++i) { |
3410 |
21 Apr 15 |
peter |
132 |
m[vec[i].substr(0,2)] = vec[i].substr(3); |
3410 |
21 Apr 15 |
peter |
133 |
} |
3410 |
21 Apr 15 |
peter |
134 |
} |
3410 |
21 Apr 15 |
peter |
135 |
} |
3410 |
21 Apr 15 |
peter |
136 |
} |
3410 |
21 Apr 15 |
peter |
137 |
|
3410 |
21 Apr 15 |
peter |
138 |
|
3358 |
23 Nov 14 |
peter |
139 |
void BamHeader::parse_region(const std::string& reg, int& id, int& begin, |
2999 |
14 Mar 13 |
peter |
140 |
int& end) const |
2999 |
14 Mar 13 |
peter |
141 |
{ |
2999 |
14 Mar 13 |
peter |
142 |
assert(header_); |
3358 |
23 Nov 14 |
peter |
143 |
const char* b = reg.c_str(); |
3358 |
23 Nov 14 |
peter |
144 |
const char* e = hts_parse_reg(b, &begin, &end); |
3358 |
23 Nov 14 |
peter |
// If begin > end suggests something is wrong and that is also how |
3358 |
23 Nov 14 |
peter |
// bam_parse_region (below in samtools impl) used to detect error |
3358 |
23 Nov 14 |
peter |
// and return non-zero. |
3358 |
23 Nov 14 |
peter |
148 |
if (begin<=end) { |
3358 |
23 Nov 14 |
peter |
149 |
std::string chr = reg.substr(0, e-b); |
3358 |
23 Nov 14 |
peter |
150 |
try { |
3358 |
23 Nov 14 |
peter |
151 |
id = tid(chr); |
3358 |
23 Nov 14 |
peter |
152 |
return; |
3358 |
23 Nov 14 |
peter |
153 |
} |
3358 |
23 Nov 14 |
peter |
154 |
catch (utility::runtime_error& e) { |
3358 |
23 Nov 14 |
peter |
155 |
; // throw below instead |
3358 |
23 Nov 14 |
peter |
156 |
} |
3358 |
23 Nov 14 |
peter |
157 |
} |
2999 |
14 Mar 13 |
peter |
158 |
std::ostringstream ss; |
2999 |
14 Mar 13 |
peter |
159 |
ss << "invalid region: '" << reg << "'"; |
2999 |
14 Mar 13 |
peter |
160 |
throw utility::runtime_error(ss.str()); |
2999 |
14 Mar 13 |
peter |
161 |
} |
2999 |
14 Mar 13 |
peter |
162 |
|
2999 |
14 Mar 13 |
peter |
163 |
|
3410 |
21 Apr 15 |
peter |
164 |
const std::string& BamHeader::program_group(const std::string& id, |
3410 |
21 Apr 15 |
peter |
165 |
const std::string& key) const |
3410 |
21 Apr 15 |
peter |
166 |
{ |
3410 |
21 Apr 15 |
peter |
167 |
return group(program_group_, "PG", id, key); |
3410 |
21 Apr 15 |
peter |
168 |
} |
3410 |
21 Apr 15 |
peter |
169 |
|
3410 |
21 Apr 15 |
peter |
170 |
|
4290 |
03 Feb 23 |
peter |
171 |
const std::map<std::string, std::string>& |
4290 |
03 Feb 23 |
peter |
172 |
BamHeader::program_group(const std::string& id) const |
4290 |
03 Feb 23 |
peter |
173 |
{ |
4290 |
03 Feb 23 |
peter |
174 |
return group(program_group_, "PG", id); |
4290 |
03 Feb 23 |
peter |
175 |
} |
4290 |
03 Feb 23 |
peter |
176 |
|
4290 |
03 Feb 23 |
peter |
177 |
|
4290 |
03 Feb 23 |
peter |
178 |
BamHeader::program_group_iterator BamHeader::program_group_begin(void) const |
4290 |
03 Feb 23 |
peter |
179 |
{ |
4290 |
03 Feb 23 |
peter |
180 |
return group_begin(program_group_, "PG"); |
4290 |
03 Feb 23 |
peter |
181 |
} |
4290 |
03 Feb 23 |
peter |
182 |
|
4290 |
03 Feb 23 |
peter |
183 |
|
4290 |
03 Feb 23 |
peter |
184 |
BamHeader::program_group_iterator BamHeader::program_group_end(void) const |
4290 |
03 Feb 23 |
peter |
185 |
{ |
4290 |
03 Feb 23 |
peter |
186 |
return group_end(program_group_, "PG"); |
4290 |
03 Feb 23 |
peter |
187 |
} |
4290 |
03 Feb 23 |
peter |
188 |
|
4290 |
03 Feb 23 |
peter |
189 |
|
3410 |
21 Apr 15 |
peter |
190 |
const std::string& BamHeader::read_group(const std::string& id, |
3410 |
21 Apr 15 |
peter |
191 |
const std::string& key) const |
3410 |
21 Apr 15 |
peter |
192 |
{ |
3410 |
21 Apr 15 |
peter |
193 |
return group(read_group_, "RG", id, key); |
3410 |
21 Apr 15 |
peter |
194 |
} |
3410 |
21 Apr 15 |
peter |
195 |
|
3410 |
21 Apr 15 |
peter |
196 |
|
3477 |
09 Mar 16 |
peter |
197 |
const std::map<std::string, std::string>& |
3477 |
09 Mar 16 |
peter |
198 |
BamHeader::read_group(const std::string& id) const |
3477 |
09 Mar 16 |
peter |
199 |
{ |
4290 |
03 Feb 23 |
peter |
200 |
return group(read_group_, "RG", id); |
3477 |
09 Mar 16 |
peter |
201 |
} |
3477 |
09 Mar 16 |
peter |
202 |
|
3477 |
09 Mar 16 |
peter |
203 |
|
3477 |
09 Mar 16 |
peter |
204 |
BamHeader::read_group_iterator BamHeader::read_group_begin(void) const |
3477 |
09 Mar 16 |
peter |
205 |
{ |
4290 |
03 Feb 23 |
peter |
206 |
return group_begin(read_group_, "RG"); |
3477 |
09 Mar 16 |
peter |
207 |
} |
3477 |
09 Mar 16 |
peter |
208 |
|
3477 |
09 Mar 16 |
peter |
209 |
|
3477 |
09 Mar 16 |
peter |
210 |
BamHeader::read_group_iterator BamHeader::read_group_end(void) const |
3477 |
09 Mar 16 |
peter |
211 |
{ |
4290 |
03 Feb 23 |
peter |
212 |
return group_end(read_group_, "RG"); |
3477 |
09 Mar 16 |
peter |
213 |
} |
3477 |
09 Mar 16 |
peter |
214 |
|
3477 |
09 Mar 16 |
peter |
215 |
|
3408 |
16 Apr 15 |
peter |
216 |
void BamHeader::swap(BamHeader& other) |
3408 |
16 Apr 15 |
peter |
217 |
{ |
3408 |
16 Apr 15 |
peter |
218 |
std::swap(header_, other.header_); |
3410 |
21 Apr 15 |
peter |
219 |
std::swap(read_group_, other.read_group_); |
3410 |
21 Apr 15 |
peter |
220 |
std::swap(program_group_, other.program_group_); |
3408 |
16 Apr 15 |
peter |
221 |
} |
3408 |
16 Apr 15 |
peter |
222 |
|
3408 |
16 Apr 15 |
peter |
223 |
|
2960 |
17 Jan 13 |
peter |
224 |
uint32_t BamHeader::target_length(size_t tid) const |
2960 |
17 Jan 13 |
peter |
225 |
{ |
2960 |
17 Jan 13 |
peter |
226 |
assert(tid < static_cast<size_t>(n_targets())); |
2960 |
17 Jan 13 |
peter |
227 |
return header_->target_len[tid]; |
2960 |
17 Jan 13 |
peter |
228 |
} |
2960 |
17 Jan 13 |
peter |
229 |
|
2960 |
17 Jan 13 |
peter |
230 |
|
2883 |
03 Dec 12 |
peter |
231 |
const char* BamHeader::target_name(size_t tid) const |
2883 |
03 Dec 12 |
peter |
232 |
{ |
2883 |
03 Dec 12 |
peter |
233 |
assert(tid < static_cast<size_t>(n_targets())); |
2883 |
03 Dec 12 |
peter |
234 |
return header_->target_name[tid]; |
2883 |
03 Dec 12 |
peter |
235 |
} |
2883 |
03 Dec 12 |
peter |
236 |
|
2883 |
03 Dec 12 |
peter |
237 |
|
3408 |
16 Apr 15 |
peter |
238 |
std::string BamHeader::text(void) const |
3408 |
16 Apr 15 |
peter |
239 |
{ |
3408 |
16 Apr 15 |
peter |
240 |
assert(header_); |
3408 |
16 Apr 15 |
peter |
241 |
return std::string(header_->text, header_->l_text); |
3408 |
16 Apr 15 |
peter |
242 |
} |
3408 |
16 Apr 15 |
peter |
243 |
|
3409 |
17 Apr 15 |
peter |
244 |
|
3408 |
16 Apr 15 |
peter |
245 |
void BamHeader::text(const std::string& txt) |
3408 |
16 Apr 15 |
peter |
246 |
{ |
3573 |
12 Jan 17 |
peter |
247 |
BamHeader tmp; |
3573 |
12 Jan 17 |
peter |
248 |
tmp.header_ = sam_hdr_parse(txt.size(), txt.c_str()); |
3573 |
12 Jan 17 |
peter |
249 |
|
3573 |
12 Jan 17 |
peter |
// throw if failed |
3573 |
12 Jan 17 |
peter |
251 |
if (!tmp.header_) { |
3573 |
12 Jan 17 |
peter |
252 |
std::ostringstream msg; |
3573 |
12 Jan 17 |
peter |
253 |
msg << "BamHeader::text: " << txt; |
3573 |
12 Jan 17 |
peter |
254 |
throw utility::runtime_error(msg.str()); |
3573 |
12 Jan 17 |
peter |
255 |
} |
3573 |
12 Jan 17 |
peter |
256 |
tmp.header_->l_text = txt.size(); |
3573 |
12 Jan 17 |
peter |
257 |
tmp.header_->text = (char*)realloc(tmp.header_->text, txt.size()+1); |
3573 |
12 Jan 17 |
peter |
258 |
if (!tmp.header_->text) { |
3573 |
12 Jan 17 |
peter |
259 |
std::ostringstream msg; |
3573 |
12 Jan 17 |
peter |
260 |
msg << "BamHeader::text(1): allocation failed\n" << txt; |
3573 |
12 Jan 17 |
peter |
261 |
throw utility::runtime_error(msg.str()); |
3573 |
12 Jan 17 |
peter |
262 |
} |
3573 |
12 Jan 17 |
peter |
// copy to temporary |
3573 |
12 Jan 17 |
peter |
264 |
memcpy(tmp.header_->text, txt.c_str(), txt.size()+1); |
3573 |
12 Jan 17 |
peter |
265 |
|
3573 |
12 Jan 17 |
peter |
// everything worked; swap data so this get the new stuff and |
3573 |
12 Jan 17 |
peter |
// destructor of tmp takes care of the old stuff. |
3573 |
12 Jan 17 |
peter |
268 |
swap(tmp); |
3408 |
16 Apr 15 |
peter |
269 |
} |
3408 |
16 Apr 15 |
peter |
270 |
|
3408 |
16 Apr 15 |
peter |
271 |
|
2999 |
14 Mar 13 |
peter |
272 |
int32_t BamHeader::tid(const std::string& name) const |
2999 |
14 Mar 13 |
peter |
273 |
{ |
3358 |
23 Nov 14 |
peter |
274 |
int res = bam_name2id(header_, name.c_str()); |
3358 |
23 Nov 14 |
peter |
275 |
if (res==-1) { |
3358 |
23 Nov 14 |
peter |
276 |
std::string msg("invalid segment name:"); |
3358 |
23 Nov 14 |
peter |
277 |
msg += name; |
3358 |
23 Nov 14 |
peter |
278 |
throw utility::runtime_error(msg); |
3358 |
23 Nov 14 |
peter |
279 |
} |
3358 |
23 Nov 14 |
peter |
280 |
return res; |
2999 |
14 Mar 13 |
peter |
281 |
} |
2999 |
14 Mar 13 |
peter |
282 |
|
2999 |
14 Mar 13 |
peter |
283 |
|
2883 |
03 Dec 12 |
peter |
284 |
int32_t BamHeader::n_targets(void) const |
2883 |
03 Dec 12 |
peter |
285 |
{ |
2883 |
03 Dec 12 |
peter |
286 |
assert(header_); |
2883 |
03 Dec 12 |
peter |
287 |
return header_->n_targets; |
2883 |
03 Dec 12 |
peter |
288 |
} |
2883 |
03 Dec 12 |
peter |
289 |
|
3408 |
16 Apr 15 |
peter |
290 |
|
3408 |
16 Apr 15 |
peter |
291 |
void swap(BamHeader& lhs, BamHeader& rhs) |
3408 |
16 Apr 15 |
peter |
292 |
{ |
3408 |
16 Apr 15 |
peter |
293 |
lhs.swap(rhs); |
3408 |
16 Apr 15 |
peter |
294 |
} |
3408 |
16 Apr 15 |
peter |
295 |
|
3408 |
16 Apr 15 |
peter |
296 |
|
3408 |
16 Apr 15 |
peter |
297 |
BamHeader& BamHeader::operator=(const BamHeader& rhs) |
3408 |
16 Apr 15 |
peter |
298 |
{ |
3408 |
16 Apr 15 |
peter |
299 |
BamHeader tmp(rhs); |
3408 |
16 Apr 15 |
peter |
300 |
swap(tmp); |
3408 |
16 Apr 15 |
peter |
301 |
return *this; |
3408 |
16 Apr 15 |
peter |
302 |
} |
3408 |
16 Apr 15 |
peter |
303 |
|
3600 |
22 Jan 17 |
peter |
304 |
|
3600 |
22 Jan 17 |
peter |
305 |
BamHeader& BamHeader::operator=(BamHeader&& rhs) |
3600 |
22 Jan 17 |
peter |
306 |
{ |
3600 |
22 Jan 17 |
peter |
307 |
swap(rhs); |
3600 |
22 Jan 17 |
peter |
308 |
return *this; |
3600 |
22 Jan 17 |
peter |
309 |
} |
3600 |
22 Jan 17 |
peter |
310 |
|
2883 |
03 Dec 12 |
peter |
311 |
}}} |