7 #ifndef _MIMETIC_CODEC_CODEC_CHAIN_
8 #define _MIMETIC_CODEC_CODEC_CHAIN_
11 #include <mimetic/codec/codec_base.h>
19 template<
typename C,
typename N = null_node>
26 template<
typename Node,
typename LastNode>
31 typename Node::content_type,
34 typename Node::next_node_type,
40 template<
typename LastNode>
41 struct push_back_node<null_node, LastNode>
43 typedef LastNode node_type;
50 template<
typename Node,
unsigned int idx>
53 typedef typename Node::next_node_type next_node_type;
54 typedef typename item<next_node_type, idx-1>::node_type node_type;
55 item(
const Node& node)
58 const node_type& node()
const
60 return item<next_node_type, idx-1>(m_node.m_next).node();
62 const typename node_type::content_type& content()
const
71 template<
typename Node>
74 typedef Node node_type;
75 item(
const Node& node)
78 const node_type& node()
const
82 const typename node_type::content_type& content()
const
95 template<
typename Node,
typename TailNode,
unsigned int idx = Node::count-1>
96 struct build_push_back_node
98 typedef typename item<Node,idx>::node_type nth_node_type;
99 typedef typename nth_node_type::content_type nth_content_type;
100 typedef codec_chain<nth_content_type,TailNode>
103 build_push_back_node<Node,next_tail_node_type,idx-1>::result_node_type
108 build_push_back_node(
const Node& initn,
const TailNode& tailn)
109 : m_initn(initn), m_tailn(tailn)
112 operator const result_node_type()
const
116 const result_node_type get()
const
118 const nth_content_type& nth_c=item<Node,idx>(m_initn).content();
119 next_tail_node_type next_tail(nth_c, m_tailn);
120 return build_push_back_node<Node,next_tail_node_type,idx-1>(m_initn,next_tail).get();
124 const TailNode& m_tailn;
128 template<
typename Node,
typename TailNode>
129 struct build_push_back_node<Node,TailNode,0>
131 typedef typename item<Node,0>::node_type nth_node_type;
132 typedef typename nth_node_type::content_type nth_content_type;
133 typedef codec_chain<nth_content_type, TailNode> next_tail_node_type;
134 typedef next_tail_node_type result_node_type;
136 build_push_back_node(
const Node& initn,
const TailNode& tailn)
137 : m_initn(initn), m_tailn(tailn)
140 operator const result_node_type()
const
144 const result_node_type get()
const
146 const nth_content_type& nth_c=item<Node,0>(m_initn).content();
147 next_tail_node_type next_tail(nth_c, m_tailn);
152 const TailNode& m_tailn;
176 template<
typename C,
typename N>
180 typedef C content_type;
181 typedef N next_node_type;
182 enum { count = 1 + next_node_type::count };
192 codec_chain(
const content_type& c,
const next_node_type& node)
193 : m_c(c), m_next(node)
198 : m_c(node.m_c), m_next(node.m_next)
206 const char* name()
const
208 return m_name.c_str();
212 m_c.process(c, m_next);
219 template<
typename Cn>
220 const Cn& get_c(
int idx)
const
224 const content_type& get_c(
int idx)
const
231 template<
typename C1>
232 const C1& operator[](
int idx)
const
237 return m_next[--idx];
243 m_c.process(c, m_next);
250 template<
typename TailC>
252 push_back_node<self_type, codec_chain<TailC> >::node_type
253 operator|(
const TailC& l)
257 build_push_back_node<self_type, tail_node> bpbn(*
this,tail);
262 next_node_type m_next;
267 m_name = std::string() + m_c.name() +
"|" + m_next.name();
278 typedef null_node self_type;
279 typedef null_content content_type;
283 template<
typename C1,
typename N1>
284 null_node(
const codec_chain<C1, N1>& node)
287 const char* name()
const
288 {
return "null_node"; }
289 self_type& operator*()
291 self_type& operator=(
char c)
293 self_type& operator++()
295 self_type& operator++(
int)
309 template<
typename A,
typename B=null_node,
typename C=null_node,
typename D=null_node,
typename E=null_node,
typename F=null_node,
typename G=null_node>
316 template<
typename A,
typename B,
typename C,
typename D,
typename E,
typename F>
317 struct node_traits<A,B,C,D,E,F>
319 typedef codec_chain<A,
324 codec_chain<F> > > > > > node_type;
327 template<
typename A,
typename B,
typename C,
typename D,
typename E>
328 struct node_traits<A,B,C,D,E>
330 typedef codec_chain<A,
334 codec_chain<E> > > > > node_type;
337 template<
typename A,
typename B,
typename C,
typename D>
338 struct node_traits<A,B,C,D>
340 typedef codec_chain<A,
343 codec_chain<D> > > > node_type;
346 template<
typename A,
typename B,
typename C>
347 struct node_traits<A,B,C>
349 typedef codec_chain<A,
351 codec_chain<C> > > node_type;
355 template<
typename A,
typename B>
356 struct node_traits<A,B>
358 typedef codec_chain<A,
359 codec_chain<B> > node_type;
363 struct node_traits<A>
365 typedef codec_chain<A> node_type;
373 struct chainable_codec
376 typename node_traits<A,B>::node_type
377 operator|(
const B& b)
379 typedef codec_chain<B> node_b;
380 const A& a =
static_cast<A&
>(*this);
381 return typename node_traits<A,B>::node_type(a, node_b(b));
392 template<
class A,
class B>
393 typename node_traits<A,B>::node_type
394 operator|(
const A& a,
const B& b)
397 typedef codec_chain<B> node_b;
398 return typename node_traits<A,B>::node_type(a, node_b(b));
401 template<
typename C,
typename Node,
typename Last>
403 push_back_node<codec_chain<C, Node>, codec_chain<Last> >::node_type
404 operator|(
const codec_chain<C, Node>& node,
const Last& l)
406 typedef codec_chain<C,Node> InitNode;
407 typedef codec_chain<Last> TailNode;
408 TailNode tailnode = l;
409 build_push_back_node<InitNode,TailNode> bpbn(node,tailnode);
Defines a chain of codecs.
Definition: codec_chain.h:178