// Copyright 2019 Google LLC // // 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 // // https://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. #ifndef dap_variant_h #define dap_variant_h #include "any.h" namespace dap { // internal functionality namespace detail { template struct TypeIsIn { static constexpr bool value = false; }; template struct TypeIsIn { static constexpr bool value = std::is_same::value || TypeIsIn::value; }; } // namespace detail // variant represents a type-safe union of DAP types. // variant can hold a value of any of the template argument types. // variant defaults to a default-constructed T0. template class variant { public: // constructors inline variant(); template inline variant(const T& val); // assignment template inline variant& operator=(const T& val); // get() returns the contained value of the type T. // If the any does not contain a value of type T, then get() will assert. template inline T& get() const; // is() returns true iff the contained value is of type T. template inline bool is() const; // accepts() returns true iff the variant accepts values of type T. template static constexpr bool accepts(); private: friend class Serializer; friend class Deserializer; any value; }; template variant::variant() : value(T0()) {} template template variant::variant(const T& v) : value(v) { static_assert(accepts(), "variant does not accept template type T"); } template template variant& variant::operator=(const T& v) { static_assert(accepts(), "variant does not accept template type T"); value = v; return *this; } template template T& variant::get() const { static_assert(accepts(), "variant does not accept template type T"); return value.get(); } template template bool variant::is() const { return value.is(); } template template constexpr bool variant::accepts() { return detail::TypeIsIn::value; } } // namespace dap #endif // dap_variant_h