OmniSciDB  340b00dbf6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 <iterator>
23 #include <list>
24 #include <set>
25 #include <unordered_set>
26 #include <vector>
27 
28 namespace shared {
29 
30 // source is destructively appended to the back of destination.
31 // source.empty() is true after call. Return number of elements appended.
32 template <typename T>
33 size_t appendMove(std::vector<T>& destination, std::vector<T>& source) {
34  if (source.empty()) {
35  return 0;
36  } else if (destination.empty()) {
37  destination = std::move(source);
38  return destination.size();
39  } else {
40  size_t const source_size = source.size();
41  destination.reserve(destination.size() + source_size);
42  std::move(std::begin(source), std::end(source), std::back_inserter(destination));
43  source.clear();
44  return source_size;
45  }
46 }
47 
48 template <typename... Ts, typename T>
49 bool dynamic_castable_to_any(T const* ptr) {
50  return (... || dynamic_cast<Ts const*>(ptr));
51 }
52 
53 // Helper to print out contents of simple containers (e.g. vector, list, deque)
54 // including nested containers, e.g. 2d vectors, list of vectors, etc.
55 // Base value_type must be a std::is_scalar_v type, though you can add custom
56 // objects below with a new `else if constexpr` block.
57 // Example: VLOG(1) << "container=" << shared::printContainer(container);
58 template <typename CONTAINER>
60  CONTAINER& container;
61 };
62 
63 template <typename CONTAINER>
65  return {container};
66 }
67 
68 template <typename CONTAINER>
69 struct is_std_container : std::false_type {};
70 template <typename T, typename A>
71 struct is_std_container<std::deque<T, A> > : std::true_type {};
72 template <typename T, typename A>
73 struct is_std_container<std::list<T, A> > : std::true_type {};
74 template <typename T, typename A>
75 struct is_std_container<std::set<T, A> > : std::true_type {};
76 template <typename T, typename A>
77 struct is_std_container<std::unordered_set<T, A> > : std::true_type {};
78 template <typename T, typename A>
79 struct is_std_container<std::vector<T, A> > : std::true_type {};
80 
81 template <typename OSTREAM, typename CONTAINER>
82 OSTREAM& operator<<(OSTREAM& os, PrintContainer<CONTAINER> pc) {
83  if (pc.container.empty()) {
84  return os << "()";
85  } else {
87  os << '(';
88  for (auto& container : pc.container) {
89  os << printContainer(container);
90  }
91  } else {
92  for (auto itr = pc.container.begin(); itr != pc.container.end(); ++itr) {
93  if constexpr (std::is_pointer_v<typename CONTAINER::value_type>) {
94  os << (itr == pc.container.begin() ? '(' : ' ') << (void const*)*itr;
95  } else {
96  os << (itr == pc.container.begin() ? '(' : ' ') << *itr;
97  }
98  }
99  }
100  return os << ')';
101  }
102 }
103 
104 // Same as strftime(buf, max, "%F", tm) but guarantees that the year is
105 // zero-padded to a minimum length of 4. Return the number of characters
106 // written, not including null byte. If max is not large enough, return 0.
107 size_t formatDate(char* buf, size_t const max, int64_t const unixtime);
108 
109 // Same as strftime(buf, max, "%F %T", tm) but guarantees that the year is
110 // zero-padded to a minimum length of 4. Return the number of characters
111 // written, not including null byte. If max is not large enough, return 0.
112 // Requirement: 0 <= dimension <= 9.
113 size_t formatDateTime(char* buf,
114  size_t const max,
115  int64_t const timestamp,
116  int const dimension);
117 
118 // Write unixtime in seconds since epoch as "HH:MM:SS" format.
119 size_t formatHMS(char* buf, size_t const max, int64_t const unixtime);
120 
121 // Result of division where quot is floored and rem is unsigned.
122 struct DivUMod {
123  int64_t quot;
124  int64_t rem;
125 };
126 
127 // Requirement: 0 < den
128 inline DivUMod divUMod(int64_t num, int64_t den) {
129  DivUMod div{num / den, num % den};
130  if (div.rem < 0) {
131  --div.quot;
132  div.rem += den;
133  }
134  return div;
135 }
136 
137 // Requirement: 0 < den.
138 inline uint64_t unsignedMod(int64_t num, int64_t den) {
139  int64_t mod = num % den;
140  if (mod < 0) {
141  mod += den;
142  }
143  return mod;
144 }
145 
146 } // namespace shared
147 
148 #endif // SHARED_MISC_H
size_t appendMove(std::vector< T > &destination, std::vector< T > &source)
Definition: misc.h:33
int64_t quot
Definition: misc.h:123
size_t formatDateTime(char *buf, size_t const max, int64_t const timestamp, int const dimension)
Definition: misc.cpp:43
size_t formatHMS(char *buf, size_t const max, int64_t const unixtime)
Definition: misc.cpp:80
CONTAINER & container
Definition: misc.h:60
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:138
int64_t rem
Definition: misc.h:124
bool dynamic_castable_to_any(T const *ptr)
Definition: misc.h:49
PrintContainer< CONTAINER > printContainer(CONTAINER &container)
Definition: misc.h:64
DivUMod divUMod(int64_t num, int64_t den)
Definition: misc.h:128