Sergiu Dotenco kindly contributed his implementation based on boost, could someone recommend an open-source c++11 style implementation, without boost? Google does provided some results, but this is a bit deep in math, I could not differentiate the quality of the implmentation.
Here's how c++11 has made compile time programming (slightly) easier
template <typename UIntType> constexpr bool IsPowerOfTwo(UIntType r)
{
return (r & (r - 1)) == 0;
}
namespace detail
{
template<class UIntType, UIntType r, bool>
struct ModuloHelper;
template<class UIntType, UIntType r>
struct ModuloHelper<UIntType, r, true>
{
template<class T>
static T calc(T value)
{
return value & (r - 1);
}
};
template<class UIntType, UIntType r>
struct ModuloHelper<UIntType, r, false>
{
template<class T>
static T calc(T value)
{
while (value >= r)
{ value -= r; }
return value;
}
};
}
template<class UIntType, UIntType r>
struct Modulo : detail::ModuloHelper<UIntType, r, IsPowerOfTwo(r)>
Related
gsl::not_null has 2 constructors one taking a forwarding reference and another one taking a value type. What is the case where the forwarding constructor alone would not work? Implementation from here
template <class T>
class not_null
{
public:
static_assert(details::is_comparable_to_nullptr<T>::value, "T cannot be compared to nullptr.");
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr not_null(U&& u) : ptr_(std::forward<U>(u))
{
Expects(ptr_ != nullptr);
}
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
constexpr not_null(T u) : ptr_(std::move(u))
{
Expects(ptr_ != nullptr);
}
...
Commit history gives the answer - https://github.com/microsoft/GSL/commit/cb2d1af89afb76bf50efe8e068c5ea1fc2872274
This allows compilers with c++17 support to infer template
instantiation types when calling not_null constructor:
int foo(not_null<const int*> x);
int main()
{
int t = 0;
not_null x{ &t };
return foo(not_null{ &t });
}
i.e. with this constructor you can write just not_null x{ &t } instead of not_null<int *> x{ &t }.
I ran into a problem with setting a function as a default parameter.
The following code doesn't make a lot of sense. What I want to achieve can be done in many different ways. This code only describes the problem I ran into and wish to know how to fix it to work to my specifications.
#include <iostream>
#include <vector>
int double_the_number(int x)
{
return x * 2;
}
template<typename T, typename FunctionType>
std::vector<FunctionType> copy_with_criteria(T iter1, T iter2, FunctionType F(FunctionType))
{
std::vector<int> new_vector;
while(iter1 != iter2)
{
new_vector.push_back(F(*iter1++));
}
return new_vector;
}
int main()
{
std::vector<int> v {1,2,3,4,5};
auto new_vector = copy_with_criteria(v.begin(), v.end(), double_the_number);
for(int x : new_vector) std::cout << x << " ";
return 0;
}
When the code above is ran, it will output 2 4 6 8 10
What I want to achieve is if I call a function without specifying the criteria function copy_with_criteria(v.begin(), v.end()) I want it to output 1,2,3,4,5
That is, somehow I would like to set the function as a default parameter which is a type of elements inside some container (in this case vector) and which returns number that has been sent to it, like this (TypeOfElements is just an example of what type the default criteria function should be):
TypeOfElements default_function(TypeOfElements x) {
return x;
}
I would not like to use any external libraries. Also I am working with c++11.
If anyone could help me with this problem I would be very grateful!
Thank you :)
Overload your function.
template <typename T>
std::vector<typename std::iterator_traits<T>::value_type>
copy_with_criteria(T iter1, T iter2)
{
return std::vector<typename std::iterator_traits<T>::value_type>(iter1, iter2);
}
You can define your function as:
template<typename T, typename FunctionType = typename std::decay<decltype(*std::declval<T>())>::type>
std::vector<FunctionType> copy_with_criteria(T iter1, T iter2, FunctionType(*F)(FunctionType) = [](FunctionType v){ return v; }) {
// ...
}
It works in C++11 as requested (see it on Coliru).
The basic idea is that you can deduce FunctionType directly from the type of the iterators and not from the function F. Then you can give to F a default by using a lambda function that is nothing more than an identity function.
Otherwise you can simply overload copy_with_criteria as suggested by aschepler (I'd rather go with his approach instead of using a default argument) or simply define a different function with a meaningful name that is explicit about your intention for you are not using criteria during that kind of copy.
Edit
As suggested by #aschepler in the comments, you can use iterator_traits<T>::value_type instead of typename std::decay<decltype(*std::declval<T>())>::type to avoid problems with some types.
Functions are the wrong thing to use here. State can easily be useful. You want to use a generic function object. And deduce the return value.
In addition, using iterator ranges is questionable. The next iteration of C++ range library is going to reduce that use.
While you want a C++11 solution, there is no reason to use the C++03/C++11 style. Be forward looking.
So let us get started.
#include <iterator>
namespace notstd {
namespace adl_helper {
using std::begin; using std::end;
template<class C>
auto adl_begin( C&& )
-> decltype( begin( std::declval<C>() ) );
template<class T, std::size_t N>
auto adl_begin( T(*)[N] )
-> T*;
}
template<class C>
using iterator_type=decltype(
::notstd::adl_helper::adl_begin( std::declval<C>() )
);
}
This finds the iterator type of a container via calling std::begin in an ADL-enabled context. This emulates what a for(:) loop does reasonably well.
namespace notstd {
template<class C>
using value_type = typename std::iterator_traits<
iterator_type<C>
>::value_type;
}
now we can value_type<C> for some type C and get the type it contains.
namespace notstd {
struct make_a_copy_t {
template<class T>
auto operator()(T&& t)const
-> std::decay_t<T>
{
return std::forward<T>(t);
}
};
}
make_a_copy_t is a functor that copies stuff.
We are almost ready to solve your problem.
template<class Op=notstd::make_a_copy_t, class C,
class R=decltype( std::declval<Op&>()(std::declval<notstd::value_type<C&>>()) )
>
std::vector<R>
copy_with_criteria(C&& c, Op op={})
{
std::vector<R> new_vector;
for (auto&& e:std::forward<C>(c))
{
new_vector.push_back( op(decltype(e)(e)) );
}
return new_vector;
}
and I believe this satisfies your criteria.
You may also need
namespace notstd {
template<class It>
struct range_t {
It b = {};
It e = {};
It begin() const { return b; }
It end() const { return e; }
range_t( It s, It f ):b(std::move(s)), e(std::move(f)) {}
range_t( It s, std::size_t count ):
range_t( s, std::next(s, count) )
{}
range_t() = default;
range_t(range_t&&)=default;
range_t(range_t const&)=default;
range_t& operator=(range_t&&)=default;
range_t& operator=(range_t const&)=default;
range_t without_front(std::size_t N)const {
return {std::next(begin(), N), end()};
}
range_t without_back(std::size_t N)const {
return {begin(), std::prev(end(),N)};
}
std::size_t size() const {
return std::distance(begin(), end());
}
// etc
};
template<class It>
range_t<It> range( It b, It e ) {
return {std::move(b), std::move(e)};
}
template<class It>
range_t<It> range( It b, std::size_t count ) {
return {std::move(b), count};
}
template<class C>
range_t<iterator_type<C&>> range( C& c ) {
using std::begin; using std::end;
return {begin(c), end(c)};
}
}
which lets you do operations on subsections of a container as a range.
So suppose you want to take the first half of a vector of int and double it.
std::vector<int> some_values{1,2,3,4,5,6,7,8,9,10};
auto front_half = notstd::range(some_values).without_back(some_values.size()/2);
auto front_doubled = copy_with_criteria( front_half, [](int x){return x*2;} );
and done.
Live example.
We have a huge legacy code base which is multithreaded and uses vectors extensively. To cut down the time spent in dynamic memory allocation, we are moving to a pools. The plan is to use Boost small vector with a custom allocator. The custom allocator will create a thread local pool per each container type. I have implemented a custom allocator based on the above idea and tested it. For some reason, the code falls in an infinite pattern inside find_prev method in Boost simple segregated storage. There are lots of places where there is a nesting of containers, like vector>> etc. Is this the right way of defining allocator ??
template<typename T, typename allocatorType>
class customAllocator
{
public:
static thread_local allocatorType *_allocator;
typedef T value_type;
typedef allocatorType allocator_Type;
template <class X> struct rebind
{
typedef customAllocator<X, allocatorType> other;
};
customAllocator()
{
_allocator = new allocatorType;
assert(_allocator);
return;
}
~customAllocator()
{
delete _allocator;
_allocator = nullptr;
return;
}
template<class X, class Y> customAllocator(const customAllocator<X, Y>& other)
{
_allocator = other._allocator;
return;
}
template<class X, class Y> customAllocator(customAllocator<X, Y>&& other)
{
_allocator = other._allocator;
other._allocator = nullptr;
return;
}
template<class X, class Y> customAllocator& operator=(const customAllocator<X, Y>& other)
{
_allocator = other._allocator;
return *this;
}
template<class X, class Y> customAllocator& operator=(customAllocator<X, Y>&& other)
{
_allocator = other._allocator;
other._allocator = nullptr;
return *this;
}
T* allocate(size_t n)
{
return _allocator->allocate(n * sizeof(T));
}
void deallocate(T* ptr, size_t n)
{
_allocator->deallocate(ptr, n);
return;
}
template<class X, class Y> bool operator==(const customAllocator<X, Y>& other) const noexcept
{ return (*this._allocator == other.allocator); }
template<class X, class Y> bool operator!=(const customAllocator<X, Y>& other) const noexcept
{ return !(*this._allocator == other._allocator); }
};
template <typename T1, typename T2>
thread_local T2 *customAllocator<T1, T2>::_allocator = nullptr;
using smallVector = boost::container::small_vector<
T,
DEFAULT_SMALL_VECTOR_LENGTH,
customAllocator<T,
boost::pool_allocator<
T,
boost::default_user_allocator_new_delete,
boost::details::pool::null_mutex,
2,
4
>>>;
I would like to use boost::range::combine as a cartesian power instead as just a product.
So instead of such expression boost::range::combine(myRange, myRange, myRange); write something like myCombine(myRange, 3);.
How it can be implemented?
Implementing this in C++17 or C++14 would be a lot easier and cleaner, but since you tagged this with c++11 here's a compliant implementation. Here's a generic way of calling a function object f with the same argument repeated N times.
First, we need a way of binding the first argument of a generic function object f and then accepting any number of arguments:
template <typename TF, typename T>
struct bound
{
TF _f;
T _x;
template <typename TFFwd, typename TFwd>
bound(TFFwd&& f, TFwd&& x)
: _f{std::forward<TFFwd>(f)}, _x{std::forward<TFwd>(x)}
{
}
template <typename... Ts>
auto operator()(Ts&&... xs)
-> decltype(_f(_x, std::forward<Ts>(xs)...))
{
return _f(_x, std::forward<Ts>(xs)...);
}
};
template <typename TF, typename T>
auto bind_first(TF&& f, T&& x)
-> decltype(bound<TF&&, T&&>(std::forward<TF>(f), std::forward<T>(x)))
{
return bound<TF&&, T&&>(std::forward<TF>(f), std::forward<T>(x));
}
Then, we need a recursive helper that will bind an argument x multiple TN times:
template <std::size_t TN>
struct helper
{
template <typename TF, typename T>
auto operator()(TF&& f, T&& x)
-> decltype(helper<TN - 1>{}(bind_first(std::forward<TF>(f), x), x))
{
return helper<TN - 1>{}(bind_first(std::forward<TF>(f), x), x);
}
};
template <>
struct helper<0>
{
template <typename TF, typename T>
auto operator()(TF&& f, T&& x)
-> decltype(f(x))
{
return f(x);
}
};
Finally, we can provide a nice interface:
template <std::size_t TN, typename TF, typename T>
auto call_with_same_arg(TF&& f, T&& x)
-> decltype(helper<TN - 1>{}(std::forward<TF>(f), std::forward<T>(x)))
{
return helper<TN - 1>{}(std::forward<TF>(f), std::forward<T>(x));
}
Usage:
int add(int a, int b, int c)
{
return a + b + c;
}
int main()
{
assert(call_with_same_arg<3>(add, 5) == 15);
}
live wandbox example
Here's a complete C++17 implementation of the same thing:
template <std::size_t TN, typename TF, typename T>
decltype(auto) call_with_same_arg(TF&& f, T&& x)
{
if constexpr(TN == 1)
{
return f(x);
}
else
{
return call_with_same_arg<TN - 1>(
[&](auto&&... xs){ return f(x, std::forward<decltype(xs)>(xs)...); }, x);
}
}
live wandbox example
For completeness, C++14 implementation:
template <std::size_t TN>
struct helper
{
template <typename TF, typename T>
decltype(auto) operator()(TF&& f, T&& x)
{
return helper<TN - 1>{}(
[&](auto&&... xs){ return f(x, std::forward<decltype(xs)>(xs)...); }, x);
}
};
template <>
struct helper<0>
{
template <typename TF, typename T>
decltype(auto) operator()(TF&& f, T&& x)
{
return f(x);
}
};
template <std::size_t TN, typename TF, typename T>
decltype(auto) call_with_same_arg(TF&& f, T&& x)
{
return helper<TN - 1>{}(std::forward<TF>(f), std::forward<T>(x));
}
live wandbox example
I'm looking for an "is_comparable" typetrait but can't find any.
It's very easy to build one that checks if an operator== for a class was implemented, but this excludes global defined operators.
Is it impossible to implement a is_comparable typetait?
I take it you mean a trait that, for two types L and R and
objects lhs and rhs of those types respectively, will yield true if
the lhs == rhs will compile and false otherwise. You appreciate that
in theory lhs == rhs might compile even though rhs == lhs, or lhs != rhs,
does not.
In that case you might implement the trait like:
#include <type_traits>
template<class ...> using void_t = void;
template<typename L, typename R, class = void>
struct is_comparable : std::false_type {};
template<typename L, typename R>
using comparability = decltype(std::declval<L>() == std::declval<R>());
template<typename L, typename R>
struct is_comparable<L,R,void_t<comparability<L,R>>> : std::true_type{};
This applies a popular SFINAE pattern for defining traits that is explained
in the answer to this question
Some illustrations:
struct noncomparable{};
struct comparable_right
{
bool operator==(comparable_right const & other) const {
return true;
}
};
struct any_comparable_right
{
template<typename T>
bool operator==(T && other) const {
return false;
}
};
bool operator==(noncomparable const & lhs, int i) {
return true;
}
#include <string>
static_assert(is_comparable<comparable_right,comparable_right>::value,"");
static_assert(!is_comparable<noncomparable,noncomparable>::value,"");
static_assert(!is_comparable<noncomparable,any_comparable_right>::value,"");
static_assert(is_comparable<any_comparable_right,noncomparable>::value,"");
static_assert(is_comparable<noncomparable,int>::value,"");
static_assert(!is_comparable<int,noncomparable>::value,"");
static_assert(is_comparable<char *,std::string>::value,"");
static_assert(!is_comparable<char const *,char>::value,"");
static_assert(is_comparable<double,char>::value,"");
If you want the trait to require that equality is symmetric and that inequality
also exists and is symmetric you can see how to elaborate it yourself.