pmt performance improvement: Switch from shared_ptr to intrusive_ptr
[debian/gnuradio] / pmt / src / lib / pmt.cc
index a141224b30761285fd31b1e9437516ad09abae81..315ff1a406638de950f9e82fa929d42884982f6f 100644 (file)
@@ -54,6 +54,8 @@ pmt_base::operator delete(void *p, size_t size)
 
 #endif
 
+void intrusive_ptr_add_ref(pmt_base* p) { ++(p->count_); }
+void intrusive_ptr_release(pmt_base* p) { if (--(p->count_) == 0 ) delete p; }
 
 pmt_base::~pmt_base()
 {
@@ -219,7 +221,7 @@ hash_string(const std::string &s)
 }
 
 bool 
-pmt_is_symbol(pmt_t obj)
+pmt_is_symbol(const pmt_t& obj)
 {
   return obj->is_symbol();
 }
@@ -250,7 +252,7 @@ pmt_intern(const std::string &name)
 }
 
 const std::string
-pmt_symbol_to_string(pmt_t sym)
+pmt_symbol_to_string(const pmt_t& sym)
 {
   if (!sym->is_symbol())
     throw pmt_wrong_type("pmt_symbol_to_string", sym);
@@ -292,8 +294,9 @@ pmt_from_long(long x)
 long
 pmt_to_long(pmt_t x)
 {
-  if (x->is_integer())
-    return _integer(x)->value();
+  pmt_integer* i = dynamic_cast<pmt_integer*>(x.get());
+  if ( i )
+    return i->value();
 
   throw pmt_wrong_type("pmt_to_long", x);
 }
@@ -363,40 +366,42 @@ pmt_to_complex(pmt_t x)
 ////////////////////////////////////////////////////////////////////////////
 
 pmt_null::pmt_null() {}
-pmt_pair::pmt_pair(pmt_t car, pmt_t cdr) : d_car(car), d_cdr(cdr) {}
+pmt_pair::pmt_pair(const pmt_t& car, const pmt_t& cdr) : d_car(car), d_cdr(cdr) {}
 
 bool
-pmt_is_null(pmt_t x)
+pmt_is_null(const pmt_t& x)
 {
   return x == PMT_NIL;
 }
 
 bool
-pmt_is_pair(pmt_t obj)
+pmt_is_pair(const pmt_t& obj)
 {
   return obj->is_pair();
 }
 
 pmt_t
-pmt_cons(pmt_t x, pmt_t y)
+pmt_cons(const pmt_t& x, const pmt_t& y)
 {
   return pmt_t(new pmt_pair(x, y));
 }
 
 pmt_t
-pmt_car(pmt_t pair)
+pmt_car(const pmt_t& pair)
 {
-  if (pair->is_pair())
-    return _pair(pair)->car();
+  pmt_pair* p = dynamic_cast<pmt_pair*>(pair.get());
+  if ( p )
+    return p->car();
   
   throw pmt_wrong_type("pmt_car", pair);
 }
 
 pmt_t
-pmt_cdr(pmt_t pair)
+pmt_cdr(const pmt_t& pair)
 {
-  if (pair->is_pair())
-    return _pair(pair)->cdr();
+  pmt_pair* p = dynamic_cast<pmt_pair*>(pair.get());
+  if ( p )
+    return p->cdr();
   
   throw pmt_wrong_type("pmt_cdr", pair);
 }
@@ -508,11 +513,11 @@ pmt_uniform_vector_elements(pmt_t vector, size_t &len)
 }
 
 void *
-pmt_uniform_vector_writeable_elements(pmt_t vector, size_t &len)
+pmt_uniform_vector_writable_elements(pmt_t vector, size_t &len)
 {
   if (!vector->is_uniform_vector())
-    throw pmt_wrong_type("pmt_uniform_vector_writeable_elements", vector);
-  return _uniform_vector(vector)->uniform_writeable_elements(len);
+    throw pmt_wrong_type("pmt_uniform_vector_writable_elements", vector);
+  return _uniform_vector(vector)->uniform_writable_elements(len);
 }
 
 ////////////////////////////////////////////////////////////////////////////
@@ -585,28 +590,31 @@ pmt_make_dict()
 void
 pmt_dict_set(pmt_t dict, pmt_t key, pmt_t value)
 {
-  if (!dict->is_dict())
+  pmt_dict* d = _dict(dict);
+  if (!d)
     throw pmt_wrong_type("pmt_dict_set", dict);
 
-  _dict(dict)->set(key, value);
+  d->set(key, value);
 }
 
 bool
 pmt_dict_has_key(pmt_t dict, pmt_t key)
 {
-  if (!dict->is_dict())
+  pmt_dict* d = _dict(dict);
+  if (!d)
     throw pmt_wrong_type("pmt_dict_has_key", dict);
 
-  return _dict(dict)->has_key(key);
+  return d->has_key(key);
 }
 
 pmt_t
 pmt_dict_ref(pmt_t dict, pmt_t key, pmt_t not_found)
 {
-  if (!dict->is_dict())
+  pmt_dict* d = _dict(dict);
+  if (!d)
     throw pmt_wrong_type("pmt_dict_ref", dict);
 
-  return _dict(dict)->ref(key, not_found);
+  return d->ref(key, not_found);
 }
 
 pmt_t
