Skip to content

Commit 025ebb2

Browse files
committed
CXX-638 Fixes required for VS2015 support
1 parent 3c3f8f2 commit 025ebb2

26 files changed

+169
-58
lines changed

src/bsoncxx/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ install(FILES
131131

132132
install(TARGETS
133133
bsoncxx
134+
RUNTIME DESTINATION bin COMPONENT runtime
134135
LIBRARY DESTINATION lib COMPONENT runtime
135136
ARCHIVE DESTINATION lib COMPONENT dev
136137
)

src/bsoncxx/builder/concatenate.hpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,13 @@ namespace builder {
2727
/// Container to concatenate a document. Use it by constructing an instance with the
2828
/// document to be concatenated, and pass it into a document stream builder.
2929
///
30-
struct BSONCXX_API concatenate_doc {
30+
struct concatenate_doc {
3131
document::view_or_value doc;
3232

33+
// MSVC seems to need a hint that it should always
34+
// inline this destructor;
35+
BSONCXX_INLINE ~concatenate_doc() = default;
36+
3337
BSONCXX_INLINE operator document::view() const {
3438
return doc;
3539
}
@@ -43,9 +47,13 @@ struct BSONCXX_API concatenate_doc {
4347
/// Container to concatenate an array. Use this with the array stream builder in order
4448
/// to pass an array into a new builder and append its values to the stream.
4549
///
46-
struct BSONCXX_API concatenate_array {
50+
struct concatenate_array {
4751
array::view_or_value array;
4852

53+
// MSVC seems to need a hint that it should always
54+
// inline this destructor;
55+
BSONCXX_INLINE ~concatenate_array() = default;
56+
4957
BSONCXX_INLINE operator array::view() const {
5058
return array;
5159
}

src/bsoncxx/builder/stream/array_context.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ class array_context {
6767
BSONCXX_INLINE typename std::enable_if<
6868
std::is_same<base, closed_context>::value &&
6969
std::is_same<typename std::remove_reference<T>::type, const finalize_type>::value,
70-
array::value>::type
70+
// TODO(MSVC): This should just be 'array::value', but
71+
// VS2015U1 can't resolve the name.
72+
bsoncxx::array::value>::type
7173
operator<<(T&&) {
7274
return _core->extract_array();
7375
}

src/bsoncxx/builder/stream/key_context.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ class key_context {
6464
BSONCXX_INLINE typename std::enable_if<
6565
std::is_same<base, closed_context>::value &&
6666
std::is_same<typename std::remove_reference<T>::type, const finalize_type>::value,
67-
document::value>::type
67+
// TODO(MSVC): This should just be 'document::value', but
68+
// VS2015U1 can't resolve the name.
69+
bsoncxx::document::value>::type
6870
operator<<(T&&) {
6971
return _core->extract_document();
7072
}

src/bsoncxx/builder/stream/value_context.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,11 @@ class value_context {
6060

6161
operator single_context();
6262

63+
#if !defined(_MSC_VER)
64+
// TODO(MSVC): Causes an ICE under VS2015U1
6365
static_assert(std::is_same<value_context, decltype(std::declval<value_context>() << 1 << "str")>::value,
6466
"value_context must be templatized on a key_context");
67+
#endif
6568

6669
private:
6770
BSONCXX_INLINE base unwrap() { return base(_core); }

src/bsoncxx/config/compiler.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
#pragma warning(push)
2020
#pragma warning(disable: 4251)
2121

22-
#define BSONCXX_INLINE inline __forceinline
22+
#define BSONCXX_INLINE inline __forceinline BSONCXX_PRIVATE
2323

2424
#else
25-
#define BSONCXX_INLINE inline __attribute__((__visibility__("hidden"), __always_inline__))
25+
#define BSONCXX_INLINE inline __attribute__((__always_inline__)) BSONCXX_PRIVATE
2626
#endif

src/bsoncxx/config/postlude.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,20 @@ static_assert(false, "BSONCXX_ENUM must be undef'ed");
5656
// export.hpp (generated by cmake)
5757
#undef BSONCXX_API_H
5858
#pragma pop_macro("BSONCXX_API_H")
59+
#undef BSONCXX_API
60+
#pragma pop_macro("BSONCXX_API")
61+
#undef BSONCXX_PRIVATE
62+
#pragma pop_macro("BSONCXX_PRIVATE")
5963
#undef BSONCXX_DEPRECATED
6064
#pragma pop_macro("BSONCXX_DEPRECATED")
6165
#undef BSONCXX_DEPRECATED_EXPORT
6266
#pragma pop_macro("BSONCXX_DEPRECATED_EXPORT")
6367
#undef BSONCXX_DEPRECATED_NO_EXPORT
6468
#pragma pop_macro("BSONCXX_DEPRECATED_NO_EXPORT")
69+
#undef DEFINE_NO_DEPRECATED
70+
#pragma pop_macro("DEFINE_NO_DEPRECATED")
6571
#undef BSONCXX_NO_DEPRECATED
6672
#pragma pop_macro("BSONCXX_NO_DEPRECATED")
67-
#undef BSONCXX_PRIVATE
68-
#pragma pop_macro("BSONCXX_PRIVATE")
69-
#undef BSONCXX_API
70-
#pragma pop_macro("BSONCXX_API")
7173

7274
// prelude.hpp
7375
#undef BSONCXX_UNREACHABLE

src/bsoncxx/config/prelude.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,23 +51,25 @@
5151
// export.hpp (generated by cmake)
5252
#pragma push_macro("BSONCXX_API_H")
5353
#undef BSONCXX_API_H
54+
#pragma push_macro("BSONCXX_API")
55+
#undef BSONCXX_API
56+
#pragma push_macro("BSONCXX_PRIVATE")
57+
#undef BSONCXX_PRIVATE
5458
#pragma push_macro("BSONCXX_DEPRECATED")
5559
#undef BSONCXX_DEPRECATED
5660
#pragma push_macro("BSONCXX_DEPRECATED_EXPORT")
5761
#undef BSONCXX_DEPRECATED_EXPORT
5862
#pragma push_macro("BSONCXX_DEPRECATED_NO_EXPORT")
5963
#undef BSONCXX_DEPRECATED_NO_EXPORT
64+
#pragma push_macro("DEFINE_NO_DEPRECATED")
65+
#undef DEFINE_NO_DEPRECATED
6066
#pragma push_macro("BSONCXX_NO_DEPRECATED")
6167
#undef BSONCXX_NO_DEPRECATED
62-
#pragma push_macro("BSONCXX_PRIVATE")
63-
#undef BSONCXX_PRIVATE
64-
#pragma push_macro("BSONCXX_API")
65-
#undef BSONCXX_API
6668

67-
#include <bsoncxx/config/compiler.hpp>
6869
#include <bsoncxx/config/config.hpp>
6970
#include <bsoncxx/config/version.hpp>
7071
#include <bsoncxx/config/export.hpp>
72+
#include <bsoncxx/config/compiler.hpp>
7173

7274
#pragma push_macro("BSONCXX_UNREACHABLE")
7375
#undef BSONCXX_UNREACHABLE

src/bsoncxx/oid.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
namespace bsoncxx {
2525
BSONCXX_INLINE_NAMESPACE_BEGIN
2626

27+
const oid::init_tag_t oid::init_tag{};
28+
2729
oid::oid() : _is_valid(false) {
2830
}
2931

src/bsoncxx/oid.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,13 @@ BSONCXX_INLINE_NAMESPACE_BEGIN
3838
class BSONCXX_API oid {
3939
public:
4040
struct init_tag_t {};
41-
static constexpr init_tag_t init_tag{};
41+
42+
// TODO(MSVC): Ideally this would be constexpr, but VS2015U1 can't
43+
// handle it.
44+
//
45+
// See https://connect.microsoft.com/VisualStudio/feedback/details/2092790
46+
//
47+
static const init_tag_t init_tag;
4248

4349
///
4450
/// Constructs an uninitialized oid.

src/bsoncxx/private/stack.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class stack {
6969

7070
std::list<T *> _buckets;
7171

72-
typename decltype(_buckets)::iterator _bucket_iter;
72+
typename std::list<T*>::iterator _bucket_iter;
7373

7474
int _bucket_index;
7575
int _bucket_size;

src/bsoncxx/stdx/optional.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ namespace stdx {
4444

4545
using ::boost::optional;
4646
using nullopt_t = ::boost::none_t;
47-
constexpr nullopt_t nullopt{};
47+
48+
// TODO(MSVC): This would be better expressed as constexpr, but VS2015U1 can't do it.
49+
const nullopt_t nullopt{::boost::none};
4850
using ::boost::make_optional;
4951

5052
} // namespace stdx

src/bsoncxx/test/bson_util_itoa.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
#include <bsoncxx/private/itoa.hpp>
44

55
TEST_CASE("util::itoa is equivalent to to_string(int)", "[bsoncxx::util::itoa]") {
6-
using namespace bsoncxx;
7-
86
for (int i = 0; i <= 10000; i++) {
9-
itoa val(i);
7+
bsoncxx::itoa val(i);
108
std::string str = std::to_string(i);
119
REQUIRE(val.length() == str.length());
1210
REQUIRE(std::string(val.c_str()) == str);

src/bsoncxx/util/functor.hpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,90 @@ namespace bsoncxx {
2222
BSONCXX_INLINE_NAMESPACE_BEGIN
2323
namespace util {
2424

25+
// TODO(MSVC): VS2015U1 Completely falls apart trying to honor the
26+
// simple definition of is_functor since is_convertible returns the
27+
// wrong results for std::function, so we fall back to a bunch of
28+
// other template metaprogramming there.
29+
30+
#if !defined(_MSC_VER)
31+
2532
template <typename FunctionLike, typename Signature>
2633
using is_functor = std::is_convertible<FunctionLike, std::function<Signature>>;
2734

35+
#else
36+
37+
namespace functor {
38+
39+
template <typename, typename>
40+
struct build_free_function;
41+
42+
template <typename F, typename R, typename... Args>
43+
struct build_free_function<F, R(Args...)> {
44+
typedef R (*type)(Args...);
45+
};
46+
47+
template <typename, typename>
48+
struct build_class_function;
49+
50+
template <typename C, typename R, typename... Args>
51+
struct build_class_function<C, R(Args...)> {
52+
typedef R (C::*type)(Args...);
53+
};
54+
55+
template <typename>
56+
struct strip_cv_from_class_function;
57+
58+
template <typename C, typename R, typename... Args>
59+
struct strip_cv_from_class_function<R (C::*)(Args...)> {
60+
typedef R (C::*type)(Args...);
61+
};
62+
63+
template <typename C, typename R, typename... Args>
64+
struct strip_cv_from_class_function<R (C::*)(Args...) const> {
65+
typedef R (C::*type)(Args...);
66+
};
67+
68+
template <typename C, typename R, typename... Args>
69+
struct strip_cv_from_class_function<R (C::*)(Args...) volatile> {
70+
typedef R (C::*type)(Args...);
71+
};
72+
73+
template <typename C, typename S>
74+
struct is_class_method_with_signature {
75+
typedef int yes;
76+
typedef char no;
77+
78+
// T stands for SFINAE
79+
template <typename T>
80+
static typename std::enable_if<std::is_convertible<typename build_class_function<C, S>::type,
81+
typename strip_cv_from_class_function<
82+
decltype(&T::operator())>::type>::value,
83+
yes>::type
84+
sfinae(void *);
85+
86+
template <typename>
87+
static no sfinae(...);
88+
89+
static bool constexpr value = sizeof(sfinae<C>(nullptr)) == sizeof(yes);
90+
};
91+
92+
template <typename F, typename S>
93+
struct is_function_with_signature
94+
: std::is_convertible<F, typename build_free_function<F, S>::type> {};
95+
96+
template <typename C, typename S, bool>
97+
struct is_functor_impl : is_class_method_with_signature<C, S> {};
98+
99+
template <typename F, typename S>
100+
struct is_functor_impl<F, S, false> : is_function_with_signature<F, S> {};
101+
102+
} // namespace functor
103+
104+
template <typename C, typename S>
105+
struct is_functor : functor::is_functor_impl<C, S, std::is_class<C>::value> {};
106+
107+
#endif
108+
28109
} // namespace util
29110
BSONCXX_INLINE_NAMESPACE_END
30111
} // namespace bsoncxx

src/mongocxx/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ generate_export_header (mongocxx
143143

144144
set(mongocxx_libs ${LIBMONGOC_LIBRARIES} ${LIBBSON_LIBRARIES})
145145

146-
target_link_libraries(mongocxx_static bsoncxx ${mongocxx_libs})
147-
target_link_libraries(mongocxx_mocked bsoncxx ${mongocxx_libs})
146+
target_link_libraries(mongocxx_static bsoncxx_static ${mongocxx_libs})
147+
target_link_libraries(mongocxx_mocked bsoncxx_static ${mongocxx_libs})
148148
target_link_libraries(mongocxx PUBLIC bsoncxx PRIVATE ${mongocxx_libs})
149149

150150
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
@@ -166,6 +166,7 @@ install(FILES
166166

167167
install(TARGETS
168168
mongocxx
169+
RUNTIME DESTINATION bin COMPONENT runtime
169170
LIBRARY DESTINATION lib COMPONENT runtime
170171
ARCHIVE DESTINATION lib COMPONENT dev
171172
)

src/mongocxx/client.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ stdx::optional<class read_concern> client::read_concern() const {
6969
if (!libmongoc::read_concern_get_level(rc)) {
7070
return stdx::nullopt;
7171
}
72-
return {(class read_concern){
73-
stdx::make_unique<read_concern::impl>(libmongoc::read_concern_copy(rc))}};
72+
return {(class read_concern)(
73+
stdx::make_unique<read_concern::impl>(libmongoc::read_concern_copy(rc)))};
7474
}
7575

7676
void client::read_preference(class read_preference rp) {

src/mongocxx/collection.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -756,8 +756,8 @@ stdx::optional<class read_concern> collection::read_concern() const {
756756
if (!libmongoc::read_concern_get_level(rc)) {
757757
return stdx::nullopt;
758758
}
759-
return {(class read_concern){
760-
stdx::make_unique<read_concern::impl>(libmongoc::read_concern_copy(rc))}};
759+
return {(class read_concern)(
760+
stdx::make_unique<read_concern::impl>(libmongoc::read_concern_copy(rc)))};
761761
}
762762

763763
void collection::read_preference(class read_preference rp) {

src/mongocxx/config/compiler.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
#pragma warning(push)
2222
#pragma warning(disable: 4251)
2323

24-
#define MONGOCXX_INLINE inline __forceinline
24+
#define MONGOCXX_INLINE inline __forceinline MONGOCXX_PRIVATE
2525

2626
#else
27-
#define MONGOCXX_INLINE inline __attribute__((__visibility__("hidden"), __always_inline__))
27+
#define MONGOCXX_INLINE inline __attribute__((__always_inline__)) MONGOCXX_PRIVATE
2828
#endif

src/mongocxx/config/postlude.hpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,22 @@
3636
#pragma pop_macro("MONGOCXX_VERSION_PATCH")
3737

3838
// export.hpp (generated by cmake)
39-
#undef DEFINE_NO_DEPRECATED
40-
#pragma pop_macro("DEFINE_NO_DEPRECATED")
41-
#undef MONGOCXX_API
42-
#pragma pop_macro("MONGOCXX_API")
4339
#undef MONGOCXX_API_H
4440
#pragma pop_macro("MONGOCXX_API_H")
41+
#undef MONGOCXX_API
42+
#pragma pop_macro("MONGOCXX_API")
43+
#undef MONGOCXX_PRIVATE
44+
#pragma pop_macro("MONGOCXX_PRIVATE")
4545
#undef MONGOCXX_DEPRECATED
4646
#pragma pop_macro("MONGOCXX_DEPRECATED")
4747
#undef MONGOCXX_DEPRECATED_EXPORT
4848
#pragma pop_macro("MONGOCXX_DEPRECATED_EXPORT")
4949
#undef MONGOCXX_DEPRECATED_NO_EXPORT
5050
#pragma pop_macro("MONGOCXX_DEPRECATED_NO_EXPORT")
51+
#undef DEFINE_NO_DEPRECATED
52+
#pragma pop_macro("DEFINE_NO_DEPRECATED")
5153
#undef MONGOCXX_NO_DEPRECATED
5254
#pragma pop_macro("MONGOCXX_NO_DEPRECATED")
53-
#undef MONGOCXX_PRIVATE
54-
#pragma pop_macro("MONGOCXX_PRIVATE")
55-
#undef MONGOCXX_API
56-
#pragma pop_macro("MONGOCXX_API")
5755

5856
// prelude.hpp
5957
#undef MONGOCXX_UNREACHABLE

0 commit comments

Comments
 (0)