Template function + functor argument, why the functor is not inlined? - c++

The code below executes 4x faster, if near "REPLACING WITH .." line, the functor compare_swaps() will be replaced with direct reference to my_intcmp(). Apparently the indirect use is not being inlined. Why?
inline bool my_intcmp( const int & a, const int & b ) {
return a < b;
}
template <class T, class compare>
void insertion_sort_3( T* first, T* last, compare compare_swaps ) {
// Count is 1?
if( 1 == (last - first) )
return;
for( T* it = first + 1; it != last; it ++ ) {
T val = *it;
T* jt;
for( jt = it; jt != first; jt -- ) {
// REPLACING WITH if( my_intcmp(val, *(jt - 1) ) gives 4x speedup, WHY?
if( compare_swaps(val, *(jt - 1)) ) {
*jt = *(jt - 1);
} else {
break;
}
}
*jt = val;
}
}
#define SIZE 100000
#define COUNT 4
int main() {
int myarr[ SIZE ];
srand( time(NULL) );
int n = COUNT;
while( n-- ) {
for( int i = 0; i < SIZE; i ++ )
myarr[ i ] = rand() % 20000;
insertion_sort_3( myarr, myarr + SIZE, my_intcmp );
}
return 0;
}

The compiler sees a function pointer which he can't really determine as not changing. I have seen this a couple of times before. The fix to the problem is to use a simple wrapper struct:
struct my_intcmp_wrapper
{
bool operator()(int v0, int v1) const {
return my_intcmp(v0, v1);
}
};
Specifically for build-in types you probably want to pass the objects by value rather than by reference. For inlined functions it probably doesn't make much of a difference but if the function isn't inlined it generally makes the situation worse.

Related

Angelscript transfer array from C++

I need to transfer an array of tiles from C++ to Angelscript, I have tried adding a function that returns an std::vector but it returns this error
Failed in call to function 'RegisterGlobalFunction' with 'array<DumbTile> GetTilesAt(int x, int y)' (Code: asINVALID_DECLARATION, -10)
my code:
std::vector<DumbTile> GetTilesAt(int x, int y) {
std::vector<DumbTile> output;
for (DumbTile t : tiles) {
if (t.x == x && t.y == y) {
output.push_back(t);
}
}
return output;
}
engine->RegisterGlobalFunction("array<DumbTile> GetTilesAt(int x, int y)", asFUNCTIONPR(GetTilesAt, (int, int), std::vector<DumbTile>), asCALL_CDECL);
Is DumbTile registered before GetTilesAt() registration?
Is array<T> registered before GetTilesAt() registration?
Both needs to be registered before you can register your function.
Are you using stock array implementation (sdk/add_on/scriptarray/) or your own, std::vector<>-based implementation? When using stock addon, application must convert std::vector to CScriptArray first, as angelscript can't really do that on its own due to way how arrays works.
There is obvious alternative - switch from using std::vector to CScriptArray everywhere where you want scripts to access data, but this might be annoying.
Example std::vector<Object*> <-> CScriptArray* conversion
template<typename Type>
void AppendVectorToArrayRef( vector<Type>& vec, CScriptArray* arr )
{
if( !vec.empty() && arr )
{
uint i = (uint)arr->GetSize();
arr->Resize( (asUINT)(i + (uint)vec.size() ) );
for( uint k = 0, l = (uint)vec.size(); k < l; k++, i++ )
{
Type* p = (Type*)arr->At( i );
*p = vec[k];
(*p)->AddRef();
}
}
}
template<typename Type>
void AssignScriptArrayInVector( vector<Type>& vec, CScriptArray* arr )
{
if( arr )
{
uint count = (uint)arr->GetSize();
if( count )
{
vec.resize( count );
for( uint i = 0; i < count; i++ )
{
Type* p = (Type*)arr->At( i );
vec[i] = *p;
}
}
}
}
Code is bit old but i think it should still work, even if it begs for some refresh.

Why do we use a wrapper function for a recursive function?

