GNU Radio 3.4.0 C++ API
|
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 ¬_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 */