/******************************************************************************
Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, Java, PHP, Ruby, Perl,
C#, OCaml, VB, Swift, Pascal, Fortran, Haskell, Objective-C, Assembly, HTML, CSS, JS, SQLite, Prolog.
Code, Compile, Run and Debug online from anywhere in world.
*******************************************************************************/
#include <iostream>
#include <vector>
#include <array>
using namespace std;
/**
* Free function which inplace
* constructs and appends objects
*/
template < class C, class C_Args >
void emplace_back(C& cContainer,C_Args& argsContainer){
cContainer.reserve(argsContainer.size());
for(const auto&arg:argsContainer){
cContainer.emplace_back(arg);
}
return;
}
template <typename Container, typename... Args>
void emplace_back(Container& container, Args &&... args)
{
container.reserve(sizeof...(Args));
(container.emplace_back(std::forward<Args>(args)),...);
}
/**
* This is a dummy socket class
* Targets : Not copyable , Defined destructor
* Can be constructed in place in a std::vector/std::array
* Solution : Implement rule of 5
* Use vector's emplace_back perfect forwarding and reserve functions to
* avoid copy and moves
*/
class socket final{
public:
explicit socket(int fd):fd(fd){
/**
* create a socket . get an fd, whatever.
* I am taking fd as an input just so that i can print the number out
*/
cout<< "socket ctor:" << fd << endl;
}
~socket(){
/**
* Implement a close() call in a real one
*/
cout<<"socket dtor:"<< fd << endl;
if(fd>0){
// close(fd);
}
}
/**
* Need to maintain a move policy
*/
socket(socket&& movedFrom) noexcept {
this->fd = movedFrom.fd;
movedFrom.fd = -1;
}
socket& operator=( socket && movedFrom) noexcept {
this->fd = movedFrom.fd;
movedFrom.fd = -1;
return *this;
}
private:
int fd;
/**
* Delete Value semantics
*/
socket& operator= ( const socket & ) = delete;
socket ( const socket & ) = delete;
};
class client{
public:
client(std::vector<int> clientIDs):clientIDs(clientIDs){
emplace_back(sockets,clientIDs);
}
private:
std::vector<socket> sockets;
std::vector<int> clientIDs;
};
int main()
{
/**
* Expected behavior: only the default constructor gets called,
* without a copy constructor or a move constructor call
* and this without a temporary object deletion
*/
cout<<"\r\nconstructing vector of sockets\r\n"<<endl;
std::vector<socket> sockets;
sockets.reserve(6);
auto fds = std::vector<int>{1, 6, 2, 3, 5,4};
emplace_back(sockets,fds);
/**
* Expected behavior: only the default constructor gets called,
* without a copy constructor or a move constructor call
* and this without a temporary object deletion
*/
cout<<"\r\nconstructing client object\r\n"<<endl;
auto cl = client(std::vector<int>(fds.begin(),fds.end()));
/**
* Expected behavior: only the default constructor gets called,
* without a copy constructor or a move constructor call
* and this without a temporary object deletion
*/
cout<<"\r\nconstructing vector of clients\r\n"<<endl;
std::vector<client> clients;
std::vector<std::vector<int>> args = {fds,fds,fds};
emplace_back(clients,args);
/**
* This is just for delay and to put a breakpoint
*/
for(long int i=0;i<1000000;i++){
for(int j=1;j<1000;j++){
int k=j+1;
}
}
cout << "\r\n\r\ndelay over, calls dtors now \r\n\r\n" << endl;
return 0;
}