15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Template metaprogramming utility functions.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This code is compiled directly on many platforms, including client
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// platforms like Windows, Mac, and embedded systems.  Before making
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// any changes here, make sure that you're not breaking any platforms.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The names choosen here reflect those used in tr1 and the boost::mpl
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// library, there are similar operations used in the Loki library as
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// well.  I prefer the boost names for 2 reasons:
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1.  I think that portions of the Boost libraries are more likely to
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be included in the c++ standard.
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2.  It is not impossible that some of the boost libraries will be
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// included in our own build in the future.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Both of these outcomes means that we may be able to directly replace
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// some of these with boost equivalents.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_TEMPLATE_UTIL_H_
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_TEMPLATE_UTIL_H_
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Types small_ and big_ are guaranteed such that sizeof(small_) <
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sizeof(big_)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef char small_;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct big_ {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char dummy[2];
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// integral_constant, defined in tr1, is a wrapper for an integer
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// value. We don't really need this generality; we could get away
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with hardcoding the integer type to bool. We use the fully
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// general integer_constant for compatibility with tr1.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T, T v>
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct integral_constant {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const T value = v;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef T value_type;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef integral_constant<T, v> type;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T, T v> const T integral_constant<T, v>::value;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Abbreviations: true_type and false_type are structs that represent boolean
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true and false values. Also define the boost::mpl versions of those names,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true_ and false_.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef integral_constant<bool, true>  true_type;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef integral_constant<bool, false> false_type;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef true_type  true_;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef false_type false_;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if_ is a templatized conditional statement.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if_<cond, A, B> is a compile time evaluation of cond.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if_<>::type contains A if cond is true, B otherwise.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<bool cond, typename A, typename B>
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct if_{
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef A type;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename A, typename B>
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct if_<false, A, B> {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef B type;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// type_equals_ is a template type comparator, similar to Loki IsSameType.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// type_equals_<A, B>::value is true iff "A" is the same type as "B".
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename A, typename B>
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct type_equals_ : public false_ {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename A>
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct type_equals_<A, A> : public true_ {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and_ is a template && operator.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and_<A, B>::value evaluates "A::value && B::value".
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename A, typename B>
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct and_ : public integral_constant<bool, (A::value && B::value)> {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or_ is a template || operator.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or_<A, B>::value evaluates "A::value || B::value".
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename A, typename B>
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct or_ : public integral_constant<bool, (A::value || B::value)> {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // Close namespace base
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_TEMPLATE_UTIL_H_
97