@@ -675,13 +683,13 @@ pmt_any_set(pmt_t obj, const boost::any &any)
 ////////////////////////////////////////////////////////////////////////////
 
 bool
-pmt_eq(pmt_t x, pmt_t y)
+pmt_eq(const pmt_t& x, const pmt_t& y)
 {
   return x == y;
 }
 
 bool
-pmt_eqv(pmt_t x, pmt_t y)
+pmt_eqv(const pmt_t& x, const pmt_t& y)
 {
   if (x == y)
     return true;
@@ -699,7 +707,7 @@ pmt_eqv(pmt_t x, pmt_t y)
 }
 
 bool
-pmt_equal(pmt_t x, pmt_t y)
+pmt_equal(const pmt_t& x, const pmt_t& y)
 {
   if (pmt_eqv(x, y))
     return true;
@@ -741,7 +749,7 @@ pmt_equal(pmt_t x, pmt_t y)
 }
 
 size_t
-pmt_length(pmt_t x)
+pmt_length(const pmt_t& x)
 {
   if (x->is_vector())
     return _vector(x)->length();
@@ -749,13 +757,16 @@ pmt_length(pmt_t x)
   if (x->is_uniform_vector())
     return _uniform_vector(x)->length();
 
-  if (x->is_pair() || x->is_null()) {
-    size_t length=0;
-    while (pmt_is_pair(x)){
+  if (x->is_null()) return 0;
+
+  if (x->is_pair()) {
+    size_t length=1;
+       pmt_t it = pmt_cdr(x);
+    while (pmt_is_pair(it)){
       length++;
-      x = pmt_cdr(x);
+      it = pmt_cdr(it);
     }
-    if (pmt_is_null(x))
+    if (pmt_is_null(it))
       return length;
 
     // not a proper list
@@ -816,7 +827,7 @@ pmt_assoc(pmt_t obj, pmt_t alist)
 }
 
 pmt_t
-pmt_map(pmt_t proc(pmt_t), pmt_t list)
+pmt_map(pmt_t proc(const pmt_t&), pmt_t list)
 {
   pmt_t r = PMT_NIL;
 
@@ -864,7 +875,7 @@ pmt_nth(size_t n, pmt_t list)
 pmt_t
 pmt_nthcdr(size_t n, pmt_t list)
 {
-  if (!(pmt_is_null(list) || pmt_is_pair(list)))
+  if (!(pmt_is_pair(list) || pmt_is_null(list)))
     throw pmt_wrong_type("pmt_nthcdr", list);
     
   while (n > 0){
@@ -927,41 +938,47 @@ pmt_subsetp(pmt_t list1, pmt_t list2)
 }
 
 pmt_t
-pmt_list1(pmt_t x1)
+pmt_list1(const pmt_t& x1)
 {
   return pmt_cons(x1, PMT_NIL);
 }
 
 pmt_t
-pmt_list2(pmt_t x1, pmt_t x2)
+pmt_list2(const pmt_t& x1, const pmt_t& x2)
 {
   return pmt_cons(x1, pmt_cons(x2, PMT_NIL));
 }
 
 pmt_t
-pmt_list3(pmt_t x1, pmt_t x2, pmt_t x3)
+pmt_list3(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3)
 {
   return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, PMT_NIL)));
 }
 
 pmt_t
-pmt_list4(pmt_t x1, pmt_t x2, pmt_t x3, pmt_t x4)
+pmt_list4(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4)
 {
   return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, pmt_cons(x4, PMT_NIL))));
 }
 
 pmt_t
-pmt_list5(pmt_t x1, pmt_t x2, pmt_t x3, pmt_t x4, pmt_t x5)
+pmt_list5(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5)
 {
   return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, pmt_cons(x4, pmt_cons(x5, PMT_NIL)))));
 }
 
 pmt_t
-pmt_list6(pmt_t x1, pmt_t x2, pmt_t x3, pmt_t x4, pmt_t x5, pmt_t x6)
+pmt_list6(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5, const pmt_t& x6)
 {
   return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, pmt_cons(x4, pmt_cons(x5, pmt_cons(x6, PMT_NIL))))));
 }
 
+pmt_t
+pmt_list_add(pmt_t list, const pmt_t& item)
+{
+  return pmt_reverse(pmt_cons(item, pmt_reverse(list)));
+}
+
 pmt_t
 pmt_caar(pmt_t pair)
 {