// 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=4ccc62b0449038044535576aed814a925db93432$
//

#include "libcef_dll/ctocpp/test/translator_test_ctocpp.h"
#include <algorithm>
#include "libcef_dll/cpptoc/test/translator_test_ref_ptr_client_child_cpptoc.h"
#include "libcef_dll/cpptoc/test/translator_test_ref_ptr_client_cpptoc.h"
#include "libcef_dll/cpptoc/test/translator_test_scoped_client_child_cpptoc.h"
#include "libcef_dll/cpptoc/test/translator_test_scoped_client_cpptoc.h"
#include "libcef_dll/ctocpp/test/translator_test_ref_ptr_library_child_ctocpp.h"
#include "libcef_dll/ctocpp/test/translator_test_ref_ptr_library_ctocpp.h"
#include "libcef_dll/ctocpp/test/translator_test_scoped_library_child_ctocpp.h"
#include "libcef_dll/ctocpp/test/translator_test_scoped_library_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
#include "libcef_dll/transfer_util.h"

// STATIC METHODS - Body may be edited by hand.

NO_SANITIZE("cfi-icall")
CefRefPtr<CefTranslatorTest> CefTranslatorTest::Create() {
  shutdown_checker::AssertNotShutdown();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  cef_translator_test_t* _retval = cef_translator_test_create();

  // Return type: refptr_same
  return CefTranslatorTestCToCpp::Wrap(_retval);
}

// VIRTUAL METHODS - Body may be edited by hand.

NO_SANITIZE("cfi-icall") void CefTranslatorTestCToCpp::GetVoid() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_void))
    return;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  _struct->get_void(_struct);
}

