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