#pragma once /****************************************************************************** * * Copyright (c) 2019 AT&T Intellectual Property. * Copyright (c) 2018-2019 Nokia. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ // Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries #include #include // Local Includes: Application specific classes, functions, and libraries namespace asn{ template struct variant { typedef variant self_type; template static void check_size () {static_assert(sizeof (T) <= S, "wrong type");} variant () : typeinfo (nullptr) {} template variant (const T& t) : typeinfo (&typeid (T)) { check_size(); new (as_()) T (t); } ~variant () { assert(!typeinfo); } template T& build () { assert(!typeinfo); typeinfo = & typeid (T); return *new (as_()) T; } template T& build (const T& t) { assert(!typeinfo); check_size(); typeinfo = & typeid (T); return *new (as_ ()) T (t); } template T& as() { assert(*typeinfo == typeid (T)); check_size(); return *as_ (); } template const T& as() const { assert(*typeinfo == typeid (T)); check_size(); return *as_ (); } template void swap(self_type& other) { assert (typeinfo); assert (*typeinfo == *other.typeinfo); std::swap (as (), other.as ()); } template void move(self_type& other) { build (); swap (other); other.destroy (); } template void copy(const self_type& other) { build (other.as ()); } template void destroy() { as ().~T (); typeinfo = nullptr; } private: self_type& operator=(const self_type&){} variant (const self_type&){} template T* as_() { void *p = buffer.raw; return static_cast (p); } template const T* as_() const { const void *p = buffer.raw; return static_cast (p); } union { long double align_me; char raw[S]; } buffer; const std::type_info *typeinfo; }; } //namspace asn