NO_SANITIZE("cfi-icall") bool CefTranslatorTestCToCpp::GetBool() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_bool))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  int _retval = _struct->get_bool(_struct);

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall") int CefTranslatorTestCToCpp::GetInt() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_int))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  int _retval = _struct->get_int(_struct);

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall") double CefTranslatorTestCToCpp::GetDouble() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_double))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  double _retval = _struct->get_double(_struct);

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall") long CefTranslatorTestCToCpp::GetLong() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_long))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  long _retval = _struct->get_long(_struct);

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall") size_t CefTranslatorTestCToCpp::GetSizet() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_sizet))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  size_t _retval = _struct->get_sizet(_struct);

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall") bool CefTranslatorTestCToCpp::SetVoid() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_void))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  int _retval = _struct->set_void(_struct);

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall") bool CefTranslatorTestCToCpp::SetBool(bool val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_bool))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  int _retval = _struct->set_bool(_struct, val);

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall") bool CefTranslatorTestCToCpp::SetInt(int val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_int))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  int _retval = _struct->set_int(_struct, val);

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall") bool CefTranslatorTestCToCpp::SetDouble(double val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_double))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  int _retval = _struct->set_double(_struct, val);

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall") bool CefTranslatorTestCToCpp::SetLong(long val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_long))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  int _retval = _struct->set_long(_struct, val);

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall") bool CefTranslatorTestCToCpp::SetSizet(size_t val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_sizet))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  int _retval = _struct->set_sizet(_struct, val);

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::SetIntList(const std::vector<int>& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_int_list))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: simple_vec_byref_const
  const size_t valCount = val.size();
  int* valList = NULL;
  if (valCount > 0) {
    valList = new int[valCount];
    DCHECK(valList);
    if (valList) {
      for (size_t i = 0; i < valCount; ++i) {
        valList[i] = val[i];
      }
    }
  }

  // Execute
  int _retval = _struct->set_int_list(_struct, valCount, valList);

  // Restore param:val; type: simple_vec_byref_const
  if (valList)
    delete[] valList;

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::GetIntListByRef(IntList& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_int_list_by_ref))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: simple_vec_byref
  size_t valSize = val.size();
  size_t valCount = std::max(GetIntListSize(), valSize);
  int* valList = NULL;
  if (valCount > 0) {
    valList = new int[valCount];
    DCHECK(valList);
    if (valList) {
      memset(valList, 0, sizeof(int) * valCount);
    }
    if (valList && valSize > 0) {
      for (size_t i = 0; i < valSize; ++i) {
        valList[i] = val[i];
      }
    }
  }

  // Execute
  int _retval = _struct->get_int_list_by_ref(_struct, &valCount, valList);

  // Restore param:val; type: simple_vec_byref
  val.clear();
  if (valCount > 0 && valList) {
    for (size_t i = 0; i < valCount; ++i) {
      val.push_back(valList[i]);
    }
    delete[] valList;
  }

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall") size_t CefTranslatorTestCToCpp::GetIntListSize() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_int_list_size))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  size_t _retval = _struct->get_int_list_size(_struct);

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall") CefString CefTranslatorTestCToCpp::GetString() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_string))
    return CefString();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  cef_string_userfree_t _retval = _struct->get_string(_struct);

  // Return type: string
  CefString _retvalStr;
  _retvalStr.AttachToUserFree(_retval);
  return _retvalStr;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::SetString(const CefString& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_string))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: string_byref_const
  DCHECK(!val.empty());
  if (val.empty())
    return false;

  // Execute
  int _retval = _struct->set_string(_struct, val.GetStruct());

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
void CefTranslatorTestCToCpp::GetStringByRef(CefString& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_string_by_ref))
    return;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  _struct->get_string_by_ref(_struct, val.GetWritableStruct());
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::SetStringList(const std::vector<CefString>& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_string_list))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: string_vec_byref_const
  cef_string_list_t valList = cef_string_list_alloc();
  DCHECK(valList);
  if (valList)
    transfer_string_list_contents(val, valList);

  // Execute
  int _retval = _struct->set_string_list(_struct, valList);

  // Restore param:val; type: string_vec_byref_const
  if (valList)
    cef_string_list_free(valList);

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::GetStringListByRef(StringList& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_string_list_by_ref))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: string_vec_byref
  cef_string_list_t valList = cef_string_list_alloc();
  DCHECK(valList);
  if (valList)
    transfer_string_list_contents(val, valList);

  // Execute
  int _retval = _struct->get_string_list_by_ref(_struct, valList);

  // Restore param:val; type: string_vec_byref
  if (valList) {
    val.clear();
    transfer_string_list_contents(valList, val);
    cef_string_list_free(valList);
  }

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::SetStringMap(const StringMap& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_string_map))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: string_map_single_byref_const
  cef_string_map_t valMap = cef_string_map_alloc();
  DCHECK(valMap);
  if (valMap)
    transfer_string_map_contents(val, valMap);

  // Execute
  int _retval = _struct->set_string_map(_struct, valMap);

  // Restore param:val; type: string_map_single_byref_const
  if (valMap)
    cef_string_map_free(valMap);

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::GetStringMapByRef(
    std::map<CefString, CefString>& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_string_map_by_ref))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: string_map_single_byref
  cef_string_map_t valMap = cef_string_map_alloc();
  DCHECK(valMap);
  if (valMap)
    transfer_string_map_contents(val, valMap);

  // Execute
  int _retval = _struct->get_string_map_by_ref(_struct, valMap);

  // Restore param:val; type: string_map_single_byref
  if (valMap) {
    val.clear();
    transfer_string_map_contents(valMap, val);
    cef_string_map_free(valMap);
  }

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::SetStringMultimap(
    const std::multimap<CefString, CefString>& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_string_multimap))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: string_map_multi_byref_const
  cef_string_multimap_t valMultimap = cef_string_multimap_alloc();
  DCHECK(valMultimap);
  if (valMultimap)
    transfer_string_multimap_contents(val, valMultimap);

  // Execute
  int _retval = _struct->set_string_multimap(_struct, valMultimap);

  // Restore param:val; type: string_map_multi_byref_const
  if (valMultimap)
    cef_string_multimap_free(valMultimap);

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::GetStringMultimapByRef(StringMultimap& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_string_multimap_by_ref))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: string_map_multi_byref
  cef_string_multimap_t valMultimap = cef_string_multimap_alloc();
  DCHECK(valMultimap);
  if (valMultimap)
    transfer_string_multimap_contents(val, valMultimap);

  // Execute
  int _retval = _struct->get_string_multimap_by_ref(_struct, valMultimap);

  // Restore param:val; type: string_map_multi_byref
  if (valMultimap) {
    val.clear();
    transfer_string_multimap_contents(valMultimap, val);
    cef_string_multimap_free(valMultimap);
  }

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall") CefPoint CefTranslatorTestCToCpp::GetPoint() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_point))
    return CefPoint();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  cef_point_t _retval = _struct->get_point(_struct);

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::SetPoint(const CefPoint& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_point))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  int _retval = _struct->set_point(_struct, &val);

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
void CefTranslatorTestCToCpp::GetPointByRef(CefPoint& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_point_by_ref))
    return;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  _struct->get_point_by_ref(_struct, &val);
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::SetPointList(const std::vector<CefPoint>& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_point_list))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: simple_vec_byref_const
  const size_t valCount = val.size();
  cef_point_t* valList = NULL;
  if (valCount > 0) {
    valList = new cef_point_t[valCount];
    DCHECK(valList);
    if (valList) {
      for (size_t i = 0; i < valCount; ++i) {
        valList[i] = val[i];
      }
    }
  }

  // Execute
  int _retval = _struct->set_point_list(_struct, valCount, valList);

  // Restore param:val; type: simple_vec_byref_const
  if (valList)
    delete[] valList;

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::GetPointListByRef(PointList& val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_point_list_by_ref))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: simple_vec_byref
  size_t valSize = val.size();
  size_t valCount = std::max(GetPointListSize(), valSize);
  cef_point_t* valList = NULL;
  if (valCount > 0) {
    valList = new cef_point_t[valCount];
    DCHECK(valList);
    if (valList) {
      memset(valList, 0, sizeof(cef_point_t) * valCount);
    }
    if (valList && valSize > 0) {
      for (size_t i = 0; i < valSize; ++i) {
        valList[i] = val[i];
      }
    }
  }

  // Execute
  int _retval = _struct->get_point_list_by_ref(_struct, &valCount, valList);

  // Restore param:val; type: simple_vec_byref
  val.clear();
  if (valCount > 0 && valList) {
    for (size_t i = 0; i < valCount; ++i) {
      val.push_back(valList[i]);
    }
    delete[] valList;
  }

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall") size_t CefTranslatorTestCToCpp::GetPointListSize() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_point_list_size))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  size_t _retval = _struct->get_point_list_size(_struct);

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
CefRefPtr<CefTranslatorTestRefPtrLibrary>
CefTranslatorTestCToCpp::GetRefPtrLibrary(int val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_ref_ptr_library))
    return nullptr;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  cef_translator_test_ref_ptr_library_t* _retval =
      _struct->get_ref_ptr_library(_struct, val);

  // Return type: refptr_same
  return CefTranslatorTestRefPtrLibraryCToCpp::Wrap(_retval);
}

