1 // ==========================================================================
2 //                 SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2018, Knut Reinert, FU Berlin
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 //       notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above copyright
13 //       notice, this list of conditions and the following disclaimer in the
14 //       documentation and/or other materials provided with the distribution.
15 //     * Neither the name of Knut Reinert or the FU Berlin nor the names of
16 //       its contributors may be used to endorse or promote products derived
17 //       from this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30 //
31 // ==========================================================================
32 // Author: David Weese <david.weese@fu-berlin.de>
33 // ==========================================================================
34 // Packed pair specialization.
35 // ==========================================================================
36 
37 #ifndef SEQAN_INCLUDE_SEQAN_BASIC_PAIR_PACKED_H_
38 #define SEQAN_INCLUDE_SEQAN_BASIC_PAIR_PACKED_H_
39 
40 namespace seqan {
41 
42 // ============================================================================
43 // Forwards
44 // ============================================================================
45 
46 // ============================================================================
47 // Tags, Classes, Enums
48 // ============================================================================
49 
50 // ----------------------------------------------------------------------------
51 // Specialization Packed Pair
52 // ----------------------------------------------------------------------------
53 
54 /*!
55  * @class PackedPair
56  * @extends Pair
57  * @headerfile <seqan/basic.h>
58  * @brief Stores two arbitrary objects. Saves memory by disabling memory alignment.
59  *
60  * @signature template <typename T1, typename T2>
61  *            class Pair<T1, T2, Pack>;
62  *
63  * @tparam T1 The type of the first object.
64  * @tparam T2 The type of the second object.
65  *
66  * Useful for external storage.
67  *
68  * Memory access could be slower.  Direct access to members by pointers is not allowed on all platforms.
69  *
70  * Functions <tt>value()</tt> is not implemented yet since there it would require using a proxy.  Use
71  * <tt>getValue()</tt>, <tt>assignValue()</tt>, <tt>moveValue()</tt>, <tt>setValue()</tt> instead.
72  */
73 
74 #pragma pack(push,1)
75 template <typename T1, typename T2>
76 struct Pair<T1, T2, Pack>
77 {
78     // ------------------------------------------------------------------------
79     // Members
80     // ------------------------------------------------------------------------
81     T1 i1{};
82     T2 i2{};
83 
84     // ------------------------------------------------------------------------
85     // Constructors
86     // ------------------------------------------------------------------------
87 
88     // Pair() = default; does not work on gcc4.9, it issues warnings if T1/T2
89     // have no proper default constructor. >=gcc5.0 reports no warnings.
90     // Caused by yara_indexer build, demo_tutorial_indices_base and
91     // demo_tutorial_index_iterators_index_bidirectional_search.
92 #if defined(COMPILER_GCC) && (__GNUC__ <= 4)
93     Pair() : i1(T1()), i2(T2()) {};
94 #else
95     Pair() = default;
96 #endif
97 
98     // NOTE(marehr) intel compiler bug in 17.x and 18.x: defaulted copy-constructor
99     // in classes with `#pragma pack(push, 1)` seg-faults. This leads to a
100     // seg-fault in yara-mapper (app test case yara).
101 #if defined(COMPILER_LINTEL) || defined(COMPILER_WINTEL)
102     Pair(Pair const & p) : i1(p.i1), i2(p.i2) {};
103 #else
104     Pair(Pair const &) = default;
105 #endif
106     Pair(Pair &&) = default;
107     ~Pair() = default;
108     Pair & operator=(Pair const &) = default;
109     Pair & operator=(Pair &&) = default;
110 
111     Pair(T1 const & _i1, T2 const & _i2) : i1(_i1), i2(_i2) {}
112 
113     template <typename T1_, typename T2_, typename TSpec__>
114     // TODO(holtgrew): explicit?
115     Pair(Pair<T1_, T2_, TSpec__> const &_p) :
116         i1(getValueI1(_p)), i2(getValueI2(_p))
117     {}
118 };
119 #pragma pack(pop)
120 
121 // ============================================================================
122 // Metafunctions
123 // ============================================================================
124 
125 template <typename T1, typename T2>
126 struct MakePacked< Pair<T1, T2> >
127 {
128     typedef Pair<T1, T2, Pack> Type;
129 };
130 
131 // ============================================================================
132 // Functions
133 // ============================================================================
134 
135 // ----------------------------------------------------------------------------
136 // Function set().
137 // ----------------------------------------------------------------------------
138 
139 // References to members to packed structs do not work.  Always copy.
140 
141 template <typename T1, typename T2>
142 inline void
143 set(Pair<T1, T2, Pack> & p1, Pair<T1, T2, Pack> & p2)
144 {
145     p1 = p2;
146 }
147 
148 // ----------------------------------------------------------------------------
149 // Function move().
150 // ----------------------------------------------------------------------------
151 
152 // References to members to packed structs do not work.  Always copy.
153 
154 template <typename T1, typename T2>
155 inline void
156 move(Pair<T1, T2, Pack> & p1, Pair<T1, T2, Pack> & p2)
157 {
158     p1 = p2;
159 }
160 
161 // -----------------------------------------------------------------------
162 // Function setValueIX()
163 // -----------------------------------------------------------------------
164 
165 // References to members to packed structs do not work.  Always copy.
166 
167 template <typename T1, typename T2, typename T>
168 inline void setValueI1(Pair<T1, T2, Pack> & pair, T const & _i)
169 {
170     pair.i1 = _i;
171 }
172 
173 template <typename T1, typename T2, typename T>
174 inline void setValueI2(Pair<T1, T2, Pack> & pair, T const & _i)
175 {
176     pair.i2 = _i;
177 }
178 
179 // -----------------------------------------------------------------------
180 // Function moveValueIX()
181 // -----------------------------------------------------------------------
182 
183 // References to members to packed structs do not work.  Always copy.
184 
185 template <typename T1, typename T2, typename T>
186 inline void moveValueI1(Pair<T1, T2, Pack> & pair, T & _i)
187 {
188     pair.i1 = _i;
189 }
190 
191 template <typename T1, typename T2, typename T>
192 inline void moveValueI2(Pair<T1, T2, Pack> & pair, T & _i)
193 {
194     pair.i2 = _i;
195 }
196 
197 }  // namespace seqan
198 
199 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_BASIC_PAIR_PACKED_H_
200