39 namespace xerus {
namespace misc {
41 #if __GNUC__ > 4 || defined(__clang__) 43 XERUS_GENERATE_HAS_FUNCTION(count)
44 XERUS_GENERATE_HAS_FUNCTION(find)
48 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t,
49 typename std::enable_if<sfinae::has_count<container_t<item_t, rest_t...>, item_t>::value,
int>::type = 0>
50 inline size_t count(
const container_t<item_t, rest_t...> &_container,
const item_t &_item) noexcept(noexcept(_container.count(_item))) {
51 return _container.count(_item);
56 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t,
57 typename std::enable_if<!sfinae::has_count<container_t<item_t, rest_t...>, item_t>::value,
int>::type = 0>
58 inline size_t count(
const container_t<item_t, rest_t...> &_container,
const item_t &_item) {
60 for(
const item_t& otherItem : _container) {
61 if(otherItem == _item) { count++; }
68 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t,
69 typename std::enable_if<sfinae::has_find<container_t<item_t, rest_t...>, item_t>::value,
int>::type = 0>
70 inline bool contains(
const container_t<item_t, rest_t...> &_container,
const item_t &_item) {
71 return _container.find(_item) != _container.end();
76 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t,
77 typename std::enable_if<!sfinae::has_find<container_t<item_t, rest_t...>, item_t>::value,
int>::type = 0>
78 inline bool contains(
const container_t<item_t, rest_t...> &_container,
const item_t &_item) {
79 return std::find(_container.begin(), _container.end(), _item) != _container.end();
87 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t,
88 typename std::enable_if<!has_member_count<container_t<item_t, rest_t...>>::value,
int>::type = 0>
89 inline size_t count(
const container_t<item_t, rest_t...> &_container,
const item_t &_item) {
91 for(
const item_t& otherItem : _container) {
92 if(otherItem == _item) { count++; }
99 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t,
100 typename std::enable_if<has_member_count<container_t<item_t, rest_t...>>::value,
int>::type = 0>
101 inline size_t count(
const container_t<item_t, rest_t...> &_container,
const item_t &_item) {
102 return _container.count(_item);
106 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t,
107 typename std::enable_if<!has_member_count<container_t<item_t, rest_t...>>::value,
int>::type = 0>
108 inline bool contains(
const container_t<item_t, rest_t...> &_container,
const item_t &_item) {
109 return std::find(_container.begin(), _container.end(), _item) != _container.end();
114 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t,
115 typename std::enable_if<has_member_count<container_t<item_t, rest_t...>>::value,
int>::type = 0>
116 inline bool contains(
const container_t<item_t, rest_t...> &_container,
const item_t &_item) {
117 return _container.find(_item) != _container.end();
123 template<
template<
class,
class...>
class containerA_t,
template<
class,
class...>
class containerB_t,
class item_t,
class... restA_t,
class... restB_t>
124 inline bool contains(
const containerA_t<item_t, restA_t...> &_largeContainer,
const containerB_t<item_t, restB_t...> &_smallContainer) {
125 for(
const item_t &item : _smallContainer) {
126 if(!contains(_largeContainer, item)) {
return false; }
133 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t>
134 inline bool disjunct(
const container_t<item_t, rest_t...>& _containerA,
const container_t<item_t, rest_t...>& _containerB) {
135 for(
const item_t& item : _containerA) {
136 if(contains(_containerB, item)) {
return false; }
143 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t>
144 inline item_t max(
const container_t<item_t, rest_t...>& _container) {
145 XERUS_REQUIRE(!_container.empty(),
"max() must not be invoked with empty container.");
146 return *std::max_element(_container.begin(), _container.end());
151 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t>
152 inline item_t min(
const container_t<item_t, rest_t...>& _container) {
153 XERUS_REQUIRE(!_container.empty(),
"min() must not be invoked with empty container.");
154 return *std::min_element(_container.begin(), _container.end());
159 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t>
160 inline item_t sum(
const container_t<item_t, rest_t...>& _container) {
161 return std::accumulate(_container.begin(), _container.end(), item_t(0));
165 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t>
166 inline item_t average(
const container_t<item_t, rest_t...>& _container) {
167 return sum(_container)/_container.size();
172 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t>
173 inline item_t product(
const container_t<item_t, rest_t...>& _container) {
174 return std::accumulate(_container.begin(), _container.end(), item_t(1), std::multiplies<item_t>());
179 template<
template<
class,
class...>
class container_t,
class item_t,
class... rest_t>
180 inline double fp_product(
const container_t<item_t, rest_t...>& _container) {
181 return std::accumulate(_container.begin(), _container.end(), double(1.0), std::multiplies<double>());
186 template<
class item_t,
class... rest_t>
187 inline item_t product(
const std::vector<item_t, rest_t...>& _container,
const size_t _first,
const size_t _last) {
188 XERUS_REQUIRE(_first <= _last && _last <= _container.size(),
"Invalid range " << _first <<
"-" << _last <<
" given (Container size " << _container.size() <<
")");
189 return std::accumulate(_container.begin()+_first, _container.begin()+_last, item_t(1), std::multiplies<item_t>());
194 template<
class rule_t,
template<
class,
class...>
class container_t,
class item_t,
class... rest_t>
195 inline void erase(container_t<item_t, rest_t...>& _container,
const rule_t& _rule) {
196 _container.erase(std::remove_if(_container.begin(), _container.end(), _rule), _container.end());
Header file for CHECK and REQUIRE macros.
The main namespace of xerus.
Header file for macros that encapsulate SFINAE functionality.
#define XERUS_REQUIRE(condition, message)
Checks whether condition is true. logs an error otherwise via XERUS_LOG(error, message).
XERUS_GENERATE_HAS_MEMBER(count) template< template< class
: Counts how often an element is contained in an arbitary container
Header file for global shorthand notations of elementary integer types and attribute lists...