NO_SANITIZE("cfi-icall")
int CefTranslatorTestCToCpp::SetRefPtrLibrary(
    CefRefPtr<CefTranslatorTestRefPtrLibrary> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_ref_ptr_library))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: refptr_same
  DCHECK(val.get());
  if (!val.get())
    return 0;

  // Execute
  int _retval = _struct->set_ref_ptr_library(
      _struct, CefTranslatorTestRefPtrLibraryCToCpp::Unwrap(val));

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
CefRefPtr<CefTranslatorTestRefPtrLibrary>
CefTranslatorTestCToCpp::SetRefPtrLibraryAndReturn(
    CefRefPtr<CefTranslatorTestRefPtrLibrary> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_ref_ptr_library_and_return))
    return nullptr;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: refptr_same
  DCHECK(val.get());
  if (!val.get())
    return nullptr;

  // Execute
  cef_translator_test_ref_ptr_library_t* _retval =
      _struct->set_ref_ptr_library_and_return(
          _struct, CefTranslatorTestRefPtrLibraryCToCpp::Unwrap(val));

  // Return type: refptr_same
  return CefTranslatorTestRefPtrLibraryCToCpp::Wrap(_retval);
}

NO_SANITIZE("cfi-icall")
int CefTranslatorTestCToCpp::SetChildRefPtrLibrary(
    CefRefPtr<CefTranslatorTestRefPtrLibraryChild> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_child_ref_ptr_library))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: refptr_same
  DCHECK(val.get());
  if (!val.get())
    return 0;

  // Execute
  int _retval = _struct->set_child_ref_ptr_library(
      _struct, CefTranslatorTestRefPtrLibraryChildCToCpp::Unwrap(val));

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
CefRefPtr<CefTranslatorTestRefPtrLibrary>
CefTranslatorTestCToCpp::SetChildRefPtrLibraryAndReturnParent(
    CefRefPtr<CefTranslatorTestRefPtrLibraryChild> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_child_ref_ptr_library_and_return_parent))
    return nullptr;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: refptr_same
  DCHECK(val.get());
  if (!val.get())
    return nullptr;

  // Execute
  cef_translator_test_ref_ptr_library_t* _retval =
      _struct->set_child_ref_ptr_library_and_return_parent(
          _struct, CefTranslatorTestRefPtrLibraryChildCToCpp::Unwrap(val));

  // Return type: refptr_same
  return CefTranslatorTestRefPtrLibraryCToCpp::Wrap(_retval);
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::SetRefPtrLibraryList(
    const std::vector<CefRefPtr<CefTranslatorTestRefPtrLibrary>>& val,
    int val1,
    int val2) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_ref_ptr_library_list))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: refptr_vec_same_byref_const
  const size_t valCount = val.size();
  cef_translator_test_ref_ptr_library_t** valList = NULL;
  if (valCount > 0) {
    valList = new cef_translator_test_ref_ptr_library_t*[valCount];
    DCHECK(valList);
    if (valList) {
      for (size_t i = 0; i < valCount; ++i) {
        valList[i] = CefTranslatorTestRefPtrLibraryCToCpp::Unwrap(val[i]);
      }
    }
  }

  // Execute
  int _retval =
      _struct->set_ref_ptr_library_list(_struct, valCount, valList, val1, val2);

  // Restore param:val; type: refptr_vec_same_byref_const
  if (valList)
    delete[] valList;

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::GetRefPtrLibraryListByRef(RefPtrLibraryList& val,
                                                        int val1,
                                                        int val2) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_ref_ptr_library_list_by_ref))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: refptr_vec_same_byref
  size_t valSize = val.size();
  size_t valCount = std::max(GetRefPtrLibraryListSize(), valSize);
  cef_translator_test_ref_ptr_library_t** valList = NULL;
  if (valCount > 0) {
    valList = new cef_translator_test_ref_ptr_library_t*[valCount];
    DCHECK(valList);
    if (valList) {
      memset(valList, 0,
             sizeof(cef_translator_test_ref_ptr_library_t*) * valCount);
    }
    if (valList && valSize > 0) {
      for (size_t i = 0; i < valSize; ++i) {
        valList[i] = CefTranslatorTestRefPtrLibraryCToCpp::Unwrap(val[i]);
      }
    }
  }

  // Execute
  int _retval = _struct->get_ref_ptr_library_list_by_ref(_struct, &valCount,
                                                         valList, val1, val2);

  // Restore param:val; type: refptr_vec_same_byref
  val.clear();
  if (valCount > 0 && valList) {
    for (size_t i = 0; i < valCount; ++i) {
      val.push_back(CefTranslatorTestRefPtrLibraryCToCpp::Wrap(valList[i]));
    }
    delete[] valList;
  }

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
size_t CefTranslatorTestCToCpp::GetRefPtrLibraryListSize() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_ref_ptr_library_list_size))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  size_t _retval = _struct->get_ref_ptr_library_list_size(_struct);

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
int CefTranslatorTestCToCpp::SetRefPtrClient(
    CefRefPtr<CefTranslatorTestRefPtrClient> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_ref_ptr_client))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: refptr_diff
  DCHECK(val.get());
  if (!val.get())
    return 0;

  // Execute
  int _retval = _struct->set_ref_ptr_client(
      _struct, CefTranslatorTestRefPtrClientCppToC::Wrap(val));

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
CefRefPtr<CefTranslatorTestRefPtrClient>
CefTranslatorTestCToCpp::SetRefPtrClientAndReturn(
    CefRefPtr<CefTranslatorTestRefPtrClient> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_ref_ptr_client_and_return))
    return nullptr;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: refptr_diff
  DCHECK(val.get());
  if (!val.get())
    return nullptr;

  // Execute
  cef_translator_test_ref_ptr_client_t* _retval =
      _struct->set_ref_ptr_client_and_return(
          _struct, CefTranslatorTestRefPtrClientCppToC::Wrap(val));

  // Return type: refptr_diff
  return CefTranslatorTestRefPtrClientCppToC::Unwrap(_retval);
}

