Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Instances? [question] #1

Closed
hippyau opened this issue May 18, 2021 · 3 comments
Closed

Multiple Instances? [question] #1

hippyau opened this issue May 18, 2021 · 3 comments

Comments

@hippyau
Copy link

hippyau commented May 18, 2021

Hi Tyill,

I am wondering, not being fluent, can there be multiple instances of Interpreter?

My situation is I have a vector, of class t_user which keeps track of a individual connected users....
A single connection [t_user] has a Programmer that contains an instance of Interpreter:

[pseudocode]

class Programmer {
public:
   Interpreter cmdline; 
};

class t_user {
public:
    std::string name = "root";
    Programmer programmer; // each user has own programmer / interpreter / environment    
};

std::vector<t_user> Users;

void main(void){

  t_user  tmp_user;
  tmp_user.name = "user1"
  Users.push_back(tmp_user);  // add a t_user to Users

  // Users[0] we just pushed
  std::string input = "$a = summ(1, 2);"
  Users[0].programmer.cmdline.cmd(input);  // <------- complains here

}

Compiler throws a fit...

In file included from /usr/include/x86_64-linux-gnu/c++/9/bits/c++allocator.h:33,
                 from /usr/include/c++/9/bits/allocator.h:46,
                 from /usr/include/c++/9/deque:64,
                 from /home/hip/dev/interpreter/user.cpp:10:
/usr/include/c++/9/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = t_user; _Args = {const t_user&}; _Tp = t_user]’:
/usr/include/c++/9/bits/alloc_traits.h:482:2:   required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = t_user; _Args = {const t_user&}; _Tp = t_user; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<t_user>]’
/usr/include/c++/9/bits/stl_vector.h:1189:30:   required from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = t_user; _Alloc = std::allocator<t_user>; std::vector<_Tp, _Alloc>::value_type = t_user]’
//home/hip/dev/interpreter/user.cpp:27:30:   required from here
/usr/include/c++/9/ext/new_allocator.h:145:20: error: use of deleted function ‘t_user::t_user(const t_user&)’
  145 |  noexcept(noexcept(::new((void *)__p)
      |                    ^~~~~~~~~~~~~~~~~~
  146 |        _Up(std::forward<_Args>(__args)...)))
      |        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It's very much probably not your fault, I am playing with multi-user interpreters where users have own instances - but would introduce some globals for them to share also.

I just wondering multiple instances are possible or if my stupid fault?

@hippyau
Copy link
Author

hippyau commented May 18, 2021

Sorry, I ask because I can comment out....


  explicit 
  Interpreter();
  ~Interpreter();

//  Interpreter(const Interpreter&) = delete;   // <----- comment out compiles, but segfaults
  Interpreter& operator=(const Interpreter&) = delete;

if I comment out the delete line above from interpreter.h (because the compiler complained about deleted function) it compiles but segfaults on attempt to use.

I probably dumb in how I'm approaching

@hippyau hippyau changed the title Multiple Instances? [question[ Multiple Instances? [question] May 18, 2021
@Tyill
Copy link
Owner

Tyill commented May 18, 2021

Hi.
Define a copy constructor and an assignment operator:

interpreter.h  

  explicit 
  Interpreter();
  ~Interpreter();

  Interpreter(const Interpreter&);
  Interpreter& operator=(const Interpreter&);
  .
  .
interpreter.cpp

  Interpreter::Interpreter() {
    m_d = new InterpreterImpl();
  }
  Interpreter::~Interpreter() {
    delete m_d;
  }
  Interpreter::Interpreter(const Interpreter& other) {
    m_d = new InterpreterImpl();
    *m_d = *other.m_d;
  }
  Interpreter& Interpreter::operator=(const Interpreter& other){
    if (this->m_d != other.m_d)   
      *m_d = *other.m_d;  
    return *this;
  }
  .
  .

And your example would be:

class Programmer {
public:
  Programmer() {
    cmdline.addOperator("=", [](string& leftOpd, string& rightOpd) ->string {
      leftOpd = rightOpd;
      return leftOpd;
    }, 10);
    
    cmdline.addFunction("summ", [](const vector<string>& args) ->string {
      string res;
      for (auto& v : args) {
        res += v;
      }
      return res;
    });
  }
  Interpreter cmdline;
};

class t_user {
public:
  std::string name = "root";
  Programmer programmer; // each user has own programmer / interpreter / environment    
};

std::vector<t_user> Users;

void main(void) {

  t_user  tmp_user;
  tmp_user.name = "user1";
  Users.push_back(tmp_user);  // add a t_user to Users

  // Users[0] we just pushed
  std::string input = "$a = summ(1, 2);";
  auto res = Users[0].programmer.cmdline.cmd(input);   // <------- complains here

  res; // 12
}

https://github.com/Tyill/interpreter/releases/tag/1.0.4

@Tyill Tyill closed this as completed May 18, 2021
@hippyau
Copy link
Author

hippyau commented May 19, 2021

Thanks so much, it makes sense now :) Thanks for your help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants