blob: f56a6d9db4662fe90ac1cbdcbdd01fb08c81abae [file] [log] [blame]
#pragma once
#ifndef GEODE_GFCPP_TYPEHELPER_H_
#define GEODE_GFCPP_TYPEHELPER_H_
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* @file Contains helper classes for extracting compile-time type traits
*/
#include "gfcpp_globals.hpp"
namespace apache {
namespace geode {
namespace client {
// Forward declaration of SharedPtr<T>
template <typename Target>
class SharedPtr;
// Forward declaration of SharedArrayPtr<T, ID>
template <typename Target, int8_t TYPEID>
class SharedArrayPtr;
// Forward declaration of CacheableArrayType<T, ID>
template <typename Target, int8_t TYPEID>
class CacheableArrayType;
/**
* @brief Helper type traits and other structs/classes to determine type
* information at compile time using typename.
* Useful for templates in particular.
*/
namespace TypeHelper {
typedef uint8_t yes_type;
typedef uint32_t no_type;
template <typename TBase, typename TDerived>
struct BDHelper {
template <typename T>
static yes_type check_sig(TDerived const volatile*, T);
static no_type check_sig(TBase const volatile*, int);
};
/**
* @brief This struct helps us determine whether or not a class is a
* subclass of another at compile time, so that it can be used
* in templates. For an explanation of how this works see:
* {@link
* http://groups.google.com/group/comp.lang.c++.moderated/msg/dd6c4e4d5160bd83}
* {@link
* http://groups.google.com/group/comp.lang.c++.moderated/msg/645b2486ae80e5fb}
*/
template <typename TBase, typename TDerived>
struct SuperSubclass {
private:
struct Host {
operator TBase const volatile*() const;
operator TDerived const volatile*();
};
public:
static const bool result = sizeof(BDHelper<TBase, TDerived>::check_sig(
Host(), 0)) == sizeof(yes_type);
};
/**
* @brief Specialization of <code>SuperSubclass</code> to return true
* for the special case when the two types being checked are same.
*/
template <typename TBase>
struct SuperSubclass<TBase, TBase> {
static const bool result = true;
};
/**
* @brief This struct helps convert a boolean value into static objects
* of different types. Useful for matching of template functions.
*/
template <bool getType = true>
struct YesNoType {
static const yes_type value = 0;
};
/**
* @brief Specialization of YesNoType for boolean value false.
*/
template <>
struct YesNoType<false> {
static const no_type value = 0;
};
/** @brief This struct unwraps the type <code>T</code> inside SharedPtr. */
template <class T>
struct UnwrapSharedPtr {};
/** @brief This struct unwraps the type <code>T</code> inside SharedPtr. */
template <class T>
struct UnwrapSharedPtr<SharedPtr<T> > {
typedef T type;
};
/** @brief This struct unwraps the type <code>T</code> inside SharedArrayPtr. */
template <class T, int8_t ID>
struct UnwrapSharedPtr<SharedArrayPtr<T, ID> > {
typedef CacheableArrayType<T, ID> type;
};
} // namespace TypeHelper
} // namespace client
} // namespace geode
} // namespace apache
/** @brief Macro to unwrap the type <code>T</code> inside SharedPtr. */
#define GF_UNWRAP_SP(T) \
typename apache::geode::client::TypeHelper::UnwrapSharedPtr<T>::type
/**
* @brief Macro to determine if the type <code>T</code> is derived from
* <code>Serializable</code>.
*/
#define GF_TYPE_IS_SERIALIZABLE(T) \
apache::geode::client::TypeHelper::SuperSubclass< \
apache::geode::client::Serializable, T>::result
/**
* @brief Macro that returns <code>yes_type</code> if the type <code>T</code> is
* derived from <code>Serializable</code> and <code>no_type</code>
* otherwise. Useful for overloaded template functions.
*/
#define GF_TYPE_IS_SERIALIZABLE_TYPE(T) \
apache::geode::client::TypeHelper::YesNoType<GF_TYPE_IS_SERIALIZABLE( \
T)>::value
#define GF_SRC_IS_TARGET_TYPE(TARGET, SRC) \
apache::geode::client::TypeHelper::YesNoType< \
apache::geode::client::TypeHelper::SuperSubclass<TARGET, \
SRC>::result>::value
#endif // GEODE_GFCPP_TYPEHELPER_H_