$$ 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 = 5

// Copyright 2015 The Cobalt Authors. 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)), SB_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), SB_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_
