pair.hh

00001 // This file is a part of Aurelia.
00002 // Copyright (C) 2010  Valentin David
00003 // Copyright (C) 2010  University of Bergen
00004 //
00005 // This program is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017 #ifndef __PAIR_HH
00018 # define __PAIR_HH
00019 
00020 # include <algorithm>
00021 # include "../lists/listable.hh"
00022 
00023 namespace aurelia {
00024 
00025   template <typename A, typename B>
00026   struct pair_pattern {
00027     typedef typename
00028     pattern_concept<typename pattern_model<A>::model>::check require1;
00029     typedef typename
00030     pattern_concept<typename pattern_model<B>::model>::check require2;
00031 
00032   private:
00033     A a;
00034     B b;
00035   public:
00036     typedef std::pair<typename pattern_model<A>::model::build_type,
00037                       typename pattern_model<B>::model::build_type> build_type;
00038     pair_pattern(const A& a, const B& b): a(a), b(b) {}
00039 
00040     build_type operator*() const {
00041       return build_type(*a, *b);
00042     }
00043     build_type operator=(const build_type& i) const {
00044       A ta(a);
00045       B tb(b);
00046       ta = i.first;
00047       tb = i.second;
00048       return i;
00049     }
00050   };
00051 
00052 
00055   template <typename A, typename B>
00056   struct pattern_model<pair_pattern<A, B> > {
00057     struct model {
00058       typedef typename
00059       pattern_concept<typename pattern_model<A>::model>::check require1;
00060       typedef typename
00061       pattern_concept<typename pattern_model<B>::model>::check require2;
00062 
00063       typedef pair_pattern<A, B> type;
00064       typedef typename pair_pattern<A, B>::build_type build_type;
00065     };
00066   };
00067 
00068   template <typename A, typename B>
00069   pair_pattern<A,B> p(const A& a, const B& b) {
00070     return pair_pattern<A,B>(a, b);
00071   }
00072 
00073   template <typename A, typename B>
00074   struct listable_model<pair_pattern<A, B> > {
00075     struct model {
00076       typedef pair_pattern<A,B> Type;
00077     };
00078   };
00079 
00080 }
00081 
00082 #endif