libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/base/meta.hpp
Go to the documentation of this file.
00001 
00014 /*
00015  *  Copyright (C) 2010 Juan Pedro Bolivar Puente
00016  *
00017  *  This file is part of Psychosynth.
00018  *   
00019  *  Psychosynth is free software: you can redistribute it and/or modify
00020  *  it under the terms of the GNU General Public License as published by
00021  *  the Free Software Foundation, either version 3 of the License, or
00022  *  (at your option) any later version.
00023  *
00024  *  Psychosynth is distributed in the hope that it will be useful,
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00027  *  GNU General Public License for more details.
00028  *
00029  *  You should have received a copy of the GNU General Public License
00030  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00031  *
00032  */
00033 
00034 #ifndef PSYNTH_BASE_META_H_
00035 #define PSYNTH_BASE_META_H_
00036 
00037 #include <boost/mpl/find_if.hpp>
00038 #include <boost/mpl/quote.hpp>
00039 #include <boost/mpl/apply.hpp>
00040 #include <boost/mpl/begin_end.hpp>
00041 #include <boost/mpl/not.hpp>
00042 #include <boost/mpl/equal_to.hpp>
00043 #include <boost/mpl/empty_sequence.hpp>
00044 #include <boost/mpl/copy.hpp>
00045 #include <boost/mpl/pair.hpp>
00046 #include <boost/mpl/reverse.hpp>
00047 #include <boost/mpl/transform.hpp>
00048 #include <boost/mpl/front_inserter.hpp>
00049 
00050 namespace psynth
00051 {
00052 namespace base
00053 {
00054 
00055 namespace mpl = boost::mpl;
00056 
00057 template <class Seq, class Default = mpl::list<> >
00058 struct safe_front :
00059         public mpl::eval_if<typename mpl::empty<Seq>::type,
00060                             Default,
00061                             mpl::front<Seq> > {};
00062 
00063 template <class Seq, class Default = mpl::list<> >
00064 struct safe_pop_front :
00065         public mpl::eval_if<typename mpl::empty<Seq>::type,
00066                             Default,
00067                             mpl::pop_front<Seq> > {};
00068 
00069 template <class Seq1, class Seq2>
00070 struct concat
00071 {
00072     typedef typename mpl::copy<
00073         typename mpl::reverse<Seq1>::type,
00074         typename mpl::front_inserter<Seq2> >::type type;
00075 };
00076 
00077 template <class Sequence, class Pred>
00078 struct every_p
00079 {
00080     template <class X>
00081     struct not_pred : public mpl::not_<typename mpl::apply<Pred, X>::type> {};
00082     
00083     typedef typename boost::is_same<
00084         typename mpl::find_if<Sequence, mpl::quote1<not_pred> >::type,
00085         typename mpl::end<Sequence>::type>::type type;
00086 };
00087 
00088 template<class Sequence, class Pred>
00089 struct any_p
00090 {
00091     typedef typename mpl::not_<
00092         boost::is_same<
00093             typename mpl::find_if<Sequence, Pred>::type,
00094             typename mpl::end<Sequence>::type> >::type type;
00095 };
00096 
00097 struct join 
00098 { 
00099     template <class Seq1, class Seq2> 
00100     struct apply 
00101     { 
00102         typedef typename mpl::reverse<
00103             typename boost::mpl::copy< 
00104                 Seq2, 
00105                 boost::mpl::front_inserter<Seq1> 
00106                 >::type >::type type; 
00107     }; 
00108 };
00109 
00114 template<class Sequence> 
00115 struct flatten 
00116 { 
00117     typedef typename boost::mpl::fold< 
00118         Sequence, 
00119         typename boost::mpl::clear<Sequence>::type, 
00120         join 
00121         >::type type; 
00122 };
00123 
00124 template <class Element, class Sequence>
00125 struct pair_seq : public mpl::transform<
00126     Sequence,
00127     mpl::lambda<typename mpl::pair<Element, mpl::_1> >
00128     >::type {};
00129 
00130 
00131 } /* namespace base */
00132 } /* namespace psynth */
00133 
00134 #endif /* PSYNTH_BASE_META_H_ */
00135