diff --git a/atom.gyp b/atom.gyp index bde0baa42cd..e52121e6e5c 100644 --- a/atom.gyp +++ b/atom.gyp @@ -164,6 +164,7 @@ 'common/platform_util.h', 'common/platform_util_mac.mm', 'common/platform_util_win.cc', + 'common/swap_or_assign.h', 'common/v8_conversions.h', 'common/v8_value_converter_impl.cc', 'common/v8_value_converter_impl.h', diff --git a/common/swap_or_assign.h b/common/swap_or_assign.h new file mode 100644 index 00000000000..3953653f8f5 --- /dev/null +++ b/common/swap_or_assign.h @@ -0,0 +1,41 @@ +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_SWAP_OR_ASSIGN_H_ +#define ATOM_COMMON_SWAP_OR_ASSIGN_H_ + +namespace internal { + +// Helper to detect whether value has specified method. +template +class HasSwapMethod { + typedef char one; + typedef long two; + template static one test(char[sizeof(&C::swap)]) ; + template static two test(...); + public: + enum { value = sizeof(test(0)) == sizeof(char) }; +}; + +template +struct enable_if {}; + +template +struct enable_if { typedef T type; }; + +template +typename enable_if::value>::type SwapOrAssign( + T& v1, const T& v2) { + v1.swap(const_cast(v2)); +} + +template +typename enable_if::value>::type SwapOrAssign( + T& v1, const T& v2) { + v1 = v2; +} + +} // namespace internal + +#endif // ATOM_COMMON_SWAP_OR_ASSIGN_H_ diff --git a/common/v8_conversions.h b/common/v8_conversions.h index 55b770996a7..a1800ce25b8 100644 --- a/common/v8_conversions.h +++ b/common/v8_conversions.h @@ -11,7 +11,11 @@ #include "base/files/file_path.h" #include "base/string16.h" +#include "base/template_util.h" +#include "base/values.h" #include "browser/api/atom_api_window.h" +#include "common/swap_or_assign.h" +#include "content/public/renderer/v8_value_converter.h" #include "googleurl/src/gurl.h" #include "ui/gfx/rect.h" #include "v8/include/v8.h" @@ -60,6 +64,13 @@ struct FromV8Value { width->IntegerValue(), height->IntegerValue()); } + operator scoped_ptr() { + scoped_ptr converter( + content::V8ValueConverter::create()); + return scoped_ptr( + converter->FromV8Value(value_, v8::Context::GetCurrent())); + } + operator std::vector() { std::vector array; v8::Handle v8_array = v8::Handle::Cast(value_); @@ -184,6 +195,12 @@ bool V8ValueCanBeConvertedTo(v8::Handle value) { return value->IsObject(); } +template<> inline +bool V8ValueCanBeConvertedTo>( + v8::Handle value) { + return value->IsObject(); +} + template<> inline bool V8ValueCanBeConvertedTo>( v8::Handle value) { @@ -218,7 +235,8 @@ template inline bool FromV8Arguments(const v8::Arguments& args, T1* value, int index = 0) { if (!V8ValueCanBeConvertedTo(args[index])) return false; - *value = static_cast(FromV8Value(args[index])); + internal::SwapOrAssign(*value, + static_cast(FromV8Value(args[index]))); return true; }