NO_SANITIZE("cfi-icall")
int CefTranslatorTestCToCpp::SetChildRefPtrClient(
    CefRefPtr<CefTranslatorTestRefPtrClientChild> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_child_ref_ptr_client))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: refptr_diff
  DCHECK(val.get());
  if (!val.get())
    return 0;

  // Execute
  int _retval = _struct->set_child_ref_ptr_client(
      _struct, CefTranslatorTestRefPtrClientChildCppToC::Wrap(val));

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
CefRefPtr<CefTranslatorTestRefPtrClient>
CefTranslatorTestCToCpp::SetChildRefPtrClientAndReturnParent(
    CefRefPtr<CefTranslatorTestRefPtrClientChild> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_child_ref_ptr_client_and_return_parent))
    return nullptr;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: refptr_diff
  DCHECK(val.get());
  if (!val.get())
    return nullptr;

  // Execute
  cef_translator_test_ref_ptr_client_t* _retval =
      _struct->set_child_ref_ptr_client_and_return_parent(
          _struct, CefTranslatorTestRefPtrClientChildCppToC::Wrap(val));

  // Return type: refptr_diff
  return CefTranslatorTestRefPtrClientCppToC::Unwrap(_retval);
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::SetRefPtrClientList(
    const std::vector<CefRefPtr<CefTranslatorTestRefPtrClient>>& val,
    int val1,
    int val2) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_ref_ptr_client_list))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: refptr_vec_diff_byref_const
  const size_t valCount = val.size();
  cef_translator_test_ref_ptr_client_t** valList = NULL;
  if (valCount > 0) {
    valList = new cef_translator_test_ref_ptr_client_t*[valCount];
    DCHECK(valList);
    if (valList) {
      for (size_t i = 0; i < valCount; ++i) {
        valList[i] = CefTranslatorTestRefPtrClientCppToC::Wrap(val[i]);
      }
    }
  }

  // Execute
  int _retval =
      _struct->set_ref_ptr_client_list(_struct, valCount, valList, val1, val2);

  // Restore param:val; type: refptr_vec_diff_byref_const
  if (valList)
    delete[] valList;

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::GetRefPtrClientListByRef(
    RefPtrClientList& val,
    CefRefPtr<CefTranslatorTestRefPtrClient> val1,
    CefRefPtr<CefTranslatorTestRefPtrClient> val2) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_ref_ptr_client_list_by_ref))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val1; type: refptr_diff
  DCHECK(val1.get());
  if (!val1.get())
    return false;
  // Verify param: val2; type: refptr_diff
  DCHECK(val2.get());
  if (!val2.get())
    return false;

  // Translate param: val; type: refptr_vec_diff_byref
  size_t valSize = val.size();
  size_t valCount = std::max(GetRefPtrLibraryListSize(), valSize);
  cef_translator_test_ref_ptr_client_t** valList = NULL;
  if (valCount > 0) {
    valList = new cef_translator_test_ref_ptr_client_t*[valCount];
    DCHECK(valList);
    if (valList) {
      memset(valList, 0,
             sizeof(cef_translator_test_ref_ptr_client_t*) * valCount);
    }
    if (valList && valSize > 0) {
      for (size_t i = 0; i < valSize; ++i) {
        valList[i] = CefTranslatorTestRefPtrClientCppToC::Wrap(val[i]);
      }
    }
  }

  // Execute
  int _retval = _struct->get_ref_ptr_client_list_by_ref(
      _struct, &valCount, valList,
      CefTranslatorTestRefPtrClientCppToC::Wrap(val1),
      CefTranslatorTestRefPtrClientCppToC::Wrap(val2));

  // Restore param:val; type: refptr_vec_diff_byref
  val.clear();
  if (valCount > 0 && valList) {
    for (size_t i = 0; i < valCount; ++i) {
      val.push_back(CefTranslatorTestRefPtrClientCppToC::Unwrap(valList[i]));
    }
    delete[] valList;
  }

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
size_t CefTranslatorTestCToCpp::GetRefPtrClientListSize() {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_ref_ptr_client_list_size))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  size_t _retval = _struct->get_ref_ptr_client_list_size(_struct);

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
CefOwnPtr<CefTranslatorTestScopedLibrary>
CefTranslatorTestCToCpp::GetOwnPtrLibrary(int val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, get_own_ptr_library))
    return CefOwnPtr<CefTranslatorTestScopedLibrary>();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  cef_translator_test_scoped_library_t* _retval =
      _struct->get_own_ptr_library(_struct, val);

  // Return type: ownptr_same
  return CefTranslatorTestScopedLibraryCToCpp::Wrap(_retval);
}