What is the purpose of a wrapper over recursive function?
Why can't we directly call the recursive function from the main function?
I've come across some explanations saying that wrapper function helps in better parameter passing - I don't understand this.
EDIT:
Consider the example of a binary search based function that returns the index of a peak element:
int findPeakUtil(int arr[], int low,
int high, int n)
{
// Find index of middle element
int mid = low + (high - low)/2;
// Compare middle element with its neighbours (if neighbours exist)
if ((mid == 0 || arr[mid - 1] <= arr[mid]) &&
(mid == n - 1 || arr[mid + 1] <= arr[mid]))
return mid;
// If middle element is not peak and its
// left neighbour is greater than it,
// then left half must have a peak element
else if (mid > 0 && arr[mid - 1] > arr[mid])
return findPeakUtil(arr, low, (mid - 1), n);
// If middle element is not peak and its
// right neighbour is greater than it,
// then right half must have a peak element
else return findPeakUtil(arr, (mid + 1), high, n);
}
// A wrapper over recursive function findPeakUtil()
int findPeak(int arr[], int n)
{
return findPeakUtil(arr, 0, n - 1, n);
}
Why is it recommended to use the wrapper function?
A wrapper function can prepare a call of a recursive function. For example a recursive function has more parameters then initially the user supplies. Or can make a preliminary checks of the validity of arguments and tests pre-conditions.
Here is a simple example provided for the demonstrative purpose.
#include <iostream>
#include <cstring>
char * recursive_reverse( char *s, size_t n )
{
if ( n < 2 ) return s;
char c = s[0];
s[0] = s[n-1];
s[n-1] = c;
recursive_reverse( s + 1, n - 2 );
return s;
}
char * reverse( char *s )
{
return recursive_reverse( s, std::strlen( s ) );
}
int main()
{
char s[] = "Hello DEBNATH KUNDU";
std::cout << s << '\n';
std::cout << reverse( s ) << '\n';
return 0;
}
The program output is
Hello DEBNATH KUNDU
UDNUK HTANBED olleH
Another example is when a class has a non-static public member function that calls a static (private/protected) recursive member function passing to it required data members of the object of the class. So in this case the non-static member function provides the public interface and the non-static recursive function provides the implementation of the interface.
Here is one more demonstrative program.
#include <iostream>
#include <utility>
#include <cstring>
class String
{
private:
enum Size : size_t { N = 100 };
char s[N];
static void recursive_reverse( char *s, size_t n )
{
if ( not ( n < 2 ) )
{
std::swap( s[0], s[n-1] );
recursive_reverse( s + 1, n - 2 );
}
}
public:
explicit String( const char *s )
{
strncpy( this->s, s, N );
this->s[N-1] = '\0';
}
void reverse() { recursive_reverse( s, std::strlen( s ) ); }
friend std::ostream & operator <<( std::ostream &os, const String &s )
{
return os << s.s;
}
};
int main()
{
String s( "Hello DEBNATH KUNDU" );
std::cout << s << '\n';
s.reverse();
std::cout << s << '\n';
return 0;
}
Its output is the same as shown above.
However it does not mean that a wrapper function is always required.

Fill vector using function specified by enum

