GNU Radio 3.4.2 C++ API
pmt.h
Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /*
00003  * Copyright 2006,2009,2010 Free Software Foundation, Inc.
00004  * 
00005  * This file is part of GNU Radio
00006  * 
00007  * GNU Radio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 3, or (at your option)
00010  * any later version.
00011  * 
00012  * GNU Radio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with GNU Radio; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022 
00023 #ifndef INCLUDED_PMT_H
00024 #define INCLUDED_PMT_H
00025 
00026 #include <boost/intrusive_ptr.hpp>
00027 #include <boost/shared_ptr.hpp>
00028 #include <boost/any.hpp>
00029 #include <complex>
00030 #include <string>
00031 #include <stdint.h>
00032 #include <iosfwd>
00033 #include <stdexcept>
00034 
00035 namespace gruel {
00036   class msg_accepter;
00037 };
00038 
00039 /*!
00040  * This file defines a polymorphic type and the operations on it.
00041  *
00042  * It draws heavily on the idea of scheme and lisp data types.
00043  * The interface parallels that in Guile 1.8, with the notable
00044  * exception that these objects are transparently reference counted.
00045  */
00046 
00047 namespace pmt {
00048 
00049 /*!
00050  * \brief base class of all pmt types
00051  */
00052 class pmt_base;
00053  
00054 /*!
00055  * \brief typedef for shared pointer (transparent reference counting).
00056  * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
00057  */
00058 typedef boost::intrusive_ptr<pmt_base> pmt_t;
00059 
00060 extern void intrusive_ptr_add_ref(pmt_base*);
00061 extern void intrusive_ptr_release(pmt_base*);
00062 
00063 class pmt_exception : public std::logic_error
00064 {
00065 public:
00066   pmt_exception(const std::string &msg, pmt_t obj);
00067 };
00068 
00069 class pmt_wrong_type : public pmt_exception
00070 {
00071 public:
00072   pmt_wrong_type(const std::string &msg, pmt_t obj);
00073 };
00074 
00075 class pmt_out_of_range : public pmt_exception
00076 {
00077 public:
00078   pmt_out_of_range(const std::string &msg, pmt_t obj);
00079 };
00080 
00081 class pmt_notimplemented : public pmt_exception
00082 {
00083 public:
00084   pmt_notimplemented(const std::string &msg, pmt_t obj);
00085 };
00086 
00087 /*
00088  * ------------------------------------------------------------------------
00089  * Booleans.  Two constants, #t and #f.
00090  *
00091  * In predicates, anything that is not #f is considered true.
00092  * I.e., there is a single false value, #f.
00093  * ------------------------------------------------------------------------
00094  */
00095 extern const pmt_t PMT_T;       //< \#t : boolean true constant
00096 extern const pmt_t PMT_F;       //< \#f : boolean false constant
00097 
00098 //! Return true if obj is \#t or \#f, else return false.
00099 bool pmt_is_bool(pmt_t obj);
00100 
00101 //! Return false if obj is \#f, else return true.
00102 bool pmt_is_true(pmt_t obj);
00103 
00104 //! Return true if obj is \#f, else return true.
00105 bool pmt_is_false(pmt_t obj);
00106 
00107 //! Return \#f is val is false, else return \#t.
00108 pmt_t pmt_from_bool(bool val);
00109 
00110 //! Return true if val is PMT_T, return false when val is PMT_F, 
00111 // else raise wrong_type exception.
00112 bool pmt_to_bool(pmt_t val);
00113 
00114 /*
00115  * ------------------------------------------------------------------------
00116  *                             Symbols
00117  * ------------------------------------------------------------------------
00118  */
00119 
00120 //! Return true if obj is a symbol, else false.
00121 bool pmt_is_symbol(const pmt_t& obj);
00122 
00123 //! Return the symbol whose name is \p s.
00124 pmt_t pmt_string_to_symbol(const std::string &s);
00125 
00126 //! Alias for pmt_string_to_symbol
00127 pmt_t pmt_intern(const std::string &s);
00128 
00129 
00130 /*!
00131  * If \p is a symbol, return the name of the symbol as a string.
00132  * Otherwise, raise the wrong_type exception.
00133  */
00134 const std::string pmt_symbol_to_string(const pmt_t& sym);
00135 
00136 /*
00137  * ------------------------------------------------------------------------
00138  *           Numbers: we support integer, real and complex
00139  * ------------------------------------------------------------------------
00140  */
00141 
00142 //! Return true if obj is any kind of number, else false.
00143 bool pmt_is_number(pmt_t obj);
00144 
00145 /*
00146  * ------------------------------------------------------------------------
00147  *                             Integers
00148  * ------------------------------------------------------------------------
00149  */
00150 
00151 //! Return true if \p x is an integer number, else false
00152 bool pmt_is_integer(pmt_t x);
00153 
00154 //! Return the pmt value that represents the integer \p x.
00155 pmt_t pmt_from_long(long x);
00156 
00157 /*!
00158  * \brief Convert pmt to long if possible.
00159  *
00160  * When \p x represents an exact integer that fits in a long,
00161  * return that integer.  Else raise an exception, either wrong_type
00162  * when x is not an exact integer, or out_of_range when it doesn't fit.
00163  */
00164 long pmt_to_long(pmt_t x);
00165 
00166 /*
00167  * ------------------------------------------------------------------------
00168  *                             uint64_t
00169  * ------------------------------------------------------------------------
00170  */
00171 
00172 //! Return true if \p x is an uint64 number, else false
00173 bool pmt_is_uint64(pmt_t x);
00174 
00175 //! Return the pmt value that represents the uint64 \p x.
00176 pmt_t pmt_from_uint64(uint64_t x);
00177 
00178 /*!
00179  * \brief Convert pmt to uint64 if possible.
00180  *
00181  * When \p x represents an exact integer that fits in a uint64,
00182  * return that uint64.  Else raise an exception, either wrong_type
00183  * when x is not an exact uint64, or out_of_range when it doesn't fit.
00184  */
00185 uint64_t pmt_to_uint64(pmt_t x);
00186 
00187 /*
00188  * ------------------------------------------------------------------------
00189  *                              Reals
00190  * ------------------------------------------------------------------------
00191  */
00192 
00193 /*
00194  * \brief Return true if \p obj is a real number, else false.
00195  */
00196 bool pmt_is_real(pmt_t obj);
00197 
00198 //! Return the pmt value that represents double \p x.
00199 pmt_t pmt_from_double(double x);
00200 
00201 /*!
00202  * \brief Convert pmt to double if possible.
00203  *
00204  * Returns the number closest to \p val that is representable
00205  * as a double.  The argument \p val must be a real or integer, otherwise
00206  * a wrong_type exception is raised.
00207  */
00208 double pmt_to_double(pmt_t x);
00209 
00210 /*
00211  * ------------------------------------------------------------------------
00212  *                             Complex
00213  * ------------------------------------------------------------------------
00214  */
00215 
00216 /*!
00217  * \brief return true if \p obj is a complex number, false otherwise.
00218  */
00219 bool pmt_is_complex(pmt_t obj);
00220 
00221 //! Return a complex number constructed of the given real and imaginary parts.
00222 pmt_t pmt_make_rectangular(double re, double im);
00223 
00224 /*!
00225  * If \p z is complex, real or integer, return the closest complex<double>.
00226  * Otherwise, raise the wrong_type exception.
00227  */
00228 std::complex<double> pmt_to_complex(pmt_t z);
00229 
00230 /*
00231  * ------------------------------------------------------------------------
00232  *                              Pairs
00233  * ------------------------------------------------------------------------
00234  */
00235 
00236 extern const pmt_t PMT_NIL;     //< the empty list
00237 
00238 //! Return true if \p x is the empty list, otherwise return false.
00239 bool pmt_is_null(const pmt_t& x);
00240 
00241 //! Return true if \p obj is a pair, else false.
00242 bool pmt_is_pair(const pmt_t& obj);
00243 
00244 //! Return a newly allocated pair whose car is \p x and whose cdr is \p y.
00245 pmt_t pmt_cons(const pmt_t& x, const pmt_t& y);
00246 
00247 //! If \p pair is a pair, return the car of the \p pair, otherwise raise wrong_type.
00248 pmt_t pmt_car(const pmt_t& pair);
00249 
00250 //! If \p pair is a pair, return the cdr of the \p pair, otherwise raise wrong_type.
00251 pmt_t pmt_cdr(const pmt_t& pair);
00252 
00253 //! Stores \p value in the car field of \p pair.
00254 void pmt_set_car(pmt_t pair, pmt_t value);
00255 
00256 //! Stores \p value in the cdr field of \p pair.
00257 void pmt_set_cdr(pmt_t pair, pmt_t value);
00258 
00259 pmt_t pmt_caar(pmt_t pair);
00260 pmt_t pmt_cadr(pmt_t pair);
00261 pmt_t pmt_cdar(pmt_t pair);
00262 pmt_t pmt_cddr(pmt_t pair);
00263 pmt_t pmt_caddr(pmt_t pair);
00264 pmt_t pmt_cadddr(pmt_t pair);
00265 
00266 /*
00267  * ------------------------------------------------------------------------
00268  *                                Tuples
00269  *
00270  * Store a fixed number of objects.  Tuples are not modifiable, and thus
00271  * are excellent for use as messages.  Indexing is zero based.
00272  * Access time to an element is O(1).
00273  * ------------------------------------------------------------------------
00274  */
00275 
00276 //! Return true if \p x is a tuple, othewise false.
00277 bool pmt_is_tuple(pmt_t x);
00278 
00279 pmt_t pmt_make_tuple();
00280 pmt_t pmt_make_tuple(const pmt_t &e0);
00281 pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1);
00282 pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2);
00283 pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3);
00284 pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4);
00285 pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5);
00286 pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6);
00287 pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7);
00288 pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8);
00289 pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8, const pmt_t &e9);
00290 
00291 /*!
00292  * If \p x is a vector or proper list, return a tuple containing the elements of x
00293  */
00294 pmt_t pmt_to_tuple(const pmt_t &x);
00295 
00296 /*!
00297  * Return the contents of position \p k of \p tuple.
00298  * \p k must be a valid index of \p tuple.
00299  */
00300 pmt_t pmt_tuple_ref(const pmt_t &tuple, size_t k);
00301 
00302 /*
00303  * ------------------------------------------------------------------------
00304  *                             Vectors
00305  *
00306  * These vectors can hold any kind of objects.  Indexing is zero based.
00307  * ------------------------------------------------------------------------
00308  */
00309 
00310 //! Return true if \p x is a vector, othewise false.
00311 bool pmt_is_vector(pmt_t x);
00312 
00313 //! Make a vector of length \p k, with initial values set to \p fill
00314 pmt_t pmt_make_vector(size_t k, pmt_t fill);
00315 
00316 /*!
00317  * Return the contents of position \p k of \p vector.
00318  * \p k must be a valid index of \p vector.
00319  */
00320 pmt_t pmt_vector_ref(pmt_t vector, size_t k);
00321 
00322 //! Store \p obj in position \p k.
00323 void pmt_vector_set(pmt_t vector, size_t k, pmt_t obj);
00324 
00325 //! Store \p fill in every position of \p vector
00326 void pmt_vector_fill(pmt_t vector, pmt_t fill);
00327 
00328 /*
00329  * ------------------------------------------------------------------------
00330  *                    Binary Large Objects (BLOBs)
00331  *
00332  * Handy for passing around uninterpreted chunks of memory.
00333  * ------------------------------------------------------------------------
00334  */
00335 
00336 //! Return true if \p x is a blob, othewise false.
00337 bool pmt_is_blob(pmt_t x);
00338 
00339 /*!
00340  * \brief Make a blob given a pointer and length in bytes
00341  *
00342  * \param buf is the pointer to data to use to create blob
00343  * \param len is the size of the data in bytes.
00344  *
00345  * The data is copied into the blob.
00346  */
00347 pmt_t pmt_make_blob(const void *buf, size_t len);
00348 
00349 //! Return a pointer to the blob's data
00350 const void *pmt_blob_data(pmt_t blob);
00351 
00352 //! Return the blob's length in bytes
00353 size_t pmt_blob_length(pmt_t blob);
00354 
00355 /*!
00356  * <pre>
00357  * ------------------------------------------------------------------------
00358  *                     Uniform Numeric Vectors
00359  *
00360  * A uniform numeric vector is a vector whose elements are all of single
00361  * numeric type.  pmt offers uniform numeric vectors for signed and
00362  * unsigned 8-bit, 16-bit, 32-bit, and 64-bit integers, two sizes of
00363  * floating point values, and complex floating-point numbers of these
00364  * two sizes.  Indexing is zero based.
00365  *
00366  * The names of the functions include these tags in their names:
00367  *
00368  *    u8  unsigned 8-bit integers
00369  *    s8  signed 8-bit integers
00370  *   u16  unsigned 16-bit integers
00371  *   s16  signed 16-bit integers
00372  *   u32  unsigned 32-bit integers
00373  *   s32  signed 32-bit integers
00374  *   u64  unsigned 64-bit integers
00375  *   s64  signed 64-bit integers
00376  *   f32  the C++ type float
00377  *   f64  the C++ type double
00378  *   c32  the C++ type complex<float>
00379  *   c64  the C++ type complex<double>
00380  * ------------------------------------------------------------------------
00381  * </pre>
00382  */
00383 
00384 //! true if \p x is any kind of uniform numeric vector
00385 bool pmt_is_uniform_vector(pmt_t x);  
00386 
00387 bool pmt_is_u8vector(pmt_t x);
00388 bool pmt_is_s8vector(pmt_t x);
00389 bool pmt_is_u16vector(pmt_t x);
00390 bool pmt_is_s16vector(pmt_t x);
00391 bool pmt_is_u32vector(pmt_t x);
00392 bool pmt_is_s32vector(pmt_t x);
00393 bool pmt_is_u64vector(pmt_t x);
00394 bool pmt_is_s64vector(pmt_t x);
00395 bool pmt_is_f32vector(pmt_t x);
00396 bool pmt_is_f64vector(pmt_t x);
00397 bool pmt_is_c32vector(pmt_t x);
00398 bool pmt_is_c64vector(pmt_t x);
00399 
00400 pmt_t pmt_make_u8vector(size_t k, uint8_t fill);
00401 pmt_t pmt_make_s8vector(size_t k, int8_t fill);
00402 pmt_t pmt_make_u16vector(size_t k, uint16_t fill);
00403 pmt_t pmt_make_s16vector(size_t k, int16_t fill);
00404 pmt_t pmt_make_u32vector(size_t k, uint32_t fill);
00405 pmt_t pmt_make_s32vector(size_t k, int32_t fill);
00406 pmt_t pmt_make_u64vector(size_t k, uint64_t fill);
00407 pmt_t pmt_make_s64vector(size_t k, int64_t fill);
00408 pmt_t pmt_make_f32vector(size_t k, float fill);
00409 pmt_t pmt_make_f64vector(size_t k, double fill);
00410 pmt_t pmt_make_c32vector(size_t k, std::complex<float> fill);
00411 pmt_t pmt_make_c64vector(size_t k, std::complex<double> fill);
00412 
00413 pmt_t pmt_init_u8vector(size_t k, const uint8_t *data);
00414 pmt_t pmt_init_s8vector(size_t k, const int8_t *data);
00415 pmt_t pmt_init_u16vector(size_t k, const uint16_t *data);
00416 pmt_t pmt_init_s16vector(size_t k, const int16_t *data);
00417 pmt_t pmt_init_u32vector(size_t k, const uint32_t *data);
00418 pmt_t pmt_init_s32vector(size_t k, const int32_t *data);
00419 pmt_t pmt_init_u64vector(size_t k, const uint64_t *data);
00420 pmt_t pmt_init_s64vector(size_t k, const int64_t *data);
00421 pmt_t pmt_init_f32vector(size_t k, const float *data);
00422 pmt_t pmt_init_f64vector(size_t k, const double *data);
00423 pmt_t pmt_init_c32vector(size_t k, const std::complex<float> *data);
00424 pmt_t pmt_init_c64vector(size_t k, const std::complex<double> *data);
00425 
00426 uint8_t  pmt_u8vector_ref(pmt_t v, size_t k);
00427 int8_t   pmt_s8vector_ref(pmt_t v, size_t k);
00428 uint16_t pmt_u16vector_ref(pmt_t v, size_t k);
00429 int16_t  pmt_s16vector_ref(pmt_t v, size_t k);
00430 uint32_t pmt_u32vector_ref(pmt_t v, size_t k);
00431 int32_t  pmt_s32vector_ref(pmt_t v, size_t k);
00432 uint64_t pmt_u64vector_ref(pmt_t v, size_t k);
00433 int64_t  pmt_s64vector_ref(pmt_t v, size_t k);
00434 float    pmt_f32vector_ref(pmt_t v, size_t k);
00435 double   pmt_f64vector_ref(pmt_t v, size_t k);
00436 std::complex<float>  pmt_c32vector_ref(pmt_t v, size_t k);
00437 std::complex<double> pmt_c64vector_ref(pmt_t v, size_t k);
00438 
00439 void pmt_u8vector_set(pmt_t v, size_t k, uint8_t x);  //< v[k] = x
00440 void pmt_s8vector_set(pmt_t v, size_t k, int8_t x);
00441 void pmt_u16vector_set(pmt_t v, size_t k, uint16_t x);
00442 void pmt_s16vector_set(pmt_t v, size_t k, int16_t x);
00443 void pmt_u32vector_set(pmt_t v, size_t k, uint32_t x);
00444 void pmt_s32vector_set(pmt_t v, size_t k, int32_t x);
00445 void pmt_u64vector_set(pmt_t v, size_t k, uint64_t x);
00446 void pmt_s64vector_set(pmt_t v, size_t k, int64_t x);
00447 void pmt_f32vector_set(pmt_t v, size_t k, float x);
00448 void pmt_f64vector_set(pmt_t v, size_t k, double x);
00449 void pmt_c32vector_set(pmt_t v, size_t k, std::complex<float> x);
00450 void pmt_c64vector_set(pmt_t v, size_t k, std::complex<double> x);
00451 
00452 // Return const pointers to the elements
00453 
00454 const void *pmt_uniform_vector_elements(pmt_t v, size_t &len);  //< works with any; len is in bytes
00455 
00456 const uint8_t  *pmt_u8vector_elements(pmt_t v, size_t &len);  //< len is in elements
00457 const int8_t   *pmt_s8vector_elements(pmt_t v, size_t &len);  //< len is in elements
00458 const uint16_t *pmt_u16vector_elements(pmt_t v, size_t &len); //< len is in elements
00459 const int16_t  *pmt_s16vector_elements(pmt_t v, size_t &len); //< len is in elements
00460 const uint32_t *pmt_u32vector_elements(pmt_t v, size_t &len); //< len is in elements
00461 const int32_t  *pmt_s32vector_elements(pmt_t v, size_t &len); //< len is in elements
00462 const uint64_t *pmt_u64vector_elements(pmt_t v, size_t &len); //< len is in elements
00463 const int64_t  *pmt_s64vector_elements(pmt_t v, size_t &len); //< len is in elements
00464 const float    *pmt_f32vector_elements(pmt_t v, size_t &len); //< len is in elements
00465 const double   *pmt_f64vector_elements(pmt_t v, size_t &len); //< len is in elements
00466 const std::complex<float>  *pmt_c32vector_elements(pmt_t v, size_t &len); //< len is in elements
00467 const std::complex<double> *pmt_c64vector_elements(pmt_t v, size_t &len); //< len is in elements
00468 
00469 // Return non-const pointers to the elements
00470 
00471 void *pmt_uniform_vector_writable_elements(pmt_t v, size_t &len);  //< works with any; len is in bytes
00472 
00473 uint8_t  *pmt_u8vector_writable_elements(pmt_t v, size_t &len);  //< len is in elements
00474 int8_t   *pmt_s8vector_writable_elements(pmt_t v, size_t &len);  //< len is in elements
00475 uint16_t *pmt_u16vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
00476 int16_t  *pmt_s16vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
00477 uint32_t *pmt_u32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
00478 int32_t  *pmt_s32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
00479 uint64_t *pmt_u64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
00480 int64_t  *pmt_s64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
00481 float    *pmt_f32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
00482 double   *pmt_f64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
00483 std::complex<float>  *pmt_c32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
00484 std::complex<double> *pmt_c64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
00485 
00486 /*
00487  * ------------------------------------------------------------------------
00488  *         Dictionary (a.k.a associative array, hash, map)
00489  *
00490  * This is a functional data structure that is persistent.  Updating a
00491  * functional data structure does not destroy the existing version, but
00492  * rather creates a new version that coexists with the old.
00493  * ------------------------------------------------------------------------
00494  */
00495 
00496 //! Return true if \p obj is a dictionary
00497 bool pmt_is_dict(const pmt_t &obj);
00498 
00499 //! Make an empty dictionary
00500 pmt_t pmt_make_dict();
00501 
00502 //! Return a new dictionary with \p key associated with \p value.
00503 pmt_t pmt_dict_add(const pmt_t &dict, const pmt_t &key, const pmt_t &value);
00504 
00505 //! Return a new dictionary with \p key removed.
00506 pmt_t pmt_dict_delete(const pmt_t &dict, const pmt_t &key);
00507 
00508 //! Return true if \p key exists in \p dict
00509 bool  pmt_dict_has_key(const pmt_t &dict, const pmt_t &key);
00510 
00511 //! If \p key exists in \p dict, return associated value; otherwise return \p not_found.
00512 pmt_t pmt_dict_ref(const pmt_t &dict, const pmt_t &key, const pmt_t &not_found);
00513 
00514 //! Return list of (key . value) pairs
00515 pmt_t pmt_dict_items(pmt_t dict);
00516 
00517 //! Return list of keys
00518 pmt_t pmt_dict_keys(pmt_t dict);
00519 
00520 //! Return list of values
00521 pmt_t pmt_dict_values(pmt_t dict);
00522 
00523 /*
00524  * ------------------------------------------------------------------------
00525  *   Any (wraps boost::any -- can be used to wrap pretty much anything)
00526  *
00527  * Cannot be serialized or used across process boundaries.
00528  * See http://www.boost.org/doc/html/any.html
00529  * ------------------------------------------------------------------------
00530  */
00531 
00532 //! Return true if \p obj is an any
00533 bool pmt_is_any(pmt_t obj);
00534 
00535 //! make an any
00536 pmt_t pmt_make_any(const boost::any &any);
00537 
00538 //! Return underlying boost::any
00539 boost::any pmt_any_ref(pmt_t obj);
00540 
00541 //! Store \p any in \p obj
00542 void pmt_any_set(pmt_t obj, const boost::any &any);
00543 
00544 
00545 /*
00546  * ------------------------------------------------------------------------
00547  *    msg_accepter -- pmt representation of gruel::msg_accepter
00548  * ------------------------------------------------------------------------
00549  */
00550 //! Return true if \p obj is a msg_accepter
00551 bool pmt_is_msg_accepter(const pmt_t &obj);
00552 
00553 //! make a msg_accepter
00554 pmt_t pmt_make_msg_accepter(boost::shared_ptr<gruel::msg_accepter> ma);
00555 
00556 //! Return underlying msg_accepter
00557 boost::shared_ptr<gruel::msg_accepter> pmt_msg_accepter_ref(const pmt_t &obj);
00558 
00559 /*
00560  * ------------------------------------------------------------------------
00561  *                        General functions
00562  * ------------------------------------------------------------------------
00563  */
00564 
00565 //! Return true if x and y are the same object; otherwise return false.
00566 bool pmt_eq(const pmt_t& x, const pmt_t& y);
00567 
00568 /*!
00569  * \brief Return true if x and y should normally be regarded as the same object, else false.
00570  *
00571  * <pre>
00572  * eqv returns true if:
00573  *   x and y are the same object.
00574  *   x and y are both \#t or both \#f.
00575  *   x and y are both symbols and their names are the same.
00576  *   x and y are both numbers, and are numerically equal.
00577  *   x and y are both the empty list (nil).
00578  *   x and y are pairs or vectors that denote same location in store.
00579  * </pre>
00580  */
00581 bool pmt_eqv(const pmt_t& x, const pmt_t& y);
00582 
00583 /*!
00584  * pmt_equal recursively compares the contents of pairs and vectors,
00585  * applying pmt_eqv on other objects such as numbers and symbols.  
00586  * pmt_equal may fail to terminate if its arguments are circular data
00587  * structures.
00588  */
00589 bool pmt_equal(const pmt_t& x, const pmt_t& y);
00590 
00591 
00592 //! Return the number of elements in v
00593 size_t pmt_length(const pmt_t& v);
00594 
00595 /*!
00596  * \brief Find the first pair in \p alist whose car field is \p obj
00597  *  and return that pair.
00598  *
00599  * \p alist (for "association list") must be a list of pairs.  If no pair
00600  * in \p alist has \p obj as its car then \#f is returned.
00601  * Uses pmt_eq to compare \p obj with car fields of the pairs in \p alist.
00602  */
00603 pmt_t pmt_assq(pmt_t obj, pmt_t alist);
00604 
00605 /*!
00606  * \brief Find the first pair in \p alist whose car field is \p obj
00607  *  and return that pair.
00608  *
00609  * \p alist (for "association list") must be a list of pairs.  If no pair
00610  * in \p alist has \p obj as its car then \#f is returned.
00611  * Uses pmt_eqv to compare \p obj with car fields of the pairs in \p alist.
00612  */
00613 pmt_t pmt_assv(pmt_t obj, pmt_t alist);
00614 
00615 /*!
00616  * \brief Find the first pair in \p alist whose car field is \p obj
00617  *  and return that pair.
00618  *
00619  * \p alist (for "association list") must be a list of pairs.  If no pair
00620  * in \p alist has \p obj as its car then \#f is returned.
00621  * Uses pmt_equal to compare \p obj with car fields of the pairs in \p alist.
00622  */
00623 pmt_t pmt_assoc(pmt_t obj, pmt_t alist);
00624 
00625 /*!
00626  * \brief Apply \p proc element-wise to the elements of list and returns
00627  * a list of the results, in order.
00628  *
00629  * \p list must be a list.  The dynamic order in which \p proc is
00630  * applied to the elements of \p list is unspecified.
00631  */
00632 pmt_t pmt_map(pmt_t proc(const pmt_t&), pmt_t list);
00633 
00634 /*!
00635  * \brief reverse \p list.
00636  *
00637  * \p list must be a proper list.
00638  */
00639 pmt_t pmt_reverse(pmt_t list);
00640 
00641 /*!
00642  * \brief destructively reverse \p list.
00643  *
00644  * \p list must be a proper list.
00645  */
00646 pmt_t pmt_reverse_x(pmt_t list);
00647 
00648 /*!
00649  * \brief (acons x y a) == (cons (cons x y) a)
00650  */
00651 inline static pmt_t
00652 pmt_acons(pmt_t x, pmt_t y, pmt_t a)
00653 {
00654   return pmt_cons(pmt_cons(x, y), a);
00655 }
00656 
00657 /*!
00658  * \brief locates \p nth element of \n list where the car is the 'zeroth' element.
00659  */
00660 pmt_t pmt_nth(size_t n, pmt_t list);
00661 
00662 /*!
00663  * \brief returns the tail of \p list that would be obtained by calling
00664  * cdr \p n times in succession.
00665  */
00666 pmt_t pmt_nthcdr(size_t n, pmt_t list);
00667 
00668 /*!
00669  * \brief Return the first sublist of \p list whose car is \p obj.
00670  * If \p obj does not occur in \p list, then \#f is returned.
00671  * pmt_memq use pmt_eq to compare \p obj with the elements of \p list.
00672  */
00673 pmt_t pmt_memq(pmt_t obj, pmt_t list);
00674 
00675 /*!
00676  * \brief Return the first sublist of \p list whose car is \p obj.
00677  * If \p obj does not occur in \p list, then \#f is returned.
00678  * pmt_memv use pmt_eqv to compare \p obj with the elements of \p list.
00679  */
00680 pmt_t pmt_memv(pmt_t obj, pmt_t list);
00681 
00682 /*!
00683  * \brief Return the first sublist of \p list whose car is \p obj.
00684  * If \p obj does not occur in \p list, then \#f is returned.
00685  * pmt_member use pmt_equal to compare \p obj with the elements of \p list.
00686  */
00687 pmt_t pmt_member(pmt_t obj, pmt_t list);
00688 
00689 /*!
00690  * \brief Return true if every element of \p list1 appears in \p list2, and false otherwise.
00691  * Comparisons are done with pmt_eqv.
00692  */
00693 bool pmt_subsetp(pmt_t list1, pmt_t list2);
00694 
00695 /*!
00696  * \brief Return a list of length 1 containing \p x1
00697  */
00698 pmt_t pmt_list1(const pmt_t& x1);
00699 
00700 /*!
00701  * \brief Return a list of length 2 containing \p x1, \p x2
00702  */
00703 pmt_t pmt_list2(const pmt_t& x1, const pmt_t& x2);
00704 
00705 /*!
00706  * \brief Return a list of length 3 containing \p x1, \p x2, \p x3
00707  */
00708 pmt_t pmt_list3(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3);
00709 
00710 /*!
00711  * \brief Return a list of length 4 containing \p x1, \p x2, \p x3, \p x4
00712  */
00713 pmt_t pmt_list4(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4);
00714 
00715 /*!
00716  * \brief Return a list of length 5 containing \p x1, \p x2, \p x3, \p x4, \p x5
00717  */
00718 pmt_t pmt_list5(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5);
00719 
00720 /*!
00721  * \brief Return a list of length 6 containing \p x1, \p x2, \p x3, \p x4, \p
00722  * x5, \p x6
00723  */
00724 pmt_t 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);
00725 
00726 /*!
00727  * \brief Return \p list with \p item added to it.
00728  */
00729 pmt_t pmt_list_add(pmt_t list, const pmt_t& item);
00730 
00731 
00732 /*
00733  * ------------------------------------------------------------------------
00734  *                           read / write
00735  * ------------------------------------------------------------------------
00736  */
00737 extern const pmt_t PMT_EOF;     //< The end of file object
00738 
00739 //! return true if obj is the EOF object, otherwise return false.
00740 bool pmt_is_eof_object(pmt_t obj);
00741 
00742 /*!
00743  * read converts external representations of pmt objects into the
00744  * objects themselves.  Read returns the next object parsable from
00745  * the given input port, updating port to point to the first
00746  * character past the end of the external representation of the
00747  * object.
00748  *
00749  * If an end of file is encountered in the input before any
00750  * characters are found that can begin an object, then an end of file
00751  * object is returned.   The port remains open, and further attempts
00752  * to read will also return an end of file object.  If an end of file
00753  * is encountered after the beginning of an object's external
00754  * representation, but the external representation is incomplete and
00755  * therefore not parsable, an error is signaled.
00756  */
00757 pmt_t pmt_read(std::istream &port);
00758 
00759 /*!
00760  * Write a written representation of \p obj to the given \p port.
00761  */
00762 void pmt_write(pmt_t obj, std::ostream &port);
00763 
00764 /*!
00765  * Return a string representation of \p obj.
00766  * This is the same output as would be generated by pmt_write.
00767  */
00768 std::string pmt_write_string(pmt_t obj);
00769 
00770 
00771 std::ostream& operator<<(std::ostream &os, pmt_t obj);
00772 
00773 /*!
00774  * \brief Write pmt string representation to stdout.
00775  */
00776 void pmt_print(pmt_t v);
00777 
00778 
00779 /*
00780  * ------------------------------------------------------------------------
00781  *                    portable byte stream representation
00782  * ------------------------------------------------------------------------
00783  */
00784 /*!
00785  * \brief Write portable byte-serial representation of \p obj to \p sink
00786  */
00787 bool pmt_serialize(pmt_t obj, std::streambuf &sink);
00788 
00789 /*!
00790  * \brief Create obj from portable byte-serial representation
00791  */
00792 pmt_t pmt_deserialize(std::streambuf &source);
00793 
00794 
00795 void pmt_dump_sizeof(); // debugging
00796 
00797 /*!
00798  * \brief Provide a simple string generating interface to pmt's serialize function
00799  */
00800 std::string pmt_serialize_str(pmt_t obj);
00801 
00802 /*!
00803  * \brief Provide a simple string generating interface to pmt's deserialize function
00804  */
00805 pmt_t pmt_deserialize_str(std::string str);
00806 
00807 } /* namespace pmt */
00808 
00809 #include <gruel/pmt_sugar.h>
00810 
00811 #endif /* INCLUDED_PMT_H */