10 #include "boost/assert.hpp" 11 #include "boost/foreach.hpp" 12 #include "boost/functional/hash_fwd.hpp" 13 #include "boost/unordered_set.hpp" 17 namespace vdj_pipe{
namespace detail{
28 class Hash_id : std::unary_function<id_type, std::size_t> {
30 explicit Hash_id(self_type
const& v) : m_(v) {}
32 std::size_t operator()(
const id_type
id)
const {
33 using boost::hash_value;
34 return hash_value(m_[
id]);
37 std::size_t operator()(obj_type
const& obj)
const {
38 using boost::hash_value;
39 return hash_value(obj);
46 class Equal_id :
public std::binary_function<id_type, id_type, bool>{
48 explicit Equal_id(self_type
const& m) : m_(m) {}
50 bool operator()(id_type id1, id_type id2)
const{
51 return m_[id1] == m_[id2];
54 template<
class ObjCompat>
55 bool operator()(id_type id1, ObjCompat
const& obj)
const{
56 return m_[id1] == obj;
59 template<
class ObjCompat>
60 bool operator()(ObjCompat
const& obj, id_type id2)
const{
61 return obj == m_[id2];
68 template<
class ObjCompat>
class Equal_obj {
70 explicit Equal_obj(self_type
const& m) : m_(m) {}
72 bool operator()(id_type id1, ObjCompat
const& obj)
const{
73 return m_[id1] == obj;
76 bool operator()(ObjCompat
const& obj, id_type id2)
const{
77 return obj == m_[id2];
84 typedef boost::unordered_set<id_type, Hash_id, Equal_id> map_t;
85 typedef std::vector<obj_type> vector_t;
88 typedef typename map_t::value_type value_type;
89 typedef typename map_t::iterator iterator;
90 typedef typename map_t::const_iterator const_iterator;
95 map_(boost::unordered::detail::default_bucket_count, Hash_id(*
this), Equal_id(*
this)),
100 explicit Id_bimap(self_type
const& bm)
101 : vid_(bm.vid_.size()),
102 map_(boost::unordered::detail::default_bucket_count, Hash_id(*
this), Equal_id(*
this)),
103 erased_(bm.erased_.size()),
109 self_type& operator=(self_type
const& bm) {
115 std::size_t size()
const {
return map_.size(); }
116 const_iterator begin()
const {
return map_.begin();}
117 const_iterator end()
const {
return map_.end();}
118 bool empty()
const {
return map_.empty();}
119 id_type min_id()
const {
return id0_;}
120 id_type max_id()
const {
return pos2id(vid_.size()-1);}
122 obj_type
const& operator[](
const id_type
id)
const {
123 BOOST_ASSERT( vpos(
id) < vid_.size() );
124 return vid_[vpos(
id)];
127 obj_type& operator[](
const id_type
id) {
128 BOOST_ASSERT( vpos(
id) < vid_.size() );
129 return vid_[vpos(
id)];
132 obj_type
const& at(
const id_type
id)
const {
133 if(
id < id0_ || vpos(
id) >= vid_.size() ) BOOST_THROW_EXCEPTION(
135 << Err::msg_t(
"invalid ID")
138 return vid_[vpos(
id)];
141 obj_type& at(
const id_type
id) {
142 if(
id < id0_ || vpos(
id) >= vid_.size() ) BOOST_THROW_EXCEPTION(
144 << Err::msg_t(
"invalid ID")
147 return vid_[vpos(
id)];
150 template<
class ObjCompat>
151 id_type
const* find(ObjCompat
const& obj)
const {
152 const const_iterator i = map_.find(
154 boost::hash<ObjCompat>(),
155 Equal_obj<ObjCompat>(*
this)
157 return i == map_.end() ? 0 : &(*i);
160 std::pair<id_type, bool> insert(obj_type
const& obj) {
161 if( id_type
const* idp = find(obj) )
return std::make_pair(*idp,
false);
162 if( erased_.empty() ) {
163 const id_type
id = pos2id(vid_.size());
166 return std::make_pair(
id,
true);
169 const id_type
id = erased_.back();
171 const std::size_t n = vpos(
id);
172 BOOST_ASSERT(vid_.size() > n);
175 return std::make_pair(
id,
true);
178 void erase(
const id_type
id) {
179 BOOST_ASSERT( vpos(
id) < vid_.size() );
180 const std::size_t pos = vpos(
id);
182 erased_.push_back(
id);
183 vid_[pos] = obj_type();
195 std::vector<id_type> erased_;
198 std::size_t vpos(
const id_type
id)
const {
199 BOOST_ASSERT(
id >= id0_ &&
"invalid ID");
200 return id() - id0_();
203 id_type pos2id(
const std::size_t n)
const {
return id_type(n + id0_());}
205 void copy(self_type
const& bm) {
206 vid_.resize(bm.vid_.size());
208 erased_ = bm.erased_;
209 BOOST_FOREACH(
const id_type
id, bm) {
210 (*this)[id] = bm[id];
Definition: id_bimap.hpp:21
Main namespace of vdj_pipe library.
Definition: sequence_file.hpp:14
Definition: exception.hpp:23