// This file was GENERATED by command:
//     pump.py union_type.h.pump
// DO NOT EDIT BY HAND!!!


// 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 {

template <typename T1, typename T2>
class UnionType2 {
 public:
  UnionType2() : specific_type_(kUnspecified) {}

  explicit UnionType2(typename internal::UnionTypeTraits<T1>::ArgType arg)
      : specific_type_(kTypeT1) {
    new (storage_.void_data()) T1(arg);
  }
  explicit UnionType2(typename internal::UnionTypeTraits<T2>::ArgType arg)
      : specific_type_(kTypeT2) {
    new (storage_.void_data()) T2(arg);
  }

  UnionType2(const UnionType2& other) {
    ConstructFromOther(other);
  }

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

  ~UnionType2() {
    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.
  template <bool dummy>
  class UnionTypeCheck<T1, dummy> {
    static bool IsType(const UnionType2<T1, T2>* union_value) {
      return union_value->specific_type_ == kTypeT1;
    }
    static typename internal::UnionTypeTraits<T1>::ReturnType
        AsType(UnionType2<T1, T2>* union_value) {
      return *(union_value->storage_.template data_as<T1>());
    }
    static typename internal::UnionTypeTraits<T1>::ConstReturnType
        AsType(const UnionType2<T1, T2>* union_value) {
      return *(union_value->storage_.template data_as<T1>());
    }
    friend class UnionType2<T1, T2>;
  };

  template <bool dummy>
  class UnionTypeCheck<T2, dummy> {
    static bool IsType(const UnionType2<T1, T2>* union_value) {
      return union_value->specific_type_ == kTypeT2;
    }
    static typename internal::UnionTypeTraits<T2>::ReturnType
        AsType(UnionType2<T1, T2>* union_value) {
      return *(union_value->storage_.template data_as<T2>());
    }
    static typename internal::UnionTypeTraits<T2>::ConstReturnType
        AsType(const UnionType2<T1, T2>* union_value) {
      return *(union_value->storage_.template data_as<T2>());
    }
    friend class UnionType2<T1, T2>;
  };

  enum SpecificType {
    kUnspecified = 0,
    kTypeT1,
    kTypeT2,
  };

  union StorageUnion {
    base::AlignedMemory<sizeof(T1), ALIGNOF(T1)> t1;
    base::AlignedMemory<sizeof(T2), ALIGNOF(T2)> t2;
  };

  void ConstructFromOther(const UnionType2& other) {
    specific_type_ = other.specific_type_;
    switch (specific_type_) {
      case kTypeT1:
        new (storage_.void_data()) T1(other.AsType<T1>());
        break;
      case kTypeT2:
        new (storage_.void_data()) T2(other.AsType<T2>());
        break;
      case kUnspecified:
        // no-op
        break;
    }
  }

  void Destruct() {
    switch (specific_type_) {
      case kTypeT1:
        storage_.template data_as<T1>()->T1::~T1();
        break;
      case kTypeT2:
        storage_.template data_as<T2>()->T2::~T2();
        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 =
      (internal::UnionTypeTraits<T1>::is_numeric_type ? 1 : 0) +
      (internal::UnionTypeTraits<T2>::is_numeric_type ? 1 : 0);
  COMPILE_ASSERT(kNumNumericTypes <= 1, AmbiguousUnionTypeConversion);
};

// Needed to instantiate base::optional<UnionTypeN>
template <typename T1, typename T2>
inline std::ostream& operator<<(
    std::ostream& stream, const UnionType2<T1, T2>& union_value) {

  if (union_value.template IsType<T1>()) {
    stream << union_value.template AsType<T1>();
  } else if (union_value.template IsType<T2>()) {
    stream << union_value.template AsType<T2>();
  } else {
    stream << "Undefined union type.";
  }

  return stream;
}


template <typename T1, typename T2, typename T3>
class UnionType3 {
 public:
  UnionType3() : specific_type_(kUnspecified) {}

  explicit UnionType3(typename internal::UnionTypeTraits<T1>::ArgType arg)
      : specific_type_(kTypeT1) {
    new (storage_.void_data()) T1(arg);
  }
  explicit UnionType3(typename internal::UnionTypeTraits<T2>::ArgType arg)
      : specific_type_(kTypeT2) {
    new (storage_.void_data()) T2(arg);
  }
  explicit UnionType3(typename internal::UnionTypeTraits<T3>::ArgType arg)
      : specific_type_(kTypeT3) {
    new (storage_.void_data()) T3(arg);
  }

  UnionType3(const UnionType3& other) {
    ConstructFromOther(other);
  }

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

  ~UnionType3() {
    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.
  template <bool dummy>
  class UnionTypeCheck<T1, dummy> {
    static bool IsType(const UnionType3<T1, T2, T3>* union_value) {
      return union_value->specific_type_ == kTypeT1;
    }
    static typename internal::UnionTypeTraits<T1>::ReturnType
        AsType(UnionType3<T1, T2, T3>* union_value) {
      return *(union_value->storage_.template data_as<T1>());
    }
    static typename internal::UnionTypeTraits<T1>::ConstReturnType
        AsType(const UnionType3<T1, T2, T3>* union_value) {
      return *(union_value->storage_.template data_as<T1>());
    }
    friend class UnionType3<T1, T2, T3>;
  };

  template <bool dummy>
  class UnionTypeCheck<T2, dummy> {
    static bool IsType(const UnionType3<T1, T2, T3>* union_value) {
      return union_value->specific_type_ == kTypeT2;
    }
    static typename internal::UnionTypeTraits<T2>::ReturnType
        AsType(UnionType3<T1, T2, T3>* union_value) {
      return *(union_value->storage_.template data_as<T2>());
    }
    static typename internal::UnionTypeTraits<T2>::ConstReturnType
        AsType(const UnionType3<T1, T2, T3>* union_value) {
      return *(union_value->storage_.template data_as<T2>());
    }
    friend class UnionType3<T1, T2, T3>;
  };

  template <bool dummy>
  class UnionTypeCheck<T3, dummy> {
    static bool IsType(const UnionType3<T1, T2, T3>* union_value) {
      return union_value->specific_type_ == kTypeT3;
    }
    static typename internal::UnionTypeTraits<T3>::ReturnType
        AsType(UnionType3<T1, T2, T3>* union_value) {
      return *(union_value->storage_.template data_as<T3>());
    }
    static typename internal::UnionTypeTraits<T3>::ConstReturnType
        AsType(const UnionType3<T1, T2, T3>* union_value) {
      return *(union_value->storage_.template data_as<T3>());
    }
    friend class UnionType3<T1, T2, T3>;
  };

  enum SpecificType {
    kUnspecified = 0,
    kTypeT1,
    kTypeT2,
    kTypeT3,
  };

  union StorageUnion {
    base::AlignedMemory<sizeof(T1), ALIGNOF(T1)> t1;
    base::AlignedMemory<sizeof(T2), ALIGNOF(T2)> t2;
    base::AlignedMemory<sizeof(T3), ALIGNOF(T3)> t3;
  };

  void ConstructFromOther(const UnionType3& other) {
    specific_type_ = other.specific_type_;
    switch (specific_type_) {
      case kTypeT1:
        new (storage_.void_data()) T1(other.AsType<T1>());
        break;
      case kTypeT2:
        new (storage_.void_data()) T2(other.AsType<T2>());
        break;
      case kTypeT3:
        new (storage_.void_data()) T3(other.AsType<T3>());
        break;
      case kUnspecified:
        // no-op
        break;
    }
  }

  void Destruct() {
    switch (specific_type_) {
      case kTypeT1:
        storage_.template data_as<T1>()->T1::~T1();
        break;
      case kTypeT2:
        storage_.template data_as<T2>()->T2::~T2();
        break;
      case kTypeT3:
        storage_.template data_as<T3>()->T3::~T3();
        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 =
      (internal::UnionTypeTraits<T1>::is_numeric_type ? 1 : 0) +
      (internal::UnionTypeTraits<T2>::is_numeric_type ? 1 : 0) +
      (internal::UnionTypeTraits<T3>::is_numeric_type ? 1 : 0);
  COMPILE_ASSERT(kNumNumericTypes <= 1, AmbiguousUnionTypeConversion);
};

// Needed to instantiate base::optional<UnionTypeN>
template <typename T1, typename T2, typename T3>
inline std::ostream& operator<<(
    std::ostream& stream, const UnionType3<T1, T2, T3>& union_value) {

  if (union_value.template IsType<T1>()) {
    stream << union_value.template AsType<T1>();
  } else if (union_value.template IsType<T2>()) {
    stream << union_value.template AsType<T2>();
  } else if (union_value.template IsType<T3>()) {
    stream << union_value.template AsType<T3>();
  } else {
    stream << "Undefined union type.";
  }

  return stream;
}


template <typename T1, typename T2, typename T3, typename T4>
class UnionType4 {
 public:
  UnionType4() : specific_type_(kUnspecified) {}

  explicit UnionType4(typename internal::UnionTypeTraits<T1>::ArgType arg)
      : specific_type_(kTypeT1) {
    new (storage_.void_data()) T1(arg);
  }
  explicit UnionType4(typename internal::UnionTypeTraits<T2>::ArgType arg)
      : specific_type_(kTypeT2) {
    new (storage_.void_data()) T2(arg);
  }
  explicit UnionType4(typename internal::UnionTypeTraits<T3>::ArgType arg)
      : specific_type_(kTypeT3) {
    new (storage_.void_data()) T3(arg);
  }
  explicit UnionType4(typename internal::UnionTypeTraits<T4>::ArgType arg)
      : specific_type_(kTypeT4) {
    new (storage_.void_data()) T4(arg);
  }

  UnionType4(const UnionType4& other) {
    ConstructFromOther(other);
  }

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

  ~UnionType4() {
    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.
  template <bool dummy>
  class UnionTypeCheck<T1, dummy> {
    static bool IsType(const UnionType4<T1, T2, T3, T4>* union_value) {
      return union_value->specific_type_ == kTypeT1;
    }
    static typename internal::UnionTypeTraits<T1>::ReturnType
        AsType(UnionType4<T1, T2, T3, T4>* union_value) {
      return *(union_value->storage_.template data_as<T1>());
    }
    static typename internal::UnionTypeTraits<T1>::ConstReturnType
        AsType(const UnionType4<T1, T2, T3, T4>* union_value) {
      return *(union_value->storage_.template data_as<T1>());
    }
    friend class UnionType4<T1, T2, T3, T4>;
  };

  template <bool dummy>
  class UnionTypeCheck<T2, dummy> {
    static bool IsType(const UnionType4<T1, T2, T3, T4>* union_value) {
      return union_value->specific_type_ == kTypeT2;
    }
    static typename internal::UnionTypeTraits<T2>::ReturnType
        AsType(UnionType4<T1, T2, T3, T4>* union_value) {
      return *(union_value->storage_.template data_as<T2>());
    }
    static typename internal::UnionTypeTraits<T2>::ConstReturnType
        AsType(const UnionType4<T1, T2, T3, T4>* union_value) {
      return *(union_value->storage_.template data_as<T2>());
    }
    friend class UnionType4<T1, T2, T3, T4>;
  };

  template <bool dummy>
  class UnionTypeCheck<T3, dummy> {
    static bool IsType(const UnionType4<T1, T2, T3, T4>* union_value) {
      return union_value->specific_type_ == kTypeT3;
    }
    static typename internal::UnionTypeTraits<T3>::ReturnType
        AsType(UnionType4<T1, T2, T3, T4>* union_value) {
      return *(union_value->storage_.template data_as<T3>());
    }
    static typename internal::UnionTypeTraits<T3>::ConstReturnType
        AsType(const UnionType4<T1, T2, T3, T4>* union_value) {
      return *(union_value->storage_.template data_as<T3>());
    }
    friend class UnionType4<T1, T2, T3, T4>;
  };

  template <bool dummy>
  class UnionTypeCheck<T4, dummy> {
    static bool IsType(const UnionType4<T1, T2, T3, T4>* union_value) {
      return union_value->specific_type_ == kTypeT4;
    }
    static typename internal::UnionTypeTraits<T4>::ReturnType
        AsType(UnionType4<T1, T2, T3, T4>* union_value) {
      return *(union_value->storage_.template data_as<T4>());
    }
    static typename internal::UnionTypeTraits<T4>::ConstReturnType
        AsType(const UnionType4<T1, T2, T3, T4>* union_value) {
      return *(union_value->storage_.template data_as<T4>());
    }
    friend class UnionType4<T1, T2, T3, T4>;
  };

  enum SpecificType {
    kUnspecified = 0,
    kTypeT1,
    kTypeT2,
    kTypeT3,
    kTypeT4,
  };

  union StorageUnion {
    base::AlignedMemory<sizeof(T1), ALIGNOF(T1)> t1;
    base::AlignedMemory<sizeof(T2), ALIGNOF(T2)> t2;
    base::AlignedMemory<sizeof(T3), ALIGNOF(T3)> t3;
    base::AlignedMemory<sizeof(T4), ALIGNOF(T4)> t4;
  };

  void ConstructFromOther(const UnionType4& other) {
    specific_type_ = other.specific_type_;
    switch (specific_type_) {
      case kTypeT1:
        new (storage_.void_data()) T1(other.AsType<T1>());
        break;
      case kTypeT2:
        new (storage_.void_data()) T2(other.AsType<T2>());
        break;
      case kTypeT3:
        new (storage_.void_data()) T3(other.AsType<T3>());
        break;
      case kTypeT4:
        new (storage_.void_data()) T4(other.AsType<T4>());
        break;
      case kUnspecified:
        // no-op
        break;
    }
  }

  void Destruct() {
    switch (specific_type_) {
      case kTypeT1:
        storage_.template data_as<T1>()->T1::~T1();
        break;
      case kTypeT2:
        storage_.template data_as<T2>()->T2::~T2();
        break;
      case kTypeT3:
        storage_.template data_as<T3>()->T3::~T3();
        break;
      case kTypeT4:
        storage_.template data_as<T4>()->T4::~T4();
        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 =
      (internal::UnionTypeTraits<T1>::is_numeric_type ? 1 : 0) +
      (internal::UnionTypeTraits<T2>::is_numeric_type ? 1 : 0) +
      (internal::UnionTypeTraits<T3>::is_numeric_type ? 1 : 0) +
      (internal::UnionTypeTraits<T4>::is_numeric_type ? 1 : 0);
  COMPILE_ASSERT(kNumNumericTypes <= 1, AmbiguousUnionTypeConversion);
};

// Needed to instantiate base::optional<UnionTypeN>
template <typename T1, typename T2, typename T3, typename T4>
inline std::ostream& operator<<(
    std::ostream& stream, const UnionType4<T1, T2, T3, T4>& union_value) {

  if (union_value.template IsType<T1>()) {
    stream << union_value.template AsType<T1>();
  } else if (union_value.template IsType<T2>()) {
    stream << union_value.template AsType<T2>();
  } else if (union_value.template IsType<T3>()) {
    stream << union_value.template AsType<T3>();
  } else if (union_value.template IsType<T4>()) {
    stream << union_value.template AsType<T4>();
  } else {
    stream << "Undefined union type.";
  }

  return stream;
}

}  // namespace script
}  // namespace cobalt

#endif  // COBALT_SCRIPT_UNION_TYPE_H_
