// Copyright (c) 2020 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=c833c2d3e1fe4bcae98906f85e6f5751c17c267a$
//

#include "libcef_dll/cpptoc/test/translator_test_scoped_library_child_child_cpptoc.h"

// GLOBAL FUNCTIONS - Body may be edited by hand.

CEF_EXPORT cef_translator_test_scoped_library_child_child_t*
cef_translator_test_scoped_library_child_child_create(int value,
                                                      int other_value,
                                                      int other_other_value) {
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  CefOwnPtr<CefTranslatorTestScopedLibraryChildChild> _retval =
      CefTranslatorTestScopedLibraryChildChild::Create(value, other_value,
                                                       other_other_value);

  // Return type: ownptr_same
  return CefTranslatorTestScopedLibraryChildChildCppToC::WrapOwn(
      OWN_PASS(_retval));
}

namespace {

// MEMBER FUNCTIONS - Body may be edited by hand.

int CEF_CALLBACK
translator_test_scoped_library_child_child_get_other_other_value(
    struct _cef_translator_test_scoped_library_child_child_t* self) {
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  DCHECK(self);
  if (!self)
    return 0;

  // Execute
  int _retval = CefTranslatorTestScopedLibraryChildChildCppToC::Get(self)
                    ->GetOtherOtherValue();

  // Return type: simple
  return _retval;
}

void CEF_CALLBACK
translator_test_scoped_library_child_child_set_other_other_value(
    struct _cef_translator_test_scoped_library_child_child_t* self,
    int value) {
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  DCHECK(self);
  if (!self)
    return;

  // Execute
  CefTranslatorTestScopedLibraryChildChildCppToC::Get(self)->SetOtherOtherValue(
      value);
}

int CEF_CALLBACK translator_test_scoped_library_child_child_get_other_value(
    struct _cef_translator_test_scoped_library_child_t* self) {
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  DCHECK(self);
  if (!self)
    return 0;

  // Execute
  int _retval =
      CefTranslatorTestScopedLibraryChildChildCppToC::Get(
          reinterpret_cast<cef_translator_test_scoped_library_child_child_t*>(
              self))
          ->GetOtherValue();

  // Return type: simple
  return _retval;
}

void CEF_CALLBACK translator_test_scoped_library_child_child_set_other_value(
    struct _cef_translator_test_scoped_library_child_t* self,
    int value) {
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  DCHECK(self);
  if (!self)
    return;

  // Execute
  CefTranslatorTestScopedLibraryChildChildCppToC::Get(
      reinterpret_cast<cef_translator_test_scoped_library_child_child_t*>(self))
      ->SetOtherValue(value);
}

int CEF_CALLBACK translator_test_scoped_library_child_child_get_value(
    struct _cef_translator_test_scoped_library_t* self) {
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  DCHECK(self);
  if (!self)
    return 0;

  // Execute
  int _retval =
      CefTranslatorTestScopedLibraryChildChildCppToC::Get(
          reinterpret_cast<cef_translator_test_scoped_library_child_child_t*>(
              self))
          ->GetValue();

  // Return type: simple
  return _retval;
}

void CEF_CALLBACK translator_test_scoped_library_child_child_set_value(
    struct _cef_translator_test_scoped_library_t* self,
    int value) {
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  DCHECK(self);
  if (!self)
    return;

  // Execute
  CefTranslatorTestScopedLibraryChildChildCppToC::Get(
      reinterpret_cast<cef_translator_test_scoped_library_child_child_t*>(self))
      ->SetValue(value);
}

}  // namespace

// CONSTRUCTOR - Do not edit by hand.

CefTranslatorTestScopedLibraryChildChildCppToC::
    CefTranslatorTestScopedLibraryChildChildCppToC() {
  GetStruct()->get_other_other_value =
      translator_test_scoped_library_child_child_get_other_other_value;
  GetStruct()->set_other_other_value =
      translator_test_scoped_library_child_child_set_other_other_value;
  GetStruct()->base.get_other_value =
      translator_test_scoped_library_child_child_get_other_value;
  GetStruct()->base.set_other_value =
      translator_test_scoped_library_child_child_set_other_value;
  GetStruct()->base.base.get_value =
      translator_test_scoped_library_child_child_get_value;
  GetStruct()->base.base.set_value =
      translator_test_scoped_library_child_child_set_value;
}

// DESTRUCTOR - Do not edit by hand.

CefTranslatorTestScopedLibraryChildChildCppToC::
    ~CefTranslatorTestScopedLibraryChildChildCppToC() {}

template <>
CefOwnPtr<CefTranslatorTestScopedLibraryChildChild>
CefCppToCScoped<CefTranslatorTestScopedLibraryChildChildCppToC,
                CefTranslatorTestScopedLibraryChildChild,
                cef_translator_test_scoped_library_child_child_t>::
    UnwrapDerivedOwn(CefWrapperType type,
                     cef_translator_test_scoped_library_child_child_t* s) {
  NOTREACHED() << "Unexpected class type: " << type;
  return CefOwnPtr<CefTranslatorTestScopedLibraryChildChild>();
}

template <>
CefRawPtr<CefTranslatorTestScopedLibraryChildChild>
CefCppToCScoped<CefTranslatorTestScopedLibraryChildChildCppToC,
                CefTranslatorTestScopedLibraryChildChild,
                cef_translator_test_scoped_library_child_child_t>::
    UnwrapDerivedRaw(CefWrapperType type,
                     cef_translator_test_scoped_library_child_child_t* s) {
  NOTREACHED() << "Unexpected class type: " << type;
  return nullptr;
}

template <>
CefWrapperType CefCppToCScoped<
    CefTranslatorTestScopedLibraryChildChildCppToC,
    CefTranslatorTestScopedLibraryChildChild,
    cef_translator_test_scoped_library_child_child_t>::kWrapperType =
    WT_TRANSLATOR_TEST_SCOPED_LIBRARY_CHILD_CHILD;
