OmniSciDB  8a228a1076
misc.h
Go to the documentation of this file.
1 /*
2  * Copyright 2019 OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SHARED_MISC_H
18 #define SHARED_MISC_H
19 
20 #include <cstdint>
21 #include <deque>
22 #include <list>
23 #include <set>
24 #include <unordered_set>
25 #include <vector>
26 
27 namespace shared {
28 
29 // source is destructively appended to the back of destination.
30 // source.empty() is true after call. Return number of elements appended.
31 template <typename T>
32 size_t appendMove(std::vector<T>& destination, std::vector<T>& source) {
33  if (source.empty()) {
34  return 0;
35  } else if (destination.empty()) {
36  destination = std::move(source);
37  return destination.size();
38  } else {
39  size_t const source_size = source.size();
40  destination.reserve(destination.size() + source_size);
41  std::move(std::begin(source), std::end(source), std::back_inserter(destination));
42  source.clear();
43  return source_size;
44  }
45 }
46 
47 template <typename... Ts, typename T>
48 bool dynamic_castable_to_any(T const* ptr) {
49  return (... || dynamic_cast<Ts const*>(ptr));
50 }
51 
52 // Helper to print out contents of simple containers (e.g. vector, list, deque)
53 // including nested containers, e.g. 2d vectors, list of vectors, etc.
54 // Base value_type must be a std::is_scalar_v type, though you can add custom
55 // objects below with a new `else if constexpr` block.
56 // Example: VLOG(1) << "container=" << shared::printContainer(container);
57 template <typename CONTAINER>
59  CONTAINER& container;
60 };
61 
62 template <typename CONTAINER>
64  return {container};
65 }
66 
67 template <typename CONTAINER>
68 struct is_std_container : std::false_type {};
69 template <typename T, typename A>
70 struct is_std_container<std::deque<T, A> > : std::true_type {};
71 template <typename T, typename A>
72 struct is_std_container<std::list<T, A> > : std::true_type {};
73 template <typename T, typename A>
74 struct is_std_container<std::set<T, A> > : std::true_type {};
75 template <typename T, typename A>
76 struct is_std_container<std::unordered_set<T, A> > : std::true_type {};
77 template <typename T, typename A>
78 struct is_std_container<std::vector<T, A> > : std::true_type {};
79 
80 template <typename OSTREAM, typename CONTAINER>
81 OSTREAM& operator<<(OSTREAM& os, PrintContainer<CONTAINER> pc) {
82  if (pc.container.empty()) {
83  return os << "()";
84  } else {
86  os << '(';
87  for (auto& container : pc.container) {
89  }
90  } else {
91  for (auto itr = pc.container.begin(); itr != pc.container.end(); ++itr) {
92  if constexpr (std::is_pointer_v<typename CONTAINER::value_type>) {
93  os << (itr == pc.container.begin() ? '(' : ' ') << (void const*)*itr;
94  } else {
95  os << (itr == pc.container.begin() ? '(' : ' ') << *itr;
96  }
97  }
98  }
99  return os << ')';
100  }
101 }
102 
103 // Same as strftime(buf, max, "%F", tm) but guarantees that the year is
104 // zero-padded to a minimum length of 4. Return the number of characters
105 // written, not including null byte. If max is not large enough, return 0.
106 size_t formatDate(char* buf, size_t const max, int64_t const unixtime);
107 
108 // Same as strftime(buf, max, "%F %T", tm) but guarantees that the year is
109 // zero-padded to a minimum length of 4. Return the number of characters
110 // written, not including null byte. If max is not large enough, return 0.
111 // Requirement: 0 <= dimension <= 9.
112 size_t formatDateTime(char* buf,
113  size_t const max,
114  int64_t const timestamp,
115  int const dimension);
116 
117 // Write unixtime in seconds since epoch as "HH:MM:SS" format.
118 size_t formatHMS(char* buf, size_t const max, int64_t const unixtime);
119 
120 // Result of division where quot is floored and rem is unsigned.
121 struct DivUMod {
122  int64_t quot;
123  int64_t rem;
124 };
125 
126 // Requirement: 0 < den
127 inline DivUMod divUMod(int64_t num, int64_t den) {
128  DivUMod div{num / den, num % den};
129  if (div.rem < 0) {
130  --div.quot;
131  div.rem += den;
132  }
133  return div;
134 }
135 
136 // Requirement: 0 < den.
137 inline uint64_t unsignedMod(int64_t num, int64_t den) {
138  int64_t mod = num % den;
139  if (mod < 0) {
140  mod += den;
141  }
142  return mod;
143 }
144 
145 } // namespace shared
146 
147 #endif // SHARED_MISC_H
size_t appendMove(std::vector< T > &destination, std::vector< T > &source)
Definition: misc.h:32
int64_t quot
Definition: misc.h:122
size_t formatDateTime(char *buf, size_t const max, int64_t const timestamp, int const dimension)
Definition: misc.cpp:42
size_t formatHMS(char *buf, size_t const max, int64_t const unixtime)
Definition: misc.cpp:78
CONTAINER & container
Definition: misc.h:59
size_t formatDate(char *buf, size_t const max, int64_t const unixtime)
Definition: misc.cpp:25
uint64_t unsignedMod(int64_t num, int64_t den)
Definition: misc.h:137
int64_t rem
Definition: misc.h:123
bool dynamic_castable_to_any(T const *ptr)
Definition: misc.h:48
PrintContainer< CONTAINER > printContainer(CONTAINER &container)
Definition: misc.h:63
DivUMod divUMod(int64_t num, int64_t den)
Definition: misc.h:127