NO_SANITIZE("cfi-icall")
int CefTranslatorTestCToCpp::SetOwnPtrLibrary(
    CefOwnPtr<CefTranslatorTestScopedLibrary> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_own_ptr_library))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: ownptr_same
  DCHECK(val.get());
  if (!val.get())
    return 0;

  // Execute
  int _retval = _struct->set_own_ptr_library(
      _struct, CefTranslatorTestScopedLibraryCToCpp::UnwrapOwn(OWN_PASS(val)));

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
CefOwnPtr<CefTranslatorTestScopedLibrary>
CefTranslatorTestCToCpp::SetOwnPtrLibraryAndReturn(
    CefOwnPtr<CefTranslatorTestScopedLibrary> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_own_ptr_library_and_return))
    return CefOwnPtr<CefTranslatorTestScopedLibrary>();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: ownptr_same
  DCHECK(val.get());
  if (!val.get())
    return CefOwnPtr<CefTranslatorTestScopedLibrary>();

  // Execute
  cef_translator_test_scoped_library_t* _retval =
      _struct->set_own_ptr_library_and_return(
          _struct,
          CefTranslatorTestScopedLibraryCToCpp::UnwrapOwn(OWN_PASS(val)));

  // Return type: ownptr_same
  return CefTranslatorTestScopedLibraryCToCpp::Wrap(_retval);
}

