Merged r4632:4645 on jcorgan/linking into trunk. Cleans up linking issues with libto...
[debian/gnuradio] / pmt / src / lib / pmt.cc
index a1569e414f45dde916763206e2207a43d6407f43..cf6547b572f6834a149ae963fc4634e94f354e1b 100644 (file)
@@ -16,8 +16,8 @@
  * 
  * You should have received a copy of the GNU General Public License
  * along with GNU Radio; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -36,18 +36,23 @@ pmt_base::~pmt_base()
 //                         Exceptions
 ////////////////////////////////////////////////////////////////////////////
 
-pmt_exception::pmt_exception(const char *msg, pmt_t obj)
-  : d_msg(msg), d_obj(obj)
+pmt_exception::pmt_exception(const std::string &msg, pmt_t obj)
+  : logic_error(msg + ": " + pmt_write_string(obj))
 {
 }
 
-pmt_wrong_type::pmt_wrong_type(const char *msg, pmt_t obj)
-  : pmt_exception(msg, obj)
+pmt_wrong_type::pmt_wrong_type(const std::string &msg, pmt_t obj)
+  : pmt_exception(msg + ": wrong_type ", obj)
 {
 }
 
-pmt_out_of_range::pmt_out_of_range(const char *msg, pmt_t obj)
-  : pmt_exception(msg, obj)
+pmt_out_of_range::pmt_out_of_range(const std::string &msg, pmt_t obj)
+  : pmt_exception(msg + ": out of range ", obj)
+{
+}
+
+pmt_notimplemented::pmt_notimplemented(const std::string &msg, pmt_t obj)
+  : pmt_exception(msg + ": notimplemented ", obj)
 {
 }
 
@@ -91,6 +96,12 @@ _vector(pmt_t x)
   return dynamic_cast<pmt_vector*>(x.get());
 }
 
+static pmt_uniform_vector *
+_uniform_vector(pmt_t x)
+{
+  return dynamic_cast<pmt_uniform_vector*>(x.get());
+}
+
 static pmt_dict *
 _dict(pmt_t x)
 {
@@ -191,6 +202,13 @@ pmt_string_to_symbol(const std::string &name)
   return sym;
 }
 
+// alias...
+pmt_t
+pmt_intern(const std::string &name)
+{
+  return pmt_string_to_symbol(name);
+}
+
 const std::string
 pmt_symbol_to_string(pmt_t sym)
 {
@@ -200,6 +218,8 @@ pmt_symbol_to_string(pmt_t sym)
   return _symbol(sym)->name();
 }
 
+
+
 ////////////////////////////////////////////////////////////////////////////
 //                             Number
 ////////////////////////////////////////////////////////////////////////////
@@ -431,6 +451,32 @@ pmt_vector_fill(pmt_t vector, pmt_t obj)
   _vector(vector)->fill(obj);
 }
 
+////////////////////////////////////////////////////////////////////////////
+//                       Uniform Numeric Vectors
+////////////////////////////////////////////////////////////////////////////
+
+bool
+pmt_is_uniform_vector(pmt_t x)
+{
+  return x->is_uniform_vector();
+}
+
+const void *
+pmt_uniform_vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_uniform_vector())
+    throw pmt_wrong_type("pmt_uniform_vector_elements", vector);
+  return _uniform_vector(vector)->uniform_elements(len);
+}
+
+void *
+pmt_uniform_vector_writeable_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);
+}
+
 ////////////////////////////////////////////////////////////////////////////
 //                            Dictionaries
 ////////////////////////////////////////////////////////////////////////////
@@ -602,6 +648,21 @@ pmt_equal(pmt_t x, pmt_t y)
     return true;
   }
 
+  if (x->is_uniform_vector() && y->is_uniform_vector()){
+    pmt_uniform_vector *xv = _uniform_vector(x);
+    pmt_uniform_vector *yv = _uniform_vector(y);
+    if (xv->length() != yv->length())
+      return false;
+
+    size_t len_x, len_y;
+    if (memcmp(xv->uniform_elements(len_x),
+              yv->uniform_elements(len_y),
+              len_x) == 0)
+      return true;
+
+    return true;
+  }
+
   // FIXME add other cases here...
 
   return false;
@@ -613,8 +674,10 @@ pmt_length(pmt_t x)
   if (x->is_vector())
     return _vector(x)->length();
 
+  if (x->is_uniform_vector())
+    return _uniform_vector(x)->length();
+
   // FIXME list length
-  // FIXME uniform vector length
   // FIXME dictionary length (number of entries)
 
   throw pmt_wrong_type("pmt_length", x);
@@ -703,3 +766,102 @@ pmt_reverse_x(pmt_t list)
   // FIXME do it destructively
   return pmt_reverse(list);
 }
+
+pmt_t
+pmt_nth(size_t n, pmt_t list)
+{
+  pmt_t t = pmt_nthcdr(n, list);
+  if (pmt_is_pair(t))
+    return pmt_car(t);
+  else
+    return PMT_NIL;
+}
+
+pmt_t
+pmt_nthcdr(size_t n, pmt_t list)
+{
+  if (!(pmt_is_null(list) || pmt_is_pair(list)))
+    throw pmt_wrong_type("pmt_nthcdr", list);
+    
+  while (n > 0){
+    if (pmt_is_pair(list)){
+      list = pmt_cdr(list);
+      n--;
+      continue;
+    }
+    if (pmt_is_null(list))
+      return PMT_NIL;
+    else
+      throw pmt_wrong_type("pmt_nthcdr: not a LIST", list);
+  }
+  return list;
+}
+
+pmt_t
+pmt_memq(pmt_t obj, pmt_t list)
+{
+  while (pmt_is_pair(list)){
+    if (pmt_eq(obj, pmt_car(list)))
+      return list;
+    list = pmt_cdr(list);
+  }
+  return PMT_BOOL_F;
+}
+
+pmt_t
+pmt_memv(pmt_t obj, pmt_t list)
+{
+  while (pmt_is_pair(list)){
+    if (pmt_eqv(obj, pmt_car(list)))
+      return list;
+    list = pmt_cdr(list);
+  }
+  return PMT_BOOL_F;
+}
+
+pmt_t
+pmt_member(pmt_t obj, pmt_t list)
+{
+  while (pmt_is_pair(list)){
+    if (pmt_equal(obj, pmt_car(list)))
+      return list;
+    list = pmt_cdr(list);
+  }
+  return PMT_BOOL_F;
+}
+
+bool
+pmt_subsetp(pmt_t list1, pmt_t list2)
+{
+  while (pmt_is_pair(list1)){
+    pmt_t p = pmt_car(list1);
+    if (pmt_is_false(pmt_memv(p, list2)))
+      return false;
+    list1 = pmt_cdr(list1);
+  }
+  return true;
+}
+
+pmt_t
+pmt_list1(pmt_t x1)
+{
+  return pmt_cons(x1, PMT_NIL);
+}
+
+pmt_t
+pmt_list2(pmt_t x1, 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)
+{
+  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)
+{
+  return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, pmt_cons(x4, PMT_NIL))));
+}