The implementation of std::vector that ships with Visual Studio 2010 and earlier versions has a well known particularity: the resize method has the following signature (C++03-compliant):
void resize(size_type new_size, value_type value);
instead of the C++11-compliant signature that's been used by the majority of other STL implementations (like gcc's STL or STLport) long before C++11:
void resize(size_type new_size, const value_type& value);
The problem with the first variant is that, in some situations, it will fail to compile if value_type has an alignment specification:
struct __declspec(align(64)) S { ... };
std::vector<S> v; // error C2719: '_Val': formal parameter with __declspec(align('64')) won't be aligned
This is a well known problem with no satisfactory workaround apart from using a different implementation of std::vector.
I'm looking for a well-written, well-tested, self-contained and STL-compatible implementation of std::vector with a MIT-style licence that I could drop into my project as a container of choice for aligned types.
I considered extracting it from STLport or gcc's STL but, being fully standard-compliant, they're both large with many non-trivial dependencies.
(I would be perfectly happy with an implementation of a reasonable subset of std::vector that would only support push_back, clear, capacity, size, reserve, resize, swap and array indexing.)
Any ideas?
The guys behind the Eigen library seem to have found a nice workaround for the problem of storing "overly-aligned types" (as Stephan T. Lavavej call them) into a std::vector as implemented in Visual Studio's STL.
Their implementation seems unnecessary complicated (check the sources here and here) but the main idea is to encapsulate the type that goes into the std::vector with a thin wrapper:
#include <vector>
template <typename T>
struct wrapper : public T
{
wrapper() {}
wrapper(const T& rhs) : T(rhs) {}
};
struct __declspec(align(64)) S
{
float x, y, z, w;
};
int main()
{
std::vector< wrapper<S> > v; // OK, no C2719 error
return 0;
}
About the implementation in Eigen, I must admit I don't quite understand
why they need Eigen::aligned_allocator_indirection,
why they need to make an exception for arithmetic types in EIGEN_WORKAROUND_MSVC_STL_SUPPORT,
why they need to define all these constructors and operators in Eigen::workaround_msvc_stl_support,
or why they need to redefine resize in their partial specialization of std::vector for the Eigen::aligned_allocator_indirection allocator...
Clues welcome. The point is, this trick works perfectly (as far as I can tell) and I don't see anything wrong with it, apart maybe from the slight inelegance.
The easiest (and best, imho) option would be to provide a free function as an extension to the vector interface, which does the right thing. The functions you need to implement resize are all available from the public interface of std::vector:
#include <vector>
template<class T, class Alloc>
void resize(std::vector<T, Alloc>& v,
typename std::vector<T, Alloc>::size_type new_size, T const& val)
{
if (v.size() < new_size)
v.insert(v.end(), new_size - v.size(), val);
else if (new_size < v.size())
v.erase(v.begin() + new_size, v.end());
}
And for consistency also the single argument version:
template<class T, class Alloc>
void resize(std::vector<T, Alloc>& v,
typename std::vector<T, Alloc>::size_type new_size)
{
v.resize(new_size); // simply forward
}
If you, however, just want to drop-in the new vector and never worry about free or member function, another option is to simply subclass std::vector:
#include <vector>
#include <memory>
template<class T, class Alloc = std::allocator<T>>
class myvector
: public std::vector<T, Alloc>
{
typedef std::vector<T, Alloc> base;
public:
typedef typename base::size_type size_type;
void resize(size_type new_size){
base::resize(new_size);
}
void resize(size_type new_size, T const& val){
if (this->size() < new_size)
this->insert(this->end(), new_size - this->size(), val);
else if (new_size < this->size())
this->erase(this->begin() + new_size, this->end());
}
};
Note that I also provided the single argument version of resize, since the two argument version would hide all base-class versions. Also note that I needed to prefix all member function calls with this->, since they are dependent on the base class std::vector, and as such on the template arguments.
Related
I am implementing a function that wants to loop over a number of elements in an std::array, but I don't really care how long the std::array is. So I was thinking of the following function:
#include <stdio.h>
#include <array>
#include <iterator>
void foo(std::array<bool,0>::const_iterator begin, std::array<bool,0>::const_iterator end)
{
printf("iterator");
}
int main()
{
std::array<bool, 25> one;
std::array<bool, 33> two;
foo(one.cbegin(), one.cend());
foo(two.cbegin(), two.cend());
}
I am quite okay with this, except for the std::array<bool,0>. My question is, is there another way to specify the iterator that is required for this function?
Update
There are some things I should mention. Of course this code is part of a bigger scope and I tried to hide as much detail as I could.
I want to ensure that the iterator being used is of bools.
I am using C++14
The function is part of a class interface and I want to be able to handle multiple array sizes. I don't want to bother the implementors of the interface to know exactly what the size of the array is.
class MyInterface
{
public:
virtual foo(std::array<bool,0>::const_iterator begin, std::array<bool,0>::const_iterator end) = 0;
~MyInterface() = default;
};
I remembered that virtual functions cannot be templated. That means I would have to template my whole interface and that would exactly loose the point of why I was trying this in the first place.
You can just make it a function template as
template <typename I>
void foo(I begin, I end)
{
std::cout << "iterator";
}
You don't need to care about container type (and the size), you can pass iterators of std::array, std::vector and std::string and so on, even raw pointers (which also satisfies iterator's requirements).
Just use span:
#include <array>
#include <span>
class MyInterface {
public:
virtual void foo(std::span<bool> barr) = 0;
// interface destructors should be virtual
virtual ~MyInterface() = default;
};
void bar(MyInterface& interface) {
std::array<bool, 42> arr;
interface.foo(arr);
}
If you don't have access to a C++20 compiler, you may use gsl::span from gsl instead.
Use a template:
template <size_t N>
void foo(std::array<bool,N>::const_iterator begin, std::array<bool,N>::const_iterator end)
{
printf("iterator");
}
And now as long as both iterators come from an array of size N this function will work.
If you want to accept iterators from different sized arrays, you just need to add another template parameter for the second iterator like
template <size_t N, size_t M>
void foo(std::array<bool,N>::const_iterator begin, std::array<bool,M>::const_iterator end)
{
printf("iterator");
}
If the function accepts two iterators when the referring std::array is redundant. Just declare the function like
template <class Iterator>
void foo( Iterator first, Iterator last );
In the declaration you can name the iterator that corresponds to the used iterator type in the function like for example
template <class ForwardIterator>
void foo( ForwardIterator first, ForwardIterator last );
Or instead of the name ForwardIterator you could use the name BidirectionalIterator or RandomAccessIterator for self-documenting.
If you need to know the value type of the iterator you can use different approaches. For example
template <class Iterator>
void foo( Iterator first, Iterator last )
{
using value_type = typename std::iterator_traits<Iterator>::value_type;
if ( first != last )
{
value_type item1 = *first;
// or
auto item2 = *first;
//
const auto &item3 = *first;
//...
}
}
In this case you will have a flexible function definition. For example if in future you will change std::array<N, bool> to std::vector<bool> the function will as usual work.
I'd like to have a function as described in title.
I've noticed that STL algorithms that work with containers of any type (list, vector, etc) containing elements of any type (int, double) provide genericity by using iterator types as template parameters, e.g.
template<typename _II, typename _OI>
inline _OI
copy(_II __first, _II __last, _OI __result)
This is a good method until the algorithm works for any type of elements. The only requirement for element type is that it must have copy constructor.
But suppose we have one concrete type
class MyElement
{
public:
void doSomethingWithElement();
};
and we want to implement a function that processes number of elements of this type by calling function doSomethingWithElement().
Writing a function that receives container of specific type is not very convenient because many containers are treated in the same way (e.g. iterators), and if there will be need for processing containers of different types we'll be forced to duplicate the code. Writing a template works fine, but it seems ugly because we have to implement function in place where it is declared (in header file). Also, when we want to process elements of only one type, parametrizing this type is not the right way to achieve the goal.
I've been thinking about iterator interface that could be used like
void processContainer(IIterator<MyElement> begin, IIterator<MyElement> end);
If this iterator had pure virtual operator++ and operator* that were implemented in derived classes, we could pass such objects to processContainer. But there is a problem: if IIterator is abstract class, we can't instantiate it in the implementation of processContainer, and if we pass a pointer to IIterator, this function will be able to modify it.
Does anybody know any other hack to do this? Or would be another approach better than these ones above? Thanks in advance.
The simpler approach is to ignore the restriction and just implement your function as a template for any iterator. If the iterator does not refer to the type, then the user will get a horrible error message in the lines of "type X does not have doSomethingWithElement member function`.
The next thing would be to provide a static_assert, the function would still take any iterator (meaning that it will participate in overload resolution for any type) but the error message will be slightly more informative.
Furthermore you can decide to use SFINAE to remove the overload from the set of candidates. But while SFINAE is a beautiful golden hammer, I am not sure that you have the appropriate nail at hand.
If you really want to go further down the lane, you can take a look at any_iterator in the Adobe libraries as an example on how to perform type erasure on the iterator type to avoid the template. The complexity of this approach is orders of magnitude higher than any of the previous, and the runtime cost will also be higher, providing the only advantage of a cleaner ABI and less code size (different iterators can be passed to a single function).
You could use std::for_each(): http://www.cplusplus.com/reference/algorithm/for_each/
full code:
void callDoSomething(MyElement &elem)
{
elem.doSomething();
}
int main()
{
std::vector<MyElement> vec(100);
std::for_each(vec.begin(), vec.end(), callDoSomething);
}
You can't do exactly what you want to do. You could use enable_if to limit the function's availability:
template < typename Container >
typename enable_if<is_same<typename Container::value_type, MyElement>,void>::type processContainer(Container c)...
It's not possible to create an abstract iterator that has the full iterator functionality - including the ability to make copies of itself - without changing the iterator interface. However, you can implement a subset of iterator functionality using an abstract base class:
#include <iterator>
#include <vector>
#include <list>
template<typename T>
struct AbstractIterator
{
virtual bool operator!=(const AbstractIterator<T>& other) const = 0;
virtual void operator++() = 0;
virtual T& operator*() = 0;
};
template<typename Iterator>
struct ConcreteIterator : AbstractIterator<typename std::iterator_traits<Iterator>::value_type>
{
typedef typename std::iterator_traits<Iterator>::value_type value_type;
Iterator i;
ConcreteIterator(Iterator i) : i(i)
{
}
virtual bool operator!=(const AbstractIterator<value_type>& other) const
{
return i != static_cast<const ConcreteIterator*>(&other)->i;
}
virtual void operator++()
{
++i;
}
virtual value_type& operator*()
{
return *i;
}
};
template<typename Iterator>
ConcreteIterator<Iterator> wrapIterator(Iterator i)
{
return ConcreteIterator<Iterator>(i);
}
class MyElement
{
public:
void doSomethingWithElement();
};
void processContainerImpl(AbstractIterator<MyElement>& first, AbstractIterator<MyElement>& last)
{
for(; first != last; ++first)
{
(*first).doSomethingWithElement();
}
}
template<typename Iterator>
void processContainer(Iterator first, Iterator last)
{
ConcreteIterator<Iterator> wrapFirst = wrapIterator(first);
ConcreteIterator<Iterator> wrapLast = wrapIterator(last);
return processContainerImpl(wrapFirst, wrapLast);
}
int main()
{
std::vector<MyElement> v;
processContainer(v.begin(), v.end());
std::list<MyElement> l;
processContainer(l.begin(), l.end());
}
I've written an asynchronous job queue class which has been working nicely for ages. It uses a std::vector as the underlying collection to keep jobs in and then processes them later as you might expect. When I add a job it does a push_back on this vector.
Recently I decided that I wanted to templatize the underlying collection type that it uses and the with way I've written it, this should be very simple. It's now declared thus:
template<typename J, typename CollectionT = std::vector<J>>
class async_jobqueue
{
public:
There's just one snag, for vectorish type containers I want to push things onto the end of the collection and call push_back, for settish type containers I'll want to call insert. How can I make a compile decision about which to call? Or is there a handy adapter I can use?
I would rather use an overloaded helper function. The one below relies on the fact that no Standard container exposes both a single-argument insert() function and a push_back() function:
#include <utility>
template<typename C, typename T>
auto insert_in_container(C& c, T&& t) ->
decltype(c.push_back(std::forward<T>(t)), void())
{
c.push_back(std::forward<T>(t));
}
template<typename C, typename T>
auto insert_in_container(C& c, T&& t) ->
decltype(c.insert(std::forward<T>(t)), void())
{
c.insert(std::forward<T>(t));
}
This is how you would use them:
#include <set>
#include <vector>
#include <iostream>
int main()
{
std::set<int> s;
std::vector<int> v;
insert_in_container(s, 5);
insert_in_container(v, 5);
std::cout << s.size() << " " << v.size();
}
And here is a live example.
How about the insert(iterator, value_type) overload and calling it with end()? It's available in both and should do what you want! Works on std::list as well!
There's really no need for type-dispatching here.
Since concepts-lite should hopefully be popping up in time for C++14, I might as well show you how this will be done then:
template<typename J, typename CollectionT = std::vector<J>>
class async_jobqueue
{
public:
requires Associative_container<CollectionT>()
void adding_function(const J& item) {
// Uses insert
}
requires Sequence_container<CollectionT>()
void adding_function(const J& item) {
// Uses push_back
}
};
Of course, this is not possible yet (and may never be). However, the reception to concepts-lite is pretty positive.
While refactoring, I wanted to change an array where entries are added to an std::vector, but for compatibility (persistency, downgrading,...), it still needs to have an upper limit.
What is the best way (elegant, stl-like, limited extra code) to have an stl-like container which is limited in size, so you know that inserting an entry fails?
Edit:
To clarify: I would like an stl-like container, that starts empty, that you can fill with entries and possibly remove entries and that iterate over the filled-in entries, but that doesn't allow to put in more than e.g. 50 entries, so almost like a sequential contrainer, but with an upper-limit.
A simple solution would be encapsulating a vector inside your own limited size container. You could use private composition or private inheritance --note that private inheritance models implemented in terms of and does not have some of the shortcomings of public inheritance.
EDIT: Sketch of the solution with private inheritance
template <typename T, unsigned int N>
class fixed_vector : std::vector<T>
{
typedef std::vector<T> vector_type;
public:
typedef typename vector_type::reference reference;
typedef typename vector_type::const_reference const_reference;
typedef typename vector_type::iterator iterator;
typedef typename vector_type::const_iterator const_iterator;
typedef typename vector_type::value_type value_type;
typedef typename vector_type::size_type size_type;
fixed_vector() : vector_type() {}
fixed_vector( size_type size, value_type const & value = value_type() )
: vector_type(size,value)
{}
void push_back( value_type v ) {
ensure_can_grow();
vector_type::push_back( v );
}
iterator insert( iterator position, value_type const & v ) {
ensure_can_grow();
vector_type::insert( position, v );
}
void reserve( size_type size ) {
if ( size > N ) throw std::invalid_argument();
vector_type::reserve( size );
}
size_type capacity() const {
// In case the default implementation acquires by default
// more than N elements, or the vector grows to a higher capacity
return std::min( vector_type::capacity(), N );
}
// provide other insert methods if required, with the same pattern
using vector_type::begin;
using vector_type::end;
using vector_type::operator[];
using vector_type::erase;
using vector_type::size;
using vector_type::empty;
private:
void ensure_can_grow() const {
// probably a different exception would make sense here:
if ( this->size() == N ) throw std::bad_alloc();
}
};
There is quite a bit of hand-waving there... std::vector take more arguments that could be added to the façade. If you need any of the other methods or typedefs, you can just bring them into scope with a using declaration, redefine the typedef, or implement the adaptor with your particular test.
Also, in this implementation the size is a compile time constant, but it would be really simple to modify it into a constructor parameter.
Customize the vector class to impose an upper limit.
Probably, you can have a new api exposed which will check the size against the upper limit and return false if exceeds otherwise call the regular insertion method.
Have a look at this static_vector implementation which I found a while ago. I think it does exactly what you want.
It's distributed under the very liberal boost license, so you're allowed to do just about anything with it.
You can create a custom allocator (e.g. derived from std::allocator) that refuses to allocate an array larger than a given size.
Note that you need to call reserve( vector_max ) on the resulting object before adding things to it. I'm filing a defect against the C++ standard, as the requirement should be unnecessary (and it is, on recent versions of GCC).
template< typename T, size_t N >
struct limited_alloc : std::allocator< T > {
size_t max_size() const { return N; }
typename std::allocator<T>::pointer allocate( size_t n ) {
if ( n < N ) return std::allocator<T>::allocate( n );
throw std::length_error( "array too large" );
}
limited_alloc() {} // silly cruft for standard requirements:
template< typename T2 >
limited_alloc( limited_alloc<T2,N> const & ) {}
template< typename T2 >
struct rebind { typedef limited_alloc<T2,N> other; };
};
enum { vector_max = 40 };
template< typename T >
struct limited_vector {
typedef std::vector< T, limited_alloc< T, vector_max > > type;
};
void f() {
limited_vector< int >::type x;
x.reserve( vector_max );
x.assign( vector_max + 1, 3 ); // throws.
}
Take a look at Boost.Array
As replacement for ordinary arrays, the STL provides class std::vector. However, std::vector<> provides the semantics of dynamic arrays. Thus, it manages data to be able to change the number of elements. This results in some overhead in case only arrays with static size are needed.
Take a look at boost::array
Edit: for add/delete boost::optional can be used as a element type of boost::array.
Is there, perhaps in boost, consistent element access semantics which works across containers?
something along the lines of:
element_of(std_pair).get<1>();
element_of(boost_tuple).get<0>();
element_of(pod_array).get<2>();
in principle i can write myself, but I would rather not reinvent the wheel.thanks
Containers have different ways of accessing them because they are inherently different. The closest that you get in the STL are iterators. All of the standard containers have iterators, so you can iterate over them and use the same algorithms on them using those iterators. However, what each iterator contains differs depending on the container (must just have the element, but maps have pairs). And if you're looking at pair as a container, it's not going to fit in with the rest because it doesn't have iterators.
In most cases, using iterators solves the problem. However, it obviously doesn't completely solve the problem, and the STL does not have a solution for it. Boost may, but I'm unaware of one.
The main point, however, is that containers are inherently different and to a great extent are not meant to be interchangeable. By using standard iterators, most containers can be swapped for one another fairly easily. But it doesn't generally make sense to swap one container for another without changing some of the code around it because they act so differently. I believe that Scott Meyers makes a point of this in his book "Effective STL."
If you're really trying to make the various containers interchangeable, I'd suggest rethinking that and looking more closely at what you're doing. Odds are that that's not the best idea. Now, it may very well be a good idea for your particular application - I certainly can't say without knowing anything about it, and you'd be the best judge of that - but in the general case, making containers truly interchangeable is a bad idea. Iterators make it possible to reuse many algorithms on them, but even there, the type of algorithms that you can use on a particular container varies depending on the type of iterators that that container uses (random access, bi-directional, etc.).
So, no, I'm not aware of a pre-existing solution for accessing container elements other than iterators, but generally speaking, I'd advise against attempting it. Containers are not truly interchangeable and are not meant to be.
I'm not aware of such a thing.
You could most probably just implement a free get function for the types you're interested in. Boost.Tuple already has it. std::pair has it in C++0x. And the rest shouldn't be too complicated.
E.g
#include <iostream>
#include <utility>
#include <vector>
#include <boost/tuple/tuple.hpp>
namespace getter
{
template <size_t Index, class Container>
typename Container::reference get(Container& c)
{
return c[Index];
}
template <size_t Index, class Container>
typename Container::const_reference get(const Container& c)
{
return c[Index];
}
template <size_t Index, class T>
T& get(T *arr)
{
return arr[Index];
}
namespace detail {
template <size_t Index, class T, class U>
struct PairTypeByIndex;
template <class T, class U>
struct PairTypeByIndex<0u, T, U>
{
typedef T type;
type& operator()(std::pair<T, U>& p) const { return p.first; }
const type& operator()(const std::pair<T, U>& p) const { return p.first; }
};
template <class T, class U>
struct PairTypeByIndex<1u, T, U>
{
typedef U type;
type& operator()(std::pair<T, U>& p) const { return p.second; }
const type& operator()(const std::pair<T, U>& p) const { return p.second; }
};
}
template <size_t Index, class T, class U>
typename detail::PairTypeByIndex<Index, T, U>::type& get(std::pair<T, U>& p)
{
return detail::PairTypeByIndex<Index, T, U>()(p);
}
template <size_t Index, class T, class U>
const typename detail::PairTypeByIndex<Index, T, U>::type& get(const std::pair<T, U>& p)
{
return detail::PairTypeByIndex<Index, T, U>()(p);
}
using boost::get;
}
int main()
{
boost::tuple<int, int> tuple(2, 3);
std::cout << getter::get<0>(tuple) << '\n';
std::vector<int> vec(10, 1); vec[2] = 100;
std::cout << getter::get<2>(vec) << '\n';
const int arr[] = {1, 2, 3, 4, 5};
std::cout << getter::get<4>(arr) << '\n';
std::pair<int, float> pair(41, 3.14);
++getter::get<0>(pair);
const std::pair<int, float> pair_ref = pair;
std::cout << getter::get<0>(pair_ref) << ' ' << getter::get<1>(pair_ref) << '\n';
}
I'm not aware of any generic accessors that would work across all known definitions of containers in C++. However, Boost.Range can be used as such to some extent.
For better flexibility, you will likely need to implement it yourself. Perhaps scratching something along this:
struct container_accessor { ... }
template <typename Container>
container_accessor make_accessor(Container& c) { ... }
template <typename Container>
container_const_accessor make_accessor(Container const& c) { ... }
where and then specialise container_accessor for all containers you need.