NO_SANITIZE("cfi-icall")
int CefTranslatorTestCToCpp::SetChildOwnPtrLibrary(
    CefOwnPtr<CefTranslatorTestScopedLibraryChild> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_child_own_ptr_library))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: ownptr_same
  DCHECK(val.get());
  if (!val.get())
    return 0;

  // Execute
  int _retval = _struct->set_child_own_ptr_library(
      _struct,
      CefTranslatorTestScopedLibraryChildCToCpp::UnwrapOwn(OWN_PASS(val)));

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
CefOwnPtr<CefTranslatorTestScopedLibrary>
CefTranslatorTestCToCpp::SetChildOwnPtrLibraryAndReturnParent(
    CefOwnPtr<CefTranslatorTestScopedLibraryChild> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_child_own_ptr_library_and_return_parent))
    return CefOwnPtr<CefTranslatorTestScopedLibrary>();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: ownptr_same
  DCHECK(val.get());
  if (!val.get())
    return CefOwnPtr<CefTranslatorTestScopedLibrary>();

  // Execute
  cef_translator_test_scoped_library_t* _retval =
      _struct->set_child_own_ptr_library_and_return_parent(
          _struct,
          CefTranslatorTestScopedLibraryChildCToCpp::UnwrapOwn(OWN_PASS(val)));

  // Return type: ownptr_same
  return CefTranslatorTestScopedLibraryCToCpp::Wrap(_retval);
}

