// variant.h - v1.6 /* * Copyright (c) 2010 Leigh Johnston. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Leigh Johnston nor the names of any * other contributors to this software may be used to endorse or * promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LIB_VARIANT #define LIB_VARIANT #include #include namespace lib { struct bad_variant_cast : public std::exception {}; struct bad_variant_argument : public std::exception {}; namespace variant_detail { class alignment_dummy; typedef void (*function_ptr)(); typedef int (alignment_dummy::*member_ptr); typedef int (alignment_dummy::*member_function_ptr)(); union max_align { char dummy0; short dummy1; int dummy2; long dummy3; long long dummy4; float dummy5; double dummy6; long double dummy7; void* dummy8; function_ptr dummy9; member_ptr dummy10; member_function_ptr dummy11; }; } template struct unused_variant { bool operator==(const unused_variant&) const { return true; } bool operator!=(const unused_variant&) const { return false; } bool operator<(const unused_variant& rhs) const { return false; } }; template, typename T3 = unused_variant<3>, typename T4 = unused_variant<4>, typename T5 = unused_variant<5>, typename T6 = unused_variant<6>, typename T7 = unused_variant<7>, typename T8 = unused_variant<8>, typename T9 = unused_variant<9>, typename T10 = unused_variant<10>, typename T11 = unused_variant<11>, typename T12 = unused_variant<12>, typename T13 = unused_variant<13>, typename T14 = unused_variant<14>, typename T15 = unused_variant<15>, typename T16 = unused_variant<16>, typename T17 = unused_variant<17>, typename T18 = unused_variant<18>, typename T19 = unused_variant<19>, typename T20 = unused_variant<20>, typename T21 = unused_variant<21>, typename T22 = unused_variant<22>, typename T23 = unused_variant<23>, typename T24 = unused_variant<24>, typename T25 = unused_variant<25>, typename T26 = unused_variant<26>, typename T27 = unused_variant<27>, typename T28 = unused_variant<28>, typename T29 = unused_variant<29>, typename T30 = unused_variant<30> > class variant { public: typedef size_t variant_type; public: // construction variant() : iVariantType(0) {} variant(const variant& rhs) : iVariantType(0) { assign(rhs); } variant(const T1& value) : iVariantType(0) { assign(value); } variant(const T2& value) : iVariantType(0) { assign(value); } variant(const T3& value) : iVariantType(0) { assign(value); } variant(const T4& value) : iVariantType(0) { assign(value); } variant(const T5& value) : iVariantType(0) { assign(value); } variant(const T6& value) : iVariantType(0) { assign(value); } variant(const T7& value) : iVariantType(0) { assign(value); } variant(const T8& value) : iVariantType(0) { assign(value); } variant(const T9& value) : iVariantType(0) { assign(value); } variant(const T10& value) : iVariantType(0) { assign(value); } variant(const T11& value) : iVariantType(0) { assign(value); } variant(const T12& value) : iVariantType(0) { assign(value); } variant(const T13& value) : iVariantType(0) { assign(value); } variant(const T14& value) : iVariantType(0) { assign(value); } variant(const T15& value) : iVariantType(0) { assign(value); } variant(const T16& value) : iVariantType(0) { assign(value); } variant(const T17& value) : iVariantType(0) { assign(value); } variant(const T18& value) : iVariantType(0) { assign(value); } variant(const T19& value) : iVariantType(0) { assign(value); } variant(const T20& value) : iVariantType(0) { assign(value); } variant(const T21& value) : iVariantType(0) { assign(value); } variant(const T22& value) : iVariantType(0) { assign(value); } variant(const T23& value) : iVariantType(0) { assign(value); } variant(const T24& value) : iVariantType(0) { assign(value); } variant(const T25& value) : iVariantType(0) { assign(value); } variant(const T26& value) : iVariantType(0) { assign(value); } variant(const T27& value) : iVariantType(0) { assign(value); } variant(const T28& value) : iVariantType(0) { assign(value); } variant(const T29& value) : iVariantType(0) { assign(value); } variant(const T30& value) : iVariantType(0) { assign(value); } ~variant() { clear(); } // state bool valid() const { return iVariantType != 0; } bool invalid() const { return iVariantType == 0; } variant_type which() const { return iVariantType; } template bool is() const { return is(static_cast(0)); } bool operator==(const variant& rhs) const { if (valid() != rhs.valid()) return false; if (which() != rhs.which()) return false; switch (which()) { case 1: return static_cast(*this) == static_cast(rhs); case 2: return static_cast(*this) == static_cast(rhs); case 3: return static_cast(*this) == static_cast(rhs); case 4: return static_cast(*this) == static_cast(rhs); case 5: return static_cast(*this) == static_cast(rhs); case 6: return static_cast(*this) == static_cast(rhs); case 7: return static_cast(*this) == static_cast(rhs); case 8: return static_cast(*this) == static_cast(rhs); case 9: return static_cast(*this) == static_cast(rhs); case 10: return static_cast(*this) == static_cast(rhs); case 11: return static_cast(*this) == static_cast(rhs); case 12: return static_cast(*this) == static_cast(rhs); case 13: return static_cast(*this) == static_cast(rhs); case 14: return static_cast(*this) == static_cast(rhs); case 15: return static_cast(*this) == static_cast(rhs); case 16: return static_cast(*this) == static_cast(rhs); case 17: return static_cast(*this) == static_cast(rhs); case 18: return static_cast(*this) == static_cast(rhs); case 19: return static_cast(*this) == static_cast(rhs); case 20: return static_cast(*this) == static_cast(rhs); case 21: return static_cast(*this) == static_cast(rhs); case 22: return static_cast(*this) == static_cast(rhs); case 23: return static_cast(*this) == static_cast(rhs); case 24: return static_cast(*this) == static_cast(rhs); case 25: return static_cast(*this) == static_cast(rhs); case 26: return static_cast(*this) == static_cast(rhs); case 27: return static_cast(*this) == static_cast(rhs); case 28: return static_cast(*this) == static_cast(rhs); case 29: return static_cast(*this) == static_cast(rhs); case 30: return static_cast(*this) == static_cast(rhs); default: return true; } } bool operator!=(const variant& rhs) const { return !operator==(rhs); } bool operator<(const variant& rhs) const { if (which() != rhs.which()) return which() < rhs.which(); switch (which()) { case 1: return static_cast(*this) < static_cast(rhs); case 2: return static_cast(*this) < static_cast(rhs); case 3: return static_cast(*this) < static_cast(rhs); case 4: return static_cast(*this) < static_cast(rhs); case 5: return static_cast(*this) < static_cast(rhs); case 6: return static_cast(*this) < static_cast(rhs); case 7: return static_cast(*this) < static_cast(rhs); case 8: return static_cast(*this) < static_cast(rhs); case 9: return static_cast(*this) < static_cast(rhs); case 10: return static_cast(*this) < static_cast(rhs); case 11: return static_cast(*this) < static_cast(rhs); case 12: return static_cast(*this) < static_cast(rhs); case 13: return static_cast(*this) < static_cast(rhs); case 14: return static_cast(*this) < static_cast(rhs); case 15: return static_cast(*this) < static_cast(rhs); case 16: return static_cast(*this) < static_cast(rhs); case 17: return static_cast(*this) < static_cast(rhs); case 18: return static_cast(*this) < static_cast(rhs); case 19: return static_cast(*this) < static_cast(rhs); case 20: return static_cast(*this) < static_cast(rhs); case 21: return static_cast(*this) < static_cast(rhs); case 22: return static_cast(*this) < static_cast(rhs); case 23: return static_cast(*this) < static_cast(rhs); case 24: return static_cast(*this) < static_cast(rhs); case 25: return static_cast(*this) < static_cast(rhs); case 26: return static_cast(*this) < static_cast(rhs); case 27: return static_cast(*this) < static_cast(rhs); case 28: return static_cast(*this) < static_cast(rhs); case 29: return static_cast(*this) < static_cast(rhs); case 30: return static_cast(*this) < static_cast(rhs); default: return false; } } // element access operator T1&() { if (iVariantType != 1) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData1); } operator T2&() { if (iVariantType != 2) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData2); } operator T3&() { if (iVariantType != 3) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData3); } operator T4&() { if (iVariantType != 4) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData4); } operator T5&() { if (iVariantType != 5) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData5); } operator T6&() { if (iVariantType != 6) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData6); } operator T7&() { if (iVariantType != 7) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData7); } operator T8&() { if (iVariantType != 8) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData8); } operator T9&() { if (iVariantType != 9) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData9); } operator T10&() { if (iVariantType != 10) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData10); } operator T11&() { if (iVariantType != 11) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData11); } operator T12&() { if (iVariantType != 12) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData12); } operator T13&() { if (iVariantType != 13) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData13); } operator T14&() { if (iVariantType != 14) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData14); } operator T15&() { if (iVariantType != 15) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData15); } operator T16&() { if (iVariantType != 16) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData16); } operator T17&() { if (iVariantType != 17) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData17); } operator T18&() { if (iVariantType != 18) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData18); } operator T19&() { if (iVariantType != 19) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData19); } operator T20&() { if (iVariantType != 20) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData20); } operator T21&() { if (iVariantType != 21) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData21); } operator T22&() { if (iVariantType != 22) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData22); } operator T23&() { if (iVariantType != 23) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData23); } operator T24&() { if (iVariantType != 24) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData24); } operator T25&() { if (iVariantType != 25) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData25); } operator T26&() { if (iVariantType != 26) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData26); } operator T27&() { if (iVariantType != 27) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData27); } operator T28&() { if (iVariantType != 28) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData28); } operator T29&() { if (iVariantType != 29) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData29); } operator T30&() { if (iVariantType != 30) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData30); } operator const T1&() const { if (iVariantType != 1) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData1); } operator const T2&() const { if (iVariantType != 2) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData2); } operator const T3&() const { if (iVariantType != 3) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData3); } operator const T4&() const { if (iVariantType != 4) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData4); } operator const T5&() const { if (iVariantType != 5) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData5); } operator const T6&() const { if (iVariantType != 6) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData6); } operator const T7&() const { if (iVariantType != 7) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData7); } operator const T8&() const { if (iVariantType != 8) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData8); } operator const T9&() const { if (iVariantType != 9) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData9); } operator const T10&() const { if (iVariantType != 10) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData10); } operator const T11&() const { if (iVariantType != 11) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData11); } operator const T12&() const { if (iVariantType != 12) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData12); } operator const T13&() const { if (iVariantType != 13) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData13); } operator const T14&() const { if (iVariantType != 14) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData14); } operator const T15&() const { if (iVariantType != 15) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData15); } operator const T16&() const { if (iVariantType != 16) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData16); } operator const T17&() const { if (iVariantType != 17) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData17); } operator const T18&() const { if (iVariantType != 18) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData18); } operator const T19&() const { if (iVariantType != 19) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData19); } operator const T20&() const { if (iVariantType != 20) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData20); } operator const T21&() const { if (iVariantType != 21) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData21); } operator const T22&() const { if (iVariantType != 22) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData22); } operator const T23&() const { if (iVariantType != 23) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData23); } operator const T24&() const { if (iVariantType != 24) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData24); } operator const T25&() const { if (iVariantType != 25) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData25); } operator const T26&() const { if (iVariantType != 26) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData26); } operator const T27&() const { if (iVariantType != 27) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData27); } operator const T28&() const { if (iVariantType != 28) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData28); } operator const T29&() const { if (iVariantType != 29) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData29); } operator const T30&() const { if (iVariantType != 30) throw bad_variant_cast(); return *reinterpret_cast(iAlignedBuffer.iData30); } // modifiers variant& operator=(const variant& rhs) { if (&rhs == this) return *this; return assign(rhs); } variant& operator=(const T1& value) { return assign(value); } variant& operator=(const T2& value) { return assign(value); } variant& operator=(const T3& value) { return assign(value); } variant& operator=(const T4& value) { return assign(value); } variant& operator=(const T5& value) { return assign(value); } variant& operator=(const T6& value) { return assign(value); } variant& operator=(const T7& value) { return assign(value); } variant& operator=(const T8& value) { return assign(value); } variant& operator=(const T9& value) { return assign(value); } variant& operator=(const T10& value) { return assign(value); } variant& operator=(const T11& value) { return assign(value); } variant& operator=(const T12& value) { return assign(value); } variant& operator=(const T13& value) { return assign(value); } variant& operator=(const T14& value) { return assign(value); } variant& operator=(const T15& value) { return assign(value); } variant& operator=(const T16& value) { return assign(value); } variant& operator=(const T17& value) { return assign(value); } variant& operator=(const T18& value) { return assign(value); } variant& operator=(const T19& value) { return assign(value); } variant& operator=(const T20& value) { return assign(value); } variant& operator=(const T21& value) { return assign(value); } variant& operator=(const T22& value) { return assign(value); } variant& operator=(const T23& value) { return assign(value); } variant& operator=(const T24& value) { return assign(value); } variant& operator=(const T25& value) { return assign(value); } variant& operator=(const T26& value) { return assign(value); } variant& operator=(const T27& value) { return assign(value); } variant& operator=(const T28& value) { return assign(value); } variant& operator=(const T29& value) { return assign(value); } variant& operator=(const T30& value) { return assign(value); } variant& assign(const T1& value) { clear(); construct(iAlignedBuffer.iData1, value, 1); return *this; } variant& assign(const T2& value) { clear(); construct(iAlignedBuffer.iData2, value, 2); return *this; } variant& assign(const T3& value) { clear(); construct(iAlignedBuffer.iData3, value, 3); return *this; } variant& assign(const T4& value) { clear(); construct(iAlignedBuffer.iData4, value, 4); return *this; } variant& assign(const T5& value) { clear(); construct(iAlignedBuffer.iData5, value, 5); return *this; } variant& assign(const T6& value) { clear(); construct(iAlignedBuffer.iData6, value, 6); return *this; } variant& assign(const T7& value) { clear(); construct(iAlignedBuffer.iData7, value, 7); return *this; } variant& assign(const T8& value) { clear(); construct(iAlignedBuffer.iData8, value, 8); return *this; } variant& assign(const T9& value) { clear(); construct(iAlignedBuffer.iData9, value, 9); return *this; } variant& assign(const T10& value) { clear(); construct(iAlignedBuffer.iData10, value, 10); return *this; } variant& assign(const T11& value) { clear(); construct(iAlignedBuffer.iData11, value, 11); return *this; } variant& assign(const T12& value) { clear(); construct(iAlignedBuffer.iData12, value, 12); return *this; } variant& assign(const T13& value) { clear(); construct(iAlignedBuffer.iData13, value, 13); return *this; } variant& assign(const T14& value) { clear(); construct(iAlignedBuffer.iData14, value, 14); return *this; } variant& assign(const T15& value) { clear(); construct(iAlignedBuffer.iData15, value, 15); return *this; } variant& assign(const T16& value) { clear(); construct(iAlignedBuffer.iData16, value, 16); return *this; } variant& assign(const T17& value) { clear(); construct(iAlignedBuffer.iData17, value, 17); return *this; } variant& assign(const T18& value) { clear(); construct(iAlignedBuffer.iData18, value, 18); return *this; } variant& assign(const T19& value) { clear(); construct(iAlignedBuffer.iData19, value, 19); return *this; } variant& assign(const T20& value) { clear(); construct(iAlignedBuffer.iData20, value, 20); return *this; } variant& assign(const T21& value) { clear(); construct(iAlignedBuffer.iData21, value, 21); return *this; } variant& assign(const T22& value) { clear(); construct(iAlignedBuffer.iData22, value, 22); return *this; } variant& assign(const T23& value) { clear(); construct(iAlignedBuffer.iData23, value, 23); return *this; } variant& assign(const T24& value) { clear(); construct(iAlignedBuffer.iData24, value, 24); return *this; } variant& assign(const T25& value) { clear(); construct(iAlignedBuffer.iData25, value, 25); return *this; } variant& assign(const T26& value) { clear(); construct(iAlignedBuffer.iData26, value, 26); return *this; } variant& assign(const T27& value) { clear(); construct(iAlignedBuffer.iData27, value, 27); return *this; } variant& assign(const T28& value) { clear(); construct(iAlignedBuffer.iData28, value, 28); return *this; } variant& assign(const T29& value) { clear(); construct(iAlignedBuffer.iData29, value, 29); return *this; } variant& assign(const T30& value) { clear(); construct(iAlignedBuffer.iData30, value, 30); return *this; } variant& assign(const variant& rhs) { if (&rhs == this) return *this; if (rhs.valid()) { switch(rhs.which()) { case 1: return assign(static_cast(rhs)); case 2: return assign(static_cast(rhs)); case 3: return assign(static_cast(rhs)); case 4: return assign(static_cast(rhs)); case 5: return assign(static_cast(rhs)); case 6: return assign(static_cast(rhs)); case 7: return assign(static_cast(rhs)); case 8: return assign(static_cast(rhs)); case 9: return assign(static_cast(rhs)); case 10: return assign(static_cast(rhs)); case 11: return assign(static_cast(rhs)); case 12: return assign(static_cast(rhs)); case 13: return assign(static_cast(rhs)); case 14: return assign(static_cast(rhs)); case 15: return assign(static_cast(rhs)); case 16: return assign(static_cast(rhs)); case 17: return assign(static_cast(rhs)); case 18: return assign(static_cast(rhs)); case 19: return assign(static_cast(rhs)); case 20: return assign(static_cast(rhs)); case 21: return assign(static_cast(rhs)); case 22: return assign(static_cast(rhs)); case 23: return assign(static_cast(rhs)); case 24: return assign(static_cast(rhs)); case 25: return assign(static_cast(rhs)); case 26: return assign(static_cast(rhs)); case 27: return assign(static_cast(rhs)); case 28: return assign(static_cast(rhs)); case 29: return assign(static_cast(rhs)); case 30: return assign(static_cast(rhs)); default: throw bad_variant_argument(); } } else clear(); return *this; } void clear() { if (valid()) { switch(which()) { case 1: destruct(&static_cast(*this)); break; case 2: destruct(&static_cast(*this)); break; case 3: destruct(&static_cast(*this)); break; case 4: destruct(&static_cast(*this)); break; case 5: destruct(&static_cast(*this)); break; case 6: destruct(&static_cast(*this)); break; case 7: destruct(&static_cast(*this)); break; case 8: destruct(&static_cast(*this)); break; case 9: destruct(&static_cast(*this)); break; case 10: destruct(&static_cast(*this)); break; case 11: destruct(&static_cast(*this)); break; case 12: destruct(&static_cast(*this)); break; case 13: destruct(&static_cast(*this)); break; case 14: destruct(&static_cast(*this)); break; case 15: destruct(&static_cast(*this)); break; case 16: destruct(&static_cast(*this)); break; case 17: destruct(&static_cast(*this)); break; case 18: destruct(&static_cast(*this)); break; case 19: destruct(&static_cast(*this)); break; case 20: destruct(&static_cast(*this)); break; case 21: destruct(&static_cast(*this)); break; case 22: destruct(&static_cast(*this)); break; case 23: destruct(&static_cast(*this)); break; case 24: destruct(&static_cast(*this)); break; case 25: destruct(&static_cast(*this)); break; case 26: destruct(&static_cast(*this)); break; case 27: destruct(&static_cast(*this)); break; case 28: destruct(&static_cast(*this)); break; case 29: destruct(&static_cast(*this)); break; case 30: destruct(&static_cast(*this)); break; } } } void swap(variant& rhs) { variant tmp = rhs; rhs = *this; *this = tmp; } private: template operator BaseClass&() { return *reinterpret_cast(iAlignedBuffer.iData1); } template operator const BaseClass&() const { return *reinterpret_cast(iAlignedBuffer.iData1); } template friend BaseClass variant_upcast(variant& aVariant) { return static_cast(aVariant); } template friend BaseClass variant_upcast(const variant& aVariant) { return static_cast(aVariant); } template inline void construct(void* aObject, const T& aValue, variant_type aVariantType) { new (aObject) T(aValue); iVariantType = aVariantType; } template inline void destruct(T* aObject) { aObject->~T(); iVariantType = 0; } union { variant_detail::max_align dummy0; char iData1[sizeof(T1)]; char iData2[sizeof(T2)]; char iData3[sizeof(T3)]; char iData4[sizeof(T4)]; char iData5[sizeof(T5)]; char iData6[sizeof(T6)]; char iData7[sizeof(T7)]; char iData8[sizeof(T8)]; char iData9[sizeof(T9)]; char iData10[sizeof(T10)]; char iData11[sizeof(T11)]; char iData12[sizeof(T12)]; char iData13[sizeof(T13)]; char iData14[sizeof(T14)]; char iData15[sizeof(T15)]; char iData16[sizeof(T16)]; char iData17[sizeof(T17)]; char iData18[sizeof(T18)]; char iData19[sizeof(T19)]; char iData20[sizeof(T20)]; char iData21[sizeof(T21)]; char iData22[sizeof(T22)]; char iData23[sizeof(T23)]; char iData24[sizeof(T24)]; char iData25[sizeof(T25)]; char iData26[sizeof(T26)]; char iData27[sizeof(T27)]; char iData28[sizeof(T28)]; char iData29[sizeof(T29)]; char iData30[sizeof(T30)]; } iAlignedBuffer; variant_type iVariantType; bool is(T1*) const { return iVariantType == 1; } bool is(T2*) const { return iVariantType == 2; } bool is(T3*) const { return iVariantType == 3; } bool is(T4*) const { return iVariantType == 4; } bool is(T5*) const { return iVariantType == 5; } bool is(T6*) const { return iVariantType == 6; } bool is(T7*) const { return iVariantType == 7; } bool is(T8*) const { return iVariantType == 8; } bool is(T9*) const { return iVariantType == 9; } bool is(T10*) const { return iVariantType == 10; } bool is(T11*) const { return iVariantType == 11; } bool is(T12*) const { return iVariantType == 12; } bool is(T13*) const { return iVariantType == 13; } bool is(T14*) const { return iVariantType == 14; } bool is(T15*) const { return iVariantType == 15; } bool is(T16*) const { return iVariantType == 16; } bool is(T17*) const { return iVariantType == 17; } bool is(T18*) const { return iVariantType == 18; } bool is(T19*) const { return iVariantType == 19; } bool is(T20*) const { return iVariantType == 20; } bool is(T21*) const { return iVariantType == 21; } bool is(T22*) const { return iVariantType == 22; } bool is(T23*) const { return iVariantType == 23; } bool is(T24*) const { return iVariantType == 24; } bool is(T25*) const { return iVariantType == 25; } bool is(T26*) const { return iVariantType == 26; } bool is(T27*) const { return iVariantType == 27; } bool is(T28*) const { return iVariantType == 28; } bool is(T29*) const { return iVariantType == 29; } bool is(T30*) const { return iVariantType == 30; } }; template, typename T3 = unused_variant<3>, typename T4 = unused_variant<4>, typename T5 = unused_variant<5>, typename T6 = unused_variant<6>, typename T7 = unused_variant<7>, typename T8 = unused_variant<8>, typename T9 = unused_variant<9>, typename T10 = unused_variant<10>, typename T11 = unused_variant<11>, typename T12 = unused_variant<12>, typename T13 = unused_variant<13>, typename T14 = unused_variant<14>, typename T15 = unused_variant<15>, typename T16 = unused_variant<16>, typename T17 = unused_variant<17>, typename T18 = unused_variant<18>, typename T19 = unused_variant<19>, typename T20 = unused_variant<20>, typename T21 = unused_variant<21>, typename T22 = unused_variant<22>, typename T23 = unused_variant<23>, typename T24 = unused_variant<24>, typename T25 = unused_variant<25>, typename T26 = unused_variant<26>, typename T27 = unused_variant<27>, typename T28 = unused_variant<28>, typename T29 = unused_variant<29>, typename T30 = unused_variant<30> > class unchecked_variant { public: typedef size_t variant_type; public: // construction unchecked_variant() : iVariantType(0) {} unchecked_variant(const unchecked_variant& rhs) : iVariantType(0) { assign(rhs); } unchecked_variant(const T1& value) : iVariantType(0) { assign(value); } unchecked_variant(const T2& value) : iVariantType(0) { assign(value); } unchecked_variant(const T3& value) : iVariantType(0) { assign(value); } unchecked_variant(const T4& value) : iVariantType(0) { assign(value); } unchecked_variant(const T5& value) : iVariantType(0) { assign(value); } unchecked_variant(const T6& value) : iVariantType(0) { assign(value); } unchecked_variant(const T7& value) : iVariantType(0) { assign(value); } unchecked_variant(const T8& value) : iVariantType(0) { assign(value); } unchecked_variant(const T9& value) : iVariantType(0) { assign(value); } unchecked_variant(const T10& value) : iVariantType(0) { assign(value); } unchecked_variant(const T11& value) : iVariantType(0) { assign(value); } unchecked_variant(const T12& value) : iVariantType(0) { assign(value); } unchecked_variant(const T13& value) : iVariantType(0) { assign(value); } unchecked_variant(const T14& value) : iVariantType(0) { assign(value); } unchecked_variant(const T15& value) : iVariantType(0) { assign(value); } unchecked_variant(const T16& value) : iVariantType(0) { assign(value); } unchecked_variant(const T17& value) : iVariantType(0) { assign(value); } unchecked_variant(const T18& value) : iVariantType(0) { assign(value); } unchecked_variant(const T19& value) : iVariantType(0) { assign(value); } unchecked_variant(const T20& value) : iVariantType(0) { assign(value); } unchecked_variant(const T21& value) : iVariantType(0) { assign(value); } unchecked_variant(const T22& value) : iVariantType(0) { assign(value); } unchecked_variant(const T23& value) : iVariantType(0) { assign(value); } unchecked_variant(const T24& value) : iVariantType(0) { assign(value); } unchecked_variant(const T25& value) : iVariantType(0) { assign(value); } unchecked_variant(const T26& value) : iVariantType(0) { assign(value); } unchecked_variant(const T27& value) : iVariantType(0) { assign(value); } unchecked_variant(const T28& value) : iVariantType(0) { assign(value); } unchecked_variant(const T29& value) : iVariantType(0) { assign(value); } unchecked_variant(const T30& value) : iVariantType(0) { assign(value); } ~unchecked_variant() { clear(); } // state bool valid() const { return iVariantType != 0; } bool invalid() const { return iVariantType == 0; } variant_type which() const { return iVariantType; } template bool is() const { return is(static_cast(0)); } bool operator==(const unchecked_variant& rhs) const { if (valid() != rhs.valid()) return false; if (which() != rhs.which()) return false; switch (which()) { case 1: return static_cast(*this) == static_cast(rhs); case 2: return static_cast(*this) == static_cast(rhs); case 3: return static_cast(*this) == static_cast(rhs); case 4: return static_cast(*this) == static_cast(rhs); case 5: return static_cast(*this) == static_cast(rhs); case 6: return static_cast(*this) == static_cast(rhs); case 7: return static_cast(*this) == static_cast(rhs); case 8: return static_cast(*this) == static_cast(rhs); case 9: return static_cast(*this) == static_cast(rhs); case 10: return static_cast(*this) == static_cast(rhs); case 11: return static_cast(*this) == static_cast(rhs); case 12: return static_cast(*this) == static_cast(rhs); case 13: return static_cast(*this) == static_cast(rhs); case 14: return static_cast(*this) == static_cast(rhs); case 15: return static_cast(*this) == static_cast(rhs); case 16: return static_cast(*this) == static_cast(rhs); case 17: return static_cast(*this) == static_cast(rhs); case 18: return static_cast(*this) == static_cast(rhs); case 19: return static_cast(*this) == static_cast(rhs); case 20: return static_cast(*this) == static_cast(rhs); case 21: return static_cast(*this) == static_cast(rhs); case 22: return static_cast(*this) == static_cast(rhs); case 23: return static_cast(*this) == static_cast(rhs); case 24: return static_cast(*this) == static_cast(rhs); case 25: return static_cast(*this) == static_cast(rhs); case 26: return static_cast(*this) == static_cast(rhs); case 27: return static_cast(*this) == static_cast(rhs); case 28: return static_cast(*this) == static_cast(rhs); case 29: return static_cast(*this) == static_cast(rhs); case 30: return static_cast(*this) == static_cast(rhs); default: return true; } } bool operator!=(const unchecked_variant& rhs) const { return !operator==(rhs); } bool operator<(const unchecked_variant& rhs) const { if (which() != rhs.which()) return which() < rhs.which(); switch (which()) { case 1: return static_cast(*this) < static_cast(rhs); case 2: return static_cast(*this) < static_cast(rhs); case 3: return static_cast(*this) < static_cast(rhs); case 4: return static_cast(*this) < static_cast(rhs); case 5: return static_cast(*this) < static_cast(rhs); case 6: return static_cast(*this) < static_cast(rhs); case 7: return static_cast(*this) < static_cast(rhs); case 8: return static_cast(*this) < static_cast(rhs); case 9: return static_cast(*this) < static_cast(rhs); case 10: return static_cast(*this) < static_cast(rhs); case 11: return static_cast(*this) < static_cast(rhs); case 12: return static_cast(*this) < static_cast(rhs); case 13: return static_cast(*this) < static_cast(rhs); case 14: return static_cast(*this) < static_cast(rhs); case 15: return static_cast(*this) < static_cast(rhs); case 16: return static_cast(*this) < static_cast(rhs); case 17: return static_cast(*this) < static_cast(rhs); case 18: return static_cast(*this) < static_cast(rhs); case 19: return static_cast(*this) < static_cast(rhs); case 20: return static_cast(*this) < static_cast(rhs); case 21: return static_cast(*this) < static_cast(rhs); case 22: return static_cast(*this) < static_cast(rhs); case 23: return static_cast(*this) < static_cast(rhs); case 24: return static_cast(*this) < static_cast(rhs); case 25: return static_cast(*this) < static_cast(rhs); case 26: return static_cast(*this) < static_cast(rhs); case 27: return static_cast(*this) < static_cast(rhs); case 28: return static_cast(*this) < static_cast(rhs); case 29: return static_cast(*this) < static_cast(rhs); case 30: return static_cast(*this) < static_cast(rhs); default: return false; } } // element access operator T1&() { return *reinterpret_cast(iAlignedBuffer.iData1); } operator T2&() { return *reinterpret_cast(iAlignedBuffer.iData2); } operator T3&() { return *reinterpret_cast(iAlignedBuffer.iData3); } operator T4&() { return *reinterpret_cast(iAlignedBuffer.iData4); } operator T5&() { return *reinterpret_cast(iAlignedBuffer.iData5); } operator T6&() { return *reinterpret_cast(iAlignedBuffer.iData6); } operator T7&() { return *reinterpret_cast(iAlignedBuffer.iData7); } operator T8&() { return *reinterpret_cast(iAlignedBuffer.iData8); } operator T9&() { return *reinterpret_cast(iAlignedBuffer.iData9); } operator T10&() { return *reinterpret_cast(iAlignedBuffer.iData10); } operator T11&() { return *reinterpret_cast(iAlignedBuffer.iData11); } operator T12&() { return *reinterpret_cast(iAlignedBuffer.iData12); } operator T13&() { return *reinterpret_cast(iAlignedBuffer.iData13); } operator T14&() { return *reinterpret_cast(iAlignedBuffer.iData14); } operator T15&() { return *reinterpret_cast(iAlignedBuffer.iData15); } operator T16&() { return *reinterpret_cast(iAlignedBuffer.iData16); } operator T17&() { return *reinterpret_cast(iAlignedBuffer.iData17); } operator T18&() { return *reinterpret_cast(iAlignedBuffer.iData18); } operator T19&() { return *reinterpret_cast(iAlignedBuffer.iData19); } operator T20&() { return *reinterpret_cast(iAlignedBuffer.iData20); } operator T21&() { return *reinterpret_cast(iAlignedBuffer.iData21); } operator T22&() { return *reinterpret_cast(iAlignedBuffer.iData22); } operator T23&() { return *reinterpret_cast(iAlignedBuffer.iData23); } operator T24&() { return *reinterpret_cast(iAlignedBuffer.iData24); } operator T25&() { return *reinterpret_cast(iAlignedBuffer.iData25); } operator T26&() { return *reinterpret_cast(iAlignedBuffer.iData26); } operator T27&() { return *reinterpret_cast(iAlignedBuffer.iData27); } operator T28&() { return *reinterpret_cast(iAlignedBuffer.iData28); } operator T29&() { return *reinterpret_cast(iAlignedBuffer.iData29); } operator T30&() { return *reinterpret_cast(iAlignedBuffer.iData30); } operator const T1&() const { return *reinterpret_cast(iAlignedBuffer.iData1); } operator const T2&() const { return *reinterpret_cast(iAlignedBuffer.iData2); } operator const T3&() const { return *reinterpret_cast(iAlignedBuffer.iData3); } operator const T4&() const { return *reinterpret_cast(iAlignedBuffer.iData4); } operator const T5&() const { return *reinterpret_cast(iAlignedBuffer.iData5); } operator const T6&() const { return *reinterpret_cast(iAlignedBuffer.iData6); } operator const T7&() const { return *reinterpret_cast(iAlignedBuffer.iData7); } operator const T8&() const { return *reinterpret_cast(iAlignedBuffer.iData8); } operator const T9&() const { return *reinterpret_cast(iAlignedBuffer.iData9); } operator const T10&() const { return *reinterpret_cast(iAlignedBuffer.iData10); } operator const T11&() const { return *reinterpret_cast(iAlignedBuffer.iData11); } operator const T12&() const { return *reinterpret_cast(iAlignedBuffer.iData12); } operator const T13&() const { return *reinterpret_cast(iAlignedBuffer.iData13); } operator const T14&() const { return *reinterpret_cast(iAlignedBuffer.iData14); } operator const T15&() const { return *reinterpret_cast(iAlignedBuffer.iData15); } operator const T16&() const { return *reinterpret_cast(iAlignedBuffer.iData16); } operator const T17&() const { return *reinterpret_cast(iAlignedBuffer.iData17); } operator const T18&() const { return *reinterpret_cast(iAlignedBuffer.iData18); } operator const T19&() const { return *reinterpret_cast(iAlignedBuffer.iData19); } operator const T20&() const { return *reinterpret_cast(iAlignedBuffer.iData20); } operator const T21&() const { return *reinterpret_cast(iAlignedBuffer.iData21); } operator const T22&() const { return *reinterpret_cast(iAlignedBuffer.iData22); } operator const T23&() const { return *reinterpret_cast(iAlignedBuffer.iData23); } operator const T24&() const { return *reinterpret_cast(iAlignedBuffer.iData24); } operator const T25&() const { return *reinterpret_cast(iAlignedBuffer.iData25); } operator const T26&() const { return *reinterpret_cast(iAlignedBuffer.iData26); } operator const T27&() const { return *reinterpret_cast(iAlignedBuffer.iData27); } operator const T28&() const { return *reinterpret_cast(iAlignedBuffer.iData28); } operator const T29&() const { return *reinterpret_cast(iAlignedBuffer.iData29); } operator const T30&() const { return *reinterpret_cast(iAlignedBuffer.iData30); } // modifiers unchecked_variant& operator=(const unchecked_variant& rhs) { if (&rhs == this) return *this; return assign(rhs); } unchecked_variant& operator=(const T1& value) { return assign(value); } unchecked_variant& operator=(const T2& value) { return assign(value); } unchecked_variant& operator=(const T3& value) { return assign(value); } unchecked_variant& operator=(const T4& value) { return assign(value); } unchecked_variant& operator=(const T5& value) { return assign(value); } unchecked_variant& operator=(const T6& value) { return assign(value); } unchecked_variant& operator=(const T7& value) { return assign(value); } unchecked_variant& operator=(const T8& value) { return assign(value); } unchecked_variant& operator=(const T9& value) { return assign(value); } unchecked_variant& operator=(const T10& value) { return assign(value); } unchecked_variant& operator=(const T11& value) { return assign(value); } unchecked_variant& operator=(const T12& value) { return assign(value); } unchecked_variant& operator=(const T13& value) { return assign(value); } unchecked_variant& operator=(const T14& value) { return assign(value); } unchecked_variant& operator=(const T15& value) { return assign(value); } unchecked_variant& operator=(const T16& value) { return assign(value); } unchecked_variant& operator=(const T17& value) { return assign(value); } unchecked_variant& operator=(const T18& value) { return assign(value); } unchecked_variant& operator=(const T19& value) { return assign(value); } unchecked_variant& operator=(const T20& value) { return assign(value); } unchecked_variant& operator=(const T21& value) { return assign(value); } unchecked_variant& operator=(const T22& value) { return assign(value); } unchecked_variant& operator=(const T23& value) { return assign(value); } unchecked_variant& operator=(const T24& value) { return assign(value); } unchecked_variant& operator=(const T25& value) { return assign(value); } unchecked_variant& operator=(const T26& value) { return assign(value); } unchecked_variant& operator=(const T27& value) { return assign(value); } unchecked_variant& operator=(const T28& value) { return assign(value); } unchecked_variant& operator=(const T29& value) { return assign(value); } unchecked_variant& operator=(const T30& value) { return assign(value); } unchecked_variant& assign(const T1& value) { clear(); construct(iAlignedBuffer.iData1, value, 1); return *this; } unchecked_variant& assign(const T2& value) { clear(); construct(iAlignedBuffer.iData2, value, 2); return *this; } unchecked_variant& assign(const T3& value) { clear(); construct(iAlignedBuffer.iData3, value, 3); return *this; } unchecked_variant& assign(const T4& value) { clear(); construct(iAlignedBuffer.iData4, value, 4); return *this; } unchecked_variant& assign(const T5& value) { clear(); construct(iAlignedBuffer.iData5, value, 5); return *this; } unchecked_variant& assign(const T6& value) { clear(); construct(iAlignedBuffer.iData6, value, 6); return *this; } unchecked_variant& assign(const T7& value) { clear(); construct(iAlignedBuffer.iData7, value, 7); return *this; } unchecked_variant& assign(const T8& value) { clear(); construct(iAlignedBuffer.iData8, value, 8); return *this; } unchecked_variant& assign(const T9& value) { clear(); construct(iAlignedBuffer.iData9, value, 9); return *this; } unchecked_variant& assign(const T10& value) { clear(); construct(iAlignedBuffer.iData10, value, 10); return *this; } unchecked_variant& assign(const T11& value) { clear(); construct(iAlignedBuffer.iData11, value, 11); return *this; } unchecked_variant& assign(const T12& value) { clear(); construct(iAlignedBuffer.iData12, value, 12); return *this; } unchecked_variant& assign(const T13& value) { clear(); construct(iAlignedBuffer.iData13, value, 13); return *this; } unchecked_variant& assign(const T14& value) { clear(); construct(iAlignedBuffer.iData14, value, 14); return *this; } unchecked_variant& assign(const T15& value) { clear(); construct(iAlignedBuffer.iData15, value, 15); return *this; } unchecked_variant& assign(const T16& value) { clear(); construct(iAlignedBuffer.iData16, value, 16); return *this; } unchecked_variant& assign(const T17& value) { clear(); construct(iAlignedBuffer.iData17, value, 17); return *this; } unchecked_variant& assign(const T18& value) { clear(); construct(iAlignedBuffer.iData18, value, 18); return *this; } unchecked_variant& assign(const T19& value) { clear(); construct(iAlignedBuffer.iData19, value, 19); return *this; } unchecked_variant& assign(const T20& value) { clear(); construct(iAlignedBuffer.iData20, value, 20); return *this; } unchecked_variant& assign(const T21& value) { clear(); construct(iAlignedBuffer.iData21, value, 21); return *this; } unchecked_variant& assign(const T22& value) { clear(); construct(iAlignedBuffer.iData22, value, 22); return *this; } unchecked_variant& assign(const T23& value) { clear(); construct(iAlignedBuffer.iData23, value, 23); return *this; } unchecked_variant& assign(const T24& value) { clear(); construct(iAlignedBuffer.iData24, value, 24); return *this; } unchecked_variant& assign(const T25& value) { clear(); construct(iAlignedBuffer.iData25, value, 25); return *this; } unchecked_variant& assign(const T26& value) { clear(); construct(iAlignedBuffer.iData26, value, 26); return *this; } unchecked_variant& assign(const T27& value) { clear(); construct(iAlignedBuffer.iData27, value, 27); return *this; } unchecked_variant& assign(const T28& value) { clear(); construct(iAlignedBuffer.iData28, value, 28); return *this; } unchecked_variant& assign(const T29& value) { clear(); construct(iAlignedBuffer.iData29, value, 29); return *this; } unchecked_variant& assign(const T30& value) { clear(); construct(iAlignedBuffer.iData30, value, 30); return *this; } unchecked_variant& assign(const unchecked_variant& rhs) { if (&rhs == this) return *this; if (rhs.valid()) { switch(rhs.which()) { case 1: return assign(static_cast(rhs)); case 2: return assign(static_cast(rhs)); case 3: return assign(static_cast(rhs)); case 4: return assign(static_cast(rhs)); case 5: return assign(static_cast(rhs)); case 6: return assign(static_cast(rhs)); case 7: return assign(static_cast(rhs)); case 8: return assign(static_cast(rhs)); case 9: return assign(static_cast(rhs)); case 10: return assign(static_cast(rhs)); case 11: return assign(static_cast(rhs)); case 12: return assign(static_cast(rhs)); case 13: return assign(static_cast(rhs)); case 14: return assign(static_cast(rhs)); case 15: return assign(static_cast(rhs)); case 16: return assign(static_cast(rhs)); case 17: return assign(static_cast(rhs)); case 18: return assign(static_cast(rhs)); case 19: return assign(static_cast(rhs)); case 20: return assign(static_cast(rhs)); case 21: return assign(static_cast(rhs)); case 22: return assign(static_cast(rhs)); case 23: return assign(static_cast(rhs)); case 24: return assign(static_cast(rhs)); case 25: return assign(static_cast(rhs)); case 26: return assign(static_cast(rhs)); case 27: return assign(static_cast(rhs)); case 28: return assign(static_cast(rhs)); case 29: return assign(static_cast(rhs)); case 30: return assign(static_cast(rhs)); } } else clear(); return *this; } void clear() { if (valid()) { switch(which()) { case 1: destruct(&static_cast(*this)); break; case 2: destruct(&static_cast(*this)); break; case 3: destruct(&static_cast(*this)); break; case 4: destruct(&static_cast(*this)); break; case 5: destruct(&static_cast(*this)); break; case 6: destruct(&static_cast(*this)); break; case 7: destruct(&static_cast(*this)); break; case 8: destruct(&static_cast(*this)); break; case 9: destruct(&static_cast(*this)); break; case 10: destruct(&static_cast(*this)); break; case 11: destruct(&static_cast(*this)); break; case 12: destruct(&static_cast(*this)); break; case 13: destruct(&static_cast(*this)); break; case 14: destruct(&static_cast(*this)); break; case 15: destruct(&static_cast(*this)); break; case 16: destruct(&static_cast(*this)); break; case 17: destruct(&static_cast(*this)); break; case 18: destruct(&static_cast(*this)); break; case 19: destruct(&static_cast(*this)); break; case 20: destruct(&static_cast(*this)); break; case 21: destruct(&static_cast(*this)); break; case 22: destruct(&static_cast(*this)); break; case 23: destruct(&static_cast(*this)); break; case 24: destruct(&static_cast(*this)); break; case 25: destruct(&static_cast(*this)); break; case 26: destruct(&static_cast(*this)); break; case 27: destruct(&static_cast(*this)); break; case 28: destruct(&static_cast(*this)); break; case 29: destruct(&static_cast(*this)); break; case 30: destruct(&static_cast(*this)); break; } } } void swap(unchecked_variant& rhs) { unchecked_variant tmp = rhs; rhs = *this; *this = tmp; } private: template operator BaseClass&() { return *reinterpret_cast(iAlignedBuffer.iData1); } template operator const BaseClass&() const { return *reinterpret_cast(iAlignedBuffer.iData1); } template friend BaseClass variant_upcast(unchecked_variant& aVariant) { return static_cast(aVariant); } template friend BaseClass variant_upcast(const unchecked_variant& aVariant) { return static_cast(aVariant); } template inline void construct(void* aObject, const T& aValue, variant_type aVariantType) { new (aObject) T(aValue); iVariantType = aVariantType; } template inline void destruct(T* aObject) { aObject->~T(); iVariantType = 0; } union { variant_detail::max_align dummy0; char iData1[sizeof(T1)]; char iData2[sizeof(T2)]; char iData3[sizeof(T3)]; char iData4[sizeof(T4)]; char iData5[sizeof(T5)]; char iData6[sizeof(T6)]; char iData7[sizeof(T7)]; char iData8[sizeof(T8)]; char iData9[sizeof(T9)]; char iData10[sizeof(T10)]; char iData11[sizeof(T11)]; char iData12[sizeof(T12)]; char iData13[sizeof(T13)]; char iData14[sizeof(T14)]; char iData15[sizeof(T15)]; char iData16[sizeof(T16)]; char iData17[sizeof(T17)]; char iData18[sizeof(T18)]; char iData19[sizeof(T19)]; char iData20[sizeof(T20)]; char iData21[sizeof(T21)]; char iData22[sizeof(T22)]; char iData23[sizeof(T23)]; char iData24[sizeof(T24)]; char iData25[sizeof(T25)]; char iData26[sizeof(T26)]; char iData27[sizeof(T27)]; char iData28[sizeof(T28)]; char iData29[sizeof(T29)]; char iData30[sizeof(T30)]; } iAlignedBuffer; variant_type iVariantType; bool is(T1*) const { return iVariantType == 1; } bool is(T2*) const { return iVariantType == 2; } bool is(T3*) const { return iVariantType == 3; } bool is(T4*) const { return iVariantType == 4; } bool is(T5*) const { return iVariantType == 5; } bool is(T6*) const { return iVariantType == 6; } bool is(T7*) const { return iVariantType == 7; } bool is(T8*) const { return iVariantType == 8; } bool is(T9*) const { return iVariantType == 9; } bool is(T10*) const { return iVariantType == 10; } bool is(T11*) const { return iVariantType == 11; } bool is(T12*) const { return iVariantType == 12; } bool is(T13*) const { return iVariantType == 13; } bool is(T14*) const { return iVariantType == 14; } bool is(T15*) const { return iVariantType == 15; } bool is(T16*) const { return iVariantType == 16; } bool is(T17*) const { return iVariantType == 17; } bool is(T18*) const { return iVariantType == 18; } bool is(T19*) const { return iVariantType == 19; } bool is(T20*) const { return iVariantType == 20; } bool is(T21*) const { return iVariantType == 21; } bool is(T22*) const { return iVariantType == 22; } bool is(T23*) const { return iVariantType == 23; } bool is(T24*) const { return iVariantType == 24; } bool is(T25*) const { return iVariantType == 25; } bool is(T26*) const { return iVariantType == 26; } bool is(T27*) const { return iVariantType == 27; } bool is(T28*) const { return iVariantType == 28; } bool is(T29*) const { return iVariantType == 29; } bool is(T30*) const { return iVariantType == 30; } }; } #endif // LIB_VARIANT