datasketches-cpp
conditional_forward.hpp
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #ifndef CONDITIONAL_FORWARD_HPP_
21 #define CONDITIONAL_FORWARD_HPP_
22 
23 #include <type_traits>
24 
25 namespace datasketches {
26 
27 // Forward type T2 as rvalue reference if type T1 is rvalue reference
28 
29 template<typename T1, typename T2>
30 using fwd_type = typename std::conditional<std::is_lvalue_reference<T1>::value,
31  T2, typename std::remove_reference<T2>::type&&>::type;
32 
33 template<typename T1, typename T2>
34 fwd_type<T1, T2> conditional_forward(T2&& value) {
35  return std::forward<fwd_type<T1, T2>>(std::forward<T2>(value));
36 }
37 
38 // Forward container as iterators
39 
40 template<typename Container>
41 auto forward_begin(Container&& c) -> typename std::enable_if<
42  std::is_lvalue_reference<Container>::value ||
43  std::is_same<typename std::remove_reference<Container>::type::const_iterator, decltype(c.begin())>::value,
44  decltype(c.begin())
45 >::type
46 {
47  return c.begin();
48 }
49 
50 template<typename Container>
51 auto forward_begin(Container&& c) -> typename std::enable_if<
52  !std::is_lvalue_reference<Container>::value &&
53  !std::is_same<typename std::remove_reference<Container>::type::const_iterator, decltype(c.begin())>::value,
54  decltype(std::make_move_iterator(c.begin()))
55 >::type
56 {
57  return std::make_move_iterator(c.begin());
58 }
59 
60 template<typename Container>
61 auto forward_end(Container&& c) -> typename std::enable_if<
62  std::is_lvalue_reference<Container>::value ||
63  std::is_same<typename std::remove_reference<Container>::type::const_iterator, decltype(c.begin())>::value,
64  decltype(c.end())
65 >::type
66 {
67  return c.end();
68 }
69 
70 template<typename Container>
71 auto forward_end(Container&& c) -> typename std::enable_if<
72  !std::is_lvalue_reference<Container>::value &&
73  !std::is_same<typename std::remove_reference<Container>::type::const_iterator, decltype(c.begin())>::value,
74  decltype(std::make_move_iterator(c.end()))
75 >::type
76 {
77  return std::make_move_iterator(c.end());
78 }
79 
80 } /* namespace datasketches */
81 
82 #endif
DataSketches namespace.
Definition: binomial_bounds.hpp:38