NO_SANITIZE("cfi-icall")
int CefTranslatorTestCToCpp::SetOwnPtrClient(
    CefOwnPtr<CefTranslatorTestScopedClient> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_own_ptr_client))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: ownptr_diff
  DCHECK(val.get());
  if (!val.get())
    return 0;

  // Execute
  int _retval = _struct->set_own_ptr_client(
      _struct, CefTranslatorTestScopedClientCppToC::WrapOwn(OWN_PASS(val)));

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
CefOwnPtr<CefTranslatorTestScopedClient>
CefTranslatorTestCToCpp::SetOwnPtrClientAndReturn(
    CefOwnPtr<CefTranslatorTestScopedClient> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_own_ptr_client_and_return))
    return CefOwnPtr<CefTranslatorTestScopedClient>();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: ownptr_diff
  DCHECK(val.get());
  if (!val.get())
    return CefOwnPtr<CefTranslatorTestScopedClient>();

  // Execute
  cef_translator_test_scoped_client_t* _retval =
      _struct->set_own_ptr_client_and_return(
          _struct, CefTranslatorTestScopedClientCppToC::WrapOwn(OWN_PASS(val)));

  // Return type: ownptr_diff
  return CefTranslatorTestScopedClientCppToC::UnwrapOwn(_retval);
}

NO_SANITIZE("cfi-icall")
int CefTranslatorTestCToCpp::SetChildOwnPtrClient(
    CefOwnPtr<CefTranslatorTestScopedClientChild> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_child_own_ptr_client))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: ownptr_diff
  DCHECK(val.get());
  if (!val.get())
    return 0;

  // Execute
  int _retval = _struct->set_child_own_ptr_client(
      _struct,
      CefTranslatorTestScopedClientChildCppToC::WrapOwn(OWN_PASS(val)));

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
CefOwnPtr<CefTranslatorTestScopedClient>
CefTranslatorTestCToCpp::SetChildOwnPtrClientAndReturnParent(
    CefOwnPtr<CefTranslatorTestScopedClientChild> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_child_own_ptr_client_and_return_parent))
    return CefOwnPtr<CefTranslatorTestScopedClient>();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: ownptr_diff
  DCHECK(val.get());
  if (!val.get())
    return CefOwnPtr<CefTranslatorTestScopedClient>();

  // Execute
  cef_translator_test_scoped_client_t* _retval =
      _struct->set_child_own_ptr_client_and_return_parent(
          _struct,
          CefTranslatorTestScopedClientChildCppToC::WrapOwn(OWN_PASS(val)));

  // Return type: ownptr_diff
  return CefTranslatorTestScopedClientCppToC::UnwrapOwn(_retval);
}

NO_SANITIZE("cfi-icall")
int CefTranslatorTestCToCpp::SetRawPtrLibrary(
    CefRawPtr<CefTranslatorTestScopedLibrary> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_raw_ptr_library))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: rawptr_same
  DCHECK(val);
  if (!val)
    return 0;

  // Execute
  int _retval = _struct->set_raw_ptr_library(
      _struct, CefTranslatorTestScopedLibraryCToCpp::UnwrapRaw(val));

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
int CefTranslatorTestCToCpp::SetChildRawPtrLibrary(
    CefRawPtr<CefTranslatorTestScopedLibraryChild> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_child_raw_ptr_library))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: rawptr_same
  DCHECK(val);
  if (!val)
    return 0;

  // Execute
  int _retval = _struct->set_child_raw_ptr_library(
      _struct, CefTranslatorTestScopedLibraryChildCToCpp::UnwrapRaw(val));

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::SetRawPtrLibraryList(
    const std::vector<CefRawPtr<CefTranslatorTestScopedLibrary>>& val,
    int val1,
    int val2) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_raw_ptr_library_list))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: rawptr_vec_same_byref_const
  const size_t valCount = val.size();
  cef_translator_test_scoped_library_t** valList = NULL;
  if (valCount > 0) {
    valList = new cef_translator_test_scoped_library_t*[valCount];
    DCHECK(valList);
    if (valList) {
      for (size_t i = 0; i < valCount; ++i) {
        valList[i] = CefTranslatorTestScopedLibraryCToCpp::UnwrapRaw(val[i]);
      }
    }
  }

  // Execute
  int _retval =
      _struct->set_raw_ptr_library_list(_struct, valCount, valList, val1, val2);

  // Restore param:val; type: rawptr_vec_same_byref_const
  if (valList)
    delete[] valList;

  // Return type: bool
  return _retval ? true : false;
}

