2222#include " traits/ctype.hpp"
2323#include " na.hpp"
2424#include " exceptions.hpp"
25+ #include " scalar_operator.hpp"
2526
2627namespace RcppHoney {
2728
@@ -177,9 +178,19 @@ class cbinder : public operand< cbinder< LhsIterator, RhsIterator, NA_VALUE >,
177178 m_rhsEnd (rhsEnd) {
178179
179180 if (lhsDims.first == -1 ) {
180- throw bounds_exception ();
181+ if (rhsDims.first > 0 ) {
182+ m_dims.first = rhsDims.first
183+ + ((rhsDims.second == 0 ) ? 1 : rhsDims.second );
184+ } else {
185+ throw bounds_exception ();
186+ }
181187 } else if (rhsDims.first == -1 ) {
182- throw bounds_exception ();
188+ if (lhsDims.first > 0 ) {
189+ m_dims.first = lhsDims.first
190+ + ((lhsDims.second == 0 ) ? 1 : lhsDims.second );
191+ } else {
192+ throw bounds_exception ();
193+ }
183194 } else if (lhsDims.second == 0 && rhsDims.second == 0 ) {
184195 if (lhsDims.first == rhsDims.first ) {
185196 m_dims.first = lhsDims.first ;
@@ -237,5 +248,99 @@ struct make_cbinder
237248 rhs.begin (), rhs.end (), hooks::extract_dims (rhs));
238249 }
239250};
251+
252+ template < typename T, typename T_ITER, typename T_RESULT, typename U,
253+ typename U_ITER, typename U_RESULT >
254+ RcppHoney::cbinder< T_ITER, U_ITER, (T::NA || U::NA) >
255+ cbind (const RcppHoney::operand< T, T_ITER, T_RESULT > &lhs,
256+ const RcppHoney::operand< U, U_ITER, U_RESULT > &rhs) {
257+ return RcppHoney::make_cbinder< (T::NA || U::NA) >()(lhs, rhs);
258+ }
259+ template < typename T, typename T_ITER, typename T_RESULT, typename U >
260+ typename RcppHoney::traits::enable_if< RcppHoney::traits::is_primitive< U >::value,
261+ RcppHoney::cbinder< T_ITER, typename RcppHoney::scalar_operator< U >::const_iterator, T::NA >
262+ >::type
263+ cbind (const RcppHoney::operand< T, T_ITER, T_RESULT > &lhs, const U &rhs) {
264+ return RcppHoney::make_cbinder< T::NA >()(lhs, RcppHoney::make_scalar_operator ()(rhs, lhs.dims ().first ));
265+ }
266+ template < typename T, typename U, typename U_ITER, typename U_RESULT >
267+ typename RcppHoney::traits::enable_if< RcppHoney::traits::is_primitive< T >::value,
268+ RcppHoney::cbinder< typename RcppHoney::scalar_operator< T >::const_iterator, U_ITER, U::NA >
269+ >::type
270+ cbind (const T &lhs, const RcppHoney::operand< U, U_ITER, U_RESULT > &rhs) {
271+ return RcppHoney::make_cbinder< U::NA >()(RcppHoney::make_scalar_operator ()(lhs, rhs.dims ().first ), rhs);
272+ }
273+ template < typename T, typename U >
274+ typename RcppHoney::traits::enable_if<
275+ (RcppHoney::hook< T >::value && RcppHoney::hook< U >::value),
276+ RcppHoney::cbinder<
277+ typename RcppHoney::hook< T >::const_iterator,
278+ typename RcppHoney::hook< U >::const_iterator,
279+ (RcppHoney::hook< T >::NA || RcppHoney::hook< U >::NA)
280+ >
281+ >::type
282+ cbind (const T &lhs, const U &rhs) {
283+ return RcppHoney::make_cbinder< (RcppHoney::hook< T >::NA || RcppHoney::hook< U >::NA) >()(
284+ lhs,
285+ rhs);
286+ }
287+ template < typename T, typename T_ITER, typename T_RESULT, typename U >
288+ typename RcppHoney::traits::enable_if< RcppHoney::hook< U >::value,
289+ RcppHoney::cbinder<
290+ T_ITER,
291+ typename RcppHoney::hook< U >::const_iterator,
292+ (T::NA || RcppHoney::hook< U >::NA)
293+ >
294+ >::type
295+ cbind (const RcppHoney::operand< T, T_ITER, T_RESULT > &lhs, const U &rhs) {
296+ return RcppHoney::make_cbinder< (T::NA || RcppHoney::hook< U >::NA) >()(
297+ lhs,
298+ rhs);
299+ }
300+ template < typename T, typename U, typename U_ITER, typename U_RESULT >
301+ typename RcppHoney::traits::enable_if< RcppHoney::hook< T >::value,
302+ RcppHoney::cbinder<
303+ typename RcppHoney::hook< T >::const_iterator,
304+ U_ITER,
305+ (U::NA || RcppHoney::hook< T >::NA)
306+ >
307+ >::type
308+ cbind (const T &lhs, const RcppHoney::operand< U, U_ITER, U_RESULT > &rhs) {
309+ return RcppHoney::make_cbinder< (U::NA || RcppHoney::hook< T >::NA) >()(
310+ lhs,
311+ rhs);
312+ }
313+ template < typename T, typename U >
314+ typename RcppHoney::traits::enable_if<
315+ RcppHoney::traits::is_primitive< T >::value
316+ && RcppHoney::hook< U >::value,
317+ RcppHoney::cbinder<
318+ typename RcppHoney::scalar_operator< T >::const_iterator,
319+ typename RcppHoney::hook< U >::const_iterator,
320+ RcppHoney::hook< U >::NA
321+ >
322+ >::type
323+ cbind (const T &lhs, const U &rhs) {
324+ dims_t dims = RcppHoney::hooks::extract_dims (rhs);
325+ return RcppHoney::make_cbinder< RcppHoney::hook< U >::NA >()(
326+ RcppHoney::make_scalar_operator ()(lhs, dims.first ),
327+ rhs);
328+ }
329+ template < typename T, typename U >
330+ typename RcppHoney::traits::enable_if<
331+ RcppHoney::traits::is_primitive< U >::value
332+ && RcppHoney::hook< T >::value,
333+ RcppHoney::cbinder<
334+ typename RcppHoney::hook< T >::const_iterator,
335+ typename RcppHoney::scalar_operator< U >::const_iterator,
336+ RcppHoney::hook< T >::NA
337+ >
338+ >::type
339+ cbind (const T &lhs, const U &rhs) {
340+ dims_t dims = RcppHoney::hooks::extract_dims (lhs);
341+ return RcppHoney::make_cbinder< RcppHoney::hook< T >::NA >()(
342+ lhs,
343+ RcppHoney::make_scalar_operator ()(rhs, dims.first ));
344+ }
240345
241346} // namespace RcppHoney
0 commit comments