The functionality that I want is like:
std::vector<float> GetFuncVec(int N, FuncType type)
{
std::vector<float> fn(N);
float tmp = (N - 1) / 2.0;
switch (type) {
case SIN:
for (int i=0; i<N; ++i)
fn[i] = sin(M_PI * i / tmp);
break;
case SINC:
for (int i=0; i<N; ++i)
fn[i] = sin(M_PI * i / tmp) / (M_PI * i / tmp);
break;
...
}
return fn;
}
I find this unsatisfactory because there is a lot of code duplication. Looking around, I found the STL algorithm std::generate() which can fill a vector using a functor, which can have an increment member to play the role of i.
I see two potential routes. The first is to use a factory to initialize the functor. The problem with this method is code separation (above, the different cases are kept nicely together) and increased overheads with multiple new classes needed.
The second is to use lambda functions (which I have very little experience with). This is nice because I can define each function in a single line in the switch statement. But I don't see how I can avoid a scoping problem (the lambda function is not accessible outside the scope of the switch statement).
Is there a solution using lambda functions? What is the best option, from an efficiency viewpoint and from a readability viewpoint?
Maybe you want something like this...? (see it run here
#include <iostream>
#include <vector>
#include <cmath>
#include <functional>
enum Func { Sin, Sinc };
std::vector<float> f(int n, Func func)
{
std::vector<float> results(n);
float tmp = (n - 1) / 2.0;
int i;
std::function<float()> fns[] = {
[&] { return sin(M_PI * i / tmp); },
[&] { return sin(M_PI * i / tmp) / (M_PI * i / tmp); }
};
auto& fn = fns[func];
for (i=0; i<n; ++i)
results[i] = fn();
return results;
}
int main()
{
std::vector<float> x = f(10, Sin);
for (auto& v : x) std::cout << v << ' '; std::cout << '\n';
std::vector<float> y = f(10, Sinc);
for (auto& v : y) std::cout << v << ' '; std::cout << '\n';
}
Output:
0 0.642788 0.984808 0.866025 0.34202 -0.34202 -0.866025 -0.984808 -0.642788 -2.44929e-16
-nan 0.920725 0.705317 0.413497 0.122477 -0.0979816 -0.206748 -0.201519 -0.115091 -3.89817e-17
One option that may not be fast (there is indirection on each function call) but that would be a bit more flexible would be to create an std::map<FuncType, std::function<float(int,float)>>. You can't use std::generate() because you need the argument i to calculate the result, but writing your own is not that hard:
template <typename Iterator, typename Generator, typename Index, typename... Args>
void generate_i(Iterator first, Iterator last, Generator gen, Index i, Args... args)
{
while (first != last) {
*first = gen(i, args...);
++i;
++first;
}
}
Now that we have this, we need to populate a map of functors:
using FuncTypeFunction = std::function<float(int,float)>;
using FuncTypeFunctionMap = std::map<FuncType, FuncTypeFunction>;
FuncTypeFunctionMap create_functype_map()
{
FuncTypeFunctionMap functions;
functions[SIN] = [] (int i, float tmp) {
return sin(M_PI * i / tmp);
};
functions[SINC] = [] (int i, float tmp) {
return sin(M_PI * i / tmp) / (M_PI * i / tmp);
};
// ...
return functions;
}
FuncTypeFunctionMap const FuncTypeFunctions = create_functype_map();
(If you prefer you can use boost.assign to improve readability of this bit.)
And finally, we can use this map:
std::vector<float> GetFuncVec(int N, FuncType type)
{
std::vector<float> fn(N);
float tmp = (N - 1) / 2.0;
auto func = FuncTypeFunctions.find(type);
if (func != FuncTypeFunctions.end()) {
generate_i(fn.begin(), fn.end(), func->second, 0, tmp);
}
return fn;
}
Adding new functions only requires populating the map in create_functype_map(). Note that each iteration in the generate_i() loop is going to invoke the operator() on std::function, which will require a level of indirection to resolve the call, similar to the overhead of a virtual method invocation. This will cost a bit in terms of performance but may not be an issue for you.
(See a demo)
You may write a general class that will be used in standard algorithm std::iota
For example
#include <iostream>
#include <functional>
#include <vector>
#include <numeric>
class Value
{
public:
Value() : i( 0 ), fn( []( size_t i ) { return ( float )i; } ) {}
Value & operator ++() { ++i; return *this; }
operator float () const { return fn( i ); }
Value & operator =( std::function<float( size_t )> fn )
{
this->fn = fn;
return *this;
}
private:
size_t i;
std::function<float( size_t )> fn;
};
enum E { First, Second };
std::vector<float> f( size_t N, E e )
{
Value value;
float tmp = N / 2.0f;
switch( e )
{
case First:
value = [tmp] ( size_t i ) { return i * tmp; };
break;
case Second:
value = [tmp] ( size_t i ) { return i * tmp + tmp; };
break;
}
std::vector<float> v( N );
std::iota( v.begin(), v.end(), value );
return v;
}
int main()
{
for ( float x : f( 10, First ) ) std::cout << x << ' ';
std::cout << std::endl;
for ( float x : f( 10, Second ) ) std::cout << x << ' ';
std::cout << std::endl;
return 0;
}
The output is
0 5 10 15 20 25 30 35 40 45
5 10 15 20 25 30 35 40 45 50
Of course you may use your own lambda expressions that include some mathematical functions like sin

I cannot make a copy constructor for a bidirectional map

I am in my first year of c++ at university and in some days i have exam.
I work hard for this exam not only to succeed but to succeed with the best mark.
In this code that I post I have to make a bidirectional map which i was able to do and some other functions for it.
The problem comes when i try to make a copy constructor for this bidirectional map.
I know it is a little shameful to come to you guys with this minor problem but I last give a try.
If someone of you has patience to help me i will be very happy to succeed with high mark at my c++ exam.
So here is the header where i create a bidirectional map.This contains 2 maps: one stores the key and the value and other stores the value like key and the first key like the value. The problem comes when i have to do a copy constructor and I not have the optimal knowledge to do this.
#ifndef BIMAP_H_INCLUDED
#define BIMAP_H_INCLUDED
#include<map>
#include <utility>
template <class T>
class BidirectionalMap
{
public:
BidirectionalMap(){};
BidirectionalMap(typename std::multimap<T,T>::iterator beg, typename std::multimap<T,T>::iterator end)
{
m1.insert(beg,end
}
void insert(T a, T b)
{
m1.insert(std::pair<T,T> (a,b));
m2.insert(std::pair<T,T> (b,a));
}
BidirectionalMap& operator =(const BidirectionalMap &c)
{
m1=c.m1;
m2=c.m2;
return *this;
}
const T& at(const T &a) const
{
if(m2.find(a)!=m2.end()) return m2.at(a);
else return m1.at(a);
}
int count(const T &a) const
{
if(m2.find(a)!=m2.end()) return m2.count(a);
else if(m1.find(a)!=m1.end()) return m1.count(a);
else return 0;
}
void erase(const T &a)
{
if(m1.find(a)!=m1.end())
{
T b=m1[a];
m1.erase(a);
m2.erase(b);
}
else
{
T b=m2[a];
m2.erase(a);
m1.erase(b);
}
}
int size() const
{
return m1.size();
}
typename std::map<T,T>::const_iterator begin() const
{
return m1.begin();
}
typename std::map<T,T>::const_iterator end() const
{
return m1.end();
}
private:
std::map<T,T> m1;
std::map<T,T> m2;
};
#endif // BIMAP_H_INCLUDED
And here is the main() where i use that bidirectional map.Do not focus on 2,3,4 but only on 5 because just there I have no idea.
#include <map>
#include <functional>
#include <iostream>
#include <algorithm>
#include <string>
#include "bimap.h"
struct LengthSum
{
int length;
LengthSum():length(0) {}
void operator()(const std::pair<std::string, std::string>& p)
{
length += p.first.length();
length += p.second.length();
}
};
const int max = 1000;
int main()
{
int yourMark = 1;
// 2-es
BidirectionalMap<int> fun;
for( int i = 1; i <= max; ++i )
fun.insert( i, i + max );
BidirectionalMap<std::string> tel;
tel.insert( "Aniko", "+36(70)555-8124" );
tel.insert( "Botond", "+36(30)555-4321" );
const BidirectionalMap<std::string> ctel = tel;
if ( fun.at( 1 ) == (1 + max) &&
ctel.at( "+36(30)555-4321" ) == "Botond" )
{
yourMark = ctel.count( "Aniko" ) +
fun.count( max * 2 ) +
ctel.count( "Unknown" );
}
// 3-as
tel.erase( "+36(70)555-8124" );
if ( 0 == tel.count( "Aniko" ) &&
max == fun.size() )
{
yourMark = ctel.size() + tel.size();
}
// 4-es
const int l = std::for_each( ctel.begin(), ctel.end(), LengthSum() ).length;
yourMark = l/10;
// 5-os
std::map<double, double> md;
md[1.12] = 8.8;
md[5.4] = 7.5;
std::multimap<int, int> mmi;
mmi.insert( std::make_pair( 1, 2 ) );
mmi.insert( std::make_pair( 3, 6 ) );
mmi.insert( std::make_pair( 5, 8 ) );
//Here is the problem because i don`t know to do this :
const BidirectionalMap<int> b( mmi.begin(), mmi.end() );//??
const BidirectionalMap<double> bd( md.begin(), md.end() );//??
if ( b.at(8) == 5 )
{
yourMark = b.size() +
bd.size() +
b.count( 9 );
}
std::cout << "Your mark is " << yourMark;
std::endl( std::cout );
}
For the 2,3,4 marks i succeeded but when it comes for the best mark(5 in my country) i crashed.
So if you have the time and patience PLEASE help me :(
First of all, you are trying to copy a multimap into a map. Multimaps can have multiple items with the same index stored, while a map has only one item per index.
So, you may have to iterate over the incoming range and insert the map element wise into your maps. What you do if you have multiple indices stored in the multimap you have to decide for yourself.
Edit:
To be compatible with both map and multimap you can always make the iterator a template argument:
template<typename TIter>
BidirectionalMap(TIter beg, TIter end) {
for(TIter it = beg; it != end; ++it) {
// insert elements
}
}
I solved it like this with help from #MatthiasB
BidirectionalMap(Titer beg, Titer end)
{
for(Titer it = beg; it != end; ++it)
{
m1.insert(*it);
m2.insert(std::pair<T,T> (it->second,it->first));
}

How do I find an element position in std::vector?

I need to find an element position in an std::vector to use it for referencing an element in another vector:
int find( const vector<type>& where, int searchParameter )
{
for( int i = 0; i < where.size(); i++ ) {
if( conditionMet( where[i], searchParameter ) ) {
return i;
}
}
return -1;
}
// caller:
const int position = find( firstVector, parameter );
if( position != -1 ) {
doAction( secondVector[position] );
}
however vector::size() returns size_t which corresponds to an unsigned integral type that can't directly store -1. How do I signal that the element is not found in a vector when using size_t instead of int as an index?
Take a look at the answers provided for this question: Invalid value for size_t?. Also you can use std::find_if with std::distance to get the index.
std::vector<type>::iterator iter = std::find_if(vec.begin(), vec.end(), comparisonFunc);
size_t index = std::distance(vec.begin(), iter);
if(index == vec.size())
{
//invalid
}
First of all, do you really need to store indices like this? Have you looked into std::map, enabling you to store key => value pairs?
Secondly, if you used iterators instead, you would be able to return std::vector.end() to indicate an invalid result. To convert an iterator to an index you simply use
size_t i = it - myvector.begin();
You could use std::numeric_limits<size_t>::max() for elements that was not found. It is a valid value, but it is impossible to create container with such max index. If std::vector has size equal to std::numeric_limits<size_t>::max(), then maximum allowed index will be (std::numeric_limits<size_t>::max()-1), since elements counted from 0.
std::vector has random-access iterators. You can do pointer arithmetic with them. In particular, this my_vec.begin() + my_vec.size() == my_vec.end() always holds. So you could do
const vector<type>::const_iterator pos = std::find_if( firstVector.begin()
, firstVector.end()
, some_predicate(parameter) );
if( position != firstVector.end() ) {
const vector<type>::size_type idx = pos-firstVector.begin();
doAction( secondVector[idx] );
}
As an alternative, there's always std::numeric_limits<vector<type>::size_type>::max() to be used as an invalid value.
In this case, it is safe to cast away the unsigned portion unless your vector can get REALLY big.
I would pull out the where.size() to a local variable since it won't change during the call. Something like this:
int find( const vector<type>& where, int searchParameter ){
int size = static_cast<int>(where.size());
for( int i = 0; i < size; i++ ) {
if( conditionMet( where[i], searchParameter ) ) {
return i;
}
}
return -1;
}
If a vector has N elements, there are N+1 possible answers for find. std::find and std::find_if return an iterator to the found element OR end() if no element is found. To change the code as little as possible, your find function should return the equivalent position:
size_t find( const vector<type>& where, int searchParameter )
{
for( size_t i = 0; i < where.size(); i++ ) {
if( conditionMet( where[i], searchParameter ) ) {
return i;
}
}
return where.size();
}
// caller:
const int position = find( firstVector, parameter );
if( position != secondVector.size() ) {
doAction( secondVector[position] );
}
I would still use std::find_if, though.
Something like this, I think. find_if_counted.hpp:
#ifndef FIND_IF_COUNTED_HPP
#define FIND_IF_COUNTED_HPP
#include <algorithm>
namespace find_if_counted_impl
{
template <typename Func>
struct func_counter
{
explicit func_counter(Func& func, unsigned &count) :
_func(func),
_count(count)
{
}
template <typename T>
bool operator()(const T& t)
{
++_count;
return _func(t);
}
private:
Func& _func;
unsigned& _count;
};
}
// generic find_if_counted,
// returns the index of the found element, otherwise returns find_if_not_found
const size_t find_if_not_found = static_cast<size_t>(-1);
template <typename InputIterator, typename Func>
size_t find_if_counted(InputIterator start, InputIterator finish, Func func)
{
unsigned count = 0;
find_if_counted_impl::func_counter<Func> f(func, count);
InputIterator result = find_if(start, finish, f);
if (result == finish)
{
return find_if_not_found;
}
else
{
return count - 1;
}
}
#endif
Example:
#include "find_if_counted.hpp"
#include <cstdlib>
#include <iostream>
#include <vector>
typedef std::vector<int> container;
int rand_number(void)
{
return rand() % 20;
}
bool is_even(int i)
{
return i % 2 == 0;
}
int main(void)
{
container vec1(10);
container vec2(10);
std::generate(vec1.begin(), vec1.end(), rand_number);
std::generate(vec2.begin(), vec2.end(), rand_number);
unsigned index = find_if_counted(vec1.begin(), vec1.end(), is_even);
if (index == find_if_not_found)
{
std::cout << "vec1 has no even numbers." << std::endl;
}
else
{
std::cout << "vec1 had an even number at index: " << index <<
" vec2's corresponding number is: " << vec2[index] << std::endl;
}
}
Though I feel like I'm doing something silly... :X Any corrections are welcome, of course.
You probably should not use your own function here.
Use find() from STL.
Example:
list L;
L.push_back(3);
L.push_back(1);
L.push_back(7);
list::iterator result = find(L.begin(), L.end(), 7);
assert(result == L.end() || *result == 7);
Take a vector of integer and a key (that we find in vector )....Now we are traversing the vector until found the key value or last index(otherwise).....If we found key then print the position , otherwise print "-1".
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int>str;
int flag,temp key, ,len,num;
flag=0;
cin>>len;
for(int i=1; i<=len; i++)
{
cin>>key;
v.push_back(key);
}
cin>>num;
for(int i=1; i<=len; i++)
{
if(str[i]==num)
{
flag++;
temp=i-1;
break;
}
}
if(flag!=0) cout<<temp<<endl;
else cout<<"-1"<<endl;
str.clear();
return 0;
}
Get rid of the notion of vector entirely
template< typename IT, typename VT>
int index_of(IT begin, IT end, const VT& val)
{
int index = 0;
for (; begin != end; ++begin)
{
if (*begin == val) return index;
}
return -1;
}
This will allow you more flexibility and let you use constructs like
int squid[] = {5,2,7,4,1,6,3,0};
int sponge[] = {4,2,4,2,4,6,2,6};
int squidlen = sizeof(squid)/sizeof(squid[0]);
int position = index_of(&squid[0], &squid[squidlen], 3);
if (position >= 0) { std::cout << sponge[position] << std::endl; }
You could also search any other container sequentially as well.