NO_SANITIZE("cfi-icall")
int CefTranslatorTestCToCpp::SetRawPtrClient(
    CefRawPtr<CefTranslatorTestScopedClient> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_raw_ptr_client))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: rawptr_diff
  DCHECK(val);
  if (!val)
    return 0;

  // Translate param: val; type: rawptr_diff
  CefOwnPtr<CefTranslatorTestScopedClientCppToC> valPtr(
      CefTranslatorTestScopedClientCppToC::WrapRaw(val));

  // Execute
  int _retval = _struct->set_raw_ptr_client(_struct, valPtr->GetStruct());

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
int CefTranslatorTestCToCpp::SetChildRawPtrClient(
    CefRawPtr<CefTranslatorTestScopedClientChild> val) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_child_raw_ptr_client))
    return 0;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Verify param: val; type: rawptr_diff
  DCHECK(val);
  if (!val)
    return 0;

  // Translate param: val; type: rawptr_diff
  CefOwnPtr<CefTranslatorTestScopedClientChildCppToC> valPtr(
      CefTranslatorTestScopedClientChildCppToC::WrapRaw(val));

  // Execute
  int _retval = _struct->set_child_raw_ptr_client(_struct, valPtr->GetStruct());

  // Return type: simple
  return _retval;
}

NO_SANITIZE("cfi-icall")
bool CefTranslatorTestCToCpp::SetRawPtrClientList(
    const std::vector<CefRawPtr<CefTranslatorTestScopedClient>>& val,
    int val1,
    int val2) {
  shutdown_checker::AssertNotShutdown();

  cef_translator_test_t* _struct = GetStruct();
  if (CEF_MEMBER_MISSING(_struct, set_raw_ptr_client_list))
    return false;

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Translate param: val; type: rawptr_vec_diff_byref_const
  const size_t valCount = val.size();
  cef_translator_test_scoped_client_t** valList = NULL;
  if (valCount > 0) {
    valList = new cef_translator_test_scoped_client_t*[valCount];
    DCHECK(valList);
    if (valList) {
      for (size_t i = 0; i < valCount; ++i) {
        valList[i] = CefTranslatorTestScopedClientCppToC::WrapRaw(val[i])
                         .release()
                         ->GetStruct();
      }
    }
  }

  // Execute
  int _retval =
      _struct->set_raw_ptr_client_list(_struct, valCount, valList, val1, val2);

  // Restore param:val; type: rawptr_vec_diff_byref_const
  if (valCount > 0) {
    for (size_t i = 0; i < valCount; ++i) {
      delete CefTranslatorTestScopedClientCppToC::GetWrapper(valList[i]);
    }
  }
  if (valList)
    delete[] valList;

  // Return type: bool
  return _retval ? true : false;
}

// CONSTRUCTOR - Do not edit by hand.

CefTranslatorTestCToCpp::CefTranslatorTestCToCpp() {}

// DESTRUCTOR - Do not edit by hand.

CefTranslatorTestCToCpp::~CefTranslatorTestCToCpp() {
  shutdown_checker::AssertNotShutdown();
}

template <>
cef_translator_test_t* CefCToCppRefCounted<
    CefTranslatorTestCToCpp,
    CefTranslatorTest,
    cef_translator_test_t>::UnwrapDerived(CefWrapperType type,
                                          CefTranslatorTest* c) {
  NOTREACHED() << "Unexpected class type: " << type;
  return nullptr;
}

template <>
CefWrapperType CefCToCppRefCounted<CefTranslatorTestCToCpp,
                                   CefTranslatorTest,
                                   cef_translator_test_t>::kWrapperType =
    WT_TRANSLATOR_TEST;
