Skip to content

Commit 6e05dff

Browse files
committed
Merge pull request #56 from taion/jjia/clang-build
Minor fixes to enable building with clang on OS X Fixes #55. Fixes #56.
2 parents 5ac5af5 + 44927a5 commit 6e05dff

File tree

12 files changed

+117
-65
lines changed

12 files changed

+117
-65
lines changed

cppwamp/include/cppwamp/codec.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include <set>
1717
#include <stdexcept>
18+
#include <string>
1819

1920
namespace wamp
2021
{

cppwamp/include/cppwamp/internal/endian.ipp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
http://www.boost.org/LICENSE_1_0.txt)
66
------------------------------------------------------------------------------*/
77

8-
#include "endian.h"
98
#include <boost/endian/conversion.hpp>
109

1110

cppwamp/include/cppwamp/internal/msgpack.ipp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void Msgpack::decodeBuffer(const TBuffer& from, Variant& to)
152152
{
153153
using namespace msgpack;
154154
auto result = unpack(from.data(), from.length(),
155-
[] (type::object_type, uint64_t, void*) {return true;});
155+
[] (type::object_type, std::size_t, void*) {return true;});
156156
const auto& obj = result.get();
157157

158158
Variant v;

cppwamp/include/cppwamp/internal/options.ipp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ Options<D>::optionOr(
7171
{
7272
auto iter = options_.find(key);
7373
if (iter != options_.end())
74-
return iter->second.to<ValueTypeOf<T>>();
74+
return iter->second.template to<ValueTypeOf<T>>();
7575
else
7676
return std::forward<T>(fallback);
7777
}

cppwamp/include/cppwamp/internal/variant.ipp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ template <typename TField, typename V> TField& Variant::get(V&& variant)
477477
{
478478
using FieldType = typename std::remove_const<TField>::type;
479479
static_assert(FieldTraits<FieldType>::isValid, "Invalid field type");
480-
if (!variant.is<FieldType>())
480+
if (!variant.template is<FieldType>())
481481
throw error::Access(wamp::typeNameOf(variant),
482482
FieldTraits<FieldType>::typeName());
483483
return Access<FieldType>::get(&variant.field_);

cppwamp/include/cppwamp/internal/varianttraits.hpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,33 @@ namespace wamp
2121
namespace internal
2222
{
2323

24+
//------------------------------------------------------------------------------
25+
template <typename T> constexpr bool isBool()
26+
{
27+
// std::vector<bool>::const_reference is not just bool in clang/libc++.
28+
return std::is_same<T, Bool>::value ||
29+
std::is_same<T, std::vector<bool>::reference>::value ||
30+
std::is_same<T, std::vector<bool>::const_reference>::value;
31+
}
32+
2433
//------------------------------------------------------------------------------
2534
template <typename T> constexpr bool isNumber()
2635
{
27-
return std::is_arithmetic<T>::value && !std::is_same<T, bool>::value;
36+
return std::is_arithmetic<T>::value && !std::is_same<T, Bool>::value;
2837
}
2938

3039
//------------------------------------------------------------------------------
3140
template <typename T> constexpr bool isSignedInteger()
3241
{
3342
return std::is_integral<T>::value && std::is_signed<T>::value &&
34-
!std::is_same<T,Bool>::value;
43+
!std::is_same<T, Bool>::value;
3544
}
3645

3746
//------------------------------------------------------------------------------
3847
template <typename T> constexpr bool isUnsignedInteger()
3948
{
4049
return std::is_integral<T>::value && !std::is_signed<T>::value &&
41-
!std::is_same<T,Bool>::value;
50+
!std::is_same<T, Bool>::value;
4251
}
4352

4453
//------------------------------------------------------------------------------
@@ -132,20 +141,15 @@ template <> struct ArgTraits<Null>
132141
using FieldType = Null;
133142
};
134143

135-
template <> struct ArgTraits<Bool>
144+
template <typename TField>
145+
struct ArgTraits<TField, typename std::enable_if<
146+
isBool<TField>() >::type >
136147
{
137148
static constexpr bool isValid = true;
138149
static String typeName() {return "Bool";}
139150
using FieldType = Bool;
140151
};
141152

142-
template <> struct ArgTraits<std::vector<bool>::reference>
143-
{
144-
static constexpr bool isValid = true;
145-
static String typeName() {return "std::vector<bool>::reference>";}
146-
using FieldType = Bool;
147-
};
148-
149153
template <typename TField>
150154
struct ArgTraits<TField, typename std::enable_if<
151155
isSignedInteger<TField>() >::type >

cppwamp/include/cppwamp/internal/varianttuple.ipp

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,37 +14,42 @@ namespace wamp
1414
namespace internal
1515
{
1616

17-
template<typename TResult, std::size_t N, typename... Ts>
18-
using TupleResult = typename std::enable_if<N != sizeof...(Ts), TResult>::type;
17+
//------------------------------------------------------------------------------
18+
// This should be possible with return type deduction, but clang doesn't like
19+
// that for some reason: http://stackoverflow.com/q/24454664.
20+
template <std::size_t N, typename... Ts>
21+
using EnableIfTupleElement =
22+
typename std::enable_if<N != sizeof...(Ts), int>::type;
1923

20-
template<typename TResult, std::size_t N, typename... Ts>
21-
using TupleLastResult =
22-
typename std::enable_if<N == sizeof...(Ts), TResult>::type;
24+
template <std::size_t N, typename... Ts>
25+
using EnableIfTupleEnd =
26+
typename std::enable_if<N == sizeof...(Ts), int>::type;
2327

2428
//------------------------------------------------------------------------------
2529
template <typename T>
26-
void assignFromTupleElement(Variant& v, T&& elem)
30+
T&& forwardTupleElement(T&& elem)
2731
{
2832
static_assert(ArgTraits<T>::isValid,
2933
"wamp::fromTuple - Invalid tuple element type");
30-
v = std::move(elem);
34+
// Normally this should be std::forward, but this function is only called by
35+
// assignFromTuple below, so elem is always actually an rvalue reference, so
36+
// using std::move is sufficient.
37+
return std::move(elem);
3138
}
3239

3340
template <typename... Ts>
34-
void assignFromTupleElement(Variant& v, std::tuple<Ts...>&& tuple)
41+
Array forwardTupleElement(std::tuple<Ts...>&& tuple)
3542
{
36-
v = toArray(std::move(tuple));
43+
return toArray(std::move(tuple));
3744
}
3845

39-
template<std::size_t N=0, typename... Ts>
40-
TupleLastResult<void,N,Ts...> assignFromTuple(Array&, std::tuple<Ts...>&&) { }
46+
template<std::size_t N = 0, typename... Ts, EnableIfTupleEnd<N, Ts...> = 0>
47+
void assignFromTuple(Array&, std::tuple<Ts...>&&) {}
4148

42-
template<std::size_t N=0, typename... Ts>
43-
TupleResult<void,N,Ts...> assignFromTuple(Array& array,
44-
std::tuple<Ts...>&& tuple)
49+
template<std::size_t N = 0, typename... Ts, EnableIfTupleElement<N, Ts...> = 0>
50+
void assignFromTuple(Array& array, std::tuple<Ts...>&& tuple)
4551
{
46-
array.push_back(Variant());
47-
assignFromTupleElement(array.back(), std::get<N>(std::move(tuple)));
52+
array.emplace_back(forwardTupleElement(std::get<N>(std::move(tuple))));
4853
assignFromTuple<N+1, Ts...>(array, std::move(tuple));
4954
}
5055

@@ -70,12 +75,11 @@ void assignToTupleElement(const Variant& v, std::tuple<Ts...>& tuple)
7075
toTuple(v.as<Array>(), tuple);
7176
}
7277

73-
template<std::size_t N=0, typename... Ts>
74-
TupleLastResult<void,N,Ts...> assignToTuple(const Array&, std::tuple<Ts...>&) {}
78+
template<std::size_t N = 0, typename... Ts, EnableIfTupleEnd<N, Ts...> = 0>
79+
void assignToTuple(const Array&, std::tuple<Ts...>&) {}
7580

76-
template<std::size_t N=0, typename... Ts>
77-
TupleResult<void,N,Ts...> assignToTuple(const Array& array,
78-
std::tuple<Ts...>& tuple)
81+
template<std::size_t N = 0, typename... Ts, EnableIfTupleElement<N, Ts...> = 0>
82+
void assignToTuple(const Array& array, std::tuple<Ts...>& tuple)
7983
{
8084
using ElemType = typename std::tuple_element<N, std::tuple<Ts...>>::type;
8185
static_assert(ArgTraits<ElemType>::isValid,
@@ -97,9 +101,12 @@ TupleResult<void,N,Ts...> assignToTuple(const Array& array,
97101
//------------------------------------------------------------------------------
98102
template <typename T> struct TupleTag {};
99103

100-
// Foward declaration
101-
template<std::size_t N=0, typename... Ts>
102-
TupleResult<bool,N,Ts...> isConvertibleToTuple(const Array& array);
104+
// Forward declarations.
105+
template<std::size_t N = 0, typename... Ts, EnableIfTupleEnd<N, Ts...> = 0>
106+
bool isConvertibleToTuple(const Array& array);
107+
108+
template<std::size_t N = 0, typename... Ts, EnableIfTupleElement<N, Ts...> = 0>
109+
bool isConvertibleToTuple(const Array& array);
103110

104111
template <typename T>
105112
bool isConvertibleToTupleElement(const Variant& v, TupleTag<T>)
@@ -114,11 +121,12 @@ bool isConvertibleToTupleElement(const Variant& v, TupleTag<std::tuple<Ts...>>)
114121
isConvertibleToTuple<0,Ts...>(v.as<Array>());
115122
}
116123

117-
template<std::size_t N=0, typename... Ts>
118-
TupleLastResult<bool,N,Ts...> isConvertibleToTuple(const Array&) {return true;}
124+
// Template defaults given in forward declaration.
125+
template<std::size_t N, typename... Ts, EnableIfTupleEnd<N, Ts...>>
126+
bool isConvertibleToTuple(const Array&) {return true;}
119127

120-
template<std::size_t N=0, typename... Ts>
121-
TupleResult<bool,N,Ts...> isConvertibleToTuple(const Array& array)
128+
template<std::size_t N, typename... Ts, EnableIfTupleElement<N, Ts...>>
129+
bool isConvertibleToTuple(const Array& array)
122130
{
123131
using ElemType = typename std::tuple_element<N, std::tuple<Ts...>>::type;
124132
bool result = isConvertibleToTupleElement(array.at(N),
@@ -128,16 +136,14 @@ TupleResult<bool,N,Ts...> isConvertibleToTuple(const Array& array)
128136

129137

130138
//------------------------------------------------------------------------------
131-
template<std::size_t N=0, typename... Ts>
132-
TupleLastResult<bool,N,Ts...> equalsTuple(const Array&,
133-
const std::tuple<Ts...>&)
139+
template<std::size_t N = 0, typename... Ts, EnableIfTupleEnd<N, Ts...> = 0>
140+
bool equalsTuple(const Array&, const std::tuple<Ts...>&)
134141
{
135142
return true;
136143
}
137144

138-
template<std::size_t N=0, typename... Ts>
139-
TupleResult<bool,N,Ts...> equalsTuple(const Array& array,
140-
const std::tuple<Ts...>& tuple)
145+
template<std::size_t N = 0, typename... Ts, EnableIfTupleElement<N, Ts...> = 0>
146+
bool equalsTuple(const Array& array, const std::tuple<Ts...>& tuple)
141147
{
142148
using ElemType = typename std::tuple_element<N, std::tuple<Ts...>>::type;
143149
static_assert(ArgTraits<ElemType>::isValid,
@@ -149,16 +155,14 @@ TupleResult<bool,N,Ts...> equalsTuple(const Array& array,
149155
}
150156

151157
//------------------------------------------------------------------------------
152-
template<std::size_t N=0, typename... Ts>
153-
TupleLastResult<bool,N,Ts...> notEqualsTuple(const Array&,
154-
const std::tuple<Ts...>&)
158+
template<std::size_t N = 0, typename... Ts, EnableIfTupleEnd<N, Ts...> = 0>
159+
bool notEqualsTuple(const Array&, const std::tuple<Ts...>&)
155160
{
156161
return false;
157162
}
158163

159-
template<std::size_t N=0, typename... Ts>
160-
TupleResult<bool,N,Ts...> notEqualsTuple(const Array& array,
161-
const std::tuple<Ts...>& tuple)
164+
template<std::size_t N = 0, typename... Ts, EnableIfTupleElement<N, Ts...> = 0>
165+
bool notEqualsTuple(const Array& array, const std::tuple<Ts...>& tuple)
162166
{
163167
using ElemType = typename std::tuple_element<N, std::tuple<Ts...>>::type;
164168
static_assert(ArgTraits<ElemType>::isValid,

cppwamp/include/cppwamp/internal/variantvisitors.hpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ namespace internal
2424
{
2525

2626
//------------------------------------------------------------------------------
27+
// The !std::is_same is required because std::vector<bool>::const_reference may
28+
// or may not just be bool.
29+
template <typename T>
30+
using EnableIfBoolRef =
31+
typename std::enable_if<
32+
isBool<T>() && !std::is_same<T, bool>::value, int
33+
>::type;
34+
2735
template <typename T, typename U>
2836
constexpr bool bothAreNumbers() {return isNumber<T>() && isNumber<U>();}
2937

@@ -63,19 +71,30 @@ class EquivalentTo : public Visitor<bool>
6371
bool operator()(const TField& lhs, const TField& rhs) const
6472
{return lhs == rhs;}
6573

74+
template <typename TArg, EnableIfBoolRef<TArg> = 0>
75+
bool operator()(const bool lhs, const TArg rhs) const
76+
{return lhs == bool(rhs);}
77+
6678
template <typename TField, typename TArg,
6779
DisableIfBothAreNumbers<TField,TArg> = 0>
6880
bool operator()(const TField&, const TArg&) const {return false;}
6981

7082
template <typename TField, typename TArg,
7183
EnableIfBothAreNumbers<TField,TArg> = 0>
72-
bool operator()(TField lhs, TArg rhs) const {return lhs == rhs;}
84+
bool operator()(const TField lhs, const TArg rhs) const
85+
{return lhs == rhs;}
7386

7487
template <typename TElem, EnableIfNotVariant<TElem> = 0>
7588
bool operator()(const Array& lhs, const std::vector<TElem>& rhs) const
7689
{
77-
return (lhs.size() == rhs.size()) ?
78-
std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin()) : false;
90+
using VecConstRef = typename std::vector<TElem>::const_reference;
91+
// clang libc++ parameterizes equality comparison for default binary
92+
// predicate on iterator value type instead of const reference type,
93+
// which leads to an ambiguous function resolution.
94+
return (lhs.size() != rhs.size()) ? false :
95+
std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin(),
96+
[](const Variant& lElem, VecConstRef rElem)
97+
{return lElem == rElem;});
7998
}
8099

81100
template <typename TValue, EnableIfNotVariant<TValue> = 0>
@@ -103,6 +122,10 @@ class NotEquivalentTo : public Visitor<bool>
103122
bool operator()(const TField& lhs, const TField& rhs) const
104123
{return lhs != rhs;}
105124

125+
template <typename TArg, EnableIfBoolRef<TArg> = 0>
126+
bool operator()(const bool lhs, const TArg rhs) const
127+
{return lhs != rhs;}
128+
106129
template <typename TField, typename TArg,
107130
DisableIfBothAreNumbers<TField,TArg> = 0>
108131
bool operator()(const TField&, const TArg&) const {return true;}
@@ -114,9 +137,14 @@ class NotEquivalentTo : public Visitor<bool>
114137
template <typename TElem, EnableIfNotVariant<TElem> = 0>
115138
bool operator()(const Array& lhs, const std::vector<TElem>& rhs) const
116139
{
140+
using VecConstRef = typename std::vector<TElem>::const_reference;
141+
// clang libc++ parameterizes equality comparison for default binary
142+
// predicate on iterator value type instead of const reference type,
143+
// which leads to an ambiguous function resolution.
117144
return (lhs.size() != rhs.size()) ? true :
118-
( std::mismatch(lhs.cbegin(), lhs.cend(), rhs.cbegin()).first !=
119-
lhs.end() );
145+
std::mismatch(lhs.cbegin(), lhs.cend(), rhs.cbegin(),
146+
[](const Variant& lElem, VecConstRef rElem)
147+
{return lElem == rElem;}).first != lhs.cend();
120148
}
121149

122150
template <typename TValue, EnableIfNotVariant<TValue> = 0>

cppwamp/include/cppwamp/null.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ namespace wamp
3535
//------------------------------------------------------------------------------
3636
struct Null
3737
{
38+
/// Default constructor. For instantiating const object.
39+
constexpr Null() {}
40+
3841
/// Compares two `Null` objects for equality. @return always `true`.
3942
bool operator==(Null) const;
4043

cppwamp/src/cppwamp.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@
2020
#include <cppwamp/version.hpp>
2121
#include <cppwamp/internal/messagetraits.hpp>
2222

23+
#if CPPWAMP_HAS_UNIX_DOMAIN_SOCKETS
24+
#include <cppwamp/udsconnector.hpp>
25+
#include <cppwamp/legacyudsconnector.hpp>
26+
#endif
27+
2328
#include <cppwamp/internal/dialoguedata.ipp>
2429
#include <cppwamp/internal/error.ipp>
2530
#include <cppwamp/internal/legacytcpconnector.ipp>
@@ -32,9 +37,6 @@
3237
#include <cppwamp/internal/version.ipp>
3338

3439
#if CPPWAMP_HAS_UNIX_DOMAIN_SOCKETS
35-
#include <cppwamp/udsconnector.hpp>
36-
#include <cppwamp/legacyudsconnector.hpp>
37-
3840
#include <cppwamp/internal/udsconnector.ipp>
3941
#include <cppwamp/internal/legacyudsconnector.ipp>
4042
#endif

0 commit comments

Comments
 (0)