cgv
Loading...
Searching...
No Matches
list.h
1#pragma once
2
3#include <iostream>
4#include <set>
6#include "signal.h"
7#include "lib_begin.h"
8
9namespace cgv {
10 namespace signal {
11
12 class CGV_API abst_managed_list
13 {
14 public:
15 std::string element_name;
16 protected:
17 std::set<abst_managed_list*> attachments;
18 void finish_create(size_t index, int as_copy_of);
19 void start_erase(size_t index);
20 public:
21 abst_managed_list(const std::string& _element_name);
22 void attach_list(abst_managed_list& attachment);
23 void detach_list(abst_managed_list& attachment);
24 virtual size_t size() const = 0;
25 virtual const void* get_element_ptr(size_t index) const;
26 virtual std::string get_element_name(size_t index) const;
27 virtual std::string* get_element_name_ptr(size_t index);
28 virtual size_t create(int as_copy_of = -1) = 0;
29 virtual void erase(size_t index) = 0;
30 cgv::signal::signal<size_t, int> on_create;
31 cgv::signal::signal<size_t> on_erase;
32 };
33
34 template <typename T>
36 {
37 protected:
38 std::vector<T*> elements;
39 std::string T::* name_member;
40 public:
41 managed_list(const std::string& _element_name, std::string T::* _name_member = 0) : abst_managed_list(_element_name), name_member(_name_member) {}
42 size_t size() const { return elements.size(); }
43 const void* get_element_ptr(size_t index) const { return &elements[index]; }
44 std::string* get_element_name_ptr(size_t index) {
45 if (name_member)
46 return &(elements[index]->*name_member);
47 return 0;
48 }
49 std::string get_element_name(size_t index) const {
50 if (name_member == 0)
51 return abst_managed_list::get_element_name(index);
52 if (index >= size()) {
53 std::cerr << "WARNING: attempt to get_element_name " << element_name << " of index " << index << " out of range[0, " << size() << "[. Returning base implementation." << std::endl;
54 return abst_managed_list::get_element_name(index);
55 }
56 T* element_ptr = elements[index];
57 if ((element_ptr->*name_member).empty())
58 return abst_managed_list::get_element_name(index);
59 return element_ptr->*name_member;
60 }
61 size_t create(int as_copy_of = -1) {
62 T* ptr;
63 if (as_copy_of == -1)
64 ptr = new T();
65 else {
66 if (as_copy_of >= (int)size()) {
67 std::cerr
68 << "WARNING: attempt to create " << element_name << " as copy of " << element_name << " with index " << as_copy_of
69 << " out of range[0, " << size() << "[.Creating default " << element_name << " instead." << std::endl;
70 ptr = new T();
71 }
72 else {
73 ptr = new T((*this)(as_copy_of));
74 if (name_member != 0) {
75 if ((ptr->*name_member).empty()) {
76 (ptr->*name_member) = "copy(";
77 (ptr->*name_member) += cgv::utils::to_string(as_copy_of) + ")";
78 }
79 }
80 }
81
82 }
83 size_t index = size();
84 elements.push_back(ptr);
85 finish_create(index, as_copy_of);
86 return index;
87 }
88 void erase(size_t index) {
89 if (index >= size()) {
90 std::cerr << "WARNING: attempt to erase " << element_name << " with index " << index << " out of range [0," << size() << "[. Erase command ignored." << std::endl;
91 return;
92 }
93 delete elements[index];
94 elements[index] = 0;
95 elements.erase(elements.begin() + index);
96 }
97 const T& operator () (size_t index) const {
98 if (index >= size()) {
99 std::cerr << "ERROR: attempt to access (read) " << element_name << " with index " << index << " out of range [0," << size() << "[." << std::endl;
100 abort();
101 }
102 return *elements[index];
103 }
104 T& operator () (size_t index) {
105 if (index >= size()) {
106 std::cerr << "ERROR: attempt to access (write) " << element_name << " with index " << index << " out of range [0," << size() << "[." << std::endl;
107 abort();
108 }
109 return *elements[index];
110 }
111 };
112
113 }
114}
115
116#include <cgv/config/lib_end.h>
Helper functions to convert numeric types into strings using std streams.
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
the cgv namespace
Definition print.h:11