QtConcurrent::blockingMapped() and std::vector<> bug - c++

It seems that QtConcurrent works fine with QT containers (QList and QVector), but fails with the STL containers, as opposed to what is claimed in the documentation
Here are the dummy functions I want to use on my containers :
void addOne(int & i)
{
++i;
}
int addOneC(const int & i)
{
return i+1;
}
Examples of what works :
int main( int argc, char** argv )
{
// Qt containers
QList<int> l;
l << 1 << 2 << 4 << 3;
QList<int> l1 = QtConcurrent::blockingMapped(l, addOneC);
QtConcurrent::blockingMap(l1, addOne);
// Standard containers
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(4);
v.push_back(3);
QtConcurrent::blockingMap(v, addOne);
}
What does not work :
int main( int argc, char** argv )
{
// Standard containers
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(4);
v.push_back(3);
vector<int> v1 = QtConcurrent::blockingMapped(v, addOneC);
}
It cause a compilation error with atrociously long and obfuscate template errors.
If anyone knew why, it would really help! Thanks!
The error log :
1>C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xutility(442) : error C2825: '_Alloc': must be a class or namespace when followed by '::'
1> .\main.cpp(187) : see reference to class template instantiation 'std::_Container_base_aux_alloc_real<_Alloc>' being compiled
1> with
1> [
1> _Alloc=int
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xutility(442) : error C2903: 'rebind' : symbol is neither a class template nor a function template
1>C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xutility(442) : error C2039: 'rebind' : is not a member of 'global namespace''
1>C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xutility(442) : error C2143: syntax error : missing ';' before '<'
1>C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xutility(442) : error C2039: 'other' : is not a member of 'global namespace''
1>C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xutility(442) : error C2238: unexpected token(s) preceding ';'
1>.\main.cpp(187) : error C2248: 'std::_Container_base_aux_alloc_real<_Alloc>::~_Container_base_aux_alloc_real' : cannot access protected member declared in class 'std::_Container_base_aux_alloc_real<_Alloc>'
1> with
1> [
1> _Alloc=int
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xutility(435) : see declaration of 'std::_Container_base_aux_alloc_real<_Alloc>::~_Container_base_aux_alloc_real'
1> with
1> [
1> _Alloc=int
1> ]
1>.\main.cpp(187) : error C2440: 'initializing' : cannot convert from 'std::_Container_base_aux_alloc_real<_Alloc>' to 'std::vector<_Ty>'
1> with
1> [
1> _Alloc=int
1> ]
1> and
1> [
1> _Ty=int
1> ]
1> No constructor could take the source type, or constructor overload resolution was ambiguous

I think you should explicitly give the type of the container to the blockingMapped.
int main( int argc, char** argv )
{
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(4);
v.push_back(3);
std::vector<int> v1 = QtConcurrent::blockingMapped<std::vector<int> >(v, addOneC);
}
Compile and give me the expected result in the simple example you gave.

Related

Removing classes from an array C++

I have a vector array for classes and im making a method that can delete the classes from that array, using std::remove(). The problem is Weapon (the class) doesn't have an operator == that std::remove needs to compare the elements.
the code:
class Weapon {
public:
std::string name;
Weapon(std::string x) {
name = x;
}
Weapon() {}
};
std::vector<Weapon> inventory{};
void removeInventory(Weapon x) {
if (inventorySize != 0) {
auto deleteFromInc = inventory.erase(std::remove(std::begin(inventory), std::end(inventory), x), std::end(inventory));
if (deleteFromInc != std::end(inventory)) {
std::cout << "Item didn't delete\n";
} else {
if (heldWeapon.name == x.name) {
heldWeapon = Weapon();
}
inventorySize = inventory.size();
std::cout << "Item deleted\n";
}
} else {
std::cout << "You have no items\n";
}
}
the error:
Rebuild started...
1>------ Rebuild All started: Project: rpag, Configuration: Debug Win32 ------
1>rpag.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xmemory(1945,1): error C2678: binary '==': no operator found which takes a left-hand operand of type 'Weapon' (or there is no acceptable conversion)
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared\guiddef.h(192,15): message : could be 'bool operator ==(const GUID &,const GUID &)' [found using argument-dependent lookup]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xmemory(1945,1): message : while trying to match the argument list '(Weapon, const _Ty)'
1> with
1> [
1> _Ty=Weapon
1> ]
1>C:\Users\alber\source\repos\rpag\rpag\rpag.cpp(89): message : see reference to function template instantiation '_FwdIt std::remove<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>,Weapon>(_FwdIt,const _FwdIt,const _Ty &)' being compiled
1> with
1> [
1> _FwdIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<Weapon>>>,
1> _Ty=Weapon
1> ]
1>Done building project "rpag.vcxproj" -- FAILED.
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
This is my first question! I hope everything is clear.
std::remove needs operator== (this is requirement of c++ standart library). And you can adds the operator into your class, or use std::remove_if - it use predicate - external function for comparison.
There is third way: you can erase items from vector manually: for (...) { erase ...}

tuple error C2661 in while creating thread using abstract class member c++

error C2661: 'std::tuple::tuple': no overloaded function takes 3 arguments
I have created an abstract class called DataManager and it has a pure virtual funnction close(ClientData b) =0 ;
ifndef _DataManager_HPP_
#define _DataManager_HPP_
#include <string>
#include "../ClientBlockData.hpp"
namespace slssm {
enum COMMAND_TYPE { DB_WRITE = 0, DB_READ, DB_NONE };
class DataManager {
public:
virtual std::vector<std::string> Update(ClientBlockData& blkData,
std::string& iQuery) = 0;
virtual void closeDb(ClientBlockData& blkData) = 0;
virtual std::string buildDbQuery(std::string& iTableName,
std::string& msg,
std::string& oTopic,
COMMAND_TYPE& oCmdType) = 0;
// ~DataManager() {}
};
which as a dervied class SQLiteManager in SQLiteManager.hpp
void closeDb(ClientBlockData& blkData) {
mDb=nullptr;
}
in the main function I use it like this
SQLiteManager* dbmang = new SQLiteManager(blkData.mDb, mTableName, iSSMLoggingFlag, qcc);
// Spawn a new listener thread that responds to queries
mQueryHandlerThreads[blkData.mLocalId] =
std::thread(&SQLiteManager::closeDb, dbmang,
blkData);
The reported error
c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.15.26726\include\memory(2539,1): error C2661: 'std::tuple<void (__cdecl slssm::SQLiteManager::* )(slssm::ClientBlockData &),slssm::SQLiteManager *,slssm::ClientBlockData>::tuple': no overloaded function takes 3 arguments
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.15.26726\include\thread(49): message : see reference to function template instantiation 'std::unique_ptr<std::tuple<void (__cdecl slssm::SQLiteManager::* )(slssm::ClientBlockData &),slssm::SQLiteManager *,slssm::ClientBlockData>,std::default_delete<_Ty>> std::make_unique<std::tuple<void (__cdecl slssm::SQLiteManager::* )(slssm::ClientBlockData &),slssm::SQLiteManager *,slssm::ClientBlockData>,void(__cdecl slssm::SQLiteManager::* )(slssm::ClientBlockData &),slssm::SQLiteManager*&,slssm::ClientBlockData&,0>(void (__cdecl slssm::SQLiteManager::* &&)(slssm::ClientBlockData &),slssm::SQLiteManager *&,slssm::ClientBlockData &)' being compiled
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.15.26726\include\thread(49): message : with
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.15.26726\include\thread(49): message : [
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.15.26726\include\thread(49): message : _Ty=std::tuple<void (__cdecl slssm::SQLiteManager::* )(slssm::ClientBlockData &),slssm::SQLiteManager *,slssm::ClientBlockData>
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.15.26726\include\thread(49): message : ]
You have to use the reference to blkData
mQueryHandlerThreads[blkData.mLocalId] =
std::thread(&SQLiteManager::closeDb, dbmang,
std::ref(blkData));

Failed to compile while the argument is lambda. [using hippomocks]

I wrote an unit test with hippomocks, but got error while compiling it.
The compiler is VS 2010.
How can I fix it ?
#include "hippomocks.h"
#include <functional>
using namespace HippoMocks;
struct A
{
virtual void f(std::function<void (int)> arg);
};
int main(void)
{
MockRepository mock;
A* aptr = mock.Mock<A>();
mock.ExpectCall(aptr, A::f); // error
return 0;
}
The output is :
main.cpp
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xlocale(323) : wa
rning C4530: C++ exception handler used, but unwind semantics are not enabled. S
pecify /EHsc
c:\users\cong\project\test\test\hippomocks.h(466) : error C2593: 'operator <<' i
s ambiguous
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\ostream(2
06): could be 'std::basic_ostream<_Elem,_Traits> &std::basic_ostream<_Elem,_Trai
ts>::operator <<(std::_Bool)'
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
c:\users\cong\project\test\test\hippomocks.h(441): or 'std::ostrea
m &HippoMocks::operator <<(std::ostream &,const HippoMocks::NotPrintable &)'
while trying to match the argument list '(std::ostream, std::tr1::functi
on<_Fty>)'
with
[
_Fty=void (int)
]
c:\users\cong\project\test\test\hippomocks.h(463) : while compiling clas
s template member function 'void HippoMocks::printArg<T>::print(std::ostream &,T
,bool)'
with
[
T=std::tr1::function<void (int)>
]
c:\users\cong\project\test\test\hippomocks.h(614) : see reference to cla
ss template instantiation 'HippoMocks::printArg<T>' being compiled
with
[
T=std::tr1::function<void (int)>
]
Enhancing #dascandy's comment here is how his method can look like. Place it after including hippomocks.h:
template<>
struct printArg<std::function<void (int)> >
{
static inline void print(std::ostream &os, std::function<void (int)> arg, bool withComma)
{
if (withComma)
{
os << ",";
}
if (arg)
{
os << "true";
}
else
{
os << "false";
}
}
};
Note that I didn't test this very example but rather took our solution and adapted the type to the original post's example. I'd be happy to know whether this works for you.

unique_ptr & vector, trying to access deleted function, Visual Studio 2013

I am trying to use unique_ptr to manage my memory, and VS2013 seems to be giving me trouble when I think it shouldn't be.
It would seem that the compiler is for whatever reason trying to access a deleted copy constructor when it really should have no reason to do so.
This is what one of my classes looks like:
class Mesh
{
public:
Mesh(oglplus::Program* program, const std::vector<Vertex>& vertices,
const std::vector<GLuint>& indices);
void draw();
private:
const oglplus::Program* _program;
std::vector<Vertex> _vertices;
std::vector<GLuint> _indices;
oglplus::Buffer _faceBuffer;
oglplus::Buffer _vertexBuffer;
oglplus::VertexArray _vao;
};
class Model
{
public:
Model(std::string filename, oglplus::Program* program);
void draw();
private:
const oglplus::Program* _program;
std::vector<std::unique_ptr<Mesh>> _meshes;
};
The issue is with the line
std::vector<std::unique_ptr<Mesh>> _meshes;
it starts spewing things like
2>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(593): error C2280: 'std::unique_ptr<Model::Mesh,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function
2> with
2> [
2> _Ty=Model::Mesh
2> ]
2> c:\program files (x86)\microsoft visual studio 12.0\vc\include\memory(1486) : see declaration of 'std::unique_ptr<Model::Mesh,std::default_delete<_Ty>>::unique_ptr'
2> with
2> [
2> _Ty=Model::Mesh
2> ]
2> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(592) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
2> with
2> [
2> _Ty=std::unique_ptr<Model::Mesh,std::default_delete<Model::Mesh>>
2> ]
2> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(723) : see reference to function template instantiation 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' being compiled
2> with
2> [
2> _Ty=std::unique_ptr<Model::Mesh,std::default_delete<Model::Mesh>>
2> ]
2> c:\program files (x86)\microsoft visual studio 12.0\vc\include\type_traits(572) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled
2> with
2> [
2> _Ty=std::unique_ptr<Model::Mesh,std::default_delete<Model::Mesh>>
2> ]
2> c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector(650) : see reference to class template instantiation 'std::is_empty<_Alloc>' being compiled
2> with
2> [
2> _Alloc=std::allocator<std::unique_ptr<Model::Mesh,std::default_delete<Model::Mesh>>>
2> ]
2> c:\users\vitali\projects\3d-stg\source\model\model.hpp(45) : see reference to class template instantiation 'std::vector<std::unique_ptr<Model::Mesh,std::default_delete<_Ty>>,std::allocator<std::unique_ptr<_Ty,std::default_delete<_Ty>>>>' being compiled
2> with
2> [
2> _Ty=Model::Mesh
2> ]
2> model.cpp
I am not using std::vector::resize() or anything like that (in-fact I commented out all uses of my _meshes vector, and even tried commenting the implementation out completely to no avail), so I don't understand why the compiler is giving me issues.
Does anybody have any ideas?
Thank you Preetish Kakkar for finding the issue. It turns out it was an issue with compiler generated functions implicitly using the copy constructor and operator= of the Mesh class forcing the compiler to try and use deleted functions.
I reproduced your problem, below is sample code.
#include <vector>
#include <memory>
class Mesh
{
public:
Mesh() {}
void draw() {}
private:
};
class Model
{
public:
Model() {}
void draw() {}
private:
typedef std::unique_ptr<Mesh> MeshUniquePtr;
std::vector<MeshUniquePtr> _meshes;
};
int _tmain(int argc, _TCHAR* argv[])
{
Model m;
Model m1;
m = m1; // causes error as you can't copy unique ptr
return 0;
}
The problem is at some point you are trying to copy two model object which can't be done as unique_ptr is not copyable.

operator overloading of stream extraction operator in C++ help

I'm having some trouble overloading my stream extraction operator in C++ for a hw assignment. I'm not really sure why I am getting these compile errors since I thought I was doing it right... Here is my code:
Complex.h
#ifndef COMPLEX_H
#define COMPLEX_H
class Complex
{
//friend ostream &operator<<(ostream &output, const Complex &complexObj) const;
// note at bottom regarding friend function
public:
Complex(double = 0.0, double = 0.0); // constructor
Complex operator+(const Complex &) const; // addition
Complex operator-(const Complex &) const; // subtraction
void print() const; // output
private:
double real; // real part
double imaginary; // imaginary part
};
#endif
Complex.cpp
#include <iostream>
#include "Complex.h"
using namespace std;
// Constructor
Complex::Complex(double realPart, double imaginaryPart) : real(realPart), imaginary(imaginaryPart)
{
}
// addition operator
Complex Complex::operator+(const Complex &operand2) const
{
return Complex(real + operand2.real, imaginary + operand2.imaginary);
}
// subtraction operator
Complex Complex::operator-(const Complex &operand2) const
{
return Complex(real - operand2.real, imaginary - operand2.imaginary);
}
// Overload << operator
ostream &Complex::operator<<(ostream &output, const Complex &complexObj) const
{
cout << '(' << complexObj.real << ", " << complexObj.imaginary << ')';
return output; // returning output allows chaining
}
// display a Complex object in the form: (a, b)
void Complex::print() const
{
cout << '(' << real << ", " << imaginary << ')';
}
main.cpp
#include <iostream>
#include "Complex.h"
using namespace std;
int main()
{
Complex x;
Complex y(4.3, 8.2);
Complex z(3.3, 1.1);
cout << "x: ";
x.print();
cout << "\ny: ";
y.print();
cout << "\nz: ";
z.print();
x = y + z;
cout << "\n\nx = y + z: " << endl;
x.print();
cout << " = ";
y.print();
cout << " + ";
z.print();
x = y - z;
cout << "\n\nx = y - z: " << endl;
x.print();
cout << " = ";
y.print();
cout << " - ";
z.print();
cout << endl;
}
Compile erros:
complex.cpp(23) : error C2039: '<<' : is not a member of 'Complex'
complex.h(5) : see declaration of 'Complex'
complex.cpp(24) : error C2270: '<<' : modifiers not allowed on nonmember functions
complex.cpp(25) : error C2248: 'Complex::real' : cannot access private member declared in class 'Complex'
complex.h(13) : see declaration of 'Complex::real'
complex.h(5) : see declaration of 'Complex'
complex.cpp(25) : error C2248: 'Complex::imaginary' : cannot access private member declared in class 'Complex'
complex.h(14) : see declaration of 'Complex::imaginary'
complex.h(5) : see declaration of 'Complex'
Thanks!
Edit:
I wasn't sure about declaring the friend function in the header file or not. When I do, I get these errors:
c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : error C2143: syntax error : missing ';' before '&'
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : error C2433: 'ostream' : 'friend' not permitted on data declarations
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : error C2061: syntax error : identifier 'ostream'
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : error C2805: binary 'operator <<' has too few parameters
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.cpp(23) : error C2872: 'ostream' : ambiguous symbol
1> could be 'c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : int ostream'
1> or 'c:\program files\microsoft visual studio 9.0\vc\include\iosfwd(708) : std::ostream'
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.cpp(23) : error C2143: syntax error : missing ';' before '&'
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.cpp(23) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.cpp(23) : error C2086: 'int ostream' : redefinition
1> c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : see declaration of 'ostream'
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.cpp(23) : error C2872: 'ostream' : ambiguous symbol
1> could be 'c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : int ostream'
1> or 'c:\program files\microsoft visual studio 9.0\vc\include\iosfwd(708) : std::ostream'
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.cpp(23) : error C2872: 'ostream' : ambiguous symbol
1> could be 'c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : int ostream'
1> or 'c:\program files\microsoft visual studio 9.0\vc\include\iosfwd(708) : std::ostream'
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.cpp(23) : error C2065: 'output' : undeclared identifier
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.cpp(23) : error C2059: syntax error : 'const'
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.cpp(24) : error C2143: syntax error : missing ';' before '{'
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.cpp(24) : error C2447: '{' : missing function header (old-style formal list?)
1>Generating Code...
1>Compiling...
1>main.cpp
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : error C2143: syntax error : missing ';' before '&'
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : error C2433: 'ostream' : 'friend' not permitted on data declarations
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : error C2061: syntax error : identifier 'ostream'
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\documents and settings\wongj\my documents\visual studio 2008\projects\c3_hw\c3_hw4\complex.h(6) : error C2805: binary 'operator <<' has too few parameters
Your commented-out declaration in the header is almost correct. Since it is a friend, it is not a member and thus cannot be const, so it should be:
friend std::ostream &operator<<(std::ostream &output, const Complex &complexObj);
Note also that you need to qualify ostream as std::ostream, since you should not use using namespace std; in a header file (you really shouldn't need to use it anywhere; it's generally better to just write out std:: when you want to use something from the standard library).
Likewise, in your source file, since it is not a member function, you do not prefix the operator definition with the class name, and it should be:
std::ostream &operator<<(std::ostream &output, const Complex &complexObj)
If you want client code to have access to the operator<< overload, add
ostream & operator<<(ostream &output, const Complex &complexObj) const
to your class header file.
If, on the other hand, you only want client code to call print(), remove the
Complex::
scoping from the operator definition in the implementation file.