]> git.tdb.fi Git - libs/datafile.git/blob - source/argumentstore.cpp
Implement proper copy semantics
[libs/datafile.git] / source / argumentstore.cpp
1 #include <stdexcept>
2 #include "argumentstore.h"
3
4 using namespace std;
5
6 namespace Msp {
7 namespace DataFile {
8
9 ArgumentStore::ArgumentStore(const StatementInfo &n):
10         info(n),
11         store(new char[info.args_size])
12 {
13         for(unsigned i=0; i<info.key.signature.size(); ++i)
14                 switch(info.key.signature[i])
15                 {
16                 case StringType::signature:
17                         new(store+info.arg_offsets[i]) StringType::Store;
18                         break;
19                 case SymbolType::signature:
20                         new(store+info.arg_offsets[i]) SymbolType::Store;
21                         break;
22                 }
23 }
24
25 ArgumentStore::ArgumentStore(const ArgumentStore &other):
26         info(other.info),
27         store(new char[info.args_size])
28 {
29         copy_from(other.store);
30 }
31
32 ArgumentStore &ArgumentStore::operator=(const ArgumentStore &other)
33 {
34         if(&other.info!=&info)
35                 throw invalid_argument("ArgumentStore::operator=");
36
37         destroy();
38         copy_from(other.store);
39
40         return *this;
41 }
42
43 ArgumentStore::~ArgumentStore()
44 {
45         destroy();
46 }
47
48 void ArgumentStore::destroy()
49 {
50         for(unsigned i=0; i<info.key.signature.size(); ++i)
51                 switch(info.key.signature[i])
52                 {
53                 case StringType::signature:
54                         reinterpret_cast<StringType::Store *>(store+info.arg_offsets[i])->~basic_string();
55                         break;
56                 case SymbolType::signature:
57                         reinterpret_cast<SymbolType::Store *>(store+info.arg_offsets[i])->~Symbol();
58                         break;
59                 }
60
61         delete[] store;
62 }
63
64 void ArgumentStore::copy_from(const char *other)
65 {
66         for(unsigned i=0; i<info.key.signature.size(); ++i)
67                 switch(info.key.signature[i])
68                 {
69                 case StringType::signature:
70                         new(store+info.arg_offsets[i]) StringType::Store(*reinterpret_cast<const StringType::Store *>(other+info.arg_offsets[i]));
71                         break;
72                 case SymbolType::signature:
73                         new(store+info.arg_offsets[i]) SymbolType::Store(*reinterpret_cast<const SymbolType::Store *>(other+info.arg_offsets[i]));
74                         break;
75                 default:
76                         copy(other+info.arg_offsets[i], other+(i+1<info.arg_offsets.size() ? info.arg_offsets[i+1] : info.args_size), store+info.arg_offsets[i]);
77                         break;
78                 }
79 }
80
81 } // namespace DataFile
82 } // namespace Msp