From 1043222e0de551f00683a1cc9060f194adc4fc85 Mon Sep 17 00:00:00 2001
From: Andrej Rode <mail@andrejro.de>
Date: Thu, 22 Feb 2018 13:28:01 +0100
Subject: blocks: replace gengen with  C++ templates

---
 docs/doxygen/CMakeLists.txt | 8 --------
 1 file changed, 8 deletions(-)

(limited to 'docs/doxygen')

diff --git a/docs/doxygen/CMakeLists.txt b/docs/doxygen/CMakeLists.txt
index 83a9ee29ed..c6d9cf92d0 100644
--- a/docs/doxygen/CMakeLists.txt
+++ b/docs/doxygen/CMakeLists.txt
@@ -45,14 +45,6 @@ if(ENABLE_GNURADIO_RUNTIME)
   list(APPEND GENERATED_DEPS pmt_generated)
 endif(ENABLE_GNURADIO_RUNTIME)
 
-if(ENABLE_GR_BLOCKS)
-  list(APPEND GENERATED_DEPS blocks_generated_includes)
-endif(ENABLE_GR_BLOCKS)
-
-if(ENABLE_GR_ANALOG)
-  list(APPEND GENERATED_DEPS analog_generated_includes)
-endif(ENABLE_GR_ANALOG)
-
 if(ENABLE_GR_DIGITAL)
   list(APPEND GENERATED_DEPS digital_generated_includes)
 endif(ENABLE_GR_DIGITAL)
-- 
cgit v1.2.3


From c70c0a4cb7f84e7047ffe717b99da6be3c0c72df Mon Sep 17 00:00:00 2001
From: Andrej Rode <mail@andrejro.de>
Date: Tue, 21 Aug 2018 14:34:46 +0200
Subject: digital: replace gengen with C++ templates

---
 docs/doxygen/CMakeLists.txt                        |   4 -
 gr-digital/include/gnuradio/digital/CMakeLists.txt |  14 +-
 gr-digital/include/gnuradio/digital/burst_shaper.h | 123 ++++++
 .../include/gnuradio/digital/burst_shaper_XX.h.t   | 123 ------
 .../include/gnuradio/digital/chunks_to_symbols.h   |  82 ++++
 .../gnuradio/digital/chunks_to_symbols_XX.h.t      |  77 ----
 gr-digital/lib/CMakeLists.txt                      |  12 +-
 gr-digital/lib/burst_shaper_XX_impl.cc.t           | 379 ------------------
 gr-digital/lib/burst_shaper_XX_impl.h.t            |  90 -----
 gr-digital/lib/burst_shaper_impl.cc                | 424 +++++++++++++++++++++
 gr-digital/lib/burst_shaper_impl.h                 |  89 +++++
 gr-digital/lib/chunks_to_symbols_XX_impl.cc.t      | 133 -------
 gr-digital/lib/chunks_to_symbols_XX_impl.h.t       |  63 ---
 gr-digital/lib/chunks_to_symbols_impl.cc           | 145 +++++++
 gr-digital/lib/chunks_to_symbols_impl.h            |  62 +++
 gr-digital/swig/CMakeLists.txt                     |   1 -
 gr-digital/swig/digital_swig1.i                    |  36 +-
 17 files changed, 941 insertions(+), 916 deletions(-)
 create mode 100644 gr-digital/include/gnuradio/digital/burst_shaper.h
 delete mode 100644 gr-digital/include/gnuradio/digital/burst_shaper_XX.h.t
 create mode 100644 gr-digital/include/gnuradio/digital/chunks_to_symbols.h
 delete mode 100644 gr-digital/include/gnuradio/digital/chunks_to_symbols_XX.h.t
 delete mode 100644 gr-digital/lib/burst_shaper_XX_impl.cc.t
 delete mode 100644 gr-digital/lib/burst_shaper_XX_impl.h.t
 create mode 100644 gr-digital/lib/burst_shaper_impl.cc
 create mode 100644 gr-digital/lib/burst_shaper_impl.h
 delete mode 100644 gr-digital/lib/chunks_to_symbols_XX_impl.cc.t
 delete mode 100644 gr-digital/lib/chunks_to_symbols_XX_impl.h.t
 create mode 100644 gr-digital/lib/chunks_to_symbols_impl.cc
 create mode 100644 gr-digital/lib/chunks_to_symbols_impl.h

(limited to 'docs/doxygen')

diff --git a/docs/doxygen/CMakeLists.txt b/docs/doxygen/CMakeLists.txt
index c6d9cf92d0..b0b3c0f460 100644
--- a/docs/doxygen/CMakeLists.txt
+++ b/docs/doxygen/CMakeLists.txt
@@ -45,10 +45,6 @@ if(ENABLE_GNURADIO_RUNTIME)
   list(APPEND GENERATED_DEPS pmt_generated)
 endif(ENABLE_GNURADIO_RUNTIME)
 
-if(ENABLE_GR_DIGITAL)
-  list(APPEND GENERATED_DEPS digital_generated_includes)
-endif(ENABLE_GR_DIGITAL)
-
 if(ENABLE_GR_FILTER)
   list(APPEND GENERATED_DEPS filter_generated_includes)
 endif(ENABLE_GR_FILTER)
diff --git a/gr-digital/include/gnuradio/digital/CMakeLists.txt b/gr-digital/include/gnuradio/digital/CMakeLists.txt
index cdaf48080b..af7a20eda5 100644
--- a/gr-digital/include/gnuradio/digital/CMakeLists.txt
+++ b/gr-digital/include/gnuradio/digital/CMakeLists.txt
@@ -17,25 +17,15 @@
 # the Free Software Foundation, Inc., 51 Franklin Street,
 # Boston, MA 02110-1301, USA.
 
-########################################################################
-# Invoke macro to generate various headers
-#######################################################################
-include(GrMiscUtils)
-GR_EXPAND_X_H(digital chunks_to_symbols_XX     bf bc sf sc if ic)
-GR_EXPAND_X_H(digital burst_shaper_XX     cc ff)
-
-add_custom_target(digital_generated_includes DEPENDS
-    ${generated_includes}
-)
-
 ########################################################################
 # Install header files
 ########################################################################
 install(FILES
-    ${generated_includes}
     additive_scrambler_bb.h
     api.h
     binary_slicer_fb.h
+    burst_shaper.h
+    chunks_to_symbols.h
     clock_recovery_mm_cc.h
     clock_recovery_mm_ff.h
     cma_equalizer_cc.h
diff --git a/gr-digital/include/gnuradio/digital/burst_shaper.h b/gr-digital/include/gnuradio/digital/burst_shaper.h
new file mode 100644
index 0000000000..25277595b3
--- /dev/null
+++ b/gr-digital/include/gnuradio/digital/burst_shaper.h
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef BURST_SHAPER_H
+#define BURST_SHAPER_H
+
+#include <gnuradio/digital/api.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+  namespace digital {
+
+    /*!
+     * \brief Burst shaper block for applying burst padding and ramping.
+     * \ingroup packet_operators_blk
+     *
+     * \details
+     *
+     * This block applies a configurable amount of zero padding before
+     * and/or after a burst indicated by tagged stream length tags.
+     *
+     * If phasing symbols are used, an alternating pattern of +1/-1
+     * symbols of length ceil(N/2) will be inserted before and after
+     * each burst, where N is the length of the taps vector. The ramp-
+     * up/ramp-down shape will be applied to these phasing symbols.
+     *
+     * If phasing symbols are not used, the taper will be applied
+     * directly to the head and tail of each burst.
+     *
+     * Length tags will be updated to include the length of any added
+     * zero padding or phasing symbols and will be placed at the
+     * beginning of the modified tagged stream. Any other tags found at
+     * the same offset as a length tag will also be placed at the
+     * beginning of the modified tagged stream, since these tags are
+     * assumed to be associated with the burst rather than a specific
+     * sample. For example, if "tx_time" tags are used to control
+     * bursts, their offsets should be consistent with their associated
+     * burst's length tags. Tags at other offsets will be placed with
+     * the samples on which they were found.
+     *
+     * \li input: stream of T
+     * \li output: stream of T
+     */
+    template <class T>
+    class DIGITAL_API burst_shaper : virtual public block
+    {
+    public:
+      typedef boost::shared_ptr< burst_shaper<T> > sptr;
+
+      /*!
+       * Make a burst shaper block.
+       *
+       * \param taps: vector of window taper taps; the first ceil(N/2)
+       *              items are the up flank and the last ceil(N/2)
+       *              items are the down flank. If taps.size() is odd,
+       *              the middle tap will be used as the last item of
+       *              the up flank and first item of the down flank.
+       * \param pre_padding: number of zero samples to insert before
+       *                     the burst.
+       * \param post_padding: number of zero samples to append after
+       *                      the burst.
+       * \param insert_phasing: if true, insert alternating +1/-1
+       *                        pattern of length ceil(N/2) before and
+       *                        after the burst and apply ramp up and
+       *                        ramp down taps, respectively, to the
+       *                        inserted patterns instead of the head
+       *                        and tail items of the burst.
+       * \param length_tag_name: the name of the tagged stream length
+       *                         tag key.
+       */
+      static sptr make(const std::vector<T> &taps,
+                       int pre_padding=0, int post_padding=0,
+                       bool insert_phasing=false,
+                       const std::string &length_tag_name="packet_len");
+
+      /*!
+       * Returns the amount of zero padding inserted before each burst.
+       */
+      virtual int pre_padding() const = 0;
+
+      /*!
+       * Returns the amount of zero padding inserted after each burst.
+       */
+      virtual int post_padding() const = 0;
+
+      /*!
+       * Returns the total amount of zero padding and phasing symbols
+       * inserted before each burst.
+       */
+      virtual int prefix_length() const = 0;
+
+      /*!
+       * Returns the total amount of zero padding and phasing symbols
+       * inserted after each burst.
+       */
+      virtual int suffix_length() const = 0;
+    };
+
+    typedef burst_shaper<float> burst_shaper_ff;
+    typedef burst_shaper<gr_complex> burst_shaper_cc;
+  } // namespace digital
+} // namespace gr
+
+#endif /* BURST_SHAPER_H */
diff --git a/gr-digital/include/gnuradio/digital/burst_shaper_XX.h.t b/gr-digital/include/gnuradio/digital/burst_shaper_XX.h.t
deleted file mode 100644
index fd7b69060e..0000000000
--- a/gr-digital/include/gnuradio/digital/burst_shaper_XX.h.t
+++ /dev/null
@@ -1,123 +0,0 @@
-/* -*- c++ -*- */
-/* 
- * Copyright 2015 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio 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 General Public License for more details.
- * 
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/digital/api.h>
-#include <gnuradio/block.h>
-
-namespace gr {
-  namespace digital {
-
-    /*!
-     * \brief Burst shaper block for applying burst padding and ramping.
-     * \ingroup packet_operators_blk
-     *
-     * \details
-     *
-     * This block applies a configurable amount of zero padding before
-     * and/or after a burst indicated by tagged stream length tags.
-     *
-     * If phasing symbols are used, an alternating pattern of +1/-1
-     * symbols of length ceil(N/2) will be inserted before and after
-     * each burst, where N is the length of the taps vector. The ramp-
-     * up/ramp-down shape will be applied to these phasing symbols.
-     *
-     * If phasing symbols are not used, the taper will be applied
-     * directly to the head and tail of each burst.
-     *
-     * Length tags will be updated to include the length of any added
-     * zero padding or phasing symbols and will be placed at the
-     * beginning of the modified tagged stream. Any other tags found at
-     * the same offset as a length tag will also be placed at the
-     * beginning of the modified tagged stream, since these tags are
-     * assumed to be associated with the burst rather than a specific
-     * sample. For example, if "tx_time" tags are used to control
-     * bursts, their offsets should be consistent with their associated
-     * burst's length tags. Tags at other offsets will be placed with
-     * the samples on which they were found.
-     *
-     * \li input: stream of @I_TYPE@
-     * \li output: stream of @O_TYPE@
-     */
-    class DIGITAL_API @NAME@ : virtual public block
-    {
-    public:
-      // gr::digital::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      /*!
-       * Make a burst shaper block.
-       *
-       * \param taps: vector of window taper taps; the first ceil(N/2)
-       *              items are the up flank and the last ceil(N/2)
-       *              items are the down flank. If taps.size() is odd,
-       *              the middle tap will be used as the last item of
-       *              the up flank and first item of the down flank.
-       * \param pre_padding: number of zero samples to insert before
-       *                     the burst.
-       * \param post_padding: number of zero samples to append after
-       *                      the burst.
-       * \param insert_phasing: if true, insert alternating +1/-1
-       *                        pattern of length ceil(N/2) before and
-       *                        after the burst and apply ramp up and
-       *                        ramp down taps, respectively, to the
-       *                        inserted patterns instead of the head
-       *                        and tail items of the burst.
-       * \param length_tag_name: the name of the tagged stream length
-       *                         tag key.
-       */
-      static sptr make(const std::vector<@O_TYPE@> &taps,
-                       int pre_padding=0, int post_padding=0,
-                       bool insert_phasing=false,
-                       const std::string &length_tag_name="packet_len");
-
-      /*!
-       * Returns the amount of zero padding inserted before each burst.
-       */
-      virtual int pre_padding() const = 0;
-
-      /*!
-       * Returns the amount of zero padding inserted after each burst.
-       */
-      virtual int post_padding() const = 0;
-
-      /*!
-       * Returns the total amount of zero padding and phasing symbols
-       * inserted before each burst.
-       */
-      virtual int prefix_length() const = 0;
-
-      /*!
-       * Returns the total amount of zero padding and phasing symbols
-       * inserted after each burst.
-       */
-      virtual int suffix_length() const = 0;
-    };
-
-  } // namespace digital
-} // namespace gr
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-digital/include/gnuradio/digital/chunks_to_symbols.h b/gr-digital/include/gnuradio/digital/chunks_to_symbols.h
new file mode 100644
index 0000000000..f7cdd45352
--- /dev/null
+++ b/gr-digital/include/gnuradio/digital/chunks_to_symbols.h
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef CHUNKS_TO_SYMBOLS_H
+#define CHUNKS_TO_SYMBOLS_H
+
+#include <gnuradio/digital/api.h>
+#include <gnuradio/sync_interpolator.h>
+#include <cstdint>
+
+namespace gr {
+  namespace digital {
+
+    /*!
+     * \brief Map a stream of unpacked symbol indexes to stream of
+     * float or complex constellation points in D dimensions (D = 1 by
+     * default) \ingroup converter_blk
+     *
+     * \details
+     * \li input: stream of IN_T
+     * \li output: stream of OUT_T
+     *
+     * \li out[n D + k] = symbol_table[in[n] D + k], k=0,1,...,D-1
+     *
+     * The combination of gr::blocks::packed_to_unpacked_XX followed
+     * by gr::digital::chunks_to_symbols_XY handles the general case
+     * of mapping from a stream of bytes or shorts into arbitrary
+     * float or complex symbols.
+     *
+     * \sa gr::blocks::packed_to_unpacked_bb, gr::blocks::unpacked_to_packed_bb,
+     * \sa gr::blocks::packed_to_unpacked_ss, gr::blocks::unpacked_to_packed_ss,
+     * \sa gr::digital::chunks_to_symbols_bf, gr::digital::chunks_to_symbols_bc.
+     * \sa gr::digital::chunks_to_symbols_sf, gr::digital::chunks_to_symbols_sc.
+     */
+    template <class IN_T, class OUT_T>
+    class DIGITAL_API chunks_to_symbols : virtual public sync_interpolator
+    {
+    public:
+      typedef boost::shared_ptr< chunks_to_symbols<IN_T,OUT_T> > sptr;
+
+      /*!
+       * Make a chunks-to-symbols block.
+       *
+       * \param symbol_table: list that maps chunks to symbols.
+       * \param D: dimension of table.
+       */
+      static sptr make(const std::vector<OUT_T> &symbol_table, const int D = 1);
+
+      virtual int D() const = 0;
+      virtual std::vector<OUT_T> symbol_table() const = 0;
+      virtual void set_symbol_table(const std::vector<OUT_T> &symbol_table) =0;
+    };
+
+    typedef chunks_to_symbols<std::uint8_t, float> chunks_to_symbols_bf;
+    typedef chunks_to_symbols<std::uint8_t, gr_complex> chunks_to_symbols_bc;
+    typedef chunks_to_symbols<std::int16_t, float> chunks_to_symbols_sf;
+    typedef chunks_to_symbols<std::int16_t, gr_complex> chunks_to_symbols_sc;
+    typedef chunks_to_symbols<std::int32_t, float> chunks_to_symbols_if;
+    typedef chunks_to_symbols<std::int32_t, gr_complex> chunks_to_symbols_ic;
+  } /* namespace digital */
+} /* namespace gr */
+
+#endif /* CHUNKS_TO_SYMBOLS_H */
diff --git a/gr-digital/include/gnuradio/digital/chunks_to_symbols_XX.h.t b/gr-digital/include/gnuradio/digital/chunks_to_symbols_XX.h.t
deleted file mode 100644
index 6683ea94fc..0000000000
--- a/gr-digital/include/gnuradio/digital/chunks_to_symbols_XX.h.t
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/digital/api.h>
-#include <gnuradio/sync_interpolator.h>
-
-namespace gr {
-  namespace digital {
-    
-    /*!
-     * \brief Map a stream of unpacked symbol indexes to stream of
-     * float or complex constellation points in D dimensions (D = 1 by
-     * default) \ingroup converter_blk
-     *
-     * \details
-     * \li input: stream of @I_TYPE@
-     * \li output: stream of @O_TYPE@
-     *
-     * \li out[n D + k] = symbol_table[in[n] D + k], k=0,1,...,D-1
-     *
-     * The combination of gr::blocks::packed_to_unpacked_XX followed
-     * by gr::digital::chunks_to_symbols_XY handles the general case
-     * of mapping from a stream of bytes or shorts into arbitrary
-     * float or complex symbols.
-     *
-     * \sa gr::blocks::packed_to_unpacked_bb, gr::blocks::unpacked_to_packed_bb,
-     * \sa gr::blocks::packed_to_unpacked_ss, gr::blocks::unpacked_to_packed_ss,
-     * \sa gr::digital::chunks_to_symbols_bf, gr::digital::chunks_to_symbols_bc.
-     * \sa gr::digital::chunks_to_symbols_sf, gr::digital::chunks_to_symbols_sc.
-     */
-    class DIGITAL_API @NAME@ : virtual public sync_interpolator
-    {
-    public:
-      // gr::digital::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      /*!
-       * Make a chunks-to-symbols block.
-       *
-       * \param symbol_table: list that maps chunks to symbols.
-       * \param D: dimension of table.
-       */
-      static sptr make(const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
-
-      virtual int D() const = 0;
-      virtual std::vector<@O_TYPE@> symbol_table() const = 0;
-      virtual void set_symbol_table(const std::vector<@O_TYPE@> &symbol_table) =0;
-    };
-
-  } /* namespace digital */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-digital/lib/CMakeLists.txt b/gr-digital/lib/CMakeLists.txt
index f19d037171..cfcee3012c 100644
--- a/gr-digital/lib/CMakeLists.txt
+++ b/gr-digital/lib/CMakeLists.txt
@@ -38,20 +38,14 @@ if(ENABLE_GR_CTRLPORT)
   ADD_DEFINITIONS(-DGR_CTRLPORT)
 endif(ENABLE_GR_CTRLPORT)
 
-########################################################################
-# Invoke macro to generate various sources
-########################################################################
-include(GrMiscUtils)
-GR_EXPAND_X_CC_H(digital chunks_to_symbols_XX_impl     bf bc sf sc if ic)
-GR_EXPAND_X_CC_H(digital burst_shaper_XX_impl     cc ff)
-
 ########################################################################
 # Setup library
 ########################################################################
 list(APPEND digital_sources
-    ${generated_sources}
     additive_scrambler_bb_impl.cc
     binary_slicer_fb_impl.cc
+    burst_shaper_impl.cc
+    chunks_to_symbols_impl.cc
     clock_recovery_mm_cc_impl.cc
     clock_recovery_mm_ff_impl.cc
     clock_tracking_loop.cc
@@ -156,7 +150,6 @@ GR_LIBRARY_FOO(gnuradio-digital)
 
 add_dependencies(
     gnuradio-digital
-    digital_generated_includes
     digital_generated_swigs
     gnuradio-runtime
     gnuradio-filter
@@ -179,7 +172,6 @@ if(ENABLE_STATIC_LIBS)
   add_library(gnuradio-digital_static STATIC ${digital_sources})
 
   add_dependencies(gnuradio-digital_static
-    digital_generated_includes
     gnuradio-runtime_static
     gnuradio-filter_static
     gnuradio-analog_static
diff --git a/gr-digital/lib/burst_shaper_XX_impl.cc.t b/gr-digital/lib/burst_shaper_XX_impl.cc.t
deleted file mode 100644
index 0a60696b8e..0000000000
--- a/gr-digital/lib/burst_shaper_XX_impl.cc.t
+++ /dev/null
@@ -1,379 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2015 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <boost/format.hpp>
-#include <gnuradio/io_signature.h>
-#include <volk/volk.h>
-#include "@IMPL_NAME@.h"
-
-#ifndef VOLK_MULT_gr_complex
-#define VOLK_MULT_gr_complex volk_32fc_x2_multiply_32fc
-#endif
-#ifndef VOLK_MULT_float
-#define VOLK_MULT_float volk_32f_x2_multiply_32f
-#endif
-
-namespace gr {
-  namespace digital {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(const std::vector<@I_TYPE@> &taps,
-                      int pre_padding, int post_padding,
-                      bool insert_phasing,
-                      const std::string &length_tag_name)
-    {
-      return gnuradio::get_initial_sptr
-        (new @IMPL_NAME@(taps, pre_padding, post_padding,
-                         insert_phasing, length_tag_name));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(const std::vector<@I_TYPE@> &taps,
-                             int pre_padding, int post_padding,
-                             bool insert_phasing,
-                             const std::string &length_tag_name)
-      : gr::block("@BASE_NAME@",
-              gr::io_signature::make(1, 1, sizeof(@I_TYPE@)),
-              gr::io_signature::make(1, 1, sizeof(@O_TYPE@))),
-        d_up_ramp(taps.begin(), taps.begin() + taps.size()/2 + taps.size()%2),
-        d_down_ramp(taps.begin() + taps.size()/2, taps.end()),
-        d_nprepad(pre_padding),
-        d_npostpad(post_padding),
-        d_insert_phasing(insert_phasing),
-        d_length_tag_key(pmt::string_to_symbol(length_tag_name)),
-        d_ncopy(0),
-        d_limit(0),
-        d_index(0),
-        d_length_tag_offset(0),
-        d_finished(false),
-        d_state(STATE_WAIT)
-    {
-        assert(d_up_ramp.size() == d_down_ramp.size());
-
-        d_up_phasing.resize(d_up_ramp.size());
-        d_down_phasing.resize(d_down_ramp.size());
-
-        @I_TYPE@ symbol;
-        for(unsigned int i = 0; i < d_up_ramp.size(); i++) {
-            symbol = (i%2 == 0) ? @I_TYPE@(1.0f) : @I_TYPE@(-1.0f);
-            d_up_phasing[i] = symbol * d_up_ramp[i];
-            d_down_phasing[i] = symbol * d_down_ramp[i];
-        }
-
-        //set_relative_rate(1.0);
-        set_tag_propagation_policy(TPP_DONT);
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-    }
-
-    void
-    @IMPL_NAME@::forecast(int noutput_items,
-                          gr_vector_int &ninput_items_required)
-    {
-      switch(d_state) {
-      case(STATE_RAMPDOWN):
-        // If inserting phasing; we don't need any input
-        if(d_insert_phasing) {
-          ninput_items_required[0] = 0;
-        }
-        else {
-          ninput_items_required[0] = noutput_items;
-        }
-        break;
-      case(STATE_POSTPAD):
-        // Padding 0's requires no input
-        ninput_items_required[0] = 0;
-        break;
-      default:
-        ninput_items_required[0] = noutput_items;
-      }
-    }
-
-    int
-    @IMPL_NAME@::general_work(int noutput_items,
-                      gr_vector_int &ninput_items,
-                      gr_vector_const_void_star &input_items,
-                      gr_vector_void_star &output_items)
-    {
-        const @I_TYPE@ *in = reinterpret_cast<const @I_TYPE@ *>(input_items[0]);
-        @O_TYPE@ *out = reinterpret_cast<@O_TYPE@ *>(output_items[0]);
-
-        int nwritten = 0;
-        int nread = 0;
-        int nspace = 0;
-        int nskip = 0;
-        int curr_tag_index = 0;
-
-        std::vector<tag_t> length_tags;
-        get_tags_in_window(length_tags, 0, 0, ninput_items[0], d_length_tag_key);
-        std::sort(length_tags.rbegin(), length_tags.rend(), tag_t::offset_compare);
-
-        while(nwritten < noutput_items) {
-            // Only check the nread condition if we are actually reading
-            // from the input stream.
-            if(((d_state != STATE_RAMPDOWN) && (d_state != STATE_POSTPAD)) ||
-               ((d_state == STATE_RAMPDOWN) && !d_insert_phasing))
-              {
-                if(nread >= ninput_items[0]) {
-                    break;
-                }
-            }
-
-            if(d_finished) {
-                d_finished = false;
-                break;
-            }
-            nspace = noutput_items - nwritten;
-            switch(d_state) {
-                case(STATE_WAIT):
-                    if(!length_tags.empty()) {
-                        d_length_tag_offset = length_tags.back().offset;
-                        curr_tag_index = (int)(d_length_tag_offset - nitems_read(0));
-                        d_ncopy = pmt::to_long(length_tags.back().value);
-                        length_tags.pop_back();
-                        nskip = curr_tag_index - nread;
-                        add_length_tag(nwritten);
-                        propagate_tags(curr_tag_index, nwritten, 1, false);
-                        enter_prepad();
-                    }
-                    else {
-                        nskip = ninput_items[0] - nread;
-                    }
-                    if(nskip > 0) {
-                        GR_LOG_WARN(d_logger,
-                                    boost::format("Dropping %1% samples") %
-                                    nskip);
-                        nread += nskip;
-                        in += nskip;
-                    }
-                    break;
-
-                case(STATE_PREPAD):
-                    write_padding(out, nwritten, nspace);
-                    if(d_index == d_limit)
-                        enter_rampup();
-                    break;
-
-                case(STATE_RAMPUP):
-                    apply_ramp(out, in, nwritten, nread, nspace);
-                    if(d_index == d_limit)
-                        enter_copy();
-                    break;
-
-                case(STATE_COPY):
-                    copy_items(out, in, nwritten, nread, nspace);
-                    if(d_index == d_limit)
-                        enter_rampdown();
-                    break;
-
-                case(STATE_RAMPDOWN):
-                    apply_ramp(out, in, nwritten, nread, nspace);
-                    if(d_index == d_limit)
-                        enter_postpad();
-                    break;
-
-                case(STATE_POSTPAD):
-                    write_padding(out, nwritten, nspace);
-                    if(d_index == d_limit)
-                        enter_wait();
-                    break;
-
-                default:
-                    throw std::runtime_error("@BASE_NAME@: invalid state");
-            }
-        }
-
-        consume_each(nread);
-
-        return nwritten;
-    }
-
-    int
-    @IMPL_NAME@::prefix_length() const
-    {
-        return (d_insert_phasing) ?
-               d_nprepad + d_up_ramp.size() : d_nprepad;
-    }
-
-    int
-    @IMPL_NAME@::suffix_length() const
-    {
-        return (d_insert_phasing) ?
-               d_npostpad + d_down_ramp.size() : d_npostpad;
-    }
-
-    void
-    @IMPL_NAME@::write_padding(@O_TYPE@ *&dst, int &nwritten, int nspace)
-    {
-        int nprocess = std::min(d_limit - d_index, nspace);
-        std::memset(dst, 0x00, nprocess * sizeof(@O_TYPE@));
-        dst += nprocess;
-        nwritten += nprocess;
-        d_index += nprocess;
-    }
-
-    void
-    @IMPL_NAME@::copy_items(@O_TYPE@ *&dst, const @I_TYPE@ *&src, int &nwritten,
-                            int &nread, int nspace)
-    {
-        int nprocess = std::min(d_limit - d_index, nspace);
-        propagate_tags(nread, nwritten, nprocess);
-        std::memcpy(dst, src, nprocess * sizeof(@O_TYPE@));
-        dst += nprocess;
-        nwritten += nprocess;
-        src += nprocess;
-        nread += nprocess;
-        d_index += nprocess;
-    }
-
-    void
-    @IMPL_NAME@::apply_ramp(@O_TYPE@ *&dst, const @I_TYPE@ *&src, int &nwritten,
-                            int &nread, int nspace)
-    {
-        int nprocess = std::min(d_limit - d_index, nspace);
-        @O_TYPE@ *phasing;
-        const @O_TYPE@ *ramp;
-
-        if(d_state == STATE_RAMPUP) {
-            phasing = &d_up_phasing[d_index];
-            ramp = &d_up_ramp[d_index];
-        }
-        else {
-            phasing = &d_down_phasing[d_index];
-            ramp = &d_down_ramp[d_index];
-        }
-
-        if(d_insert_phasing)
-            std::memcpy(dst, phasing, nprocess * sizeof(@O_TYPE@));
-        else {
-            propagate_tags(nread, nwritten, nprocess);
-            VOLK_MULT_@O_TYPE@(dst, src, ramp, nprocess);
-            src += nprocess;
-            nread += nprocess;
-        }
-
-        dst += nprocess;
-        nwritten += nprocess;
-        d_index += nprocess;
-    }
-
-    void
-    @IMPL_NAME@::add_length_tag(int offset)
-    {
-        add_item_tag(0, nitems_written(0) + offset, d_length_tag_key,
-                     pmt::from_long(d_ncopy + prefix_length() +
-                                    suffix_length()),
-                     pmt::string_to_symbol(name()));
-    }
-
-    void
-    @IMPL_NAME@::propagate_tags(int in_offset, int out_offset, int count, bool skip)
-    {
-        uint64_t abs_start = nitems_read(0) + in_offset;
-        uint64_t abs_end = abs_start + count;
-        uint64_t abs_offset = nitems_written(0) + out_offset;
-        tag_t temp_tag;
-
-        std::vector<tag_t> tags;
-        std::vector<tag_t>::iterator it;
-
-        get_tags_in_range(tags, 0, abs_start, abs_end);
-
-        for(it = tags.begin(); it != tags.end(); it++) {
-            if(!pmt::equal(it->key, d_length_tag_key)) {
-                if(skip && (it->offset == d_length_tag_offset))
-                    continue;
-                temp_tag = *it;
-                temp_tag.offset = abs_offset + it->offset - abs_start;
-                add_item_tag(0, temp_tag);
-            }
-        }
-    }
-
-    void
-    @IMPL_NAME@::enter_wait()
-    {
-        d_finished = true;
-        d_index = 0;
-        d_state = STATE_WAIT;
-    }
-
-    void
-    @IMPL_NAME@::enter_prepad()
-    {
-        d_limit = d_nprepad;
-        d_index = 0;
-        d_state = STATE_PREPAD;
-    }
-
-    void
-    @IMPL_NAME@::enter_rampup()
-    {
-        if(d_insert_phasing)
-            d_limit = d_up_ramp.size();
-        else
-            d_limit = std::min((size_t)(d_ncopy/2), d_up_ramp.size());
-        d_index = 0;
-        d_state = STATE_RAMPUP;
-    }
-
-    void
-    @IMPL_NAME@::enter_copy()
-    {
-        if(d_insert_phasing)
-            d_limit = d_ncopy;
-        else
-            d_limit = d_ncopy - std::min((size_t)((d_ncopy/2)*2),
-                                         d_up_ramp.size() +
-                                         d_down_ramp.size());
-        d_index = 0;
-        d_state = STATE_COPY;
-    }
-
-    void
-    @IMPL_NAME@::enter_rampdown()
-    {
-        if(d_insert_phasing)
-            d_limit = d_down_ramp.size();
-        else
-            d_limit = std::min((size_t)(d_ncopy/2), d_down_ramp.size());
-        d_index = 0;
-        d_state = STATE_RAMPDOWN;
-    }
-
-    void
-    @IMPL_NAME@::enter_postpad()
-    {
-        d_limit = d_npostpad;
-        d_index = 0;
-        d_state = STATE_POSTPAD;
-    }
-
-  } /* namespace digital */
-} /* namespace gr */
diff --git a/gr-digital/lib/burst_shaper_XX_impl.h.t b/gr-digital/lib/burst_shaper_XX_impl.h.t
deleted file mode 100644
index 99ad7fb08a..0000000000
--- a/gr-digital/lib/burst_shaper_XX_impl.h.t
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- c++ -*- */
-/* 
- * Copyright 2015 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio 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 General Public License for more details.
- * 
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/digital/@BASE_NAME@.h>
-
-namespace gr {
-  namespace digital {
-
-    class @IMPL_NAME@ : public @BASE_NAME@
-    {
-    protected:
-      enum state_t {STATE_WAIT, STATE_PREPAD, STATE_RAMPUP,
-                    STATE_COPY, STATE_RAMPDOWN, STATE_POSTPAD};
-
-    private:
-      const std::vector<@O_TYPE@> d_up_ramp;
-      const std::vector<@O_TYPE@> d_down_ramp;
-      const int d_nprepad;
-      const int d_npostpad;
-      const bool d_insert_phasing;
-      const pmt::pmt_t d_length_tag_key;
-      std::vector<@O_TYPE@> d_up_phasing;
-      std::vector<@O_TYPE@> d_down_phasing;
-      int d_ncopy;
-      int d_limit;
-      int d_index;
-      uint64_t d_length_tag_offset;
-      bool d_finished;
-      state_t d_state;
-
-      void write_padding(@O_TYPE@ *&dst, int &nwritten, int nspace);
-      void copy_items(@O_TYPE@ *&dst, const @I_TYPE@ *&src, int &nwritten,
-                      int &nread, int nspace);
-      void apply_ramp(@O_TYPE@ *&dst, const @I_TYPE@ *&src, int &nwritten,
-                      int &nread, int nspace);
-      void add_length_tag(int offset);
-      void propagate_tags(int in_offset, int out_offset, int count, bool skip=true);
-      void enter_wait();
-      void enter_prepad();
-      void enter_rampup();
-      void enter_copy();
-      void enter_rampdown();
-      void enter_postpad();
-
-    public:
-      @IMPL_NAME@(const std::vector<@O_TYPE@> &taps, int pre_padding,
-                  int post_padding, bool insert_phasing,
-                  const std::string &length_tag_name);
-      ~@IMPL_NAME@();
-
-      void forecast(int noutput_items, gr_vector_int &ninput_items_required);
-
-      int general_work(int noutput_items,
-		       gr_vector_int &ninput_items,
-		       gr_vector_const_void_star &input_items,
-		       gr_vector_void_star &output_items);
-      int pre_padding() const { return d_nprepad; }
-      int post_padding() const { return d_npostpad; }
-      int prefix_length() const;
-      int suffix_length() const;
-    };
-
-  } // namespace digital
-} // namespace gr
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-digital/lib/burst_shaper_impl.cc b/gr-digital/lib/burst_shaper_impl.cc
new file mode 100644
index 0000000000..d732ec76aa
--- /dev/null
+++ b/gr-digital/lib/burst_shaper_impl.cc
@@ -0,0 +1,424 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "burst_shaper_impl.h"
+#include <boost/format.hpp>
+#include <gnuradio/io_signature.h>
+#include <volk/volk.h>
+
+namespace gr {
+  namespace digital {
+
+    template <class T>
+    typename burst_shaper<T>::sptr
+    burst_shaper<T>::make(const std::vector<T> &taps,
+                      int pre_padding, int post_padding,
+                      bool insert_phasing,
+                      const std::string &length_tag_name)
+    {
+      return gnuradio::get_initial_sptr
+        (new burst_shaper_impl<T>(taps, pre_padding, post_padding,
+                         insert_phasing, length_tag_name));
+    }
+
+    template <class T>
+    burst_shaper_impl<T>::burst_shaper_impl(const std::vector<T> &taps,
+                             int pre_padding, int post_padding,
+                             bool insert_phasing,
+                             const std::string &length_tag_name)
+      : gr::block("burst_shaper",
+              gr::io_signature::make(1, 1, sizeof(T)),
+              gr::io_signature::make(1, 1, sizeof(T))),
+        d_up_ramp(taps.begin(), taps.begin() + taps.size()/2 + taps.size()%2),
+        d_down_ramp(taps.begin() + taps.size()/2, taps.end()),
+        d_nprepad(pre_padding),
+        d_npostpad(post_padding),
+        d_insert_phasing(insert_phasing),
+        d_length_tag_key(pmt::string_to_symbol(length_tag_name)),
+        d_ncopy(0),
+        d_limit(0),
+        d_index(0),
+        d_length_tag_offset(0),
+        d_finished(false),
+        d_state(STATE_WAIT)
+    {
+        assert(d_up_ramp.size() == d_down_ramp.size());
+
+        d_up_phasing.resize(d_up_ramp.size());
+        d_down_phasing.resize(d_down_ramp.size());
+
+        T symbol;
+        for(unsigned int i = 0; i < d_up_ramp.size(); i++) {
+            symbol = (i%2 == 0) ? T(1.0f) : T(-1.0f);
+            d_up_phasing[i] = symbol * d_up_ramp[i];
+            d_down_phasing[i] = symbol * d_down_ramp[i];
+        }
+
+        //set_relative_rate(1.0);
+        this->set_tag_propagation_policy(gr::block::TPP_DONT);
+    }
+
+    template <class T>
+    burst_shaper_impl<T>::~burst_shaper_impl()
+    {
+    }
+
+    template <class T>
+    void
+    burst_shaper_impl<T>::forecast(int noutput_items,
+                          gr_vector_int &ninput_items_required)
+    {
+      switch(d_state) {
+      case(STATE_RAMPDOWN):
+        // If inserting phasing; we don't need any input
+        if(d_insert_phasing) {
+          ninput_items_required[0] = 0;
+        }
+        else {
+          ninput_items_required[0] = noutput_items;
+        }
+        break;
+      case(STATE_POSTPAD):
+        // Padding 0's requires no input
+        ninput_items_required[0] = 0;
+        break;
+      default:
+        ninput_items_required[0] = noutput_items;
+      }
+    }
+
+    template <class T>
+    int
+    burst_shaper_impl<T>::general_work(int noutput_items,
+                      gr_vector_int &ninput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+    {
+        const T *in = reinterpret_cast<const T *>(input_items[0]);
+        T *out = reinterpret_cast<T *>(output_items[0]);
+
+        int nwritten = 0;
+        int nread = 0;
+        int nspace = 0;
+        int nskip = 0;
+        int curr_tag_index = 0;
+
+        std::vector<tag_t> length_tags;
+        this->get_tags_in_window(length_tags, 0, 0, ninput_items[0], d_length_tag_key);
+        std::sort(length_tags.rbegin(), length_tags.rend(), tag_t::offset_compare);
+
+        while(nwritten < noutput_items) {
+            // Only check the nread condition if we are actually reading
+            // from the input stream.
+            if(((d_state != STATE_RAMPDOWN) && (d_state != STATE_POSTPAD)) ||
+               ((d_state == STATE_RAMPDOWN) && !d_insert_phasing))
+              {
+                if(nread >= ninput_items[0]) {
+                    break;
+                }
+            }
+
+            if(d_finished) {
+                d_finished = false;
+                break;
+            }
+            nspace = noutput_items - nwritten;
+            switch(d_state) {
+                case(STATE_WAIT):
+                    if(!length_tags.empty()) {
+                        d_length_tag_offset = length_tags.back().offset;
+                        curr_tag_index = (int)(d_length_tag_offset - this->nitems_read(0));
+                        d_ncopy = pmt::to_long(length_tags.back().value);
+                        length_tags.pop_back();
+                        nskip = curr_tag_index - nread;
+                        add_length_tag(nwritten);
+                        propagate_tags(curr_tag_index, nwritten, 1, false);
+                        enter_prepad();
+                    }
+                    else {
+                        nskip = ninput_items[0] - nread;
+                    }
+                    if(nskip > 0) {
+                        GR_LOG_WARN(this->d_logger,
+                                    boost::format("Dropping %1% samples") %
+                                    nskip);
+                        nread += nskip;
+                        in += nskip;
+                    }
+                    break;
+
+                case(STATE_PREPAD):
+                    write_padding(out, nwritten, nspace);
+                    if(d_index == d_limit)
+                        enter_rampup();
+                    break;
+
+                case(STATE_RAMPUP):
+                    apply_ramp(out, in, nwritten, nread, nspace);
+                    if(d_index == d_limit)
+                        enter_copy();
+                    break;
+
+                case(STATE_COPY):
+                    copy_items(out, in, nwritten, nread, nspace);
+                    if(d_index == d_limit)
+                        enter_rampdown();
+                    break;
+
+                case(STATE_RAMPDOWN):
+                    apply_ramp(out, in, nwritten, nread, nspace);
+                    if(d_index == d_limit)
+                        enter_postpad();
+                    break;
+
+                case(STATE_POSTPAD):
+                    write_padding(out, nwritten, nspace);
+                    if(d_index == d_limit)
+                        enter_wait();
+                    break;
+
+                default:
+                    throw std::runtime_error("burst_shaper: invalid state");
+            }
+        }
+
+        this->consume_each(nread);
+
+        return nwritten;
+    }
+
+    template <class T>
+    int
+    burst_shaper_impl<T>::prefix_length() const
+    {
+        return (d_insert_phasing) ?
+               d_nprepad + d_up_ramp.size() : d_nprepad;
+    }
+
+      template <class T>
+    int
+    burst_shaper_impl<T>::suffix_length() const
+    {
+        return (d_insert_phasing) ?
+               d_npostpad + d_down_ramp.size() : d_npostpad;
+    }
+
+      template <class T>
+    void
+    burst_shaper_impl<T>::write_padding(T *&dst, int &nwritten, int nspace)
+    {
+        int nprocess = std::min(d_limit - d_index, nspace);
+        std::memset(dst, 0x00, nprocess * sizeof(T));
+        dst += nprocess;
+        nwritten += nprocess;
+        d_index += nprocess;
+    }
+
+      template <class T>
+    void
+    burst_shaper_impl<T>::copy_items(T *&dst, const T *&src, int &nwritten,
+                            int &nread, int nspace)
+    {
+        int nprocess = std::min(d_limit - d_index, nspace);
+        propagate_tags(nread, nwritten, nprocess);
+        std::memcpy(dst, src, nprocess * sizeof(T));
+        dst += nprocess;
+        nwritten += nprocess;
+        src += nprocess;
+        nread += nprocess;
+        d_index += nprocess;
+    }
+
+      template <>
+    void
+    burst_shaper_impl<gr_complex>::apply_ramp(gr_complex *&dst, const gr_complex *&src, int &nwritten,
+                            int &nread, int nspace)
+    {
+        int nprocess = std::min(d_limit - d_index, nspace);
+        gr_complex *phasing;
+        const gr_complex *ramp;
+
+        if(d_state == STATE_RAMPUP) {
+            phasing = &d_up_phasing[d_index];
+            ramp = &d_up_ramp[d_index];
+        }
+        else {
+            phasing = &d_down_phasing[d_index];
+            ramp = &d_down_ramp[d_index];
+        }
+
+        if(d_insert_phasing)
+            std::memcpy(dst, phasing, nprocess * sizeof(gr_complex));
+        else {
+            propagate_tags(nread, nwritten, nprocess);
+            volk_32fc_x2_multiply_32fc(dst, src, ramp, nprocess);
+            src += nprocess;
+            nread += nprocess;
+        }
+
+        dst += nprocess;
+        nwritten += nprocess;
+        d_index += nprocess;
+    }
+
+      template <>
+      void
+      burst_shaper_impl<float>::apply_ramp(float *&dst, const float *&src, int &nwritten,
+                                                int &nread, int nspace)
+      {
+          int nprocess = std::min(d_limit - d_index, nspace);
+          float *phasing;
+          const float *ramp;
+
+          if(d_state == STATE_RAMPUP) {
+              phasing = &d_up_phasing[d_index];
+              ramp = &d_up_ramp[d_index];
+          }
+          else {
+              phasing = &d_down_phasing[d_index];
+              ramp = &d_down_ramp[d_index];
+          }
+
+          if(d_insert_phasing)
+              std::memcpy(dst, phasing, nprocess * sizeof(float));
+          else {
+              propagate_tags(nread, nwritten, nprocess);
+              volk_32f_x2_multiply_32f(dst, src, ramp, nprocess);
+              src += nprocess;
+              nread += nprocess;
+          }
+
+          dst += nprocess;
+          nwritten += nprocess;
+          d_index += nprocess;
+      }
+
+
+
+      template <class T>
+    void
+    burst_shaper_impl<T>::add_length_tag(int offset)
+    {
+        this->add_item_tag(0, this->nitems_written(0) + offset, d_length_tag_key,
+                     pmt::from_long(d_ncopy + prefix_length() +
+                                    suffix_length()),
+                     pmt::string_to_symbol(this->name()));
+    }
+
+      template <class T>
+    void
+    burst_shaper_impl<T>::propagate_tags(int in_offset, int out_offset, int count, bool skip)
+    {
+        uint64_t abs_start = this->nitems_read(0) + in_offset;
+        uint64_t abs_end = abs_start + count;
+        uint64_t abs_offset = this->nitems_written(0) + out_offset;
+        tag_t temp_tag;
+
+        std::vector<tag_t> tags;
+        std::vector<tag_t>::iterator it;
+
+        this->get_tags_in_range(tags, 0, abs_start, abs_end);
+
+        for(it = tags.begin(); it != tags.end(); it++) {
+            if(!pmt::equal(it->key, d_length_tag_key)) {
+                if(skip && (it->offset == d_length_tag_offset))
+                    continue;
+                temp_tag = *it;
+                temp_tag.offset = abs_offset + it->offset - abs_start;
+                this->add_item_tag(0, temp_tag);
+            }
+        }
+    }
+
+      template <class T>
+    void
+    burst_shaper_impl<T>::enter_wait()
+    {
+        d_finished = true;
+        d_index = 0;
+        d_state = STATE_WAIT;
+    }
+
+      template <class T>
+    void
+    burst_shaper_impl<T>::enter_prepad()
+    {
+        d_limit = d_nprepad;
+        d_index = 0;
+        d_state = STATE_PREPAD;
+    }
+
+      template <class T>
+    void
+    burst_shaper_impl<T>::enter_rampup()
+    {
+        if(d_insert_phasing)
+            d_limit = d_up_ramp.size();
+        else
+            d_limit = std::min((size_t)(d_ncopy/2), d_up_ramp.size());
+        d_index = 0;
+        d_state = STATE_RAMPUP;
+    }
+
+      template <class T>
+    void
+    burst_shaper_impl<T>::enter_copy()
+    {
+        if(d_insert_phasing)
+            d_limit = d_ncopy;
+        else
+            d_limit = d_ncopy - std::min((size_t)((d_ncopy/2)*2),
+                                         d_up_ramp.size() +
+                                         d_down_ramp.size());
+        d_index = 0;
+        d_state = STATE_COPY;
+    }
+
+      template <class T>
+    void
+    burst_shaper_impl<T>::enter_rampdown()
+    {
+        if(d_insert_phasing)
+            d_limit = d_down_ramp.size();
+        else
+            d_limit = std::min((size_t)(d_ncopy/2), d_down_ramp.size());
+        d_index = 0;
+        d_state = STATE_RAMPDOWN;
+    }
+
+      template <class T>
+    void
+    burst_shaper_impl<T>::enter_postpad()
+    {
+        d_limit = d_npostpad;
+        d_index = 0;
+        d_state = STATE_POSTPAD;
+    }
+
+      template class burst_shaper<gr_complex>;
+      template class burst_shaper<float>;
+  } /* namespace digital */
+} /* namespace gr */
diff --git a/gr-digital/lib/burst_shaper_impl.h b/gr-digital/lib/burst_shaper_impl.h
new file mode 100644
index 0000000000..dbcbb5068a
--- /dev/null
+++ b/gr-digital/lib/burst_shaper_impl.h
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef BURST_SHAPER_IMPL_H
+#define BURST_SHAPER_IMPL_H
+
+#include <gnuradio/digital/burst_shaper.h>
+
+namespace gr {
+  namespace digital {
+
+    template <class T>
+    class burst_shaper_impl : public burst_shaper<T>
+    {
+    protected:
+      enum state_t {STATE_WAIT, STATE_PREPAD, STATE_RAMPUP,
+                    STATE_COPY, STATE_RAMPDOWN, STATE_POSTPAD};
+
+    private:
+      const std::vector<T> d_up_ramp;
+      const std::vector<T> d_down_ramp;
+      const int d_nprepad;
+      const int d_npostpad;
+      const bool d_insert_phasing;
+      const pmt::pmt_t d_length_tag_key;
+      std::vector<T> d_up_phasing;
+      std::vector<T> d_down_phasing;
+      int d_ncopy;
+      int d_limit;
+      int d_index;
+      uint64_t d_length_tag_offset;
+      bool d_finished;
+      state_t d_state;
+
+      void write_padding(T *&dst, int &nwritten, int nspace);
+      void copy_items(T *&dst, const T *&src, int &nwritten,
+                      int &nread, int nspace);
+      void apply_ramp(T *&dst, const T *&src, int &nwritten,
+                      int &nread, int nspace);
+      void add_length_tag(int offset);
+      void propagate_tags(int in_offset, int out_offset, int count, bool skip=true);
+      void enter_wait();
+      void enter_prepad();
+      void enter_rampup();
+      void enter_copy();
+      void enter_rampdown();
+      void enter_postpad();
+
+    public:
+      burst_shaper_impl(const std::vector<T> &taps, int pre_padding,
+                  int post_padding, bool insert_phasing,
+                  const std::string &length_tag_name);
+      ~burst_shaper_impl();
+
+      void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+		       gr_vector_int &ninput_items,
+		       gr_vector_const_void_star &input_items,
+		       gr_vector_void_star &output_items);
+      int pre_padding() const { return d_nprepad; }
+      int post_padding() const { return d_npostpad; }
+      int prefix_length() const;
+      int suffix_length() const;
+    };
+
+  } // namespace digital
+} // namespace gr
+
+#endif /* BURST_SHAPER_IMPL_H */
diff --git a/gr-digital/lib/chunks_to_symbols_XX_impl.cc.t b/gr-digital/lib/chunks_to_symbols_XX_impl.cc.t
deleted file mode 100644
index b08bdde08f..0000000000
--- a/gr-digital/lib/chunks_to_symbols_XX_impl.cc.t
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <gnuradio/tag_checker.h>
-#include <assert.h>
-
-namespace gr {
-  namespace digital {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(const std::vector<@O_TYPE@> &symbol_table, const int D)
-    {
-      return gnuradio::get_initial_sptr
-        (new @IMPL_NAME@(symbol_table, D));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(const std::vector<@O_TYPE@> &symbol_table, const int D)
-    : sync_interpolator("@BASE_NAME@",
-			   io_signature::make(1, -1, sizeof(@I_TYPE@)),
-			   io_signature::make(1, -1, sizeof(@O_TYPE@)),
-			   D),
-      d_D(D), d_symbol_table(symbol_table)
-    {
-      message_port_register_in(pmt::mp("set_symbol_table"));
-      set_msg_handler(
-        pmt::mp("set_symbol_table"),
-        boost::bind(&@IMPL_NAME@::handle_set_symbol_table,
-                    this, _1));
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-    }
-
-
-    void
-    @IMPL_NAME@::set_vector_from_pmt(std::vector<gr_complex> &symbol_table, pmt::pmt_t &symbol_table_pmt) {
-      symbol_table.resize(0);
-      for (unsigned int i=0; i<pmt::length(symbol_table_pmt); i++) {
-        symbol_table.push_back(pmt::c32vector_ref(symbol_table_pmt, i));
-      }      
-    }
-
-    void
-    @IMPL_NAME@::set_vector_from_pmt(std::vector<float> &symbol_table, pmt::pmt_t &symbol_table_pmt) {
-      symbol_table.resize(0);
-      for (unsigned int i=0; i<pmt::length(symbol_table_pmt); i++) {
-        float f = pmt::f32vector_ref(symbol_table_pmt, i);
-        symbol_table.push_back(f);
-      }
-    }
-    
-    void
-    @IMPL_NAME@::handle_set_symbol_table(pmt::pmt_t symbol_table_pmt)
-    {
-      std::vector<@O_TYPE@> symbol_table;
-      set_vector_from_pmt(symbol_table, symbol_table_pmt);
-      set_symbol_table(symbol_table);
-    }
-
-    
-    void
-    @IMPL_NAME@::set_symbol_table(const std::vector<@O_TYPE@> &symbol_table)
-    {
-      d_symbol_table.resize(0);
-      for (unsigned int i=0; i<symbol_table.size(); i++) {
-        d_symbol_table.push_back(symbol_table[i]);
-      }
-    }
-
-    int
-    @IMPL_NAME@::work(int noutput_items,
-		      gr_vector_const_void_star &input_items,
-		      gr_vector_void_star &output_items)
-    {
-      assert(noutput_items % d_D == 0);
-      assert(input_items.size() == output_items.size());
-      int nstreams = input_items.size();
-
-      for(int m = 0; m < nstreams; m++) {
-        const @I_TYPE@ *in = (@I_TYPE@*)input_items[m];
-        @O_TYPE@ *out = (@O_TYPE@*)output_items[m];
-
-        std::vector<tag_t> tags;
-        get_tags_in_range(tags, m, nitems_read(m), nitems_read(m)+noutput_items/d_D);
-        tag_checker tchecker(tags);
-
-        // per stream processing
-        for(int i = 0; i < noutput_items / d_D; i++) {
-          
-          std::vector<tag_t> tags_now;
-          tchecker.get_tags(tags_now, i+nitems_read(m));
-          for (unsigned int j=0; j<tags_now.size(); j++) {
-            tag_t tag = tags_now[j];
-            dispatch_msg(tag.key, tag.value);
-          }
-          assert(((unsigned int)in[i]*d_D+d_D) <= d_symbol_table.size());
-          memcpy(out, &d_symbol_table[(unsigned int)in[i]*d_D], d_D*sizeof(@O_TYPE@));
-          out+=d_D;
-        }
-      }
-      return noutput_items;
-    }
-
-  } /* namespace digital */
-} /* namespace gr */
diff --git a/gr-digital/lib/chunks_to_symbols_XX_impl.h.t b/gr-digital/lib/chunks_to_symbols_XX_impl.h.t
deleted file mode 100644
index e0857bfb3c..0000000000
--- a/gr-digital/lib/chunks_to_symbols_XX_impl.h.t
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/digital/@BASE_NAME@.h>
-
-namespace gr {
-  namespace digital {
-
-    class @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      int d_D;
-      std::vector<@O_TYPE@> d_symbol_table;
-
-    public:
-      @IMPL_NAME@(const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
-
-      ~@IMPL_NAME@();
-
-      void set_vector_from_pmt(std::vector<float> &symbol_table, pmt::pmt_t &symbol_table_pmt);
-      void set_vector_from_pmt(std::vector<gr_complex> &symbol_table, pmt::pmt_t &symbol_table_pmt);
-
-      void handle_set_symbol_table(pmt::pmt_t symbol_table_pmt);
-      void set_symbol_table(const std::vector<@O_TYPE@> &symbol_table);
-      
-      int D() const { return d_D; }
-      std::vector<@O_TYPE@> symbol_table() const { return d_symbol_table; }
-
-      int work(int noutput_items,
-	       gr_vector_const_void_star &input_items,
-	       gr_vector_void_star &output_items);
-
-      bool check_topology(int ninputs, int noutputs) { return ninputs == noutputs; }
-    };
-
-  } /* namespace digital */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-digital/lib/chunks_to_symbols_impl.cc b/gr-digital/lib/chunks_to_symbols_impl.cc
new file mode 100644
index 0000000000..0d01c337d4
--- /dev/null
+++ b/gr-digital/lib/chunks_to_symbols_impl.cc
@@ -0,0 +1,145 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "chunks_to_symbols_impl.h"
+#include <gnuradio/io_signature.h>
+#include <gnuradio/tag_checker.h>
+#include <assert.h>
+
+namespace gr {
+  namespace digital {
+
+    template <class IN_T, class OUT_T>
+    typename chunks_to_symbols<IN_T,OUT_T>::sptr
+    chunks_to_symbols<IN_T,OUT_T>::make(const std::vector<OUT_T> &symbol_table, const int D)
+    {
+      return gnuradio::get_initial_sptr
+        (new chunks_to_symbols_impl<IN_T,OUT_T>(symbol_table, D));
+    }
+
+    template <class IN_T, class OUT_T>
+    chunks_to_symbols_impl<IN_T,OUT_T>::chunks_to_symbols_impl(const std::vector<OUT_T> &symbol_table, const int D)
+    : sync_interpolator("chunks_to_symbols",
+			   io_signature::make(1, -1, sizeof(IN_T)),
+			   io_signature::make(1, -1, sizeof(OUT_T)),
+			   D),
+      d_D(D), d_symbol_table(symbol_table)
+    {
+      this->message_port_register_in(pmt::mp("set_symbol_table"));
+      this->set_msg_handler(
+        pmt::mp("set_symbol_table"),
+        boost::bind(&chunks_to_symbols_impl<IN_T,OUT_T>::handle_set_symbol_table,
+                    this, _1));
+    }
+
+    template <class IN_T, class OUT_T>
+    chunks_to_symbols_impl<IN_T,OUT_T>::~chunks_to_symbols_impl()
+    {
+    }
+
+
+    template <class IN_T, class OUT_T>
+    void
+    chunks_to_symbols_impl<IN_T,OUT_T>::set_vector_from_pmt(std::vector<gr_complex> &symbol_table, pmt::pmt_t &symbol_table_pmt) {
+      symbol_table.resize(0);
+      for (unsigned int i=0; i<pmt::length(symbol_table_pmt); i++) {
+        symbol_table.push_back(pmt::c32vector_ref(symbol_table_pmt, i));
+      }
+    }
+
+    template <class IN_T, class OUT_T>
+    void
+    chunks_to_symbols_impl<IN_T,OUT_T>::set_vector_from_pmt(std::vector<float> &symbol_table, pmt::pmt_t &symbol_table_pmt) {
+      symbol_table.resize(0);
+      for (unsigned int i=0; i<pmt::length(symbol_table_pmt); i++) {
+        float f = pmt::f32vector_ref(symbol_table_pmt, i);
+        symbol_table.push_back(f);
+      }
+    }
+
+    template <class IN_T, class OUT_T>
+    void
+    chunks_to_symbols_impl<IN_T,OUT_T>::handle_set_symbol_table(pmt::pmt_t symbol_table_pmt)
+    {
+      std::vector<OUT_T> symbol_table;
+      set_vector_from_pmt(symbol_table, symbol_table_pmt);
+      set_symbol_table(symbol_table);
+    }
+
+
+    template <class IN_T, class OUT_T>
+    void
+    chunks_to_symbols_impl<IN_T,OUT_T>::set_symbol_table(const std::vector<OUT_T> &symbol_table)
+    {
+      d_symbol_table.resize(0);
+      for (unsigned int i=0; i<symbol_table.size(); i++) {
+        d_symbol_table.push_back(symbol_table[i]);
+      }
+    }
+
+    template <class IN_T, class OUT_T>
+    int
+    chunks_to_symbols_impl<IN_T,OUT_T>::work(int noutput_items,
+		      gr_vector_const_void_star &input_items,
+		      gr_vector_void_star &output_items)
+    {
+      assert(noutput_items % d_D == 0);
+      assert(input_items.size() == output_items.size());
+      int nstreams = input_items.size();
+
+      for(int m = 0; m < nstreams; m++) {
+        const IN_T *in = (IN_T*)input_items[m];
+        OUT_T *out = (OUT_T*)output_items[m];
+
+        std::vector<tag_t> tags;
+        this->get_tags_in_range(tags, m, this->nitems_read(m), this->nitems_read(m)+noutput_items/d_D);
+        tag_checker tchecker(tags);
+
+        // per stream processing
+        for(int i = 0; i < noutput_items / d_D; i++) {
+
+          std::vector<tag_t> tags_now;
+          tchecker.get_tags(tags_now, i+this->nitems_read(m));
+          for (unsigned int j=0; j<tags_now.size(); j++) {
+            tag_t tag = tags_now[j];
+            this->dispatch_msg(tag.key, tag.value);
+          }
+          assert(((unsigned int)in[i]*d_D+d_D) <= d_symbol_table.size());
+          memcpy(out, &d_symbol_table[(unsigned int)in[i]*d_D], d_D*sizeof(OUT_T));
+          out+=d_D;
+        }
+      }
+      return noutput_items;
+    }
+    template class chunks_to_symbols<std::uint8_t, float>;
+    template class chunks_to_symbols<std::uint8_t, gr_complex>;
+    template class chunks_to_symbols<std::int16_t, float>;
+    template class chunks_to_symbols<std::int16_t, gr_complex>;
+    template class chunks_to_symbols<std::int32_t, float>;
+    template class chunks_to_symbols<std::int32_t, gr_complex>;
+
+  } /* namespace digital */
+} /* namespace gr */
diff --git a/gr-digital/lib/chunks_to_symbols_impl.h b/gr-digital/lib/chunks_to_symbols_impl.h
new file mode 100644
index 0000000000..ae8c9a6c3a
--- /dev/null
+++ b/gr-digital/lib/chunks_to_symbols_impl.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef CHUNKS_TO_SYMBOLS_IMPL_H
+#define CHUNKS_TO_SYMBOLS_IMPL_H
+
+#include <gnuradio/digital/chunks_to_symbols.h>
+
+namespace gr {
+  namespace digital {
+
+    template <class IN_T, class OUT_T>
+    class chunks_to_symbols_impl : public chunks_to_symbols<IN_T, OUT_T>
+    {
+    private:
+      int d_D;
+      std::vector<OUT_T> d_symbol_table;
+
+    public:
+      chunks_to_symbols_impl(const std::vector<OUT_T> &symbol_table, const int D = 1);
+
+      ~chunks_to_symbols_impl();
+
+      void set_vector_from_pmt(std::vector<float> &symbol_table, pmt::pmt_t &symbol_table_pmt);
+      void set_vector_from_pmt(std::vector<gr_complex> &symbol_table, pmt::pmt_t &symbol_table_pmt);
+
+      void handle_set_symbol_table(pmt::pmt_t symbol_table_pmt);
+      void set_symbol_table(const std::vector<OUT_T> &symbol_table);
+
+      int D() const { return d_D; }
+      std::vector<OUT_T> symbol_table() const { return d_symbol_table; }
+
+      int work(int noutput_items,
+	       gr_vector_const_void_star &input_items,
+	       gr_vector_void_star &output_items);
+
+      bool check_topology(int ninputs, int noutputs) { return ninputs == noutputs; }
+    };
+
+  } /* namespace digital */
+} /* namespace gr */
+
+#endif /* CHUNKS_TO_SYMBOLS_IMPL_H */
diff --git a/gr-digital/swig/CMakeLists.txt b/gr-digital/swig/CMakeLists.txt
index 658ac46ed6..fcfc14c33c 100644
--- a/gr-digital/swig/CMakeLists.txt
+++ b/gr-digital/swig/CMakeLists.txt
@@ -62,7 +62,6 @@ foreach(swigfile ${GR_SWIG_BLOCK_IFILES})
     ${CMAKE_CURRENT_BINARY_DIR}/../include/gnuradio/digital
   )
   set(GR_SWIG_DOCS_TARGET_DEPS runtime_swig_swig_doc)
-  set(GR_SWIG_TARGET_DEPS digital_generated_includes)
   set(GR_SWIG_LIBRARIES gnuradio-digital
     gnuradio-filter gnuradio-analog gnuradio-blocks)
   GR_SWIG_MAKE(${swigfile} ${swigfile}.i)
diff --git a/gr-digital/swig/digital_swig1.i b/gr-digital/swig/digital_swig1.i
index 6d19da0328..dd6cd97745 100644
--- a/gr-digital/swig/digital_swig1.i
+++ b/gr-digital/swig/digital_swig1.i
@@ -38,14 +38,8 @@
 
 %{
 #include "gnuradio/digital/additive_scrambler_bb.h"
-#include "gnuradio/digital/burst_shaper_cc.h"
-#include "gnuradio/digital/burst_shaper_ff.h"
-#include "gnuradio/digital/chunks_to_symbols_bc.h"
-#include "gnuradio/digital/chunks_to_symbols_bf.h"
-#include "gnuradio/digital/chunks_to_symbols_ic.h"
-#include "gnuradio/digital/chunks_to_symbols_if.h"
-#include "gnuradio/digital/chunks_to_symbols_sc.h"
-#include "gnuradio/digital/chunks_to_symbols_sf.h"
+#include "gnuradio/digital/burst_shaper.h"
+#include "gnuradio/digital/chunks_to_symbols.h"
 #include "gnuradio/digital/clock_recovery_mm_cc.h"
 #include "gnuradio/digital/clock_recovery_mm_ff.h"
 #include "gnuradio/digital/diff_decoder_bb.h"
@@ -68,14 +62,8 @@
 %}
 
 %include "gnuradio/digital/additive_scrambler_bb.h"
-%include "gnuradio/digital/burst_shaper_cc.h"
-%include "gnuradio/digital/burst_shaper_ff.h"
-%include "gnuradio/digital/chunks_to_symbols_bc.h"
-%include "gnuradio/digital/chunks_to_symbols_bf.h"
-%include "gnuradio/digital/chunks_to_symbols_ic.h"
-%include "gnuradio/digital/chunks_to_symbols_if.h"
-%include "gnuradio/digital/chunks_to_symbols_sc.h"
-%include "gnuradio/digital/chunks_to_symbols_sf.h"
+%include "gnuradio/digital/burst_shaper.h"
+%include "gnuradio/digital/chunks_to_symbols.h"
 %include "gnuradio/digital/clock_recovery_mm_cc.h"
 %include "gnuradio/digital/clock_recovery_mm_ff.h"
 %include "gnuradio/digital/diff_decoder_bb.h"
@@ -97,14 +85,14 @@
 %include "gnuradio/digital/msk_timing_recovery_cc.h"
 
 GR_SWIG_BLOCK_MAGIC2(digital, additive_scrambler_bb);
-GR_SWIG_BLOCK_MAGIC2(digital, burst_shaper_cc);
-GR_SWIG_BLOCK_MAGIC2(digital, burst_shaper_ff);
-GR_SWIG_BLOCK_MAGIC2(digital, chunks_to_symbols_bc);
-GR_SWIG_BLOCK_MAGIC2(digital, chunks_to_symbols_bf);
-GR_SWIG_BLOCK_MAGIC2(digital, chunks_to_symbols_ic);
-GR_SWIG_BLOCK_MAGIC2(digital, chunks_to_symbols_if);
-GR_SWIG_BLOCK_MAGIC2(digital, chunks_to_symbols_sc);
-GR_SWIG_BLOCK_MAGIC2(digital, chunks_to_symbols_sf);
+GR_SWIG_BLOCK_MAGIC2_TMPL(digital, burst_shaper_cc, burst_shaper<gr_complex>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(digital, burst_shaper_ff, burst_shaper<float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(digital, chunks_to_symbols_bc, chunks_to_symbols<std::uint8_t,gr_complex>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(digital, chunks_to_symbols_bf, chunks_to_symbols<std::uint8_t,float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(digital, chunks_to_symbols_ic, chunks_to_symbols<std::int32_t,gr_complex>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(digital, chunks_to_symbols_if, chunks_to_symbols<std::int32_t,float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(digital, chunks_to_symbols_sc, chunks_to_symbols<std::int16_t,gr_complex>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(digital, chunks_to_symbols_sf, chunks_to_symbols<std::int16_t,float>);
 GR_SWIG_BLOCK_MAGIC2(digital, clock_recovery_mm_cc);
 GR_SWIG_BLOCK_MAGIC2(digital, clock_recovery_mm_ff);
 GR_SWIG_BLOCK_MAGIC2(digital, diff_decoder_bb);
-- 
cgit v1.2.3


From 7588f103b9e75eea56d241868d161d0f04f3fd79 Mon Sep 17 00:00:00 2001
From: Andrej Rode <mail@andrejro.de>
Date: Tue, 21 Aug 2018 15:32:45 +0200
Subject: filter: replace gengen with C++ templates

---
 docs/doxygen/CMakeLists.txt                        |   4 -
 gr-digital/lib/cpmmod_bc_impl.h                    |  13 +-
 gr-digital/lib/modulate_vector.cc                  |   2 +-
 gr-digital/lib/ofdm_sync_sc_cfb_impl.cc            |   3 +-
 gr-filter/include/gnuradio/filter/CMakeLists.txt   |  17 +-
 gr-filter/include/gnuradio/filter/fir_filter.h     | 234 +-----
 .../include/gnuradio/filter/fir_filter_XXX.h.t     |  81 --
 gr-filter/include/gnuradio/filter/fir_filter_blk.h |  87 +++
 .../gnuradio/filter/freq_xlating_fir_filter.h      | 100 +++
 .../filter/freq_xlating_fir_filter_XXX.h.t         |  98 ---
 .../include/gnuradio/filter/interp_fir_filter.h    |  87 +++
 .../gnuradio/filter/interp_fir_filter_XXX.h.t      |  81 --
 .../gnuradio/filter/rational_resampler_base.h      | 102 +++
 .../filter/rational_resampler_base_XXX.h.t         |  98 ---
 gr-filter/lib/CMakeLists.txt                       |  19 +-
 gr-filter/lib/fir_filter.cc                        | 858 ++++-----------------
 gr-filter/lib/fir_filter_XXX_impl.cc.t             | 107 ---
 gr-filter/lib/fir_filter_XXX_impl.h.t              |  56 --
 gr-filter/lib/fir_filter_blk_impl.cc               | 115 +++
 gr-filter/lib/fir_filter_blk_impl.h                |  55 ++
 .../lib/freq_xlating_fir_filter_XXX_impl.cc.t      | 178 -----
 gr-filter/lib/freq_xlating_fir_filter_XXX_impl.h.t |  74 --
 gr-filter/lib/freq_xlating_fir_filter_impl.cc      | 190 +++++
 gr-filter/lib/freq_xlating_fir_filter_impl.h       |  70 ++
 gr-filter/lib/interp_fir_filter_XXX_impl.cc.t      | 155 ----
 gr-filter/lib/interp_fir_filter_XXX_impl.h.t       |  62 --
 gr-filter/lib/interp_fir_filter_impl.cc            | 167 ++++
 gr-filter/lib/interp_fir_filter_impl.h             |  61 ++
 .../lib/rational_resampler_base_XXX_impl.cc.t      | 176 -----
 gr-filter/lib/rational_resampler_base_XXX_impl.h.t |  72 --
 gr-filter/lib/rational_resampler_base_impl.cc      | 188 +++++
 gr-filter/lib/rational_resampler_base_impl.h       |  71 ++
 gr-filter/swig/CMakeLists.txt                      |   1 -
 gr-filter/swig/filter_swig.i                       | 104 +--
 34 files changed, 1540 insertions(+), 2246 deletions(-)
 delete mode 100644 gr-filter/include/gnuradio/filter/fir_filter_XXX.h.t
 create mode 100644 gr-filter/include/gnuradio/filter/fir_filter_blk.h
 create mode 100644 gr-filter/include/gnuradio/filter/freq_xlating_fir_filter.h
 delete mode 100644 gr-filter/include/gnuradio/filter/freq_xlating_fir_filter_XXX.h.t
 create mode 100644 gr-filter/include/gnuradio/filter/interp_fir_filter.h
 delete mode 100644 gr-filter/include/gnuradio/filter/interp_fir_filter_XXX.h.t
 create mode 100644 gr-filter/include/gnuradio/filter/rational_resampler_base.h
 delete mode 100644 gr-filter/include/gnuradio/filter/rational_resampler_base_XXX.h.t
 delete mode 100644 gr-filter/lib/fir_filter_XXX_impl.cc.t
 delete mode 100644 gr-filter/lib/fir_filter_XXX_impl.h.t
 create mode 100644 gr-filter/lib/fir_filter_blk_impl.cc
 create mode 100644 gr-filter/lib/fir_filter_blk_impl.h
 delete mode 100644 gr-filter/lib/freq_xlating_fir_filter_XXX_impl.cc.t
 delete mode 100644 gr-filter/lib/freq_xlating_fir_filter_XXX_impl.h.t
 create mode 100644 gr-filter/lib/freq_xlating_fir_filter_impl.cc
 create mode 100644 gr-filter/lib/freq_xlating_fir_filter_impl.h
 delete mode 100644 gr-filter/lib/interp_fir_filter_XXX_impl.cc.t
 delete mode 100644 gr-filter/lib/interp_fir_filter_XXX_impl.h.t
 create mode 100644 gr-filter/lib/interp_fir_filter_impl.cc
 create mode 100644 gr-filter/lib/interp_fir_filter_impl.h
 delete mode 100644 gr-filter/lib/rational_resampler_base_XXX_impl.cc.t
 delete mode 100644 gr-filter/lib/rational_resampler_base_XXX_impl.h.t
 create mode 100644 gr-filter/lib/rational_resampler_base_impl.cc
 create mode 100644 gr-filter/lib/rational_resampler_base_impl.h

(limited to 'docs/doxygen')

diff --git a/docs/doxygen/CMakeLists.txt b/docs/doxygen/CMakeLists.txt
index b0b3c0f460..019b01c305 100644
--- a/docs/doxygen/CMakeLists.txt
+++ b/docs/doxygen/CMakeLists.txt
@@ -45,10 +45,6 @@ if(ENABLE_GNURADIO_RUNTIME)
   list(APPEND GENERATED_DEPS pmt_generated)
 endif(ENABLE_GNURADIO_RUNTIME)
 
-if(ENABLE_GR_FILTER)
-  list(APPEND GENERATED_DEPS filter_generated_includes)
-endif(ENABLE_GR_FILTER)
-
 if(ENABLE_GR_TRELLIS)
   list(APPEND GENERATED_DEPS trellis_generated_includes)
 endif(ENABLE_GR_TRELLIS)
diff --git a/gr-digital/lib/cpmmod_bc_impl.h b/gr-digital/lib/cpmmod_bc_impl.h
index 3402e6e2bb..f6385d0d30 100644
--- a/gr-digital/lib/cpmmod_bc_impl.h
+++ b/gr-digital/lib/cpmmod_bc_impl.h
@@ -1,19 +1,19 @@
 /* -*- c++ -*- */
 /*
  * Copyright 2010,2012 Free Software Foundation, Inc.
- * 
+ *
  * This file is part of GNU Radio
- * 
+ *
  * GNU Radio is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3, or (at your option)
  * any later version.
- * 
+ *
  * GNU Radio 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 General Public License for more details.
- * 
+ *
  * 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., 51 Franklin Street,
@@ -26,7 +26,7 @@
 #include <gnuradio/digital/cpmmod_bc.h>
 #include <gnuradio/blocks/char_to_float.h>
 #include <gnuradio/analog/frequency_modulator_fc.h>
-#include <gnuradio/filter/interp_fir_filter_fff.h>
+#include <gnuradio/filter/interp_fir_filter.h>
 
 namespace gr {
   namespace digital {
@@ -45,7 +45,7 @@ namespace gr {
       gr::blocks::char_to_float::sptr d_char_to_float;
       gr::filter::interp_fir_filter_fff::sptr d_pulse_shaper;
       analog::frequency_modulator_fc::sptr d_fm;
-  
+
     public:
       cpmmod_bc_impl(const std::string &name,
 		     analog::cpm::cpm_type type, float h,
@@ -65,4 +65,3 @@ namespace gr {
 } /* namespace gr */
 
 #endif /* INCLUDED_DIGITAL_CPMMOD_BC_IMPL_H */
-
diff --git a/gr-digital/lib/modulate_vector.cc b/gr-digital/lib/modulate_vector.cc
index 4ef6e804ae..81964aa8e5 100644
--- a/gr-digital/lib/modulate_vector.cc
+++ b/gr-digital/lib/modulate_vector.cc
@@ -42,7 +42,7 @@
 
 #include <gnuradio/blocks/vector_source.h>
 #include <gnuradio/blocks/vector_sink.h>
-#include <gnuradio/filter/fir_filter_ccf.h>
+#include <gnuradio/filter/fir_filter_blk.h>
 #include <gnuradio/top_block.h>
 #include <gnuradio/digital/modulate_vector.h>
 
diff --git a/gr-digital/lib/ofdm_sync_sc_cfb_impl.cc b/gr-digital/lib/ofdm_sync_sc_cfb_impl.cc
index 4c5bad14e1..b928d94e99 100644
--- a/gr-digital/lib/ofdm_sync_sc_cfb_impl.cc
+++ b/gr-digital/lib/ofdm_sync_sc_cfb_impl.cc
@@ -35,8 +35,7 @@
 #include <gnuradio/blocks/divide.h>
 #include <gnuradio/blocks/multiply.h>
 #include <gnuradio/blocks/sample_and_hold.h>
-#include <gnuradio/filter/fir_filter_ccf.h>
-#include <gnuradio/filter/fir_filter_fff.h>
+#include <gnuradio/filter/fir_filter_blk.h>
 
 namespace gr {
   namespace digital {
diff --git a/gr-filter/include/gnuradio/filter/CMakeLists.txt b/gr-filter/include/gnuradio/filter/CMakeLists.txt
index 9338d96713..8f17b496b2 100644
--- a/gr-filter/include/gnuradio/filter/CMakeLists.txt
+++ b/gr-filter/include/gnuradio/filter/CMakeLists.txt
@@ -17,24 +17,10 @@
 # the Free Software Foundation, Inc., 51 Franklin Street,
 # Boston, MA 02110-1301, USA.
 
-########################################################################
-# Invoke macro to generate various headers
-#######################################################################
-include(GrMiscUtils)
-GR_EXPAND_X_H(filter fir_filter_XXX              ccc ccf fcc fff fsf scc)
-GR_EXPAND_X_H(filter freq_xlating_fir_filter_XXX ccc ccf fcc fcf scf scc)
-GR_EXPAND_X_H(filter interp_fir_filter_XXX       ccc ccf fcc fff fsf scc)
-GR_EXPAND_X_H(filter rational_resampler_base_XXX ccc ccf fcc fff fsf scc)
-
-add_custom_target(filter_generated_includes DEPENDS
-    ${generated_includes}
-)
-
 ########################################################################
 # Install header files
 ########################################################################
 install(FILES
-    ${generated_includes}
     api.h
     firdes.h
     fir_filter.h
@@ -57,6 +43,7 @@ install(FILES
     fft_filter_ccc.h
     fft_filter_ccf.h
     fft_filter_fff.h
+    freq_xlating_fir_filter.h
     mmse_interpolator_cc.h
     mmse_interpolator_ff.h
     mmse_resampler_cc.h
@@ -75,8 +62,8 @@ install(FILES
     pfb_decimator_ccf.h
     pfb_interpolator_ccf.h
     pfb_synthesizer_ccf.h
+    rational_resampler_base.h
     single_pole_iir_filter_cc.h
     single_pole_iir_filter_ff.h
     DESTINATION ${GR_INCLUDE_DIR}/gnuradio/filter
 )
-
diff --git a/gr-filter/include/gnuradio/filter/fir_filter.h b/gr-filter/include/gnuradio/filter/fir_filter.h
index 99ca96c19a..48562d3680 100644
--- a/gr-filter/include/gnuradio/filter/fir_filter.h
+++ b/gr-filter/include/gnuradio/filter/fir_filter.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -23,206 +23,46 @@
 #ifndef INCLUDED_FILTER_FIR_FILTER_H
 #define INCLUDED_FILTER_FIR_FILTER_H
 
+#include <cstdint>
 #include <gnuradio/filter/api.h>
-#include <vector>
 #include <gnuradio/gr_complex.h>
+#include <vector>
 
 namespace gr {
-  namespace filter {
-    namespace kernel {
-
-      class FILTER_API fir_filter_fff
-      {
-      public:
-	fir_filter_fff(int decimation,
-		       const std::vector<float> &taps);
-	~fir_filter_fff();
-
-	void set_taps(const std::vector<float> &taps);
-	void update_tap(float t, unsigned int index);
-	std::vector<float> taps() const;
-	unsigned int ntaps() const;
-
-	float filter(const float input[]);
-	void  filterN(float output[],
-		      const float input[],
-		      unsigned long n);
-	void  filterNdec(float output[],
-			 const float input[],
-			 unsigned long n,
-			 unsigned int decimate);
-
-      protected:
-	std::vector<float> d_taps;
-	unsigned int  d_ntaps;
-	float       **d_aligned_taps;
-	float        *d_output;
-	int           d_align;
-	int           d_naligned;
-      };
-
-      /**************************************************************/
-
-      class FILTER_API fir_filter_ccf
-      {
-      public:
-	fir_filter_ccf(int decimation,
-		       const std::vector<float> &taps);
-	~fir_filter_ccf();
-
-	void set_taps(const std::vector<float> &taps);
-	void update_tap(float t, unsigned int index);
-	std::vector<float> taps() const;
-	unsigned int ntaps() const;
-
-	gr_complex filter(const gr_complex input[]);
-	void filterN(gr_complex output[],
-		     const gr_complex input[],
-		     unsigned long n);
-	void filterNdec(gr_complex output[],
-			const gr_complex input[],
-			unsigned long n,
-			unsigned int decimate);
-
-      protected:
-	std::vector<float> d_taps;
-	unsigned int d_ntaps;
-	float      **d_aligned_taps;
-	gr_complex  *d_output;
-	int          d_align;
-	int          d_naligned;
-      };
-
-      /**************************************************************/
-
-      class FILTER_API fir_filter_fcc
-      {
-      public:
-	fir_filter_fcc(int decimation,
-		       const std::vector<gr_complex> &taps);
-	~fir_filter_fcc();
-
-	void set_taps(const std::vector<gr_complex> &taps);
-	void update_tap(gr_complex t, unsigned int index);
-	std::vector<gr_complex> taps() const;
-	unsigned int ntaps() const;
-
-	gr_complex filter(const float input[]);
-	void filterN(gr_complex output[],
-		     const float input[],
-		     unsigned long n);
-	void filterNdec(gr_complex output[],
-			const float input[],
-			unsigned long n,
-			unsigned int decimate);
-
-      protected:
-	std::vector<gr_complex> d_taps;
-	unsigned int d_ntaps;
-	gr_complex **d_aligned_taps;
-	gr_complex  *d_output;
-	int          d_align;
-	int          d_naligned;
-      };
-
-      /**************************************************************/
-
-      class FILTER_API fir_filter_ccc
-      {
-      public:
-	fir_filter_ccc(int decimation,
-		       const std::vector<gr_complex> &taps);
-	~fir_filter_ccc();
-
-	void set_taps(const std::vector<gr_complex> &taps);
-	void update_tap(gr_complex t, unsigned int index);
-	std::vector<gr_complex> taps() const;
-	unsigned int ntaps() const;
-
-	gr_complex filter(const gr_complex input[]);
-	void filterN(gr_complex output[],
-		     const gr_complex input[],
-		     unsigned long n);
-	void filterNdec(gr_complex output[],
-			const gr_complex input[],
-			unsigned long n,
-			unsigned int decimate);
-
-      protected:
-	std::vector<gr_complex> d_taps;
-	unsigned int d_ntaps;
-	gr_complex **d_aligned_taps;
-	gr_complex  *d_output;
-	int          d_align;
-	int          d_naligned;
-      };
-
-      /**************************************************************/
-
-      class FILTER_API fir_filter_scc
-      {
-      public:
-	fir_filter_scc(int decimation,
-		       const std::vector<gr_complex> &taps);
-	~fir_filter_scc();
-
-	void set_taps(const std::vector<gr_complex> &taps);
-	void update_tap(gr_complex t, unsigned int index);
-	std::vector<gr_complex> taps() const;
-	unsigned int ntaps() const;
-
-	gr_complex filter(const short input[]);
-	void filterN(gr_complex output[],
-		     const short input[],
-		     unsigned long n);
-	void filterNdec(gr_complex output[],
-			const short input[],
-			unsigned long n,
-			unsigned int decimate);
-
-      protected:
-	std::vector<gr_complex> d_taps;
-	unsigned int d_ntaps;
-	gr_complex **d_aligned_taps;
-	gr_complex  *d_output;
-	int          d_align;
-	int          d_naligned;
-      };
-
-      /**************************************************************/
-
-      class FILTER_API fir_filter_fsf
-      {
-      public:
-	fir_filter_fsf(int decimation,
-		       const std::vector<float> &taps);
-	~fir_filter_fsf();
-
-	void set_taps(const std::vector<float> &taps);
-	void update_tap(float t, unsigned int index);
-	std::vector<float> taps() const;
-	unsigned int ntaps() const;
-
-	short filter(const float input[]);
-	void filterN(short output[],
-		     const float input[],
-		     unsigned long n);
-	void filterNdec(short output[],
-			const float input[],
-			unsigned long n,
-			unsigned int decimate);
-
-      protected:
-	std::vector<float> d_taps;
-	unsigned int d_ntaps;
-	float      **d_aligned_taps;
-	short       *d_output;
-	int          d_align;
-	int          d_naligned;
-      };
-
-    } /* namespace kernel */
-  } /* namespace filter */
+namespace filter {
+namespace kernel {
+
+template <class IN_T, class OUT_T, class TAP_T>
+class FILTER_API fir_filter {
+    public:
+    fir_filter(int decimation, const std::vector<TAP_T>& taps);
+    ~fir_filter();
+
+    void set_taps(const std::vector<TAP_T>& taps);
+    void update_tap(TAP_T t, unsigned int index);
+    std::vector<TAP_T> taps() const;
+    unsigned int ntaps() const;
+
+    OUT_T filter(const IN_T input[]);
+    void filterN(OUT_T output[], const IN_T input[], unsigned long n);
+    void filterNdec(OUT_T output[], const IN_T input[], unsigned long n, unsigned int decimate);
+
+    protected:
+    std::vector<TAP_T> d_taps;
+    unsigned int d_ntaps;
+    TAP_T** d_aligned_taps;
+    OUT_T* d_output;
+    int d_align;
+    int d_naligned;
+};
+typedef fir_filter<float, float, float> fir_filter_fff;
+typedef fir_filter<gr_complex, gr_complex, float> fir_filter_ccf;
+typedef fir_filter<float, gr_complex, gr_complex> fir_filter_fcc;
+typedef fir_filter<gr_complex, gr_complex, gr_complex> fir_filter_ccc;
+typedef fir_filter<std::int16_t, gr_complex, gr_complex> fir_filter_scc;
+typedef fir_filter<float, std::int16_t, float> fir_filter_fsf;
+} /* namespace kernel */
+} /* namespace filter */
 } /* namespace gr */
 
 #endif /* INCLUDED_FILTER_FIR_FILTER_H */
diff --git a/gr-filter/include/gnuradio/filter/fir_filter_XXX.h.t b/gr-filter/include/gnuradio/filter/fir_filter_XXX.h.t
deleted file mode 100644
index 5e38653c63..0000000000
--- a/gr-filter/include/gnuradio/filter/fir_filter_XXX.h.t
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifndef @GUARD_NAME@
-#define	@GUARD_NAME@
-
-#include <gnuradio/filter/api.h>
-#include <gnuradio/sync_decimator.h>
-
-namespace gr {
-  namespace filter {
-
-    /*!
-     * \brief FIR filter with @I_TYPE@ input, @O_TYPE@ output, and @TAP_TYPE@ taps
-     * \ingroup filter_blk
-     *
-     * \details
-     * The fir_filter_XXX blocks create finite impulse response
-     * (FIR) filters that perform the convolution in the time
-     * domain:
-     *
-     * \code
-     *   out = 0
-     *   for i in ntaps:
-     *      out += input[n-i] * taps[i]
-     * \endcode
-     *
-     * The taps are a C++ vector (or Python list) of values of the
-     * type specified by the third letter in the block's suffix. For
-     * this block, the value is of type @TAP_TYPE@. Taps can be
-     * created using the firdes or optfir tools.
-     *
-     * These versions of the filter can also act as down-samplers
-     * (or decimators) by specifying an integer value for \p
-     * decimation.
-     */
-    class FILTER_API @BASE_NAME@ : virtual public sync_decimator
-    {
-    public:
-
-      // gr::filter::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      /*!
-       * \brief FIR filter with @I_TYPE@ input, @O_TYPE@ output, and @TAP_TYPE@ taps
-       *
-       * \param decimation set the integer decimation rate
-       * \param taps a vector/list of taps of type @TAP_TYPE@
-       */
-      static sptr make(int decimation,
-                       const std::vector<@TAP_TYPE@> &taps);
-
-      virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0;
-      virtual std::vector<@TAP_TYPE@> taps() const = 0;
-    };
-
-  } /* namespace filter */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/include/gnuradio/filter/fir_filter_blk.h b/gr-filter/include/gnuradio/filter/fir_filter_blk.h
new file mode 100644
index 0000000000..be0ca50bb6
--- /dev/null
+++ b/gr-filter/include/gnuradio/filter/fir_filter_blk.h
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FIR_FILTER_BLK_H
+#define	FIR_FILTER_BLK_H
+
+#include <gnuradio/filter/api.h>
+#include <gnuradio/sync_decimator.h>
+#include <cstdint>
+
+namespace gr {
+  namespace filter {
+
+    /*!
+     * \brief FIR filter with IN_T input, OUT_T output, and TAP_T taps
+     * \ingroup filter_blk
+     *
+     * \details
+     * The fir_filter_blk_XXX blocks create finite impulse response
+     * (FIR) filters that perform the convolution in the time
+     * domain:
+     *
+     * \code
+     *   out = 0
+     *   for i in ntaps:
+     *      out += input[n-i] * taps[i]
+     * \endcode
+     *
+     * The taps are a C++ vector (or Python list) of values of the
+     * type specified by the third letter in the block's suffix. For
+     * this block, the value is of type TAP_T. Taps can be
+     * created using the firdes or optfir tools.
+     *
+     * These versions of the filter can also act as down-samplers
+     * (or decimators) by specifying an integer value for \p
+     * decimation.
+     */
+    template <class IN_T, class OUT_T, class TAP_T>
+    class FILTER_API fir_filter_blk : virtual public sync_decimator
+    {
+    public:
+
+      typedef boost::shared_ptr< fir_filter_blk<IN_T,OUT_T,TAP_T> > sptr;
+
+      /*!
+       * \brief FIR filter with IN_T input, OUT_T output, and TAP_T taps
+       *
+       * \param decimation set the integer decimation rate
+       * \param taps a vector/list of taps of type TAP_T
+       */
+      static sptr make(int decimation,
+                       const std::vector<TAP_T> &taps);
+
+      virtual void set_taps(const std::vector<TAP_T> &taps) = 0;
+      virtual std::vector<TAP_T> taps() const = 0;
+    };
+
+    typedef fir_filter_blk<gr_complex, gr_complex, gr_complex> fir_filter_ccc;
+    typedef fir_filter_blk<gr_complex, gr_complex, float> fir_filter_ccf;
+    typedef fir_filter_blk<float, gr_complex, gr_complex> fir_filter_fcc;
+    typedef fir_filter_blk<float, float, float> fir_filter_fff;
+    typedef fir_filter_blk<float, std::int16_t, float> fir_filter_fsf;
+    typedef fir_filter_blk<std::int16_t, gr_complex, gr_complex> fir_filter_scc;
+
+  } /* namespace filter */
+} /* namespace gr */
+
+#endif /* FIR_FILTER_BLK_H */
diff --git a/gr-filter/include/gnuradio/filter/freq_xlating_fir_filter.h b/gr-filter/include/gnuradio/filter/freq_xlating_fir_filter.h
new file mode 100644
index 0000000000..d06f5ed042
--- /dev/null
+++ b/gr-filter/include/gnuradio/filter/freq_xlating_fir_filter.h
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FREQ_XLATING_FIR_FILTER_H
+#define	FREQ_XLATING_FIR_FILTER_H
+
+#include <gnuradio/filter/api.h>
+#include <gnuradio/sync_decimator.h>
+
+namespace gr {
+  namespace filter {
+
+
+    /*!
+     * \brief FIR filter combined with frequency translation with
+     * IN_T input, OUT_T output and TAP_T taps
+     *
+     * \ingroup channelizers_blk
+     *
+     * This class efficiently combines a frequency translation
+     * (typically "down conversion") with a FIR filter (typically
+     * low-pass) and decimation.  It is ideally suited for a "channel
+     * selection filter" and can be efficiently used to select and
+     * decimate a narrow band signal out of wide bandwidth input.
+     *
+     * Uses a single input array to produce a single output array.
+     * Additional inputs and/or outputs are ignored.
+     *
+     * - freq (input):
+     *        Receives a PMT pair: (intern("freq"), double(frequency).
+     *        The block then sets its frequency translation value to
+     *        the new frequency provided by the message. A tag is then
+     *        produced when the new frequency is applied to let
+     *        downstream blocks know when this has taken affect.
+     *        Use the filter's group delay to determine when the
+     *        transients after the change have settled down.
+     */
+    template <class IN_T, class OUT_T, class TAP_T>
+    class FILTER_API freq_xlating_fir_filter : virtual public sync_decimator
+    {
+    public:
+      typedef boost::shared_ptr< freq_xlating_fir_filter<IN_T,OUT_T,TAP_T> > sptr;
+
+      /*!
+       * \brief FIR filter with IN_T input, OUT_T output, and
+       * TAP_T taps that also frequency translates a signal from
+       * \p center_freq.
+       *
+       * Construct a FIR filter with the given taps and a composite
+       * frequency translation that shifts center_freq down to zero
+       * Hz. The frequency translation logically comes before the
+       * filtering operation.
+       *
+       * \param decimation set the integer decimation rate
+       * \param taps a vector/list of taps of type TAP_T
+       * \param center_freq Center frequency of signal to down convert from (Hz)
+       * \param sampling_freq Sampling rate of signal (in Hz)
+       */
+      static sptr make(int decimation,
+				  const std::vector<TAP_T> &taps,
+				  double center_freq,
+				  double sampling_freq);
+
+      virtual void set_center_freq(double center_freq) = 0;
+      virtual double center_freq() const = 0;
+
+      virtual void set_taps(const std::vector<TAP_T> &taps) = 0;
+      virtual std::vector<TAP_T> taps() const = 0;
+    };
+    typedef freq_xlating_fir_filter<gr_complex, gr_complex, gr_complex> freq_xlating_fir_filter_ccc;
+    typedef freq_xlating_fir_filter<gr_complex, gr_complex, float> freq_xlating_fir_filter_ccf;
+    typedef freq_xlating_fir_filter<float, gr_complex, gr_complex> freq_xlating_fir_filter_fcc;
+    typedef freq_xlating_fir_filter<float, gr_complex, float> freq_xlating_fir_filter_fcf;
+    typedef freq_xlating_fir_filter<std::int16_t, gr_complex, float> freq_xlating_fir_filter_scf;
+    typedef freq_xlating_fir_filter<std::int16_t, gr_complex, gr_complex> freq_xlating_fir_filter_scc;
+
+
+  } /* namespace filter */
+} /* namespace gr */
+
+#endif /* FREQ_XLATING_FIR_FILTER_H */
diff --git a/gr-filter/include/gnuradio/filter/freq_xlating_fir_filter_XXX.h.t b/gr-filter/include/gnuradio/filter/freq_xlating_fir_filter_XXX.h.t
deleted file mode 100644
index d8cb8f962c..0000000000
--- a/gr-filter/include/gnuradio/filter/freq_xlating_fir_filter_XXX.h.t
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2002,2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/*
- * WARNING: This file is automatically generated by cmake.
- * Any changes made to this file will be overwritten.
- */
-
-#ifndef @GUARD_NAME@
-#define	@GUARD_NAME@
-
-#include <gnuradio/filter/api.h>
-#include <gnuradio/sync_decimator.h>
-
-namespace gr {
-  namespace filter {
-
-
-    /*!
-     * \brief FIR filter combined with frequency translation with
-     * @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
-     *
-     * \ingroup channelizers_blk
-     *
-     * This class efficiently combines a frequency translation
-     * (typically "down conversion") with a FIR filter (typically
-     * low-pass) and decimation.  It is ideally suited for a "channel
-     * selection filter" and can be efficiently used to select and
-     * decimate a narrow band signal out of wide bandwidth input.
-     *
-     * Uses a single input array to produce a single output array.
-     * Additional inputs and/or outputs are ignored.
-     *
-     * - freq (input):
-     *        Receives a PMT pair: (intern("freq"), double(frequency).
-     *        The block then sets its frequency translation value to
-     *        the new frequency provided by the message. A tag is then
-     *        produced when the new frequency is applied to let
-     *        downstream blocks know when this has taken affect.
-     *        Use the filter's group delay to determine when the
-     *        transients after the change have settled down.
-     */
-    class FILTER_API @BASE_NAME@ : virtual public sync_decimator
-    {
-    public:
-      // gr::filter::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      /*!
-       * \brief FIR filter with @I_TYPE@ input, @O_TYPE@ output, and
-       * @TAP_TYPE@ taps that also frequency translates a signal from
-       * \p center_freq.
-       *
-       * Construct a FIR filter with the given taps and a composite
-       * frequency translation that shifts center_freq down to zero
-       * Hz. The frequency translation logically comes before the
-       * filtering operation.
-       *
-       * \param decimation set the integer decimation rate
-       * \param taps a vector/list of taps of type @TAP_TYPE@
-       * \param center_freq Center frequency of signal to down convert from (Hz)
-       * \param sampling_freq Sampling rate of signal (in Hz)
-       */
-      static sptr make(int decimation,
-				  const std::vector<@TAP_TYPE@> &taps,
-				  double center_freq,
-				  double sampling_freq);
-
-      virtual void set_center_freq(double center_freq) = 0;
-      virtual double center_freq() const = 0;
-
-      virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0;
-      virtual std::vector<@TAP_TYPE@> taps() const = 0;
-    };
-
-  } /* namespace filter */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/include/gnuradio/filter/interp_fir_filter.h b/gr-filter/include/gnuradio/filter/interp_fir_filter.h
new file mode 100644
index 0000000000..abdc12ec20
--- /dev/null
+++ b/gr-filter/include/gnuradio/filter/interp_fir_filter.h
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INTERP_FIR_FILTER_H
+#define	INTERP_FIR_FILTER_H
+
+#include <gnuradio/filter/api.h>
+#include <gnuradio/sync_interpolator.h>
+#include <cstdint>
+
+namespace gr {
+  namespace filter {
+
+    /*!
+     * \brief Interpolating FIR filter with IN_T input, OUT_T output and TAP_T taps
+     * \ingroup filter_blk
+     *
+     * \details
+     * The fir_filter_XXX blocks create finite impulse response
+     * (FIR) filters that perform the convolution in the time
+     * domain:
+     *
+     * \code
+     *   out = 0
+     *   for i in ntaps:
+     *      out += input[n-i] * taps[i]
+     * \endcode
+     *
+     * The taps are a C++ vector (or Python list) of values of the
+     * type specified by the third letter in the block's suffix. For
+     * this block, the value is of type TAP_T. Taps can be
+     * created using the firdes or optfir tools.
+     *
+     * These versions of the filter can also act as up-samplers
+     * (or interpolators) by specifying an integer value for \p
+     * interpolation.
+     *
+     */
+    template <class IN_T, class OUT_T, class TAP_T>
+    class FILTER_API interp_fir_filter : virtual public sync_interpolator
+    {
+    public:
+      // gr::filter::interp_fir_filter::sptr
+      typedef boost::shared_ptr<interp_fir_filter> sptr;
+
+      /*!
+       * \brief Interpolating FIR filter with IN_T input, OUT_T output, and TAP_T taps
+       *
+       * \param interpolation set the integer interpolation rate
+       * \param taps a vector/list of taps of type TAP_T
+       */
+      static sptr make(unsigned interpolation,
+				  const std::vector<TAP_T> &taps);
+
+      virtual void set_taps(const std::vector<TAP_T> &taps) = 0;
+      virtual std::vector<TAP_T> taps() const = 0;
+    };
+    typedef interp_fir_filter<gr_complex, gr_complex, gr_complex> interp_fir_filter_ccc;
+    typedef interp_fir_filter<gr_complex, gr_complex, float> interp_fir_filter_ccf;
+    typedef interp_fir_filter<float, gr_complex, gr_complex> interp_fir_filter_fcc;
+    typedef interp_fir_filter<float, float, float> interp_fir_filter_fff;
+    typedef interp_fir_filter<float, std::int16_t, float> interp_fir_filter_fsf;
+    typedef interp_fir_filter<std::int16_t, gr_complex, gr_complex> interp_fir_filter_scc;
+
+  } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INTERP_FIR_FILTER_H */
diff --git a/gr-filter/include/gnuradio/filter/interp_fir_filter_XXX.h.t b/gr-filter/include/gnuradio/filter/interp_fir_filter_XXX.h.t
deleted file mode 100644
index 5b0f3511b4..0000000000
--- a/gr-filter/include/gnuradio/filter/interp_fir_filter_XXX.h.t
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifndef @GUARD_NAME@
-#define	@GUARD_NAME@
-
-#include <gnuradio/filter/api.h>
-#include <gnuradio/sync_interpolator.h>
-
-namespace gr {
-  namespace filter {
-
-    /*!
-     * \brief Interpolating FIR filter with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
-     * \ingroup filter_blk
-     *
-     * \details
-     * The fir_filter_XXX blocks create finite impulse response
-     * (FIR) filters that perform the convolution in the time
-     * domain:
-     *
-     * \code
-     *   out = 0
-     *   for i in ntaps:
-     *      out += input[n-i] * taps[i]
-     * \endcode
-     *
-     * The taps are a C++ vector (or Python list) of values of the
-     * type specified by the third letter in the block's suffix. For
-     * this block, the value is of type @TAP_TYPE@. Taps can be
-     * created using the firdes or optfir tools.
-     *
-     * These versions of the filter can also act as up-samplers
-     * (or interpolators) by specifying an integer value for \p
-     * interpolation.
-     *
-     */
-    class FILTER_API @BASE_NAME@ : virtual public sync_interpolator
-    {
-    public:
-      // gr::filter::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      /*!
-       * \brief Interpolating FIR filter with @I_TYPE@ input, @O_TYPE@ output, and @TAP_TYPE@ taps
-       *
-       * \param interpolation set the integer interpolation rate
-       * \param taps a vector/list of taps of type @TAP_TYPE@
-       */
-      static sptr make(unsigned interpolation,
-				  const std::vector<@TAP_TYPE@> &taps);
-
-      virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0;
-      virtual std::vector<@TAP_TYPE@> taps() const = 0;
-    };
-
-  } /* namespace filter */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/include/gnuradio/filter/rational_resampler_base.h b/gr-filter/include/gnuradio/filter/rational_resampler_base.h
new file mode 100644
index 0000000000..97974c6c15
--- /dev/null
+++ b/gr-filter/include/gnuradio/filter/rational_resampler_base.h
@@ -0,0 +1,102 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef RATIONAL_RESAMPLER_BASE_H
+#define	RATIONAL_RESAMPLER_BASE_H
+
+#include <gnuradio/filter/api.h>
+#include <gnuradio/block.h>
+
+
+namespace gr {
+  namespace filter {
+
+    /*!
+     * \brief Rational Resampling Polyphase FIR filter with IN_T
+     * input, OUT_T output and TAP_T taps.
+     * \ingroup resamplers_blk
+     *
+     * Make a rational resampling FIR filter. If the input signal is
+     * at rate fs, then the output signal will be at a rate of \p
+     * interpolation * fs / \p decimation.
+     *
+     * The interpolation and decimation rates should be kept as
+     * small as possible, and generally should be relatively prime
+     * to help reduce complexity in memory and computation.
+     *
+     * The set of \p taps supplied to this filterbank should be
+     * designed around the resampling amount and must avoid aliasing
+     * (when interpolation/decimation < 1) and images (when
+     * interpolation/decimation > 1).
+     *
+     * As with any filter, the behavior of the filter taps (or
+     * coefficients) is determined by the highest sampling rate that
+     * the filter will ever see. In the case of a resampler that
+     * increases the sampling rate, the highest sampling rate observed
+     * is \p interpolation since in the filterbank, the number of
+     * filter arms is equal to \p interpolation. When the resampler
+     * decreases the sampling rate (decimation > interpolation), then
+     * the highest rate is the input sample rate of the original
+     * signal. We must create a filter based around this value to
+     * reduce any aliasing that may occur from out-of-band signals.
+     *
+     * Another way to think about how to create the filter taps is
+     * that the filter is effectively applied after interpolation and
+     * before decimation. And yet another way to think of it is that
+     * the taps should be a LPF that is at least as narrow as the
+     * narrower of the required anti-image postfilter or anti-alias
+     * prefilter.
+     */
+    template <class IN_T, class OUT_T, class TAP_T>
+    class FILTER_API rational_resampler_base : virtual public block
+    {
+    public:
+      typedef boost::shared_ptr< rational_resampler_base<IN_T,OUT_T,TAP_T> > sptr;
+
+      /*!
+       * Make a rational resampling FIR filter.
+       *
+       * \param interpolation The integer interpolation rate of the filter
+       * \param decimation The integer decimation rate of the filter
+       * \param taps The filter taps to control images and aliases
+       */
+      static sptr make(unsigned interpolation,
+                       unsigned decimation,
+                       const std::vector<TAP_T> &taps);
+
+      virtual unsigned interpolation() const = 0;
+      virtual unsigned decimation() const = 0;
+
+      virtual void set_taps(const std::vector<TAP_T> &taps) = 0;
+      virtual std::vector<TAP_T> taps() const = 0;
+    };
+    typedef rational_resampler_base<gr_complex, gr_complex, gr_complex> rational_resampler_base_ccc;
+    typedef rational_resampler_base<gr_complex, gr_complex, float> rational_resampler_base_ccf;
+    typedef rational_resampler_base<float, gr_complex, gr_complex> rational_resampler_base_fcc;
+    typedef rational_resampler_base<float, float, float> rational_resampler_base_fff;
+    typedef rational_resampler_base<float, std::int16_t, float> rational_resampler_base_fsf;
+    typedef rational_resampler_base<std::int16_t, gr_complex, gr_complex> rational_resampler_base_scc;
+
+  } /* namespace filter */
+} /* namespace gr */
+
+#endif /* RATIONAL_RESAMPLER_BASE_H */
diff --git a/gr-filter/include/gnuradio/filter/rational_resampler_base_XXX.h.t b/gr-filter/include/gnuradio/filter/rational_resampler_base_XXX.h.t
deleted file mode 100644
index d5f8379804..0000000000
--- a/gr-filter/include/gnuradio/filter/rational_resampler_base_XXX.h.t
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifndef @GUARD_NAME@
-#define	@GUARD_NAME@
-
-#include <gnuradio/filter/api.h>
-#include <gnuradio/block.h>
-
-
-namespace gr {
-  namespace filter {
-
-    /*!
-     * \brief Rational Resampling Polyphase FIR filter with @I_TYPE@
-     * input, @O_TYPE@ output and @TAP_TYPE@ taps.
-     * \ingroup resamplers_blk
-     *
-     * Make a rational resampling FIR filter. If the input signal is
-     * at rate fs, then the output signal will be at a rate of \p
-     * interpolation * fs / \p decimation.
-     *
-     * The interpolation and decimation rates should be kept as
-     * small as possible, and generally should be relatively prime
-     * to help reduce complexity in memory and computation.
-     *
-     * The set of \p taps supplied to this filterbank should be
-     * designed around the resampling amount and must avoid aliasing
-     * (when interpolation/decimation < 1) and images (when
-     * interpolation/decimation > 1).
-     *
-     * As with any filter, the behavior of the filter taps (or
-     * coefficients) is determined by the highest sampling rate that
-     * the filter will ever see. In the case of a resampler that
-     * increases the sampling rate, the highest sampling rate observed
-     * is \p interpolation since in the filterbank, the number of
-     * filter arms is equal to \p interpolation. When the resampler
-     * decreases the sampling rate (decimation > interpolation), then
-     * the highest rate is the input sample rate of the original
-     * signal. We must create a filter based around this value to
-     * reduce any aliasing that may occur from out-of-band signals.
-     *
-     * Another way to think about how to create the filter taps is
-     * that the filter is effectively applied after interpolation and
-     * before decimation. And yet another way to think of it is that
-     * the taps should be a LPF that is at least as narrow as the
-     * narrower of the required anti-image postfilter or anti-alias
-     * prefilter.
-     */
-    class FILTER_API @NAME@ : virtual public block
-    {
-    public:
-      // gr::filter::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      /*!
-       * Make a rational resampling FIR filter.
-       *
-       * \param interpolation The integer interpolation rate of the filter
-       * \param decimation The integer decimation rate of the filter
-       * \param taps The filter taps to control images and aliases
-       */
-      static sptr make(unsigned interpolation,
-                       unsigned decimation,
-                       const std::vector<@TAP_TYPE@> &taps);
-
-      virtual unsigned interpolation() const = 0;
-      virtual unsigned decimation() const = 0;
-
-      virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0;
-      virtual std::vector<@TAP_TYPE@> taps() const = 0;
-    };
-
-  } /* namespace filter */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/lib/CMakeLists.txt b/gr-filter/lib/CMakeLists.txt
index 8bd7236865..5bb7b5d1fb 100644
--- a/gr-filter/lib/CMakeLists.txt
+++ b/gr-filter/lib/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014,2017 Free Software Foundation, Inc.
+# Copyright (C) 2012-2014,2017-2018 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -17,15 +17,6 @@
 # the Free Software Foundation, Inc., 51 Franklin Street,
 # Boston, MA 02110-1301, USA.
 
-########################################################################
-# Invoke macro to generate various sources and headers
-########################################################################
-include(GrMiscUtils)
-GR_EXPAND_X_CC_H(filter fir_filter_XXX_impl              ccc ccf fcc fff fsf scc)
-GR_EXPAND_X_CC_H(filter freq_xlating_fir_filter_XXX_impl ccc ccf fcc fcf scf scc)
-GR_EXPAND_X_CC_H(filter interp_fir_filter_XXX_impl       ccc ccf fcc fff fsf scc)
-GR_EXPAND_X_CC_H(filter rational_resampler_base_XXX_impl ccc ccf fcc fff fsf scc)
-
 ########################################################################
 # Setup the include and linker paths
 ########################################################################
@@ -53,17 +44,19 @@ endif(ENABLE_GR_CTRLPORT)
 ########################################################################
 list(APPEND filter_sources
   fir_filter.cc
+  fir_filter_blk_impl.cc
   fir_filter_with_buffer.cc
   fft_filter.cc
   firdes.cc
+  freq_xlating_fir_filter_impl.cc
   iir_filter.cc
+  interp_fir_filter_impl.cc
   mmse_fir_interpolator_cc.cc
   mmse_fir_interpolator_ff.cc
   mmse_interp_differentiator_cc.cc
   mmse_interp_differentiator_ff.cc
   pm_remez.cc
   polyphase_filterbank.cc
-  ${generated_sources}
   dc_blocker_cc_impl.cc
   dc_blocker_ff_impl.cc
   filter_delay_fc_impl.cc
@@ -90,6 +83,7 @@ list(APPEND filter_sources
   pfb_decimator_ccf_impl.cc
   pfb_interpolator_ccf_impl.cc
   pfb_synthesizer_ccf_impl.cc
+  rational_resampler_base_impl.cc
   single_pole_iir_filter_cc_impl.cc
   single_pole_iir_filter_ff_impl.cc
 )
@@ -121,7 +115,7 @@ add_library(gnuradio-filter SHARED ${filter_sources})
 target_link_libraries(gnuradio-filter ${filter_libs})
 GR_LIBRARY_FOO(gnuradio-filter)
 add_dependencies(gnuradio-filter
-  filter_generated_includes filter_generated_swigs
+  filter_generated_swigs
   gnuradio-runtime gnuradio-fft)
 
 if(ENABLE_STATIC_LIBS)
@@ -139,7 +133,6 @@ if(ENABLE_STATIC_LIBS)
   add_library(gnuradio-filter_static STATIC ${filter_sources})
 
   add_dependencies(gnuradio-filter_static
-    filter_generated_includes
     gnuradio-runtime_static gnuradio-fft_static)
 
   if(NOT WIN32)
diff --git a/gr-filter/lib/fir_filter.cc b/gr-filter/lib/fir_filter.cc
index 895c778076..b85e972255 100644
--- a/gr-filter/lib/fir_filter.cc
+++ b/gr-filter/lib/fir_filter.cc
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -20,703 +20,169 @@
  * Boston, MA 02110-1301, USA.
  */
 
-#include <gnuradio/filter/fir_filter.h>
-#include <gnuradio/fft/fft.h>
-#include <volk/volk.h>
 #include <cstdio>
 #include <cstring>
+#include <gnuradio/fft/fft.h>
+#include <gnuradio/filter/fir_filter.h>
+#include <volk/volk.h>
 
 namespace gr {
-  namespace filter {
-    namespace kernel {
-
-      fir_filter_fff::fir_filter_fff(int decimation,
-				     const std::vector<float> &taps)
-      {
-	d_align = volk_get_alignment();
-	d_naligned = std::max((size_t)1, d_align / sizeof(float));
-
-	d_aligned_taps = NULL;
-	set_taps(taps);
-
-	// Make sure the output sample is always aligned, too.
-	d_output = (float*)volk_malloc(1*sizeof(float), d_align);
-      }
-
-      fir_filter_fff::~fir_filter_fff()
-      {
-	// Free all aligned taps
-	if(d_aligned_taps != NULL) {
-	  for(int i = 0; i < d_naligned; i++) {
-	    volk_free(d_aligned_taps[i]);
-	  }
-	  ::free(d_aligned_taps);
-	  d_aligned_taps = NULL;
-	}
-
-	// Free output sample
-	volk_free(d_output);
-      }
-
-      void
-      fir_filter_fff::set_taps(const std::vector<float> &taps)
-      {
-	// Free the taps if already allocated
-	if(d_aligned_taps!= NULL) {
-	  for(int i = 0; i < d_naligned; i++) {
-	    volk_free(d_aligned_taps[i]);
-	  }
-	  ::free(d_aligned_taps);
-	  d_aligned_taps = NULL;
-	}
-
-	d_ntaps = (int)taps.size();
-	d_taps = taps;
-	std::reverse(d_taps.begin(), d_taps.end());
-
-	// Make a set of taps at all possible arch alignments
-	d_aligned_taps = (float**)malloc(d_naligned*sizeof(float*));
-	for(int i = 0; i < d_naligned; i++) {
-          d_aligned_taps[i] = (float*)volk_malloc((d_ntaps+d_naligned-1)*sizeof(float), d_align);
-	  memset(d_aligned_taps[i], 0, sizeof(float)*(d_ntaps+d_naligned-1));
-	  for(unsigned int j = 0; j < d_ntaps; j++)
-	    d_aligned_taps[i][i+j] = d_taps[j];
-	}
-      }
-
-      void
-      fir_filter_fff::update_tap(float t, unsigned int index)
-      {
-	d_taps[index] = t;
-	for(int i = 0; i < d_naligned; i++) {
-	  d_aligned_taps[i][i+index] = t;
-	}
-      }
-
-      std::vector<float>
-      fir_filter_fff::taps() const
-      {
-	std::vector<float> t = d_taps;
-	std::reverse(t.begin(), t.end());
-	return t;
-      }
-
-      unsigned int
-      fir_filter_fff::ntaps() const
-      {
-	return d_ntaps;
-      }
-
-      float
-      fir_filter_fff::filter(const float input[])
-      {
-	const float *ar = (float *)((size_t) input & ~(d_align-1));
-	unsigned al = input - ar;
-
-	volk_32f_x2_dot_prod_32f_a(d_output, ar,
-				   d_aligned_taps[al],
-				   d_ntaps+al);
-	return *d_output;
-      }
-
-      void
-      fir_filter_fff::filterN(float output[],
-			      const float input[],
-			      unsigned long n)
-      {
-	for(unsigned long i = 0; i < n; i++) {
-	  output[i] = filter(&input[i]);
-	}
-      }
-
-      void
-      fir_filter_fff::filterNdec(float output[],
-				 const float input[],
-				 unsigned long n,
-				 unsigned int decimate)
-      {
-	unsigned long j = 0;
-	for(unsigned long i = 0; i < n; i++) {
-	  output[i] = filter(&input[j]);
-	  j += decimate;
-	}
-      }
-
-      /**************************************************************/
-
-      fir_filter_ccf::fir_filter_ccf(int decimation,
-				     const std::vector<float> &taps)
-      {
-	d_align = volk_get_alignment();
-	d_naligned = std::max((size_t)1, d_align / sizeof(gr_complex));
-
-	d_aligned_taps = NULL;
-	set_taps(taps);
-
-	// Make sure the output sample is always aligned, too.
-	d_output = (gr_complex*)volk_malloc(1*sizeof(gr_complex), d_align);
-      }
-
-      fir_filter_ccf::~fir_filter_ccf()
-      {
-	// Free all aligned taps
-	if(d_aligned_taps != NULL) {
-	  for(int i = 0; i < d_naligned; i++) {
-	    volk_free(d_aligned_taps[i]);
-	  }
-	  ::free(d_aligned_taps);
-	  d_aligned_taps = NULL;
-	}
-
-	// Free output sample
-	volk_free(d_output);
-      }
-
-      void
-      fir_filter_ccf::set_taps(const std::vector<float> &taps)
-      {
-	// Free the taps if already allocated
-	if(d_aligned_taps != NULL) {
-	  for(int i = 0; i < d_naligned; i++) {
-	    volk_free(d_aligned_taps[i]);
-	  }
-	  ::free(d_aligned_taps);
-	  d_aligned_taps = NULL;
-	}
-
-	d_ntaps = (int)taps.size();
-	d_taps = taps;
-	std::reverse(d_taps.begin(), d_taps.end());
-
-	// Make a set of taps at all possible arch alignments
-	d_aligned_taps = (float**)malloc(d_naligned*sizeof(float*));
-	for(int i = 0; i < d_naligned; i++) {
-          d_aligned_taps[i] = (float*)volk_malloc((d_ntaps+d_naligned-1)*sizeof(float), d_align);
-	  memset(d_aligned_taps[i], 0, sizeof(float)*(d_ntaps+d_naligned-1));
-	  for(unsigned int j = 0; j < d_ntaps; j++)
-	    d_aligned_taps[i][i+j] = d_taps[j];
-	}
-      }
-
-      void
-      fir_filter_ccf::update_tap(float t, unsigned int index)
-      {
-	d_taps[index] = t;
-	for(int i = 0; i < d_naligned; i++) {
-	  d_aligned_taps[i][i+index] = t;
-	}
-      }
-
-      std::vector<float>
-      fir_filter_ccf::taps() const
-      {
-	std::vector<float> t = d_taps;
-	std::reverse(t.begin(), t.end());
-	return t;
-      }
-
-      unsigned int
-      fir_filter_ccf::ntaps() const
-      {
-	return d_ntaps;
-      }
-
-      gr_complex
-      fir_filter_ccf::filter(const gr_complex input[])
-      {
-	const gr_complex *ar = (gr_complex *)((size_t) input & ~(d_align-1));
-	unsigned al = input - ar;
-
-	volk_32fc_32f_dot_prod_32fc_a(d_output, ar,
-				      d_aligned_taps[al],
-				      (d_ntaps+al));
-	return *d_output;
-      }
-
-      void
-      fir_filter_ccf::filterN(gr_complex output[],
-			      const gr_complex input[],
-			      unsigned long n)
-      {
-	for(unsigned long i = 0; i < n; i++)
-	  output[i] = filter(&input[i]);
-      }
-
-
-      void
-      fir_filter_ccf::filterNdec(gr_complex output[],
-				 const gr_complex input[],
-				 unsigned long n,
-				 unsigned int decimate)
-      {
-	unsigned long j = 0;
-	for(unsigned long i = 0; i < n; i++){
-	  output[i] = filter(&input[j]);
-	  j += decimate;
-	}
-      }
-
-
-      /**************************************************************/
-
-
-      fir_filter_fcc::fir_filter_fcc(int decimation,
-				     const std::vector<gr_complex> &taps)
-      {
-	d_align = volk_get_alignment();
-	d_naligned = std::max((size_t)1, d_align / sizeof(float));
-
-	d_aligned_taps = NULL;
-	set_taps(taps);
-
-	// Make sure the output sample is always aligned, too.
-	d_output = (gr_complex*)volk_malloc(1*sizeof(gr_complex), d_align);
-      }
-
-      fir_filter_fcc::~fir_filter_fcc()
-      {
-	// Free all aligned taps
-	if(d_aligned_taps != NULL) {
-	  for(int i = 0; i < d_naligned; i++) {
-	    volk_free(d_aligned_taps[i]);
-	  }
-	  ::free(d_aligned_taps);
-	  d_aligned_taps = NULL;
-	}
-
-	// Free output sample
-	volk_free(d_output);
-      }
-
-      void
-      fir_filter_fcc::set_taps(const std::vector<gr_complex> &taps)
-      {
-	// Free the taps if already allocated
-	if(d_aligned_taps != NULL) {
-	  for(int i = 0; i < d_naligned; i++) {
-	    volk_free(d_aligned_taps[i]);
-	  }
-	  ::free(d_aligned_taps);
-	  d_aligned_taps = NULL;
-	}
-
-	d_ntaps = (int)taps.size();
-	d_taps = taps;
-	std::reverse(d_taps.begin(), d_taps.end());
-
-	// Make a set of taps at all possible arch alignments
-	d_aligned_taps = (gr_complex**)malloc(d_naligned*sizeof(gr_complex*));
-	for(int i = 0; i < d_naligned; i++) {
-          d_aligned_taps[i] = (gr_complex*)volk_malloc((d_ntaps+d_naligned-1)*sizeof(gr_complex), d_align);
-	  memset(d_aligned_taps[i], 0, sizeof(gr_complex)*(d_ntaps+d_naligned-1));
-	  for(unsigned int j = 0; j < d_ntaps; j++)
-	    d_aligned_taps[i][i+j] = d_taps[j];
-	}
-      }
-
-      void
-      fir_filter_fcc::update_tap(gr_complex t, unsigned int index)
-      {
-	d_taps[index] = t;
-	for(int i = 0; i < d_naligned; i++) {
-	  d_aligned_taps[i][i+index] = t;
-	}
-      }
-
-
-      std::vector<gr_complex>
-      fir_filter_fcc::taps() const
-      {
-	std::vector<gr_complex> t = d_taps;
-	std::reverse(t.begin(), t.end());
-	return t;
-      }
-
-      unsigned int
-      fir_filter_fcc::ntaps() const
-      {
-	return d_ntaps;
-      }
-
-      gr_complex
-      fir_filter_fcc::filter(const float input[])
-      {
-	const float *ar = (float *)((size_t) input & ~(d_align-1));
-	unsigned al = input - ar;
-
-	volk_32fc_32f_dot_prod_32fc_a(d_output,
-				      d_aligned_taps[al],
-				      ar,
-				      (d_ntaps+al));
-	return *d_output;
-      }
-
-      void
-      fir_filter_fcc::filterN(gr_complex output[],
-			      const float input[],
-			      unsigned long n)
-      {
-	for(unsigned long i = 0; i < n; i++)
-	  output[i] = filter(&input[i]);
-      }
-
-
-      void
-      fir_filter_fcc::filterNdec(gr_complex output[],
-				 const float input[],
-				 unsigned long n,
-				 unsigned int decimate)
-      {
-	unsigned long j = 0;
-	for(unsigned long i = 0; i < n; i++){
-	  output[i] = filter(&input[j]);
-	  j += decimate;
-	}
-      }
-
-      /**************************************************************/
-
-      fir_filter_ccc::fir_filter_ccc(int decimation,
-				     const std::vector<gr_complex> &taps)
-      {
-	d_align = volk_get_alignment();
-	d_naligned = std::max((size_t)1, d_align / sizeof(gr_complex));
-
-	d_aligned_taps = NULL;
-	set_taps(taps);
-
-	// Make sure the output sample is always aligned, too.
-	d_output = (gr_complex*)volk_malloc(1*sizeof(gr_complex), d_align);
-      }
-
-      fir_filter_ccc::~fir_filter_ccc()
-      {
-	// Free all aligned taps
-	if(d_aligned_taps != NULL) {
-	  for(int i = 0; i < d_naligned; i++) {
-	    volk_free(d_aligned_taps[i]);
-	  }
-	  ::free(d_aligned_taps);
-	  d_aligned_taps = NULL;
-	}
-
-	// Free output sample
-	volk_free(d_output);
-      }
-
-      void
-      fir_filter_ccc::set_taps(const std::vector<gr_complex> &taps)
-      {
-	// Free the taps if already allocated
-	if(d_aligned_taps != NULL) {
-	  for(int i = 0; i < d_naligned; i++) {
-	    volk_free(d_aligned_taps[i]);
-	  }
-	  ::free(d_aligned_taps);
-	  d_aligned_taps = NULL;
-	}
-
-	d_ntaps = (int)taps.size();
-	d_taps = taps;
-	std::reverse(d_taps.begin(), d_taps.end());
-
-	// Make a set of taps at all possible arch alignments
-	d_aligned_taps = (gr_complex**)malloc(d_naligned*sizeof(gr_complex*));
-	for(int i = 0; i < d_naligned; i++) {
-          d_aligned_taps[i] = (gr_complex*)volk_malloc((d_ntaps+d_naligned-1)*sizeof(gr_complex), d_align);
-	  memset(d_aligned_taps[i], 0, sizeof(gr_complex)*(d_ntaps+d_naligned-1));
-	  for(unsigned int j = 0; j < d_ntaps; j++)
-	    d_aligned_taps[i][i+j] = d_taps[j];
-	}
-      }
-
-      void
-      fir_filter_ccc::update_tap(gr_complex t, unsigned int index)
-      {
-	d_taps[index] = t;
-	for(int i = 0; i < d_naligned; i++) {
-	  d_aligned_taps[i][i+index] = t;
-	}
-      }
-
-      std::vector<gr_complex>
-      fir_filter_ccc::taps() const
-      {
-	std::vector<gr_complex> t = d_taps;
-	std::reverse(t.begin(), t.end());
-	return t;
-      }
-
-      unsigned int
-      fir_filter_ccc::ntaps() const
-      {
-	return d_ntaps;
-      }
-
-      gr_complex
-      fir_filter_ccc::filter(const gr_complex input[])
-      {
-	const gr_complex *ar = (gr_complex *)((size_t) input & ~(d_align-1));
-	unsigned al = input - ar;
-
-	volk_32fc_x2_dot_prod_32fc_a(d_output, ar,
-				     d_aligned_taps[al],
-				     (d_ntaps+al));
-	return *d_output;
-      }
-
-      void
-      fir_filter_ccc::filterN(gr_complex output[],
-			      const gr_complex input[],
-			      unsigned long n)
-      {
-	for(unsigned long i = 0; i < n; i++)
-	  output[i] = filter(&input[i]);
-      }
-
-
-      void
-      fir_filter_ccc::filterNdec(gr_complex output[],
-				 const gr_complex input[],
-				 unsigned long n,
-				 unsigned int decimate)
-      {
-	unsigned long j = 0;
-	for(unsigned long i = 0; i < n; i++){
-	  output[i] = filter(&input[j]);
-	  j += decimate;
-	}
-      }
-
-      /**************************************************************/
-
-      fir_filter_scc::fir_filter_scc(int decimation,
-				     const std::vector<gr_complex> &taps)
-      {
-	d_align = volk_get_alignment();
-	d_naligned = std::max((size_t)1, d_align / sizeof(short));
-
-	d_aligned_taps = NULL;
-	set_taps(taps);
-
-	// Make sure the output sample is always aligned, too.
-	d_output = (gr_complex*)volk_malloc(1*sizeof(gr_complex), d_align);
-      }
-
-      fir_filter_scc::~fir_filter_scc()
-      {
-	// Free all aligned taps
-	if(d_aligned_taps != NULL) {
-	  for(int i = 0; i < d_naligned; i++) {
-	    volk_free(d_aligned_taps[i]);
-	  }
-	  ::free(d_aligned_taps);
-	  d_aligned_taps = NULL;
-	}
-
-	// Free output sample
-	volk_free(d_output);
-      }
-
-      void
-      fir_filter_scc::set_taps(const std::vector<gr_complex> &taps)
-      {
-	// Free the taps if already allocated
-	if(d_aligned_taps != NULL) {
-	  for(int i = 0; i < d_naligned; i++) {
-	    volk_free(d_aligned_taps[i]);
-	  }
-	  ::free(d_aligned_taps);
-	  d_aligned_taps = NULL;
-	}
-
-	d_ntaps = (int)taps.size();
-	d_taps = taps;
-	std::reverse(d_taps.begin(), d_taps.end());
-
-	// Make a set of taps at all possible arch alignments
-	d_aligned_taps = (gr_complex**)malloc(d_naligned*sizeof(gr_complex*));
-	for(int i = 0; i < d_naligned; i++) {
-          d_aligned_taps[i] = (gr_complex*)volk_malloc((d_ntaps+d_naligned-1)*sizeof(gr_complex), d_align);
-	  memset(d_aligned_taps[i], 0, sizeof(gr_complex)*(d_ntaps+d_naligned-1));
-	  for(unsigned int j = 0; j < d_ntaps; j++)
-	    d_aligned_taps[i][i+j] = d_taps[j];
-	}
-      }
-
-      void
-      fir_filter_scc::update_tap(gr_complex t, unsigned int index)
-      {
-	d_taps[index] = t;
-	for(int i = 0; i < d_naligned; i++) {
-	  d_aligned_taps[i][i+index] = t;
-	}
-      }
-
-      std::vector<gr_complex>
-      fir_filter_scc::taps() const
-      {
-	std::vector<gr_complex> t = d_taps;
-	std::reverse(t.begin(), t.end());
-	return t;
-      }
-
-      unsigned int
-      fir_filter_scc::ntaps() const
-      {
-	return d_ntaps;
-      }
-
-      gr_complex
-      fir_filter_scc::filter(const short input[])
-      {
-	const short *ar = (short *)((size_t) input & ~(d_align-1));
-	unsigned al = input - ar;
-
-	volk_16i_32fc_dot_prod_32fc_a(d_output, ar,
-				      d_aligned_taps[al],
-				      (d_ntaps+al));
-
-	return *d_output;
-      }
-
-      void
-      fir_filter_scc::filterN(gr_complex output[],
-			      const short input[],
-			      unsigned long n)
-      {
-	for(unsigned long i = 0; i < n; i++)
-	  output[i] = filter(&input[i]);
-      }
-
-
-      void
-      fir_filter_scc::filterNdec(gr_complex output[],
-				 const short input[],
-				 unsigned long n,
-				 unsigned int decimate)
-      {
-	unsigned long j = 0;
-	for(unsigned long i = 0; i < n; i++){
-	  output[i] = filter(&input[j]);
-	  j += decimate;
-	}
-      }
-
-      /**************************************************************/
-
-      fir_filter_fsf::fir_filter_fsf(int decimation,
-				     const std::vector<float> &taps)
-      {
-	d_align = volk_get_alignment();
-	d_naligned = std::max((size_t)1, d_align / sizeof(float));
-
-	d_aligned_taps = NULL;
-	set_taps(taps);
-
-	// Make sure the output sample is always aligned, too.
-	d_output = (short*)volk_malloc(1*sizeof(short), d_align);
-      }
-
-      fir_filter_fsf::~fir_filter_fsf()
-      {
-      	// Free all aligned taps
-	if(d_aligned_taps != NULL) {
-	  for(int i = 0; i < d_naligned; i++) {
-	    volk_free(d_aligned_taps[i]);
-	  }
-	  ::free(d_aligned_taps);
-	  d_aligned_taps = NULL;
-	}
-
-	// Free output sample
-	volk_free(d_output);
-      }
-
-      void
-      fir_filter_fsf::set_taps(const std::vector<float> &taps)
-      {
-	// Free the taps if already allocated
-	if(d_aligned_taps != NULL) {
-	  for(int i = 0; i < d_naligned; i++) {
-	    volk_free(d_aligned_taps[i]);
-	  }
-	  ::free(d_aligned_taps);
-	  d_aligned_taps = NULL;
-	}
-
-	d_ntaps = (int)taps.size();
-	d_taps = taps;
-	std::reverse(d_taps.begin(), d_taps.end());
-
-	// Make a set of taps at all possible arch alignments
-	d_aligned_taps = (float**)malloc(d_naligned*sizeof(float*));
-	for(int i = 0; i < d_naligned; i++) {
-          d_aligned_taps[i] = (float*)volk_malloc((d_ntaps+d_naligned-1)*sizeof(float), d_align);
-	  memset(d_aligned_taps[i], 0, sizeof(float)*(d_ntaps+d_naligned-1));
-	  for(unsigned int j = 0; j < d_ntaps; j++)
-	    d_aligned_taps[i][i+j] = d_taps[j];
-	}
-      }
-
-      void
-      fir_filter_fsf::update_tap(float t, unsigned int index)
-      {
-	d_taps[index] = t;
-	for(int i = 0; i < d_naligned; i++) {
-	  d_aligned_taps[i][i+index] = t;
-	}
-      }
-
-      std::vector<float>
-      fir_filter_fsf::taps() const
-      {
-	std::vector<float> t = d_taps;
-	std::reverse(t.begin(), t.end());
-	return t;
-      }
-
-      unsigned int
-      fir_filter_fsf::ntaps() const
-      {
-	return d_ntaps;
-      }
-
-      short
-      fir_filter_fsf::filter(const float input[])
-      {
-	const float *ar = (float *)((size_t) input & ~(d_align-1));
-	unsigned al = input - ar;
-
-	volk_32f_x2_dot_prod_16i_a(d_output, ar,
-				   d_aligned_taps[al],
-				   (d_ntaps+al));
-
-	return *d_output;
-      }
-
-      void
-      fir_filter_fsf::filterN(short output[],
-			      const float input[],
-			      unsigned long n)
-      {
-	for(unsigned long i = 0; i < n; i++)
-	  output[i] = filter(&input[i]);
-      }
-
-      void
-      fir_filter_fsf::filterNdec(short output[],
-				 const float input[],
-				 unsigned long n,
-				 unsigned int decimate)
-      {
-	unsigned long j = 0;
-	for(unsigned long i = 0; i < n; i++){
-	  output[i] = filter(&input[j]);
-	  j += decimate;
-	}
-      }
-
-    } /* namespace kernel */
-  } /* namespace filter */
+namespace filter {
+namespace kernel {
+
+template <class IN_T, class OUT_T, class TAP_T>
+fir_filter<IN_T, OUT_T, TAP_T>::fir_filter(int decimation, const std::vector<TAP_T>& taps) {
+    d_align = volk_get_alignment();
+    d_naligned = std::max((size_t)1, d_align / sizeof(IN_T));
+
+    d_aligned_taps = NULL;
+    set_taps(taps);
+
+    // Make sure the output sample is always aligned, too.
+    d_output = (OUT_T*)volk_malloc(1 * sizeof(OUT_T), d_align);
+}
+
+template <class IN_T, class OUT_T, class TAP_T>
+fir_filter<IN_T, OUT_T, TAP_T>::~fir_filter() {
+    // Free all aligned taps
+    if (d_aligned_taps != NULL) {
+        for (int i = 0; i < d_naligned; i++) {
+            volk_free(d_aligned_taps[i]);
+        }
+        ::free(d_aligned_taps);
+        d_aligned_taps = NULL;
+    }
+
+    // Free output sample
+    volk_free(d_output);
+}
+
+template <class IN_T, class OUT_T, class TAP_T>
+void fir_filter<IN_T, OUT_T, TAP_T>::set_taps(const std::vector<TAP_T>& taps) {
+    // Free the taps if already allocated
+    if (d_aligned_taps != NULL) {
+        for (int i = 0; i < d_naligned; i++) {
+            volk_free(d_aligned_taps[i]);
+        }
+        ::free(d_aligned_taps);
+        d_aligned_taps = NULL;
+    }
+
+    d_ntaps = (int)taps.size();
+    d_taps = taps;
+    std::reverse(d_taps.begin(), d_taps.end());
+
+    // Make a set of taps at all possible arch alignments
+    d_aligned_taps = (TAP_T**)malloc(d_naligned * sizeof(TAP_T*));
+    for (int i = 0; i < d_naligned; i++) {
+        d_aligned_taps[i] =
+            (TAP_T*)volk_malloc((d_ntaps + d_naligned - 1) * sizeof(TAP_T), d_align);
+        memset(d_aligned_taps[i], 0, sizeof(TAP_T) * (d_ntaps + d_naligned - 1));
+        for (unsigned int j = 0; j < d_ntaps; j++)
+            d_aligned_taps[i][i + j] = d_taps[j];
+    }
+}
+
+template <class IN_T, class OUT_T, class TAP_T>
+void fir_filter<IN_T, OUT_T, TAP_T>::update_tap(TAP_T t, unsigned int index) {
+    d_taps[index] = t;
+    for (int i = 0; i < d_naligned; i++) {
+        d_aligned_taps[i][i + index] = t;
+    }
+}
+
+template <class IN_T, class OUT_T, class TAP_T>
+std::vector<TAP_T> fir_filter<IN_T, OUT_T, TAP_T>::taps() const {
+    std::vector<TAP_T> t = d_taps;
+    std::reverse(t.begin(), t.end());
+    return t;
+}
+
+template <class IN_T, class OUT_T, class TAP_T>
+unsigned int fir_filter<IN_T, OUT_T, TAP_T>::ntaps() const {
+    return d_ntaps;
+}
+
+template <class IN_T, class OUT_T, class TAP_T>
+void fir_filter<IN_T, OUT_T, TAP_T>::filterN(OUT_T output[], const IN_T input[], unsigned long n) {
+    for (unsigned long i = 0; i < n; i++) {
+        output[i] = filter(&input[i]);
+    }
+}
+
+template <class IN_T, class OUT_T, class TAP_T>
+void fir_filter<IN_T,OUT_T,TAP_T>::filterNdec(OUT_T output[],
+                                const IN_T input[],
+                                unsigned long n,
+                                unsigned int decimate) {
+    unsigned long j = 0;
+    for (unsigned long i = 0; i < n; i++) {
+        output[i] = filter(&input[j]);
+        j += decimate;
+    }
+}
+
+template <>
+float fir_filter<float, float, float>::filter(const float input[]) {
+    const float* ar = (float*)((size_t)input & ~(d_align - 1));
+    unsigned al = input - ar;
+
+    volk_32f_x2_dot_prod_32f_a(d_output, ar, d_aligned_taps[al], d_ntaps + al);
+    return *d_output;
+}
+
+template <>
+gr_complex fir_filter<gr_complex, gr_complex, float>::filter(const gr_complex input[]) {
+    const gr_complex* ar = (gr_complex*)((size_t)input & ~(d_align - 1));
+    unsigned al = input - ar;
+
+    volk_32fc_32f_dot_prod_32fc_a(d_output, ar, d_aligned_taps[al], (d_ntaps + al));
+    return *d_output;
+}
+
+template <>
+gr_complex fir_filter<float, gr_complex, gr_complex>::filter(const float input[]) {
+    const float* ar = (float*)((size_t)input & ~(d_align - 1));
+    unsigned al = input - ar;
+
+    volk_32fc_32f_dot_prod_32fc_a(d_output, d_aligned_taps[al], ar, (d_ntaps + al));
+    return *d_output;
+}
+
+template <>
+gr_complex fir_filter<gr_complex, gr_complex, gr_complex>::filter(const gr_complex input[]) {
+    const gr_complex* ar = (gr_complex*)((size_t)input & ~(d_align - 1));
+    unsigned al = input - ar;
+
+    volk_32fc_x2_dot_prod_32fc_a(d_output, ar, d_aligned_taps[al], (d_ntaps + al));
+    return *d_output;
+}
+
+template <>
+gr_complex fir_filter<std::int16_t, gr_complex, gr_complex>::filter(const std::int16_t input[]) {
+    const std::int16_t* ar = (std::int16_t*)((size_t)input & ~(d_align - 1));
+    unsigned al = input - ar;
+
+    volk_16i_32fc_dot_prod_32fc_a(d_output, ar, d_aligned_taps[al], (d_ntaps + al));
+
+    return *d_output;
+}
+
+template <>
+short fir_filter<float, std::int16_t, float>::filter(const float input[]) {
+    const float* ar = (float*)((size_t)input & ~(d_align - 1));
+    unsigned al = input - ar;
+
+    volk_32f_x2_dot_prod_16i_a(d_output, ar, d_aligned_taps[al], (d_ntaps + al));
+
+    return *d_output;
+}
+  template class fir_filter<float, float, float>;
+  template class fir_filter<gr_complex, gr_complex, float>;
+  template class fir_filter<float, gr_complex, gr_complex>;
+  template class fir_filter<gr_complex, gr_complex, gr_complex>;
+  template class fir_filter<std::int16_t, gr_complex, gr_complex>;
+  template class fir_filter<float, std::int16_t, float>;
+} /* namespace kernel */
+} /* namespace filter */
 } /* namespace gr */
diff --git a/gr-filter/lib/fir_filter_XXX_impl.cc.t b/gr-filter/lib/fir_filter_XXX_impl.cc.t
deleted file mode 100644
index 4a112a2180..0000000000
--- a/gr-filter/lib/fir_filter_XXX_impl.cc.t
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@IMPL_NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <volk/volk.h>
-
-namespace gr {
-  namespace filter {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(int decimation, const std::vector<@TAP_TYPE@> &taps)
-    {
-      return gnuradio::get_initial_sptr(new @IMPL_NAME@
-					(decimation, taps));
-    }
-
-
-    @IMPL_NAME@::@IMPL_NAME@(int decimation, const std::vector<@TAP_TYPE@> &taps)
-      : sync_decimator("@BASE_NAME@",
-			  io_signature::make(1, 1, sizeof(@I_TYPE@)),
-			  io_signature::make(1, 1, sizeof(@O_TYPE@)),
-			  decimation)
-    {
-      d_fir = new kernel::@BASE_NAME@(decimation, taps);
-      d_updated = false;
-      set_history(d_fir->ntaps());
-
-      const int alignment_multiple =
-	volk_get_alignment() / sizeof(float);
-      set_alignment(std::max(1, alignment_multiple));
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-      delete d_fir;
-    }
-
-    void
-    @IMPL_NAME@::set_taps(const std::vector<@TAP_TYPE@> &taps)
-    {
-      gr::thread::scoped_lock l(d_setlock);
-      d_fir->set_taps(taps);
-      d_updated = true;
-    }
-
-    std::vector<@TAP_TYPE@>
-    @IMPL_NAME@::taps() const
-    {
-      return d_fir->taps();
-    }
-
-    int
-    @IMPL_NAME@::work(int noutput_items,
-		      gr_vector_const_void_star &input_items,
-		      gr_vector_void_star &output_items)
-    {
-      gr::thread::scoped_lock l(d_setlock);
-
-      const @I_TYPE@ *in = (const @I_TYPE@*)input_items[0];
-      @O_TYPE@ *out = (@O_TYPE@*)output_items[0];
-
-      if (d_updated) {
-	set_history(d_fir->ntaps());
-	d_updated = false;
-	return 0;	     // history requirements may have changed.
-      }
-
-      if (decimation() == 1) {
-	d_fir->filterN(out, in, noutput_items);
-      }
-      else {
-	d_fir->filterNdec(out, in, noutput_items,
-			  decimation());
-      }
-
-      return noutput_items;
-    }
-
-  } /* namespace filter */
-} /* namespace gr */
-
diff --git a/gr-filter/lib/fir_filter_XXX_impl.h.t b/gr-filter/lib/fir_filter_XXX_impl.h.t
deleted file mode 100644
index 3678d82acb..0000000000
--- a/gr-filter/lib/fir_filter_XXX_impl.h.t
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifndef @GUARD_NAME@
-#define	@GUARD_NAME@
-
-#include <gnuradio/filter/fir_filter.h>
-#include <gnuradio/filter/@BASE_NAME@.h>
-
-namespace gr {
-  namespace filter {
-
-    class FILTER_API @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      kernel::@BASE_NAME@ *d_fir;
-      bool d_updated;
-
-    public:
-      @IMPL_NAME@(int decimation, const std::vector<@TAP_TYPE@> &taps);
-
-      ~@IMPL_NAME@();
-
-      void set_taps(const std::vector<@TAP_TYPE@> &taps);
-      std::vector<@TAP_TYPE@> taps() const;
-
-      int work(int noutput_items,
-	       gr_vector_const_void_star &input_items,
-	       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace filter */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/lib/fir_filter_blk_impl.cc b/gr-filter/lib/fir_filter_blk_impl.cc
new file mode 100644
index 0000000000..2ffa62e596
--- /dev/null
+++ b/gr-filter/lib/fir_filter_blk_impl.cc
@@ -0,0 +1,115 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "fir_filter_blk_impl.h"
+#include <gnuradio/io_signature.h>
+#include <volk/volk.h>
+
+namespace gr {
+  namespace filter {
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    typename fir_filter_blk<IN_T,OUT_T,TAP_T>::sptr
+    fir_filter_blk<IN_T,OUT_T,TAP_T>::make(int decimation, const std::vector<TAP_T> &taps)
+    {
+      return gnuradio::get_initial_sptr(new fir_filter_blk_impl<IN_T,OUT_T,TAP_T>
+					(decimation, taps));
+    }
+
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    fir_filter_blk_impl<IN_T,OUT_T,TAP_T>::fir_filter_blk_impl(int decimation, const std::vector<TAP_T> &taps)
+      : sync_decimator("fir_filter_blk<IN_T,OUT_T,TAP_T>",
+			  io_signature::make(1, 1, sizeof(IN_T)),
+			  io_signature::make(1, 1, sizeof(OUT_T)),
+			  decimation)
+    {
+      d_fir = new kernel::fir_filter<IN_T,OUT_T,TAP_T>(decimation, taps);
+      d_updated = false;
+      this->set_history(d_fir->ntaps());
+
+      const int alignment_multiple =
+	volk_get_alignment() / sizeof(float);
+      this->set_alignment(std::max(1, alignment_multiple));
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    fir_filter_blk_impl<IN_T,OUT_T,TAP_T>::~fir_filter_blk_impl()
+    {
+      delete d_fir;
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    void
+    fir_filter_blk_impl<IN_T,OUT_T,TAP_T>::set_taps(const std::vector<TAP_T> &taps)
+    {
+      gr::thread::scoped_lock l(this->d_setlock);
+      d_fir->set_taps(taps);
+      d_updated = true;
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    std::vector<TAP_T>
+    fir_filter_blk_impl<IN_T,OUT_T,TAP_T>::taps() const
+    {
+      return d_fir->taps();
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    int
+    fir_filter_blk_impl<IN_T,OUT_T,TAP_T>::work(int noutput_items,
+		      gr_vector_const_void_star &input_items,
+		      gr_vector_void_star &output_items)
+    {
+      gr::thread::scoped_lock l(this->d_setlock);
+
+      const IN_T *in = (const IN_T*)input_items[0];
+      OUT_T *out = (OUT_T*)output_items[0];
+
+      if (d_updated) {
+	this->set_history(d_fir->ntaps());
+	d_updated = false;
+	return 0;	     // history requirements may have changed.
+      }
+
+      if (this->decimation() == 1) {
+	d_fir->filterN(out, in, noutput_items);
+      }
+      else {
+	d_fir->filterNdec(out, in, noutput_items,
+			  this->decimation());
+      }
+
+      return noutput_items;
+    }
+    template class fir_filter_blk<gr_complex, gr_complex, gr_complex>;
+    template class fir_filter_blk<gr_complex, gr_complex, float>;
+    template class fir_filter_blk<float, gr_complex, gr_complex>;
+    template class fir_filter_blk<float, float, float>;
+    template class fir_filter_blk<float, std::int16_t, float>;
+    template class fir_filter_blk<std::int16_t, gr_complex, gr_complex>;
+  } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/fir_filter_blk_impl.h b/gr-filter/lib/fir_filter_blk_impl.h
new file mode 100644
index 0000000000..03faaebf26
--- /dev/null
+++ b/gr-filter/lib/fir_filter_blk_impl.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FIR_FILTER_BLK_IMPL_H
+#define	FIR_FILTER_BLK_IMPL_H
+
+#include <gnuradio/filter/fir_filter.h>
+#include <gnuradio/filter/fir_filter_blk.h>
+
+namespace gr {
+  namespace filter {
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    class FILTER_API fir_filter_blk_impl : public fir_filter_blk<IN_T, OUT_T, TAP_T>
+    {
+    private:
+      kernel::fir_filter<IN_T, OUT_T, TAP_T> *d_fir;
+      bool d_updated;
+
+    public:
+      fir_filter_blk_impl(int decimation, const std::vector<TAP_T> &taps);
+
+      ~fir_filter_blk_impl();
+
+      void set_taps(const std::vector<TAP_T> &taps);
+      std::vector<TAP_T> taps() const;
+
+      int work(int noutput_items,
+	       gr_vector_const_void_star &input_items,
+	       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace filter */
+} /* namespace gr */
+
+#endif /* FIR_FILTER_BLK_IMPL_H */
diff --git a/gr-filter/lib/freq_xlating_fir_filter_XXX_impl.cc.t b/gr-filter/lib/freq_xlating_fir_filter_XXX_impl.cc.t
deleted file mode 100644
index fc6ede2bb5..0000000000
--- a/gr-filter/lib/freq_xlating_fir_filter_XXX_impl.cc.t
+++ /dev/null
@@ -1,178 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,2010,2012,2018 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/*
- * WARNING: This file is automatically generated by cmake.
- * Any changes made to this file will be overwritten.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@IMPL_NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <gnuradio/math.h>
-#include <volk/volk.h>
-
-namespace gr {
-  namespace filter {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(int decimation,
-		      const std::vector<@TAP_TYPE@> &taps,
-		      double center_freq,
-		      double sampling_freq)
-    {
-      return gnuradio::get_initial_sptr(new @IMPL_NAME@
-					(decimation, taps,
-					 center_freq,
-					 sampling_freq));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(int decimation,
-			     const std::vector<@TAP_TYPE@> &taps,
-			     double center_freq,
-			     double sampling_freq)
-    : sync_decimator("@BASE_NAME@",
-			io_signature::make(1, 1, sizeof(@I_TYPE@)),
-			io_signature::make(1, 1, sizeof(@O_TYPE@)),
-			decimation),
-      d_proto_taps(taps), d_center_freq(center_freq),
-      d_sampling_freq(sampling_freq),
-      d_updated(false)
-    {
-      std::vector<gr_complex> dummy_taps;
-      d_composite_fir = new kernel::@CFIR_TYPE@(decimation, dummy_taps);
-
-      set_history(d_proto_taps.size());
-      build_composite_fir();
-
-      message_port_register_in(pmt::mp("freq"));
-      set_msg_handler(pmt::mp("freq"),
-                      boost::bind(&@IMPL_NAME@::handle_set_center_freq,
-                                  this, _1));
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-      delete d_composite_fir;
-    }
-
-    void
-    @IMPL_NAME@::build_composite_fir()
-    {
-      std::vector<gr_complex> ctaps(d_proto_taps.size());
-
-      // The basic principle of this block is to perform:
-      //    x(t) -> (mult by -fwT0) -> LPF -> decim -> y(t)
-      // We switch things up here to:
-      //    x(t) -> BPF -> decim -> (mult by fwT0*decim) -> y(t)
-      // The BPF is the baseband filter (LPF) moved up to the
-      // center frequency fwT0. We then apply a derotator
-      // with -fwT0 to downshift the signal to baseband.
-
-      float fwT0 = 2 * GR_M_PI * d_center_freq / d_sampling_freq;
-      for(unsigned int i = 0; i < d_proto_taps.size(); i++) {
-	ctaps[i] = d_proto_taps[i] * exp(gr_complex(0, i * fwT0));
-      }
-
-      d_composite_fir->set_taps(ctaps);
-      d_r.set_phase_incr(exp(gr_complex(0, -fwT0 * decimation())));
-    }
-
-    void
-    @IMPL_NAME@::set_center_freq(double center_freq)
-    {
-      d_center_freq = center_freq;
-      d_updated = true;
-    }
-
-    double
-    @IMPL_NAME@::center_freq() const
-    {
-      return d_center_freq;
-    }
-
-    void
-    @IMPL_NAME@::set_taps(const std::vector<@TAP_TYPE@> &taps)
-    {
-      d_proto_taps = taps;
-      d_updated = true;
-    }
-
-    std::vector<@TAP_TYPE@>
-    @IMPL_NAME@::taps() const
-    {
-      return d_proto_taps;
-    }
-
-    void
-    @IMPL_NAME@::handle_set_center_freq(pmt::pmt_t msg)
-    {
-      if(pmt::is_dict(msg) && pmt::dict_has_key(msg, pmt::intern("freq")) ) {
-        pmt::pmt_t x = pmt::dict_ref(msg, pmt::intern("freq"), pmt::PMT_NIL );
-        if(pmt::is_real(x)) {
-          double freq = pmt::to_double(x);
-          set_center_freq(freq);
-        }
-      } else if(pmt::is_pair(msg)) {
-        pmt::pmt_t x = pmt::cdr(msg);
-        if(pmt::is_real(x)) {
-          double freq = pmt::to_double(x);
-          set_center_freq(freq);
-        }
-      }
-    }
-
-    int
-    @IMPL_NAME@::work(int noutput_items,
-		      gr_vector_const_void_star &input_items,
-		      gr_vector_void_star &output_items)
-    {
-      @I_TYPE@ *in  = (@I_TYPE@ *)input_items[0];
-      @O_TYPE@ *out = (@O_TYPE@ *)output_items[0];
-
-      // rebuild composite FIR if the center freq has changed
-      if(d_updated) {
-	set_history(d_proto_taps.size());
-	build_composite_fir();
-	d_updated = false;
-
-        // Tell downstream items where the frequency change was applied
-        add_item_tag(0, nitems_written(0),
-                     pmt::intern("freq"), pmt::from_double(d_center_freq),
-                     alias_pmt());
-	return 0;		     // history requirements may have changed.
-      }
-
-      unsigned j = 0;
-      for (int i = 0; i < noutput_items; i++){
-        out[i] = d_r.rotate(d_composite_fir->filter(&in[j]));
-        j += decimation();
-      }
-
-      return noutput_items;
-    }
-
-  } /* namespace filter */
-} /* namespace gr */
diff --git a/gr-filter/lib/freq_xlating_fir_filter_XXX_impl.h.t b/gr-filter/lib/freq_xlating_fir_filter_XXX_impl.h.t
deleted file mode 100644
index bd7aced6f8..0000000000
--- a/gr-filter/lib/freq_xlating_fir_filter_XXX_impl.h.t
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2002,2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/*
- * WARNING: This file is automatically generated by cmake.
- * Any changes made to this file will be overwritten.
- */
-
-#ifndef @GUARD_NAME@
-#define	@GUARD_NAME@
-
-#include <gnuradio/filter/api.h>
-#include <gnuradio/filter/fir_filter.h>
-#include <gnuradio/filter/@BASE_NAME@.h>
-#include <gnuradio/blocks/rotator.h>
-
-namespace gr {
-  namespace filter {
-
-    class FILTER_API @IMPL_NAME@ : public @BASE_NAME@
-    {
-    protected:
-      std::vector<@TAP_TYPE@>	d_proto_taps;
-      kernel::@CFIR_TYPE@      *d_composite_fir;
-      blocks::rotator		d_r;
-      double			d_center_freq;
-      double			d_sampling_freq;
-      bool			d_updated;
-
-      virtual void build_composite_fir();
-    public:
-
-      @IMPL_NAME@(int decimation,
-		  const std::vector<@TAP_TYPE@> &taps,
-		  double center_freq,
-		  double sampling_freq);
-      virtual ~@IMPL_NAME@();
-
-      void set_center_freq(double center_freq);
-      double center_freq() const;
-
-      void set_taps(const std::vector<@TAP_TYPE@> &taps);
-      std::vector<@TAP_TYPE@> taps() const;
-
-      void handle_set_center_freq(pmt::pmt_t msg);
-
-      int work(int noutput_items,
-	       gr_vector_const_void_star &input_items,
-	       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace filter */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/lib/freq_xlating_fir_filter_impl.cc b/gr-filter/lib/freq_xlating_fir_filter_impl.cc
new file mode 100644
index 0000000000..5a858c3d10
--- /dev/null
+++ b/gr-filter/lib/freq_xlating_fir_filter_impl.cc
@@ -0,0 +1,190 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "freq_xlating_fir_filter_impl.h"
+#include <gnuradio/io_signature.h>
+#include <gnuradio/math.h>
+#include <volk/volk.h>
+
+namespace gr {
+  namespace filter {
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    typename freq_xlating_fir_filter<IN_T,OUT_T,TAP_T>::sptr
+    freq_xlating_fir_filter<IN_T,OUT_T,TAP_T>::make(int decimation,
+		      const std::vector<TAP_T> &taps,
+		      double center_freq,
+		      double sampling_freq)
+    {
+      return gnuradio::get_initial_sptr(new freq_xlating_fir_filter_impl<IN_T,OUT_T,TAP_T>
+					(decimation, taps,
+					 center_freq,
+					 sampling_freq));
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    freq_xlating_fir_filter_impl<IN_T,OUT_T,TAP_T>::freq_xlating_fir_filter_impl(int decimation,
+			     const std::vector<TAP_T> &taps,
+			     double center_freq,
+			     double sampling_freq)
+    : sync_decimator("freq_xlating_fir_filter<IN_T,OUT_T,TAP_T>",
+			io_signature::make(1, 1, sizeof(IN_T)),
+			io_signature::make(1, 1, sizeof(OUT_T)),
+			decimation),
+      d_proto_taps(taps), d_center_freq(center_freq),
+      d_sampling_freq(sampling_freq),
+      d_updated(false)
+    {
+      std::vector<gr_complex> dummy_taps;
+      d_composite_fir = new kernel::fir_filter<IN_T,OUT_T,gr_complex>(decimation, dummy_taps);
+
+      this->set_history(this->d_proto_taps.size());
+      this->build_composite_fir();
+
+      this->message_port_register_in(pmt::mp("freq"));
+      this->set_msg_handler(pmt::mp("freq"),
+                      boost::bind(&freq_xlating_fir_filter_impl<IN_T,OUT_T,TAP_T>::handle_set_center_freq,
+                                  this, _1));
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    freq_xlating_fir_filter_impl<IN_T,OUT_T,TAP_T>::~freq_xlating_fir_filter_impl()
+    {
+      delete d_composite_fir;
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    void
+    freq_xlating_fir_filter_impl<IN_T,OUT_T,TAP_T>::build_composite_fir()
+    {
+      std::vector<gr_complex> ctaps(d_proto_taps.size());
+
+      // The basic principle of this block is to perform:
+      //    x(t) -> (mult by -fwT0) -> LPF -> decim -> y(t)
+      // We switch things up here to:
+      //    x(t) -> BPF -> decim -> (mult by fwT0*decim) -> y(t)
+      // The BPF is the baseband filter (LPF) moved up to the
+      // center frequency fwT0. We then apply a derotator
+      // with -fwT0 to downshift the signal to baseband.
+
+      float fwT0 = 2 * GR_M_PI * d_center_freq / d_sampling_freq;
+      for(unsigned int i = 0; i < d_proto_taps.size(); i++) {
+	ctaps[i] = d_proto_taps[i] * exp(gr_complex(0, i * fwT0));
+      }
+
+      d_composite_fir->set_taps(ctaps);
+      d_r.set_phase_incr(exp(gr_complex(0, -fwT0 * this->decimation())));
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    void
+    freq_xlating_fir_filter_impl<IN_T,OUT_T,TAP_T>::set_center_freq(double center_freq)
+    {
+      d_center_freq = center_freq;
+      d_updated = true;
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    double
+    freq_xlating_fir_filter_impl<IN_T,OUT_T,TAP_T>::center_freq() const
+    {
+      return d_center_freq;
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    void
+    freq_xlating_fir_filter_impl<IN_T,OUT_T,TAP_T>::set_taps(const std::vector<TAP_T> &taps)
+    {
+      d_proto_taps = taps;
+      d_updated = true;
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    std::vector<TAP_T>
+    freq_xlating_fir_filter_impl<IN_T,OUT_T,TAP_T>::taps() const
+    {
+      return d_proto_taps;
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    void
+    freq_xlating_fir_filter_impl<IN_T,OUT_T,TAP_T>::handle_set_center_freq(pmt::pmt_t msg)
+    {
+      if(pmt::is_dict(msg) && pmt::dict_has_key(msg, pmt::intern("freq")) ) {
+        pmt::pmt_t x = pmt::dict_ref(msg, pmt::intern("freq"), pmt::PMT_NIL );
+        if(pmt::is_real(x)) {
+          double freq = pmt::to_double(x);
+          set_center_freq(freq);
+        }
+      } else if(pmt::is_pair(msg)) {
+        pmt::pmt_t x = pmt::cdr(msg);
+        if(pmt::is_real(x)) {
+          double freq = pmt::to_double(x);
+          set_center_freq(freq);
+        }
+      }
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    int
+    freq_xlating_fir_filter_impl<IN_T,OUT_T,TAP_T>::work(int noutput_items,
+		      gr_vector_const_void_star &input_items,
+		      gr_vector_void_star &output_items)
+    {
+      IN_T *in  = (IN_T *)input_items[0];
+      OUT_T *out = (OUT_T *)output_items[0];
+
+      // rebuild composite FIR if the center freq has changed
+      if(d_updated) {
+	this->set_history(d_proto_taps.size());
+	build_composite_fir();
+	d_updated = false;
+
+        // Tell downstream items where the frequency change was applied
+        this->add_item_tag(0, this->nitems_written(0),
+                     pmt::intern("freq"), pmt::from_double(d_center_freq),
+                     this->alias_pmt());
+	return 0;		     // history requirements may have changed.
+      }
+
+      unsigned j = 0;
+      for (int i = 0; i < noutput_items; i++){
+        out[i] = d_r.rotate(d_composite_fir->filter(&in[j]));
+        j += this->decimation();
+      }
+
+      return noutput_items;
+    }
+
+    template class freq_xlating_fir_filter<gr_complex, gr_complex, gr_complex>;
+    template class freq_xlating_fir_filter<gr_complex, gr_complex, float>;
+    template class freq_xlating_fir_filter<float, gr_complex, gr_complex>;
+    template class freq_xlating_fir_filter<float, gr_complex, float>;
+    template class freq_xlating_fir_filter<std::int16_t, gr_complex, float>;
+    template class freq_xlating_fir_filter<std::int16_t, gr_complex, gr_complex>;
+
+  } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/freq_xlating_fir_filter_impl.h b/gr-filter/lib/freq_xlating_fir_filter_impl.h
new file mode 100644
index 0000000000..176b57f93b
--- /dev/null
+++ b/gr-filter/lib/freq_xlating_fir_filter_impl.h
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FREQ_XLATING_FIR_FILTER_IMPL_H
+#define	FREQ_XLATING_FIR_FILTER_IMPL_H
+
+#include <gnuradio/filter/api.h>
+#include <gnuradio/filter/fir_filter.h>
+#include <gnuradio/filter/freq_xlating_fir_filter.h>
+#include <gnuradio/blocks/rotator.h>
+
+namespace gr {
+  namespace filter {
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    class FILTER_API freq_xlating_fir_filter_impl : public freq_xlating_fir_filter<IN_T,OUT_T,TAP_T>
+    {
+    protected:
+      std::vector<TAP_T>	d_proto_taps;
+      kernel::fir_filter<IN_T, OUT_T, gr_complex>      *d_composite_fir;
+      blocks::rotator		d_r;
+      double			d_center_freq;
+      double			d_sampling_freq;
+      bool			d_updated;
+
+      virtual void build_composite_fir();
+    public:
+
+      freq_xlating_fir_filter_impl(int decimation,
+		  const std::vector<TAP_T> &taps,
+		  double center_freq,
+		  double sampling_freq);
+      virtual ~freq_xlating_fir_filter_impl();
+
+      void set_center_freq(double center_freq);
+      double center_freq() const;
+
+      void set_taps(const std::vector<TAP_T> &taps);
+      std::vector<TAP_T> taps() const;
+
+      void handle_set_center_freq(pmt::pmt_t msg);
+
+      int work(int noutput_items,
+	       gr_vector_const_void_star &input_items,
+	       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace filter */
+} /* namespace gr */
+
+#endif /* FREQ_XLATING_FIR_FILTER_IMPL_H */
diff --git a/gr-filter/lib/interp_fir_filter_XXX_impl.cc.t b/gr-filter/lib/interp_fir_filter_XXX_impl.cc.t
deleted file mode 100644
index 507322b21d..0000000000
--- a/gr-filter/lib/interp_fir_filter_XXX_impl.cc.t
+++ /dev/null
@@ -1,155 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@IMPL_NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <volk/volk.h>
-#include <stdexcept>
-
-namespace gr {
-  namespace filter {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(unsigned interpolation,
-		      const std::vector<@TAP_TYPE@> &taps)
-    {
-      return gnuradio::get_initial_sptr(new @IMPL_NAME@
-					(interpolation, taps));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(unsigned interpolation,
-			     const std::vector<@TAP_TYPE@> &taps)
-    : sync_interpolator("@BASE_NAME@",
-			   io_signature::make(1, 1, sizeof(@I_TYPE@)),
-			   io_signature::make(1, 1, sizeof(@O_TYPE@)),
-			   interpolation),
-      d_updated(false), d_firs(interpolation)
-    {
-      if(interpolation == 0) {
-	throw std::out_of_range("@IMPL_NAME@: interpolation must be > 0\n");
-      }
-
-      if(taps.size() == 0) {
-	throw std::runtime_error("@IMPL_NAME@: no filter taps provided.\n");
-      }
-
-      std::vector<@TAP_TYPE@> dummy_taps;
-
-      for(unsigned i = 0; i < interpolation; i++) {
-	d_firs[i] = new kernel::@FIR_TYPE@(1, dummy_taps);
-      }
-
-      set_taps(taps);
-      install_taps(d_new_taps);
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-      for(unsigned i = 0; i < interpolation(); i++) {
-	delete d_firs[i];
-      }
-    }
-
-    void
-    @IMPL_NAME@::set_taps(const std::vector<@TAP_TYPE@> &taps)
-    {
-      d_new_taps = taps;
-      d_updated = true;
-
-      // round up length to a multiple of the interpolation factor
-      int n = taps.size() % interpolation();
-      if(n > 0) {
-	n = interpolation() - n;
-	while(n-- > 0) {
-	  d_new_taps.insert(d_new_taps.end(), 0);
-	}
-      }
-
-      if(d_new_taps.size() % interpolation() != 0) {
-	throw std::runtime_error("@IMPL_NAME@: error setting interpolator taps.\n");
-      }
-    }
-
-    void
-    @IMPL_NAME@::install_taps(const std::vector<@TAP_TYPE@> &taps)
-    {
-      unsigned nfilters = interpolation();
-      int nt = taps.size() / nfilters;
-
-      std::vector< std::vector <@TAP_TYPE@> > xtaps(nfilters);
-
-      for(unsigned n = 0; n < nfilters; n++) {
-	xtaps[n].resize (nt);
-      }
-
-      for(size_t i = 0; i < taps.size(); i++) {
-	xtaps[i % nfilters][i / nfilters] = taps[i];
-      }
-
-      for(unsigned n = 0; n < nfilters; n++) {
-	d_firs[n]->set_taps (xtaps[n]);
-      }
-
-      set_history(nt);
-      d_updated = false;
-    }
-
-    std::vector<@TAP_TYPE@>
-    @IMPL_NAME@::taps() const
-    {
-      return d_new_taps;
-    }
-
-    int
-    @NAME@::work(int noutput_items,
-		 gr_vector_const_void_star &input_items,
-		 gr_vector_void_star &output_items)
-    {
-      const @I_TYPE@ *in = (const @I_TYPE@ *)input_items[0];
-      @O_TYPE@ *out = (@O_TYPE@ *)output_items[0];
-
-      if(d_updated) {
-	install_taps(d_new_taps);
-	return 0;	     // history requirements may have changed.
-      }
-
-      int nfilters = interpolation();
-      int ni = noutput_items / interpolation();
-
-      for(int i = 0; i < ni; i++) {
-	for(int nf = 0; nf < nfilters; nf++) {
-	  out[nf] = d_firs[nf]->filter(&in[i]);
-	}
-	out += nfilters;
-      }
-
-      return noutput_items;
-    }
-
-  } /* namespace filter */
-} /* namespace gr */
diff --git a/gr-filter/lib/interp_fir_filter_XXX_impl.h.t b/gr-filter/lib/interp_fir_filter_XXX_impl.h.t
deleted file mode 100644
index 0e39de613c..0000000000
--- a/gr-filter/lib/interp_fir_filter_XXX_impl.h.t
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifndef @GUARD_NAME@
-#define	@GUARD_NAME@
-
-#include <gnuradio/filter/api.h>
-#include <gnuradio/filter/fir_filter.h>
-#include <gnuradio/filter/@BASE_NAME@.h>
-#include <vector>
-
-namespace gr {
-  namespace filter {
-
-    class FILTER_API @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      bool d_updated;
-      std::vector<kernel::@FIR_TYPE@ *> d_firs;
-      std::vector<@TAP_TYPE@> d_new_taps;
-
-      void install_taps(const std::vector<@TAP_TYPE@> &taps);
-
-    public:
-      @IMPL_NAME@(unsigned interpolation,
-		  const std::vector<@TAP_TYPE@> &taps);
-
-      ~@IMPL_NAME@();
-
-      void set_taps(const std::vector<@TAP_TYPE@> &taps);
-      std::vector<@TAP_TYPE@> taps() const;
-
-      int work(int noutput_items,
-	       gr_vector_const_void_star &input_items,
-	       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace filter */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/lib/interp_fir_filter_impl.cc b/gr-filter/lib/interp_fir_filter_impl.cc
new file mode 100644
index 0000000000..a7020ce653
--- /dev/null
+++ b/gr-filter/lib/interp_fir_filter_impl.cc
@@ -0,0 +1,167 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "interp_fir_filter_impl.h"
+#include <gnuradio/io_signature.h>
+#include <volk/volk.h>
+#include <stdexcept>
+
+namespace gr {
+  namespace filter {
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    typename interp_fir_filter<IN_T,OUT_T,TAP_T>::sptr
+    interp_fir_filter<IN_T,OUT_T,TAP_T>::make(unsigned interpolation,
+		      const std::vector<TAP_T> &taps)
+    {
+      return gnuradio::get_initial_sptr(new interp_fir_filter_impl<IN_T,OUT_T,TAP_T>
+					(interpolation, taps));
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    interp_fir_filter_impl<IN_T,OUT_T,TAP_T>::interp_fir_filter_impl(unsigned interpolation,
+			     const std::vector<TAP_T> &taps)
+    : sync_interpolator("interp_fir_filter<IN_T,OUT_T,TAP_T>",
+			   io_signature::make(1, 1, sizeof(IN_T)),
+			   io_signature::make(1, 1, sizeof(OUT_T)),
+			   interpolation),
+      d_updated(false), d_firs(interpolation)
+    {
+      if(interpolation == 0) {
+	throw std::out_of_range("interp_fir_filter_impl: interpolation must be > 0\n");
+      }
+
+      if(taps.size() == 0) {
+	throw std::runtime_error("interp_fir_filter_impl: no filter taps provided.\n");
+      }
+
+      std::vector<TAP_T> dummy_taps;
+
+      for(unsigned i = 0; i < interpolation; i++) {
+        d_firs[i] = new kernel::fir_filter<IN_T,OUT_T,TAP_T>(1, dummy_taps);
+      }
+
+      set_taps(taps);
+      install_taps(d_new_taps);
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    interp_fir_filter_impl<IN_T,OUT_T,TAP_T>::~interp_fir_filter_impl()
+    {
+      for(unsigned i = 0; i < this->interpolation(); i++) {
+	delete d_firs[i];
+      }
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    void
+    interp_fir_filter_impl<IN_T,OUT_T,TAP_T>::set_taps(const std::vector<TAP_T> &taps)
+    {
+      d_new_taps = taps;
+      d_updated = true;
+
+      // round up length to a multiple of the interpolation factor
+      int n = taps.size() % this->interpolation();
+      if(n > 0) {
+	n = this->interpolation() - n;
+	while(n-- > 0) {
+	  d_new_taps.insert(d_new_taps.end(), 0);
+	}
+      }
+
+      if(d_new_taps.size() % this->interpolation() != 0) {
+	throw std::runtime_error("interp_fir_filter_impl: error setting interpolator taps.\n");
+      }
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    void
+    interp_fir_filter_impl<IN_T,OUT_T,TAP_T>::install_taps(const std::vector<TAP_T> &taps)
+    {
+      unsigned nfilters = this->interpolation();
+      int nt = taps.size() / nfilters;
+
+      std::vector< std::vector <TAP_T> > xtaps(nfilters);
+
+      for(unsigned n = 0; n < nfilters; n++) {
+	xtaps[n].resize (nt);
+      }
+
+      for(size_t i = 0; i < taps.size(); i++) {
+	xtaps[i % nfilters][i / nfilters] = taps[i];
+      }
+
+      for(unsigned n = 0; n < nfilters; n++) {
+	d_firs[n]->set_taps (xtaps[n]);
+      }
+
+      this->set_history(nt);
+      d_updated = false;
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    std::vector<TAP_T>
+    interp_fir_filter_impl<IN_T,OUT_T,TAP_T>::taps() const
+    {
+      return d_new_taps;
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    int
+    interp_fir_filter_impl<IN_T,OUT_T,TAP_T>::work(int noutput_items,
+		 gr_vector_const_void_star &input_items,
+		 gr_vector_void_star &output_items)
+    {
+      const IN_T *in = (const IN_T *)input_items[0];
+      OUT_T *out = (OUT_T *)output_items[0];
+
+      if(d_updated) {
+	install_taps(d_new_taps);
+	return 0;	     // history requirements may have changed.
+      }
+
+      int nfilters = this->interpolation();
+      int ni = noutput_items / this->interpolation();
+
+      for(int i = 0; i < ni; i++) {
+	for(int nf = 0; nf < nfilters; nf++) {
+	  out[nf] = d_firs[nf]->filter(&in[i]);
+	}
+	out += nfilters;
+      }
+
+      return noutput_items;
+    }
+    template class interp_fir_filter<gr_complex, gr_complex, gr_complex>;
+    template class interp_fir_filter<gr_complex, gr_complex, float>;
+    template class interp_fir_filter<float, gr_complex, gr_complex>;
+    template class interp_fir_filter<float, float, float>;
+    template class interp_fir_filter<float, std::int16_t, float>;
+    template class interp_fir_filter<std::int16_t, gr_complex, gr_complex>;
+
+
+  } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/interp_fir_filter_impl.h b/gr-filter/lib/interp_fir_filter_impl.h
new file mode 100644
index 0000000000..0ebcc19edf
--- /dev/null
+++ b/gr-filter/lib/interp_fir_filter_impl.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INTERP_FIR_FILTER_IMPL_H
+#define	INTERP_FIR_FILTER_IMPL_H
+
+#include <gnuradio/filter/api.h>
+#include <gnuradio/filter/fir_filter.h>
+#include <gnuradio/filter/interp_fir_filter.h>
+#include <vector>
+
+namespace gr {
+  namespace filter {
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    class FILTER_API interp_fir_filter_impl : public interp_fir_filter<IN_T,OUT_T,TAP_T>
+    {
+    private:
+      bool d_updated;
+      std::vector< kernel::fir_filter<IN_T,OUT_T,TAP_T> *> d_firs;
+      std::vector<TAP_T> d_new_taps;
+
+      void install_taps(const std::vector<TAP_T> &taps);
+
+    public:
+      interp_fir_filter_impl(unsigned interpolation,
+		  const std::vector<TAP_T> &taps);
+
+      ~interp_fir_filter_impl();
+
+      void set_taps(const std::vector<TAP_T> &taps);
+      std::vector<TAP_T> taps() const;
+
+      int work(int noutput_items,
+	       gr_vector_const_void_star &input_items,
+	       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INTERP_FIR_FILTER_IMPL_H */
diff --git a/gr-filter/lib/rational_resampler_base_XXX_impl.cc.t b/gr-filter/lib/rational_resampler_base_XXX_impl.cc.t
deleted file mode 100644
index 0b74e60969..0000000000
--- a/gr-filter/lib/rational_resampler_base_XXX_impl.cc.t
+++ /dev/null
@@ -1,176 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@IMPL_NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <volk/volk.h>
-#include <stdexcept>
-
-namespace gr {
-  namespace filter {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(unsigned interpolation,
-		      unsigned decimation,
-		      const std::vector<@TAP_TYPE@> &taps)
-    {
-      return gnuradio::get_initial_sptr
-	(new @IMPL_NAME@(interpolation, decimation, taps));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(unsigned interpolation,
-			     unsigned decimation,
-			     const std::vector<@TAP_TYPE@> &taps)
-    : block("@BASE_NAME@",
-	       io_signature::make(1, 1, sizeof(@I_TYPE@)),
-	       io_signature::make(1, 1, sizeof(@O_TYPE@))),
-      d_history(1),
-      d_interpolation(interpolation),
-      d_decimation(decimation),
-      d_ctr(0),
-      d_firs(interpolation),
-      d_updated(false)
-    {
-      if(interpolation == 0)
-	throw std::out_of_range("@IMPL_NAME@: interpolation must be > 0");
-      if(decimation == 0)
-	throw std::out_of_range("@IMPL_NAME@: decimation must be > 0");
-
-      set_relative_rate(1.0 * interpolation / decimation);
-      set_output_multiple(1);
-
-      std::vector<@TAP_TYPE@> dummy_taps;
-
-      for(unsigned i = 0; i < interpolation; i++) {
-	d_firs[i] = new kernel::@FIR_TYPE@(1, dummy_taps);
-      }
-
-      set_taps(taps);
-      install_taps(d_new_taps);
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-      int interp = interpolation();
-      for(int i = 0; i < interp; i++) {
-	delete d_firs[i];
-      }
-    }
-
-    void
-    @IMPL_NAME@::set_taps(const std::vector<@TAP_TYPE@> &taps)
-    {
-      d_new_taps = taps;
-      d_updated = true;
-
-      // round up length to a multiple of the interpolation factor
-      int n = taps.size() % interpolation();
-      if(n > 0) {
-	n = interpolation() - n;
-	while(n-- > 0) {
-	  d_new_taps.insert(d_new_taps.end(), 0);
-	}
-      }
-
-      assert(d_new_taps.size() % interpolation() == 0);
-    }
-
-    void
-    @IMPL_NAME@::install_taps(const std::vector<@TAP_TYPE@> &taps)
-    {
-      int nfilters = interpolation();
-      int nt = taps.size() / nfilters;
-
-      assert(nt * nfilters == (int) taps.size());
-
-      std::vector< std::vector <@TAP_TYPE@> > xtaps(nfilters);
-
-      for(int n = 0; n < nfilters; n++)
-	xtaps[n].resize (nt);
-
-      for(int i = 0; i < (int)taps.size(); i++)
-	xtaps[i % nfilters][i / nfilters] = taps[i];
-
-      for(int n = 0; n < nfilters; n++)
-	d_firs[n]->set_taps(xtaps[n]);
-
-      set_history(nt);
-      d_updated = false;
-    }
-
-    std::vector<@TAP_TYPE@>
-    @IMPL_NAME@::taps() const
-    {
-      return d_new_taps;
-    }
-
-    void
-    @IMPL_NAME@::forecast(int noutput_items, gr_vector_int &ninput_items_required)
-    {
-      int nreqd = std::max((unsigned)1, (int)((double) (noutput_items+1) * \
-				        decimation() / interpolation()) + history() - 1);
-      unsigned ninputs = ninput_items_required.size();
-      for(unsigned i = 0; i < ninputs; i++)
-	ninput_items_required[i] = nreqd;
-    }
-
-    int
-    @IMPL_NAME@::general_work(int noutput_items,
-			      gr_vector_int &ninput_items,
-			      gr_vector_const_void_star &input_items,
-			      gr_vector_void_star &output_items)
-    {
-      const @I_TYPE@ *in = (const @I_TYPE@ *)input_items[0];
-      @O_TYPE@ *out = (@O_TYPE@ *)output_items[0];
-
-      if(d_updated) {
-	install_taps(d_new_taps);
-	return 0;		// history requirement may have increased.
-      }
-
-      unsigned int ctr = d_ctr;
-      int count = 0;
-
-      int i = 0;
-      while((i < noutput_items) && (count < ninput_items[0])) {
-	out[i++] = d_firs[ctr]->filter(in);
-	ctr += decimation();
-	while(ctr >= interpolation()) {
-	  ctr -= interpolation();
-	  in++;
-          count++;
-	}
-      }
-
-      d_ctr = ctr;
-      consume_each(count);
-      return i;
-    }
-
-  } /* namespace filter */
-} /* namespace gr */
diff --git a/gr-filter/lib/rational_resampler_base_XXX_impl.h.t b/gr-filter/lib/rational_resampler_base_XXX_impl.h.t
deleted file mode 100644
index debd059092..0000000000
--- a/gr-filter/lib/rational_resampler_base_XXX_impl.h.t
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/* @WARNING@ */
-
-#ifndef @GUARD_NAME@
-#define	@GUARD_NAME@
-
-#include <gnuradio/filter/fir_filter.h>
-#include <gnuradio/filter/@BASE_NAME@.h>
-
-namespace gr {
-  namespace filter {
-
-    class FILTER_API @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      unsigned d_history;
-      unsigned d_interpolation;
-      unsigned d_decimation;
-      unsigned d_ctr;
-      std::vector<@TAP_TYPE@> d_new_taps;
-      std::vector<kernel::@FIR_TYPE@ *> d_firs;
-      bool d_updated;
-
-      void install_taps(const std::vector<@TAP_TYPE@> &taps);
-
-    public:
-      @IMPL_NAME@(unsigned interpolation, unsigned decimation,
-		  const std::vector<@TAP_TYPE@> &taps);
-
-      ~@IMPL_NAME@();
-
-      unsigned history() const { return d_history; }
-      void set_history(unsigned history) { d_history = history; }
-
-      unsigned interpolation() const { return d_interpolation; }
-      unsigned decimation() const { return d_decimation; }
-
-      void set_taps(const std::vector<@TAP_TYPE@> &taps);
-      std::vector<@TAP_TYPE@> taps() const;
-
-      void forecast(int noutput_items, gr_vector_int &ninput_items_required);
-      int  general_work(int noutput_items,
-			gr_vector_int &ninput_items,
-			gr_vector_const_void_star &input_items,
-			gr_vector_void_star &output_items);
-    };
-
-  } /* namespace filter */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/lib/rational_resampler_base_impl.cc b/gr-filter/lib/rational_resampler_base_impl.cc
new file mode 100644
index 0000000000..133f62e3f8
--- /dev/null
+++ b/gr-filter/lib/rational_resampler_base_impl.cc
@@ -0,0 +1,188 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "rational_resampler_base_impl.h"
+#include <gnuradio/io_signature.h>
+#include <volk/volk.h>
+#include <stdexcept>
+
+namespace gr {
+  namespace filter {
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    typename rational_resampler_base<IN_T,OUT_T,TAP_T>::sptr
+    rational_resampler_base<IN_T,OUT_T,TAP_T>::make(unsigned interpolation,
+		      unsigned decimation,
+		      const std::vector<TAP_T> &taps)
+    {
+      return gnuradio::get_initial_sptr
+	(new rational_resampler_base_impl<IN_T,OUT_T,TAP_T>(interpolation, decimation, taps));
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    rational_resampler_base_impl<IN_T,OUT_T,TAP_T>::rational_resampler_base_impl(unsigned interpolation,
+			     unsigned decimation,
+			     const std::vector<TAP_T> &taps)
+    : block("rational_resampler_base<IN_T,OUT_T,TAP_T>",
+	       io_signature::make(1, 1, sizeof(IN_T)),
+	       io_signature::make(1, 1, sizeof(OUT_T))),
+      d_history(1),
+      d_interpolation(interpolation),
+      d_decimation(decimation),
+      d_ctr(0),
+      d_firs(interpolation),
+      d_updated(false)
+    {
+      if(interpolation == 0)
+	throw std::out_of_range("rational_resampler_base_impl<IN_T,OUT_T,TAP_T>: interpolation must be > 0");
+      if(decimation == 0)
+	throw std::out_of_range("rational_resampler_base_impl<IN_T,OUT_T,TAP_T>: decimation must be > 0");
+
+      this->set_relative_rate(1.0 * interpolation / decimation);
+      this->set_output_multiple(1);
+
+      std::vector<TAP_T> dummy_taps;
+
+      for(unsigned i = 0; i < interpolation; i++) {
+        d_firs[i] = new kernel::fir_filter<IN_T,OUT_T,TAP_T>(1, dummy_taps);
+      }
+
+      set_taps(taps);
+      install_taps(d_new_taps);
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    rational_resampler_base_impl<IN_T,OUT_T,TAP_T>::~rational_resampler_base_impl()
+    {
+      int interp = this->interpolation();
+      for(int i = 0; i < interp; i++) {
+	delete d_firs[i];
+      }
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    void
+    rational_resampler_base_impl<IN_T,OUT_T,TAP_T>::set_taps(const std::vector<TAP_T> &taps)
+    {
+      d_new_taps = taps;
+      d_updated = true;
+
+      // round up length to a multiple of the interpolation factor
+      int n = taps.size() % this->interpolation();
+      if(n > 0) {
+	n = this->interpolation() - n;
+	while(n-- > 0) {
+	  d_new_taps.insert(d_new_taps.end(), 0);
+	}
+      }
+
+      assert(d_new_taps.size() % this->interpolation() == 0);
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    void
+    rational_resampler_base_impl<IN_T,OUT_T,TAP_T>::install_taps(const std::vector<TAP_T> &taps)
+    {
+      int nfilters = this->interpolation();
+      int nt = taps.size() / nfilters;
+
+      assert(nt * nfilters == (int) taps.size());
+
+      std::vector< std::vector <TAP_T> > xtaps(nfilters);
+
+      for(int n = 0; n < nfilters; n++)
+	xtaps[n].resize (nt);
+
+      for(int i = 0; i < (int)taps.size(); i++)
+	xtaps[i % nfilters][i / nfilters] = taps[i];
+
+      for(int n = 0; n < nfilters; n++)
+	d_firs[n]->set_taps(xtaps[n]);
+
+      set_history(nt);
+      d_updated = false;
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    std::vector<TAP_T>
+    rational_resampler_base_impl<IN_T,OUT_T,TAP_T>::taps() const
+    {
+      return d_new_taps;
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    void
+    rational_resampler_base_impl<IN_T,OUT_T,TAP_T>::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+    {
+      int nreqd = std::max((unsigned)1, (int)((double) (noutput_items+1) * \
+				        this->decimation() / this->interpolation()) + history() - 1);
+      unsigned ninputs = ninput_items_required.size();
+      for(unsigned i = 0; i < ninputs; i++)
+	ninput_items_required[i] = nreqd;
+    }
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    int
+    rational_resampler_base_impl<IN_T,OUT_T,TAP_T>::general_work(int noutput_items,
+			      gr_vector_int &ninput_items,
+			      gr_vector_const_void_star &input_items,
+			      gr_vector_void_star &output_items)
+    {
+      const IN_T *in = (const IN_T *)input_items[0];
+      OUT_T *out = (OUT_T *)output_items[0];
+
+      if(d_updated) {
+	install_taps(d_new_taps);
+	return 0;		// history requirement may have increased.
+      }
+
+      unsigned int ctr = d_ctr;
+      int count = 0;
+
+      int i = 0;
+      while((i < noutput_items) && (count < ninput_items[0])) {
+	out[i++] = d_firs[ctr]->filter(in);
+	ctr += this->decimation();
+	while(ctr >= this->interpolation()) {
+	  ctr -= this->interpolation();
+	  in++;
+          count++;
+	}
+      }
+
+      d_ctr = ctr;
+      this->consume_each(count);
+      return i;
+    }
+    template class rational_resampler_base<gr_complex, gr_complex, gr_complex>;
+    template class rational_resampler_base<gr_complex, gr_complex, float>;
+    template class rational_resampler_base<float, gr_complex, gr_complex>;
+    template class rational_resampler_base<float, float, float>;
+    template class rational_resampler_base<float, std::int16_t, float>;
+    template class rational_resampler_base<std::int16_t, gr_complex, gr_complex>;
+
+  } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/rational_resampler_base_impl.h b/gr-filter/lib/rational_resampler_base_impl.h
new file mode 100644
index 0000000000..a42d1b0fda
--- /dev/null
+++ b/gr-filter/lib/rational_resampler_base_impl.h
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef RATIONAL_RESAMPLER_IMPL_BASE_H
+#define	RATIONAL_RESAMPLER_IMPL_BASE_H
+
+#include <gnuradio/filter/fir_filter.h>
+#include <gnuradio/filter/rational_resampler_base.h>
+
+namespace gr {
+  namespace filter {
+
+    template <class IN_T, class OUT_T, class TAP_T>
+    class FILTER_API rational_resampler_base_impl : public rational_resampler_base<IN_T,OUT_T,TAP_T>
+    {
+    private:
+      unsigned d_history;
+      unsigned d_interpolation;
+      unsigned d_decimation;
+      unsigned d_ctr;
+      std::vector<TAP_T> d_new_taps;
+      std::vector<kernel::fir_filter<IN_T,OUT_T,TAP_T> *> d_firs;
+      bool d_updated;
+
+      void install_taps(const std::vector<TAP_T> &taps);
+
+    public:
+      rational_resampler_base_impl(unsigned interpolation, unsigned decimation,
+		  const std::vector<TAP_T> &taps);
+
+      ~rational_resampler_base_impl();
+
+      unsigned history() const { return d_history; }
+      void set_history(unsigned history) { d_history = history; }
+
+      unsigned interpolation() const { return d_interpolation; }
+      unsigned decimation() const { return d_decimation; }
+
+      void set_taps(const std::vector<TAP_T> &taps);
+      std::vector<TAP_T> taps() const;
+
+      void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+      int  general_work(int noutput_items,
+			gr_vector_int &ninput_items,
+			gr_vector_const_void_star &input_items,
+			gr_vector_void_star &output_items);
+    };
+
+  } /* namespace filter */
+} /* namespace gr */
+
+#endif /* RATIONAL_RESAMPLER_IMPL_BASE_H */
diff --git a/gr-filter/swig/CMakeLists.txt b/gr-filter/swig/CMakeLists.txt
index ee8389dddb..2308739062 100644
--- a/gr-filter/swig/CMakeLists.txt
+++ b/gr-filter/swig/CMakeLists.txt
@@ -42,7 +42,6 @@ set(GR_SWIG_DOC_DIRS
     ${CMAKE_CURRENT_BINARY_DIR}/../include/gnuradio/filter
 )
 set(GR_SWIG_DOCS_TARGET_DEPS runtime_swig_swig_doc)
-set(GR_SWIG_TARGET_DEPS filter_generated_includes)
 set(GR_SWIG_LIBRARIES gnuradio-filter gnuradio-fft)
 
 GR_SWIG_MAKE(filter_swig filter_swig.i)
diff --git a/gr-filter/swig/filter_swig.i b/gr-filter/swig/filter_swig.i
index db0ad0fd95..939f038208 100644
--- a/gr-filter/swig/filter_swig.i
+++ b/gr-filter/swig/filter_swig.i
@@ -34,12 +34,7 @@
 #include "gnuradio/filter/dc_blocker_ff.h"
 #include "gnuradio/filter/filter_delay_fc.h"
 #include "gnuradio/filter/filterbank_vcvcf.h"
-#include "gnuradio/filter/fir_filter_ccc.h"
-#include "gnuradio/filter/fir_filter_ccf.h"
-#include "gnuradio/filter/fir_filter_fcc.h"
-#include "gnuradio/filter/fir_filter_fff.h"
-#include "gnuradio/filter/fir_filter_fsf.h"
-#include "gnuradio/filter/fir_filter_scc.h"
+#include "gnuradio/filter/fir_filter_blk.h"
 #include "gnuradio/filter/fft_filter_ccc.h"
 #include "gnuradio/filter/fft_filter_ccf.h"
 #include "gnuradio/filter/fft_filter_fff.h"
@@ -47,24 +42,14 @@
 #include "gnuradio/filter/mmse_interpolator_ff.h"
 #include "gnuradio/filter/mmse_resampler_cc.h"
 #include "gnuradio/filter/mmse_resampler_ff.h"
-#include "gnuradio/filter/freq_xlating_fir_filter_ccc.h"
-#include "gnuradio/filter/freq_xlating_fir_filter_ccf.h"
-#include "gnuradio/filter/freq_xlating_fir_filter_fcc.h"
-#include "gnuradio/filter/freq_xlating_fir_filter_fcf.h"
-#include "gnuradio/filter/freq_xlating_fir_filter_scf.h"
-#include "gnuradio/filter/freq_xlating_fir_filter_scc.h"
+#include "gnuradio/filter/freq_xlating_fir_filter.h"
 #include "gnuradio/filter/hilbert_fc.h"
 #include "gnuradio/filter/iir_filter_ffd.h"
 #include "gnuradio/filter/iir_filter_ccc.h"
 #include "gnuradio/filter/iir_filter_ccf.h"
 #include "gnuradio/filter/iir_filter_ccd.h"
 #include "gnuradio/filter/iir_filter_ccz.h"
-#include "gnuradio/filter/interp_fir_filter_ccc.h"
-#include "gnuradio/filter/interp_fir_filter_ccf.h"
-#include "gnuradio/filter/interp_fir_filter_fcc.h"
-#include "gnuradio/filter/interp_fir_filter_fff.h"
-#include "gnuradio/filter/interp_fir_filter_fsf.h"
-#include "gnuradio/filter/interp_fir_filter_scc.h"
+#include "gnuradio/filter/interp_fir_filter.h"
 #include "gnuradio/filter/pfb_arb_resampler_ccf.h"
 #include "gnuradio/filter/pfb_arb_resampler_ccc.h"
 #include "gnuradio/filter/pfb_arb_resampler_fff.h"
@@ -72,12 +57,7 @@
 #include "gnuradio/filter/pfb_decimator_ccf.h"
 #include "gnuradio/filter/pfb_interpolator_ccf.h"
 #include "gnuradio/filter/pfb_synthesizer_ccf.h"
-#include "gnuradio/filter/rational_resampler_base_ccc.h"
-#include "gnuradio/filter/rational_resampler_base_ccf.h"
-#include "gnuradio/filter/rational_resampler_base_fcc.h"
-#include "gnuradio/filter/rational_resampler_base_fff.h"
-#include "gnuradio/filter/rational_resampler_base_fsf.h"
-#include "gnuradio/filter/rational_resampler_base_scc.h"
+#include "gnuradio/filter/rational_resampler_base.h"
 #include "gnuradio/filter/single_pole_iir_filter_cc.h"
 #include "gnuradio/filter/single_pole_iir_filter_ff.h"
 %}
@@ -88,12 +68,7 @@
 %include "gnuradio/filter/dc_blocker_ff.h"
 %include "gnuradio/filter/filter_delay_fc.h"
 %include "gnuradio/filter/filterbank_vcvcf.h"
-%include "gnuradio/filter/fir_filter_ccc.h"
-%include "gnuradio/filter/fir_filter_ccf.h"
-%include "gnuradio/filter/fir_filter_fcc.h"
-%include "gnuradio/filter/fir_filter_fff.h"
-%include "gnuradio/filter/fir_filter_fsf.h"
-%include "gnuradio/filter/fir_filter_scc.h"
+%include "gnuradio/filter/fir_filter_blk.h"
 %include "gnuradio/filter/fft_filter_ccc.h"
 %include "gnuradio/filter/fft_filter_ccf.h"
 %include "gnuradio/filter/fft_filter_fff.h"
@@ -101,24 +76,14 @@
 %include "gnuradio/filter/mmse_interpolator_ff.h"
 %include "gnuradio/filter/mmse_resampler_cc.h"
 %include "gnuradio/filter/mmse_resampler_ff.h"
-%include "gnuradio/filter/freq_xlating_fir_filter_ccc.h"
-%include "gnuradio/filter/freq_xlating_fir_filter_ccf.h"
-%include "gnuradio/filter/freq_xlating_fir_filter_fcc.h"
-%include "gnuradio/filter/freq_xlating_fir_filter_fcf.h"
-%include "gnuradio/filter/freq_xlating_fir_filter_scf.h"
-%include "gnuradio/filter/freq_xlating_fir_filter_scc.h"
+%include "gnuradio/filter/freq_xlating_fir_filter.h"
 %include "gnuradio/filter/hilbert_fc.h"
 %include "gnuradio/filter/iir_filter_ffd.h"
 %include "gnuradio/filter/iir_filter_ccc.h"
 %include "gnuradio/filter/iir_filter_ccf.h"
 %include "gnuradio/filter/iir_filter_ccd.h"
 %include "gnuradio/filter/iir_filter_ccz.h"
-%include "gnuradio/filter/interp_fir_filter_ccc.h"
-%include "gnuradio/filter/interp_fir_filter_ccf.h"
-%include "gnuradio/filter/interp_fir_filter_fcc.h"
-%include "gnuradio/filter/interp_fir_filter_fff.h"
-%include "gnuradio/filter/interp_fir_filter_fsf.h"
-%include "gnuradio/filter/interp_fir_filter_scc.h"
+%include "gnuradio/filter/interp_fir_filter.h"
 %include "gnuradio/filter/pfb_arb_resampler_ccf.h"
 %include "gnuradio/filter/pfb_arb_resampler_ccc.h"
 %include "gnuradio/filter/pfb_arb_resampler_fff.h"
@@ -126,12 +91,7 @@
 %include "gnuradio/filter/pfb_decimator_ccf.h"
 %include "gnuradio/filter/pfb_interpolator_ccf.h"
 %include "gnuradio/filter/pfb_synthesizer_ccf.h"
-%include "gnuradio/filter/rational_resampler_base_ccc.h"
-%include "gnuradio/filter/rational_resampler_base_ccf.h"
-%include "gnuradio/filter/rational_resampler_base_fcc.h"
-%include "gnuradio/filter/rational_resampler_base_fff.h"
-%include "gnuradio/filter/rational_resampler_base_fsf.h"
-%include "gnuradio/filter/rational_resampler_base_scc.h"
+%include "gnuradio/filter/rational_resampler_base.h"
 %include "gnuradio/filter/single_pole_iir_filter_cc.h"
 %include "gnuradio/filter/single_pole_iir_filter_ff.h"
 
@@ -139,12 +99,12 @@ GR_SWIG_BLOCK_MAGIC2(filter, dc_blocker_cc);
 GR_SWIG_BLOCK_MAGIC2(filter, dc_blocker_ff);
 GR_SWIG_BLOCK_MAGIC2(filter, filter_delay_fc);
 GR_SWIG_BLOCK_MAGIC2(filter, filterbank_vcvcf);
-GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_ccc);
-GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_ccf);
-GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_fcc);
-GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_fff);
-GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_fsf);
-GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_scc);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, fir_filter_ccc, fir_filter_blk<gr_complex, gr_complex, gr_complex>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, fir_filter_ccf, fir_filter_blk<gr_complex, gr_complex, float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, fir_filter_fcc, fir_filter_blk<float, gr_complex, gr_complex>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, fir_filter_fff, fir_filter_blk<float, float, float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, fir_filter_fsf, fir_filter_blk<float, std::int16_t, float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, fir_filter_scc, fir_filter_blk<std::int16_t, gr_complex, gr_complex>);
 GR_SWIG_BLOCK_MAGIC2(filter, fft_filter_ccc);
 GR_SWIG_BLOCK_MAGIC2(filter, fft_filter_ccf);
 GR_SWIG_BLOCK_MAGIC2(filter, fft_filter_fff);
@@ -152,24 +112,24 @@ GR_SWIG_BLOCK_MAGIC2(filter, mmse_interpolator_cc);
 GR_SWIG_BLOCK_MAGIC2(filter, mmse_interpolator_ff);
 GR_SWIG_BLOCK_MAGIC2(filter, mmse_resampler_cc);
 GR_SWIG_BLOCK_MAGIC2(filter, mmse_resampler_ff);
-GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_ccc);
-GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_ccf);
-GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_fcc);
-GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_fcf);
-GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_scf);
-GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_scc);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, freq_xlating_fir_filter_ccc, freq_xlating_fir_filter<gr_complex, gr_complex, gr_complex>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, freq_xlating_fir_filter_ccf, freq_xlating_fir_filter<gr_complex, gr_complex, float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, freq_xlating_fir_filter_fcc, freq_xlating_fir_filter<float, gr_complex, gr_complex>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, freq_xlating_fir_filter_fcf, freq_xlating_fir_filter<float, gr_complex, float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, freq_xlating_fir_filter_scf, freq_xlating_fir_filter<std::int16_t, gr_complex, float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, freq_xlating_fir_filter_scc, freq_xlating_fir_filter<std::int16_t, gr_complex, gr_complex>);
 GR_SWIG_BLOCK_MAGIC2(filter, hilbert_fc);
 GR_SWIG_BLOCK_MAGIC2(filter, iir_filter_ffd);
 GR_SWIG_BLOCK_MAGIC2(filter, iir_filter_ccc);
 GR_SWIG_BLOCK_MAGIC2(filter, iir_filter_ccf);
 GR_SWIG_BLOCK_MAGIC2(filter, iir_filter_ccd);
 GR_SWIG_BLOCK_MAGIC2(filter, iir_filter_ccz);
-GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_ccc);
-GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_ccf);
-GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_fcc);
-GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_fff);
-GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_fsf);
-GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_scc);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, interp_fir_filter_ccc, interp_fir_filter<gr_complex, gr_complex, gr_complex>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, interp_fir_filter_ccf, interp_fir_filter<gr_complex, gr_complex, float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, interp_fir_filter_fcc, interp_fir_filter<float, gr_complex, gr_complex>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, interp_fir_filter_fff, interp_fir_filter<float, float, float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, interp_fir_filter_fsf, interp_fir_filter<float, std::int16_t, float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, interp_fir_filter_scc, interp_fir_filter<std::int16_t, gr_complex, gr_complex>);
 GR_SWIG_BLOCK_MAGIC2(filter, pfb_arb_resampler_ccf);
 GR_SWIG_BLOCK_MAGIC2(filter, pfb_arb_resampler_ccc);
 GR_SWIG_BLOCK_MAGIC2(filter, pfb_arb_resampler_fff);
@@ -177,11 +137,11 @@ GR_SWIG_BLOCK_MAGIC2(filter, pfb_channelizer_ccf);
 GR_SWIG_BLOCK_MAGIC2(filter, pfb_decimator_ccf);
 GR_SWIG_BLOCK_MAGIC2(filter, pfb_interpolator_ccf);
 GR_SWIG_BLOCK_MAGIC2(filter, pfb_synthesizer_ccf);
-GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_ccc);
-GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_ccf);
-GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_fcc);
-GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_fff);
-GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_fsf);
-GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_scc);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, rational_resampler_base_ccc, rational_resampler_base<gr_complex,gr_complex,gr_complex>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, rational_resampler_base_ccf, rational_resampler_base<gr_complex,gr_complex,float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, rational_resampler_base_fcc, rational_resampler_base<float,gr_complex,gr_complex>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, rational_resampler_base_fff, rational_resampler_base<float,float,float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, rational_resampler_base_fsf, rational_resampler_base<float,std::int16_t,float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(filter, rational_resampler_base_scc, rational_resampler_base<std::int16_t,gr_complex,gr_complex>);
 GR_SWIG_BLOCK_MAGIC2(filter, single_pole_iir_filter_cc);
 GR_SWIG_BLOCK_MAGIC2(filter, single_pole_iir_filter_ff);
-- 
cgit v1.2.3


From 97ba0b074f4ecc1cc78b5d1902c5e2458b4b5c5a Mon Sep 17 00:00:00 2001
From: Andrej Rode <mail@andrejro.de>
Date: Mon, 20 Aug 2018 13:58:33 +0200
Subject: trellis: replace gengen with C++ templates

---
 docs/doxygen/CMakeLists.txt                        |   4 -
 gr-trellis/include/gnuradio/trellis/CMakeLists.txt |  33 ++--
 gr-trellis/include/gnuradio/trellis/encoder.h      |  65 ++++++++
 gr-trellis/include/gnuradio/trellis/encoder_XX.h.t |  60 -------
 gr-trellis/include/gnuradio/trellis/metrics.h      |  68 ++++++++
 gr-trellis/include/gnuradio/trellis/metrics_X.h.t  |  63 --------
 .../include/gnuradio/trellis/pccc_decoder_X.h.t    |  69 --------
 .../include/gnuradio/trellis/pccc_decoder_blk.h    |  73 +++++++++
 .../gnuradio/trellis/pccc_decoder_combined_XX.h.t  |  79 ---------
 .../gnuradio/trellis/pccc_decoder_combined_blk.h   |  85 ++++++++++
 gr-trellis/include/gnuradio/trellis/pccc_encoder.h |  69 ++++++++
 .../include/gnuradio/trellis/pccc_encoder_XX.h.t   |  63 --------
 .../include/gnuradio/trellis/sccc_decoder_X.h.t    |  69 --------
 .../include/gnuradio/trellis/sccc_decoder_blk.h    |  73 +++++++++
 .../gnuradio/trellis/sccc_decoder_combined_XX.h.t  |  80 ----------
 .../gnuradio/trellis/sccc_decoder_combined_blk.h   |  86 ++++++++++
 gr-trellis/include/gnuradio/trellis/sccc_encoder.h |  67 ++++++++
 .../include/gnuradio/trellis/sccc_encoder_XX.h.t   |  63 --------
 gr-trellis/include/gnuradio/trellis/viterbi.h      |  66 ++++++++
 gr-trellis/include/gnuradio/trellis/viterbi_X.h.t  |  62 --------
 .../include/gnuradio/trellis/viterbi_combined.h    |  83 ++++++++++
 .../gnuradio/trellis/viterbi_combined_XX.h.t       |  71 ---------
 gr-trellis/lib/CMakeLists.txt                      |  32 ++--
 gr-trellis/lib/encoder_XX_impl.cc.t                | 118 --------------
 gr-trellis/lib/encoder_XX_impl.h.t                 |  60 -------
 gr-trellis/lib/encoder_impl.cc                     | 131 +++++++++++++++
 gr-trellis/lib/encoder_impl.h                      |  59 +++++++
 gr-trellis/lib/metrics_X_impl.cc.t                 | 123 --------------
 gr-trellis/lib/metrics_X_impl.h.t                  |  68 --------
 gr-trellis/lib/metrics_impl.cc                     | 135 ++++++++++++++++
 gr-trellis/lib/metrics_impl.h                      |  68 ++++++++
 gr-trellis/lib/pccc_decoder_X_impl.cc.t            | 118 --------------
 gr-trellis/lib/pccc_decoder_X_impl.h.t             |  80 ----------
 gr-trellis/lib/pccc_decoder_blk_impl.cc            | 125 +++++++++++++++
 gr-trellis/lib/pccc_decoder_blk_impl.h             |  80 ++++++++++
 gr-trellis/lib/pccc_decoder_combined_XX_impl.cc.t  | 139 ----------------
 gr-trellis/lib/pccc_decoder_combined_XX_impl.h.t   |  93 -----------
 gr-trellis/lib/pccc_decoder_combined_blk_impl.cc   | 150 ++++++++++++++++++
 gr-trellis/lib/pccc_decoder_combined_blk_impl.h    |  92 +++++++++++
 gr-trellis/lib/pccc_encoder_XX_impl.cc.t           |  91 -----------
 gr-trellis/lib/pccc_encoder_XX_impl.h.t            |  66 --------
 gr-trellis/lib/pccc_encoder_impl.cc                |  99 ++++++++++++
 gr-trellis/lib/pccc_encoder_impl.h                 |  65 ++++++++
 gr-trellis/lib/sccc_decoder_X_impl.cc.t            | 116 --------------
 gr-trellis/lib/sccc_decoder_X_impl.h.t             |  80 ----------
 gr-trellis/lib/sccc_decoder_blk_impl.cc            | 123 ++++++++++++++
 gr-trellis/lib/sccc_decoder_blk_impl.h             |  80 ++++++++++
 gr-trellis/lib/sccc_decoder_combined_XX_impl.cc.t  | 139 ----------------
 gr-trellis/lib/sccc_decoder_combined_XX_impl.h.t   |  93 -----------
 gr-trellis/lib/sccc_decoder_combined_blk_impl.cc   | 151 ++++++++++++++++++
 gr-trellis/lib/sccc_decoder_combined_blk_impl.h    |  92 +++++++++++
 gr-trellis/lib/sccc_encoder_XX_impl.cc.t           |  93 -----------
 gr-trellis/lib/sccc_encoder_XX_impl.h.t            |  66 --------
 gr-trellis/lib/sccc_encoder_impl.cc                | 101 ++++++++++++
 gr-trellis/lib/sccc_encoder_impl.h                 |  65 ++++++++
 gr-trellis/lib/viterbi_X_impl.cc.t                 | 124 ---------------
 gr-trellis/lib/viterbi_X_impl.h.t                  |  69 --------
 gr-trellis/lib/viterbi_combined_XX_impl.cc.t       | 153 ------------------
 gr-trellis/lib/viterbi_combined_XX_impl.h.t        |  81 ----------
 gr-trellis/lib/viterbi_combined_impl.cc            | 176 +++++++++++++++++++++
 gr-trellis/lib/viterbi_combined_impl.h             |  80 ++++++++++
 gr-trellis/lib/viterbi_impl.cc                     | 135 ++++++++++++++++
 gr-trellis/lib/viterbi_impl.h                      |  69 ++++++++
 gr-trellis/swig/CMakeLists.txt                     |   1 -
 gr-trellis/swig/trellis_swig0.i                    |  96 ++++-------
 gr-trellis/swig/trellis_swig1.i                    | 145 ++++++-----------
 66 files changed, 2911 insertions(+), 2860 deletions(-)
 create mode 100644 gr-trellis/include/gnuradio/trellis/encoder.h
 delete mode 100644 gr-trellis/include/gnuradio/trellis/encoder_XX.h.t
 create mode 100644 gr-trellis/include/gnuradio/trellis/metrics.h
 delete mode 100644 gr-trellis/include/gnuradio/trellis/metrics_X.h.t
 delete mode 100644 gr-trellis/include/gnuradio/trellis/pccc_decoder_X.h.t
 create mode 100644 gr-trellis/include/gnuradio/trellis/pccc_decoder_blk.h
 delete mode 100644 gr-trellis/include/gnuradio/trellis/pccc_decoder_combined_XX.h.t
 create mode 100644 gr-trellis/include/gnuradio/trellis/pccc_decoder_combined_blk.h
 create mode 100644 gr-trellis/include/gnuradio/trellis/pccc_encoder.h
 delete mode 100644 gr-trellis/include/gnuradio/trellis/pccc_encoder_XX.h.t
 delete mode 100644 gr-trellis/include/gnuradio/trellis/sccc_decoder_X.h.t
 create mode 100644 gr-trellis/include/gnuradio/trellis/sccc_decoder_blk.h
 delete mode 100644 gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_XX.h.t
 create mode 100644 gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_blk.h
 create mode 100644 gr-trellis/include/gnuradio/trellis/sccc_encoder.h
 delete mode 100644 gr-trellis/include/gnuradio/trellis/sccc_encoder_XX.h.t
 create mode 100644 gr-trellis/include/gnuradio/trellis/viterbi.h
 delete mode 100644 gr-trellis/include/gnuradio/trellis/viterbi_X.h.t
 create mode 100644 gr-trellis/include/gnuradio/trellis/viterbi_combined.h
 delete mode 100644 gr-trellis/include/gnuradio/trellis/viterbi_combined_XX.h.t
 delete mode 100644 gr-trellis/lib/encoder_XX_impl.cc.t
 delete mode 100644 gr-trellis/lib/encoder_XX_impl.h.t
 create mode 100644 gr-trellis/lib/encoder_impl.cc
 create mode 100644 gr-trellis/lib/encoder_impl.h
 delete mode 100644 gr-trellis/lib/metrics_X_impl.cc.t
 delete mode 100644 gr-trellis/lib/metrics_X_impl.h.t
 create mode 100644 gr-trellis/lib/metrics_impl.cc
 create mode 100644 gr-trellis/lib/metrics_impl.h
 delete mode 100644 gr-trellis/lib/pccc_decoder_X_impl.cc.t
 delete mode 100644 gr-trellis/lib/pccc_decoder_X_impl.h.t
 create mode 100644 gr-trellis/lib/pccc_decoder_blk_impl.cc
 create mode 100644 gr-trellis/lib/pccc_decoder_blk_impl.h
 delete mode 100644 gr-trellis/lib/pccc_decoder_combined_XX_impl.cc.t
 delete mode 100644 gr-trellis/lib/pccc_decoder_combined_XX_impl.h.t
 create mode 100644 gr-trellis/lib/pccc_decoder_combined_blk_impl.cc
 create mode 100644 gr-trellis/lib/pccc_decoder_combined_blk_impl.h
 delete mode 100644 gr-trellis/lib/pccc_encoder_XX_impl.cc.t
 delete mode 100644 gr-trellis/lib/pccc_encoder_XX_impl.h.t
 create mode 100644 gr-trellis/lib/pccc_encoder_impl.cc
 create mode 100644 gr-trellis/lib/pccc_encoder_impl.h
 delete mode 100644 gr-trellis/lib/sccc_decoder_X_impl.cc.t
 delete mode 100644 gr-trellis/lib/sccc_decoder_X_impl.h.t
 create mode 100644 gr-trellis/lib/sccc_decoder_blk_impl.cc
 create mode 100644 gr-trellis/lib/sccc_decoder_blk_impl.h
 delete mode 100644 gr-trellis/lib/sccc_decoder_combined_XX_impl.cc.t
 delete mode 100644 gr-trellis/lib/sccc_decoder_combined_XX_impl.h.t
 create mode 100644 gr-trellis/lib/sccc_decoder_combined_blk_impl.cc
 create mode 100644 gr-trellis/lib/sccc_decoder_combined_blk_impl.h
 delete mode 100644 gr-trellis/lib/sccc_encoder_XX_impl.cc.t
 delete mode 100644 gr-trellis/lib/sccc_encoder_XX_impl.h.t
 create mode 100644 gr-trellis/lib/sccc_encoder_impl.cc
 create mode 100644 gr-trellis/lib/sccc_encoder_impl.h
 delete mode 100644 gr-trellis/lib/viterbi_X_impl.cc.t
 delete mode 100644 gr-trellis/lib/viterbi_X_impl.h.t
 delete mode 100644 gr-trellis/lib/viterbi_combined_XX_impl.cc.t
 delete mode 100644 gr-trellis/lib/viterbi_combined_XX_impl.h.t
 create mode 100644 gr-trellis/lib/viterbi_combined_impl.cc
 create mode 100644 gr-trellis/lib/viterbi_combined_impl.h
 create mode 100644 gr-trellis/lib/viterbi_impl.cc
 create mode 100644 gr-trellis/lib/viterbi_impl.h

(limited to 'docs/doxygen')

diff --git a/docs/doxygen/CMakeLists.txt b/docs/doxygen/CMakeLists.txt
index 019b01c305..8c8bd4b248 100644
--- a/docs/doxygen/CMakeLists.txt
+++ b/docs/doxygen/CMakeLists.txt
@@ -45,10 +45,6 @@ if(ENABLE_GNURADIO_RUNTIME)
   list(APPEND GENERATED_DEPS pmt_generated)
 endif(ENABLE_GNURADIO_RUNTIME)
 
-if(ENABLE_GR_TRELLIS)
-  list(APPEND GENERATED_DEPS trellis_generated_includes)
-endif(ENABLE_GR_TRELLIS)
-
 ########################################################################
 # Make and install doxygen docs
 ########################################################################
diff --git a/gr-trellis/include/gnuradio/trellis/CMakeLists.txt b/gr-trellis/include/gnuradio/trellis/CMakeLists.txt
index 831f2916dc..a9c664606c 100644
--- a/gr-trellis/include/gnuradio/trellis/CMakeLists.txt
+++ b/gr-trellis/include/gnuradio/trellis/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2012,2014 Free Software Foundation, Inc.
+# Copyright 2012,2014,2018 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -17,42 +17,31 @@
 # the Free Software Foundation, Inc., 51 Franklin Street,
 # Boston, MA 02110-1301, USA.
 
-########################################################################
-# Invoke macro to generate various headers
-########################################################################
-include(GrMiscUtils)
-GR_EXPAND_X_H(trellis encoder_XX                 bb bs bi ss si ii)
-GR_EXPAND_X_H(trellis sccc_encoder_XX            bb bs bi ss si ii)
-GR_EXPAND_X_H(trellis pccc_encoder_XX            bb bs bi ss si ii)
-GR_EXPAND_X_H(trellis metrics_X                  s i f c)
-GR_EXPAND_X_H(trellis viterbi_X                  b s i)
-GR_EXPAND_X_H(trellis viterbi_combined_XX        sb ss si ib is ii fb fs fi cb cs ci)
-GR_EXPAND_X_H(trellis sccc_decoder_X             b s i)
-GR_EXPAND_X_H(trellis sccc_decoder_combined_XX   fb fs fi cb cs ci)
-GR_EXPAND_X_H(trellis pccc_decoder_X             b s i)
-GR_EXPAND_X_H(trellis pccc_decoder_combined_XX   fb fs fi cb cs ci)
-
-add_custom_target(trellis_generated_includes DEPENDS
-    ${generated_includes}
-)
-
 ########################################################################
 # Install header files
 ########################################################################
 install(FILES
-    ${generated_includes}
     api.h
     base.h
     calc_metric.h
     constellation_metrics_cf.h
     core_algorithms.h
+    encoder.h
     fsm.h
     interleaver.h
+    metrics.h
+    pccc_decoder_blk.h
+    pccc_decoder_combined_blk.h
+    pccc_encoder.h
     permutation.h
     quicksort_index.h
+    sccc_encoder.h
+    sccc_decoder_blk.h
+    sccc_decoder_combined_blk.h
     siso_type.h
     siso_combined_f.h
     siso_f.h
+    viterbi.h
+    viterbi_combined.h
     DESTINATION ${GR_INCLUDE_DIR}/gnuradio/trellis
 )
-
diff --git a/gr-trellis/include/gnuradio/trellis/encoder.h b/gr-trellis/include/gnuradio/trellis/encoder.h
new file mode 100644
index 0000000000..5f022f2a01
--- /dev/null
+++ b/gr-trellis/include/gnuradio/trellis/encoder.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef ENCODER_H
+#define ENCODER_H
+
+#include <gnuradio/trellis/api.h>
+#include <gnuradio/trellis/fsm.h>
+#include <gnuradio/sync_block.h>
+#include <cstdint>
+
+namespace gr {
+  namespace trellis {
+
+    /*!
+     * \brief Convolutional encoder.
+     * \ingroup trellis_coding_blk
+     */
+    template <class IN_T, class OUT_T>
+    class TRELLIS_API encoder : virtual public sync_block
+    {
+    public:
+      typedef boost::shared_ptr< encoder<IN_T,OUT_T> > sptr;
+
+      static sptr make(const fsm &FSM, int ST);
+
+      static sptr make(const fsm &FSM, int ST, int K);
+
+      virtual fsm FSM() const = 0;
+      virtual int ST() const = 0;
+      virtual int K() const = 0;
+      virtual void set_FSM(const fsm &FSM) =0;
+      virtual void set_ST(int ST) =0;
+      virtual void set_K(int K) =0;
+    };
+    typedef encoder<std::uint8_t, std::uint8_t> encoder_bb;
+    typedef encoder<std::uint8_t, std::int16_t> encoder_bs;
+    typedef encoder<std::uint8_t, std::int32_t> encoder_bi;
+    typedef encoder<std::int16_t, std::int16_t> encoder_ss;
+    typedef encoder<std::int16_t, std::int32_t> encoder_si;
+    typedef encoder<std::int32_t, std::int32_t> encoder_ii;
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* ENCODER_H */
diff --git a/gr-trellis/include/gnuradio/trellis/encoder_XX.h.t b/gr-trellis/include/gnuradio/trellis/encoder_XX.h.t
deleted file mode 100644
index affd62f68b..0000000000
--- a/gr-trellis/include/gnuradio/trellis/encoder_XX.h.t
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/api.h>
-#include <gnuradio/trellis/fsm.h>
-#include <gnuradio/sync_block.h>
-
-namespace gr {
-  namespace trellis {
-
-    /*!
-     * \brief Convolutional encoder.
-     * \ingroup trellis_coding_blk
-     */
-    class TRELLIS_API @NAME@ : virtual public sync_block
-    {
-    public:
-      // gr::trellis::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      static sptr make(const fsm &FSM, int ST);
-
-      static sptr make(const fsm &FSM, int ST, int K);
-
-      virtual fsm FSM() const = 0;
-      virtual int ST() const = 0;
-      virtual int K() const = 0;
-      virtual void set_FSM(const fsm &FSM) =0;
-      virtual void set_ST(int ST) =0;
-      virtual void set_K(int K) =0;
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/include/gnuradio/trellis/metrics.h b/gr-trellis/include/gnuradio/trellis/metrics.h
new file mode 100644
index 0000000000..e2ca32222a
--- /dev/null
+++ b/gr-trellis/include/gnuradio/trellis/metrics.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef METRICS_H
+#define METRICS_H
+
+#include <gnuradio/trellis/api.h>
+#include <gnuradio/trellis/calc_metric.h>
+#include <gnuradio/block.h>
+#include <cstdint>
+
+namespace gr {
+  namespace trellis {
+
+    /*!
+     * \brief Evaluate metrics for use by the Viterbi algorithm.
+     * \ingroup trellis_coding_blk
+     */
+template<class T>
+    class TRELLIS_API metrics : virtual public block
+    {
+    public:
+      // gr::trellis::metrics::sptr
+      typedef boost::shared_ptr< metrics<T> > sptr;
+
+      static sptr make(int O, int D, const std::vector<T> &TABLE,
+		       digital::trellis_metric_type_t TYPE);
+
+      virtual int O() const = 0;
+      virtual int D() const = 0;
+      virtual digital::trellis_metric_type_t TYPE() const = 0;
+      virtual std::vector<T> TABLE() const = 0;
+
+      virtual void set_O(int O) = 0;
+      virtual void set_D(int D) = 0;
+      virtual void set_TYPE(digital::trellis_metric_type_t type) = 0;
+      virtual void set_TABLE(const std::vector<T> &table) = 0;
+    };
+
+
+typedef metrics<std::int16_t> metrics_s;
+typedef metrics<std::int32_t> metrics_i;
+typedef metrics<float> metrics_f;
+typedef metrics<gr_complex> metrics_c;
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* METRICS_H */
diff --git a/gr-trellis/include/gnuradio/trellis/metrics_X.h.t b/gr-trellis/include/gnuradio/trellis/metrics_X.h.t
deleted file mode 100644
index f463c865a9..0000000000
--- a/gr-trellis/include/gnuradio/trellis/metrics_X.h.t
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/api.h>
-#include <gnuradio/trellis/calc_metric.h>
-#include <gnuradio/block.h>
-
-namespace gr {
-  namespace trellis {
-
-    /*!
-     * \brief Evaluate metrics for use by the Viterbi algorithm.
-     * \ingroup trellis_coding_blk
-     */
-    class TRELLIS_API @NAME@ : virtual public block
-    {
-    public:
-      // gr::trellis::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      static sptr make(int O, int D, const std::vector<@I_TYPE@> &TABLE,
-		       digital::trellis_metric_type_t TYPE);
-
-      virtual int O() const = 0;
-      virtual int D() const = 0;
-      virtual digital::trellis_metric_type_t TYPE() const = 0;
-      virtual std::vector<@I_TYPE@> TABLE() const = 0;
-
-      virtual void set_O(int O) = 0;
-      virtual void set_D(int D) = 0;
-      virtual void set_TYPE(digital::trellis_metric_type_t type) = 0;
-      virtual void set_TABLE(const std::vector<@I_TYPE@> &table) = 0;
-    };
-
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/include/gnuradio/trellis/pccc_decoder_X.h.t b/gr-trellis/include/gnuradio/trellis/pccc_decoder_X.h.t
deleted file mode 100644
index affce07042..0000000000
--- a/gr-trellis/include/gnuradio/trellis/pccc_decoder_X.h.t
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/api.h>
-#include <gnuradio/trellis/fsm.h>
-#include <gnuradio/trellis/interleaver.h>
-#include <gnuradio/trellis/siso_type.h>
-#include <gnuradio/block.h>
-#include <vector>
-
-namespace gr {
-  namespace trellis {
-
-    /*!
-     *  \ingroup trellis_coding_blk
-     */
-    class TRELLIS_API @NAME@ : virtual public block
-    {
-    public:
-      // gr::trellis::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      static sptr make(const fsm &FSM1, int ST10, int ST1K,
-		       const fsm &FSM2, int ST20, int ST2K,
-		       const interleaver &INTERLEAVER,
-		       int blocklength,
-		       int repetitions,
-		       siso_type_t SISO_TYPE);
-
-      virtual fsm FSM1() const = 0;
-      virtual fsm FSM2() const = 0;
-      virtual int ST10() const = 0;
-      virtual int ST1K() const = 0;
-      virtual int ST20() const = 0;
-      virtual int ST2K() const = 0;
-      virtual interleaver INTERLEAVER() const = 0;
-      virtual int blocklength() const = 0;
-      virtual int repetitions() const = 0;
-      virtual siso_type_t SISO_TYPE() const = 0;
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/include/gnuradio/trellis/pccc_decoder_blk.h b/gr-trellis/include/gnuradio/trellis/pccc_decoder_blk.h
new file mode 100644
index 0000000000..8684f33f03
--- /dev/null
+++ b/gr-trellis/include/gnuradio/trellis/pccc_decoder_blk.h
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef PCCC_DECODER_BLK_H
+#define PCCC_DECODER_BLK_H
+
+#include <gnuradio/trellis/api.h>
+#include <gnuradio/trellis/fsm.h>
+#include <gnuradio/trellis/interleaver.h>
+#include <gnuradio/trellis/siso_type.h>
+#include <gnuradio/block.h>
+#include <vector>
+#include <cstdint>
+
+namespace gr {
+  namespace trellis {
+
+    /*!
+     *  \ingroup trellis_coding_blk
+     */
+template<class T>
+    class TRELLIS_API pccc_decoder_blk : virtual public block
+    {
+    public:
+      // gr::trellis::pccc_decoder_blk::sptr
+      typedef boost::shared_ptr< pccc_decoder_blk<T> > sptr;
+
+      static sptr make(const fsm &FSM1, int ST10, int ST1K,
+		       const fsm &FSM2, int ST20, int ST2K,
+		       const interleaver &INTERLEAVER,
+		       int blocklength,
+		       int repetitions,
+		       siso_type_t SISO_TYPE);
+
+      virtual fsm FSM1() const = 0;
+      virtual fsm FSM2() const = 0;
+      virtual int ST10() const = 0;
+      virtual int ST1K() const = 0;
+      virtual int ST20() const = 0;
+      virtual int ST2K() const = 0;
+      virtual interleaver INTERLEAVER() const = 0;
+      virtual int blocklength() const = 0;
+      virtual int repetitions() const = 0;
+      virtual siso_type_t SISO_TYPE() const = 0;
+    };
+
+typedef pccc_decoder_blk<std::uint8_t> pccc_decoder_b;
+typedef pccc_decoder_blk<std::int16_t> pccc_decoder_s;
+typedef pccc_decoder_blk<std::int32_t> pccc_decoder_i;
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* PCCC_DECODER_BLK_H */
diff --git a/gr-trellis/include/gnuradio/trellis/pccc_decoder_combined_XX.h.t b/gr-trellis/include/gnuradio/trellis/pccc_decoder_combined_XX.h.t
deleted file mode 100644
index 719b0aa1e5..0000000000
--- a/gr-trellis/include/gnuradio/trellis/pccc_decoder_combined_XX.h.t
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/api.h>
-#include <gnuradio/trellis/fsm.h>
-#include <gnuradio/trellis/interleaver.h>
-#include <gnuradio/trellis/calc_metric.h>
-#include <gnuradio/trellis/siso_type.h>
-#include <gnuradio/block.h>
-#include <vector>
-
-namespace gr {
-  namespace trellis {
-
-    /*!
-     *  \ingroup trellis_coding_blk
-     */
-    class TRELLIS_API @NAME@ : virtual public block
-    {
-    public:
-      // gr::trellis::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      static sptr make(const fsm &FSMo, int STo0, int SToK,
-		       const fsm &FSMi, int STi0, int STiK,
-		       const interleaver &INTERLEAVER,
-		       int blocklength,
-		       int repetitions,
-		       siso_type_t SISO_TYPE,
-		       int D,
-		       const std::vector<@I_TYPE@> &TABLE,
-		       digital::trellis_metric_type_t METRIC_TYPE,
-		       float scaling);
-
-      virtual fsm FSM1() const = 0;
-      virtual fsm FSM2() const = 0;
-      virtual int ST10() const = 0;
-      virtual int ST1K() const = 0;
-      virtual int ST20() const = 0;
-      virtual int ST2K() const = 0;
-      virtual interleaver INTERLEAVER() const = 0;
-      virtual int blocklength() const = 0;
-      virtual int repetitions() const = 0;
-      virtual int D() const = 0;
-      virtual std::vector<@I_TYPE@> TABLE() const = 0;
-      virtual digital::trellis_metric_type_t METRIC_TYPE() const = 0;
-      virtual siso_type_t SISO_TYPE() const = 0;
-      virtual float scaling() const = 0;
-      virtual void set_scaling(float scaling) = 0;
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/include/gnuradio/trellis/pccc_decoder_combined_blk.h b/gr-trellis/include/gnuradio/trellis/pccc_decoder_combined_blk.h
new file mode 100644
index 0000000000..e09c08f3bc
--- /dev/null
+++ b/gr-trellis/include/gnuradio/trellis/pccc_decoder_combined_blk.h
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PCCC_DECODER_COMBINED_BLK_H
+#define PCCC_DECODER_COMBINED_BLK_H
+
+#include <gnuradio/trellis/api.h>
+#include <gnuradio/trellis/fsm.h>
+#include <gnuradio/trellis/interleaver.h>
+#include <gnuradio/trellis/calc_metric.h>
+#include <gnuradio/trellis/siso_type.h>
+#include <gnuradio/block.h>
+#include <vector>
+#include <cstdint>
+
+namespace gr {
+  namespace trellis {
+
+    /*!
+     *  \ingroup trellis_coding_blk
+     */
+    template <class IN_T,class OUT_T>
+    class TRELLIS_API pccc_decoder_combined_blk : virtual public block
+    {
+    public:
+      typedef boost::shared_ptr< pccc_decoder_combined_blk<IN_T,OUT_T> > sptr;
+
+      static sptr make(const fsm &FSMo, int STo0, int SToK,
+		       const fsm &FSMi, int STi0, int STiK,
+		       const interleaver &INTERLEAVER,
+		       int blocklength,
+		       int repetitions,
+		       siso_type_t SISO_TYPE,
+		       int D,
+		       const std::vector<IN_T> &TABLE,
+		       digital::trellis_metric_type_t METRIC_TYPE,
+		       float scaling);
+
+      virtual fsm FSM1() const = 0;
+      virtual fsm FSM2() const = 0;
+      virtual int ST10() const = 0;
+      virtual int ST1K() const = 0;
+      virtual int ST20() const = 0;
+      virtual int ST2K() const = 0;
+      virtual interleaver INTERLEAVER() const = 0;
+      virtual int blocklength() const = 0;
+      virtual int repetitions() const = 0;
+      virtual int D() const = 0;
+      virtual std::vector<IN_T> TABLE() const = 0;
+      virtual digital::trellis_metric_type_t METRIC_TYPE() const = 0;
+      virtual siso_type_t SISO_TYPE() const = 0;
+      virtual float scaling() const = 0;
+      virtual void set_scaling(float scaling) = 0;
+    };
+
+    typedef pccc_decoder_combined_blk<float, std::uint8_t> pccc_decoder_combined_fb;
+    typedef pccc_decoder_combined_blk<float, std::int16_t> pccc_decoder_combined_fs;
+    typedef pccc_decoder_combined_blk<float, std::int32_t> pccc_decoder_combined_fi;
+    typedef pccc_decoder_combined_blk<gr_complex, std::uint8_t> pccc_decoder_combined_cb;
+    typedef pccc_decoder_combined_blk<gr_complex, std::int16_t> pccc_decoder_combined_cs;
+    typedef pccc_decoder_combined_blk<gr_complex, std::int32_t> pccc_decoder_combined_ci;
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* PCCC_DECODER_COMBINED_BLK_H */
diff --git a/gr-trellis/include/gnuradio/trellis/pccc_encoder.h b/gr-trellis/include/gnuradio/trellis/pccc_encoder.h
new file mode 100644
index 0000000000..6f3ee25170
--- /dev/null
+++ b/gr-trellis/include/gnuradio/trellis/pccc_encoder.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PCCC_ENCODER_H
+#define PCCC_ENCODER_H
+
+#include <gnuradio/trellis/api.h>
+#include <gnuradio/trellis/fsm.h>
+#include <gnuradio/trellis/interleaver.h>
+#include <gnuradio/sync_block.h>
+#include <vector>
+#include <cstdint>
+
+namespace gr {
+  namespace trellis {
+
+    /*!
+     * \brief PCCC encoder.
+     * \ingroup trellis_coding_blk
+     */
+    template <class IN_T, class OUT_T>
+    class TRELLIS_API pccc_encoder : virtual public sync_block
+    {
+    public:
+      typedef boost::shared_ptr<pccc_encoder<IN_T,OUT_T>> sptr;
+
+      static sptr make(const fsm &FSM1, int ST1,
+		       const fsm &FSM2, int ST2,
+		       const interleaver &INTERLEAVER,
+		       int blocklength);
+
+      virtual fsm FSM1() const = 0;
+      virtual int ST1() const = 0;
+      virtual fsm FSM2() const = 0;
+      virtual int ST2() const = 0;
+      virtual interleaver INTERLEAVER() const = 0;
+      virtual int blocklength() const = 0;
+    };
+    typedef pccc_encoder<std::uint8_t, std::uint8_t> pccc_encoder_bb;
+    typedef pccc_encoder<std::uint8_t, std::int16_t> pccc_encoder_bs;
+    typedef pccc_encoder<std::uint8_t, std::int32_t> pccc_encoder_bi;
+    typedef pccc_encoder<std::int16_t, std::int16_t> pccc_encoder_ss;
+    typedef pccc_encoder<std::int16_t, std::int32_t> pccc_encoder_si;
+    typedef pccc_encoder<std::int32_t, std::int32_t> pccc_encoder_ii;
+
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* PCCC_ENCODER_H */
diff --git a/gr-trellis/include/gnuradio/trellis/pccc_encoder_XX.h.t b/gr-trellis/include/gnuradio/trellis/pccc_encoder_XX.h.t
deleted file mode 100644
index 5308fe275d..0000000000
--- a/gr-trellis/include/gnuradio/trellis/pccc_encoder_XX.h.t
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/api.h>
-#include <gnuradio/trellis/fsm.h>
-#include <gnuradio/trellis/interleaver.h>
-#include <gnuradio/sync_block.h>
-#include <vector>
-
-namespace gr {
-  namespace trellis {
-
-    /*!
-     * \brief PCCC encoder.
-     * \ingroup trellis_coding_blk
-     */
-    class TRELLIS_API @NAME@ : virtual public sync_block
-    {
-    public:
-      // gr::trellis::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      static sptr make(const fsm &FSM1, int ST1,
-		       const fsm &FSM2, int ST2,
-		       const interleaver &INTERLEAVER,
-		       int blocklength);
-
-      virtual fsm FSM1() const = 0;
-      virtual int ST1() const = 0;
-      virtual fsm FSM2() const = 0;
-      virtual int ST2() const = 0;
-      virtual interleaver INTERLEAVER() const = 0;
-      virtual int blocklength() const = 0;
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/include/gnuradio/trellis/sccc_decoder_X.h.t b/gr-trellis/include/gnuradio/trellis/sccc_decoder_X.h.t
deleted file mode 100644
index cc1d86b709..0000000000
--- a/gr-trellis/include/gnuradio/trellis/sccc_decoder_X.h.t
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/api.h>
-#include <gnuradio/trellis/fsm.h>
-#include <gnuradio/trellis/interleaver.h>
-#include <gnuradio/trellis/siso_type.h>
-#include <gnuradio/block.h>
-#include <vector>
-
-namespace gr {
-  namespace trellis {
-
-    /*!
-     *  \ingroup trellis_coding_blk
-     */
-    class TRELLIS_API @NAME@ : virtual public block
-    {
-    public:
-      // gr::trellis::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      static sptr make(const fsm &FSMo, int STo0, int SToK,
-		       const fsm &FSMi, int STi0, int STiK,
-		       const interleaver &INTERLEAVER,
-		       int blocklength,
-		       int repetitions,
-		       siso_type_t SISO_TYPE);
-
-      virtual fsm FSMo() const = 0;
-      virtual fsm FSMi() const = 0;
-      virtual int STo0() const = 0;
-      virtual int SToK() const = 0;
-      virtual int STi0() const = 0;
-      virtual int STiK() const = 0;
-      virtual interleaver INTERLEAVER() const = 0;
-      virtual int blocklength() const = 0;
-      virtual int repetitions() const = 0;
-      virtual siso_type_t SISO_TYPE() const = 0;
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/include/gnuradio/trellis/sccc_decoder_blk.h b/gr-trellis/include/gnuradio/trellis/sccc_decoder_blk.h
new file mode 100644
index 0000000000..48b90dc927
--- /dev/null
+++ b/gr-trellis/include/gnuradio/trellis/sccc_decoder_blk.h
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef SCCC_DECODER_BLK_H
+#define SCCC_DECODER_BLK_H
+
+#include <gnuradio/trellis/api.h>
+#include <gnuradio/trellis/fsm.h>
+#include <gnuradio/trellis/interleaver.h>
+#include <gnuradio/trellis/siso_type.h>
+#include <gnuradio/block.h>
+#include <vector>
+#include <cstdint>
+
+namespace gr {
+  namespace trellis {
+
+    /*!
+     *  \ingroup trellis_coding_blk
+     */
+template<class T>
+    class TRELLIS_API sccc_decoder_blk : virtual public block
+    {
+    public:
+      // gr::trellis::sccc_decoder_blk::sptr
+      typedef boost::shared_ptr< sccc_decoder_blk<T> > sptr;
+
+      static sptr make(const fsm &FSMo, int STo0, int SToK,
+		       const fsm &FSMi, int STi0, int STiK,
+		       const interleaver &INTERLEAVER,
+		       int blocklength,
+		       int repetitions,
+		       siso_type_t SISO_TYPE);
+
+      virtual fsm FSMo() const = 0;
+      virtual fsm FSMi() const = 0;
+      virtual int STo0() const = 0;
+      virtual int SToK() const = 0;
+      virtual int STi0() const = 0;
+      virtual int STiK() const = 0;
+      virtual interleaver INTERLEAVER() const = 0;
+      virtual int blocklength() const = 0;
+      virtual int repetitions() const = 0;
+      virtual siso_type_t SISO_TYPE() const = 0;
+    };
+
+typedef sccc_decoder_blk<std::uint8_t> sccc_decoder_b;
+typedef sccc_decoder_blk<std::int16_t> sccc_decoder_s;
+typedef sccc_decoder_blk<std::int32_t> sccc_decoder_i;
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* SCCC_DECODER_BLK_H */
diff --git a/gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_XX.h.t b/gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_XX.h.t
deleted file mode 100644
index e1f95dff1f..0000000000
--- a/gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_XX.h.t
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/api.h>
-#include <gnuradio/trellis/fsm.h>
-#include <gnuradio/trellis/interleaver.h>
-#include <gnuradio/trellis/calc_metric.h>
-#include <gnuradio/trellis/siso_type.h>
-#include <gnuradio/block.h>
-#include <vector>
-
-namespace gr {
-  namespace trellis {
-
-    /*!
-     *  \ingroup trellis_coding_blk
-     */
-    class TRELLIS_API @NAME@ : virtual public block
-    {
-    public:
-      // gr::trellis::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      static sptr make(const fsm &FSMo, int STo0, int SToK,
-		       const fsm &FSMi, int STi0, int STiK,
-		       const interleaver &INTERLEAVER,
-		       int blocklength,
-		       int repetitions,
-		       siso_type_t SISO_TYPE,
-		       int D,
-		       const std::vector<@I_TYPE@> &TABLE,
-		       digital::trellis_metric_type_t METRIC_TYPE,
-		       float scaling);
-
-      virtual fsm FSMo() const = 0;
-      virtual fsm FSMi() const = 0;
-      virtual int STo0() const = 0;
-      virtual int SToK() const = 0;
-      virtual int STi0() const = 0;
-      virtual int STiK() const = 0;
-      virtual interleaver INTERLEAVER() const = 0;
-      virtual int blocklength() const = 0;
-      virtual int repetitions() const = 0;
-      virtual int D() const = 0;
-      virtual std::vector<@I_TYPE@> TABLE() const = 0;
-      virtual digital::trellis_metric_type_t METRIC_TYPE() const = 0;
-      virtual siso_type_t SISO_TYPE() const = 0;
-      virtual float scaling() const  = 0;
-
-      virtual void set_scaling(float scaling) = 0;
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_blk.h b/gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_blk.h
new file mode 100644
index 0000000000..cfec71e981
--- /dev/null
+++ b/gr-trellis/include/gnuradio/trellis/sccc_decoder_combined_blk.h
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SCCC_DECODER_COMBINED_BLK_H
+#define SCCC_DECODER_COMBINED_BLK_H
+
+#include <gnuradio/trellis/api.h>
+#include <gnuradio/trellis/fsm.h>
+#include <gnuradio/trellis/interleaver.h>
+#include <gnuradio/trellis/calc_metric.h>
+#include <gnuradio/trellis/siso_type.h>
+#include <gnuradio/block.h>
+#include <vector>
+#include <cstdint>
+
+namespace gr {
+  namespace trellis {
+
+    /*!
+     *  \ingroup trellis_coding_blk
+     */
+    template <class IN_T,class OUT_T>
+    class TRELLIS_API sccc_decoder_combined_blk : virtual public block
+    {
+    public:
+      typedef boost::shared_ptr< sccc_decoder_combined_blk<IN_T,OUT_T> > sptr;
+
+      static sptr make(const fsm &FSMo, int STo0, int SToK,
+		       const fsm &FSMi, int STi0, int STiK,
+		       const interleaver &INTERLEAVER,
+		       int blocklength,
+		       int repetitions,
+		       siso_type_t SISO_TYPE,
+		       int D,
+		       const std::vector<IN_T> &TABLE,
+		       digital::trellis_metric_type_t METRIC_TYPE,
+		       float scaling);
+
+      virtual fsm FSMo() const = 0;
+      virtual fsm FSMi() const = 0;
+      virtual int STo0() const = 0;
+      virtual int SToK() const = 0;
+      virtual int STi0() const = 0;
+      virtual int STiK() const = 0;
+      virtual interleaver INTERLEAVER() const = 0;
+      virtual int blocklength() const = 0;
+      virtual int repetitions() const = 0;
+      virtual int D() const = 0;
+      virtual std::vector<IN_T> TABLE() const = 0;
+      virtual digital::trellis_metric_type_t METRIC_TYPE() const = 0;
+      virtual siso_type_t SISO_TYPE() const = 0;
+      virtual float scaling() const  = 0;
+
+      virtual void set_scaling(float scaling) = 0;
+    };
+
+    typedef sccc_decoder_combined_blk<float, std::uint8_t> sccc_decoder_combined_fb;
+    typedef sccc_decoder_combined_blk<float, std::int16_t> sccc_decoder_combined_fs;
+    typedef sccc_decoder_combined_blk<float, std::int32_t> sccc_decoder_combined_fi;
+    typedef sccc_decoder_combined_blk<gr_complex, std::uint8_t> sccc_decoder_combined_cb;
+    typedef sccc_decoder_combined_blk<gr_complex, std::int16_t> sccc_decoder_combined_cs;
+    typedef sccc_decoder_combined_blk<gr_complex, std::int32_t> sccc_decoder_combined_ci;
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* SCCC_DECODER_COMBINED_H */
diff --git a/gr-trellis/include/gnuradio/trellis/sccc_encoder.h b/gr-trellis/include/gnuradio/trellis/sccc_encoder.h
new file mode 100644
index 0000000000..394cce50de
--- /dev/null
+++ b/gr-trellis/include/gnuradio/trellis/sccc_encoder.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SCCC_ENCODER_H
+#define SCCC_ENCODER_H
+
+#include <gnuradio/trellis/api.h>
+#include <gnuradio/trellis/fsm.h>
+#include <gnuradio/trellis/interleaver.h>
+#include <gnuradio/sync_block.h>
+#include <vector>
+
+namespace gr {
+  namespace trellis {
+
+    /*!
+     * \brief SCCC encoder.
+     * \ingroup trellis_coding_blk
+     */
+    template <class IN_T, class OUT_T>
+    class TRELLIS_API sccc_encoder : virtual public sync_block
+    {
+    public:
+      typedef boost::shared_ptr< sccc_encoder<IN_T,OUT_T> > sptr;
+
+      static sptr make(const fsm &FSMo, int STo,
+		       const fsm &FSMi, int STi,
+		       const interleaver &INTERLEAVER,
+		       int blocklength);
+
+      virtual fsm FSMo() const = 0;
+      virtual int STo() const = 0;
+      virtual fsm FSMi() const = 0;
+      virtual int STi() const = 0;
+      virtual interleaver INTERLEAVER() const = 0;
+      virtual int blocklength() const = 0;
+    };
+    typedef sccc_encoder<std::uint8_t, std::uint8_t> sccc_encoder_bb;
+    typedef sccc_encoder<std::uint8_t, std::int16_t> sccc_encoder_bs;
+    typedef sccc_encoder<std::uint8_t, std::int32_t> sccc_encoder_bi;
+    typedef sccc_encoder<std::int16_t, std::int16_t> sccc_encoder_ss;
+    typedef sccc_encoder<std::uint8_t, std::int32_t> sccc_encoder_si;
+    typedef sccc_encoder<std::int32_t, std::int32_t> sccc_encoder_ii;
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* SCCC_ENCODER_H */
diff --git a/gr-trellis/include/gnuradio/trellis/sccc_encoder_XX.h.t b/gr-trellis/include/gnuradio/trellis/sccc_encoder_XX.h.t
deleted file mode 100644
index 85fad02eeb..0000000000
--- a/gr-trellis/include/gnuradio/trellis/sccc_encoder_XX.h.t
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/api.h>
-#include <gnuradio/trellis/fsm.h>
-#include <gnuradio/trellis/interleaver.h>
-#include <gnuradio/sync_block.h>
-#include <vector>
-
-namespace gr {
-  namespace trellis {
-
-    /*!
-     * \brief SCCC encoder.
-     * \ingroup trellis_coding_blk
-     */
-    class TRELLIS_API @NAME@ : virtual public sync_block
-    {
-    public:
-      // gr::trellis::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      static sptr make(const fsm &FSMo, int STo,
-		       const fsm &FSMi, int STi,
-		       const interleaver &INTERLEAVER,
-		       int blocklength);
-
-      virtual fsm FSMo() const = 0;
-      virtual int STo() const = 0;
-      virtual fsm FSMi() const = 0;
-      virtual int STi() const = 0;
-      virtual interleaver INTERLEAVER() const = 0;
-      virtual int blocklength() const = 0;
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/include/gnuradio/trellis/viterbi.h b/gr-trellis/include/gnuradio/trellis/viterbi.h
new file mode 100644
index 0000000000..c37392fb99
--- /dev/null
+++ b/gr-trellis/include/gnuradio/trellis/viterbi.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef VITERBI_H
+#define VITERBI_H
+
+#include <gnuradio/trellis/api.h>
+#include <gnuradio/trellis/fsm.h>
+#include <gnuradio/trellis/core_algorithms.h>
+#include <gnuradio/block.h>
+#include <cstdint>
+
+namespace gr {
+  namespace trellis {
+
+    /*!
+     *  \ingroup trellis_coding_blk
+     */
+template<class T>
+    class TRELLIS_API viterbi : virtual public block
+    {
+    public:
+      // gr::trellis::viterbi::sptr
+      typedef boost::shared_ptr< viterbi<T> > sptr;
+
+      static sptr make(const fsm &FSM, int K,
+		       int S0, int SK);
+
+      virtual fsm FSM() const  = 0;
+      virtual int K()  const = 0;
+      virtual int S0()  const = 0;
+      virtual int SK()  const = 0;
+
+      virtual void set_FSM(const fsm &FSM) =0;
+      virtual void set_K(int K) =0;
+      virtual void set_S0(int S0) =0;
+      virtual void set_SK(int SK) =0;
+    };
+
+typedef viterbi<std::uint8_t> viterbi_b;
+typedef viterbi<std::int16_t> viterbi_s;
+typedef viterbi<std::int32_t> viterbi_i;
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* VITERBI_H */
diff --git a/gr-trellis/include/gnuradio/trellis/viterbi_X.h.t b/gr-trellis/include/gnuradio/trellis/viterbi_X.h.t
deleted file mode 100644
index 252ffb715d..0000000000
--- a/gr-trellis/include/gnuradio/trellis/viterbi_X.h.t
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/api.h>
-#include <gnuradio/trellis/fsm.h>
-#include <gnuradio/trellis/core_algorithms.h>
-#include <gnuradio/block.h>
-
-namespace gr {
-  namespace trellis {
-
-    /*!
-     *  \ingroup trellis_coding_blk
-     */
-    class TRELLIS_API @NAME@ : virtual public block
-    {
-    public:
-      // gr::trellis::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      static sptr make(const fsm &FSM, int K,
-		       int S0, int SK);
-
-      virtual fsm FSM() const  = 0;
-      virtual int K()  const = 0;
-      virtual int S0()  const = 0;
-      virtual int SK()  const = 0;
-
-      virtual void set_FSM(const fsm &FSM) =0;
-      virtual void set_K(int K) =0;
-      virtual void set_S0(int S0) =0;
-      virtual void set_SK(int SK) =0;
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/include/gnuradio/trellis/viterbi_combined.h b/gr-trellis/include/gnuradio/trellis/viterbi_combined.h
new file mode 100644
index 0000000000..b48106a8b4
--- /dev/null
+++ b/gr-trellis/include/gnuradio/trellis/viterbi_combined.h
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef VITERBI_COMBINED_H
+#define VITERBI_COMBINED_H
+
+#include <gnuradio/trellis/api.h>
+#include <gnuradio/trellis/fsm.h>
+#include <gnuradio/trellis/calc_metric.h>
+#include <gnuradio/trellis/core_algorithms.h>
+#include <gnuradio/block.h>
+#include <cstdint>
+
+namespace gr {
+  namespace trellis {
+
+    /*!
+     *  \ingroup trellis_coding_blk
+     */
+    template <class IN_T,class OUT_T>
+    class TRELLIS_API viterbi_combined : virtual public block
+    {
+    public:
+      typedef boost::shared_ptr< viterbi_combined<IN_T,OUT_T> > sptr;
+
+      static sptr make(const fsm &FSM, int K,
+		       int S0, int SK, int D,
+		       const std::vector<IN_T> &TABLE,
+		       digital::trellis_metric_type_t TYPE);
+
+      virtual fsm FSM() const = 0;
+      virtual int K() const = 0;
+      virtual int S0() const  = 0;
+      virtual int SK() const = 0;
+      virtual int D() const = 0;
+      virtual std::vector<IN_T> TABLE() const = 0;
+      virtual digital::trellis_metric_type_t TYPE() const = 0;
+
+      virtual void set_FSM(const fsm &FSM) =0;
+      virtual void set_K(int K) =0;
+      virtual void set_S0(int S0) =0;
+      virtual void set_SK(int SK) =0;
+      virtual void set_D(int D) =0;
+      virtual void set_TABLE (const std::vector<IN_T> &table) = 0;
+      virtual void set_TYPE(digital::trellis_metric_type_t type) = 0;
+    };
+
+    typedef viterbi_combined<std::int16_t, std::uint8_t> viterbi_combined_sb;
+    typedef viterbi_combined<std::int16_t, std::int16_t> viterbi_combined_ss;
+    typedef viterbi_combined<std::int16_t, std::int32_t> viterbi_combined_si;
+    typedef viterbi_combined<std::int32_t, std::uint8_t> viterbi_combined_ib;
+    typedef viterbi_combined<std::int32_t, std::int16_t> viterbi_combined_is;
+    typedef viterbi_combined<std::int32_t, std::int32_t> viterbi_combined_ii;
+    typedef viterbi_combined<float, std::uint8_t> viterbi_combined_fb;
+    typedef viterbi_combined<float, std::int16_t> viterbi_combined_fs;
+    typedef viterbi_combined<float, std::int32_t> viterbi_combined_fi;
+    typedef viterbi_combined<gr_complex, std::uint8_t> viterbi_combined_cb;
+    typedef viterbi_combined<gr_complex, std::int16_t> viterbi_combined_cs;
+    typedef viterbi_combined<gr_complex, std::int32_t> viterbi_combined_ci;
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* VITERBI_COMBINED_H */
diff --git a/gr-trellis/include/gnuradio/trellis/viterbi_combined_XX.h.t b/gr-trellis/include/gnuradio/trellis/viterbi_combined_XX.h.t
deleted file mode 100644
index 4546e95739..0000000000
--- a/gr-trellis/include/gnuradio/trellis/viterbi_combined_XX.h.t
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/api.h>
-#include <gnuradio/trellis/fsm.h>
-#include <gnuradio/trellis/calc_metric.h>
-#include <gnuradio/trellis/core_algorithms.h>
-#include <gnuradio/block.h>
-
-namespace gr {
-  namespace trellis {
-
-    /*!
-     *  \ingroup trellis_coding_blk
-     */
-    class TRELLIS_API @NAME@ : virtual public block
-    {
-    public:
-      // gr::trellis::@BASE_NAME@::sptr
-      typedef boost::shared_ptr<@BASE_NAME@> sptr;
-
-      static sptr make(const fsm &FSM, int K,
-		       int S0, int SK, int D,
-		       const std::vector<@I_TYPE@> &TABLE,
-		       digital::trellis_metric_type_t TYPE);
-
-      virtual fsm FSM() const = 0;
-      virtual int K() const = 0;
-      virtual int S0() const  = 0;
-      virtual int SK() const = 0;
-      virtual int D() const = 0;
-      virtual std::vector<@I_TYPE@> TABLE() const = 0;
-      virtual digital::trellis_metric_type_t TYPE() const = 0;
-
-      virtual void set_FSM(const fsm &FSM) =0;
-      virtual void set_K(int K) =0;
-      virtual void set_S0(int S0) =0;
-      virtual void set_SK(int SK) =0;
-      virtual void set_D(int D) =0;
-      virtual void set_TABLE (const std::vector<@I_TYPE@> &table) = 0;
-      virtual void set_TYPE(digital::trellis_metric_type_t type) = 0;
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/lib/CMakeLists.txt b/gr-trellis/lib/CMakeLists.txt
index a016f9885a..968de82879 100644
--- a/gr-trellis/lib/CMakeLists.txt
+++ b/gr-trellis/lib/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2012,2014 Free Software Foundation, Inc.
+# Copyright 2012,2014,2018 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -34,36 +34,30 @@ if(ENABLE_GR_CTRLPORT)
   ADD_DEFINITIONS(-DGR_CTRLPORT)
 endif(ENABLE_GR_CTRLPORT)
 
-#######################################################################
-# Invoke macro to generate various sources and headers
-########################################################################
-include(GrMiscUtils)
-GR_EXPAND_X_CC_H(trellis encoder_XX_impl                bb bs bi ss si ii)
-GR_EXPAND_X_CC_H(trellis sccc_encoder_XX_impl           bb bs bi ss si ii)
-GR_EXPAND_X_CC_H(trellis pccc_encoder_XX_impl           bb bs bi ss si ii)
-GR_EXPAND_X_CC_H(trellis metrics_X_impl                 s i f c)
-GR_EXPAND_X_CC_H(trellis viterbi_X_impl                 b s i)
-GR_EXPAND_X_CC_H(trellis viterbi_combined_XX_impl       sb ss si ib is ii fb fs fi cb cs ci)
-GR_EXPAND_X_CC_H(trellis sccc_decoder_X_impl            b s i)
-GR_EXPAND_X_CC_H(trellis sccc_decoder_combined_XX_impl  fb fs fi cb cs ci)
-GR_EXPAND_X_CC_H(trellis pccc_decoder_X_impl            b s i)
-GR_EXPAND_X_CC_H(trellis pccc_decoder_combined_XX_impl  fb fs fi cb cs ci)
-
 ########################################################################
 # Setup library
 ########################################################################
 list(APPEND trellis_sources
-    ${generated_sources}
     base.cc
     calc_metric.cc
     core_algorithms.cc
+    encoder_impl.cc
     fsm.cc
     interleaver.cc
     quicksort_index.cc
     constellation_metrics_cf_impl.cc
+    metrics_impl.cc
+    pccc_decoder_blk_impl.cc
+    pccc_encoder_impl.cc
+    pccc_decoder_combined_blk_impl.cc
     permutation_impl.cc
+    sccc_decoder_blk_impl.cc
+    sccc_decoder_combined_blk_impl.cc
+    sccc_encoder_impl.cc
     siso_f_impl.cc
     siso_combined_f_impl.cc
+    viterbi_impl.cc
+    viterbi_combined_impl.cc
 )
 
 list(APPEND trellis_libs
@@ -90,7 +84,7 @@ add_library(gnuradio-trellis SHARED ${trellis_sources})
 target_link_libraries(gnuradio-trellis ${trellis_libs})
 GR_LIBRARY_FOO(gnuradio-trellis)
 add_dependencies(gnuradio-trellis
-  trellis_generated_includes trellis_generated_swigs
+  trellis_generated_swigs
   gnuradio-runtime gnuradio-digital)
 
 if(ENABLE_STATIC_LIBS)
@@ -108,7 +102,7 @@ if(ENABLE_STATIC_LIBS)
   add_library(gnuradio-trellis_static STATIC ${trellis_sources})
 
   add_dependencies(gnuradio-trellis_static
-    trellis_generated_includes trellis_generated_swigs
+    trellis_generated_swigs
     gnuradio-runtime_static gnuradio-digital_static
     )
 
diff --git a/gr-trellis/lib/encoder_XX_impl.cc.t b/gr-trellis/lib/encoder_XX_impl.cc.t
deleted file mode 100644
index 3a004a2f94..0000000000
--- a/gr-trellis/lib/encoder_XX_impl.cc.t
+++ /dev/null
@@ -1,118 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <iostream>
-
-namespace gr {
-  namespace trellis {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(const fsm &FSM, int ST)
-    {
-      return gnuradio::get_initial_sptr
-	(new @IMPL_NAME@(FSM,ST,0,false));
-    }
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(const fsm &FSM, int ST, int K)
-    {
-      return gnuradio::get_initial_sptr
-	(new @IMPL_NAME@(FSM,ST,K,true));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(const fsm &FSM, int ST, int K, bool B)
-    : sync_block("@BASE_NAME@",
-		    io_signature::make(1, 1, sizeof(@I_TYPE@)),
-		    io_signature::make(1, 1, sizeof(@O_TYPE@))),
-      d_FSM(FSM),
-      d_ST(ST),
-      d_K(K),
-      d_B(B)      
-    {
-    }
-
-    void @IMPL_NAME@::set_FSM(const fsm &FSM) 
-    { 
-      gr::thread::scoped_lock guard(d_setlock);
-      d_FSM = FSM; 
-    }
-
-    void @IMPL_NAME@::set_ST(int ST) 
-    { 
-      gr::thread::scoped_lock guard(d_setlock);
-      d_ST = ST; 
-    }
-
-    void @IMPL_NAME@::set_K(int K) 
-    { 
-      gr::thread::scoped_lock guard(d_setlock);
-      d_K = K; 
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-    }
-
-    int
-    @IMPL_NAME@::work(int noutput_items,
-		      gr_vector_const_void_star &input_items,
-		      gr_vector_void_star &output_items)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      int ST_tmp = 0;
-
-      if (d_B){ // blockwise operation
-        int nblocks = noutput_items /d_K;
-	const @I_TYPE@ *in = (const @I_TYPE@*)input_items[0];
-	@O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
-        for(int n = 0; n < nblocks; n++) {
-          ST_tmp = d_ST;
-          for(int i = 0; i < d_K; i++) {
-            out[n*d_K+i] = (@O_TYPE@)d_FSM.OS()[ST_tmp*d_FSM.I()+in[n*d_K+i]];
-            ST_tmp = (int)d_FSM.NS()[ST_tmp*d_FSM.I()+in[n*d_K+i]];
-          }
-        }
-        return nblocks*d_K;
-      } // end blockwise operation
-      else{ // streaming operation
-        const @I_TYPE@ *in = (const @I_TYPE@*)input_items[0];
-        @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
-        ST_tmp = d_ST;
-        for(int i = 0; i < noutput_items; i++) {
-          out[i] = (@O_TYPE@)d_FSM.OS()[ST_tmp*d_FSM.I()+in[i]]; 
-          ST_tmp = (int)d_FSM.NS()[ST_tmp*d_FSM.I()+in[i]];
-        }
-        d_ST = ST_tmp;
-        return noutput_items;
-      } // end streaming operation  
-   }
-
-  } /* namespace trellis */
-} /* namespace gr */
diff --git a/gr-trellis/lib/encoder_XX_impl.h.t b/gr-trellis/lib/encoder_XX_impl.h.t
deleted file mode 100644
index 2b0ff31f4d..0000000000
--- a/gr-trellis/lib/encoder_XX_impl.h.t
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/@BASE_NAME@.h>
-
-namespace gr {
-  namespace trellis {
-
-    class @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      fsm d_FSM;
-      int d_ST;
-      int d_K;
-      bool d_B;
- 
-
-    public:
-      @IMPL_NAME@(const fsm &FSM, int ST, int K, bool B);
-      ~@IMPL_NAME@();
-
-      fsm FSM() const { return d_FSM;; }
-      int ST() const {  return d_ST; }
-      int K() const {  return d_K; }
-      void set_FSM(const fsm &FSM);
-      void set_ST(int ST);
-      void set_K(int K);
-      int work(int noutput_items,
-	       gr_vector_const_void_star &input_items,
-	       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/lib/encoder_impl.cc b/gr-trellis/lib/encoder_impl.cc
new file mode 100644
index 0000000000..ecb0410a5f
--- /dev/null
+++ b/gr-trellis/lib/encoder_impl.cc
@@ -0,0 +1,131 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "encoder_impl.h"
+#include <gnuradio/io_signature.h>
+#include <iostream>
+
+namespace gr {
+  namespace trellis {
+
+    template <class IN_T, class OUT_T>
+    typename encoder<IN_T,OUT_T>::sptr
+    encoder<IN_T,OUT_T>::make(const fsm &FSM, int ST)
+    {
+      return gnuradio::get_initial_sptr
+	(new encoder_impl<IN_T,OUT_T>(FSM,ST,0,false));
+    }
+
+    template <class IN_T, class OUT_T>
+    typename encoder<IN_T,OUT_T>::sptr
+    encoder<IN_T,OUT_T>::make(const fsm &FSM, int ST, int K)
+    {
+      return gnuradio::get_initial_sptr
+	(new encoder_impl<IN_T,OUT_T>(FSM,ST,K,true));
+    }
+
+    template <class IN_T, class OUT_T>
+    encoder_impl<IN_T,OUT_T>::encoder_impl(const fsm &FSM, int ST, int K, bool B)
+    : sync_block("encoder<IN_T,OUT_T>",
+		    io_signature::make(1, 1, sizeof(IN_T)),
+		    io_signature::make(1, 1, sizeof(OUT_T))),
+      d_FSM(FSM),
+      d_ST(ST),
+      d_K(K),
+      d_B(B)
+    {
+    }
+
+    template <class IN_T, class OUT_T>
+    void encoder_impl<IN_T,OUT_T>::set_FSM(const fsm &FSM)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_FSM = FSM;
+    }
+
+    template <class IN_T, class OUT_T>
+    void encoder_impl<IN_T,OUT_T>::set_ST(int ST)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_ST = ST;
+    }
+
+    template <class IN_T, class OUT_T>
+    void encoder_impl<IN_T,OUT_T>::set_K(int K)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_K = K;
+    }
+
+    template <class IN_T, class OUT_T>
+    encoder_impl<IN_T,OUT_T>::~encoder_impl()
+    {
+    }
+
+    template <class IN_T, class OUT_T>
+    int
+    encoder_impl<IN_T,OUT_T>::work(int noutput_items,
+		      gr_vector_const_void_star &input_items,
+		      gr_vector_void_star &output_items)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      int ST_tmp = 0;
+
+      if (d_B){ // blockwise operation
+        int nblocks = noutput_items /d_K;
+	const IN_T *in = (const IN_T*)input_items[0];
+	OUT_T *out = (OUT_T *) output_items[0];
+        for(int n = 0; n < nblocks; n++) {
+          ST_tmp = d_ST;
+          for(int i = 0; i < d_K; i++) {
+            out[n*d_K+i] = (OUT_T)d_FSM.OS()[ST_tmp*d_FSM.I()+in[n*d_K+i]];
+            ST_tmp = (int)d_FSM.NS()[ST_tmp*d_FSM.I()+in[n*d_K+i]];
+          }
+        }
+        return nblocks*d_K;
+      } // end blockwise operation
+      else{ // streaming operation
+        const IN_T *in = (const IN_T*)input_items[0];
+        OUT_T *out = (OUT_T *) output_items[0];
+        ST_tmp = d_ST;
+        for(int i = 0; i < noutput_items; i++) {
+          out[i] = (OUT_T)d_FSM.OS()[ST_tmp*d_FSM.I()+in[i]];
+          ST_tmp = (int)d_FSM.NS()[ST_tmp*d_FSM.I()+in[i]];
+        }
+        d_ST = ST_tmp;
+        return noutput_items;
+      } // end streaming operation
+   }
+    template class encoder<std::uint8_t, std::uint8_t>;
+    template class encoder<std::uint8_t, std::int16_t>;
+    template class encoder<std::uint8_t, std::int32_t>;
+    template class encoder<std::int16_t, std::int16_t>;
+    template class encoder<std::int16_t, std::int32_t>;
+    template class encoder<std::int32_t, std::int32_t>;
+
+
+  } /* namespace trellis */
+} /* namespace gr */
diff --git a/gr-trellis/lib/encoder_impl.h b/gr-trellis/lib/encoder_impl.h
new file mode 100644
index 0000000000..5832b9d848
--- /dev/null
+++ b/gr-trellis/lib/encoder_impl.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef ENCODER_IMPL_H
+#define ENCODER_IMPL_H
+
+#include <gnuradio/trellis/encoder.h>
+
+namespace gr {
+  namespace trellis {
+
+    template <class IN_T, class OUT_T>
+    class encoder_impl : public encoder<IN_T,OUT_T>
+    {
+    private:
+      fsm d_FSM;
+      int d_ST;
+      int d_K;
+      bool d_B;
+
+
+    public:
+      encoder_impl(const fsm &FSM, int ST, int K, bool B);
+      ~encoder_impl();
+
+      fsm FSM() const { return d_FSM;; }
+      int ST() const {  return d_ST; }
+      int K() const {  return d_K; }
+      void set_FSM(const fsm &FSM);
+      void set_ST(int ST);
+      void set_K(int K);
+      int work(int noutput_items,
+	       gr_vector_const_void_star &input_items,
+	       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* ENCODER_IMPL_H */
diff --git a/gr-trellis/lib/metrics_X_impl.cc.t b/gr-trellis/lib/metrics_X_impl.cc.t
deleted file mode 100644
index 5e74e4b2fc..0000000000
--- a/gr-trellis/lib/metrics_X_impl.cc.t
+++ /dev/null
@@ -1,123 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <assert.h>
-#include <stdexcept>
-#include <iostream>
-
-namespace gr {
-  namespace trellis {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(int O, int D,  const std::vector<@I_TYPE@> &TABLE,
-		      digital::trellis_metric_type_t TYPE)
-    {
-      return gnuradio::get_initial_sptr
-	(new @IMPL_NAME@(O,D,TABLE,TYPE));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(int O, int D,  const std::vector<@I_TYPE@> &TABLE,
-			     digital::trellis_metric_type_t TYPE)
-    : block("@BASE_NAME@",
-	       io_signature::make(1, -1, sizeof (@I_TYPE@)),
-	       io_signature::make(1, -1, sizeof (float))),
-      d_O(O), d_D(D), d_TYPE(TYPE), d_TABLE(TABLE)
-    {
-      set_relative_rate (1.0 * d_O / ((double) d_D));
-      set_output_multiple ((int)d_O);
-    }
-
-    void @IMPL_NAME@::set_O(int O)
-    { 
-      gr::thread::scoped_lock guard(d_setlock);
-      d_O = O; 
-      set_relative_rate (1.0 * d_O / ((double) d_D));
-      set_output_multiple ((int)d_O);
-    }
-
-    void @IMPL_NAME@::set_D(int D)
-    { 
-      gr::thread::scoped_lock guard(d_setlock);
-      d_D = D; 
-      set_relative_rate (1.0 * d_O / ((double) d_D));
-    }
-
-    void
-    @IMPL_NAME@::set_TYPE(digital::trellis_metric_type_t type)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      d_TYPE = type;
-    }
-
-    void
-    @IMPL_NAME@::set_TABLE(const std::vector<@I_TYPE@> &table)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      d_TABLE = table;
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-    }
-
-
-    void
-    @IMPL_NAME@::forecast(int noutput_items, gr_vector_int &ninput_items_required)
-    {
-      int input_required = d_D * noutput_items / d_O;
-      unsigned ninputs = ninput_items_required.size();
-      for(unsigned int i = 0; i < ninputs; i++)
-	ninput_items_required[i] = input_required;
-    }
-
-    int
-    @IMPL_NAME@::general_work(int noutput_items,
-			      gr_vector_int &ninput_items,
-			      gr_vector_const_void_star &input_items,
-			      gr_vector_void_star &output_items)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      int nstreams = input_items.size();
-
-      for(int m = 0; m < nstreams; m++) {
-	const @I_TYPE@ *in = (@I_TYPE@*)input_items[m];
-	float *out = (float*)output_items[m];
-
-	for(int i = 0; i < noutput_items / d_O ; i++) {
-	  calc_metric(d_O, d_D, d_TABLE,&(in[i*d_D]), &(out[i*d_O]), d_TYPE);
-	}
-      }
-
-      consume_each(d_D * noutput_items / d_O);
-      return noutput_items;
-    }
-
-  } /* namespace trellis */
-} /* namespace gr */
diff --git a/gr-trellis/lib/metrics_X_impl.h.t b/gr-trellis/lib/metrics_X_impl.h.t
deleted file mode 100644
index 9323ae4645..0000000000
--- a/gr-trellis/lib/metrics_X_impl.h.t
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/@BASE_NAME@.h>
-
-namespace gr {
-  namespace trellis {
-
-    class @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      int d_O;
-      int d_D;
-      digital::trellis_metric_type_t d_TYPE;
-      std::vector<@I_TYPE@> d_TABLE;
-
-    public:
-      @IMPL_NAME@(int O, int D,  const std::vector<@I_TYPE@> &TABLE,
-		  digital::trellis_metric_type_t TYPE);
-      ~@IMPL_NAME@();
-
-      int O() const { return d_O; }
-      int D() const { return d_D; }
-      digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
-      std::vector<@I_TYPE@> TABLE() const { return d_TABLE; }
-
-      void set_O(int O);
-      void set_D(int D);
-      void set_TYPE(digital::trellis_metric_type_t type);
-      void set_TABLE(const std::vector<@I_TYPE@> &table);
-
-      void forecast(int noutput_items,
-		    gr_vector_int &ninput_items_required);
-
-      int general_work(int noutput_items,
-		       gr_vector_int &ninput_items,
-		       gr_vector_const_void_star &input_items,
-		       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/lib/metrics_impl.cc b/gr-trellis/lib/metrics_impl.cc
new file mode 100644
index 0000000000..cf0697c521
--- /dev/null
+++ b/gr-trellis/lib/metrics_impl.cc
@@ -0,0 +1,135 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "metrics_impl.h"
+#include <gnuradio/io_signature.h>
+#include <assert.h>
+#include <stdexcept>
+#include <iostream>
+
+namespace gr {
+  namespace trellis {
+
+    template <class T>
+    typename metrics<T>::sptr
+    metrics<T>::make(int O, int D,  const std::vector<T> &TABLE,
+		      digital::trellis_metric_type_t TYPE)
+    {
+      return gnuradio::get_initial_sptr
+	(new metrics_impl<T>(O,D,TABLE,TYPE));
+    }
+
+    template <class T>
+    metrics_impl<T>::metrics_impl(int O, int D,  const std::vector<T> &TABLE,
+			     digital::trellis_metric_type_t TYPE)
+    : block("metrics",
+	       io_signature::make(1, -1, sizeof (T)),
+	       io_signature::make(1, -1, sizeof (float))),
+      d_O(O), d_D(D), d_TYPE(TYPE), d_TABLE(TABLE)
+    {
+      this->set_relative_rate (1.0 * d_O / ((double) d_D));
+      this->set_output_multiple ((int)d_O);
+    }
+
+    template <class T>
+    void metrics_impl<T>::set_O(int O)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_O = O;
+      this->set_relative_rate (1.0 * d_O / ((double) d_D));
+      this->set_output_multiple ((int)d_O);
+    }
+
+    template <class T>
+    void metrics_impl<T>::set_D(int D)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_D = D;
+      this->set_relative_rate (1.0 * d_O / ((double) d_D));
+    }
+
+    template <class T>
+    void
+    metrics_impl<T>::set_TYPE(digital::trellis_metric_type_t type)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_TYPE = type;
+    }
+
+    template <class T>
+    void
+    metrics_impl<T>::set_TABLE(const std::vector<T> &table)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_TABLE = table;
+    }
+
+    template <class T>
+    metrics_impl<T>::~metrics_impl()
+    {
+    }
+
+
+    template <class T>
+    void
+    metrics_impl<T>::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+    {
+      int input_required = d_D * noutput_items / d_O;
+      unsigned ninputs = ninput_items_required.size();
+      for(unsigned int i = 0; i < ninputs; i++)
+	ninput_items_required[i] = input_required;
+    }
+
+    template <class T>
+    int
+    metrics_impl<T>::general_work(int noutput_items,
+			      gr_vector_int &ninput_items,
+			      gr_vector_const_void_star &input_items,
+			      gr_vector_void_star &output_items)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      int nstreams = input_items.size();
+
+      for(int m = 0; m < nstreams; m++) {
+	const T *in = (T*)input_items[m];
+	float *out = (float*)output_items[m];
+
+	for(int i = 0; i < noutput_items / d_O ; i++) {
+	  calc_metric(d_O, d_D, d_TABLE,&(in[i*d_D]), &(out[i*d_O]), d_TYPE);
+	}
+      }
+
+      this->consume_each(d_D * noutput_items / d_O);
+      return noutput_items;
+    }
+
+template class metrics<std::int16_t>;
+template class metrics<std::int32_t>;
+template class metrics<float>;
+template class metrics<gr_complex>;
+  } /* namespace trellis */
+} /* namespace gr */
diff --git a/gr-trellis/lib/metrics_impl.h b/gr-trellis/lib/metrics_impl.h
new file mode 100644
index 0000000000..95c5f44845
--- /dev/null
+++ b/gr-trellis/lib/metrics_impl.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef METRICS_IMPL_H
+#define METRICS_IMPL_H
+
+#include <gnuradio/trellis/metrics.h>
+
+namespace gr {
+  namespace trellis {
+
+template<class T>
+    class metrics_impl : public  metrics<T>
+    {
+    private:
+      int d_O;
+      int d_D;
+      digital::trellis_metric_type_t d_TYPE;
+      std::vector<T> d_TABLE;
+
+    public:
+      metrics_impl(int O, int D,  const std::vector<T> &TABLE,
+		  digital::trellis_metric_type_t TYPE);
+      ~metrics_impl();
+
+      int O() const { return d_O; }
+      int D() const { return d_D; }
+      digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
+      std::vector<T> TABLE() const { return d_TABLE; }
+
+      void set_O(int O);
+      void set_D(int D);
+      void set_TYPE(digital::trellis_metric_type_t type);
+      void set_TABLE(const std::vector<T> &table);
+
+      void forecast(int noutput_items,
+		    gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+		       gr_vector_int &ninput_items,
+		       gr_vector_const_void_star &input_items,
+		       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* METRICS_IMPL_H */
diff --git a/gr-trellis/lib/pccc_decoder_X_impl.cc.t b/gr-trellis/lib/pccc_decoder_X_impl.cc.t
deleted file mode 100644
index 4f80598540..0000000000
--- a/gr-trellis/lib/pccc_decoder_X_impl.cc.t
+++ /dev/null
@@ -1,118 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <iostream>
-#include <gnuradio/trellis/core_algorithms.h>
-
-namespace gr {
-  namespace trellis {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(const fsm &FSM1, int ST10, int ST1K,
-		      const fsm &FSM2, int ST20, int ST2K,
-		      const interleaver &INTERLEAVER,
-		      int blocklength,
-		      int repetitions,
-		      siso_type_t SISO_TYPE)
-    {
-      return gnuradio::get_initial_sptr
-	(new @IMPL_NAME@(FSM1, ST10, ST1K,
-			 FSM2, ST20, ST2K,
-			 INTERLEAVER,
-			 blocklength,
-			 repetitions,
-			 SISO_TYPE));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(const fsm &FSM1, int ST10, int ST1K,
-			     const fsm &FSM2, int ST20, int ST2K,
-			     const interleaver &INTERLEAVER,
-			     int blocklength,
-			     int repetitions,
-			     siso_type_t SISO_TYPE)
-    : block("@BASE_NAME@",
-	       io_signature::make(1, 1, sizeof(float)),
-	       io_signature::make(1, 1, sizeof(@O_TYPE@))),
-      d_FSM1(FSM1), d_ST10(ST10), d_ST1K(ST1K),
-      d_FSM2(FSM2), d_ST20(ST20), d_ST2K(ST2K),
-      d_INTERLEAVER(INTERLEAVER),
-      d_blocklength(blocklength),
-      d_repetitions(repetitions),
-      d_SISO_TYPE(SISO_TYPE)
-    {
-      set_relative_rate (1.0 / ((double) d_FSM1.O() * d_FSM2.O()));
-      set_output_multiple (d_blocklength);
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-    }
-
-    void
-    @IMPL_NAME@::forecast(int noutput_items,
-			  gr_vector_int &ninput_items_required)
-    {
-      int input_required = d_FSM1.O() * d_FSM2.O() * noutput_items;
-      ninput_items_required[0] = input_required;
-    }
-
-    //===========================================================
-
-    int
-    @IMPL_NAME@::general_work(int noutput_items,
-			      gr_vector_int &ninput_items,
-			      gr_vector_const_void_star &input_items,
-			      gr_vector_void_star &output_items)
-    {
-      int nblocks = noutput_items / d_blocklength;
-
-      float (*p2min)(float, float) = NULL;
-      if(d_SISO_TYPE == TRELLIS_MIN_SUM)
-	p2min = &min;
-      else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
-	p2min = &min_star;
-
-      const float *in = (const float *) input_items[0];
-      @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
-      for(int n=0;n<nblocks;n++) {
-	pccc_decoder(d_FSM1, d_ST10, d_ST1K,
-		     d_FSM2, d_ST20, d_ST2K,
-		     d_INTERLEAVER, d_blocklength, d_repetitions,
-		     p2min,
-		     &(in[n*d_blocklength*d_FSM1.O()*d_FSM2.O()]),
-		     &(out[n*d_blocklength]));
-      }
-
-      consume_each(d_FSM1.O() * d_FSM2.O() * noutput_items);
-      return noutput_items;
-    }
-
-  } /* namespace trellis */
-} /* namespace gr */
diff --git a/gr-trellis/lib/pccc_decoder_X_impl.h.t b/gr-trellis/lib/pccc_decoder_X_impl.h.t
deleted file mode 100644
index 43a7257fc5..0000000000
--- a/gr-trellis/lib/pccc_decoder_X_impl.h.t
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/@BASE_NAME@.h>
-
-namespace gr {
-  namespace trellis {
-
-    class @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      fsm d_FSM1;
-      int d_ST10;
-      int d_ST1K;
-      fsm d_FSM2;
-      int d_ST20;
-      int d_ST2K;
-      interleaver d_INTERLEAVER;
-      int d_blocklength;
-      int d_repetitions;
-      siso_type_t d_SISO_TYPE;
-      std::vector<float> d_buffer;
-
-    public:
-      @IMPL_NAME@(const fsm &FSM1, int ST10, int ST1K,
-		  const fsm &FSM2, int ST20, int ST2K,
-		  const interleaver &INTERLEAVER,
-		  int blocklength,
-		  int repetitions,
-		  siso_type_t SISO_TYPE);
-      ~@IMPL_NAME@();
-
-      fsm FSM1() const { return d_FSM1; }
-      fsm FSM2() const { return d_FSM2; }
-      int ST10() const { return d_ST10; }
-      int ST1K() const { return d_ST1K; }
-      int ST20() const { return d_ST20; }
-      int ST2K() const { return d_ST2K; }
-      interleaver INTERLEAVER() const { return d_INTERLEAVER; }
-      int blocklength() const { return d_blocklength; }
-      int repetitions() const { return d_repetitions; }
-      siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
-
-      void forecast(int noutput_items,
-		    gr_vector_int &ninput_items_required);
-
-      int general_work(int noutput_items,
-		       gr_vector_int &ninput_items,
-		       gr_vector_const_void_star &input_items,
-		       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/lib/pccc_decoder_blk_impl.cc b/gr-trellis/lib/pccc_decoder_blk_impl.cc
new file mode 100644
index 0000000000..3cadff97ea
--- /dev/null
+++ b/gr-trellis/lib/pccc_decoder_blk_impl.cc
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pccc_decoder_blk_impl.h"
+#include <gnuradio/io_signature.h>
+#include <iostream>
+#include <gnuradio/trellis/core_algorithms.h>
+
+namespace gr {
+  namespace trellis {
+
+    template <class T>
+    typename pccc_decoder_blk<T>::sptr
+    pccc_decoder_blk<T>::make(const fsm &FSM1, int ST10, int ST1K,
+		      const fsm &FSM2, int ST20, int ST2K,
+		      const interleaver &INTERLEAVER,
+		      int blocklength,
+		      int repetitions,
+		      siso_type_t SISO_TYPE)
+    {
+      return gnuradio::get_initial_sptr
+	(new pccc_decoder_blk_impl<T>(FSM1, ST10, ST1K,
+			 FSM2, ST20, ST2K,
+			 INTERLEAVER,
+			 blocklength,
+			 repetitions,
+			 SISO_TYPE));
+    }
+
+    template <class T>
+    pccc_decoder_blk_impl<T>::pccc_decoder_blk_impl(const fsm &FSM1, int ST10, int ST1K,
+			     const fsm &FSM2, int ST20, int ST2K,
+			     const interleaver &INTERLEAVER,
+			     int blocklength,
+			     int repetitions,
+			     siso_type_t SISO_TYPE)
+    : block("pccc_decoder_blk",
+	       io_signature::make(1, 1, sizeof(float)),
+	       io_signature::make(1, 1, sizeof(T))),
+      d_FSM1(FSM1), d_ST10(ST10), d_ST1K(ST1K),
+      d_FSM2(FSM2), d_ST20(ST20), d_ST2K(ST2K),
+      d_INTERLEAVER(INTERLEAVER),
+      d_blocklength(blocklength),
+      d_repetitions(repetitions),
+      d_SISO_TYPE(SISO_TYPE)
+    {
+      this->set_relative_rate (1.0 / ((double) d_FSM1.O() * d_FSM2.O()));
+      this->set_output_multiple (d_blocklength);
+    }
+
+    template <class T>
+    pccc_decoder_blk_impl<T>::~pccc_decoder_blk_impl()
+    {
+    }
+
+    template <class T>
+    void
+    pccc_decoder_blk_impl<T>::forecast(int noutput_items,
+			  gr_vector_int &ninput_items_required)
+    {
+      int input_required = d_FSM1.O() * d_FSM2.O() * noutput_items;
+      ninput_items_required[0] = input_required;
+    }
+
+    //===========================================================
+
+    template <class T>
+    int
+    pccc_decoder_blk_impl<T>::general_work(int noutput_items,
+			      gr_vector_int &ninput_items,
+			      gr_vector_const_void_star &input_items,
+			      gr_vector_void_star &output_items)
+    {
+      int nblocks = noutput_items / d_blocklength;
+
+      float (*p2min)(float, float) = NULL;
+      if(d_SISO_TYPE == TRELLIS_MIN_SUM)
+	p2min = &min;
+      else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+	p2min = &min_star;
+
+      const float *in = (const float *) input_items[0];
+      T *out = (T *) output_items[0];
+      for(int n=0;n<nblocks;n++) {
+	pccc_decoder(d_FSM1, d_ST10, d_ST1K,
+		     d_FSM2, d_ST20, d_ST2K,
+		     d_INTERLEAVER, d_blocklength, d_repetitions,
+		     p2min,
+		     &(in[n*d_blocklength*d_FSM1.O()*d_FSM2.O()]),
+		     &(out[n*d_blocklength]));
+      }
+
+      this->consume_each(d_FSM1.O() * d_FSM2.O() * noutput_items);
+      return noutput_items;
+    }
+
+template class pccc_decoder_blk<std::uint8_t>;
+template class pccc_decoder_blk<std::int16_t>;
+template class pccc_decoder_blk<std::int32_t>;
+  } /* namespace trellis */
+} /* namespace gr */
diff --git a/gr-trellis/lib/pccc_decoder_blk_impl.h b/gr-trellis/lib/pccc_decoder_blk_impl.h
new file mode 100644
index 0000000000..ed4e2d24a6
--- /dev/null
+++ b/gr-trellis/lib/pccc_decoder_blk_impl.h
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef PCCC_DECODER_BLK_IMPL_H
+#define PCCC_DECODER_BLK_IMPL_H
+
+#include <gnuradio/trellis/pccc_decoder_blk.h>
+
+namespace gr {
+  namespace trellis {
+
+template<class T>
+    class pccc_decoder_blk_impl  : public  pccc_decoder_blk<T>
+    {
+    private:
+      fsm d_FSM1;
+      int d_ST10;
+      int d_ST1K;
+      fsm d_FSM2;
+      int d_ST20;
+      int d_ST2K;
+      interleaver d_INTERLEAVER;
+      int d_blocklength;
+      int d_repetitions;
+      siso_type_t d_SISO_TYPE;
+      std::vector<float> d_buffer;
+
+    public:
+      pccc_decoder_blk_impl(const fsm &FSM1, int ST10, int ST1K,
+		  const fsm &FSM2, int ST20, int ST2K,
+		  const interleaver &INTERLEAVER,
+		  int blocklength,
+		  int repetitions,
+		  siso_type_t SISO_TYPE);
+      ~pccc_decoder_blk_impl();
+
+      fsm FSM1() const { return d_FSM1; }
+      fsm FSM2() const { return d_FSM2; }
+      int ST10() const { return d_ST10; }
+      int ST1K() const { return d_ST1K; }
+      int ST20() const { return d_ST20; }
+      int ST2K() const { return d_ST2K; }
+      interleaver INTERLEAVER() const { return d_INTERLEAVER; }
+      int blocklength() const { return d_blocklength; }
+      int repetitions() const { return d_repetitions; }
+      siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
+
+      void forecast(int noutput_items,
+		    gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+		       gr_vector_int &ninput_items,
+		       gr_vector_const_void_star &input_items,
+		       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* PCCC_DECODER_BLK_IMPL_H */
diff --git a/gr-trellis/lib/pccc_decoder_combined_XX_impl.cc.t b/gr-trellis/lib/pccc_decoder_combined_XX_impl.cc.t
deleted file mode 100644
index 6841066416..0000000000
--- a/gr-trellis/lib/pccc_decoder_combined_XX_impl.cc.t
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <iostream>
-#include <gnuradio/trellis/core_algorithms.h>
-
-namespace gr {
-  namespace trellis {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(const fsm &FSMo, int STo0, int SToK,
-		      const fsm &FSMi, int STi0, int STiK,
-		      const interleaver &INTERLEAVER,
-		      int blocklength,
-		      int repetitions,
-		      siso_type_t SISO_TYPE,
-		      int D,
-		      const std::vector<@I_TYPE@> &TABLE,
-		      digital::trellis_metric_type_t METRIC_TYPE,
-		      float scaling)
-    {
-      return gnuradio::get_initial_sptr
-	(new @NAME@(FSMo, STo0, SToK, FSMi, STi0, STiK,
-		    INTERLEAVER, blocklength, repetitions,
-		    SISO_TYPE, D, TABLE,METRIC_TYPE, scaling));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(const fsm &FSMo, int STo0, int SToK,
-			     const fsm &FSMi, int STi0, int STiK,
-			     const interleaver &INTERLEAVER,
-			     int blocklength,
-			     int repetitions,
-			     siso_type_t SISO_TYPE,
-			     int D,
-			     const std::vector<@I_TYPE@> &TABLE,
-			     digital::trellis_metric_type_t METRIC_TYPE,
-			     float scaling)
-    : block("@BASE_NAME@",
-	       io_signature::make(1, 1, sizeof(@I_TYPE@)),
-	       io_signature::make(1, 1, sizeof(@O_TYPE@))),
-      d_FSMo(FSMo), d_STo0(STo0), d_SToK(SToK),
-      d_FSMi(FSMi), d_STi0(STi0), d_STiK(STiK),
-      d_INTERLEAVER(INTERLEAVER),
-      d_blocklength(blocklength),
-      d_repetitions(repetitions),
-      d_SISO_TYPE(SISO_TYPE),
-      d_D(D),
-      d_TABLE(TABLE),
-      d_METRIC_TYPE(METRIC_TYPE),
-      d_scaling(scaling)
-    {
-      assert(d_FSMo.I() == d_FSMi.I());
-      set_relative_rate (1.0 / ((double) d_D));
-      set_output_multiple (d_blocklength);
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-    }
-
-    void
-    @IMPL_NAME@::set_scaling(float scaling)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      d_scaling = scaling;
-    }
-
-    void
-    @IMPL_NAME@::forecast(int noutput_items,
-			  gr_vector_int &ninput_items_required)
-    {
-      int input_required = d_D * noutput_items;
-      ninput_items_required[0] = input_required;
-    }
-
-    //===========================================================
-
-    int
-    @IMPL_NAME@::general_work(int noutput_items,
-			      gr_vector_int &ninput_items,
-			      gr_vector_const_void_star &input_items,
-			      gr_vector_void_star &output_items)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      int nblocks = noutput_items / d_blocklength;
-
-      float (*p2min)(float, float) = NULL;
-      if(d_SISO_TYPE == TRELLIS_MIN_SUM)
-	p2min = &min;
-      else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
-	p2min = &min_star;
-
-      const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0];
-      @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
-      for (int n=0;n<nblocks;n++) {
-	pccc_decoder_combined(d_FSMo, d_STo0, d_SToK,
-			      d_FSMi, d_STi0, d_STiK,
-			      d_INTERLEAVER, d_blocklength, d_repetitions,
-			      p2min,
-			      d_D,d_TABLE,
-			      d_METRIC_TYPE,
-			      d_scaling,
-			      &(in[n*d_blocklength*d_D]),
-			      &(out[n*d_blocklength]));
-      }
-
-      consume_each(d_D * noutput_items);
-      return noutput_items;
-    }
-
-  } /* namespace trellis */
-} /* namespace gr */
diff --git a/gr-trellis/lib/pccc_decoder_combined_XX_impl.h.t b/gr-trellis/lib/pccc_decoder_combined_XX_impl.h.t
deleted file mode 100644
index 7606017547..0000000000
--- a/gr-trellis/lib/pccc_decoder_combined_XX_impl.h.t
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/@BASE_NAME@.h>
-
-namespace gr {
-  namespace trellis {
-
-    class @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      fsm d_FSMo;
-      int d_STo0;
-      int d_SToK;
-      fsm d_FSMi;
-      int d_STi0;
-      int d_STiK;
-      interleaver d_INTERLEAVER;
-      int d_blocklength;
-      int d_repetitions;
-      siso_type_t d_SISO_TYPE;
-      int d_D;
-      std::vector<@I_TYPE@> d_TABLE;
-      digital::trellis_metric_type_t d_METRIC_TYPE;
-      float d_scaling;
-      std::vector<float> d_buffer;
-
-    public:
-      @IMPL_NAME@(const fsm &FSMo, int STo0, int SToK,
-		  const fsm &FSMi, int STi0, int STiK,
-		  const interleaver &INTERLEAVER,
-		  int blocklength,
-		  int repetitions,
-		  siso_type_t SISO_TYPE,
-		  int D,
-		  const std::vector<@I_TYPE@> &TABLE,
-		  digital::trellis_metric_type_t METRIC_TYPE,
-		  float scaling);
-      ~@IMPL_NAME@();
-
-      fsm FSM1() const { return d_FSMo; }
-      fsm FSM2() const { return d_FSMi; }
-      int ST10() const { return d_STo0; }
-      int ST1K() const { return d_SToK; }
-      int ST20() const { return d_STi0; }
-      int ST2K() const { return d_STiK; }
-      interleaver INTERLEAVER() const { return d_INTERLEAVER; }
-      int blocklength() const { return d_blocklength; }
-      int repetitions() const { return d_repetitions; }
-      int D() const { return d_D; }
-      std::vector<@I_TYPE@> TABLE() const { return d_TABLE; }
-      digital::trellis_metric_type_t METRIC_TYPE() const { return d_METRIC_TYPE; }
-      siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
-      float scaling() const { return d_scaling; }
-      void set_scaling(float scaling);
-
-      void forecast(int noutput_items,
-		    gr_vector_int &ninput_items_required);
-
-      int general_work(int noutput_items,
-		       gr_vector_int &ninput_items,
-		       gr_vector_const_void_star &input_items,
-		       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/lib/pccc_decoder_combined_blk_impl.cc b/gr-trellis/lib/pccc_decoder_combined_blk_impl.cc
new file mode 100644
index 0000000000..a985c0d9c0
--- /dev/null
+++ b/gr-trellis/lib/pccc_decoder_combined_blk_impl.cc
@@ -0,0 +1,150 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pccc_decoder_combined_blk_impl.h"
+#include <gnuradio/io_signature.h>
+#include <iostream>
+#include <gnuradio/trellis/core_algorithms.h>
+
+namespace gr {
+  namespace trellis {
+
+    template <class IN_T,class OUT_T>
+    typename pccc_decoder_combined_blk<IN_T,OUT_T>::sptr
+    pccc_decoder_combined_blk<IN_T,OUT_T>::make(const fsm &FSMo, int STo0, int SToK,
+		      const fsm &FSMi, int STi0, int STiK,
+		      const interleaver &INTERLEAVER,
+		      int blocklength,
+		      int repetitions,
+		      siso_type_t SISO_TYPE,
+		      int D,
+		      const std::vector<IN_T> &TABLE,
+		      digital::trellis_metric_type_t METRIC_TYPE,
+		      float scaling)
+    {
+      return gnuradio::get_initial_sptr
+	(new pccc_decoder_combined_blk_impl<IN_T,OUT_T>(FSMo, STo0, SToK, FSMi, STi0, STiK,
+		    INTERLEAVER, blocklength, repetitions,
+		    SISO_TYPE, D, TABLE,METRIC_TYPE, scaling));
+    }
+
+    template <class IN_T,class OUT_T>
+    pccc_decoder_combined_blk_impl<IN_T,OUT_T>::pccc_decoder_combined_blk_impl(const fsm &FSMo, int STo0, int SToK,
+			     const fsm &FSMi, int STi0, int STiK,
+			     const interleaver &INTERLEAVER,
+			     int blocklength,
+			     int repetitions,
+			     siso_type_t SISO_TYPE,
+			     int D,
+			     const std::vector<IN_T> &TABLE,
+			     digital::trellis_metric_type_t METRIC_TYPE,
+			     float scaling)
+    : block("pccc_decoder_combined_blk<IN_T,OUT_T>",
+	       io_signature::make(1, 1, sizeof(IN_T)),
+	       io_signature::make(1, 1, sizeof(OUT_T))),
+      d_FSMo(FSMo), d_STo0(STo0), d_SToK(SToK),
+      d_FSMi(FSMi), d_STi0(STi0), d_STiK(STiK),
+      d_INTERLEAVER(INTERLEAVER),
+      d_blocklength(blocklength),
+      d_repetitions(repetitions),
+      d_SISO_TYPE(SISO_TYPE),
+      d_D(D),
+      d_TABLE(TABLE),
+      d_METRIC_TYPE(METRIC_TYPE),
+      d_scaling(scaling)
+    {
+      assert(d_FSMo.I() == d_FSMi.I());
+      this->set_relative_rate (1.0 / ((double) d_D));
+      this->set_output_multiple (d_blocklength);
+    }
+
+    template <class IN_T,class OUT_T>
+    pccc_decoder_combined_blk_impl<IN_T,OUT_T>::~pccc_decoder_combined_blk_impl()
+    {
+    }
+
+    template <class IN_T,class OUT_T>
+    void
+    pccc_decoder_combined_blk_impl<IN_T,OUT_T>::set_scaling(float scaling)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_scaling = scaling;
+    }
+
+    template <class IN_T,class OUT_T>
+    void
+    pccc_decoder_combined_blk_impl<IN_T,OUT_T>::forecast(int noutput_items,
+			  gr_vector_int &ninput_items_required)
+    {
+      int input_required = d_D * noutput_items;
+      ninput_items_required[0] = input_required;
+    }
+
+    //===========================================================
+
+    template <class IN_T,class OUT_T>
+    int
+    pccc_decoder_combined_blk_impl<IN_T,OUT_T>::general_work(int noutput_items,
+			      gr_vector_int &ninput_items,
+			      gr_vector_const_void_star &input_items,
+			      gr_vector_void_star &output_items)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      int nblocks = noutput_items / d_blocklength;
+
+      float (*p2min)(float, float) = NULL;
+      if(d_SISO_TYPE == TRELLIS_MIN_SUM)
+	p2min = &min;
+      else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+	p2min = &min_star;
+
+      const IN_T *in = (const IN_T *) input_items[0];
+      OUT_T *out = (OUT_T *) output_items[0];
+      for (int n=0;n<nblocks;n++) {
+	pccc_decoder_combined(d_FSMo, d_STo0, d_SToK,
+			      d_FSMi, d_STi0, d_STiK,
+			      d_INTERLEAVER, d_blocklength, d_repetitions,
+			      p2min,
+			      d_D,d_TABLE,
+			      d_METRIC_TYPE,
+			      d_scaling,
+			      &(in[n*d_blocklength*d_D]),
+			      &(out[n*d_blocklength]));
+      }
+
+      this->consume_each(d_D * noutput_items);
+      return noutput_items;
+    }
+    template class pccc_decoder_combined_blk<float, std::uint8_t>;
+    template class pccc_decoder_combined_blk<float, std::int16_t>;
+    template class pccc_decoder_combined_blk<float, std::int32_t>;
+    template class pccc_decoder_combined_blk<gr_complex, std::uint8_t>;
+    template class pccc_decoder_combined_blk<gr_complex, std::int16_t>;
+    template class pccc_decoder_combined_blk<gr_complex, std::int32_t>;
+
+
+  } /* namespace trellis */
+} /* namespace gr */
diff --git a/gr-trellis/lib/pccc_decoder_combined_blk_impl.h b/gr-trellis/lib/pccc_decoder_combined_blk_impl.h
new file mode 100644
index 0000000000..544a965607
--- /dev/null
+++ b/gr-trellis/lib/pccc_decoder_combined_blk_impl.h
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PCCC_DECODER_COMBINED_BLK_IMPL_H
+#define PCCC_DECODER_COMBINED_BLK_IMPL_H
+
+#include <gnuradio/trellis/pccc_decoder_combined_blk.h>
+
+namespace gr {
+  namespace trellis {
+
+    template <class IN_T,class OUT_T>
+    class pccc_decoder_combined_blk_impl : public pccc_decoder_combined_blk<IN_T,OUT_T>
+    {
+    private:
+      fsm d_FSMo;
+      int d_STo0;
+      int d_SToK;
+      fsm d_FSMi;
+      int d_STi0;
+      int d_STiK;
+      interleaver d_INTERLEAVER;
+      int d_blocklength;
+      int d_repetitions;
+      siso_type_t d_SISO_TYPE;
+      int d_D;
+      std::vector<IN_T> d_TABLE;
+      digital::trellis_metric_type_t d_METRIC_TYPE;
+      float d_scaling;
+      std::vector<float> d_buffer;
+
+    public:
+      pccc_decoder_combined_blk_impl(const fsm &FSMo, int STo0, int SToK,
+		  const fsm &FSMi, int STi0, int STiK,
+		  const interleaver &INTERLEAVER,
+		  int blocklength,
+		  int repetitions,
+		  siso_type_t SISO_TYPE,
+		  int D,
+		  const std::vector<IN_T> &TABLE,
+		  digital::trellis_metric_type_t METRIC_TYPE,
+		  float scaling);
+      ~pccc_decoder_combined_blk_impl();
+
+      fsm FSM1() const { return d_FSMo; }
+      fsm FSM2() const { return d_FSMi; }
+      int ST10() const { return d_STo0; }
+      int ST1K() const { return d_SToK; }
+      int ST20() const { return d_STi0; }
+      int ST2K() const { return d_STiK; }
+      interleaver INTERLEAVER() const { return d_INTERLEAVER; }
+      int blocklength() const { return d_blocklength; }
+      int repetitions() const { return d_repetitions; }
+      int D() const { return d_D; }
+      std::vector<IN_T> TABLE() const { return d_TABLE; }
+      digital::trellis_metric_type_t METRIC_TYPE() const { return d_METRIC_TYPE; }
+      siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
+      float scaling() const { return d_scaling; }
+      void set_scaling(float scaling);
+
+      void forecast(int noutput_items,
+		    gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+		       gr_vector_int &ninput_items,
+		       gr_vector_const_void_star &input_items,
+		       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* PCCC_DECODER_COMBINED_BLK_IMPL_H */
diff --git a/gr-trellis/lib/pccc_encoder_XX_impl.cc.t b/gr-trellis/lib/pccc_encoder_XX_impl.cc.t
deleted file mode 100644
index 8fd143ca9d..0000000000
--- a/gr-trellis/lib/pccc_encoder_XX_impl.cc.t
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <iostream>
-
-namespace gr {
-  namespace trellis {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(const fsm &FSM1, int ST1,
-		      const fsm &FSM2, int ST2,
-		      const interleaver &INTERLEAVER,
-		      int blocklength)
-    {
-      return gnuradio::get_initial_sptr
-	(new @IMPL_NAME@(FSM1, ST1, FSM2, ST2, INTERLEAVER, blocklength));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(const fsm &FSM1, int ST1,
-			     const fsm &FSM2, int ST2,
-			     const interleaver &INTERLEAVER,
-			     int blocklength)
-    : sync_block("@BASE_NAME@",
-		    io_signature::make(1, 1, sizeof(@I_TYPE@)),
-		    io_signature::make(1, 1, sizeof(@O_TYPE@))),
-      d_FSM1(FSM1), d_ST1(ST1),
-      d_FSM2(FSM2), d_ST2(ST2),
-      d_INTERLEAVER(INTERLEAVER),
-      d_blocklength(blocklength)
-    {
-      assert(d_FSM1.I() == d_FSM2.I());
-      set_output_multiple(d_blocklength);
-      d_buffer.resize(d_blocklength);
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-    }
-
-    int
-    @NAME@::work(int noutput_items,
-		 gr_vector_const_void_star &input_items,
-		 gr_vector_void_star &output_items)
-    {
-      for(int b = 0 ; b<noutput_items/d_blocklength; b++) {
-	const @I_TYPE@ *in = (const @I_TYPE@*)input_items[0]+b*d_blocklength;
-	@O_TYPE@ *out = (@O_TYPE@*)output_items[0]+b*d_blocklength;
-
-	int ST1_tmp = d_ST1;
-	int ST2_tmp = d_ST2;
-	for(int i = 0; i < d_blocklength; i++) {
-	  int k = d_INTERLEAVER.INTER()[i];
-	  int o1 = d_FSM1.OS()[ST1_tmp*d_FSM1.I()+in[i]];
-	  ST1_tmp = (int) d_FSM1.NS()[ST1_tmp*d_FSM1.I()+in[i]];
-	  int o2 = d_FSM2.OS()[ST2_tmp*d_FSM2.I()+in[k]];
-	  ST2_tmp = (int) d_FSM2.NS()[ST2_tmp*d_FSM2.I()+in[k]];
-	  out[i] = (@O_TYPE@) (o1*d_FSM2.O() + o2);
-	}
-      }
-      return noutput_items;
-    }
-
-  } /* namespace trellis */
-} /* namespace gr */
diff --git a/gr-trellis/lib/pccc_encoder_XX_impl.h.t b/gr-trellis/lib/pccc_encoder_XX_impl.h.t
deleted file mode 100644
index 5561b716d3..0000000000
--- a/gr-trellis/lib/pccc_encoder_XX_impl.h.t
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/@BASE_NAME@.h>
-
-namespace gr {
-  namespace trellis {
-
-    class @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      fsm d_FSM1;
-      int d_ST1;
-      fsm d_FSM2;
-      int d_ST2;
-      interleaver d_INTERLEAVER;
-      int d_blocklength;
-      std::vector<int> d_buffer;
-
-    public:
-      @IMPL_NAME@(const fsm &FSM1, int ST1,
-		  const fsm &FSM2, int ST2,
-		  const interleaver &INTERLEAVER,
-		  int blocklength);
-      ~@IMPL_NAME@();
-
-      fsm FSM1() const { return d_FSM1; }
-      int ST1() const { return d_ST1; }
-      fsm FSM2() const { return d_FSM2; }
-      int ST2() const { return d_ST2; }
-      interleaver INTERLEAVER() const { return d_INTERLEAVER; }
-      int blocklength() const { return d_blocklength; }
-
-      int work(int noutput_items,
-	       gr_vector_const_void_star &input_items,
-	       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/lib/pccc_encoder_impl.cc b/gr-trellis/lib/pccc_encoder_impl.cc
new file mode 100644
index 0000000000..2804f4b39c
--- /dev/null
+++ b/gr-trellis/lib/pccc_encoder_impl.cc
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pccc_encoder_impl.h"
+#include <gnuradio/io_signature.h>
+#include <iostream>
+
+namespace gr {
+  namespace trellis {
+
+    template <class IN_T, class OUT_T>
+    typename pccc_encoder<IN_T,OUT_T>::sptr
+    pccc_encoder<IN_T,OUT_T>::make(const fsm &FSM1, int ST1,
+		      const fsm &FSM2, int ST2,
+		      const interleaver &INTERLEAVER,
+		      int blocklength)
+    {
+      return gnuradio::get_initial_sptr
+	(new pccc_encoder_impl<IN_T,OUT_T>(FSM1, ST1, FSM2, ST2, INTERLEAVER, blocklength));
+    }
+
+    template <class IN_T, class OUT_T>
+    pccc_encoder_impl<IN_T,OUT_T>::pccc_encoder_impl(const fsm &FSM1, int ST1,
+			     const fsm &FSM2, int ST2,
+			     const interleaver &INTERLEAVER,
+			     int blocklength)
+    : sync_block("pccc_encoder<IN_T,OUT_T>",
+		    io_signature::make(1, 1, sizeof(IN_T)),
+		    io_signature::make(1, 1, sizeof(OUT_T))),
+      d_FSM1(FSM1), d_ST1(ST1),
+      d_FSM2(FSM2), d_ST2(ST2),
+      d_INTERLEAVER(INTERLEAVER),
+      d_blocklength(blocklength)
+    {
+      assert(d_FSM1.I() == d_FSM2.I());
+      this->set_output_multiple(d_blocklength);
+      d_buffer.resize(d_blocklength);
+    }
+
+    template <class IN_T, class OUT_T>
+    pccc_encoder_impl<IN_T,OUT_T>::~pccc_encoder_impl()
+    {
+    }
+
+    template <class IN_T, class OUT_T>
+    int
+    pccc_encoder_impl<IN_T,OUT_T>::work(int noutput_items,
+		 gr_vector_const_void_star &input_items,
+		 gr_vector_void_star &output_items)
+    {
+      for(int b = 0 ; b<noutput_items/d_blocklength; b++) {
+	const IN_T *in = (const IN_T*)input_items[0]+b*d_blocklength;
+	OUT_T *out = (OUT_T*)output_items[0]+b*d_blocklength;
+
+	int ST1_tmp = d_ST1;
+	int ST2_tmp = d_ST2;
+	for(int i = 0; i < d_blocklength; i++) {
+	  int k = d_INTERLEAVER.INTER()[i];
+	  int o1 = d_FSM1.OS()[ST1_tmp*d_FSM1.I()+in[i]];
+	  ST1_tmp = (int) d_FSM1.NS()[ST1_tmp*d_FSM1.I()+in[i]];
+	  int o2 = d_FSM2.OS()[ST2_tmp*d_FSM2.I()+in[k]];
+	  ST2_tmp = (int) d_FSM2.NS()[ST2_tmp*d_FSM2.I()+in[k]];
+	  out[i] = (OUT_T) (o1*d_FSM2.O() + o2);
+	}
+      }
+      return noutput_items;
+    }
+    template class pccc_encoder<std::uint8_t, std::uint8_t>;
+    template class pccc_encoder<std::uint8_t, std::int16_t>;
+    template class pccc_encoder<std::uint8_t, std::int32_t>;
+    template class pccc_encoder<std::int16_t, std::int16_t>;
+    template class pccc_encoder<std::int16_t, std::int32_t>;
+    template class pccc_encoder<std::int32_t, std::int32_t>;
+
+  } /* namespace trellis */
+} /* namespace gr */
diff --git a/gr-trellis/lib/pccc_encoder_impl.h b/gr-trellis/lib/pccc_encoder_impl.h
new file mode 100644
index 0000000000..834e8986c4
--- /dev/null
+++ b/gr-trellis/lib/pccc_encoder_impl.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PCCC_ENCODER_IMPL_H
+#define PCCC_ENCODER_IMPL_H
+
+#include <gnuradio/trellis/pccc_encoder.h>
+
+namespace gr {
+  namespace trellis {
+
+    template <class IN_T, class OUT_T>
+    class pccc_encoder_impl : public pccc_encoder<IN_T,OUT_T>
+    {
+    private:
+      fsm d_FSM1;
+      int d_ST1;
+      fsm d_FSM2;
+      int d_ST2;
+      interleaver d_INTERLEAVER;
+      int d_blocklength;
+      std::vector<int> d_buffer;
+
+    public:
+      pccc_encoder_impl(const fsm &FSM1, int ST1,
+		  const fsm &FSM2, int ST2,
+		  const interleaver &INTERLEAVER,
+		  int blocklength);
+      ~pccc_encoder_impl();
+
+      fsm FSM1() const { return d_FSM1; }
+      int ST1() const { return d_ST1; }
+      fsm FSM2() const { return d_FSM2; }
+      int ST2() const { return d_ST2; }
+      interleaver INTERLEAVER() const { return d_INTERLEAVER; }
+      int blocklength() const { return d_blocklength; }
+
+      int work(int noutput_items,
+	       gr_vector_const_void_star &input_items,
+	       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* PCCC_ENCODER_IMPL_H */
diff --git a/gr-trellis/lib/sccc_decoder_X_impl.cc.t b/gr-trellis/lib/sccc_decoder_X_impl.cc.t
deleted file mode 100644
index 6f1bac585a..0000000000
--- a/gr-trellis/lib/sccc_decoder_X_impl.cc.t
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <iostream>
-#include <gnuradio/trellis/core_algorithms.h>
-
-namespace gr {
-  namespace trellis {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(const fsm &FSMo, int STo0, int SToK,
-		      const fsm &FSMi, int STi0, int STiK,
-		      const interleaver &INTERLEAVER,
-		      int blocklength,
-		      int repetitions,
-		      siso_type_t SISO_TYPE)
-    {
-      return gnuradio::get_initial_sptr
-	(new @IMPL_NAME@(FSMo, STo0, SToK, FSMi, STi0, STiK,
-			 INTERLEAVER, blocklength, repetitions,
-			 SISO_TYPE));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(const fsm &FSMo, int STo0, int SToK,
-			     const fsm &FSMi, int STi0, int STiK,
-			     const interleaver &INTERLEAVER,
-			     int blocklength,
-			     int repetitions,
-			     siso_type_t SISO_TYPE)
-    : block("@BASE_NAME@",
-	       io_signature::make(1, 1, sizeof(float)),
-	       io_signature::make(1, 1, sizeof(@O_TYPE@))),
-      d_FSMo(FSMo), d_STo0(STo0), d_SToK(SToK),
-      d_FSMi(FSMi), d_STi0(STi0), d_STiK(STiK),
-      d_INTERLEAVER(INTERLEAVER),
-      d_blocklength(blocklength),
-      d_repetitions(repetitions),
-      d_SISO_TYPE(SISO_TYPE)
-    {
-      set_relative_rate(1.0 / ((double) d_FSMi.O()));
-      set_output_multiple(d_blocklength);
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-    }
-
-    void
-    @IMPL_NAME@::forecast(int noutput_items,
-			  gr_vector_int &ninput_items_required)
-    {
-      int input_required =  d_FSMi.O() * noutput_items ;
-      ninput_items_required[0] = input_required;
-    }
-
-    //===========================================================
-
-    int
-    @IMPL_NAME@::general_work(int noutput_items,
-			      gr_vector_int &ninput_items,
-			      gr_vector_const_void_star &input_items,
-			      gr_vector_void_star &output_items)
-    {
-      int nblocks = noutput_items / d_blocklength;
-      float (*p2min)(float, float) = NULL;
-
-      if(d_SISO_TYPE == TRELLIS_MIN_SUM)
-	p2min = &min;
-      else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
-	p2min = &min_star;
-
-      const float *in = (const float*)input_items[0];
-      @O_TYPE@ *out = (@O_TYPE@*)output_items[0];
-
-      for(int n = 0; n < nblocks; n++) {
-	sccc_decoder(d_FSMo, d_STo0, d_SToK,
-		     d_FSMi, d_STi0, d_STiK,
-		     d_INTERLEAVER, d_blocklength, d_repetitions,
-		     p2min,
-		     &(in[n*d_blocklength*d_FSMi.O()]),
-		     &(out[n*d_blocklength]));
-      }
-
-      consume_each(d_FSMi.O() * noutput_items );
-      return noutput_items;
-    }
-
-  } /* namespace trellis */
-} /* namespace gr */
diff --git a/gr-trellis/lib/sccc_decoder_X_impl.h.t b/gr-trellis/lib/sccc_decoder_X_impl.h.t
deleted file mode 100644
index c79e6ebbab..0000000000
--- a/gr-trellis/lib/sccc_decoder_X_impl.h.t
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/@BASE_NAME@.h>
-
-namespace gr {
-  namespace trellis {
-
-    class @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      fsm d_FSMo;
-      int d_STo0;
-      int d_SToK;
-      fsm d_FSMi;
-      int d_STi0;
-      int d_STiK;
-      interleaver d_INTERLEAVER;
-      int d_blocklength;
-      int d_repetitions;
-      siso_type_t d_SISO_TYPE;
-      std::vector<float> d_buffer;
-
-    public:
-      @IMPL_NAME@(const fsm &FSMo, int STo0, int SToK,
-		  const fsm &FSMi, int STi0, int STiK,
-		  const interleaver &INTERLEAVER,
-		  int blocklength,
-		  int repetitions,
-		  siso_type_t SISO_TYPE);
-      ~@IMPL_NAME@();
-
-      fsm FSMo() const { return d_FSMo; }
-      fsm FSMi() const { return d_FSMi; }
-      int STo0() const { return d_STo0; }
-      int SToK() const { return d_SToK; }
-      int STi0() const { return d_STi0; }
-      int STiK() const { return d_STiK; }
-      interleaver INTERLEAVER() const { return d_INTERLEAVER; }
-      int blocklength() const { return d_blocklength; }
-      int repetitions() const { return d_repetitions; }
-      siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
-
-      void forecast(int noutput_items,
-		    gr_vector_int &ninput_items_required);
-
-      int general_work(int noutput_items,
-		       gr_vector_int &ninput_items,
-		       gr_vector_const_void_star &input_items,
-		       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/lib/sccc_decoder_blk_impl.cc b/gr-trellis/lib/sccc_decoder_blk_impl.cc
new file mode 100644
index 0000000000..7855f9f0fe
--- /dev/null
+++ b/gr-trellis/lib/sccc_decoder_blk_impl.cc
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sccc_decoder_blk_impl.h"
+#include <gnuradio/io_signature.h>
+#include <iostream>
+#include <gnuradio/trellis/core_algorithms.h>
+
+namespace gr {
+  namespace trellis {
+
+    template <class T>
+    typename sccc_decoder_blk<T>::sptr
+    sccc_decoder_blk<T>::make(const fsm &FSMo, int STo0, int SToK,
+		      const fsm &FSMi, int STi0, int STiK,
+		      const interleaver &INTERLEAVER,
+		      int blocklength,
+		      int repetitions,
+		      siso_type_t SISO_TYPE)
+    {
+      return gnuradio::get_initial_sptr
+	(new sccc_decoder_blk_impl<T>(FSMo, STo0, SToK, FSMi, STi0, STiK,
+			 INTERLEAVER, blocklength, repetitions,
+			 SISO_TYPE));
+    }
+
+    template <class T>
+    sccc_decoder_blk_impl<T>::sccc_decoder_blk_impl(const fsm &FSMo, int STo0, int SToK,
+			     const fsm &FSMi, int STi0, int STiK,
+			     const interleaver &INTERLEAVER,
+			     int blocklength,
+			     int repetitions,
+			     siso_type_t SISO_TYPE)
+    : block("sccc_decoder_blk",
+	       io_signature::make(1, 1, sizeof(float)),
+	       io_signature::make(1, 1, sizeof(T))),
+      d_FSMo(FSMo), d_STo0(STo0), d_SToK(SToK),
+      d_FSMi(FSMi), d_STi0(STi0), d_STiK(STiK),
+      d_INTERLEAVER(INTERLEAVER),
+      d_blocklength(blocklength),
+      d_repetitions(repetitions),
+      d_SISO_TYPE(SISO_TYPE)
+    {
+      this->set_relative_rate(1.0 / ((double) d_FSMi.O()));
+      this->set_output_multiple(d_blocklength);
+    }
+
+    template <class T>
+    sccc_decoder_blk_impl<T>::~sccc_decoder_blk_impl()
+    {
+    }
+
+    template <class T>
+    void
+    sccc_decoder_blk_impl<T>::forecast(int noutput_items,
+			  gr_vector_int &ninput_items_required)
+    {
+      int input_required =  d_FSMi.O() * noutput_items ;
+      ninput_items_required[0] = input_required;
+    }
+
+    //===========================================================
+
+    template <class T>
+    int
+    sccc_decoder_blk_impl<T>::general_work(int noutput_items,
+			      gr_vector_int &ninput_items,
+			      gr_vector_const_void_star &input_items,
+			      gr_vector_void_star &output_items)
+    {
+      int nblocks = noutput_items / d_blocklength;
+      float (*p2min)(float, float) = NULL;
+
+      if(d_SISO_TYPE == TRELLIS_MIN_SUM)
+	p2min = &min;
+      else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+	p2min = &min_star;
+
+      const float *in = (const float*)input_items[0];
+      T *out = (T*)output_items[0];
+
+      for(int n = 0; n < nblocks; n++) {
+	sccc_decoder(d_FSMo, d_STo0, d_SToK,
+		     d_FSMi, d_STi0, d_STiK,
+		     d_INTERLEAVER, d_blocklength, d_repetitions,
+		     p2min,
+		     &(in[n*d_blocklength*d_FSMi.O()]),
+		     &(out[n*d_blocklength]));
+      }
+
+      this->consume_each(d_FSMi.O() * noutput_items );
+      return noutput_items;
+    }
+
+template class sccc_decoder_blk<std::uint8_t>;
+template class sccc_decoder_blk<std::int16_t>;
+template class sccc_decoder_blk<std::int32_t>;
+  } /* namespace trellis */
+} /* namespace gr */
diff --git a/gr-trellis/lib/sccc_decoder_blk_impl.h b/gr-trellis/lib/sccc_decoder_blk_impl.h
new file mode 100644
index 0000000000..0c3e2d9310
--- /dev/null
+++ b/gr-trellis/lib/sccc_decoder_blk_impl.h
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef SCCC_DECODER_BLK_IMPL_H
+#define SCCC_DECODER_BLK_IMPL_H
+
+#include <gnuradio/trellis/sccc_decoder_blk.h>
+
+namespace gr {
+  namespace trellis {
+
+template<class T>
+    class sccc_decoder_blk_impl : public  sccc_decoder_blk<T>
+    {
+    private:
+      fsm d_FSMo;
+      int d_STo0;
+      int d_SToK;
+      fsm d_FSMi;
+      int d_STi0;
+      int d_STiK;
+      interleaver d_INTERLEAVER;
+      int d_blocklength;
+      int d_repetitions;
+      siso_type_t d_SISO_TYPE;
+      std::vector<float> d_buffer;
+
+    public:
+      sccc_decoder_blk_impl(const fsm &FSMo, int STo0, int SToK,
+		  const fsm &FSMi, int STi0, int STiK,
+		  const interleaver &INTERLEAVER,
+		  int blocklength,
+		  int repetitions,
+		  siso_type_t SISO_TYPE);
+      ~sccc_decoder_blk_impl();
+
+      fsm FSMo() const { return d_FSMo; }
+      fsm FSMi() const { return d_FSMi; }
+      int STo0() const { return d_STo0; }
+      int SToK() const { return d_SToK; }
+      int STi0() const { return d_STi0; }
+      int STiK() const { return d_STiK; }
+      interleaver INTERLEAVER() const { return d_INTERLEAVER; }
+      int blocklength() const { return d_blocklength; }
+      int repetitions() const { return d_repetitions; }
+      siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
+
+      void forecast(int noutput_items,
+		    gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+		       gr_vector_int &ninput_items,
+		       gr_vector_const_void_star &input_items,
+		       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* SCCC_DECODER_BLK_IMPL_H */
diff --git a/gr-trellis/lib/sccc_decoder_combined_XX_impl.cc.t b/gr-trellis/lib/sccc_decoder_combined_XX_impl.cc.t
deleted file mode 100644
index 224c5f8027..0000000000
--- a/gr-trellis/lib/sccc_decoder_combined_XX_impl.cc.t
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <iostream>
-#include <gnuradio/trellis/core_algorithms.h>
-
-namespace gr {
-  namespace trellis {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(const fsm &FSMo, int STo0, int SToK,
-		      const fsm &FSMi, int STi0, int STiK,
-		      const interleaver &INTERLEAVER,
-		      int blocklength,
-		      int repetitions,
-		      siso_type_t SISO_TYPE,
-		      int D,
-		      const std::vector<@I_TYPE@> &TABLE,
-		      digital::trellis_metric_type_t METRIC_TYPE,
-		      float scaling)
-    {
-      return gnuradio::get_initial_sptr
-	(new @IMPL_NAME@(FSMo, STo0, SToK, FSMi, STi0, STiK,
-			 INTERLEAVER, blocklength, repetitions,
-			 SISO_TYPE, D, TABLE,METRIC_TYPE, scaling));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(const fsm &FSMo, int STo0, int SToK,
-			     const fsm &FSMi, int STi0, int STiK,
-			     const interleaver &INTERLEAVER,
-			     int blocklength,
-			     int repetitions,
-			     siso_type_t SISO_TYPE,
-			     int D,
-			     const std::vector<@I_TYPE@> &TABLE,
-			     digital::trellis_metric_type_t METRIC_TYPE,
-			     float scaling)
-    : block("@BASE_NAME@",
-	       io_signature::make(1, 1, sizeof(@I_TYPE@)),
-	       io_signature::make(1, 1, sizeof(@O_TYPE@))),
-      d_FSMo(FSMo), d_STo0(STo0), d_SToK(SToK),
-      d_FSMi(FSMi), d_STi0(STi0), d_STiK(STiK),
-      d_INTERLEAVER(INTERLEAVER),
-      d_blocklength(blocklength),
-      d_repetitions(repetitions),
-      d_SISO_TYPE(SISO_TYPE),
-      d_D(D),
-      d_TABLE(TABLE),
-      d_METRIC_TYPE(METRIC_TYPE),
-      d_scaling(scaling)
-    {
-      set_relative_rate(1.0 / ((double) d_D));
-      set_output_multiple(d_blocklength);
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-    }
-
-    void
-    @IMPL_NAME@::set_scaling(float scaling)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      d_scaling = scaling;
-    }
-
-    void
-    @IMPL_NAME@::forecast(int noutput_items,
-			  gr_vector_int &ninput_items_required)
-    {
-      int input_required =  d_D * noutput_items ;
-      ninput_items_required[0] = input_required;
-    }
-
-    //===========================================================
-
-    int
-    @IMPL_NAME@::general_work(int noutput_items,
-			      gr_vector_int &ninput_items,
-			      gr_vector_const_void_star &input_items,
-			      gr_vector_void_star &output_items)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      int nblocks = noutput_items / d_blocklength;
-      float (*p2min)(float, float) = NULL;
-
-      if(d_SISO_TYPE == TRELLIS_MIN_SUM)
-	p2min = &min;
-      else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
-	p2min = &min_star;
-
-      const @I_TYPE@ *in = (const @I_TYPE@*)input_items[0];
-      @O_TYPE@ *out = (@O_TYPE@*)output_items[0];
-
-      for(int n = 0; n < nblocks; n++) {
-	sccc_decoder_combined(d_FSMo, d_STo0, d_SToK,
-			      d_FSMi, d_STi0, d_STiK,
-			      d_INTERLEAVER, d_blocklength, d_repetitions,
-			      p2min,
-			      d_D,d_TABLE,
-			      d_METRIC_TYPE,
-			      d_scaling,
-			      &(in[n*d_blocklength*d_D]),
-			      &(out[n*d_blocklength]));
-      }
-
-      consume_each(d_D * noutput_items);
-      return noutput_items;
-    }
-
-  } /* namespace trellis */
-} /* namespace gr */
diff --git a/gr-trellis/lib/sccc_decoder_combined_XX_impl.h.t b/gr-trellis/lib/sccc_decoder_combined_XX_impl.h.t
deleted file mode 100644
index 6a38f0114f..0000000000
--- a/gr-trellis/lib/sccc_decoder_combined_XX_impl.h.t
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/@BASE_NAME@.h>
-
-namespace gr {
-  namespace trellis {
-
-    class @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      fsm d_FSMo;
-      int d_STo0;
-      int d_SToK;
-      fsm d_FSMi;
-      int d_STi0;
-      int d_STiK;
-      interleaver d_INTERLEAVER;
-      int d_blocklength;
-      int d_repetitions;
-      siso_type_t d_SISO_TYPE;
-      int d_D;
-      std::vector<@I_TYPE@> d_TABLE;
-      digital::trellis_metric_type_t d_METRIC_TYPE;
-      float d_scaling;
-      std::vector<float> d_buffer;
-
-    public:
-      @IMPL_NAME@(const fsm &FSMo, int STo0, int SToK,
-		  const fsm &FSMi, int STi0, int STiK,
-		  const interleaver &INTERLEAVER,
-		  int blocklength,
-		  int repetitions,
-		  siso_type_t SISO_TYPE,
-		  int D,
-		  const std::vector<@I_TYPE@> &TABLE,
-		  digital::trellis_metric_type_t METRIC_TYPE,
-		  float scaling);
-      ~@IMPL_NAME@();
-
-      fsm FSMo() const { return d_FSMo; }
-      fsm FSMi() const { return d_FSMi; }
-      int STo0() const { return d_STo0; }
-      int SToK() const { return d_SToK; }
-      int STi0() const { return d_STi0; }
-      int STiK() const { return d_STiK; }
-      interleaver INTERLEAVER() const { return d_INTERLEAVER; }
-      int blocklength() const { return d_blocklength; }
-      int repetitions() const { return d_repetitions; }
-      int D() const { return d_D; }
-      std::vector<@I_TYPE@> TABLE() const { return d_TABLE; }
-      digital::trellis_metric_type_t METRIC_TYPE() const { return d_METRIC_TYPE; }
-      siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
-      float scaling() const { return d_scaling; }
-      void set_scaling(float scaling);
-
-      void forecast(int noutput_items,
-		    gr_vector_int &ninput_items_required);
-
-      int general_work(int noutput_items,
-		       gr_vector_int &ninput_items,
-		       gr_vector_const_void_star &input_items,
-		       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/lib/sccc_decoder_combined_blk_impl.cc b/gr-trellis/lib/sccc_decoder_combined_blk_impl.cc
new file mode 100644
index 0000000000..bf8845ce52
--- /dev/null
+++ b/gr-trellis/lib/sccc_decoder_combined_blk_impl.cc
@@ -0,0 +1,151 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sccc_decoder_combined_blk_impl.h"
+#include <gnuradio/io_signature.h>
+#include <iostream>
+#include <gnuradio/trellis/core_algorithms.h>
+
+namespace gr {
+  namespace trellis {
+
+    template <class IN_T, class OUT_T>
+    typename sccc_decoder_combined_blk<IN_T,OUT_T>::sptr
+    sccc_decoder_combined_blk<IN_T,OUT_T>::make(const fsm &FSMo, int STo0, int SToK,
+		      const fsm &FSMi, int STi0, int STiK,
+		      const interleaver &INTERLEAVER,
+		      int blocklength,
+		      int repetitions,
+		      siso_type_t SISO_TYPE,
+		      int D,
+		      const std::vector<IN_T> &TABLE,
+		      digital::trellis_metric_type_t METRIC_TYPE,
+		      float scaling)
+    {
+      return gnuradio::get_initial_sptr
+	(new sccc_decoder_combined_blk_impl<IN_T,OUT_T>(FSMo, STo0, SToK, FSMi, STi0, STiK,
+			 INTERLEAVER, blocklength, repetitions,
+			 SISO_TYPE, D, TABLE,METRIC_TYPE, scaling));
+    }
+
+    template <class IN_T, class OUT_T>
+    sccc_decoder_combined_blk_impl<IN_T,OUT_T>::sccc_decoder_combined_blk_impl(const fsm &FSMo, int STo0, int SToK,
+			     const fsm &FSMi, int STi0, int STiK,
+			     const interleaver &INTERLEAVER,
+			     int blocklength,
+			     int repetitions,
+			     siso_type_t SISO_TYPE,
+			     int D,
+			     const std::vector<IN_T> &TABLE,
+			     digital::trellis_metric_type_t METRIC_TYPE,
+			     float scaling)
+    : block("sccc_decoder_combined_blk<IN_T,OUT_T>",
+	       io_signature::make(1, 1, sizeof(IN_T)),
+	       io_signature::make(1, 1, sizeof(OUT_T))),
+      d_FSMo(FSMo), d_STo0(STo0), d_SToK(SToK),
+      d_FSMi(FSMi), d_STi0(STi0), d_STiK(STiK),
+      d_INTERLEAVER(INTERLEAVER),
+      d_blocklength(blocklength),
+      d_repetitions(repetitions),
+      d_SISO_TYPE(SISO_TYPE),
+      d_D(D),
+      d_TABLE(TABLE),
+      d_METRIC_TYPE(METRIC_TYPE),
+      d_scaling(scaling)
+    {
+      this->set_relative_rate(1.0 / ((double) d_D));
+      this->set_output_multiple(d_blocklength);
+    }
+
+    template <class IN_T, class OUT_T>
+    sccc_decoder_combined_blk_impl<IN_T,OUT_T>::~sccc_decoder_combined_blk_impl()
+    {
+    }
+
+    template <class IN_T, class OUT_T>
+    void
+    sccc_decoder_combined_blk_impl<IN_T,OUT_T>::set_scaling(float scaling)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_scaling = scaling;
+    }
+
+    template <class IN_T, class OUT_T>
+    void
+    sccc_decoder_combined_blk_impl<IN_T,OUT_T>::forecast(int noutput_items,
+			  gr_vector_int &ninput_items_required)
+    {
+      int input_required =  d_D * noutput_items ;
+      ninput_items_required[0] = input_required;
+    }
+
+    //===========================================================
+
+    template <class IN_T, class OUT_T>
+    int
+    sccc_decoder_combined_blk_impl<IN_T,OUT_T>::general_work(int noutput_items,
+			      gr_vector_int &ninput_items,
+			      gr_vector_const_void_star &input_items,
+			      gr_vector_void_star &output_items)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      int nblocks = noutput_items / d_blocklength;
+      float (*p2min)(float, float) = NULL;
+
+      if(d_SISO_TYPE == TRELLIS_MIN_SUM)
+	p2min = &min;
+      else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+	p2min = &min_star;
+
+      const IN_T *in = (const IN_T*)input_items[0];
+      OUT_T *out = (OUT_T*)output_items[0];
+
+      for(int n = 0; n < nblocks; n++) {
+	sccc_decoder_combined(d_FSMo, d_STo0, d_SToK,
+			      d_FSMi, d_STi0, d_STiK,
+			      d_INTERLEAVER, d_blocklength, d_repetitions,
+			      p2min,
+			      d_D,d_TABLE,
+			      d_METRIC_TYPE,
+			      d_scaling,
+			      &(in[n*d_blocklength*d_D]),
+			      &(out[n*d_blocklength]));
+      }
+
+      this->consume_each(d_D * noutput_items);
+      return noutput_items;
+    }
+
+    template class sccc_decoder_combined_blk<float, std::uint8_t>;
+    template class sccc_decoder_combined_blk<float, std::int16_t>;
+    template class sccc_decoder_combined_blk<float, std::int32_t>;
+    template class sccc_decoder_combined_blk<gr_complex, std::uint8_t>;
+    template class sccc_decoder_combined_blk<gr_complex, std::int16_t>;
+    template class sccc_decoder_combined_blk<gr_complex, std::int32_t>;
+
+
+  } /* namespace trellis */
+} /* namespace gr */
diff --git a/gr-trellis/lib/sccc_decoder_combined_blk_impl.h b/gr-trellis/lib/sccc_decoder_combined_blk_impl.h
new file mode 100644
index 0000000000..8236c79a49
--- /dev/null
+++ b/gr-trellis/lib/sccc_decoder_combined_blk_impl.h
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SCCC_DECODER_COMBINED_BLK_IMPL_H
+#define SCCC_DECODER_COMBINED_BLK_IMPL_H
+
+#include <gnuradio/trellis/sccc_decoder_combined_blk.h>
+
+namespace gr {
+  namespace trellis {
+
+    template <class IN_T, class OUT_T>
+    class sccc_decoder_combined_blk_impl : public sccc_decoder_combined_blk<IN_T,OUT_T>
+    {
+    private:
+      fsm d_FSMo;
+      int d_STo0;
+      int d_SToK;
+      fsm d_FSMi;
+      int d_STi0;
+      int d_STiK;
+      interleaver d_INTERLEAVER;
+      int d_blocklength;
+      int d_repetitions;
+      siso_type_t d_SISO_TYPE;
+      int d_D;
+      std::vector<IN_T> d_TABLE;
+      digital::trellis_metric_type_t d_METRIC_TYPE;
+      float d_scaling;
+      std::vector<float> d_buffer;
+
+    public:
+      sccc_decoder_combined_blk_impl(const fsm &FSMo, int STo0, int SToK,
+		  const fsm &FSMi, int STi0, int STiK,
+		  const interleaver &INTERLEAVER,
+		  int blocklength,
+		  int repetitions,
+		  siso_type_t SISO_TYPE,
+		  int D,
+		  const std::vector<IN_T> &TABLE,
+		  digital::trellis_metric_type_t METRIC_TYPE,
+		  float scaling);
+      ~sccc_decoder_combined_blk_impl();
+
+      fsm FSMo() const { return d_FSMo; }
+      fsm FSMi() const { return d_FSMi; }
+      int STo0() const { return d_STo0; }
+      int SToK() const { return d_SToK; }
+      int STi0() const { return d_STi0; }
+      int STiK() const { return d_STiK; }
+      interleaver INTERLEAVER() const { return d_INTERLEAVER; }
+      int blocklength() const { return d_blocklength; }
+      int repetitions() const { return d_repetitions; }
+      int D() const { return d_D; }
+      std::vector<IN_T> TABLE() const { return d_TABLE; }
+      digital::trellis_metric_type_t METRIC_TYPE() const { return d_METRIC_TYPE; }
+      siso_type_t SISO_TYPE() const { return d_SISO_TYPE; }
+      float scaling() const { return d_scaling; }
+      void set_scaling(float scaling);
+
+      void forecast(int noutput_items,
+		    gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+		       gr_vector_int &ninput_items,
+		       gr_vector_const_void_star &input_items,
+		       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* SCCC_DECODER_COMBINED_BLK_IMPL_H */
diff --git a/gr-trellis/lib/sccc_encoder_XX_impl.cc.t b/gr-trellis/lib/sccc_encoder_XX_impl.cc.t
deleted file mode 100644
index 9924b3c7d2..0000000000
--- a/gr-trellis/lib/sccc_encoder_XX_impl.cc.t
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <iostream>
-
-namespace gr {
-  namespace trellis {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(const fsm &FSMo, int STo,
-		      const fsm &FSMi, int STi,
-		      const interleaver &INTERLEAVER,
-		      int blocklength)
-    {
-      return gnuradio::get_initial_sptr
-	(new @IMPL_NAME@(FSMo, STo, FSMi, STi, INTERLEAVER, blocklength));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(const fsm &FSMo, int STo,
-			     const fsm &FSMi, int STi,
-			     const interleaver &INTERLEAVER,
-			     int blocklength)
-    : sync_block("@BASE_NAME@",
-		    io_signature::make(1, 1, sizeof(@I_TYPE@)),
-		    io_signature::make(1, 1, sizeof(@O_TYPE@))),
-      d_FSMo(FSMo), d_STo(STo),
-      d_FSMi(FSMi), d_STi(STi),
-      d_INTERLEAVER(INTERLEAVER),
-      d_blocklength(blocklength)
-    {
-      set_output_multiple(d_blocklength);
-      d_buffer.resize(d_blocklength);
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-    }
-
-    int
-    @IMPL_NAME@::work(int noutput_items,
-		      gr_vector_const_void_star &input_items,
-		      gr_vector_void_star &output_items)
-    {
-      for(int b = 0; b < noutput_items/d_blocklength; b++) {
-	const @I_TYPE@ *in = (const @I_TYPE@*)input_items[0]+b*d_blocklength;
-	@O_TYPE@ *out = (@O_TYPE@*)output_items[0]+b*d_blocklength;
-
-	int STo_tmp = d_STo;
-	for(int i = 0; i < d_blocklength; i++) {
-	  d_buffer[i] = d_FSMo.OS()[STo_tmp*d_FSMo.I()+in[i]];
-	  STo_tmp = (int) d_FSMo.NS()[STo_tmp*d_FSMo.I()+in[i]];
-	}
-
-	int STi_tmp = d_STi;
-	for(int i = 0; i < d_blocklength; i++) {
-	  int k = d_INTERLEAVER.INTER()[i];
-	  out[i] = (@O_TYPE@) d_FSMi.OS()[STi_tmp*d_FSMi.I()+d_buffer[k]];
-	  STi_tmp = (int) d_FSMi.NS()[STi_tmp*d_FSMi.I()+d_buffer[k]];
-	}
-      }
-      return noutput_items;
-    }
-
-  } /* namespace trellis */
-} /* namespace gr */
-
diff --git a/gr-trellis/lib/sccc_encoder_XX_impl.h.t b/gr-trellis/lib/sccc_encoder_XX_impl.h.t
deleted file mode 100644
index fc64f2ade8..0000000000
--- a/gr-trellis/lib/sccc_encoder_XX_impl.h.t
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/@BASE_NAME@.h>
-
-namespace gr {
-  namespace trellis {
-
-    class @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      fsm d_FSMo;
-      int d_STo;
-      fsm d_FSMi;
-      int d_STi;
-      interleaver d_INTERLEAVER;
-      int d_blocklength;
-      std::vector<int> d_buffer;
-
-    public:
-      @IMPL_NAME@(const fsm &FSMo, int STo,
-		  const fsm &FSMi, int STi,
-		  const interleaver &INTERLEAVER,
-		  int blocklength);
-      ~@IMPL_NAME@();
-
-      fsm FSMo() const { return d_FSMo; }
-      int STo() const { return d_STo; }
-      fsm FSMi() const { return d_FSMi; }
-      int STi() const { return d_STi; }
-      interleaver INTERLEAVER() const { return d_INTERLEAVER; }
-      int blocklength() const { return d_blocklength; }
-
-      int work(int noutput_items,
-	       gr_vector_const_void_star &input_items,
-	       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/lib/sccc_encoder_impl.cc b/gr-trellis/lib/sccc_encoder_impl.cc
new file mode 100644
index 0000000000..9c3e1da2d5
--- /dev/null
+++ b/gr-trellis/lib/sccc_encoder_impl.cc
@@ -0,0 +1,101 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sccc_encoder_impl.h"
+#include <gnuradio/io_signature.h>
+#include <iostream>
+
+namespace gr {
+  namespace trellis {
+
+    template <class IN_T, class OUT_T>
+    typename sccc_encoder<IN_T,OUT_T>::sptr
+    sccc_encoder<IN_T,OUT_T>::make(const fsm &FSMo, int STo,
+		      const fsm &FSMi, int STi,
+		      const interleaver &INTERLEAVER,
+		      int blocklength)
+    {
+      return gnuradio::get_initial_sptr
+	(new sccc_encoder_impl<IN_T,OUT_T>(FSMo, STo, FSMi, STi, INTERLEAVER, blocklength));
+    }
+
+    template <class IN_T, class OUT_T>
+    sccc_encoder_impl<IN_T,OUT_T>::sccc_encoder_impl(const fsm &FSMo, int STo,
+			     const fsm &FSMi, int STi,
+			     const interleaver &INTERLEAVER,
+			     int blocklength)
+    : sync_block("sccc_encoder<IN_T,OUT_T>",
+		    io_signature::make(1, 1, sizeof(IN_T)),
+		    io_signature::make(1, 1, sizeof(OUT_T))),
+      d_FSMo(FSMo), d_STo(STo),
+      d_FSMi(FSMi), d_STi(STi),
+      d_INTERLEAVER(INTERLEAVER),
+      d_blocklength(blocklength)
+    {
+      this->set_output_multiple(d_blocklength);
+      d_buffer.resize(d_blocklength);
+    }
+
+    template <class IN_T, class OUT_T>
+    sccc_encoder_impl<IN_T,OUT_T>::~sccc_encoder_impl()
+    {
+    }
+
+    template <class IN_T, class OUT_T>
+    int
+    sccc_encoder_impl<IN_T,OUT_T>::work(int noutput_items,
+		      gr_vector_const_void_star &input_items,
+		      gr_vector_void_star &output_items)
+    {
+      for(int b = 0; b < noutput_items/d_blocklength; b++) {
+	const IN_T *in = (const IN_T*)input_items[0]+b*d_blocklength;
+	OUT_T *out = (OUT_T*)output_items[0]+b*d_blocklength;
+
+	int STo_tmp = d_STo;
+	for(int i = 0; i < d_blocklength; i++) {
+	  d_buffer[i] = d_FSMo.OS()[STo_tmp*d_FSMo.I()+in[i]];
+	  STo_tmp = (int) d_FSMo.NS()[STo_tmp*d_FSMo.I()+in[i]];
+	}
+
+	int STi_tmp = d_STi;
+	for(int i = 0; i < d_blocklength; i++) {
+	  int k = d_INTERLEAVER.INTER()[i];
+	  out[i] = (OUT_T) d_FSMi.OS()[STi_tmp*d_FSMi.I()+d_buffer[k]];
+	  STi_tmp = (int) d_FSMi.NS()[STi_tmp*d_FSMi.I()+d_buffer[k]];
+	}
+      }
+      return noutput_items;
+    }
+    template class sccc_encoder<std::uint8_t, std::uint8_t>;
+    template class sccc_encoder<std::uint8_t, std::int16_t>;
+    template class sccc_encoder<std::uint8_t, std::int32_t>;
+    template class sccc_encoder<std::int16_t, std::int16_t>;
+    template class sccc_encoder<std::int16_t, std::int32_t>;
+    template class sccc_encoder<std::int32_t, std::int32_t>;
+
+
+  } /* namespace trellis */
+} /* namespace gr */
diff --git a/gr-trellis/lib/sccc_encoder_impl.h b/gr-trellis/lib/sccc_encoder_impl.h
new file mode 100644
index 0000000000..40968906dc
--- /dev/null
+++ b/gr-trellis/lib/sccc_encoder_impl.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SCCC_ENCODER_IMPL_H
+#define SCCC_ENCODER_IMPL_H
+
+#include <gnuradio/trellis/sccc_encoder.h>
+
+namespace gr {
+  namespace trellis {
+
+    template <class IN_T, class OUT_T>
+    class sccc_encoder_impl : public sccc_encoder<IN_T,OUT_T>
+    {
+    private:
+      fsm d_FSMo;
+      int d_STo;
+      fsm d_FSMi;
+      int d_STi;
+      interleaver d_INTERLEAVER;
+      int d_blocklength;
+      std::vector<int> d_buffer;
+
+    public:
+      sccc_encoder_impl(const fsm &FSMo, int STo,
+		  const fsm &FSMi, int STi,
+		  const interleaver &INTERLEAVER,
+		  int blocklength);
+      ~sccc_encoder_impl();
+
+      fsm FSMo() const { return d_FSMo; }
+      int STo() const { return d_STo; }
+      fsm FSMi() const { return d_FSMi; }
+      int STi() const { return d_STi; }
+      interleaver INTERLEAVER() const { return d_INTERLEAVER; }
+      int blocklength() const { return d_blocklength; }
+
+      int work(int noutput_items,
+	       gr_vector_const_void_star &input_items,
+	       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* SCCC_ENCODER_IMPL_H */
diff --git a/gr-trellis/lib/viterbi_X_impl.cc.t b/gr-trellis/lib/viterbi_X_impl.cc.t
deleted file mode 100644
index d5949f0321..0000000000
--- a/gr-trellis/lib/viterbi_X_impl.cc.t
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <iostream>
-
-namespace gr {
-  namespace trellis {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(const fsm &FSM, int K,
-		      int S0, int SK)
-    {
-      return gnuradio::get_initial_sptr
-	(new @IMPL_NAME@(FSM, K, S0, SK));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(const fsm &FSM, int K,
-			     int S0, int SK)
-    : block("@BASE_NAME@",
-	       io_signature::make(1, -1, sizeof(float)),
-	       io_signature::make(1, -1, sizeof(@TYPE@))),
-      d_FSM(FSM), d_K(K), d_S0(S0), d_SK(SK)//,
-      //d_trace(FSM.S()*K)
-    {
-      set_relative_rate(1.0 / ((double)d_FSM.O()));
-      set_output_multiple(d_K);
-    }
-
-    void @IMPL_NAME@::set_FSM(const fsm &FSM) 
-    { 
-      gr::thread::scoped_lock guard(d_setlock); 
-      d_FSM = FSM; 
-      set_relative_rate(1.0 / ((double)d_FSM.O()));
-    }
-
-    void @IMPL_NAME@::set_K(int K) 
-    { 
-      gr::thread::scoped_lock guard(d_setlock); 
-      d_K = K; 
-      set_output_multiple(d_K);
-    }
-
-    void @IMPL_NAME@::set_S0(int S0) 
-    { 
-      gr::thread::scoped_lock guard(d_setlock); 
-      d_S0 = S0; 
-    }
-
-    void @IMPL_NAME@::set_SK(int SK) 
-    { 
-      gr::thread::scoped_lock guard(d_setlock); 
-      d_SK = SK; 
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-    }
-
-    void
-    @IMPL_NAME@::forecast(int noutput_items,
-			  gr_vector_int &ninput_items_required)
-    {
-      int input_required =  d_FSM.O() * noutput_items;
-      unsigned ninputs = ninput_items_required.size();
-      for(unsigned int i = 0; i < ninputs; i++) {
-	ninput_items_required[i] = input_required;
-      }
-    }
-
-    int
-    @IMPL_NAME@::general_work(int noutput_items,
-			      gr_vector_int &ninput_items,
-			      gr_vector_const_void_star &input_items,
-			      gr_vector_void_star &output_items)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      int nstreams = input_items.size();
-      int nblocks = noutput_items / d_K;
-
-      for(int m = 0; m < nstreams; m++) {
-	const float *in = (const float*)input_items[m];
-	@TYPE@ *out = (@TYPE@*)output_items[m];
-
-	for(int n = 0; n < nblocks; n++) {
-	  viterbi_algorithm(d_FSM.I(), d_FSM.S(), d_FSM.O(),
-			    d_FSM.NS(), d_FSM.OS(), d_FSM.PS(),
-			    d_FSM.PI(), d_K,d_S0, d_SK,
-			    &(in[n*d_K*d_FSM.O()]), &(out[n*d_K]));
-	}
-      }
-
-      consume_each(d_FSM.O() * noutput_items);
-      return noutput_items;
-    }
-
-  } /* namespace trellis */
-} /* namespace gr */
diff --git a/gr-trellis/lib/viterbi_X_impl.h.t b/gr-trellis/lib/viterbi_X_impl.h.t
deleted file mode 100644
index 1479ad5a3f..0000000000
--- a/gr-trellis/lib/viterbi_X_impl.h.t
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/@BASE_NAME@.h>
-
-namespace gr {
-  namespace trellis {
-
-    class @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      fsm d_FSM;
-      int d_K;
-      int d_S0;
-      int d_SK;
-      //std::vector<int> d_trace;
-
-    public:
-      @IMPL_NAME@(const fsm &FSM, int K,
-		  int S0, int SK);
-      ~@IMPL_NAME@();
-
-      fsm FSM() const  { return d_FSM; }
-      int K()  const { return d_K; }
-      int S0()  const { return d_S0; }
-      int SK()  const { return d_SK; }
-
-      void set_FSM(const fsm &FSM);
-      void set_K(int K);
-      void set_S0(int S0);
-      void set_SK(int SK);
-      //std::vector<int> trace () const { return d_trace; }
-
-      void forecast(int noutput_items,
-		    gr_vector_int &ninput_items_required);
-      int general_work(int noutput_items,
-		       gr_vector_int &ninput_items,
-		       gr_vector_const_void_star &input_items,
-		       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/lib/viterbi_combined_XX_impl.cc.t b/gr-trellis/lib/viterbi_combined_XX_impl.cc.t
deleted file mode 100644
index 6d83dc4402..0000000000
--- a/gr-trellis/lib/viterbi_combined_XX_impl.cc.t
+++ /dev/null
@@ -1,153 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2010,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "@NAME@.h"
-#include <gnuradio/io_signature.h>
-#include <iostream>
-
-namespace gr {
-  namespace trellis {
-
-    @BASE_NAME@::sptr
-    @BASE_NAME@::make(const fsm &FSM, int K,
-		      int S0, int SK, int D,
-		      const std::vector<@I_TYPE@> &TABLE,
-		      digital::trellis_metric_type_t TYPE)
-    {
-      return gnuradio::get_initial_sptr
-	(new @NAME@(FSM, K, S0, SK, D, TABLE,TYPE));
-    }
-
-    @IMPL_NAME@::@IMPL_NAME@(const fsm &FSM, int K,
-			     int S0, int SK, int D,
-			     const std::vector<@I_TYPE@> &TABLE,
-			     digital::trellis_metric_type_t TYPE)
-    : block("@BASE_NAME@",
-	       io_signature::make(1, -1, sizeof(@I_TYPE@)),
-	       io_signature::make(1, -1, sizeof(@O_TYPE@))),
-      d_FSM(FSM), d_K(K), d_S0(S0), d_SK(SK), d_D(D),
-      d_TABLE(TABLE), d_TYPE(TYPE)//,
-      //d_trace(FSM.S()*K)
-    {
-      set_relative_rate(1.0 / ((double)d_D));
-      set_output_multiple(d_K);
-    }
-
-    void
-    @IMPL_NAME@::set_K(int K)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      d_K = K;
-      set_output_multiple(d_K);
-    }
-
-    void
-    @IMPL_NAME@::set_D(int D)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      d_D = D;
-      set_relative_rate(1.0 / ((double)d_D));
-    }
-   
-    void @IMPL_NAME@::set_FSM(const fsm &FSM)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      d_FSM = FSM;
-    }
-
-    void @IMPL_NAME@::set_S0(int S0)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      d_S0 = S0;
-    }
-
-    void @IMPL_NAME@::set_SK(int SK)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      d_SK = SK;
-    }
-
-    void
-    @IMPL_NAME@::set_TYPE(digital::trellis_metric_type_t type)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      d_TYPE = type;
-    }
-
-    void
-    @IMPL_NAME@::set_TABLE(const std::vector<@I_TYPE@> &table)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      d_TABLE = table;
-    }
-
-    @IMPL_NAME@::~@IMPL_NAME@()
-    {
-    }
-
-    void
-    @IMPL_NAME@::forecast(int noutput_items,
-			  gr_vector_int &ninput_items_required)
-    {
-      int input_required =  d_D * noutput_items;
-      unsigned ninputs = ninput_items_required.size();
-      for(unsigned int i = 0; i < ninputs; i++) {
-	ninput_items_required[i] = input_required;
-      }
-    }
-
-    int
-    @IMPL_NAME@::general_work(int noutput_items,
-			      gr_vector_int &ninput_items,
-			      gr_vector_const_void_star &input_items,
-			      gr_vector_void_star &output_items)
-    {
-      gr::thread::scoped_lock guard(d_setlock);
-      int nstreams = input_items.size();
-      int nblocks = noutput_items / d_K;
-
-      for(int m=0;m<nstreams;m++) {
-	const @I_TYPE@ *in = (const @I_TYPE@*)input_items[m];
-	@O_TYPE@ *out = (@O_TYPE@*)output_items[m];
-
-	for(int n=0;n<nblocks;n++) {
-	  viterbi_algorithm_combined(d_FSM.I(), d_FSM.S(), d_FSM.O(),
-				     d_FSM.NS(), d_FSM.OS(), d_FSM.PS(),
-				     d_FSM.PI(), d_K,d_S0, d_SK, d_D,
-				     d_TABLE, d_TYPE,
-				     &(in[n*d_K*d_D]), &(out[n*d_K]));
-	}
-      }
-
-      consume_each(d_D * noutput_items);
-      return noutput_items;
-    }
-
-  } /* namespace trellis */
-} /* namespace gr */
-
diff --git a/gr-trellis/lib/viterbi_combined_XX_impl.h.t b/gr-trellis/lib/viterbi_combined_XX_impl.h.t
deleted file mode 100644
index 788e609895..0000000000
--- a/gr-trellis/lib/viterbi_combined_XX_impl.h.t
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2012 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// @WARNING@
-
-#ifndef @GUARD_NAME@
-#define @GUARD_NAME@
-
-#include <gnuradio/trellis/@BASE_NAME@.h>
-
-namespace gr {
-  namespace trellis {
-
-    class @IMPL_NAME@ : public @BASE_NAME@
-    {
-    private:
-      fsm d_FSM;
-      int d_K;
-      int d_S0;
-      int d_SK;
-      int d_D;
-      std::vector<@I_TYPE@> d_TABLE;
-      digital::trellis_metric_type_t d_TYPE;
-      //std::vector<int> d_trace;
-
-    public:
-      @IMPL_NAME@(const fsm &FSM, int K,
-		  int S0, int SK, int D,
-		  const std::vector<@I_TYPE@> &TABLE,
-		  digital::trellis_metric_type_t TYPE);
-      ~@IMPL_NAME@();
-
-      fsm FSM() const  { return d_FSM; }
-      int K()  const { return d_K; }
-      int S0()  const { return d_S0; }
-      int SK()  const { return d_SK; }
-      int D()  const { return d_D; }
-      std::vector<@I_TYPE@> TABLE() const { return d_TABLE; }
-      digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
-      //std::vector<int> trace() const { return d_trace; }
-
-      void set_FSM(const fsm &FSM);
-      void set_K(int K);
-      void set_S0(int S0);
-      void set_SK(int SK);
-      void set_D(int D);
-      void set_TABLE(const std::vector<@I_TYPE@> &table);
-      void set_TYPE(digital::trellis_metric_type_t type);
-
-      void forecast(int noutput_items,
-		    gr_vector_int &ninput_items_required);
-
-      int general_work(int noutput_items,
-		       gr_vector_int &ninput_items,
-		       gr_vector_const_void_star &input_items,
-		       gr_vector_void_star &output_items);
-    };
-
-  } /* namespace trellis */
-} /* namespace gr */
-
-#endif /* @GUARD_NAME@ */
diff --git a/gr-trellis/lib/viterbi_combined_impl.cc b/gr-trellis/lib/viterbi_combined_impl.cc
new file mode 100644
index 0000000000..e552f5a9b9
--- /dev/null
+++ b/gr-trellis/lib/viterbi_combined_impl.cc
@@ -0,0 +1,176 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "viterbi_combined_impl.h"
+#include <gnuradio/io_signature.h>
+#include <iostream>
+
+namespace gr {
+  namespace trellis {
+
+    template <class IN_T,class OUT_T>
+    typename viterbi_combined<IN_T,OUT_T>::sptr
+    viterbi_combined<IN_T,OUT_T>::make(const fsm &FSM, int K,
+		      int S0, int SK, int D,
+		      const std::vector<IN_T> &TABLE,
+		      digital::trellis_metric_type_t TYPE)
+    {
+      return gnuradio::get_initial_sptr
+	(new viterbi_combined_impl<IN_T,OUT_T>(FSM, K, S0, SK, D, TABLE,TYPE));
+    }
+
+    template <class IN_T,class OUT_T>
+    viterbi_combined_impl<IN_T,OUT_T>::viterbi_combined_impl(const fsm &FSM, int K,
+			     int S0, int SK, int D,
+			     const std::vector<IN_T> &TABLE,
+			     digital::trellis_metric_type_t TYPE)
+    : block("viterbi_combined<IN_T,OUT_T>",
+	       io_signature::make(1, -1, sizeof(IN_T)),
+	       io_signature::make(1, -1, sizeof(OUT_T))),
+      d_FSM(FSM), d_K(K), d_S0(S0), d_SK(SK), d_D(D),
+      d_TABLE(TABLE), d_TYPE(TYPE)//,
+      //d_trace(FSM.S()*K)
+    {
+      this->set_relative_rate(1.0 / ((double)d_D));
+      this->set_output_multiple(d_K);
+    }
+
+    template <class IN_T,class OUT_T>
+    void
+    viterbi_combined_impl<IN_T,OUT_T>::set_K(int K)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_K = K;
+      this->set_output_multiple(d_K);
+    }
+
+    template <class IN_T,class OUT_T>
+    void
+    viterbi_combined_impl<IN_T,OUT_T>::set_D(int D)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_D = D;
+      this->set_relative_rate(1.0 / ((double)d_D));
+    }
+
+    template <class IN_T,class OUT_T>
+    void viterbi_combined_impl<IN_T,OUT_T>::set_FSM(const fsm &FSM)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_FSM = FSM;
+    }
+
+    template <class IN_T,class OUT_T>
+    void viterbi_combined_impl<IN_T,OUT_T>::set_S0(int S0)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_S0 = S0;
+    }
+
+    template <class IN_T,class OUT_T>
+    void viterbi_combined_impl<IN_T,OUT_T>::set_SK(int SK)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_SK = SK;
+    }
+
+    template <class IN_T,class OUT_T>
+    void
+    viterbi_combined_impl<IN_T,OUT_T>::set_TYPE(digital::trellis_metric_type_t type)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_TYPE = type;
+    }
+
+    template <class IN_T,class OUT_T>
+    void
+    viterbi_combined_impl<IN_T,OUT_T>::set_TABLE(const std::vector<IN_T> &table)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_TABLE = table;
+    }
+
+    template <class IN_T,class OUT_T>
+    viterbi_combined_impl<IN_T,OUT_T>::~viterbi_combined_impl()
+    {
+    }
+
+    template <class IN_T,class OUT_T>
+    void
+    viterbi_combined_impl<IN_T,OUT_T>::forecast(int noutput_items,
+			  gr_vector_int &ninput_items_required)
+    {
+      int input_required =  d_D * noutput_items;
+      unsigned ninputs = ninput_items_required.size();
+      for(unsigned int i = 0; i < ninputs; i++) {
+	ninput_items_required[i] = input_required;
+      }
+    }
+
+    template <class IN_T,class OUT_T>
+    int
+    viterbi_combined_impl<IN_T,OUT_T>::general_work(int noutput_items,
+			      gr_vector_int &ninput_items,
+			      gr_vector_const_void_star &input_items,
+			      gr_vector_void_star &output_items)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      int nstreams = input_items.size();
+      int nblocks = noutput_items / d_K;
+
+      for(int m=0;m<nstreams;m++) {
+	const IN_T *in = (const IN_T*)input_items[m];
+	OUT_T *out = (OUT_T*)output_items[m];
+
+	for(int n=0;n<nblocks;n++) {
+	  viterbi_algorithm_combined(d_FSM.I(), d_FSM.S(), d_FSM.O(),
+				     d_FSM.NS(), d_FSM.OS(), d_FSM.PS(),
+				     d_FSM.PI(), d_K,d_S0, d_SK, d_D,
+				     d_TABLE, d_TYPE,
+				     &(in[n*d_K*d_D]), &(out[n*d_K]));
+	}
+      }
+
+      this->consume_each(d_D * noutput_items);
+      return noutput_items;
+    }
+
+    template class viterbi_combined<std::int16_t, std::uint8_t>;
+    template class viterbi_combined<std::int16_t, std::int16_t>;
+    template class viterbi_combined<std::int16_t, std::int32_t>;
+    template class viterbi_combined<std::int32_t, std::uint8_t>;
+    template class viterbi_combined<std::int32_t, std::int16_t>;
+    template class viterbi_combined<std::int32_t, std::int32_t>;
+    template class viterbi_combined<float, std::uint8_t>;
+    template class viterbi_combined<float, std::int16_t>;
+    template class viterbi_combined<float, std::int32_t>;
+    template class viterbi_combined<gr_complex, std::uint8_t>;
+    template class viterbi_combined<gr_complex, std::int16_t>;
+    template class viterbi_combined<gr_complex, std::int32_t>;
+
+
+  } /* namespace trellis */
+} /* namespace gr */
diff --git a/gr-trellis/lib/viterbi_combined_impl.h b/gr-trellis/lib/viterbi_combined_impl.h
new file mode 100644
index 0000000000..e83114673f
--- /dev/null
+++ b/gr-trellis/lib/viterbi_combined_impl.h
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef VITERBI_COMBINED_IMPL_H
+#define VITERBI_COMBINED_IMPL_H
+
+#include <gnuradio/trellis/viterbi_combined.h>
+
+namespace gr {
+  namespace trellis {
+
+    template <class IN_T,class OUT_T>
+    class viterbi_combined_impl : public viterbi_combined<IN_T,OUT_T>
+    {
+    private:
+      fsm d_FSM;
+      int d_K;
+      int d_S0;
+      int d_SK;
+      int d_D;
+      std::vector<IN_T> d_TABLE;
+      digital::trellis_metric_type_t d_TYPE;
+      //std::vector<int> d_trace;
+
+    public:
+      viterbi_combined_impl(const fsm &FSM, int K,
+		  int S0, int SK, int D,
+		  const std::vector<IN_T> &TABLE,
+		  digital::trellis_metric_type_t TYPE);
+      ~viterbi_combined_impl();
+
+      fsm FSM() const  { return d_FSM; }
+      int K()  const { return d_K; }
+      int S0()  const { return d_S0; }
+      int SK()  const { return d_SK; }
+      int D()  const { return d_D; }
+      std::vector<IN_T> TABLE() const { return d_TABLE; }
+      digital::trellis_metric_type_t TYPE() const { return d_TYPE; }
+      //std::vector<int> trace() const { return d_trace; }
+
+      void set_FSM(const fsm &FSM);
+      void set_K(int K);
+      void set_S0(int S0);
+      void set_SK(int SK);
+      void set_D(int D);
+      void set_TABLE(const std::vector<IN_T> &table);
+      void set_TYPE(digital::trellis_metric_type_t type);
+
+      void forecast(int noutput_items,
+		    gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+		       gr_vector_int &ninput_items,
+		       gr_vector_const_void_star &input_items,
+		       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* VITERBI_COMBINED_IMPL_H */
diff --git a/gr-trellis/lib/viterbi_impl.cc b/gr-trellis/lib/viterbi_impl.cc
new file mode 100644
index 0000000000..4b5f428d60
--- /dev/null
+++ b/gr-trellis/lib/viterbi_impl.cc
@@ -0,0 +1,135 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "viterbi_impl.h"
+#include <gnuradio/io_signature.h>
+#include <iostream>
+
+namespace gr {
+  namespace trellis {
+
+    template <class T>
+    typename viterbi<T>::sptr
+    viterbi<T>::make(const fsm &FSM, int K,
+		      int S0, int SK)
+    {
+      return gnuradio::get_initial_sptr
+	(new viterbi_impl<T>(FSM, K, S0, SK));
+    }
+
+    template <class T>
+    viterbi_impl<T>::viterbi_impl(const fsm &FSM, int K,
+			     int S0, int SK)
+    : block("viterbi",
+	       io_signature::make(1, -1, sizeof(float)),
+	       io_signature::make(1, -1, sizeof(T))),
+      d_FSM(FSM), d_K(K), d_S0(S0), d_SK(SK)//,
+      //d_trace(FSM.S()*K)
+    {
+      this->set_relative_rate(1.0 / ((double)d_FSM.O()));
+      this->set_output_multiple(d_K);
+    }
+
+    template <class T>
+    void viterbi_impl<T>::set_FSM(const fsm &FSM) 
+    { 
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_FSM = FSM; 
+      this->set_relative_rate(1.0 / ((double)d_FSM.O()));
+    }
+
+    template <class T>
+    void viterbi_impl<T>::set_K(int K) 
+    { 
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_K = K; 
+      this->set_output_multiple(d_K);
+    }
+
+    template <class T>
+    void viterbi_impl<T>::set_S0(int S0) 
+    { 
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_S0 = S0; 
+    }
+
+    template <class T>
+    void viterbi_impl<T>::set_SK(int SK) 
+    { 
+      gr::thread::scoped_lock guard(this->d_setlock);
+      d_SK = SK; 
+    }
+
+    template <class T>
+    viterbi_impl<T>::~viterbi_impl()
+    {
+    }
+
+    template <class T>
+    void
+    viterbi_impl<T>::forecast(int noutput_items,
+			  gr_vector_int &ninput_items_required)
+    {
+      int input_required =  d_FSM.O() * noutput_items;
+      unsigned ninputs = ninput_items_required.size();
+      for(unsigned int i = 0; i < ninputs; i++) {
+	ninput_items_required[i] = input_required;
+      }
+    }
+
+    template <class T>
+    int
+    viterbi_impl<T>::general_work(int noutput_items,
+			      gr_vector_int &ninput_items,
+			      gr_vector_const_void_star &input_items,
+			      gr_vector_void_star &output_items)
+    {
+      gr::thread::scoped_lock guard(this->d_setlock);
+      int nstreams = input_items.size();
+      int nblocks = noutput_items / d_K;
+
+      for(int m = 0; m < nstreams; m++) {
+	const float *in = (const float*)input_items[m];
+	T *out = (T*)output_items[m];
+
+	for(int n = 0; n < nblocks; n++) {
+	  viterbi_algorithm(d_FSM.I(), d_FSM.S(), d_FSM.O(),
+			    d_FSM.NS(), d_FSM.OS(), d_FSM.PS(),
+			    d_FSM.PI(), d_K,d_S0, d_SK,
+			    &(in[n*d_K*d_FSM.O()]), &(out[n*d_K]));
+	}
+      }
+
+      this->consume_each(d_FSM.O() * noutput_items);
+      return noutput_items;
+    }
+
+template class viterbi<std::uint8_t>;
+template class viterbi<std::int16_t>;
+template class viterbi<std::int32_t>;
+  } /* namespace trellis */
+} /* namespace gr */
diff --git a/gr-trellis/lib/viterbi_impl.h b/gr-trellis/lib/viterbi_impl.h
new file mode 100644
index 0000000000..c9f40a0b79
--- /dev/null
+++ b/gr-trellis/lib/viterbi_impl.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef VITERBI_IMPL_H
+#define VITERBI_IMPL_H
+
+#include <gnuradio/trellis/viterbi.h>
+
+namespace gr {
+  namespace trellis {
+
+template<class T>
+    class viterbi_impl : public  viterbi<T>
+    {
+    private:
+      fsm d_FSM;
+      int d_K;
+      int d_S0;
+      int d_SK;
+      //std::vector<int> d_trace;
+
+    public:
+      viterbi_impl(const fsm &FSM, int K,
+		  int S0, int SK);
+      ~viterbi_impl();
+
+      fsm FSM() const  { return d_FSM; }
+      int K()  const { return d_K; }
+      int S0()  const { return d_S0; }
+      int SK()  const { return d_SK; }
+
+      void set_FSM(const fsm &FSM);
+      void set_K(int K);
+      void set_S0(int S0);
+      void set_SK(int SK);
+      //std::vector<int> trace () const { return d_trace; }
+
+      void forecast(int noutput_items,
+		    gr_vector_int &ninput_items_required);
+      int general_work(int noutput_items,
+		       gr_vector_int &ninput_items,
+		       gr_vector_const_void_star &input_items,
+		       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace trellis */
+} /* namespace gr */
+
+#endif /* VITERBI_IMPL_H */
diff --git a/gr-trellis/swig/CMakeLists.txt b/gr-trellis/swig/CMakeLists.txt
index 14012abad5..1f9b7679df 100644
--- a/gr-trellis/swig/CMakeLists.txt
+++ b/gr-trellis/swig/CMakeLists.txt
@@ -59,7 +59,6 @@ foreach(swigfile ${GR_SWIG_TRELLIS_IFILES})
     ${CMAKE_CURRENT_BINARY_DIR}/../include/gnuradio/trellis
   )
   set(GR_SWIG_DOCS_TARGET_DEPS runtime_swig_swig_doc)
-  set(GR_SWIG_TARGET_DEPS trellis_generated_includes)
   set(GR_SWIG_LIBRARIES gnuradio-trellis gnuradio-digital)
   GR_SWIG_MAKE(${swigfile} ${swigfile}.i)
 
diff --git a/gr-trellis/swig/trellis_swig0.i b/gr-trellis/swig/trellis_swig0.i
index 9f309c5ca3..596a043db4 100644
--- a/gr-trellis/swig/trellis_swig0.i
+++ b/gr-trellis/swig/trellis_swig0.i
@@ -38,80 +38,44 @@
 #include "gnuradio/trellis/permutation.h"
 #include "gnuradio/trellis/siso_combined_f.h"
 #include "gnuradio/trellis/siso_f.h"
-#include "gnuradio/trellis/encoder_bb.h"
-#include "gnuradio/trellis/encoder_bs.h"
-#include "gnuradio/trellis/encoder_bi.h"
-#include "gnuradio/trellis/encoder_ss.h"
-#include "gnuradio/trellis/encoder_si.h"
-#include "gnuradio/trellis/encoder_ii.h"
-#include "gnuradio/trellis/sccc_encoder_bb.h"
-#include "gnuradio/trellis/sccc_encoder_bs.h"
-#include "gnuradio/trellis/sccc_encoder_bi.h"
-#include "gnuradio/trellis/sccc_encoder_ss.h"
-#include "gnuradio/trellis/sccc_encoder_si.h"
-#include "gnuradio/trellis/sccc_encoder_ii.h"
-#include "gnuradio/trellis/pccc_encoder_bb.h"
-#include "gnuradio/trellis/pccc_encoder_bs.h"
-#include "gnuradio/trellis/pccc_encoder_bi.h"
-#include "gnuradio/trellis/pccc_encoder_ss.h"
-#include "gnuradio/trellis/pccc_encoder_si.h"
-#include "gnuradio/trellis/pccc_encoder_ii.h"
-#include "gnuradio/trellis/metrics_s.h"
-#include "gnuradio/trellis/metrics_i.h"
-#include "gnuradio/trellis/metrics_f.h"
-#include "gnuradio/trellis/metrics_c.h"
+#include "gnuradio/trellis/encoder.h"
+#include "gnuradio/trellis/sccc_encoder.h"
+#include "gnuradio/trellis/pccc_encoder.h"
+#include "gnuradio/trellis/metrics.h"
 %}
 
 %include "gnuradio/trellis/constellation_metrics_cf.h"
 %include "gnuradio/trellis/permutation.h"
 %include "gnuradio/trellis/siso_combined_f.h"
 %include "gnuradio/trellis/siso_f.h"
-%include "gnuradio/trellis/encoder_bb.h"
-%include "gnuradio/trellis/encoder_bs.h"
-%include "gnuradio/trellis/encoder_bi.h"
-%include "gnuradio/trellis/encoder_ss.h"
-%include "gnuradio/trellis/encoder_si.h"
-%include "gnuradio/trellis/encoder_ii.h"
-%include "gnuradio/trellis/sccc_encoder_bb.h"
-%include "gnuradio/trellis/sccc_encoder_bs.h"
-%include "gnuradio/trellis/sccc_encoder_bi.h"
-%include "gnuradio/trellis/sccc_encoder_ss.h"
-%include "gnuradio/trellis/sccc_encoder_si.h"
-%include "gnuradio/trellis/sccc_encoder_ii.h"
-%include "gnuradio/trellis/pccc_encoder_bb.h"
-%include "gnuradio/trellis/pccc_encoder_bs.h"
-%include "gnuradio/trellis/pccc_encoder_bi.h"
-%include "gnuradio/trellis/pccc_encoder_ss.h"
-%include "gnuradio/trellis/pccc_encoder_si.h"
-%include "gnuradio/trellis/pccc_encoder_ii.h"
-%include "gnuradio/trellis/metrics_s.h"
-%include "gnuradio/trellis/metrics_i.h"
-%include "gnuradio/trellis/metrics_f.h"
-%include "gnuradio/trellis/metrics_c.h"
+%include "gnuradio/trellis/encoder.h"
+%include "gnuradio/trellis/sccc_encoder.h"
+%include "gnuradio/trellis/pccc_encoder.h"
+%include "gnuradio/trellis/metrics.h"
 
 GR_SWIG_BLOCK_MAGIC2(trellis, constellation_metrics_cf);
 GR_SWIG_BLOCK_MAGIC2(trellis, permutation);
 GR_SWIG_BLOCK_MAGIC2(trellis, siso_combined_f);
 GR_SWIG_BLOCK_MAGIC2(trellis, siso_f);
-GR_SWIG_BLOCK_MAGIC2(trellis, encoder_bb);
-GR_SWIG_BLOCK_MAGIC2(trellis, encoder_bs);
-GR_SWIG_BLOCK_MAGIC2(trellis, encoder_bi);
-GR_SWIG_BLOCK_MAGIC2(trellis, encoder_ss);
-GR_SWIG_BLOCK_MAGIC2(trellis, encoder_si);
-GR_SWIG_BLOCK_MAGIC2(trellis, encoder_ii);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_encoder_bb);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_encoder_bs);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_encoder_bi);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_encoder_ss);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_encoder_si);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_encoder_ii);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_encoder_bb);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_encoder_bs);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_encoder_bi);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_encoder_ss);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_encoder_si);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_encoder_ii);
-GR_SWIG_BLOCK_MAGIC2(trellis, metrics_s);
-GR_SWIG_BLOCK_MAGIC2(trellis, metrics_i);
-GR_SWIG_BLOCK_MAGIC2(trellis, metrics_f);
-GR_SWIG_BLOCK_MAGIC2(trellis, metrics_c);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, encoder_bb, encoder<std::uint8_t,std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, encoder_bs, encoder<std::uint8_t,std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, encoder_bi, encoder<std::uint8_t,std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, encoder_ss, encoder<std::int16_t,std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, encoder_si, encoder<std::int16_t,std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, encoder_ii, encoder<std::int32_t,std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_encoder_bb, sccc_encoder<std::uint8_t,std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_encoder_bs, sccc_encoder<std::uint8_t,std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_encoder_bi, sccc_encoder<std::uint8_t,std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_encoder_ss, sccc_encoder<std::int16_t,std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_encoder_si, sccc_encoder<std::int16_t,std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_encoder_ii, sccc_encoder<std::int32_t,std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_encoder_bb, pccc_encoder<std::uint8_t,std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_encoder_bs, pccc_encoder<std::uint8_t,std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_encoder_bi, pccc_encoder<std::uint8_t,std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_encoder_ss, pccc_encoder<std::int16_t,std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_encoder_si, pccc_encoder<std::int16_t,std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_encoder_ii, pccc_encoder<std::int32_t,std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, metrics_s, metrics<std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, metrics_i, metrics<std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, metrics_f, metrics<float>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, metrics_c, metrics<gr_complex>);
diff --git a/gr-trellis/swig/trellis_swig1.i b/gr-trellis/swig/trellis_swig1.i
index 6481aee245..7a8728efd2 100644
--- a/gr-trellis/swig/trellis_swig1.i
+++ b/gr-trellis/swig/trellis_swig1.i
@@ -33,105 +33,52 @@
 %include "gnuradio/trellis/interleaver.h"
 
 %{
-#include "gnuradio/trellis/pccc_decoder_b.h"
-#include "gnuradio/trellis/pccc_decoder_s.h"
-#include "gnuradio/trellis/pccc_decoder_i.h"
-#include "gnuradio/trellis/pccc_decoder_combined_fb.h"
-#include "gnuradio/trellis/pccc_decoder_combined_fs.h"
-#include "gnuradio/trellis/pccc_decoder_combined_fi.h"
-#include "gnuradio/trellis/pccc_decoder_combined_cb.h"
-#include "gnuradio/trellis/pccc_decoder_combined_cs.h"
-#include "gnuradio/trellis/pccc_decoder_combined_ci.h"
-#include "gnuradio/trellis/viterbi_b.h"
-#include "gnuradio/trellis/viterbi_s.h"
-#include "gnuradio/trellis/viterbi_i.h"
-#include "gnuradio/trellis/viterbi_combined_sb.h"
-#include "gnuradio/trellis/viterbi_combined_ss.h"
-#include "gnuradio/trellis/viterbi_combined_si.h"
-#include "gnuradio/trellis/viterbi_combined_ib.h"
-#include "gnuradio/trellis/viterbi_combined_is.h"
-#include "gnuradio/trellis/viterbi_combined_ii.h"
-#include "gnuradio/trellis/viterbi_combined_fb.h"
-#include "gnuradio/trellis/viterbi_combined_fs.h"
-#include "gnuradio/trellis/viterbi_combined_fi.h"
-#include "gnuradio/trellis/viterbi_combined_cb.h"
-#include "gnuradio/trellis/viterbi_combined_cs.h"
-#include "gnuradio/trellis/viterbi_combined_ci.h"
-#include "gnuradio/trellis/sccc_decoder_b.h"
-#include "gnuradio/trellis/sccc_decoder_s.h"
-#include "gnuradio/trellis/sccc_decoder_i.h"
-#include "gnuradio/trellis/sccc_decoder_combined_fb.h"
-#include "gnuradio/trellis/sccc_decoder_combined_fs.h"
-#include "gnuradio/trellis/sccc_decoder_combined_fi.h"
-#include "gnuradio/trellis/sccc_decoder_combined_cb.h"
-#include "gnuradio/trellis/sccc_decoder_combined_cs.h"
-#include "gnuradio/trellis/sccc_decoder_combined_ci.h"
+#include "gnuradio/trellis/pccc_decoder_blk.h"
+#include "gnuradio/trellis/pccc_decoder_combined_blk.h"
+#include "gnuradio/trellis/viterbi.h"
+#include "gnuradio/trellis/viterbi_combined.h"
+#include "gnuradio/trellis/sccc_decoder_blk.h"
+#include "gnuradio/trellis/sccc_decoder_combined_blk.h"
 %}
 
-%include "gnuradio/trellis/pccc_decoder_b.h"
-%include "gnuradio/trellis/pccc_decoder_s.h"
-%include "gnuradio/trellis/pccc_decoder_i.h"
-%include "gnuradio/trellis/pccc_decoder_combined_fb.h"
-%include "gnuradio/trellis/pccc_decoder_combined_fs.h"
-%include "gnuradio/trellis/pccc_decoder_combined_fi.h"
-%include "gnuradio/trellis/pccc_decoder_combined_cb.h"
-%include "gnuradio/trellis/pccc_decoder_combined_cs.h"
-%include "gnuradio/trellis/pccc_decoder_combined_ci.h"
-%include "gnuradio/trellis/viterbi_b.h"
-%include "gnuradio/trellis/viterbi_s.h"
-%include "gnuradio/trellis/viterbi_i.h"
-%include "gnuradio/trellis/viterbi_combined_sb.h"
-%include "gnuradio/trellis/viterbi_combined_ss.h"
-%include "gnuradio/trellis/viterbi_combined_si.h"
-%include "gnuradio/trellis/viterbi_combined_ib.h"
-%include "gnuradio/trellis/viterbi_combined_is.h"
-%include "gnuradio/trellis/viterbi_combined_ii.h"
-%include "gnuradio/trellis/viterbi_combined_fb.h"
-%include "gnuradio/trellis/viterbi_combined_fs.h"
-%include "gnuradio/trellis/viterbi_combined_fi.h"
-%include "gnuradio/trellis/viterbi_combined_cb.h"
-%include "gnuradio/trellis/viterbi_combined_cs.h"
-%include "gnuradio/trellis/viterbi_combined_ci.h"
-%include "gnuradio/trellis/sccc_decoder_b.h"
-%include "gnuradio/trellis/sccc_decoder_s.h"
-%include "gnuradio/trellis/sccc_decoder_i.h"
-%include "gnuradio/trellis/sccc_decoder_combined_fb.h"
-%include "gnuradio/trellis/sccc_decoder_combined_fs.h"
-%include "gnuradio/trellis/sccc_decoder_combined_fi.h"
-%include "gnuradio/trellis/sccc_decoder_combined_cb.h"
-%include "gnuradio/trellis/sccc_decoder_combined_cs.h"
-%include "gnuradio/trellis/sccc_decoder_combined_ci.h"
+%include "gnuradio/trellis/pccc_decoder_blk.h"
+%include "gnuradio/trellis/pccc_decoder_combined_blk.h"
+%include "gnuradio/trellis/viterbi.h"
+%include "gnuradio/trellis/viterbi_combined.h"
+%include "gnuradio/trellis/sccc_decoder_blk.h"
+%include "gnuradio/trellis/sccc_decoder_combined_blk.h"
 
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_decoder_b);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_decoder_s);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_decoder_i);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_decoder_combined_fb);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_decoder_combined_fs);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_decoder_combined_fi);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_decoder_combined_cb);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_decoder_combined_cs);
-GR_SWIG_BLOCK_MAGIC2(trellis, pccc_decoder_combined_ci);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_b);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_s);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_i);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_combined_sb);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_combined_ss);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_combined_si);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_combined_ib);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_combined_is);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_combined_ii);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_combined_fb);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_combined_fs);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_combined_fi);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_combined_cb);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_combined_cs);
-GR_SWIG_BLOCK_MAGIC2(trellis, viterbi_combined_ci);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_decoder_b);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_decoder_s);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_decoder_i);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_decoder_combined_fb);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_decoder_combined_fs);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_decoder_combined_fi);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_decoder_combined_cb);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_decoder_combined_cs);
-GR_SWIG_BLOCK_MAGIC2(trellis, sccc_decoder_combined_ci);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_decoder_b, pccc_decoder_blk<std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_decoder_s, pccc_decoder_blk<std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_decoder_i, pccc_decoder_blk<std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_b, viterbi<std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_s, viterbi<std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_i, viterbi<std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_combined_sb, viterbi_combined<std::int16_t,std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_combined_ss, viterbi_combined<std::int16_t,std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_combined_si, viterbi_combined<std::int16_t,std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_combined_ib, viterbi_combined<std::int32_t,std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_combined_is, viterbi_combined<std::int32_t,std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_combined_ii, viterbi_combined<std::int32_t,std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_combined_fb, viterbi_combined<float,std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_combined_fs, viterbi_combined<float,std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_combined_fi, viterbi_combined<float,std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_combined_cb, viterbi_combined<gr_complex,std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_combined_cs, viterbi_combined<gr_complex,std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, viterbi_combined_ci, viterbi_combined<gr_complex,std::int32_t>);
+
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_decoder_b, sccc_decoder_blk<std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_decoder_s, sccc_decoder_blk<std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_decoder_i, sccc_decoder_blk<std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_decoder_combined_fb, sccc_decoder_combined_blk<float, std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_decoder_combined_fs, sccc_decoder_combined_blk<float, std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_decoder_combined_fi, sccc_decoder_combined_blk<float, std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_decoder_combined_cb, sccc_decoder_combined_blk<gr_complex, std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_decoder_combined_cs, sccc_decoder_combined_blk<gr_complex, std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, sccc_decoder_combined_ci, sccc_decoder_combined_blk<gr_complex, std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_decoder_combined_fb, pccc_decoder_combined_blk<float, std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_decoder_combined_fs, pccc_decoder_combined_blk<float, std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_decoder_combined_fi, pccc_decoder_combined_blk<float, std::int32_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_decoder_combined_cb, pccc_decoder_combined_blk<gr_complex, std::uint8_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_decoder_combined_cs, pccc_decoder_combined_blk<gr_complex, std::int16_t>);
+GR_SWIG_BLOCK_MAGIC2_TMPL(trellis, pccc_decoder_combined_ci, pccc_decoder_combined_blk<gr_complex, std::int32_t>);
-- 
cgit v1.2.3


From a02e23e1889b90a85a9d5f5a86078382471bd8eb Mon Sep 17 00:00:00 2001
From: Andrej Rode <mail@andrejro.de>
Date: Wed, 22 Aug 2018 15:38:18 +0200
Subject: cmake: remove gengen tools

---
 cmake/Modules/GrMiscUtils.cmake                    | 173 ----------------
 docs/doxygen/Doxyfile.in                           |   2 -
 gnuradio-runtime/python/build_utils.py             | 227 --------------------
 gnuradio-runtime/python/build_utils_codes.py       |  53 -----
 .../gr-newmod/cmake/Modules/GrMiscUtils.cmake      | 176 ----------------
 .../python/modtool/gr-newmod/python/build_utils.py | 228 ---------------------
 .../modtool/gr-newmod/python/build_utils_codes.py  |  53 -----
 7 files changed, 912 deletions(-)
 delete mode 100644 gnuradio-runtime/python/build_utils.py
 delete mode 100644 gr-utils/python/modtool/gr-newmod/python/build_utils.py
 delete mode 100644 gr-utils/python/modtool/gr-newmod/python/build_utils_codes.py

(limited to 'docs/doxygen')

diff --git a/cmake/Modules/GrMiscUtils.cmake b/cmake/Modules/GrMiscUtils.cmake
index 6f0c8ac270..920e8adbee 100644
--- a/cmake/Modules/GrMiscUtils.cmake
+++ b/cmake/Modules/GrMiscUtils.cmake
@@ -302,176 +302,3 @@ set(CMAKE_REQUIRED_LIBRARIES -lpthread)
     )
     GR_ADD_COND_DEF(HAVE_SCHED_SETSCHEDULER)
 endmacro(GR_CHECK_LINUX_SCHED_AVAIL)
-
-########################################################################
-# Macros to generate source and header files from template
-########################################################################
-macro(GR_EXPAND_X_H component root)
-
-  include(GrPython)
-
-  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-"#!${PYTHON_EXECUTABLE}
-
-import sys, os, re
-sys.path.append('${GR_RUNTIME_PYTHONPATH}')
-os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
-os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
-
-if __name__ == '__main__':
-    import build_utils
-    root, inp = sys.argv[1:3]
-    for sig in sys.argv[3:]:
-        name = re.sub ('X+', sig, root)
-        d = build_utils.standard_dict2(name, sig, '${component}')
-        build_utils.expand_template(d, inp)
-")
-
-  #make a list of all the generated headers
-  unset(expanded_files_h)
-  foreach(sig ${ARGN})
-    string(REGEX REPLACE "X+" ${sig} name ${root})
-    list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
-  endforeach(sig)
-  unset(name)
-
-  #create a command to generate the headers
-  add_custom_command(
-    OUTPUT ${expanded_files_h}
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
-    COMMAND ${PYTHON_EXECUTABLE} -B
-    ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-    ${root} ${root}.h.t ${ARGN}
-  )
-
-  #install rules for the generated headers
-  list(APPEND generated_includes ${expanded_files_h})
-
-endmacro(GR_EXPAND_X_H)
-
-macro(GR_EXPAND_X_CC_H component root)
-
-  include(GrPython)
-
-  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-"#!${PYTHON_EXECUTABLE}
-
-import sys, os, re
-sys.path.append('${GR_RUNTIME_PYTHONPATH}')
-os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
-os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
-
-if __name__ == '__main__':
-    import build_utils
-    root, inp = sys.argv[1:3]
-    for sig in sys.argv[3:]:
-        name = re.sub ('X+', sig, root)
-        d = build_utils.standard_impl_dict2(name, sig, '${component}')
-        build_utils.expand_template(d, inp)
-")
-
-  #make a list of all the generated files
-  unset(expanded_files_cc)
-  unset(expanded_files_h)
-  foreach(sig ${ARGN})
-    string(REGEX REPLACE "X+" ${sig} name ${root})
-    list(APPEND expanded_files_cc ${CMAKE_CURRENT_BINARY_DIR}/${name}.cc)
-    list(APPEND expanded_files_h  ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
-  endforeach(sig)
-  unset(name)
-
-  #create a command to generate the source files
-  add_custom_command(
-    OUTPUT ${expanded_files_cc}
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.cc.t
-    COMMAND ${PYTHON_EXECUTABLE} -B
-    ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-    ${root} ${root}.cc.t ${ARGN}
-  )
-
-  #create a command to generate the header files
-  add_custom_command(
-    OUTPUT ${expanded_files_h}
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
-    COMMAND ${PYTHON_EXECUTABLE} -B
-    ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-    ${root} ${root}.h.t ${ARGN}
-  )
-
-  #make source files depends on headers to force generation
-  set_source_files_properties(${expanded_files_cc}
-    PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
-  )
-
-  #install rules for the generated files
-  list(APPEND generated_sources ${expanded_files_cc})
-  list(APPEND generated_headers ${expanded_files_h})
-
-endmacro(GR_EXPAND_X_CC_H)
-
-macro(GR_EXPAND_X_CC_H_IMPL component root)
-
-  include(GrPython)
-
-  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-"#!${PYTHON_EXECUTABLE}
-
-import sys, os, re
-sys.path.append('${GR_RUNTIME_PYTHONPATH}')
-os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
-os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
-
-if __name__ == '__main__':
-    import build_utils
-    root, inp = sys.argv[1:3]
-    for sig in sys.argv[3:]:
-        name = re.sub ('X+', sig, root)
-        d = build_utils.standard_dict(name, sig, '${component}')
-        build_utils.expand_template(d, inp, '_impl')
-")
-
-  #make a list of all the generated files
-  unset(expanded_files_cc_impl)
-  unset(expanded_files_h_impl)
-  unset(expanded_files_h)
-  foreach(sig ${ARGN})
-    string(REGEX REPLACE "X+" ${sig} name ${root})
-    list(APPEND expanded_files_cc_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.cc)
-    list(APPEND expanded_files_h_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.h)
-    list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/../include/gnuradio/${component}/${name}.h)
-  endforeach(sig)
-  unset(name)
-
-  #create a command to generate the _impl.cc files
-  add_custom_command(
-    OUTPUT ${expanded_files_cc_impl}
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.cc.t
-    COMMAND ${PYTHON_EXECUTABLE} -B
-    ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-    ${root} ${root}_impl.cc.t ${ARGN}
-  )
-
-  #create a command to generate the _impl.h files
-  add_custom_command(
-    OUTPUT ${expanded_files_h_impl}
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.h.t
-    COMMAND ${PYTHON_EXECUTABLE} -B
-    ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-    ${root} ${root}_impl.h.t ${ARGN}
-  )
-
-  #make _impl.cc source files depend on _impl.h to force generation
-  set_source_files_properties(${expanded_files_cc_impl}
-    PROPERTIES OBJECT_DEPENDS "${expanded_files_h_impl}"
-  )
-
-  #make _impl.h source files depend on headers to force generation
-  set_source_files_properties(${expanded_files_h_impl}
-    PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
-  )
-
-  #install rules for the generated files
-  list(APPEND generated_sources ${expanded_files_cc_impl})
-  list(APPEND generated_headers ${expanded_files_h_impl})
-
-endmacro(GR_EXPAND_X_CC_H_IMPL)
diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in
index 3be1cbc23a..698798d762 100644
--- a/docs/doxygen/Doxyfile.in
+++ b/docs/doxygen/Doxyfile.in
@@ -738,8 +738,6 @@ EXCLUDE                = @abs_top_srcdir@/volk \
                          @abs_top_builddir@/dtools \
                          @abs_top_builddir@/gnuradio-runtime/lib/runtime/gr_error_handler.cc \
                          @abs_top_builddir@/gnuradio-runtime/swig \
-                         @abs_top_builddir@/gnuradio-runtime/python/build_utils.py \
-                         @abs_top_builddir@/gnuradio-runtime/python/build_utils_codes.py \
                          @abs_top_builddir@/gnuradio-runtime/python/gnuradio/gr/gr_threading.py \
                          @abs_top_builddir@/gnuradio-runtime/python/gnuradio/gr/gr_threading_23.py \
                          @abs_top_builddir@/gnuradio-runtime/python/gnuradio/gr/gr_threading_24.py \
diff --git a/gnuradio-runtime/python/build_utils.py b/gnuradio-runtime/python/build_utils.py
deleted file mode 100644
index 82a2265cc2..0000000000
--- a/gnuradio-runtime/python/build_utils.py
+++ /dev/null
@@ -1,227 +0,0 @@
-#
-# Copyright 2004,2009,2012 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio 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 General Public License for more details.
-#
-# 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-"""Misc utilities used at build time
-"""
-from __future__ import unicode_literals
-
-import re, os, os.path
-from build_utils_codes import *
-
-
-# set srcdir to the directory that contains Makefile.am
-try:
-    srcdir = os.environ['srcdir']
-except KeyError as e:
-    srcdir = "."
-srcdir = srcdir + '/'
-
-# set do_makefile to either true or false dependeing on the environment
-try:
-    if os.environ['do_makefile'] == '0':
-        do_makefile = False
-    else:
-        do_makefile = True
-except KeyError as e:
-    do_makefile = False
-
-# set do_sources to either true or false dependeing on the environment
-try:
-    if os.environ['do_sources'] == '0':
-        do_sources = False
-    else:
-        do_sources = True
-except KeyError as e:
-    do_sources = True
-
-name_dict = {}
-
-def log_output_name (name):
-    (base, ext) = os.path.splitext (name)
-    ext = ext[1:]                       # drop the leading '.'
-
-    entry = name_dict.setdefault (ext, [])
-    entry.append (name)
-
-def open_and_log_name (name, dir):
-    global do_sources
-    if do_sources:
-        f = open (name, dir)
-    else:
-        f = None
-    log_output_name (name)
-    return f
-
-def expand_template (d, template_filename, extra = ""):
-    '''Given a dictionary D and a TEMPLATE_FILENAME, expand template into output file
-    '''
-    global do_sources
-    output_extension = extract_extension (template_filename)
-    template = open_src (template_filename, 'r')
-    output_name = d['NAME'] + extra + '.' + output_extension
-    log_output_name (output_name)
-    if do_sources:
-        output = open (output_name, 'w')
-        do_substitution (d, template, output)
-        output.close ()
-    template.close ()
-
-def output_glue (dirname):
-    output_makefile_fragment ()
-    output_ifile_include (dirname)
-
-def output_makefile_fragment ():
-    global do_makefile
-    if not do_makefile:
-        return
-# overwrite the source, which must be writable; this should have been
-# checked for beforehand in the top-level Makefile.gen.gen .
-    f = open (os.path.join (os.environ.get('gendir', os.environ.get('srcdir', '.')), 'Makefile.gen'), 'w')
-    f.write ('#\n# This file is machine generated.  All edits will be overwritten\n#\n')
-    output_subfrag (f, 'h')
-    output_subfrag (f, 'i')
-    output_subfrag (f, 'cc')
-    f.close ()
-
-def output_ifile_include (dirname):
-    global do_sources
-    if do_sources:
-        f = open ('%s_generated.i' % (dirname,), 'w')
-        f.write ('//\n// This file is machine generated.  All edits will be overwritten\n//\n')
-        files = name_dict.setdefault ('i', [])
-        files.sort ()
-        f.write ('%{\n')
-        for file in files:
-            f.write ('#include <%s>\n' % (file[0:-1] + 'h',))
-        f.write ('%}\n\n')
-        for file in files:
-            f.write ('%%include <%s>\n' % (file,))
-
-def output_subfrag (f, ext):
-    files = name_dict.setdefault (ext, [])
-    files.sort ()
-    f.write ("GENERATED_%s =" % (ext.upper ()))
-    for file in files:
-        f.write (" \\\n\t%s" % (file,))
-    f.write ("\n\n")
-
-def extract_extension (template_name):
-    # template name is something like: GrFIRfilterXXX.h.t
-    # we return everything between the penultimate . and .t
-    mo = re.search (r'\.([a-z]+)\.t$', template_name)
-    if not mo:
-        raise ValueError("Incorrectly formed template_name '%s'" % (template_name,))
-    return mo.group (1)
-
-def open_src (name, mode):
-    global srcdir
-    return open (os.path.join (srcdir, name), mode)
-
-def do_substitution (d, in_file, out_file):
-    def repl (match_obj):
-        key = match_obj.group (1)
-        # print key
-        return d[key]
-
-    inp = in_file.read ()
-    out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, inp)
-    out_file.write (out)
-
-
-
-copyright = '''/* -*- c++ -*- */
-/*
- * Copyright 2003,2004 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-'''
-
-def is_complex (code3):
-    if i_code (code3) == 'c' or o_code (code3) == 'c':
-        return '1'
-    else:
-        return '0'
-
-
-def standard_dict (name, code3, package='gr'):
-    d = {}
-    d['NAME'] = name
-    d['NAME_IMPL'] = name+'_impl'
-    d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
-    d['GUARD_NAME_IMPL'] = 'INCLUDED_%s_%s_IMPL_H' % (package.upper(), name.upper())
-    d['BASE_NAME'] = re.sub ('^' + package + '_', '', name)
-    d['SPTR_NAME'] = '%s_sptr' % name
-    d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
-    d['COPYRIGHT'] = copyright
-    d['TYPE'] = i_type (code3)
-    d['I_TYPE'] = i_type (code3)
-    d['O_TYPE'] = o_type (code3)
-    d['TAP_TYPE'] = tap_type (code3)
-    d['IS_COMPLEX'] = is_complex (code3)
-    return d
-
-
-def standard_dict2 (name, code3, package):
-    d = {}
-    d['NAME'] = name
-    d['BASE_NAME'] = name
-    d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
-    d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
-    d['COPYRIGHT'] = copyright
-    d['TYPE'] = i_type (code3)
-    d['I_TYPE'] = i_type (code3)
-    d['O_TYPE'] = o_type (code3)
-    d['TAP_TYPE'] = tap_type (code3)
-    d['IS_COMPLEX'] = is_complex (code3)
-    return d
-
-def standard_impl_dict2 (name, code3, package):
-    d = {}
-    d['NAME'] = name
-    d['IMPL_NAME'] = name
-    d['BASE_NAME'] = name.rstrip("impl").rstrip("_")
-    d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
-    d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
-    d['COPYRIGHT'] = copyright
-    d['FIR_TYPE'] = "fir_filter_" + code3
-    d['CFIR_TYPE'] = "fir_filter_" + code3[0:2] + 'c'
-    d['TYPE'] = i_type (code3)
-    d['I_TYPE'] = i_type (code3)
-    d['O_TYPE'] = o_type (code3)
-    d['TAP_TYPE'] = tap_type (code3)
-    d['IS_COMPLEX'] = is_complex (code3)
-    return d
diff --git a/gnuradio-runtime/python/build_utils_codes.py b/gnuradio-runtime/python/build_utils_codes.py
index 22a6bdb99b..e69de29bb2 100644
--- a/gnuradio-runtime/python/build_utils_codes.py
+++ b/gnuradio-runtime/python/build_utils_codes.py
@@ -1,53 +0,0 @@
-from __future__ import unicode_literals
-#
-# Copyright 2004 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio 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 General Public License for more details.
-#
-# 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-def i_code (code3):
-    return code3[0]
-
-def o_code (code3):
-    if len (code3) >= 2:
-        return code3[1]
-    else:
-        return code3[0]
-
-def tap_code (code3):
-    if len (code3) >= 3:
-        return code3[2]
-    else:
-        return code3[0]
-
-def i_type (code3):
-    return char_to_type[i_code (code3)]
-
-def o_type (code3):
-    return char_to_type[o_code (code3)]
-
-def tap_type (code3):
-    return char_to_type[tap_code (code3)]
-
-
-char_to_type = {}
-char_to_type['s'] = 'short'
-char_to_type['i'] = 'int'
-char_to_type['f'] = 'float'
-char_to_type['c'] = 'gr_complex'
-char_to_type['b'] = 'unsigned char'
diff --git a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake
index cc8e7c17dc..beeeebe72a 100644
--- a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake
+++ b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake
@@ -303,179 +303,3 @@ set(CMAKE_REQUIRED_LIBRARIES -lpthread)
     )
     GR_ADD_COND_DEF(HAVE_SCHED_SETSCHEDULER)
 endmacro(GR_CHECK_LINUX_SCHED_AVAIL)
-
-########################################################################
-# Macros to generate source and header files from template
-########################################################################
-macro(GR_EXPAND_X_H component root)
-
-  include(GrPython)
-
-  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-"#!${PYTHON_EXECUTABLE}
-
-import sys, os, re
-sys.path.append('${GR_RUNTIME_PYTHONPATH}')
-sys.path.append('${CMAKE_SOURCE_DIR}/python')
-os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
-os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
-
-if __name__ == '__main__':
-    import build_utils
-    root, inp = sys.argv[1:3]
-    for sig in sys.argv[3:]:
-        name = re.sub ('X+', sig, root)
-        d = build_utils.standard_dict2(name, sig, '${component}')
-        build_utils.expand_template(d, inp)
-")
-
-  #make a list of all the generated headers
-  unset(expanded_files_h)
-  foreach(sig ${ARGN})
-    string(REGEX REPLACE "X+" ${sig} name ${root})
-    list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
-  endforeach(sig)
-  unset(name)
-
-  #create a command to generate the headers
-  add_custom_command(
-    OUTPUT ${expanded_files_h}
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
-    COMMAND ${PYTHON_EXECUTABLE} -B
-    ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-    ${root} ${root}.h.t ${ARGN}
-  )
-
-  #install rules for the generated headers
-  list(APPEND generated_includes ${expanded_files_h})
-
-endmacro(GR_EXPAND_X_H)
-
-macro(GR_EXPAND_X_CC_H component root)
-
-  include(GrPython)
-
-  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-"#!${PYTHON_EXECUTABLE}
-
-import sys, os, re
-sys.path.append('${GR_RUNTIME_PYTHONPATH}')
-sys.path.append('${CMAKE_SOURCE_DIR}/python')
-os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
-os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
-
-if __name__ == '__main__':
-    import build_utils
-    root, inp = sys.argv[1:3]
-    for sig in sys.argv[3:]:
-        name = re.sub ('X+', sig, root)
-        d = build_utils.standard_impl_dict2(name, sig, '${component}')
-        build_utils.expand_template(d, inp)
-")
-
-  #make a list of all the generated files
-  unset(expanded_files_cc)
-  unset(expanded_files_h)
-  foreach(sig ${ARGN})
-    string(REGEX REPLACE "X+" ${sig} name ${root})
-    list(APPEND expanded_files_cc ${CMAKE_CURRENT_BINARY_DIR}/${name}.cc)
-    list(APPEND expanded_files_h  ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
-  endforeach(sig)
-  unset(name)
-
-  #create a command to generate the source files
-  add_custom_command(
-    OUTPUT ${expanded_files_cc}
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.cc.t
-    COMMAND ${PYTHON_EXECUTABLE} -B
-    ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-    ${root} ${root}.cc.t ${ARGN}
-  )
-
-  #create a command to generate the header files
-  add_custom_command(
-    OUTPUT ${expanded_files_h}
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
-    COMMAND ${PYTHON_EXECUTABLE} -B
-    ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-    ${root} ${root}.h.t ${ARGN}
-  )
-
-  #make source files depends on headers to force generation
-  set_source_files_properties(${expanded_files_cc}
-    PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
-  )
-
-  #install rules for the generated files
-  list(APPEND generated_sources ${expanded_files_cc})
-  list(APPEND generated_headers ${expanded_files_h})
-
-endmacro(GR_EXPAND_X_CC_H)
-
-macro(GR_EXPAND_X_CC_H_IMPL component root)
-
-  include(GrPython)
-
-  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-"#!${PYTHON_EXECUTABLE}
-
-import sys, os, re
-sys.path.append('${GR_RUNTIME_PYTHONPATH}')
-sys.path.append('${CMAKE_SOURCE_DIR}/python')
-os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
-os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
-
-if __name__ == '__main__':
-    import build_utils
-    root, inp = sys.argv[1:3]
-    for sig in sys.argv[3:]:
-        name = re.sub ('X+', sig, root)
-        d = build_utils.standard_dict(name, sig, '${component}')
-        build_utils.expand_template(d, inp, '_impl')
-")
-
-  #make a list of all the generated files
-  unset(expanded_files_cc_impl)
-  unset(expanded_files_h_impl)
-  unset(expanded_files_h)
-  foreach(sig ${ARGN})
-    string(REGEX REPLACE "X+" ${sig} name ${root})
-    list(APPEND expanded_files_cc_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.cc)
-    list(APPEND expanded_files_h_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.h)
-    list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/../include/gnuradio/${component}/${name}.h)
-  endforeach(sig)
-  unset(name)
-
-  #create a command to generate the _impl.cc files
-  add_custom_command(
-    OUTPUT ${expanded_files_cc_impl}
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.cc.t
-    COMMAND ${PYTHON_EXECUTABLE} -B
-    ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-    ${root} ${root}_impl.cc.t ${ARGN}
-  )
-
-  #create a command to generate the _impl.h files
-  add_custom_command(
-    OUTPUT ${expanded_files_h_impl}
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.h.t
-    COMMAND ${PYTHON_EXECUTABLE} -B
-    ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
-    ${root} ${root}_impl.h.t ${ARGN}
-  )
-
-  #make _impl.cc source files depend on _impl.h to force generation
-  set_source_files_properties(${expanded_files_cc_impl}
-    PROPERTIES OBJECT_DEPENDS "${expanded_files_h_impl}"
-  )
-
-  #make _impl.h source files depend on headers to force generation
-  set_source_files_properties(${expanded_files_h_impl}
-    PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
-  )
-
-  #install rules for the generated files
-  list(APPEND generated_sources ${expanded_files_cc_impl})
-  list(APPEND generated_headers ${expanded_files_h_impl})
-
-endmacro(GR_EXPAND_X_CC_H_IMPL)
diff --git a/gr-utils/python/modtool/gr-newmod/python/build_utils.py b/gr-utils/python/modtool/gr-newmod/python/build_utils.py
deleted file mode 100644
index 0b26844cbf..0000000000
--- a/gr-utils/python/modtool/gr-newmod/python/build_utils.py
+++ /dev/null
@@ -1,228 +0,0 @@
-#
-# Copyright 2004,2009,2012 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio 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 General Public License for more details.
-#
-# 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-"""Misc utilities used at build time
-"""
-from __future__ import absolute_import
-from __future__ import unicode_literals
-
-import re, os, os.path
-from .build_utils_codes import *
-
-
-# set srcdir to the directory that contains Makefile.am
-try:
-    srcdir = os.environ['srcdir']
-except KeyError as e:
-    srcdir = "."
-srcdir = srcdir + '/'
-
-# set do_makefile to either true or false dependeing on the environment
-try:
-    if os.environ['do_makefile'] == '0':
-        do_makefile = False
-    else:
-        do_makefile = True
-except KeyError as e:
-    do_makefile = False
-
-# set do_sources to either true or false dependeing on the environment
-try:
-    if os.environ['do_sources'] == '0':
-        do_sources = False
-    else:
-        do_sources = True
-except KeyError as e:
-    do_sources = True
-
-name_dict = {}
-
-def log_output_name (name):
-    (base, ext) = os.path.splitext (name)
-    ext = ext[1:]                       # drop the leading '.'
-
-    entry = name_dict.setdefault (ext, [])
-    entry.append (name)
-
-def open_and_log_name (name, dir):
-    global do_sources
-    if do_sources:
-        f = open (name, dir)
-    else:
-        f = None
-    log_output_name (name)
-    return f
-
-def expand_template (d, template_filename, extra = ""):
-    '''Given a dictionary D and a TEMPLATE_FILENAME, expand template into output file
-    '''
-    global do_sources
-    output_extension = extract_extension (template_filename)
-    template = open_src (template_filename, 'r')
-    output_name = d['NAME'] + extra + '.' + output_extension
-    log_output_name (output_name)
-    if do_sources:
-        output = open (output_name, 'w')
-        do_substitution (d, template, output)
-        output.close ()
-    template.close ()
-
-def output_glue (dirname):
-    output_makefile_fragment ()
-    output_ifile_include (dirname)
-
-def output_makefile_fragment ():
-    global do_makefile
-    if not do_makefile:
-        return
-# overwrite the source, which must be writable; this should have been
-# checked for beforehand in the top-level Makefile.gen.gen .
-    f = open (os.path.join (os.environ.get('gendir', os.environ.get('srcdir', '.')), 'Makefile.gen'), 'w')
-    f.write ('#\n# This file is machine generated.  All edits will be overwritten\n#\n')
-    output_subfrag (f, 'h')
-    output_subfrag (f, 'i')
-    output_subfrag (f, 'cc')
-    f.close ()
-
-def output_ifile_include (dirname):
-    global do_sources
-    if do_sources:
-        f = open ('%s_generated.i' % (dirname,), 'w')
-        f.write ('//\n// This file is machine generated.  All edits will be overwritten\n//\n')
-        files = name_dict.setdefault ('i', [])
-        files.sort ()
-        f.write ('%{\n')
-        for file in files:
-            f.write ('#include <%s>\n' % (file[0:-1] + 'h',))
-        f.write ('%}\n\n')
-        for file in files:
-            f.write ('%%include <%s>\n' % (file,))
-
-def output_subfrag (f, ext):
-    files = name_dict.setdefault (ext, [])
-    files.sort ()
-    f.write ("GENERATED_%s =" % (ext.upper ()))
-    for file in files:
-        f.write (" \\\n\t%s" % (file,))
-    f.write ("\n\n")
-
-def extract_extension (template_name):
-    # template name is something like: GrFIRfilterXXX.h.t
-    # we return everything between the penultimate . and .t
-    mo = re.search (r'\.([a-z]+)\.t$', template_name)
-    if not mo:
-        raise ValueError("Incorrectly formed template_name '%s'" % (template_name,))
-    return mo.group (1)
-
-def open_src (name, mode):
-    global srcdir
-    return open (os.path.join (srcdir, name), mode)
-
-def do_substitution (d, in_file, out_file):
-    def repl (match_obj):
-        key = match_obj.group (1)
-        # print key
-        return d[key]
-
-    inp = in_file.read ()
-    out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, inp)
-    out_file.write (out)
-
-
-
-copyright = '''/* -*- c++ -*- */
-/*
- * Copyright 2003,2004 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-'''
-
-def is_complex (code3):
-    if i_code (code3) == 'c' or o_code (code3) == 'c':
-        return '1'
-    else:
-        return '0'
-
-
-def standard_dict (name, code3, package='gr'):
-    d = {}
-    d['NAME'] = name
-    d['NAME_IMPL'] = name+'_impl'
-    d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
-    d['GUARD_NAME_IMPL'] = 'INCLUDED_%s_%s_IMPL_H' % (package.upper(), name.upper())
-    d['BASE_NAME'] = re.sub ('^' + package + '_', '', name)
-    d['SPTR_NAME'] = '%s_sptr' % name
-    d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
-    d['COPYRIGHT'] = copyright
-    d['TYPE'] = i_type (code3)
-    d['I_TYPE'] = i_type (code3)
-    d['O_TYPE'] = o_type (code3)
-    d['TAP_TYPE'] = tap_type (code3)
-    d['IS_COMPLEX'] = is_complex (code3)
-    return d
-
-
-def standard_dict2 (name, code3, package):
-    d = {}
-    d['NAME'] = name
-    d['BASE_NAME'] = name
-    d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
-    d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
-    d['COPYRIGHT'] = copyright
-    d['TYPE'] = i_type (code3)
-    d['I_TYPE'] = i_type (code3)
-    d['O_TYPE'] = o_type (code3)
-    d['TAP_TYPE'] = tap_type (code3)
-    d['IS_COMPLEX'] = is_complex (code3)
-    return d
-
-def standard_impl_dict2 (name, code3, package):
-    d = {}
-    d['NAME'] = name
-    d['IMPL_NAME'] = name
-    d['BASE_NAME'] = name.rstrip("impl").rstrip("_")
-    d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
-    d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
-    d['COPYRIGHT'] = copyright
-    d['FIR_TYPE'] = "fir_filter_" + code3
-    d['CFIR_TYPE'] = "fir_filter_" + code3[0:2] + 'c'
-    d['TYPE'] = i_type (code3)
-    d['I_TYPE'] = i_type (code3)
-    d['O_TYPE'] = o_type (code3)
-    d['TAP_TYPE'] = tap_type (code3)
-    d['IS_COMPLEX'] = is_complex (code3)
-    return d
diff --git a/gr-utils/python/modtool/gr-newmod/python/build_utils_codes.py b/gr-utils/python/modtool/gr-newmod/python/build_utils_codes.py
deleted file mode 100644
index 22a6bdb99b..0000000000
--- a/gr-utils/python/modtool/gr-newmod/python/build_utils_codes.py
+++ /dev/null
@@ -1,53 +0,0 @@
-from __future__ import unicode_literals
-#
-# Copyright 2004 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio 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 General Public License for more details.
-#
-# 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-def i_code (code3):
-    return code3[0]
-
-def o_code (code3):
-    if len (code3) >= 2:
-        return code3[1]
-    else:
-        return code3[0]
-
-def tap_code (code3):
-    if len (code3) >= 3:
-        return code3[2]
-    else:
-        return code3[0]
-
-def i_type (code3):
-    return char_to_type[i_code (code3)]
-
-def o_type (code3):
-    return char_to_type[o_code (code3)]
-
-def tap_type (code3):
-    return char_to_type[tap_code (code3)]
-
-
-char_to_type = {}
-char_to_type['s'] = 'short'
-char_to_type['i'] = 'int'
-char_to_type['f'] = 'float'
-char_to_type['c'] = 'gr_complex'
-char_to_type['b'] = 'unsigned char'
-- 
cgit v1.2.3


From 890217f5b1420b3de96b381febf889fd403c210e Mon Sep 17 00:00:00 2001
From: Andrej Rode <mail@andrejro.de>
Date: Wed, 22 Aug 2018 22:58:55 +0200
Subject: pmt: replace file generation with pre-generated files

---
 docs/doxygen/CMakeLists.txt                    |    4 -
 gnuradio-runtime/include/pmt/CMakeLists.txt    |    1 +
 gnuradio-runtime/include/pmt/pmt_serial_tags.h |   62 +
 gnuradio-runtime/lib/CMakeLists.txt            |    5 -
 gnuradio-runtime/lib/pmt/CMakeLists.txt        |   63 +-
 gnuradio-runtime/lib/pmt/gen-serial-tags.py    |   56 -
 gnuradio-runtime/lib/pmt/generate_unv.py       |  192 ---
 gnuradio-runtime/lib/pmt/pmt-serial-tags.scm   |   77 -
 gnuradio-runtime/lib/pmt/pmt_int.h             |    3 -
 gnuradio-runtime/lib/pmt/pmt_unv.cc            | 1821 ++++++++++++++++++++++++
 gnuradio-runtime/lib/pmt/pmt_unv_int.h         |  331 +++++
 gnuradio-runtime/lib/pmt/qa_pmt_unv.cc         |  448 ++++++
 gnuradio-runtime/lib/pmt/qa_pmt_unv.h          |   61 +
 gnuradio-runtime/lib/pmt/unv_qa_template.cc.t  |   35 -
 gnuradio-runtime/lib/pmt/unv_template.cc.t     |  149 --
 gnuradio-runtime/lib/pmt/unv_template.h.t      |   25 -
 gnuradio-runtime/swig/CMakeLists.txt           |    1 -
 17 files changed, 2727 insertions(+), 607 deletions(-)
 create mode 100644 gnuradio-runtime/include/pmt/pmt_serial_tags.h
 delete mode 100644 gnuradio-runtime/lib/pmt/gen-serial-tags.py
 delete mode 100644 gnuradio-runtime/lib/pmt/generate_unv.py
 delete mode 100644 gnuradio-runtime/lib/pmt/pmt-serial-tags.scm
 create mode 100644 gnuradio-runtime/lib/pmt/pmt_unv.cc
 create mode 100644 gnuradio-runtime/lib/pmt/pmt_unv_int.h
 create mode 100644 gnuradio-runtime/lib/pmt/qa_pmt_unv.cc
 create mode 100644 gnuradio-runtime/lib/pmt/qa_pmt_unv.h
 delete mode 100644 gnuradio-runtime/lib/pmt/unv_qa_template.cc.t
 delete mode 100644 gnuradio-runtime/lib/pmt/unv_template.cc.t
 delete mode 100644 gnuradio-runtime/lib/pmt/unv_template.h.t

(limited to 'docs/doxygen')

diff --git a/docs/doxygen/CMakeLists.txt b/docs/doxygen/CMakeLists.txt
index 8c8bd4b248..952579f589 100644
--- a/docs/doxygen/CMakeLists.txt
+++ b/docs/doxygen/CMakeLists.txt
@@ -41,10 +41,6 @@ configure_file(
 
 set(BUILT_DIRS ${CMAKE_CURRENT_BINARY_DIR}/xml ${CMAKE_CURRENT_BINARY_DIR}/html)
 
-if(ENABLE_GNURADIO_RUNTIME)
-  list(APPEND GENERATED_DEPS pmt_generated)
-endif(ENABLE_GNURADIO_RUNTIME)
-
 ########################################################################
 # Make and install doxygen docs
 ########################################################################
diff --git a/gnuradio-runtime/include/pmt/CMakeLists.txt b/gnuradio-runtime/include/pmt/CMakeLists.txt
index f4a541e0dd..2b33ea0105 100644
--- a/gnuradio-runtime/include/pmt/CMakeLists.txt
+++ b/gnuradio-runtime/include/pmt/CMakeLists.txt
@@ -25,5 +25,6 @@ install(FILES
   pmt.h
   pmt_pool.h
   pmt_sugar.h
+  pmt_serial_tags.h
   DESTINATION ${GR_INCLUDE_DIR}/pmt
 )
diff --git a/gnuradio-runtime/include/pmt/pmt_serial_tags.h b/gnuradio-runtime/include/pmt/pmt_serial_tags.h
new file mode 100644
index 0000000000..ea89693a49
--- /dev/null
+++ b/gnuradio-runtime/include/pmt/pmt_serial_tags.h
@@ -0,0 +1,62 @@
+
+//
+// Copyright 2011 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// GNU Radio 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+//
+// THIS FILE IS MACHINE GENERATED FROM gen-serial-tags.py. DO NOT EDIT BY HAND.
+// See pmt-serial-tags.scm for additional commentary.
+//
+
+#ifndef INCLUDED_PMT_SERIAL_TAGS_H
+#define INCLUDED_PMT_SERIAL_TAGS_H
+
+enum pst_tags {
+    PST_TRUE = 0x00,
+    PST_FALSE = 0x01,
+    PST_SYMBOL = 0x02,
+    PST_INT32 = 0x03,
+    PST_DOUBLE = 0x04,
+    PST_COMPLEX = 0x05,
+    PST_NULL = 0x06,
+    PST_PAIR = 0x07,
+    PST_VECTOR = 0x08,
+    PST_DICT = 0x09,
+    PST_UNIFORM_VECTOR = 0x0a,
+    PST_UINT64 = 0x0b,
+    PST_TUPLE = 0x0c,
+    UVI_ENDIAN_MASK = 0x80,
+    UVI_SUBTYPE_MASK = 0x7f,
+    UVI_LITTLE_ENDIAN = 0x00,
+    UVI_BIG_ENDIAN = 0x80,
+    UVI_U8 = 0x00,
+    UVI_S8 = 0x01,
+    UVI_U16 = 0x02,
+    UVI_S16 = 0x03,
+    UVI_U32 = 0x04,
+    UVI_S32 = 0x05,
+    UVI_U64 = 0x06,
+    UVI_S64 = 0x07,
+    UVI_F32 = 0x08,
+    UVI_F64 = 0x09,
+    UVI_C32 = 0x0a,
+    UVI_C64 = 0x0b,
+    PST_COMMENT = 0x3b,
+    PST_COMMENT_END = 0x0a
+};
+#endif /* INCLUDED_PMT_SERIAL_TAGS_H */
diff --git a/gnuradio-runtime/lib/CMakeLists.txt b/gnuradio-runtime/lib/CMakeLists.txt
index 4fd5a610f6..cd4a850c79 100644
--- a/gnuradio-runtime/lib/CMakeLists.txt
+++ b/gnuradio-runtime/lib/CMakeLists.txt
@@ -198,11 +198,6 @@ add_library(gnuradio-runtime SHARED ${gnuradio_runtime_sources})
 target_link_libraries(gnuradio-runtime ${gnuradio_runtime_libs})
 GR_LIBRARY_FOO(gnuradio-runtime)
 
-add_dependencies(gnuradio-runtime
-  pmt_generated runtime_generated_includes
-)
-
-
 #######################################################
 # STATIC LIB BUILD
 #######################################################
diff --git a/gnuradio-runtime/lib/pmt/CMakeLists.txt b/gnuradio-runtime/lib/pmt/CMakeLists.txt
index 85b2a4d6e0..c840b8b930 100644
--- a/gnuradio-runtime/lib/pmt/CMakeLists.txt
+++ b/gnuradio-runtime/lib/pmt/CMakeLists.txt
@@ -23,57 +23,8 @@
 include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
 include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 
-########################################################################
-# Generate serial tags header file
-########################################################################
-
-get_filename_component(PMT_SERIAL_TAGS_H
-    ${CMAKE_CURRENT_BINARY_DIR}/../../include/pmt/pmt_serial_tags.h ABSOLUTE
-)
-
-add_custom_command(
-    OUTPUT ${PMT_SERIAL_TAGS_H}
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/gen-serial-tags.py
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/pmt-serial-tags.scm
-    COMMAND ${PYTHON_EXECUTABLE}
-        ${CMAKE_CURRENT_SOURCE_DIR}/gen-serial-tags.py
-        ${CMAKE_CURRENT_SOURCE_DIR}/pmt-serial-tags.scm
-        ${PMT_SERIAL_TAGS_H}
-)
-
-install(
-    FILES ${PMT_SERIAL_TAGS_H}
-    DESTINATION ${GR_INCLUDE_DIR}/pmt
-)
-
-include(AddFileDependencies)
-ADD_FILE_DEPENDENCIES(
-    ${CMAKE_CURRENT_SOURCE_DIR}/pmt_serialize.cc
-    ${PMT_SERIAL_TAGS_H}
-)
-
-########################################################################
-# Generate other pmt stuff
-########################################################################
-add_custom_command(
-    OUTPUT
-        ${CMAKE_CURRENT_BINARY_DIR}/pmt_unv_int.h
-        ${CMAKE_CURRENT_BINARY_DIR}/qa_pmt_unv.h
-        ${CMAKE_CURRENT_BINARY_DIR}/pmt_unv.cc
-        ${CMAKE_CURRENT_BINARY_DIR}/qa_pmt_unv.cc
-    DEPENDS
-        ${CMAKE_CURRENT_SOURCE_DIR}/generate_unv.py
-        ${CMAKE_CURRENT_SOURCE_DIR}/unv_template.h.t
-        ${CMAKE_CURRENT_SOURCE_DIR}/unv_template.cc.t
-        ${CMAKE_CURRENT_SOURCE_DIR}/unv_qa_template.cc.t
-    COMMAND ${PYTHON_EXECUTABLE} -B -c
-    "import os, sys; srcdir='${CMAKE_CURRENT_SOURCE_DIR}'; sys.path.append(srcdir); os.environ['srcdir']=srcdir; from generate_unv import main; main()"
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-    VERBATIM
-)
-
 set(pmt_sources
-  ${CMAKE_CURRENT_BINARY_DIR}/pmt_unv.cc
+  ${CMAKE_CURRENT_SOURCE_DIR}/pmt_unv.cc
   ${CMAKE_CURRENT_SOURCE_DIR}/pmt.cc
   ${CMAKE_CURRENT_SOURCE_DIR}/pmt_io.cc
   ${CMAKE_CURRENT_SOURCE_DIR}/pmt_pool.cc
@@ -85,10 +36,6 @@ list(APPEND gnuradio_pmt_libs
     ${LOG4CPP_LIBRARIES}
 )
 
-add_custom_target(pmt_generated
-  DEPENDS ${PMT_SERIAL_TAGS_H} ${CMAKE_CURRENT_BINARY_DIR}/pmt_unv_int.h)
-
-
 #Add Windows DLL resource file if using MSVC
 if(MSVC)
     include(${CMAKE_SOURCE_DIR}/cmake/Modules/GrVersion.cmake)
@@ -109,14 +56,10 @@ target_link_libraries(gnuradio-pmt ${gnuradio_pmt_libs})
 
 GR_LIBRARY_FOO(gnuradio-pmt)
 
-add_dependencies(gnuradio-pmt
-  pmt_generated
-)
-
 if(ENABLE_STATIC_LIBS)
   add_library(gnuradio-pmt_static STATIC ${pmt_sources})
 
-  add_dependencies(gnuradio-pmt_static pmt_generated)
+  add_dependencies(gnuradio-pmt_static)
 
   if(NOT WIN32)
     set_target_properties(gnuradio-pmt_static
@@ -140,7 +83,7 @@ include(GrTest)
 list(APPEND test_gnuradio_pmt_sources
   qa_pmt.cc
   qa_pmt_prims.cc
-  ${CMAKE_CURRENT_BINARY_DIR}/qa_pmt_unv.cc
+  qa_pmt_unv.cc
 )
 
 include_directories(${CPPUNIT_INCLUDE_DIRS})
diff --git a/gnuradio-runtime/lib/pmt/gen-serial-tags.py b/gnuradio-runtime/lib/pmt/gen-serial-tags.py
deleted file mode 100644
index 2ff2240a47..0000000000
--- a/gnuradio-runtime/lib/pmt/gen-serial-tags.py
+++ /dev/null
@@ -1,56 +0,0 @@
-"""
-//
-// Copyright 2011 Free Software Foundation, Inc.
-//
-// This file is part of GNU Radio
-//
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3, or (at your option)
-// any later version.
-//
-// GNU Radio 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 General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-//
-// THIS FILE IS MACHINE GENERATED FROM %s. DO NOT EDIT BY HAND.
-// See %s for additional commentary.
-//
-
-#ifndef INCLUDED_PMT_SERIAL_TAGS_H
-#define INCLUDED_PMT_SERIAL_TAGS_H
-
-enum pst_tags {
-%s
-};
-#endif /* INCLUDED_PMT_SERIAL_TAGS_H */
-"""
-
-from __future__ import print_function
-from __future__ import unicode_literals
-
-import sys, os, re
-
-if __name__ == '__main__':
-    if len(sys.argv) != 3:
-        print("Usage %s <input_scm_file> <output_hdr_file>"%__file__)
-        exit()
-    input_scm_file, output_hdr_file = sys.argv[1:]
-    enums = list()
-    for line in open(input_scm_file).readlines():
-        match = re.match('^\s*\(define\s+([\w|-]+)\s+#x([0-9a-fA-F]+)\)', line)
-        if not match: continue
-        name, value = match.groups()
-        name = name.upper().replace('-', '_')
-        enums.append('    %s = 0x%s'%(name, value))
-    open(output_hdr_file, 'w').write(__doc__%(
-        os.path.basename(__file__),
-        os.path.basename(input_scm_file),
-        ',\n'.join(enums),
-    ))
diff --git a/gnuradio-runtime/lib/pmt/generate_unv.py b/gnuradio-runtime/lib/pmt/generate_unv.py
deleted file mode 100644
index 45c57a3fb8..0000000000
--- a/gnuradio-runtime/lib/pmt/generate_unv.py
+++ /dev/null
@@ -1,192 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2006,2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio 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 General Public License for more details.
-#
-# 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-"""
-Generate code for uniform numeric vectors
-"""
-from __future__ import unicode_literals
-
-import re, os, os.path
-
-
-unv_types = (
-    ('u8', 'uint8_t'),
-    ('s8', 'int8_t'),
-    ('u16', 'uint16_t'),
-    ('s16', 'int16_t'),
-    ('u32', 'uint32_t'),
-    ('s32', 'int32_t'),
-    ('u64', 'uint64_t'),
-    ('s64', 'int64_t'),
-    ('f32', 'float'),
-    ('f64', 'double'),
-    ('c32', 'std::complex<float>'),
-    ('c64', 'std::complex<double>')
-    )
-
-header = """\
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2009 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 General Public License for more details.
- *
- * 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-"""
-
-guard_tail = """
-#endif
-"""
-
-includes = """
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <vector>
-#include <pmt/pmt.h>
-#include <boost/lexical_cast.hpp>
-#include "pmt_int.h"
-"""
-
-qa_includes = """
-#include <qa_pmt_unv.h>
-#include <cppunit/TestAssert.h>
-#include <pmt/pmt.h>
-#include <stdio.h>
-
-using namespace pmt;
-"""
-
-
-# set srcdir to the directory that contains Makefile.am
-try:
-    srcdir = os.environ['srcdir']
-except KeyError as e:
-    srcdir = "."
-srcdir = srcdir + '/'
-
-
-def open_src (name, mode):
-    global srcdir
-    return open(os.path.join (srcdir, name), mode)
-
-
-def guard_name(filename):
-    return 'INCLUDED_' + re.sub('\.', '_', filename.upper())
-
-def guard_head(filename):
-    guard = guard_name(filename)
-    return """
-#ifndef %s
-#define %s
-""" % (guard, guard)
-
-
-def do_substitution (d, input, out_file):
-    def repl (match_obj):
-        key = match_obj.group (1)
-        # print key
-        return d[key]
-
-    out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, input)
-    out_file.write (out)
-
-
-def generate_h():
-    template = open_src('unv_template.h.t', 'r').read()
-    output_filename = 'pmt_unv_int.h'
-    output = open(output_filename, 'w')
-    output.write(header)
-    output.write(guard_head(output_filename))
-    for tag, typ in unv_types:
-        d = { 'TAG' : tag, 'TYPE' : typ }
-        do_substitution(d, template, output)
-    output.write(guard_tail)
-
-def generate_cc():
-    template = open_src('unv_template.cc.t', 'r').read()
-    output = open('pmt_unv.cc', 'w')
-    output.write(header)
-    output.write(includes)
-    for tag, typ in unv_types:
-        d = { 'TAG' : tag, 'TYPE' : typ }
-        do_substitution(d, template, output)
-
-
-def generate_qa_h():
-    output_filename = 'qa_pmt_unv.h'
-    output = open(output_filename, 'w')
-    output.write(header)
-    output.write(guard_head(output_filename))
-
-    output.write('''
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/TestCase.h>
-
-class qa_pmt_unv : public CppUnit::TestCase {
-
-  CPPUNIT_TEST_SUITE(qa_pmt_unv);
-''')
-    for tag, typ in unv_types:
-        output.write('  CPPUNIT_TEST(test_%svector);\n' % (tag,))
-    output.write('''\
-  CPPUNIT_TEST_SUITE_END();
-
- private:
-''')
-    for tag, typ in unv_types:
-        output.write('  void test_%svector();\n' % (tag,))
-    output.write('};\n')
-    output.write(guard_tail)
-
-def generate_qa_cc():
-    template = open_src('unv_qa_template.cc.t', 'r').read()
-    output = open('qa_pmt_unv.cc', 'w')
-    output.write(header)
-    output.write(qa_includes)
-    for tag, typ in unv_types:
-        d = { 'TAG' : tag, 'TYPE' : typ }
-        do_substitution(d, template, output)
-
-
-def main():
-    generate_h()
-    generate_cc()
-    generate_qa_h()
-    generate_qa_cc()
-
-if __name__ == '__main__':
-    main()
diff --git a/gnuradio-runtime/lib/pmt/pmt-serial-tags.scm b/gnuradio-runtime/lib/pmt/pmt-serial-tags.scm
deleted file mode 100644
index 4f06bf75f8..0000000000
--- a/gnuradio-runtime/lib/pmt/pmt-serial-tags.scm
+++ /dev/null
@@ -1,77 +0,0 @@
-;;; -*-scheme-*-
-;;;
-;;; Copyright 2007 Free Software Foundation, Inc.
-;;;
-;;; This file is part of GNU Radio
-;;;
-;;; GNU Radio is free software; you can redistribute it and/or modify
-;;; it under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 3, or (define at your option)
-;;; any later version.
-;;;
-;;; GNU Radio 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 General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License along
-;;; with this program; if not, write to the Free Software Foundation, Inc.,
-;;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-;;;
-
-;;; definitions of tag values used for marshalling pmt data
-
-(define pst-true		#x00)
-(define pst-false		#x01)
-(define pst-symbol		#x02)   ; untagged-int16 n; followed by n bytes of symbol name
-(define pst-int32		#x03)
-(define pst-double		#x04)
-(define pst-complex		#x05)   ; complex<double>: real, imag
-(define pst-null		#x06)
-(define pst-pair		#x07)   ; followed by two objects
-(define pst-vector		#x08)   ; untagged-int32 n; followed by n objects
-(define pst-dict		#x09)   ; untagged-int32 n; followed by n key/value tuples
-
-(define pst-uniform-vector	#x0a)
-(define pst-uint64	#x0b)
-(define pst-tuple	#x0c)
-
-;; u8, s8, u16, s16, u32, s32, u64, s64, f32, f64, c32, c64
-;;
-;;   untagged-uint8  tag
-;;   untagged-uint8  uvi (define uniform vector info, see below)
-;;   untagged-int32  n-items
-;;   untagged-uint8  npad
-;;   npad bytes of zeros to align binary data
-;;   n-items binary numeric items
-;;
-;; uvi:
-;; +-+-+-+-+-+-+-+-+
-;; |B|   subtype   |
-;; +-+-+-+-+-+-+-+-+
-;;
-;; B == 0, numeric data is little-endian.
-;; B == 1, numeric data is big-endian.
-
-    (define uvi-endian-mask     #x80)
-    (define uvi-subtype-mask    #x7f)
-
-    (define uvi-little-endian   #x00)
-    (define uvi-big-endian      #x80)
-
-    (define uvi-u8		#x00)
-    (define uvi-s8		#x01)
-    (define uvi-u16		#x02)
-    (define uvi-s16		#x03)
-    (define uvi-u32		#x04)
-    (define uvi-s32		#x05)
-    (define uvi-u64		#x06)
-    (define uvi-s64		#x07)
-    (define uvi-f32		#x08)
-    (define uvi-f64		#x09)
-    (define uvi-c32		#x0a)
-    (define uvi-c64		#x0b)
-
-
-(define pst-comment		#x3b)	; ascii ';'
-(define pst-comment-end		#x0a)	; ascii '\n'
diff --git a/gnuradio-runtime/lib/pmt/pmt_int.h b/gnuradio-runtime/lib/pmt/pmt_int.h
index f06f507944..ead058598d 100644
--- a/gnuradio-runtime/lib/pmt/pmt_int.h
+++ b/gnuradio-runtime/lib/pmt/pmt_int.h
@@ -242,9 +242,6 @@ public:
   virtual size_t itemsize() const = 0;
   virtual const std::string string_ref(size_t k) const { return std::string("not implemented"); }
 };
-
-#include "pmt_unv_int.h"
-
 } /* namespace pmt */
 
 #endif /* INCLUDED_PMT_INT_H */
diff --git a/gnuradio-runtime/lib/pmt/pmt_unv.cc b/gnuradio-runtime/lib/pmt/pmt_unv.cc
new file mode 100644
index 0000000000..cda0c085cd
--- /dev/null
+++ b/gnuradio-runtime/lib/pmt/pmt_unv.cc
@@ -0,0 +1,1821 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// This file is machine generated using the generate_unv.py tool
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pmt_unv_int.h"
+#include "pmt_int.h"
+#include <pmt/pmt.h>
+#include <boost/lexical_cast.hpp>
+#include <vector>
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_u8vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_u8vector *
+_u8vector(pmt_t x)
+{
+  return dynamic_cast<pmt_u8vector*>(x.get());
+}
+
+
+pmt_u8vector::pmt_u8vector(size_t k, uint8_t fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_u8vector::pmt_u8vector(size_t k, const uint8_t *data)
+  : d_v(k)
+{
+  if(k)
+    memcpy( &d_v[0], data, k * sizeof(uint8_t) );
+}
+
+uint8_t
+pmt_u8vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw out_of_range("pmt_u8vector_ref", from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_u8vector::set(size_t k, uint8_t x)
+{
+  if (k >= length())
+    throw out_of_range("pmt_u8vector_set", from_long(k));
+  d_v[k] = x;
+}
+
+const uint8_t *
+pmt_u8vector::elements(size_t &len)
+{
+  len = length();
+  return len ?  &d_v[0] : nullptr;
+}
+
+uint8_t *
+pmt_u8vector::writable_elements(size_t &len)
+{
+  len = length();
+  return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_u8vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(uint8_t);
+  return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_u8vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(uint8_t);
+  return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_u8vector(pmt_t obj)
+{
+  return obj->is_u8vector();
+}
+
+pmt_t
+make_u8vector(size_t k, uint8_t fill)
+{
+  return pmt_t(new pmt_u8vector(k, fill));
+}
+
+pmt_t
+init_u8vector(size_t k, const uint8_t *data)
+{
+  return pmt_t(new pmt_u8vector(k, data));
+}
+
+pmt_t
+init_u8vector(size_t k, const std::vector< uint8_t > &data)
+{
+  if(k) {
+    return pmt_t(new pmt_u8vector(k, &data[0]));
+  }
+  return pmt_t(new pmt_u8vector(k, static_cast< uint8_t >(0))); // fills an empty vector with 0
+}
+
+uint8_t
+u8vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_u8vector())
+    throw wrong_type("pmt_u8vector_ref", vector);
+  return _u8vector(vector)->ref(k);
+}
+
+void
+u8vector_set(pmt_t vector, size_t k, uint8_t obj)
+{
+  if (!vector->is_u8vector())
+    throw wrong_type("pmt_u8vector_set", vector);
+  _u8vector(vector)->set(k, obj);
+}
+
+const uint8_t *
+u8vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_u8vector())
+    throw wrong_type("pmt_u8vector_elements", vector);
+  return _u8vector(vector)->elements(len);
+}
+
+const std::vector< uint8_t >
+u8vector_elements(pmt_t vector)
+{
+  if (!vector->is_u8vector())
+    throw wrong_type("pmt_u8vector_elements", vector);
+  size_t len;
+  const uint8_t *array = _u8vector(vector)->elements(len);
+  const std::vector< uint8_t > vec(array, array+len);
+  return vec;
+}
+
+
+uint8_t *
+u8vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_u8vector())
+    throw wrong_type("pmt_u8vector_writable_elements", vector);
+  return _u8vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_u8vector::string_ref(size_t k) const
+{
+  return boost::lexical_cast< std::string, uint8_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_s8vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_s8vector *
+_s8vector(pmt_t x)
+{
+  return dynamic_cast<pmt_s8vector*>(x.get());
+}
+
+
+pmt_s8vector::pmt_s8vector(size_t k, int8_t fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_s8vector::pmt_s8vector(size_t k, const int8_t *data)
+  : d_v(k)
+{
+  if(k)
+    memcpy( &d_v[0], data, k * sizeof(int8_t) );
+}
+
+int8_t
+pmt_s8vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw out_of_range("pmt_s8vector_ref", from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_s8vector::set(size_t k, int8_t x)
+{
+  if (k >= length())
+    throw out_of_range("pmt_s8vector_set", from_long(k));
+  d_v[k] = x;
+}
+
+const int8_t *
+pmt_s8vector::elements(size_t &len)
+{
+  len = length();
+  return len ?  &d_v[0] : nullptr;
+}
+
+int8_t *
+pmt_s8vector::writable_elements(size_t &len)
+{
+  len = length();
+  return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_s8vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(int8_t);
+  return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_s8vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(int8_t);
+  return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_s8vector(pmt_t obj)
+{
+  return obj->is_s8vector();
+}
+
+pmt_t
+make_s8vector(size_t k, int8_t fill)
+{
+  return pmt_t(new pmt_s8vector(k, fill));
+}
+
+pmt_t
+init_s8vector(size_t k, const int8_t *data)
+{
+  return pmt_t(new pmt_s8vector(k, data));
+}
+
+pmt_t
+init_s8vector(size_t k, const std::vector< int8_t > &data)
+{
+  if(k) {
+    return pmt_t(new pmt_s8vector(k, &data[0]));
+  }
+  return pmt_t(new pmt_s8vector(k, static_cast< int8_t >(0))); // fills an empty vector with 0
+}
+
+int8_t
+s8vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_s8vector())
+    throw wrong_type("pmt_s8vector_ref", vector);
+  return _s8vector(vector)->ref(k);
+}
+
+void
+s8vector_set(pmt_t vector, size_t k, int8_t obj)
+{
+  if (!vector->is_s8vector())
+    throw wrong_type("pmt_s8vector_set", vector);
+  _s8vector(vector)->set(k, obj);
+}
+
+const int8_t *
+s8vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_s8vector())
+    throw wrong_type("pmt_s8vector_elements", vector);
+  return _s8vector(vector)->elements(len);
+}
+
+const std::vector< int8_t >
+s8vector_elements(pmt_t vector)
+{
+  if (!vector->is_s8vector())
+    throw wrong_type("pmt_s8vector_elements", vector);
+  size_t len;
+  const int8_t *array = _s8vector(vector)->elements(len);
+  const std::vector< int8_t > vec(array, array+len);
+  return vec;
+}
+
+
+int8_t *
+s8vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_s8vector())
+    throw wrong_type("pmt_s8vector_writable_elements", vector);
+  return _s8vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_s8vector::string_ref(size_t k) const
+{
+  return boost::lexical_cast< std::string, int8_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_u16vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_u16vector *
+_u16vector(pmt_t x)
+{
+  return dynamic_cast<pmt_u16vector*>(x.get());
+}
+
+
+pmt_u16vector::pmt_u16vector(size_t k, uint16_t fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_u16vector::pmt_u16vector(size_t k, const uint16_t *data)
+  : d_v(k)
+{
+  if(k)
+    memcpy( &d_v[0], data, k * sizeof(uint16_t) );
+}
+
+uint16_t
+pmt_u16vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw out_of_range("pmt_u16vector_ref", from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_u16vector::set(size_t k, uint16_t x)
+{
+  if (k >= length())
+    throw out_of_range("pmt_u16vector_set", from_long(k));
+  d_v[k] = x;
+}
+
+const uint16_t *
+pmt_u16vector::elements(size_t &len)
+{
+  len = length();
+  return len ?  &d_v[0] : nullptr;
+}
+
+uint16_t *
+pmt_u16vector::writable_elements(size_t &len)
+{
+  len = length();
+  return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_u16vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(uint16_t);
+  return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_u16vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(uint16_t);
+  return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_u16vector(pmt_t obj)
+{
+  return obj->is_u16vector();
+}
+
+pmt_t
+make_u16vector(size_t k, uint16_t fill)
+{
+  return pmt_t(new pmt_u16vector(k, fill));
+}
+
+pmt_t
+init_u16vector(size_t k, const uint16_t *data)
+{
+  return pmt_t(new pmt_u16vector(k, data));
+}
+
+pmt_t
+init_u16vector(size_t k, const std::vector< uint16_t > &data)
+{
+  if(k) {
+    return pmt_t(new pmt_u16vector(k, &data[0]));
+  }
+  return pmt_t(new pmt_u16vector(k, static_cast< uint16_t >(0))); // fills an empty vector with 0
+}
+
+uint16_t
+u16vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_u16vector())
+    throw wrong_type("pmt_u16vector_ref", vector);
+  return _u16vector(vector)->ref(k);
+}
+
+void
+u16vector_set(pmt_t vector, size_t k, uint16_t obj)
+{
+  if (!vector->is_u16vector())
+    throw wrong_type("pmt_u16vector_set", vector);
+  _u16vector(vector)->set(k, obj);
+}
+
+const uint16_t *
+u16vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_u16vector())
+    throw wrong_type("pmt_u16vector_elements", vector);
+  return _u16vector(vector)->elements(len);
+}
+
+const std::vector< uint16_t >
+u16vector_elements(pmt_t vector)
+{
+  if (!vector->is_u16vector())
+    throw wrong_type("pmt_u16vector_elements", vector);
+  size_t len;
+  const uint16_t *array = _u16vector(vector)->elements(len);
+  const std::vector< uint16_t > vec(array, array+len);
+  return vec;
+}
+
+
+uint16_t *
+u16vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_u16vector())
+    throw wrong_type("pmt_u16vector_writable_elements", vector);
+  return _u16vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_u16vector::string_ref(size_t k) const
+{
+  return boost::lexical_cast< std::string, uint16_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_s16vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_s16vector *
+_s16vector(pmt_t x)
+{
+  return dynamic_cast<pmt_s16vector*>(x.get());
+}
+
+
+pmt_s16vector::pmt_s16vector(size_t k, int16_t fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_s16vector::pmt_s16vector(size_t k, const int16_t *data)
+  : d_v(k)
+{
+  if(k)
+    memcpy( &d_v[0], data, k * sizeof(int16_t) );
+}
+
+int16_t
+pmt_s16vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw out_of_range("pmt_s16vector_ref", from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_s16vector::set(size_t k, int16_t x)
+{
+  if (k >= length())
+    throw out_of_range("pmt_s16vector_set", from_long(k));
+  d_v[k] = x;
+}
+
+const int16_t *
+pmt_s16vector::elements(size_t &len)
+{
+  len = length();
+  return len ?  &d_v[0] : nullptr;
+}
+
+int16_t *
+pmt_s16vector::writable_elements(size_t &len)
+{
+  len = length();
+  return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_s16vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(int16_t);
+  return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_s16vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(int16_t);
+  return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_s16vector(pmt_t obj)
+{
+  return obj->is_s16vector();
+}
+
+pmt_t
+make_s16vector(size_t k, int16_t fill)
+{
+  return pmt_t(new pmt_s16vector(k, fill));
+}
+
+pmt_t
+init_s16vector(size_t k, const int16_t *data)
+{
+  return pmt_t(new pmt_s16vector(k, data));
+}
+
+pmt_t
+init_s16vector(size_t k, const std::vector< int16_t > &data)
+{
+  if(k) {
+    return pmt_t(new pmt_s16vector(k, &data[0]));
+  }
+  return pmt_t(new pmt_s16vector(k, static_cast< int16_t >(0))); // fills an empty vector with 0
+}
+
+int16_t
+s16vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_s16vector())
+    throw wrong_type("pmt_s16vector_ref", vector);
+  return _s16vector(vector)->ref(k);
+}
+
+void
+s16vector_set(pmt_t vector, size_t k, int16_t obj)
+{
+  if (!vector->is_s16vector())
+    throw wrong_type("pmt_s16vector_set", vector);
+  _s16vector(vector)->set(k, obj);
+}
+
+const int16_t *
+s16vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_s16vector())
+    throw wrong_type("pmt_s16vector_elements", vector);
+  return _s16vector(vector)->elements(len);
+}
+
+const std::vector< int16_t >
+s16vector_elements(pmt_t vector)
+{
+  if (!vector->is_s16vector())
+    throw wrong_type("pmt_s16vector_elements", vector);
+  size_t len;
+  const int16_t *array = _s16vector(vector)->elements(len);
+  const std::vector< int16_t > vec(array, array+len);
+  return vec;
+}
+
+
+int16_t *
+s16vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_s16vector())
+    throw wrong_type("pmt_s16vector_writable_elements", vector);
+  return _s16vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_s16vector::string_ref(size_t k) const
+{
+  return boost::lexical_cast< std::string, int16_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_u32vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_u32vector *
+_u32vector(pmt_t x)
+{
+  return dynamic_cast<pmt_u32vector*>(x.get());
+}
+
+
+pmt_u32vector::pmt_u32vector(size_t k, uint32_t fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_u32vector::pmt_u32vector(size_t k, const uint32_t *data)
+  : d_v(k)
+{
+  if(k)
+    memcpy( &d_v[0], data, k * sizeof(uint32_t) );
+}
+
+uint32_t
+pmt_u32vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw out_of_range("pmt_u32vector_ref", from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_u32vector::set(size_t k, uint32_t x)
+{
+  if (k >= length())
+    throw out_of_range("pmt_u32vector_set", from_long(k));
+  d_v[k] = x;
+}
+
+const uint32_t *
+pmt_u32vector::elements(size_t &len)
+{
+  len = length();
+  return len ?  &d_v[0] : nullptr;
+}
+
+uint32_t *
+pmt_u32vector::writable_elements(size_t &len)
+{
+  len = length();
+  return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_u32vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(uint32_t);
+  return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_u32vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(uint32_t);
+  return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_u32vector(pmt_t obj)
+{
+  return obj->is_u32vector();
+}
+
+pmt_t
+make_u32vector(size_t k, uint32_t fill)
+{
+  return pmt_t(new pmt_u32vector(k, fill));
+}
+
+pmt_t
+init_u32vector(size_t k, const uint32_t *data)
+{
+  return pmt_t(new pmt_u32vector(k, data));
+}
+
+pmt_t
+init_u32vector(size_t k, const std::vector< uint32_t > &data)
+{
+  if(k) {
+    return pmt_t(new pmt_u32vector(k, &data[0]));
+  }
+  return pmt_t(new pmt_u32vector(k, static_cast< uint32_t >(0))); // fills an empty vector with 0
+}
+
+uint32_t
+u32vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_u32vector())
+    throw wrong_type("pmt_u32vector_ref", vector);
+  return _u32vector(vector)->ref(k);
+}
+
+void
+u32vector_set(pmt_t vector, size_t k, uint32_t obj)
+{
+  if (!vector->is_u32vector())
+    throw wrong_type("pmt_u32vector_set", vector);
+  _u32vector(vector)->set(k, obj);
+}
+
+const uint32_t *
+u32vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_u32vector())
+    throw wrong_type("pmt_u32vector_elements", vector);
+  return _u32vector(vector)->elements(len);
+}
+
+const std::vector< uint32_t >
+u32vector_elements(pmt_t vector)
+{
+  if (!vector->is_u32vector())
+    throw wrong_type("pmt_u32vector_elements", vector);
+  size_t len;
+  const uint32_t *array = _u32vector(vector)->elements(len);
+  const std::vector< uint32_t > vec(array, array+len);
+  return vec;
+}
+
+
+uint32_t *
+u32vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_u32vector())
+    throw wrong_type("pmt_u32vector_writable_elements", vector);
+  return _u32vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_u32vector::string_ref(size_t k) const
+{
+  return boost::lexical_cast< std::string, uint32_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_s32vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_s32vector *
+_s32vector(pmt_t x)
+{
+  return dynamic_cast<pmt_s32vector*>(x.get());
+}
+
+
+pmt_s32vector::pmt_s32vector(size_t k, int32_t fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_s32vector::pmt_s32vector(size_t k, const int32_t *data)
+  : d_v(k)
+{
+  if(k)
+    memcpy( &d_v[0], data, k * sizeof(int32_t) );
+}
+
+int32_t
+pmt_s32vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw out_of_range("pmt_s32vector_ref", from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_s32vector::set(size_t k, int32_t x)
+{
+  if (k >= length())
+    throw out_of_range("pmt_s32vector_set", from_long(k));
+  d_v[k] = x;
+}
+
+const int32_t *
+pmt_s32vector::elements(size_t &len)
+{
+  len = length();
+  return len ?  &d_v[0] : nullptr;
+}
+
+int32_t *
+pmt_s32vector::writable_elements(size_t &len)
+{
+  len = length();
+  return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_s32vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(int32_t);
+  return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_s32vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(int32_t);
+  return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_s32vector(pmt_t obj)
+{
+  return obj->is_s32vector();
+}
+
+pmt_t
+make_s32vector(size_t k, int32_t fill)
+{
+  return pmt_t(new pmt_s32vector(k, fill));
+}
+
+pmt_t
+init_s32vector(size_t k, const int32_t *data)
+{
+  return pmt_t(new pmt_s32vector(k, data));
+}
+
+pmt_t
+init_s32vector(size_t k, const std::vector< int32_t > &data)
+{
+  if(k) {
+    return pmt_t(new pmt_s32vector(k, &data[0]));
+  }
+  return pmt_t(new pmt_s32vector(k, static_cast< int32_t >(0))); // fills an empty vector with 0
+}
+
+int32_t
+s32vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_s32vector())
+    throw wrong_type("pmt_s32vector_ref", vector);
+  return _s32vector(vector)->ref(k);
+}
+
+void
+s32vector_set(pmt_t vector, size_t k, int32_t obj)
+{
+  if (!vector->is_s32vector())
+    throw wrong_type("pmt_s32vector_set", vector);
+  _s32vector(vector)->set(k, obj);
+}
+
+const int32_t *
+s32vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_s32vector())
+    throw wrong_type("pmt_s32vector_elements", vector);
+  return _s32vector(vector)->elements(len);
+}
+
+const std::vector< int32_t >
+s32vector_elements(pmt_t vector)
+{
+  if (!vector->is_s32vector())
+    throw wrong_type("pmt_s32vector_elements", vector);
+  size_t len;
+  const int32_t *array = _s32vector(vector)->elements(len);
+  const std::vector< int32_t > vec(array, array+len);
+  return vec;
+}
+
+
+int32_t *
+s32vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_s32vector())
+    throw wrong_type("pmt_s32vector_writable_elements", vector);
+  return _s32vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_s32vector::string_ref(size_t k) const
+{
+  return boost::lexical_cast< std::string, int32_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_u64vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_u64vector *
+_u64vector(pmt_t x)
+{
+  return dynamic_cast<pmt_u64vector*>(x.get());
+}
+
+
+pmt_u64vector::pmt_u64vector(size_t k, uint64_t fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_u64vector::pmt_u64vector(size_t k, const uint64_t *data)
+  : d_v(k)
+{
+  if(k)
+    memcpy( &d_v[0], data, k * sizeof(uint64_t) );
+}
+
+uint64_t
+pmt_u64vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw out_of_range("pmt_u64vector_ref", from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_u64vector::set(size_t k, uint64_t x)
+{
+  if (k >= length())
+    throw out_of_range("pmt_u64vector_set", from_long(k));
+  d_v[k] = x;
+}
+
+const uint64_t *
+pmt_u64vector::elements(size_t &len)
+{
+  len = length();
+  return len ?  &d_v[0] : nullptr;
+}
+
+uint64_t *
+pmt_u64vector::writable_elements(size_t &len)
+{
+  len = length();
+  return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_u64vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(uint64_t);
+  return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_u64vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(uint64_t);
+  return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_u64vector(pmt_t obj)
+{
+  return obj->is_u64vector();
+}
+
+pmt_t
+make_u64vector(size_t k, uint64_t fill)
+{
+  return pmt_t(new pmt_u64vector(k, fill));
+}
+
+pmt_t
+init_u64vector(size_t k, const uint64_t *data)
+{
+  return pmt_t(new pmt_u64vector(k, data));
+}
+
+pmt_t
+init_u64vector(size_t k, const std::vector< uint64_t > &data)
+{
+  if(k) {
+    return pmt_t(new pmt_u64vector(k, &data[0]));
+  }
+  return pmt_t(new pmt_u64vector(k, static_cast< uint64_t >(0))); // fills an empty vector with 0
+}
+
+uint64_t
+u64vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_u64vector())
+    throw wrong_type("pmt_u64vector_ref", vector);
+  return _u64vector(vector)->ref(k);
+}
+
+void
+u64vector_set(pmt_t vector, size_t k, uint64_t obj)
+{
+  if (!vector->is_u64vector())
+    throw wrong_type("pmt_u64vector_set", vector);
+  _u64vector(vector)->set(k, obj);
+}
+
+const uint64_t *
+u64vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_u64vector())
+    throw wrong_type("pmt_u64vector_elements", vector);
+  return _u64vector(vector)->elements(len);
+}
+
+const std::vector< uint64_t >
+u64vector_elements(pmt_t vector)
+{
+  if (!vector->is_u64vector())
+    throw wrong_type("pmt_u64vector_elements", vector);
+  size_t len;
+  const uint64_t *array = _u64vector(vector)->elements(len);
+  const std::vector< uint64_t > vec(array, array+len);
+  return vec;
+}
+
+
+uint64_t *
+u64vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_u64vector())
+    throw wrong_type("pmt_u64vector_writable_elements", vector);
+  return _u64vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_u64vector::string_ref(size_t k) const
+{
+  return boost::lexical_cast< std::string, uint64_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_s64vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_s64vector *
+_s64vector(pmt_t x)
+{
+  return dynamic_cast<pmt_s64vector*>(x.get());
+}
+
+
+pmt_s64vector::pmt_s64vector(size_t k, int64_t fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_s64vector::pmt_s64vector(size_t k, const int64_t *data)
+  : d_v(k)
+{
+  if(k)
+    memcpy( &d_v[0], data, k * sizeof(int64_t) );
+}
+
+int64_t
+pmt_s64vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw out_of_range("pmt_s64vector_ref", from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_s64vector::set(size_t k, int64_t x)
+{
+  if (k >= length())
+    throw out_of_range("pmt_s64vector_set", from_long(k));
+  d_v[k] = x;
+}
+
+const int64_t *
+pmt_s64vector::elements(size_t &len)
+{
+  len = length();
+  return len ?  &d_v[0] : nullptr;
+}
+
+int64_t *
+pmt_s64vector::writable_elements(size_t &len)
+{
+  len = length();
+  return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_s64vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(int64_t);
+  return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_s64vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(int64_t);
+  return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_s64vector(pmt_t obj)
+{
+  return obj->is_s64vector();
+}
+
+pmt_t
+make_s64vector(size_t k, int64_t fill)
+{
+  return pmt_t(new pmt_s64vector(k, fill));
+}
+
+pmt_t
+init_s64vector(size_t k, const int64_t *data)
+{
+  return pmt_t(new pmt_s64vector(k, data));
+}
+
+pmt_t
+init_s64vector(size_t k, const std::vector< int64_t > &data)
+{
+  if(k) {
+    return pmt_t(new pmt_s64vector(k, &data[0]));
+  }
+  return pmt_t(new pmt_s64vector(k, static_cast< int64_t >(0))); // fills an empty vector with 0
+}
+
+int64_t
+s64vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_s64vector())
+    throw wrong_type("pmt_s64vector_ref", vector);
+  return _s64vector(vector)->ref(k);
+}
+
+void
+s64vector_set(pmt_t vector, size_t k, int64_t obj)
+{
+  if (!vector->is_s64vector())
+    throw wrong_type("pmt_s64vector_set", vector);
+  _s64vector(vector)->set(k, obj);
+}
+
+const int64_t *
+s64vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_s64vector())
+    throw wrong_type("pmt_s64vector_elements", vector);
+  return _s64vector(vector)->elements(len);
+}
+
+const std::vector< int64_t >
+s64vector_elements(pmt_t vector)
+{
+  if (!vector->is_s64vector())
+    throw wrong_type("pmt_s64vector_elements", vector);
+  size_t len;
+  const int64_t *array = _s64vector(vector)->elements(len);
+  const std::vector< int64_t > vec(array, array+len);
+  return vec;
+}
+
+
+int64_t *
+s64vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_s64vector())
+    throw wrong_type("pmt_s64vector_writable_elements", vector);
+  return _s64vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_s64vector::string_ref(size_t k) const
+{
+  return boost::lexical_cast< std::string, int64_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_f32vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_f32vector *
+_f32vector(pmt_t x)
+{
+  return dynamic_cast<pmt_f32vector*>(x.get());
+}
+
+
+pmt_f32vector::pmt_f32vector(size_t k, float fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_f32vector::pmt_f32vector(size_t k, const float *data)
+  : d_v(k)
+{
+  if(k)
+    memcpy( &d_v[0], data, k * sizeof(float) );
+}
+
+float
+pmt_f32vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw out_of_range("pmt_f32vector_ref", from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_f32vector::set(size_t k, float x)
+{
+  if (k >= length())
+    throw out_of_range("pmt_f32vector_set", from_long(k));
+  d_v[k] = x;
+}
+
+const float *
+pmt_f32vector::elements(size_t &len)
+{
+  len = length();
+  return len ?  &d_v[0] : nullptr;
+}
+
+float *
+pmt_f32vector::writable_elements(size_t &len)
+{
+  len = length();
+  return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_f32vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(float);
+  return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_f32vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(float);
+  return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_f32vector(pmt_t obj)
+{
+  return obj->is_f32vector();
+}
+
+pmt_t
+make_f32vector(size_t k, float fill)
+{
+  return pmt_t(new pmt_f32vector(k, fill));
+}
+
+pmt_t
+init_f32vector(size_t k, const float *data)
+{
+  return pmt_t(new pmt_f32vector(k, data));
+}
+
+pmt_t
+init_f32vector(size_t k, const std::vector< float > &data)
+{
+  if(k) {
+    return pmt_t(new pmt_f32vector(k, &data[0]));
+  }
+  return pmt_t(new pmt_f32vector(k, static_cast< float >(0))); // fills an empty vector with 0
+}
+
+float
+f32vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_f32vector())
+    throw wrong_type("pmt_f32vector_ref", vector);
+  return _f32vector(vector)->ref(k);
+}
+
+void
+f32vector_set(pmt_t vector, size_t k, float obj)
+{
+  if (!vector->is_f32vector())
+    throw wrong_type("pmt_f32vector_set", vector);
+  _f32vector(vector)->set(k, obj);
+}
+
+const float *
+f32vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_f32vector())
+    throw wrong_type("pmt_f32vector_elements", vector);
+  return _f32vector(vector)->elements(len);
+}
+
+const std::vector< float >
+f32vector_elements(pmt_t vector)
+{
+  if (!vector->is_f32vector())
+    throw wrong_type("pmt_f32vector_elements", vector);
+  size_t len;
+  const float *array = _f32vector(vector)->elements(len);
+  const std::vector< float > vec(array, array+len);
+  return vec;
+}
+
+
+float *
+f32vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_f32vector())
+    throw wrong_type("pmt_f32vector_writable_elements", vector);
+  return _f32vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_f32vector::string_ref(size_t k) const
+{
+  return boost::lexical_cast< std::string, float > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_f64vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_f64vector *
+_f64vector(pmt_t x)
+{
+  return dynamic_cast<pmt_f64vector*>(x.get());
+}
+
+
+pmt_f64vector::pmt_f64vector(size_t k, double fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_f64vector::pmt_f64vector(size_t k, const double *data)
+  : d_v(k)
+{
+  if(k)
+    memcpy( &d_v[0], data, k * sizeof(double) );
+}
+
+double
+pmt_f64vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw out_of_range("pmt_f64vector_ref", from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_f64vector::set(size_t k, double x)
+{
+  if (k >= length())
+    throw out_of_range("pmt_f64vector_set", from_long(k));
+  d_v[k] = x;
+}
+
+const double *
+pmt_f64vector::elements(size_t &len)
+{
+  len = length();
+  return len ?  &d_v[0] : nullptr;
+}
+
+double *
+pmt_f64vector::writable_elements(size_t &len)
+{
+  len = length();
+  return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_f64vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(double);
+  return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_f64vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(double);
+  return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_f64vector(pmt_t obj)
+{
+  return obj->is_f64vector();
+}
+
+pmt_t
+make_f64vector(size_t k, double fill)
+{
+  return pmt_t(new pmt_f64vector(k, fill));
+}
+
+pmt_t
+init_f64vector(size_t k, const double *data)
+{
+  return pmt_t(new pmt_f64vector(k, data));
+}
+
+pmt_t
+init_f64vector(size_t k, const std::vector< double > &data)
+{
+  if(k) {
+    return pmt_t(new pmt_f64vector(k, &data[0]));
+  }
+  return pmt_t(new pmt_f64vector(k, static_cast< double >(0))); // fills an empty vector with 0
+}
+
+double
+f64vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_f64vector())
+    throw wrong_type("pmt_f64vector_ref", vector);
+  return _f64vector(vector)->ref(k);
+}
+
+void
+f64vector_set(pmt_t vector, size_t k, double obj)
+{
+  if (!vector->is_f64vector())
+    throw wrong_type("pmt_f64vector_set", vector);
+  _f64vector(vector)->set(k, obj);
+}
+
+const double *
+f64vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_f64vector())
+    throw wrong_type("pmt_f64vector_elements", vector);
+  return _f64vector(vector)->elements(len);
+}
+
+const std::vector< double >
+f64vector_elements(pmt_t vector)
+{
+  if (!vector->is_f64vector())
+    throw wrong_type("pmt_f64vector_elements", vector);
+  size_t len;
+  const double *array = _f64vector(vector)->elements(len);
+  const std::vector< double > vec(array, array+len);
+  return vec;
+}
+
+
+double *
+f64vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_f64vector())
+    throw wrong_type("pmt_f64vector_writable_elements", vector);
+  return _f64vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_f64vector::string_ref(size_t k) const
+{
+  return boost::lexical_cast< std::string, double > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_c32vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_c32vector *
+_c32vector(pmt_t x)
+{
+  return dynamic_cast<pmt_c32vector*>(x.get());
+}
+
+
+pmt_c32vector::pmt_c32vector(size_t k, std::complex<float> fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_c32vector::pmt_c32vector(size_t k, const std::complex<float> *data)
+  : d_v(k)
+{
+  if(k)
+    memcpy( &d_v[0], data, k * sizeof(std::complex<float>) );
+}
+
+std::complex<float>
+pmt_c32vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw out_of_range("pmt_c32vector_ref", from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_c32vector::set(size_t k, std::complex<float> x)
+{
+  if (k >= length())
+    throw out_of_range("pmt_c32vector_set", from_long(k));
+  d_v[k] = x;
+}
+
+const std::complex<float> *
+pmt_c32vector::elements(size_t &len)
+{
+  len = length();
+  return len ?  &d_v[0] : nullptr;
+}
+
+std::complex<float> *
+pmt_c32vector::writable_elements(size_t &len)
+{
+  len = length();
+  return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_c32vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(std::complex<float>);
+  return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_c32vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(std::complex<float>);
+  return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_c32vector(pmt_t obj)
+{
+  return obj->is_c32vector();
+}
+
+pmt_t
+make_c32vector(size_t k, std::complex<float> fill)
+{
+  return pmt_t(new pmt_c32vector(k, fill));
+}
+
+pmt_t
+init_c32vector(size_t k, const std::complex<float> *data)
+{
+  return pmt_t(new pmt_c32vector(k, data));
+}
+
+pmt_t
+init_c32vector(size_t k, const std::vector< std::complex<float> > &data)
+{
+  if(k) {
+    return pmt_t(new pmt_c32vector(k, &data[0]));
+  }
+  return pmt_t(new pmt_c32vector(k, static_cast< std::complex<float> >(0))); // fills an empty vector with 0
+}
+
+std::complex<float>
+c32vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_c32vector())
+    throw wrong_type("pmt_c32vector_ref", vector);
+  return _c32vector(vector)->ref(k);
+}
+
+void
+c32vector_set(pmt_t vector, size_t k, std::complex<float> obj)
+{
+  if (!vector->is_c32vector())
+    throw wrong_type("pmt_c32vector_set", vector);
+  _c32vector(vector)->set(k, obj);
+}
+
+const std::complex<float> *
+c32vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_c32vector())
+    throw wrong_type("pmt_c32vector_elements", vector);
+  return _c32vector(vector)->elements(len);
+}
+
+const std::vector< std::complex<float> >
+c32vector_elements(pmt_t vector)
+{
+  if (!vector->is_c32vector())
+    throw wrong_type("pmt_c32vector_elements", vector);
+  size_t len;
+  const std::complex<float> *array = _c32vector(vector)->elements(len);
+  const std::vector< std::complex<float> > vec(array, array+len);
+  return vec;
+}
+
+
+std::complex<float> *
+c32vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_c32vector())
+    throw wrong_type("pmt_c32vector_writable_elements", vector);
+  return _c32vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_c32vector::string_ref(size_t k) const
+{
+  return boost::lexical_cast< std::string, std::complex<float> > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_c64vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_c64vector *
+_c64vector(pmt_t x)
+{
+  return dynamic_cast<pmt_c64vector*>(x.get());
+}
+
+
+pmt_c64vector::pmt_c64vector(size_t k, std::complex<double> fill)
+  : d_v(k)
+{
+  for (size_t i = 0; i < k; i++)
+    d_v[i] = fill;
+}
+
+pmt_c64vector::pmt_c64vector(size_t k, const std::complex<double> *data)
+  : d_v(k)
+{
+  if(k)
+    memcpy( &d_v[0], data, k * sizeof(std::complex<double>) );
+}
+
+std::complex<double>
+pmt_c64vector::ref(size_t k) const
+{
+  if (k >= length())
+    throw out_of_range("pmt_c64vector_ref", from_long(k));
+  return d_v[k];
+}
+
+void
+pmt_c64vector::set(size_t k, std::complex<double> x)
+{
+  if (k >= length())
+    throw out_of_range("pmt_c64vector_set", from_long(k));
+  d_v[k] = x;
+}
+
+const std::complex<double> *
+pmt_c64vector::elements(size_t &len)
+{
+  len = length();
+  return len ?  &d_v[0] : nullptr;
+}
+
+std::complex<double> *
+pmt_c64vector::writable_elements(size_t &len)
+{
+  len = length();
+  return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_c64vector::uniform_elements(size_t &len)
+{
+  len = length() * sizeof(std::complex<double>);
+  return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_c64vector::uniform_writable_elements(size_t &len)
+{
+  len = length() * sizeof(std::complex<double>);
+  return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_c64vector(pmt_t obj)
+{
+  return obj->is_c64vector();
+}
+
+pmt_t
+make_c64vector(size_t k, std::complex<double> fill)
+{
+  return pmt_t(new pmt_c64vector(k, fill));
+}
+
+pmt_t
+init_c64vector(size_t k, const std::complex<double> *data)
+{
+  return pmt_t(new pmt_c64vector(k, data));
+}
+
+pmt_t
+init_c64vector(size_t k, const std::vector< std::complex<double> > &data)
+{
+  if(k) {
+    return pmt_t(new pmt_c64vector(k, &data[0]));
+  }
+  return pmt_t(new pmt_c64vector(k, static_cast< std::complex<double> >(0))); // fills an empty vector with 0
+}
+
+std::complex<double>
+c64vector_ref(pmt_t vector, size_t k)
+{
+  if (!vector->is_c64vector())
+    throw wrong_type("pmt_c64vector_ref", vector);
+  return _c64vector(vector)->ref(k);
+}
+
+void
+c64vector_set(pmt_t vector, size_t k, std::complex<double> obj)
+{
+  if (!vector->is_c64vector())
+    throw wrong_type("pmt_c64vector_set", vector);
+  _c64vector(vector)->set(k, obj);
+}
+
+const std::complex<double> *
+c64vector_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_c64vector())
+    throw wrong_type("pmt_c64vector_elements", vector);
+  return _c64vector(vector)->elements(len);
+}
+
+const std::vector< std::complex<double> >
+c64vector_elements(pmt_t vector)
+{
+  if (!vector->is_c64vector())
+    throw wrong_type("pmt_c64vector_elements", vector);
+  size_t len;
+  const std::complex<double> *array = _c64vector(vector)->elements(len);
+  const std::vector< std::complex<double> > vec(array, array+len);
+  return vec;
+}
+
+
+std::complex<double> *
+c64vector_writable_elements(pmt_t vector, size_t &len)
+{
+  if (!vector->is_c64vector())
+    throw wrong_type("pmt_c64vector_writable_elements", vector);
+  return _c64vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_c64vector::string_ref(size_t k) const
+{
+  return boost::lexical_cast< std::string, std::complex<double> > (ref(k));
+}
+
+} /* namespace pmt */
diff --git a/gnuradio-runtime/lib/pmt/pmt_unv_int.h b/gnuradio-runtime/lib/pmt/pmt_unv_int.h
new file mode 100644
index 0000000000..4b4364b411
--- /dev/null
+++ b/gnuradio-runtime/lib/pmt/pmt_unv_int.h
@@ -0,0 +1,331 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_PMT_UNV_INT_H
+#define INCLUDED_PMT_UNV_INT_H
+
+#include "pmt_int.h"
+
+#include <vector>
+#include <cstdint>
+
+namespace pmt{
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_u8vector
+////////////////////////////////////////////////////////////////////////////
+class PMT_API pmt_u8vector : public pmt_uniform_vector
+{
+  std::vector< uint8_t >	d_v;
+
+public:
+  pmt_u8vector(size_t k, uint8_t fill);
+  pmt_u8vector(size_t k, const uint8_t *data);
+  // ~pmt_u8vector();
+
+  bool is_u8vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  size_t itemsize() const { return sizeof(uint8_t); }
+  uint8_t ref(size_t k) const;
+  void set(size_t k, uint8_t x);
+  const uint8_t *elements(size_t &len);
+  uint8_t *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+  virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_s8vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_s8vector : public pmt_uniform_vector
+{
+  std::vector< int8_t >	d_v;
+
+public:
+  pmt_s8vector(size_t k, int8_t fill);
+  pmt_s8vector(size_t k, const int8_t *data);
+  // ~pmt_s8vector();
+
+  bool is_s8vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  size_t itemsize() const { return sizeof(int8_t); }
+  int8_t ref(size_t k) const;
+  void set(size_t k, int8_t x);
+  const int8_t *elements(size_t &len);
+  int8_t *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+  virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_u16vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_u16vector : public pmt_uniform_vector
+{
+  std::vector< uint16_t >	d_v;
+
+public:
+  pmt_u16vector(size_t k, uint16_t fill);
+  pmt_u16vector(size_t k, const uint16_t *data);
+  // ~pmt_u16vector();
+
+  bool is_u16vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  size_t itemsize() const { return sizeof(uint16_t); }
+  uint16_t ref(size_t k) const;
+  void set(size_t k, uint16_t x);
+  const uint16_t *elements(size_t &len);
+  uint16_t *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+  virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_s16vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_s16vector : public pmt_uniform_vector
+{
+  std::vector< int16_t >	d_v;
+
+public:
+  pmt_s16vector(size_t k, int16_t fill);
+  pmt_s16vector(size_t k, const int16_t *data);
+  // ~pmt_s16vector();
+
+  bool is_s16vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  size_t itemsize() const { return sizeof(int16_t); }
+  int16_t ref(size_t k) const;
+  void set(size_t k, int16_t x);
+  const int16_t *elements(size_t &len);
+  int16_t *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+  virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_u32vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_u32vector : public pmt_uniform_vector
+{
+  std::vector< uint32_t >	d_v;
+
+public:
+  pmt_u32vector(size_t k, uint32_t fill);
+  pmt_u32vector(size_t k, const uint32_t *data);
+  // ~pmt_u32vector();
+
+  bool is_u32vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  size_t itemsize() const { return sizeof(uint32_t); }
+  uint32_t ref(size_t k) const;
+  void set(size_t k, uint32_t x);
+  const uint32_t *elements(size_t &len);
+  uint32_t *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+  virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_s32vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_s32vector : public pmt_uniform_vector
+{
+  std::vector< int32_t >	d_v;
+
+public:
+  pmt_s32vector(size_t k, int32_t fill);
+  pmt_s32vector(size_t k, const int32_t *data);
+  // ~pmt_s32vector();
+
+  bool is_s32vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  size_t itemsize() const { return sizeof(int32_t); }
+  int32_t ref(size_t k) const;
+  void set(size_t k, int32_t x);
+  const int32_t *elements(size_t &len);
+  int32_t *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+  virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_u64vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_u64vector : public pmt_uniform_vector
+{
+  std::vector< uint64_t >	d_v;
+
+public:
+  pmt_u64vector(size_t k, uint64_t fill);
+  pmt_u64vector(size_t k, const uint64_t *data);
+  // ~pmt_u64vector();
+
+  bool is_u64vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  size_t itemsize() const { return sizeof(uint64_t); }
+  uint64_t ref(size_t k) const;
+  void set(size_t k, uint64_t x);
+  const uint64_t *elements(size_t &len);
+  uint64_t *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+  virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_s64vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_s64vector : public pmt_uniform_vector
+{
+  std::vector< int64_t >	d_v;
+
+public:
+  pmt_s64vector(size_t k, int64_t fill);
+  pmt_s64vector(size_t k, const int64_t *data);
+  // ~pmt_s64vector();
+
+  bool is_s64vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  size_t itemsize() const { return sizeof(int64_t); }
+  int64_t ref(size_t k) const;
+  void set(size_t k, int64_t x);
+  const int64_t *elements(size_t &len);
+  int64_t *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+  virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_f32vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_f32vector : public pmt_uniform_vector
+{
+  std::vector< float >	d_v;
+
+public:
+  pmt_f32vector(size_t k, float fill);
+  pmt_f32vector(size_t k, const float *data);
+  // ~pmt_f32vector();
+
+  bool is_f32vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  size_t itemsize() const { return sizeof(float); }
+  float ref(size_t k) const;
+  void set(size_t k, float x);
+  const float *elements(size_t &len);
+  float *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+  virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_f64vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_f64vector : public pmt_uniform_vector
+{
+  std::vector< double >	d_v;
+
+public:
+  pmt_f64vector(size_t k, double fill);
+  pmt_f64vector(size_t k, const double *data);
+  // ~pmt_f64vector();
+
+  bool is_f64vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  size_t itemsize() const { return sizeof(double); }
+  double ref(size_t k) const;
+  void set(size_t k, double x);
+  const double *elements(size_t &len);
+  double *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+  virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_c32vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_c32vector : public pmt_uniform_vector
+{
+  std::vector< std::complex<float> >	d_v;
+
+public:
+  pmt_c32vector(size_t k, std::complex<float> fill);
+  pmt_c32vector(size_t k, const std::complex<float> *data);
+  // ~pmt_c32vector();
+
+  bool is_c32vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  size_t itemsize() const { return sizeof(std::complex<float>); }
+  std::complex<float> ref(size_t k) const;
+  void set(size_t k, std::complex<float> x);
+  const std::complex<float> *elements(size_t &len);
+  std::complex<float> *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+  virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//                           pmt_c64vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_c64vector : public pmt_uniform_vector
+{
+  std::vector< std::complex<double> >	d_v;
+
+public:
+  pmt_c64vector(size_t k, std::complex<double> fill);
+  pmt_c64vector(size_t k, const std::complex<double> *data);
+  // ~pmt_c64vector();
+
+  bool is_c64vector() const { return true; }
+  size_t length() const { return d_v.size(); }
+  size_t itemsize() const { return sizeof(std::complex<double>); }
+  std::complex<double> ref(size_t k) const;
+  void set(size_t k, std::complex<double> x);
+  const std::complex<double> *elements(size_t &len);
+  std::complex<double> *writable_elements(size_t &len);
+  const void *uniform_elements(size_t &len);
+  void *uniform_writable_elements(size_t &len);
+  virtual const std::string string_ref(size_t k) const;
+};
+} /* namespace pmt */
+#endif
diff --git a/gnuradio-runtime/lib/pmt/qa_pmt_unv.cc b/gnuradio-runtime/lib/pmt/qa_pmt_unv.cc
new file mode 100644
index 0000000000..9751f5e610
--- /dev/null
+++ b/gnuradio-runtime/lib/pmt/qa_pmt_unv.cc
@@ -0,0 +1,448 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qa_pmt_unv.h>
+#include <cppunit/TestAssert.h>
+#include <pmt/pmt.h>
+#include <stdio.h>
+
+using namespace pmt;
+void
+qa_pmt_unv::test_u8vector()
+{
+  static const size_t N = 3;
+  pmt::pmt_t v1 = pmt::make_u8vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
+  uint8_t s0 = uint8_t(10);
+  uint8_t s1 = uint8_t(20);
+  uint8_t s2 = uint8_t(30);
+
+  pmt::u8vector_set(v1, 0, s0);
+  pmt::u8vector_set(v1, 1, s1);
+  pmt::u8vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt::u8vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt::u8vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt::u8vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt::u8vector_ref(v1, N), pmt::out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt::u8vector_set(v1, N, uint8_t(0)), pmt::out_of_range);
+
+  size_t	len;
+  const uint8_t *rd = pmt::u8vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  uint8_t *wr = pmt::u8vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = uint8_t(0);
+  CPPUNIT_ASSERT_EQUAL(uint8_t(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
+void
+qa_pmt_unv::test_s8vector()
+{
+  static const size_t N = 3;
+  pmt::pmt_t v1 = pmt::make_s8vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
+  int8_t s0 = int8_t(10);
+  int8_t s1 = int8_t(20);
+  int8_t s2 = int8_t(30);
+
+  pmt::s8vector_set(v1, 0, s0);
+  pmt::s8vector_set(v1, 1, s1);
+  pmt::s8vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt::s8vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt::s8vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt::s8vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt::s8vector_ref(v1, N), pmt::out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt::s8vector_set(v1, N, int8_t(0)), pmt::out_of_range);
+
+  size_t	len;
+  const int8_t *rd = pmt::s8vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  int8_t *wr = pmt::s8vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = int8_t(0);
+  CPPUNIT_ASSERT_EQUAL(int8_t(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
+void
+qa_pmt_unv::test_u16vector()
+{
+  static const size_t N = 3;
+  pmt::pmt_t v1 = pmt::make_u16vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
+  uint16_t s0 = uint16_t(10);
+  uint16_t s1 = uint16_t(20);
+  uint16_t s2 = uint16_t(30);
+
+  pmt::u16vector_set(v1, 0, s0);
+  pmt::u16vector_set(v1, 1, s1);
+  pmt::u16vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt::u16vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt::u16vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt::u16vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt::u16vector_ref(v1, N), pmt::out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt::u16vector_set(v1, N, uint16_t(0)), pmt::out_of_range);
+
+  size_t	len;
+  const uint16_t *rd = pmt::u16vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  uint16_t *wr = pmt::u16vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = uint16_t(0);
+  CPPUNIT_ASSERT_EQUAL(uint16_t(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
+void
+qa_pmt_unv::test_s16vector()
+{
+  static const size_t N = 3;
+  pmt::pmt_t v1 = pmt::make_s16vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
+  int16_t s0 = int16_t(10);
+  int16_t s1 = int16_t(20);
+  int16_t s2 = int16_t(30);
+
+  pmt::s16vector_set(v1, 0, s0);
+  pmt::s16vector_set(v1, 1, s1);
+  pmt::s16vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt::s16vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt::s16vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt::s16vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt::s16vector_ref(v1, N), pmt::out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt::s16vector_set(v1, N, int16_t(0)), pmt::out_of_range);
+
+  size_t	len;
+  const int16_t *rd = pmt::s16vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  int16_t *wr = pmt::s16vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = int16_t(0);
+  CPPUNIT_ASSERT_EQUAL(int16_t(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
+void
+qa_pmt_unv::test_u32vector()
+{
+  static const size_t N = 3;
+  pmt::pmt_t v1 = pmt::make_u32vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
+  uint32_t s0 = uint32_t(10);
+  uint32_t s1 = uint32_t(20);
+  uint32_t s2 = uint32_t(30);
+
+  pmt::u32vector_set(v1, 0, s0);
+  pmt::u32vector_set(v1, 1, s1);
+  pmt::u32vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt::u32vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt::u32vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt::u32vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt::u32vector_ref(v1, N), pmt::out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt::u32vector_set(v1, N, uint32_t(0)), pmt::out_of_range);
+
+  size_t	len;
+  const uint32_t *rd = pmt::u32vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  uint32_t *wr = pmt::u32vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = uint32_t(0);
+  CPPUNIT_ASSERT_EQUAL(uint32_t(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
+void
+qa_pmt_unv::test_s32vector()
+{
+  static const size_t N = 3;
+  pmt::pmt_t v1 = pmt::make_s32vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
+  int32_t s0 = int32_t(10);
+  int32_t s1 = int32_t(20);
+  int32_t s2 = int32_t(30);
+
+  pmt::s32vector_set(v1, 0, s0);
+  pmt::s32vector_set(v1, 1, s1);
+  pmt::s32vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt::s32vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt::s32vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt::s32vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt::s32vector_ref(v1, N), pmt::out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt::s32vector_set(v1, N, int32_t(0)), pmt::out_of_range);
+
+  size_t	len;
+  const int32_t *rd = pmt::s32vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  int32_t *wr = pmt::s32vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = int32_t(0);
+  CPPUNIT_ASSERT_EQUAL(int32_t(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
+void
+qa_pmt_unv::test_u64vector()
+{
+  static const size_t N = 3;
+  pmt::pmt_t v1 = pmt::make_u64vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
+  uint64_t s0 = uint64_t(10);
+  uint64_t s1 = uint64_t(20);
+  uint64_t s2 = uint64_t(30);
+
+  pmt::u64vector_set(v1, 0, s0);
+  pmt::u64vector_set(v1, 1, s1);
+  pmt::u64vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt::u64vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt::u64vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt::u64vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt::u64vector_ref(v1, N), pmt::out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt::u64vector_set(v1, N, uint64_t(0)), pmt::out_of_range);
+
+  size_t	len;
+  const uint64_t *rd = pmt::u64vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  uint64_t *wr = pmt::u64vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = uint64_t(0);
+  CPPUNIT_ASSERT_EQUAL(uint64_t(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
+void
+qa_pmt_unv::test_s64vector()
+{
+  static const size_t N = 3;
+  pmt::pmt_t v1 = pmt::make_s64vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
+  int64_t s0 = int64_t(10);
+  int64_t s1 = int64_t(20);
+  int64_t s2 = int64_t(30);
+
+  pmt::s64vector_set(v1, 0, s0);
+  pmt::s64vector_set(v1, 1, s1);
+  pmt::s64vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt::s64vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt::s64vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt::s64vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt::s64vector_ref(v1, N), pmt::out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt::s64vector_set(v1, N, int64_t(0)), pmt::out_of_range);
+
+  size_t	len;
+  const int64_t *rd = pmt::s64vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  int64_t *wr = pmt::s64vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = int64_t(0);
+  CPPUNIT_ASSERT_EQUAL(int64_t(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
+void
+qa_pmt_unv::test_f32vector()
+{
+  static const size_t N = 3;
+  pmt::pmt_t v1 = pmt::make_f32vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
+  float s0 = float(10);
+  float s1 = float(20);
+  float s2 = float(30);
+
+  pmt::f32vector_set(v1, 0, s0);
+  pmt::f32vector_set(v1, 1, s1);
+  pmt::f32vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt::f32vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt::f32vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt::f32vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt::f32vector_ref(v1, N), pmt::out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt::f32vector_set(v1, N, float(0)), pmt::out_of_range);
+
+  size_t	len;
+  const float *rd = pmt::f32vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  float *wr = pmt::f32vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = float(0);
+  CPPUNIT_ASSERT_EQUAL(float(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
+void
+qa_pmt_unv::test_f64vector()
+{
+  static const size_t N = 3;
+  pmt::pmt_t v1 = pmt::make_f64vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
+  double s0 = double(10);
+  double s1 = double(20);
+  double s2 = double(30);
+
+  pmt::f64vector_set(v1, 0, s0);
+  pmt::f64vector_set(v1, 1, s1);
+  pmt::f64vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt::f64vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt::f64vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt::f64vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt::f64vector_ref(v1, N), pmt::out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt::f64vector_set(v1, N, double(0)), pmt::out_of_range);
+
+  size_t	len;
+  const double *rd = pmt::f64vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  double *wr = pmt::f64vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = double(0);
+  CPPUNIT_ASSERT_EQUAL(double(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
+void
+qa_pmt_unv::test_c32vector()
+{
+  static const size_t N = 3;
+  pmt::pmt_t v1 = pmt::make_c32vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
+  std::complex<float> s0 = std::complex<float>(10);
+  std::complex<float> s1 = std::complex<float>(20);
+  std::complex<float> s2 = std::complex<float>(30);
+
+  pmt::c32vector_set(v1, 0, s0);
+  pmt::c32vector_set(v1, 1, s1);
+  pmt::c32vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt::c32vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt::c32vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt::c32vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt::c32vector_ref(v1, N), pmt::out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt::c32vector_set(v1, N, std::complex<float>(0)), pmt::out_of_range);
+
+  size_t	len;
+  const std::complex<float> *rd = pmt::c32vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  std::complex<float> *wr = pmt::c32vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = std::complex<float>(0);
+  CPPUNIT_ASSERT_EQUAL(std::complex<float>(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
+void
+qa_pmt_unv::test_c64vector()
+{
+  static const size_t N = 3;
+  pmt::pmt_t v1 = pmt::make_c64vector(N, 0);
+  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
+  std::complex<double> s0 = std::complex<double>(10);
+  std::complex<double> s1 = std::complex<double>(20);
+  std::complex<double> s2 = std::complex<double>(30);
+
+  pmt::c64vector_set(v1, 0, s0);
+  pmt::c64vector_set(v1, 1, s1);
+  pmt::c64vector_set(v1, 2, s2);
+
+  CPPUNIT_ASSERT_EQUAL(s0, pmt::c64vector_ref(v1, 0));
+  CPPUNIT_ASSERT_EQUAL(s1, pmt::c64vector_ref(v1, 1));
+  CPPUNIT_ASSERT_EQUAL(s2, pmt::c64vector_ref(v1, 2));
+
+  CPPUNIT_ASSERT_THROW(pmt::c64vector_ref(v1, N), pmt::out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt::c64vector_set(v1, N, std::complex<double>(0)), pmt::out_of_range);
+
+  size_t	len;
+  const std::complex<double> *rd = pmt::c64vector_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
+
+  std::complex<double> *wr = pmt::c64vector_writable_elements(v1, len);
+  CPPUNIT_ASSERT_EQUAL(len, N);
+  wr[0] = std::complex<double>(0);
+  CPPUNIT_ASSERT_EQUAL(std::complex<double>(0), wr[0]);
+  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
+  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
+}
diff --git a/gnuradio-runtime/lib/pmt/qa_pmt_unv.h b/gnuradio-runtime/lib/pmt/qa_pmt_unv.h
new file mode 100644
index 0000000000..71462a9212
--- /dev/null
+++ b/gnuradio-runtime/lib/pmt/qa_pmt_unv.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_PMT_UNV_H
+#define INCLUDED_QA_PMT_UNV_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_pmt_unv : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE(qa_pmt_unv);
+  CPPUNIT_TEST(test_u8vector);
+  CPPUNIT_TEST(test_s8vector);
+  CPPUNIT_TEST(test_u16vector);
+  CPPUNIT_TEST(test_s16vector);
+  CPPUNIT_TEST(test_u32vector);
+  CPPUNIT_TEST(test_s32vector);
+  CPPUNIT_TEST(test_u64vector);
+  CPPUNIT_TEST(test_s64vector);
+  CPPUNIT_TEST(test_f32vector);
+  CPPUNIT_TEST(test_f64vector);
+  CPPUNIT_TEST(test_c32vector);
+  CPPUNIT_TEST(test_c64vector);
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  void test_u8vector();
+  void test_s8vector();
+  void test_u16vector();
+  void test_s16vector();
+  void test_u32vector();
+  void test_s32vector();
+  void test_u64vector();
+  void test_s64vector();
+  void test_f32vector();
+  void test_f64vector();
+  void test_c32vector();
+  void test_c64vector();
+};
+
+#endif
diff --git a/gnuradio-runtime/lib/pmt/unv_qa_template.cc.t b/gnuradio-runtime/lib/pmt/unv_qa_template.cc.t
deleted file mode 100644
index ea675cee16..0000000000
--- a/gnuradio-runtime/lib/pmt/unv_qa_template.cc.t
+++ /dev/null
@@ -1,35 +0,0 @@
-void
-qa_pmt_unv::test_@TAG@vector()
-{
-  static const size_t N = 3;
-  pmt::pmt_t v1 = pmt::make_@TAG@vector(N, 0);
-  CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
-  @TYPE@ s0 = @TYPE@(10);
-  @TYPE@ s1 = @TYPE@(20);
-  @TYPE@ s2 = @TYPE@(30);
-
-  pmt::@TAG@vector_set(v1, 0, s0);
-  pmt::@TAG@vector_set(v1, 1, s1);
-  pmt::@TAG@vector_set(v1, 2, s2);
-
-  CPPUNIT_ASSERT_EQUAL(s0, pmt::@TAG@vector_ref(v1, 0));
-  CPPUNIT_ASSERT_EQUAL(s1, pmt::@TAG@vector_ref(v1, 1));
-  CPPUNIT_ASSERT_EQUAL(s2, pmt::@TAG@vector_ref(v1, 2));
-
-  CPPUNIT_ASSERT_THROW(pmt::@TAG@vector_ref(v1, N), pmt::out_of_range);
-  CPPUNIT_ASSERT_THROW(pmt::@TAG@vector_set(v1, N, @TYPE@(0)), pmt::out_of_range);
-
-  size_t	len;
-  const @TYPE@ *rd = pmt::@TAG@vector_elements(v1, len);
-  CPPUNIT_ASSERT_EQUAL(len, N);
-  CPPUNIT_ASSERT_EQUAL(s0, rd[0]);
-  CPPUNIT_ASSERT_EQUAL(s1, rd[1]);
-  CPPUNIT_ASSERT_EQUAL(s2, rd[2]);
-
-  @TYPE@ *wr = pmt::@TAG@vector_writable_elements(v1, len);
-  CPPUNIT_ASSERT_EQUAL(len, N);
-  wr[0] = @TYPE@(0);
-  CPPUNIT_ASSERT_EQUAL(@TYPE@(0), wr[0]);
-  CPPUNIT_ASSERT_EQUAL(s1, wr[1]);
-  CPPUNIT_ASSERT_EQUAL(s2, wr[2]);
-}
diff --git a/gnuradio-runtime/lib/pmt/unv_template.cc.t b/gnuradio-runtime/lib/pmt/unv_template.cc.t
deleted file mode 100644
index b6c9d05c1d..0000000000
--- a/gnuradio-runtime/lib/pmt/unv_template.cc.t
+++ /dev/null
@@ -1,149 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-//                           pmt_@TAG@vector
-////////////////////////////////////////////////////////////////////////////
-
-namespace pmt {
-
-static pmt_@TAG@vector *
-_@TAG@vector(pmt_t x)
-{
-  return dynamic_cast<pmt_@TAG@vector*>(x.get());
-}
-
-
-pmt_@TAG@vector::pmt_@TAG@vector(size_t k, @TYPE@ fill)
-  : d_v(k)
-{
-  for (size_t i = 0; i < k; i++)
-    d_v[i] = fill;
-}
-
-pmt_@TAG@vector::pmt_@TAG@vector(size_t k, const @TYPE@ *data)
-  : d_v(k)
-{
-  if(k)
-    memcpy( &d_v[0], data, k * sizeof(@TYPE@) );
-}
-
-@TYPE@
-pmt_@TAG@vector::ref(size_t k) const
-{
-  if (k >= length())
-    throw out_of_range("pmt_@TAG@vector_ref", from_long(k));
-  return d_v[k];
-}
-
-void
-pmt_@TAG@vector::set(size_t k, @TYPE@ x)
-{
-  if (k >= length())
-    throw out_of_range("pmt_@TAG@vector_set", from_long(k));
-  d_v[k] = x;
-}
-
-const @TYPE@ *
-pmt_@TAG@vector::elements(size_t &len)
-{
-  len = length();
-  return len ?  &d_v[0] : nullptr;
-}
-
-@TYPE@ *
-pmt_@TAG@vector::writable_elements(size_t &len)
-{
-  len = length();
-  return len ? &d_v[0] : nullptr;
-}
-
-const void*
-pmt_@TAG@vector::uniform_elements(size_t &len)
-{
-  len = length() * sizeof(@TYPE@);
-  return len ? &d_v[0] : nullptr;
-}
-
-void*
-pmt_@TAG@vector::uniform_writable_elements(size_t &len)
-{
-  len = length() * sizeof(@TYPE@);
-  return len ? (&d_v[0]) : nullptr;
-}
-
-bool
-is_@TAG@vector(pmt_t obj)
-{
-  return obj->is_@TAG@vector();
-}
-
-pmt_t
-make_@TAG@vector(size_t k, @TYPE@ fill)
-{
-  return pmt_t(new pmt_@TAG@vector(k, fill));
-}
-
-pmt_t
-init_@TAG@vector(size_t k, const @TYPE@ *data)
-{
-  return pmt_t(new pmt_@TAG@vector(k, data));
-}
-
-pmt_t
-init_@TAG@vector(size_t k, const std::vector< @TYPE@ > &data)
-{
-  if(k) {
-    return pmt_t(new pmt_@TAG@vector(k, &data[0]));
-  }
-  return pmt_t(new pmt_@TAG@vector(k, static_cast< @TYPE@ >(0))); // fills an empty vector with 0
-}
-
-@TYPE@
-@TAG@vector_ref(pmt_t vector, size_t k)
-{
-  if (!vector->is_@TAG@vector())
-    throw wrong_type("pmt_@TAG@vector_ref", vector);
-  return _@TAG@vector(vector)->ref(k);
-}
-
-void
-@TAG@vector_set(pmt_t vector, size_t k, @TYPE@ obj)
-{
-  if (!vector->is_@TAG@vector())
-    throw wrong_type("pmt_@TAG@vector_set", vector);
-  _@TAG@vector(vector)->set(k, obj);
-}
-
-const @TYPE@ *
-@TAG@vector_elements(pmt_t vector, size_t &len)
-{
-  if (!vector->is_@TAG@vector())
-    throw wrong_type("pmt_@TAG@vector_elements", vector);
-  return _@TAG@vector(vector)->elements(len);
-}
-
-const std::vector< @TYPE@ >
-@TAG@vector_elements(pmt_t vector)
-{
-  if (!vector->is_@TAG@vector())
-    throw wrong_type("pmt_@TAG@vector_elements", vector);
-  size_t len;
-  const @TYPE@ *array = _@TAG@vector(vector)->elements(len);
-  const std::vector< @TYPE@ > vec(array, array+len);
-  return vec;
-}
-
-
-@TYPE@ *
-@TAG@vector_writable_elements(pmt_t vector, size_t &len)
-{
-  if (!vector->is_@TAG@vector())
-    throw wrong_type("pmt_@TAG@vector_writable_elements", vector);
-  return _@TAG@vector(vector)->writable_elements(len);
-}
-
-const std::string
-pmt_@TAG@vector::string_ref(size_t k) const
-{
-  return boost::lexical_cast< std::string, @TYPE@ > (ref(k));
-}
-
-} /* namespace pmt */
diff --git a/gnuradio-runtime/lib/pmt/unv_template.h.t b/gnuradio-runtime/lib/pmt/unv_template.h.t
deleted file mode 100644
index ab5c163570..0000000000
--- a/gnuradio-runtime/lib/pmt/unv_template.h.t
+++ /dev/null
@@ -1,25 +0,0 @@
-
-////////////////////////////////////////////////////////////////////////////
-//                           pmt_@TAG@vector
-////////////////////////////////////////////////////////////////////////////
-
-class pmt_@TAG@vector : public pmt_uniform_vector
-{
-  std::vector< @TYPE@ >	d_v;
-
-public:
-  pmt_@TAG@vector(size_t k, @TYPE@ fill);
-  pmt_@TAG@vector(size_t k, const @TYPE@ *data);
-  // ~pmt_@TAG@vector();
-
-  bool is_@TAG@vector() const { return true; }
-  size_t length() const { return d_v.size(); }
-  size_t itemsize() const { return sizeof(@TYPE@); }
-  @TYPE@ ref(size_t k) const;
-  void set(size_t k, @TYPE@ x);
-  const @TYPE@ *elements(size_t &len);
-  @TYPE@ *writable_elements(size_t &len);
-  const void *uniform_elements(size_t &len);
-  void *uniform_writable_elements(size_t &len);
-  virtual const std::string string_ref(size_t k) const;
-};
diff --git a/gnuradio-runtime/swig/CMakeLists.txt b/gnuradio-runtime/swig/CMakeLists.txt
index 9135f311c6..a48aaeb9f3 100644
--- a/gnuradio-runtime/swig/CMakeLists.txt
+++ b/gnuradio-runtime/swig/CMakeLists.txt
@@ -45,7 +45,6 @@ set(GR_SWIG_LIBRARIES
 set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/pmt_swig_doc.i)
 set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include/pmt
   ${CMAKE_CURRENT_BINARY_DIR}/../include/pmt)
-list(APPEND GR_SWIG_TARGET_DEPS pmt_generated)
 GR_SWIG_MAKE(pmt_swig pmt_swig.i)
 
 GR_SWIG_INSTALL(
-- 
cgit v1.2.3