$$ 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 COBALT_SCRIPT_UNION_TYPE_H_
#define COBALT_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  // COBALT_SCRIPT_UNION_TYPE_H_
