summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
m---------PMC0
-rw-r--r--include/gnuradio/block.hpp31
-rw-r--r--include/gnuradio/gr_block.h20
-rw-r--r--include/gnuradio/gr_tags.h26
-rw-r--r--include/gnuradio/tags.hpp34
-rw-r--r--lib/CMakeLists.txt14
-rw-r--r--lib/block.cpp54
-rw-r--r--lib/gr_block.cpp64
-rw-r--r--lib/pmx_helper.hpp263
-rw-r--r--lib/tag_handlers.hpp2
-rw-r--r--lib/tags.cpp36
12 files changed, 454 insertions, 93 deletions
diff --git a/.gitmodules b/.gitmodules
index ed5ffe7..98a7640 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,3 +7,6 @@
[submodule "Apology"]
path = Apology
url = https://github.com/guruofquality/Apology.git
+[submodule "PMC"]
+ path = PMC
+ url = https://github.com/guruofquality/PMC.git
diff --git a/PMC b/PMC
new file mode 160000
+Subproject 7d96189a250a2ad14acd8a900ff4b114266a664
diff --git a/include/gnuradio/block.hpp b/include/gnuradio/block.hpp
index 23274b1..bcce34a 100644
--- a/include/gnuradio/block.hpp
+++ b/include/gnuradio/block.hpp
@@ -22,6 +22,7 @@
#include <gnuradio/tags.hpp>
#include <vector>
#include <string>
+#include <boost/range.hpp> //iterator range
namespace gnuradio
{
@@ -214,32 +215,14 @@ struct GRAS_API Block : Element
void set_tag_propagation_policy(tag_propagation_policy_t p);
- void add_item_tag(
- const size_t which_output, const Tag &tag
- );
-
- void add_item_tag(
- const size_t which_output,
- uint64_t abs_offset,
- const pmt::pmt_t &key,
- const pmt::pmt_t &value,
- const pmt::pmt_t &srcid=pmt::PMT_F
- );
+ //! Send a tag to the downstream on the given output port
+ void post_output_tag(const size_t which_output, const Tag &tag);
- void get_tags_in_range(
- std::vector<Tag> &tags,
- const size_t which_input,
- uint64_t abs_start,
- uint64_t abs_end
- );
+ //! Iterator return type get_input_tags - stl and boost compliant
+ typedef boost::iterator_range<std::vector<Tag>::const_iterator> TagIter;
- void get_tags_in_range(
- std::vector<Tag> &tags,
- const size_t which_input,
- uint64_t abs_start,
- uint64_t abs_end,
- const pmt::pmt_t &key
- );
+ //! Get an iterator of item tags for the given input
+ TagIter get_input_tags(const size_t which_input = 0);
/*******************************************************************
* Work related routines from basic block
diff --git a/include/gnuradio/gr_block.h b/include/gnuradio/gr_block.h
index 7328dd1..8e0c40e 100644
--- a/include/gnuradio/gr_block.h
+++ b/include/gnuradio/gr_block.h
@@ -80,6 +80,26 @@ struct GRAS_API gr_block : gnuradio::Block
gr_vector_void_star &output_items
);
+ void add_item_tag(
+ const size_t which_output, const gr_tag_t &tag
+ );
+
+ void add_item_tag(
+ const size_t which_output,
+ uint64_t abs_offset,
+ const pmt::pmt_t &key,
+ const pmt::pmt_t &value,
+ const pmt::pmt_t &srcid=pmt::PMT_F
+ );
+
+ void get_tags_in_range(
+ std::vector<gr_tag_t> &tags,
+ const size_t which_input,
+ uint64_t abs_start,
+ uint64_t abs_end,
+ const pmt::pmt_t &key = pmt::pmt_t()
+ );
+
unsigned history(void) const;
void set_history(unsigned history);
diff --git a/include/gnuradio/gr_tags.h b/include/gnuradio/gr_tags.h
index e4c9508..ca45170 100644
--- a/include/gnuradio/gr_tags.h
+++ b/include/gnuradio/gr_tags.h
@@ -17,8 +17,30 @@
#ifndef INCLUDED_GR_TAGS_H
#define INCLUDED_GR_TAGS_H
-#include <gnuradio/tags.hpp>
+#include <gnuradio/gras.hpp>
+#include <gruel/pmt.h>
-typedef gnuradio::Tag gr_tag_t;
+struct GRAS_API gr_tag_t
+{
+
+ //! the item \p tag occurred at (as a uint64_t)
+ uint64_t offset;
+
+ //! the key of \p tag (as a PMT symbol)
+ pmt::pmt_t key;
+
+ //! the value of \p tag (as a PMT)
+ pmt::pmt_t value;
+
+ //! the source ID of \p tag (as a PMT)
+ pmt::pmt_t srcid;
+
+ //! Comparison function to test which tag, \p x or \p y, came first in time
+ static inline bool offset_compare(
+ const gr_tag_t &x, const gr_tag_t &y
+ ){
+ return x.offset < y.offset;
+ }
+};
#endif /*INCLUDED_GR_TAGS_H*/
diff --git a/include/gnuradio/tags.hpp b/include/gnuradio/tags.hpp
index d8414d8..bc83709 100644
--- a/include/gnuradio/tags.hpp
+++ b/include/gnuradio/tags.hpp
@@ -18,34 +18,36 @@
#define INCLUDED_GNURADIO_TAGS_HPP
#include <gnuradio/gras.hpp>
-#include <gruel/pmt.h>
+#include <boost/operators.hpp>
+#include <PMC/PMC.hpp>
+#include <boost/cstdint.hpp>
namespace gnuradio
{
-struct GRAS_API Tag
+struct GRAS_API Tag : boost::less_than_comparable<Tag>
{
+ //! Make an empty tag with null members
+ Tag(void);
- //! the item \p tag occurred at (as a uint64_t)
- uint64_t offset;
+ //! Make a tag from parameters to initialize the members
+ Tag(const uint64_t &offset, const PMCC &key, const PMCC &value, const PMCC &srcid = PMCC());
- //! the key of \p tag (as a PMT symbol)
- pmt::pmt_t key;
+ //! the absolute item count associated with this tag
+ boost::uint64_t offset;
- //! the value of \p tag (as a PMT)
- pmt::pmt_t value;
+ //! A symbolic name identifying the type of tag
+ PMCC key;
- //! the source ID of \p tag (as a PMT)
- pmt::pmt_t srcid;
+ //! The value of this tag -> the sample metadata
+ PMCC value;
- //! Comparison function to test which tag, \p x or \p y, came first in time
- static inline bool offset_compare(
- const Tag &x, const Tag &y
- ){
- return x.offset < y.offset;
- }
+ //! The optional source ID -> something unique
+ PMCC srcid;
};
+GRAS_API bool operator<(const Tag &lhs, const Tag &rhs);
+
} //namespace gnuradio
#endif /*INCLUDED_GNURADIO_TAGS_HPP*/
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 131c00a..bb471f7 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -12,6 +12,19 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
endif()
########################################################################
+# Setup PMC Deps
+########################################################################
+include_directories(${GRAS_SOURCE_DIR}/PMC/include)
+
+list(APPEND GNURADIO_CORE_INCLUDE_DIRS ${GRAS_SOURCE_DIR}/PMC/include)
+GR_SET_GLOBAL(GNURADIO_CORE_INCLUDE_DIRS ${GNURADIO_CORE_INCLUDE_DIRS})
+
+list(APPEND GNURADIO_CORE_SWIG_INCLUDE_DIRS ${GRAS_SOURCE_DIR}/PMC/include)
+GR_SET_GLOBAL(GNURADIO_CORE_SWIG_INCLUDE_DIRS ${GNURADIO_CORE_SWIG_INCLUDE_DIRS})
+
+add_subdirectory(${GRAS_SOURCE_DIR}/PMC ${CMAKE_BINARY_DIR}/PMC)
+
+########################################################################
# Setup Theron Deps
########################################################################
set(THERON_SOURCE_DIR ${GRAS_SOURCE_DIR}/Theron)
@@ -39,6 +52,7 @@ list(APPEND gnuradio_core_sources
${CMAKE_CURRENT_SOURCE_DIR}/debug.cpp
${CMAKE_CURRENT_SOURCE_DIR}/element.cpp
${CMAKE_CURRENT_SOURCE_DIR}/sbuffer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/tags.cpp
${CMAKE_CURRENT_SOURCE_DIR}/block.cpp
${CMAKE_CURRENT_SOURCE_DIR}/block_actor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/block_task.cpp
diff --git a/lib/block.cpp b/lib/block.cpp
index 6b27ab2..95d27fa 100644
--- a/lib/block.cpp
+++ b/lib/block.cpp
@@ -176,64 +176,18 @@ void Block::set_tag_propagation_policy(Block::tag_propagation_policy_t p)
(*this)->block->tag_prop_policy = p;
}
-void Block::add_item_tag(
+void Block::post_output_tag(
const size_t which_output,
const Tag &tag
){
(*this)->block->post_downstream(which_output, InputTagMessage(tag));
}
-void Block::add_item_tag(
- const size_t which_output,
- uint64_t abs_offset,
- const pmt::pmt_t &key,
- const pmt::pmt_t &value,
- const pmt::pmt_t &srcid
-){
- Tag t;
- t.offset = abs_offset;
- t.key = key;
- t.value = value;
- t.srcid = srcid;
- this->add_item_tag(which_output, t);
-}
-
-void Block::get_tags_in_range(
- std::vector<Tag> &tags,
- const size_t which_input,
- uint64_t abs_start,
- uint64_t abs_end
-){
- const std::vector<Tag> &input_tags = (*this)->block->input_tags[which_input];
- tags.clear();
- for (size_t i = 0; i < input_tags.size(); i++)
- {
- if (input_tags[i].offset >= abs_start and input_tags[i].offset <= abs_end)
- {
- tags.push_back(input_tags[i]);
- }
- }
-}
-
-void Block::get_tags_in_range(
- std::vector<Tag> &tags,
- const size_t which_input,
- uint64_t abs_start,
- uint64_t abs_end,
- const pmt::pmt_t &key
+Block::TagIter Block::get_input_tags(
+ const size_t which_input
){
const std::vector<Tag> &input_tags = (*this)->block->input_tags[which_input];
- tags.clear();
- for (size_t i = 0; i < input_tags.size(); i++)
- {
- if (
- input_tags[i].offset >= abs_start and
- input_tags[i].offset <= abs_end and
- pmt::pmt_equal(input_tags[i].key, key)
- ){
- tags.push_back(input_tags[i]);
- }
- }
+ return boost::make_iterator_range(input_tags.begin(), input_tags.end());
}
void Block::forecast(int, std::vector<int> &)
diff --git a/lib/gr_block.cpp b/lib/gr_block.cpp
index b4e7c04..f8ce6f4 100644
--- a/lib/gr_block.cpp
+++ b/lib/gr_block.cpp
@@ -15,7 +15,9 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "element_impl.hpp"
+#include "pmx_helper.hpp"
#include <gr_block.h>
+#include <boost/foreach.hpp>
gr_block::gr_block(void)
{
@@ -147,3 +149,65 @@ bool gr_block::is_set_max_noutput_items(void) const
{
return this->max_noutput_items() != 0;
}
+
+//TODO Tag2gr_tag and gr_tag2Tag need PMC to/from PMT logic
+//currently PMC holds the pmt_t, this is temporary
+static gr_tag_t Tag2gr_tag(const gnuradio::Tag &tag)
+{
+ gr_tag_t t;
+ t.offset = tag.offset;
+ t.key = pmt::pmc_to_pmt(tag.key);
+ t.value = pmt::pmc_to_pmt(tag.value);
+ t.srcid = pmt::pmc_to_pmt(tag.srcid);
+ return t;
+}
+
+static gnuradio::Tag gr_tag2Tag(const gr_tag_t &tag)
+{
+ return gnuradio::Tag
+ (
+ tag.offset,
+ pmt::pmt_to_pmc(tag.key),
+ pmt::pmt_to_pmc(tag.value),
+ pmt::pmt_to_pmc(tag.srcid)
+ );
+}
+
+void gr_block::add_item_tag(
+ const size_t which_output, const gr_tag_t &tag
+){
+ this->post_output_tag(which_output, gr_tag2Tag(tag));
+}
+
+void gr_block::add_item_tag(
+ const size_t which_output,
+ uint64_t abs_offset,
+ const pmt::pmt_t &key,
+ const pmt::pmt_t &value,
+ const pmt::pmt_t &srcid
+){
+ gr_tag_t t;
+ t.offset = abs_offset;
+ t.key = key;
+ t.value = value;
+ t.srcid = srcid;
+ this->add_item_tag(which_output, t);
+}
+
+void gr_block::get_tags_in_range(
+ std::vector<gr_tag_t> &tags,
+ const size_t which_input,
+ uint64_t abs_start,
+ uint64_t abs_end,
+ const pmt::pmt_t &key
+){
+ tags.clear();
+ BOOST_FOREACH(const gnuradio::Tag &tag, this->get_input_tags(which_input))
+ {
+ if (tag.offset >= abs_start and tag.offset <= abs_end)
+ {
+ gr_tag_t t = Tag2gr_tag(tag);
+ if (key or pmt::pmt_equal(t.key, key)) tags.push_back(t);
+ }
+ }
+}
diff --git a/lib/pmx_helper.hpp b/lib/pmx_helper.hpp
new file mode 100644
index 0000000..b44345c
--- /dev/null
+++ b/lib/pmx_helper.hpp
@@ -0,0 +1,263 @@
+//
+// Copyright 2012 Josh Blum
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef INCLUDED_LIBGRAS_PMX_HELPER_HPP
+#define INCLUDED_LIBGRAS_PMX_HELPER_HPP
+
+#include <PMC/PMC.hpp>
+#include <PMC/Containers.hpp>
+#include <gruel/pmt.h>
+#include <boost/foreach.hpp>
+
+namespace pmt
+{
+
+inline pmt_t pmc_to_pmt(const PMCC &p)
+{
+ //the container is null
+ if (not p) return pmt::pmt_t();
+
+ #define decl_pmc_to_pmt(type, conv) if (p.is<type >()) return conv(p.as<type >())
+
+ //bool
+ decl_pmc_to_pmt(bool, pmt_from_bool);
+
+ //string
+ decl_pmc_to_pmt(std::string, pmt_string_to_symbol);
+
+ //numeric types
+ decl_pmc_to_pmt(int8_t, pmt_from_long);
+ decl_pmc_to_pmt(int16_t, pmt_from_long);
+ decl_pmc_to_pmt(int32_t, pmt_from_long);
+ decl_pmc_to_pmt(uint8_t, pmt_from_long);
+ decl_pmc_to_pmt(uint16_t, pmt_from_long);
+ decl_pmc_to_pmt(uint32_t, pmt_from_long);
+ decl_pmc_to_pmt(int64_t, pmt_from_uint64);
+ decl_pmc_to_pmt(uint64_t, pmt_from_uint64);
+ decl_pmc_to_pmt(float, pmt_from_double);
+ decl_pmc_to_pmt(double, pmt_from_double);
+ #define pmt_from_complex(x) pmt_make_rectangular((x).real(), (x).imag())
+ decl_pmc_to_pmt(std::complex<float>, pmt_from_complex);
+ decl_pmc_to_pmt(std::complex<double>, pmt_from_complex);
+
+ //pair container
+ if (p.is<PMCPair>())
+ {
+ const PMCPair &pr = p.as<PMCPair>();
+ return pmt_cons(pmc_to_pmt(pr.first), pmc_to_pmt(pr.second));
+ }
+
+ //fucking tuples
+/*
+for i in range(11):
+ args = list()
+ for j in range(i):
+ args.append('pmc_to_pmt(p.as<PMCTuple<%d> >()[%d])'%(i, j))
+ print ' if (p.is<PMCTuple<%d> >())'%i
+ print ' return pmt_make_tuple(%s);'%(', '.join(args),)
+*/
+ if (p.is<PMCTuple<0> >())
+ return pmt_make_tuple();
+ if (p.is<PMCTuple<1> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<1> >()[0]));
+ if (p.is<PMCTuple<2> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<2> >()[0]), pmc_to_pmt(p.as<PMCTuple<2> >()[1]));
+ if (p.is<PMCTuple<3> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<3> >()[0]), pmc_to_pmt(p.as<PMCTuple<3> >()[1]), pmc_to_pmt(p.as<PMCTuple<3> >()[2]));
+ if (p.is<PMCTuple<4> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<4> >()[0]), pmc_to_pmt(p.as<PMCTuple<4> >()[1]), pmc_to_pmt(p.as<PMCTuple<4> >()[2]), pmc_to_pmt(p.as<PMCTuple<4> >()[3]));
+ if (p.is<PMCTuple<5> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<5> >()[0]), pmc_to_pmt(p.as<PMCTuple<5> >()[1]), pmc_to_pmt(p.as<PMCTuple<5> >()[2]), pmc_to_pmt(p.as<PMCTuple<5> >()[3]), pmc_to_pmt(p.as<PMCTuple<5> >()[4]));
+ if (p.is<PMCTuple<6> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<6> >()[0]), pmc_to_pmt(p.as<PMCTuple<6> >()[1]), pmc_to_pmt(p.as<PMCTuple<6> >()[2]), pmc_to_pmt(p.as<PMCTuple<6> >()[3]), pmc_to_pmt(p.as<PMCTuple<6> >()[4]), pmc_to_pmt(p.as<PMCTuple<6> >()[5]));
+ if (p.is<PMCTuple<7> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<7> >()[0]), pmc_to_pmt(p.as<PMCTuple<7> >()[1]), pmc_to_pmt(p.as<PMCTuple<7> >()[2]), pmc_to_pmt(p.as<PMCTuple<7> >()[3]), pmc_to_pmt(p.as<PMCTuple<7> >()[4]), pmc_to_pmt(p.as<PMCTuple<7> >()[5]), pmc_to_pmt(p.as<PMCTuple<7> >()[6]));
+ if (p.is<PMCTuple<8> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<8> >()[0]), pmc_to_pmt(p.as<PMCTuple<8> >()[1]), pmc_to_pmt(p.as<PMCTuple<8> >()[2]), pmc_to_pmt(p.as<PMCTuple<8> >()[3]), pmc_to_pmt(p.as<PMCTuple<8> >()[4]), pmc_to_pmt(p.as<PMCTuple<8> >()[5]), pmc_to_pmt(p.as<PMCTuple<8> >()[6]), pmc_to_pmt(p.as<PMCTuple<8> >()[7]));
+ if (p.is<PMCTuple<9> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<9> >()[0]), pmc_to_pmt(p.as<PMCTuple<9> >()[1]), pmc_to_pmt(p.as<PMCTuple<9> >()[2]), pmc_to_pmt(p.as<PMCTuple<9> >()[3]), pmc_to_pmt(p.as<PMCTuple<9> >()[4]), pmc_to_pmt(p.as<PMCTuple<9> >()[5]), pmc_to_pmt(p.as<PMCTuple<9> >()[6]), pmc_to_pmt(p.as<PMCTuple<9> >()[7]), pmc_to_pmt(p.as<PMCTuple<9> >()[8]));
+ if (p.is<PMCTuple<10> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<10> >()[0]), pmc_to_pmt(p.as<PMCTuple<10> >()[1]), pmc_to_pmt(p.as<PMCTuple<10> >()[2]), pmc_to_pmt(p.as<PMCTuple<10> >()[3]), pmc_to_pmt(p.as<PMCTuple<10> >()[4]), pmc_to_pmt(p.as<PMCTuple<10> >()[5]), pmc_to_pmt(p.as<PMCTuple<10> >()[6]), pmc_to_pmt(p.as<PMCTuple<10> >()[7]), pmc_to_pmt(p.as<PMCTuple<10> >()[8]), pmc_to_pmt(p.as<PMCTuple<10> >()[9]));
+
+ //vector container
+ if (p.is<PMCList>())
+ {
+ const PMCList &l = p.as<PMCList>();
+ pmt_t v = pmt_make_vector(l.size(), pmt_t());
+ for (size_t i = 0; i < l.size(); i++)
+ {
+ pmt_vector_set(v, i, pmc_to_pmt(l[i]));
+ }
+ return v;
+ }
+
+ //numeric arrays
+ #define decl_pmc_to_pmt_numeric_array(type, suffix) \
+ if (p.is<std::vector<type> >()) return pmt_init_ ## suffix ## vector(p.as<std::vector<type> >().size(), &p.as<std::vector<type> >()[0])
+ decl_pmc_to_pmt_numeric_array(uint8_t, u8);
+ decl_pmc_to_pmt_numeric_array(uint16_t, u16);
+ decl_pmc_to_pmt_numeric_array(uint32_t, u32);
+ decl_pmc_to_pmt_numeric_array(uint64_t, u64);
+ decl_pmc_to_pmt_numeric_array(int8_t, s8);
+ decl_pmc_to_pmt_numeric_array(int16_t, s16);
+ decl_pmc_to_pmt_numeric_array(int32_t, s32);
+ decl_pmc_to_pmt_numeric_array(int64_t, s64);
+ decl_pmc_to_pmt_numeric_array(float, f32);
+ decl_pmc_to_pmt_numeric_array(double, f64);
+ decl_pmc_to_pmt_numeric_array(std::complex<float>, c32);
+ decl_pmc_to_pmt_numeric_array(std::complex<double>, c64);
+
+ //dictionary container
+ if (p.is<PMCDict>())
+ {
+ const PMCDict &m = p.as<PMCDict>();
+ pmt_t d = pmt_make_dict();
+ BOOST_FOREACH(const PMCPair &pr, m)
+ {
+ d = pmt_dict_add(d, pmc_to_pmt(pr.first), pmc_to_pmt(pr.second));
+ }
+ return d;
+ }
+
+ //set container
+ if (p.is<PMCSet>())
+ {
+ const PMCSet &s = p.as<PMCSet>();
+ pmt_t l = PMT_NIL;
+ BOOST_FOREACH(const PMCC &elem, s)
+ {
+ l = pmt_list_add(l, pmc_to_pmt(elem));
+ }
+ return l;
+ }
+
+ //is it already a pmt?
+ if (p.is<pmt_t>()) return p.as<pmt_t>();
+
+ //backup plan... boost::any
+ return pmt_make_any(p);
+
+}
+
+inline PMCC pmt_to_pmc(const pmt_t &p)
+{
+ //if the container null?
+ if (not p) return PMC();
+
+ #define decl_pmt_to_pmc(check, conv) if (check(p)) return PMC::make(conv(p))
+
+ //bool
+ decl_pmt_to_pmc(pmt_is_bool, pmt_to_bool);
+
+ //string
+ decl_pmt_to_pmc(pmt_is_symbol, pmt_symbol_to_string);
+
+ //numeric types
+ decl_pmt_to_pmc(pmt_is_integer, pmt_to_long);
+ decl_pmt_to_pmc(pmt_is_uint64, pmt_to_uint64);
+ decl_pmt_to_pmc(pmt_is_real, pmt_to_double);
+ decl_pmt_to_pmc(pmt_is_complex, pmt_to_complex);
+
+ //is it a boost any holding a PMCC?
+ if (pmt_is_any(p))
+ {
+ const boost::any a = pmt_any_ref(p);
+ if (a.type() == typeid(PMCC)) return boost::any_cast<PMCC>(a);
+ }
+
+ //pair container
+ if (pmt_is_pair(p))
+ {
+ PMCPair pr(pmt_to_pmc(pmt_car(p)), pmt_to_pmc(pmt_cdr(p)));
+ return PMC::make(pr);
+ }
+
+ //fucking tuples
+ #define decl_pmt_to_pmc_tuple(n) \
+ if (pmt_is_tuple(p) and pmt_length(p) == n) \
+ { \
+ PMCTuple<n> t; \
+ for (size_t i = 0; i < n; i++) t[i] = pmt_to_pmc(pmt_tuple_ref(p, i)); \
+ return PMC::make(t); \
+ }
+ decl_pmt_to_pmc_tuple(0);
+ decl_pmt_to_pmc_tuple(1);
+ decl_pmt_to_pmc_tuple(2);
+ decl_pmt_to_pmc_tuple(3);
+ decl_pmt_to_pmc_tuple(4);
+ decl_pmt_to_pmc_tuple(5);
+ decl_pmt_to_pmc_tuple(6);
+ decl_pmt_to_pmc_tuple(7);
+ decl_pmt_to_pmc_tuple(8);
+ decl_pmt_to_pmc_tuple(9);
+ decl_pmt_to_pmc_tuple(10);
+
+ //vector container
+ if (pmt_is_vector(p))
+ {
+ PMCList l(pmt_length(p));
+ for (size_t i = 0; i < l.size(); i++)
+ {
+ l[i] = pmt_to_pmc(pmt_vector_ref(p, i));
+ }
+ return PMC::make(l);
+ }
+
+ //numeric arrays
+ #define decl_pmt_to_pmc_numeric_array(type, suffix) \
+ if (pmt_is_ ## suffix ## vector(p)) \
+ { \
+ size_t n; const type* i = pmt_ ## suffix ## vector_elements(p, n); \
+ return PMC::make(std::vector<type>(i, i+n)); \
+ }
+ decl_pmt_to_pmc_numeric_array(uint8_t, u8);
+ decl_pmt_to_pmc_numeric_array(uint16_t, u16);
+ decl_pmt_to_pmc_numeric_array(uint32_t, u32);
+ decl_pmt_to_pmc_numeric_array(uint64_t, u64);
+ decl_pmt_to_pmc_numeric_array(int8_t, s8);
+ decl_pmt_to_pmc_numeric_array(int16_t, s16);
+ decl_pmt_to_pmc_numeric_array(int32_t, s32);
+ decl_pmt_to_pmc_numeric_array(int64_t, s64);
+ decl_pmt_to_pmc_numeric_array(float, f32);
+ decl_pmt_to_pmc_numeric_array(double, f64);
+ decl_pmt_to_pmc_numeric_array(std::complex<float>, c32);
+ decl_pmt_to_pmc_numeric_array(std::complex<double>, c64);
+
+ //dictionary container
+ if (pmt_is_dict(p))
+ {
+ PMCDict m;
+ pmt_t items = pmt_dict_items(p);
+ for (size_t i = 0; i < pmt_length(items); i++)
+ {
+ pmt_t item = pmt_nth(i, items);
+ PMCC key = pmt_to_pmc(pmt_car(item));
+ PMCC val = pmt_to_pmc(pmt_cdr(item));
+ m[key] = val;
+ }
+ return PMC::make(m);
+ }
+
+ //set container
+ //FIXME no pmt_is_list...
+
+ //backup plan... store the pmt
+ return PMC::make(p);
+}
+
+}
+
+#endif /*INCLUDED_LIBGRAS_PMX_HELPER_HPP*/
diff --git a/lib/tag_handlers.hpp b/lib/tag_handlers.hpp
index 9e20bc0..4e630fb 100644
--- a/lib/tag_handlers.hpp
+++ b/lib/tag_handlers.hpp
@@ -27,7 +27,7 @@ GRAS_FORCE_INLINE void BlockActor::sort_tags(const size_t i)
{
if (not this->input_tags_changed[i]) return;
std::vector<Tag> &tags_i = this->input_tags[i];
- std::sort(tags_i.begin(), tags_i.end(), Tag::offset_compare);
+ std::sort(tags_i.begin(), tags_i.end());
this->input_tags_changed[i] = false;
}
diff --git a/lib/tags.cpp b/lib/tags.cpp
new file mode 100644
index 0000000..ec563d0
--- /dev/null
+++ b/lib/tags.cpp
@@ -0,0 +1,36 @@
+//
+// Copyright 2012 Josh Blum
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include <gnuradio/tags.hpp>
+
+using namespace gnuradio;
+
+Tag::Tag(void):
+ offset(0)
+{
+ //NOP
+}
+
+Tag::Tag(const uint64_t &offset, const PMCC &key, const PMCC &value, const PMCC &srcid):
+ offset(offset), key(key), value(value), srcid(srcid)
+{
+ //NOP
+}
+
+bool gnuradio::operator<(const Tag &lhs, const Tag &rhs)
+{
+ return lhs.offset < rhs.offset;
+}