$$ This is a pump file for generating file templates.  Pump is a python
$$ script that is part of the Google Test suite of utilities.  Description
$$ can be found here:
$$
$$ http://code.google.com/p/googletest/wiki/PumpManual
$$

$$ Maximum number of different member types in a union.
$var MAX_MEMBERS = 4

// 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 SCRIPT_UNION_TYPE_H_
#define SCRIPT_UNION_TYPE_H_

// Implementation of IDL union types.
// http://heycam.github.io/webidl/#idl-union
//
// The member types for a given union type are set at compile-time as template
// parameters. Use templated IsType<> functions to check if a certain type is
// the specific type.
// http://heycam.github.io/webidl/#dfn-specific-type
// The template function AsType can be used to return the specific type.
//
// Attempting to instantiate a UnionType with an unsupported type will result
// in a compile-time assert.
//
// Attempting to query or retrieve a type that is not a part of the union will
// result in a compile-time assert.
//
// Each UnionTypeN allows for definition of a union type with N members. The
// template parameters should be the flattened member types of the union:
// http://heycam.github.io/webidl/#dfn-flattened-union-member-types
//
// Per the specification, there should be either 0 or 1 nullable types in union.
// In the case that there is one nullable type, the entire union type should
// be declared as nullable (with base::optional<>). A corollary to this is that
// none of the member types in the UnionTypeN template should be nullable.

#include <iosfwd>
#include <limits>

#include "base/memory/aligned_memory.h"
#include "cobalt/script/union_type_internal.h"

namespace cobalt {
namespace script {

$$ Skip the case where there is only one type
$range NUM_MEMBERS 2..MAX_MEMBERS
$for NUM_MEMBERS [[

$range TYPE 1..NUM_MEMBERS


template <$for TYPE , [[typename T$(TYPE)]]>
class UnionType$(NUM_MEMBERS) {
 public:

$range CTOR_TYPE 2..NUM_MEMBERS
  UnionType$(NUM_MEMBERS)() : specific_type_(kUnspecified) {}


$for TYPE [[
  explicit UnionType$(NUM_MEMBERS)([[typename internal::UnionTypeTraits<T$(TYPE)>::ArgType arg]])
      : specific_type_(kTypeT$(TYPE)) {
    new (storage_.void_data()) T$(TYPE)(arg);
  }

]]

  UnionType$(NUM_MEMBERS)(const UnionType$(NUM_MEMBERS)& other) {
    ConstructFromOther(other);
  }

  UnionType$(NUM_MEMBERS)& operator=(const UnionType$(NUM_MEMBERS)& other) {
    if (&other != this) {
      Destruct();
      ConstructFromOther(other);
    }
    return *this;
  }

  ~UnionType$(NUM_MEMBERS)() {
    Destruct();
  }

  // Forward these checks to the UnionTypeCheck helper class, which works around
  // being unable to do template specializations in class scope.
  template <typename S>
  bool IsType() const {
    return UnionTypeCheck<S>::IsType(this);
  }
  template <typename S>
  typename internal::UnionTypeTraits<S>::ReturnType AsType() {
    return UnionTypeCheck<S>::AsType(this);
  }
  template <typename S>
  typename internal::UnionTypeTraits<S>::ConstReturnType AsType() const {
    return UnionTypeCheck<S>::AsType(this);
  }

 private:
  // Internal helper class for checking and getting the union's specific type.
  // Only partial class template specializations are allowed in class scope,
  // hence the extra dummy template variable.
  template <typename U, bool = false>
  class UnionTypeCheck {
    // Attempting to query for types that are not part of the union will
    // result in a compile-time error.
    COMPILE_ASSERT(sizeof(U) == 0, UnsupportedType);
  };

  // Specializations of the UnionTypeCheck class for each member type of the
  // union.
$for TYPE [[

  template <bool dummy>
  class UnionTypeCheck<T$(TYPE), dummy> {
    static bool IsType(const UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>* union_value) {
      return union_value->specific_type_ == kTypeT$(TYPE);
    }
    static typename internal::UnionTypeTraits<T$(TYPE)>::ReturnType
        AsType(UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>* union_value) {
      return *(union_value->storage_.template data_as<T$(TYPE)>());
    }
    static typename internal::UnionTypeTraits<T$(TYPE)>::ConstReturnType
        AsType(const UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>* union_value) {
      return *(union_value->storage_.template data_as<T$(TYPE)>());
    }
    friend class UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>;
  };

]]

  enum SpecificType {
    kUnspecified = 0,
$for TYPE [[

    kTypeT$(TYPE),
]]

  };

  union StorageUnion {
$for TYPE [[

    base::AlignedMemory<sizeof(T$(TYPE)), ALIGNOF(T$(TYPE))> t$(TYPE);
]]

  };

  void ConstructFromOther(const UnionType$(NUM_MEMBERS)& other) {
    specific_type_ = other.specific_type_;
    switch (specific_type_) {
$for TYPE [[

      case kTypeT$(TYPE):
        new (storage_.void_data()) T$(TYPE)(other.AsType<T$(TYPE)>());
        break;
]]

      case kUnspecified:
        // no-op
        break;
    }
  }

  void Destruct() {
    switch (specific_type_) {
$for TYPE [[

      case kTypeT$(TYPE):
        storage_.template data_as<T$(TYPE)>()->T$(TYPE)::~T$(TYPE)();
        break;
]]

      case kUnspecified:
        // no-op
        break;
    }
    specific_type_ = kUnspecified;
  }

  base::AlignedMemory<sizeof(StorageUnion), ALIGNOF(StorageUnion)> storage_;
  SpecificType specific_type_;

  // Count the number of numeric types in this union. There can be a max of one.
  // Otherwise, the JS->Cobalt conversion is ambiguous.
  // The spec doesn't seem to describe this limitation, but this is what Blink
  // does.
  static const int kNumNumericTypes =
      $for TYPE  +
      [[(internal::UnionTypeTraits<T$(TYPE)>::is_numeric_type ? 1 : 0)]];
  COMPILE_ASSERT(kNumNumericTypes <= 1, AmbiguousUnionTypeConversion);
};

// Needed to instantiate base::optional<UnionTypeN>
template <$for TYPE , [[typename T$(TYPE)]]>
inline std::ostream& operator<<(
    std::ostream& stream, const UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>& union_value) {

 $for TYPE [[ if (union_value.template IsType<T$(TYPE)>()) {
    stream << union_value.template AsType<T$(TYPE)>();
  } else
]] {
    stream << "Undefined union type.";
  }

  return stream;
}

]]  $$ for NUM_MEMBERS

}  // namespace script
}  // namespace cobalt

#endif  // SCRIPT_UNION_TYPE_H_
