blob: 7767d7e3785a1f92d07a1fa8f06cf40dbee62ec4 [file] [log] [blame]
/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* 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.
*/
#ifndef COBALT_SCRIPT_UNION_TYPE_INTERNAL_H_
#define COBALT_SCRIPT_UNION_TYPE_INTERNAL_H_
// Details of union type implementation. See union_type.h
#include <limits>
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "cobalt/base/enable_if.h"
#include "cobalt/base/type_id.h"
namespace cobalt {
namespace script {
namespace internal {
template <typename T>
struct UnionTypeDefaultTraits {
typedef const T& ArgType;
typedef T& ReturnType;
typedef const T& ConstReturnType;
static base::TypeId GetTypeID() { return base::GetTypeId<T>(); }
static const bool is_interface_type = false;
static const bool is_numeric_type = false;
static const bool is_boolean_type = false;
static const bool is_string_type = false;
};
// Default traits for types with no specialization
template <typename T, typename = void>
struct UnionTypeTraits : UnionTypeDefaultTraits<T> {
// This assert will only be evaluated if the template is instantiated.
COMPILE_ASSERT(sizeof(T) == 0, UnionTypeNotImplementedForType);
};
template <typename T>
struct UnionTypeTraits<scoped_refptr<T> >
: UnionTypeDefaultTraits<scoped_refptr<T> > {
static base::TypeId GetTypeID() { return base::GetTypeId<T>(); }
static const bool is_interface_type = true;
};
template <>
struct UnionTypeTraits<std::string> : UnionTypeDefaultTraits<std::string> {
static const bool is_string_type = true;
};
// std::numeric_limits<T>::digits will be 0 for non-specialized types, 1 for
// bool, and something larger for the other types.
template <typename T>
struct UnionTypeTraits<
T, typename base::enable_if<(std::numeric_limits<T>::digits > 1)>::type>
: UnionTypeDefaultTraits<T> {
typedef T ArgType;
typedef T ReturnType;
typedef T ConstReturnType;
static const bool is_numeric_type = true;
};
template <>
struct UnionTypeTraits<bool> : UnionTypeDefaultTraits<bool> {
typedef bool ArgType;
typedef bool ReturnType;
typedef bool ConstReturnType;
static const bool is_boolean_type = true;
};
// Explicitly blacklist nullable types. None of the union members should be
// nullable. If the union has a nullable member, then the whole union type
// should be declared nullable such as base::optional<base::UnionTypeN<...> >
template <typename T>
struct UnionTypeTraits<base::optional<T> > : UnionTypeDefaultTraits<T> {
// This assert will only be evaluated if the template is instantiated.
COMPILE_ASSERT(sizeof(T) == 0, NullableTypesAreNotPermittedInUnionss);
};
} // namespace internal
} // namespace script
} // namespace cobalt
#endif // COBALT_SCRIPT_UNION_TYPE_INTERNAL_H_