3030
3131namespace geode
3232{
33- template < typename T1, typename T2 = T1 >
34- class BijectiveMapping
33+ template < typename T1,
34+ typename T2,
35+ template < typename >
36+ class StorageType >
37+ class MappingBase
3538 {
3639 public:
37- void map ( const T1& in, const T2& out )
38- {
39- in2out_.emplace ( in, out );
40- out2in_.emplace ( out, in );
41- }
40+ template < typename T >
41+ using Storage = typename StorageType< T >::Type;
4242
4343 void reserve ( index_t capacity )
4444 {
@@ -56,65 +56,90 @@ namespace geode
5656 return out2in_.contains ( value );
5757 }
5858
59- size_t size ( ) const
59+ const Storage< T2 >& in2out ( const T1& in ) const
6060 {
61- return in2out_.size ( );
61+ return in2out_.at ( in );
6262 }
6363
64- const T2& in2out ( const T1& in ) const
64+ const Storage< T1 >& out2in ( const T2& out ) const
6565 {
66- return in2out_ .at ( in );
66+ return out2in_ .at ( out );
6767 }
68- const T1& out2in ( const T2& out ) const
68+
69+ protected:
70+ MappingBase () = default ;
71+
72+ index_t size_input () const
6973 {
70- return out2in_.at ( out );
74+ return static_cast < index_t >( in2out_.size () );
75+ }
76+
77+ index_t size_output () const
78+ {
79+ return static_cast < index_t >( out2in_.size () );
80+ }
81+
82+ absl::flat_hash_map< T1, Storage< T2 > >& in2out_map ()
83+ {
84+ return in2out_;
85+ }
86+
87+ absl::flat_hash_map< T2, Storage< T1 > >& out2in_map ()
88+ {
89+ return out2in_;
7190 }
7291
7392 private:
74- absl::flat_hash_map< T1, T2 > in2out_;
75- absl::flat_hash_map< T2, T1 > out2in_;
93+ absl::flat_hash_map< T1, Storage< T2 > > in2out_;
94+ absl::flat_hash_map< T2, Storage< T1 > > out2in_;
95+ };
96+
97+ template < typename T >
98+ struct OneValueStorage
99+ {
100+ using Type = T;
76101 };
77102
78103 template < typename T1, typename T2 = T1 >
79- class GenericMapping
104+ class BijectiveMapping : public MappingBase < T1, T2, OneValueStorage >
80105 {
81106 public:
82- template < typename T >
83- using Storage = absl::InlinedVector< T, 1 >;
84-
85107 void map ( const T1& in, const T2& out )
86108 {
87- in2out_[in]. push_back ( out );
88- out2in_[out]. push_back ( in );
109+ this -> in2out_map (). emplace ( in, out );
110+ this -> out2in_map (). emplace ( out, in );
89111 }
90112
91- void reserve ( index_t capacity )
113+ index_t size () const
92114 {
93- in2out_.reserve ( capacity );
94- out2in_.reserve ( capacity );
115+ return this ->size_input ();
95116 }
117+ };
96118
97- index_t size_in () const
98- {
99- return static_cast < index_t >( in2out_.size () );
100- }
119+ template < typename T >
120+ struct MultipleValueStorage
121+ {
122+ using Type = absl::InlinedVector< T, 1 >;
123+ };
101124
102- index_t size_out () const
125+ template < typename T1, typename T2 = T1 >
126+ class GenericMapping : public MappingBase < T1, T2, MultipleValueStorage >
127+ {
128+ public:
129+ void map ( const T1& in, const T2& out )
103130 {
104- return static_cast < index_t >( out2in_.size () );
131+ this ->in2out_map ()[in].push_back ( out );
132+ this ->out2in_map ()[out].push_back ( in );
105133 }
106134
107- const Storage< T2 >& in2out ( const T1& in ) const
135+ index_t size_in ( ) const
108136 {
109- return in2out_. at ( in );
137+ return this -> size_input ( );
110138 }
111- const Storage< T1 >& out2in ( const T2& out ) const
139+
140+ index_t size_out () const
112141 {
113- return out2in_. at ( out );
142+ return this -> size_output ( );
114143 }
115-
116- private:
117- absl::flat_hash_map< T1, Storage< T2 > > in2out_;
118- absl::flat_hash_map< T2, Storage< T1 > > out2in_;
119144 };
120145} // namespace geode
0 commit comments