Ticket #8658: stl_like_algorithm_v1.patch

File stl_like_algorithm_v1.patch, 30.9 KB (added by lordhoto, 17 years ago)

path against SVN from 20070509

  • test/common/array.h

     
    5959                TS_ASSERT( array[1] == 33 );
    6060                TS_ASSERT( array[2] == -11 );
    6161        }
     62
     63        void test_insert_at( void )
     64        {
     65                Common::Array<int> array;
     66
     67                // First of all some data
     68                array.push_back(-12);
     69                array.push_back(17);
     70                array.push_back(25);
     71                array.push_back(-11);
     72
     73                // Insert some data
     74                array.insert_at(2, 33);
     75
     76                TS_ASSERT( array[0] == -12 );
     77                TS_ASSERT( array[1] == 17 );
     78                TS_ASSERT( array[2] == 33 );
     79                TS_ASSERT( array[3] == 25 );
     80                TS_ASSERT( array[4] == -11 );
     81        }
     82
     83        void test_remove_at( void )
     84        {
     85                Common::Array<int> array;
     86
     87                // First of all some data
     88                array.push_back(-12);
     89                array.push_back(17);
     90                array.push_back(33);
     91                array.push_back(25);
     92                array.push_back(-11);
     93
     94                // Remove some data
     95                array.remove_at(1);
     96
     97                TS_ASSERT( array[0] == -12 );
     98                TS_ASSERT( array[1] == 33 );
     99                TS_ASSERT( array[2] == 25 );
     100                TS_ASSERT( array[3] == -11 );
     101        }
     102
     103        void test_push_back( void )
     104        {
     105                Common::Array<int> array1, array2;
     106
     107                // Some data for both
     108                array1.push_back(-3);
     109                array1.push_back(5);
     110                array1.push_back(9);
     111
     112                array2.push_back(3);
     113                array2.push_back(-2);
     114                array2.push_back(-131);
     115
     116                array1.push_back(array2);
     117
     118                TS_ASSERT( array1[0] == -3 );
     119                TS_ASSERT( array1[1] == 5 );
     120                TS_ASSERT( array1[2] == 9 );
     121                TS_ASSERT( array1[3] == 3 );
     122                TS_ASSERT( array1[4] == -2 );
     123                TS_ASSERT( array1[5] == -131 );
     124        }
     125
     126        void test_copy_constructor( void )
     127        {
     128                Common::Array<int> array1;
     129
     130                // Some data for both
     131                array1.push_back(-3);
     132                array1.push_back(5);
     133                array1.push_back(9);
     134
     135                Common::Array<int> array2(array1);
     136
     137                TS_ASSERT( array2[0] == -3 );
     138                TS_ASSERT( array2[1] == 5 );
     139                TS_ASSERT( array2[2] == 9 );
     140        }
    62141};
  • gui/browser.cpp

     
    2727#include "common/config-manager.h"
    2828#include "common/fs.h"
    2929#include "common/system.h"
    30 #include "common/func.h"
     30#include "common/algorithm.h"
    3131
    3232namespace GUI {
    3333
  • common/hash-str.h

     
    2929
    3030uint hashit(const char *str);
    3131uint hashit_lower(const char *str);     // Generate a hash based on the lowercase version of the string
     32inline uint hashit(const String &str) { return hashit(str.c_str()); }
     33inline uint hashit_lower(const String &str) { return hashit_lower(str.c_str()); }
    3234
    3335
    3436// FIXME: The following functors obviously are not consistently named
  • common/func.h

     
    2626
    2727namespace Common {
    2828
    29 template <class T>
    30 struct EqualTo {
    31   bool operator()(const T& x, const T& y) const { return x == y; }
     29template<class Arg, class Result>
     30struct UnaryFunction {
     31        typedef Arg ArgumenType;
     32        typedef Result ResultType;
    3233};
    3334
    34 template <class T>
    35 struct Less {
    36   bool operator()(const T& x, const T& y) const { return x < y; }
     35template<class Arg1, class Arg2, class Result>
     36struct BinaryFunction {
     37        typedef Arg1 FirstArgumentType;
     38        typedef Arg2 SecondArgumentType;
     39        typedef Result ResultType;
    3740};
    3841
     42template<class T>
     43struct EqualTo : public BinaryFunction<T, T, bool> {
     44        bool operator()(const T& x, const T& y) const { return x == y; }
     45};
     46
     47template<class T>
     48struct Less : public BinaryFunction<T, T, bool> {
     49        bool operator()(const T& x, const T& y) const { return x < y; }
     50};
     51
     52template<class Op>
     53class Binder1st : public UnaryFunction<typename Op::SecondArgumentType, typename Op::ResultType> {
     54private:
     55        Op _op;
     56        typename Op::FirstArgumentType _arg1;
     57public:
     58        Binder1st(const Op &op, const typename Op::FirstArgumentType &arg1) : _op(op), _arg1(arg1) {}
     59
     60        typename Op::ResultType operator()(typename Op::SecondArgumentType v) const {
     61                return _op(_arg1, v);
     62        }
     63};
     64
     65template<class Op, class T>
     66inline Binder1st<Op> bind1st(const Op &op, const T &t) {
     67        return Binder1st<Op>(op, t);
     68}
     69
     70template<class Op>
     71class Binder2nd : public UnaryFunction<typename Op::FirstArgumentType, typename Op::ResultType> {
     72private:
     73        Op _op;
     74        typename Op::SecondArgumentType _arg2;
     75public:
     76        Binder2nd(const Op &op, const typename Op::SecondArgumentType &arg2) : _op(op), _arg2(arg2) {}
     77
     78        typename Op::ResultType operator()(typename Op::FirstArgumentType v) const {
     79                return _op(v, _arg2);
     80        }
     81};
     82
     83template<class Op, class T>
     84inline Binder2nd<Op> bind2nd(const Op &op, const T &t) {
     85        return Binder2nd<Op>(op, t);
     86}
     87
     88template<class Arg, class Result>
     89class PointerToUnaryFunc : public UnaryFunction<Arg, Result> {
     90private:
     91        Result (*_func)(Arg);
     92public:
     93        typedef Result (*FuncType)(Arg);
     94       
     95        PointerToUnaryFunc(const FuncType &func) : _func(func) {}
     96        Result operator()(Arg v) const {
     97                return _func(v);
     98        }
     99};
     100
     101template<class Arg1, class Arg2, class Result>
     102class PointerToBinaryFunc : public BinaryFunction<Arg1, Arg2, Result> {
     103private:
     104        Result (*_func)(Arg1, Arg2);
     105public:
     106        typedef Result (*FuncType)(Arg1, Arg2);
     107
     108        PointerToBinaryFunc(const FuncType &func) : _func(func) {}
     109        Result operator()(Arg1 v1, Arg2 v2) const {
     110                return _func(v1, v2);
     111        }
     112};
     113
     114template<class Arg, class Result>
     115inline PointerToUnaryFunc<Arg, Result> ptr_fun(Result (*func)(Arg)) {
     116        return PointerToUnaryFunc<Arg, Result>(func);
     117}
     118
     119template<class Arg1, class Arg2, class Result>
     120inline PointerToBinaryFunc<Arg1, Arg2, Result> ptr_fun(Result (*func)(Arg1, Arg2)) {
     121        return PointerToBinaryFunc<Arg1, Arg2, Result>(func);
     122}
     123
     124template<class Result, class T>
     125class MemFunc0 : public UnaryFunction<T*, Result> {
     126private:
     127        Result (T::*_func)();
     128public:
     129        typedef Result (T::*FuncType)();
     130
     131        MemFunc0(const FuncType &func) : _func(func) {}
     132        Result operator()(T *v) const {
     133                return (v->*_func)();
     134        }
     135};
     136
     137template<class Result, class T>
     138class ConstMemFunc0 : public UnaryFunction<T*, Result> {
     139private:
     140        Result (T::*_func)() const;
     141public:
     142        typedef Result (T::*FuncType)() const;
     143
     144        ConstMemFunc0(const FuncType &func) : _func(func) {}
     145        Result operator()(T *v) const {
     146                return (v->*_func)();
     147        }
     148};
     149
     150template<class Result, class Arg, class T>
     151class MemFunc1 : public BinaryFunction<T*, Arg, Result> {
     152private:
     153        Result (T::*_func)(Arg);
     154public:
     155        typedef Result (T::*FuncType)(Arg);
     156
     157        MemFunc1(const FuncType &func) : _func(func) {}
     158        Result operator()(T *v1, Arg v2) const {
     159                return (v1->*_func)(v2);
     160        }
     161};
     162
     163template<class Result, class Arg, class T>
     164class ConstMemFunc1 : public BinaryFunction<T*, Arg, Result> {
     165private:
     166        Result (T::*_func)(Arg) const;
     167public:
     168        typedef Result (T::*FuncType)(Arg) const;
     169
     170        ConstMemFunc1(const FuncType &func) : _func(func) {}
     171        Result operator()(T *v1, Arg v2) const {
     172                return (v1->*_func)(v2);
     173        }
     174};
     175
     176template<class Result, class T>
     177inline MemFunc0<Result, T> mem_fun(Result (T::*f)()) {
     178        return MemFunc0<Result, T>(f);
     179}
     180
     181template<class Result, class T>
     182inline ConstMemFunc0<Result, T> mem_fun(Result (T::*f)() const) {
     183        return ConstMemFunc0<Result, T>(f);
     184}
     185
     186template<class Result, class Arg, class T>
     187inline MemFunc1<Result, Arg, T> mem_fun(Result (T::*f)(Arg)) {
     188        return MemFunc1<Result, Arg, T>(f);
     189}
     190
     191template<class Result, class Arg, class T>
     192inline ConstMemFunc1<Result, Arg, T> mem_fun(Result (T::*f)(Arg) const) {
     193        return ConstMemFunc1<Result, Arg, T>(f);
     194}
     195
     196template<class Cont>
     197class BackInsertIterator {
     198private:
     199        Cont *_container;
     200
     201public:
     202        BackInsertIterator(Cont &c) : _container(&c) {}
     203
     204        BackInsertIterator &operator =(const typename Cont::value_type &v) {
     205                _container->push_back(v);
     206                return *this;
     207        }
     208
     209        BackInsertIterator &operator *() { return *this; }
     210        BackInsertIterator &operator ++() { return *this; }
     211        BackInsertIterator operator ++(int) { return *this; }
     212};
     213
     214template<class Cont>
     215BackInsertIterator<Cont> back_inserter(Cont &c) {
     216        return BackInsertIterator<Cont>(c);
     217}
     218
     219template<class Cont>
     220class FrontInsertIterator {
     221private:
     222        Cont *_container;
     223
     224public:
     225        FrontInsertIterator(Cont &c) : _container(&c) {}
     226
     227        FrontInsertIterator &operator =(const typename Cont::value_type &v) {
     228                _container->push_front(v);
     229                return *this;
     230        }
     231
     232        FrontInsertIterator &operator *() { return *this; }
     233        FrontInsertIterator &operator ++() { return *this; }
     234        FrontInsertIterator operator ++(int) { return *this; }
     235};
     236
     237template<class Cont>
     238FrontInsertIterator<Cont> front_inserter(Cont &c) {
     239        return FrontInsertIterator<Cont>(c);
     240}
     241
    39242/**
    40243 * Base template for hash functor objects, used by HashMap.
    41244 * This needs to be specialized for every type that you need to hash.
     
    61264
    62265#undef GENERATE_TRIVIAL_HASH_FUNCTOR
    63266
    64 
    65 // Simple sort function, modelled after std::sort.
    66 // Use it like this:  sort(container.begin(), container.end()).
    67 // Also work on plain old int arrays etc.
    68 template <typename T>
    69 void sort(T first, T last) {
    70         if (first == last)
    71                 return;
    72 
    73         // Simple selection sort
    74         T i(first);
    75         for (; i != last; ++i) {
    76                 T minElem(i);
    77                 T j(i);
    78                 ++j;
    79                 for (; j != last; ++j)
    80                         if (*j < *minElem)
    81                                 minElem = j;
    82                 if (minElem != i)
    83                         SWAP(*minElem, *i);
    84         }
    85 }
    86 
    87 
    88267}       // End of namespace Common
    89268
    90269#endif
     270
  • common/array.h

     
    2323#define COMMON_ARRAY_H
    2424
    2525#include "common/scummsys.h"
     26#include "common/algorithm.h"
    2627
    2728namespace Common {
    2829
     
    3738        typedef T *iterator;
    3839        typedef const T *const_iterator;
    3940
     41        typedef T value_type;
     42
    4043public:
    4144        Array() : _capacity(0), _size(0), _data(0) {}
    4245        Array(const Array<T>& array) : _capacity(0), _size(0), _data(0) {
    4346                _size = array._size;
    4447                _capacity = _size + 32;
    4548                _data = new T[_capacity];
    46                 for (int i = 0; i < _size; i++)
    47                         _data[i] = array._data[i];
     49                copy(array._data, array._data + _size, _data);
    4850        }
    4951
    5052        ~Array() {
     
    5961
    6062        void push_back(const Array<T>& array) {
    6163                ensureCapacity(_size + array._size);
    62                 for (int i = 0; i < array._size; i++)
    63                         _data[_size++] = array._data[i];
     64                copy(array._data, array._data + array._size, _data + _size);
     65                _size += array._size;
    6466        }
    6567
    6668        void insert_at(int idx, const T& element) {
    6769                assert(idx >= 0 && idx <= _size);
    6870                ensureCapacity(_size + 1);
    69                 // The following loop is not efficient if you can just memcpy things around.
    70                 // e.g. if you have a list of ints. But for real objects (String...), memcpy
    71                 // usually isn't correct (specifically, for any class which has a non-default
    72                 // copy behaviour. E.g. the String class uses a refCounter which has to be
    73                 // updated whenever a String is copied.
    74                 for (int i = _size; i > idx; i--) {
    75                         _data[i] = _data[i-1];
    76                 }
     71                copy_backward(_data + idx, _data + _size, _data + _size + 1);
    7772                _data[idx] = element;
    7873                _size++;
    7974        }
     
    8176        T remove_at(int idx) {
    8277                assert(idx >= 0 && idx < _size);
    8378                T tmp = _data[idx];
    84                 for (int i = idx; i < _size - 1; i++)
    85                         _data[i] = _data[i+1];
     79                copy(_data + idx + 1, _data + _size, _data + idx);
    8680                _size--;
    8781                return tmp;
    8882        }
     
    108102                _size = array._size;
    109103                _capacity = _size + 32;
    110104                _data = new T[_capacity];
    111                 for (int i = 0; i < _size; i++)
    112                         _data[i] = array._data[i];
     105                copy(array._data, array._data + _size, _data);
    113106
    114107                return *this;
    115108        }
     
    149142        }
    150143
    151144        bool contains(const T &key) const {
    152                 for (const_iterator i = begin(); i != end(); ++i) {
    153                         if (*i == key)
    154                                 return true;
    155                 }
    156                 return false;
     145                return find(begin(), end(), key) != end();
    157146        }
    158147
    159148
     
    168157
    169158                if (old_data) {
    170159                        // Copy old data
    171                         for (int i = 0; i < _size; i++)
    172                                 _data[i] = old_data[i];
     160                        copy(old_data, old_data + _size, _data);
    173161                        delete [] old_data;
    174162                }
    175163        }
  • common/algorithm.h

     
     1/* ScummVM - Scumm Interpreter
     2 * Copyright (C) 2007 The ScummVM project
     3 *
     4 * This program is free software; you can redistribute it and/or
     5 * modify it under the terms of the GNU General Public License
     6 * as published by the Free Software Foundation; either version 2
     7 * of the License, or (at your option) any later version.
     8 *
     9 * This program is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with this program; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     17 *
     18 * $URL$
     19 * $Id$
     20 */
     21
     22#ifndef COMMON_ALGORITHM_H
     23#define COMMON_ALGORITHM_H
     24
     25#include "common/scummsys.h"
     26
     27namespace Common {
     28
     29template<class In, class Out>
     30Out copy(In first, In last, Out dst) {
     31        while (first != last)
     32                *dst++ = *first++;
     33        return dst;
     34}
     35
     36template<class In, class Out>
     37Out copy_backward(In first, In last, Out dst) {
     38        while (first != last)
     39                *--dst = *--last;
     40        return dst;
     41}
     42
     43template<class In, class Out, class Op>
     44Out copy_if(In first, In last, Out dst, Op op) {
     45        while (first != last) {
     46                if (op(*first))
     47                        *dst++ = *first;
     48                ++first;
     49        }
     50        return dst;
     51}
     52
     53template<class In, class T>
     54In find(In first, In last, const T &v) {
     55        while (first != last) {
     56                if (*first == v)
     57                        return first;
     58                ++first;
     59        }
     60        return last;
     61}
     62
     63template<class In, class Pred>
     64In find_if(In first, In last, Pred p) {
     65        while (first != last) {
     66                if (p(*first))
     67                        return first;
     68                ++first;
     69        }
     70        return last;
     71}
     72
     73template<class In, class Op>
     74Op for_each(In first, In last, Op f) {
     75        while (first != last) f(*first++);
     76        return f;
     77}
     78
     79// Simple sort function, modelled after std::sort.
     80// Use it like this:  sort(container.begin(), container.end()).
     81// Also work on plain old int arrays etc.
     82template<class T>
     83void sort(T first, T last) {
     84        if (first == last)
     85                return;
     86
     87        // Simple selection sort
     88        T i(first);
     89        for (; i != last; ++i) {
     90                T minElem(i);
     91                T j(i);
     92                ++j;
     93                for (; j != last; ++j)
     94                        if (*j < *minElem)
     95                                minElem = j;
     96                if (minElem != i)
     97                        SWAP(*minElem, *i);
     98        }
     99}
     100
     101} // end of namespace Common
     102#endif
     103
  • common/list.h

    Property changes on: common/algorithm.h
    ___________________________________________________________________
    Name: svn:mime-type
       + text/plain
    Name: svn:keywords
       + Date Rev Author URL Id
    Name: svn:eol-style
       + native
    
     
    111111        NodeBase *_anchor;
    112112
    113113public:
    114         typedef Iterator<T>        iterator;
    115         typedef Iterator<const T>  const_iterator;
     114        typedef Iterator<T>                     iterator;
     115        typedef Iterator<const T>       const_iterator;
    116116
     117        typedef T value_type;
     118
    117119public:
    118120        List() {
    119121                _anchor = new NodeBase;
  • engines/kyra/resource.h

     
    3838        ResourceFile() : _open(false), _protected(false), _filename() {}
    3939        virtual ~ResourceFile() {}
    4040
    41         virtual uint8 *getFile(uint file) = 0;
    42         virtual bool getFileHandle(uint file, Common::File &filehandle) = 0;
    43         virtual uint32 getFileSize(uint file) = 0;
     41        virtual uint8 *getFile(uint file) const = 0;
     42        virtual bool getFileHandle(uint file, Common::File &filehandle) const = 0;
     43        virtual uint32 getFileSize(uint file) const = 0;
    4444
    4545        uint filename() const { return _filename; }
    4646
     
    6262                uint _name;
    6363                uint32 _start;
    6464                uint32 _size;
     65               
     66                operator uint() const { return _name; }
    6567        };
    6668
    6769public:
    6870        PAKFile(const char *file, const char *physfile, Common::File &pakfile, bool isAmiga = false);
    6971        ~PAKFile();
    7072
    71         uint8 *getFile(uint file);
    72         bool getFileHandle(uint file, Common::File &filehandle);
    73         uint32 getFileSize(uint file);
     73        uint8 *getFile(uint file) const;
     74        bool getFileHandle(uint file, Common::File &filehandle) const;
     75        uint32 getFileSize(uint file) const;
    7476private:
    75         bool openFile(Common::File &filehandle);
     77        bool openFile(Common::File &filehandle) const;
    7678
    7779        Common::String _physfile;
    7880        uint32 _physOffset;
    7981
     82        typedef Common::List<PakChunk>::iterator PakIterator;
     83        typedef Common::List<PakChunk>::const_iterator ConstPakIterator;
    8084        Common::List<PakChunk> _files; // the entries
    8185};
    8286
     
    8690                uint _name;
    8791                uint32 _start;
    8892                uint32 _size;
     93               
     94                operator uint() const { return _name; }
    8995        };
    9096public:
    9197        INSFile(const char *file);
    9298        ~INSFile();
    9399
    94         uint8 *getFile(uint file);
    95         bool getFileHandle(uint file, Common::File &filehandle);
    96         uint32 getFileSize(uint file);
     100        uint8 *getFile(uint file) const;
     101        bool getFileHandle(uint file, Common::File &filehandle) const;
     102        uint32 getFileSize(uint file) const;
    97103protected:
     104        typedef Common::List<FileEntry>::iterator FileIterator;
     105        typedef Common::List<FileEntry>::const_iterator ConstFileIterator;
    98106        Common::List<FileEntry> _files; // the entries
    99107
    100108        Common::String _physfile;
     
    105113        Resource(KyraEngine *vm);
    106114        ~Resource();
    107115       
    108         bool loadPakFile(const Common::String &filename, const bool forcePC = false);
     116        bool loadPakFile(const Common::String &filename);
    109117        void unloadPakFile(const Common::String &filename);
    110         bool isInPakList(const Common::String &filename);
     118        bool isInPakList(const Common::String &filename) const;
    111119
    112         uint32 getFileSize(const char *file);
    113         uint8* fileData(const char *file, uint32 *size);
     120        uint32 getFileSize(const char *file) const;
     121        uint8* fileData(const char *file, uint32 *size) const;
    114122        // it gives back a file handle (used for the speech player)
    115123        // it could be that the needed file is embedded in the returned
    116124        // handle
     
    119127        bool loadFileToBuf(const char *file, void *buf, uint32 maxSize);
    120128
    121129protected:
     130        typedef Common::List<ResourceFile*>::iterator ResIterator;
     131        typedef Common::List<ResourceFile*>::const_iterator ConstResIterator;
     132
    122133        KyraEngine *_vm;
    123134        Common::List<ResourceFile*> _pakfiles;
    124135};
  • engines/kyra/resource.cpp

     
    2626#include "common/file.h"
    2727#include "common/fs.h"
    2828#include "common/hash-str.h"
     29#include "common/func.h"
     30#include "common/algorithm.h"
    2931
    3032#include "gui/message.h"
    3133
     
    3537#include "kyra/screen.h"
    3638
    3739namespace Kyra {
     40
     41namespace {
     42struct ResFilenameEqual : public Common::BinaryFunction<ResourceFile*, uint, bool> {
     43        uint _filename;
     44        ResFilenameEqual(uint file) : _filename(file) {}
     45
     46        bool operator()(ResourceFile *f) {
     47                return f->filename() == _filename;
     48        }
     49};
     50} // end of anonymous namespace
     51
    3852Resource::Resource(KyraEngine *vm) {
    3953        _vm = vm;
    4054
    4155        if (_vm->game() == GI_KYRA1) {
    4256                // we're loading KYRA.DAT here too (but just for Kyrandia 1)
    43                 if (!loadPakFile("KYRA.DAT", true) || !StaticResource::checkKyraDat()) {
     57                if (!loadPakFile("KYRA.DAT") || !StaticResource::checkKyraDat()) {
    4458                        GUI::MessageDialog errorMsg("You're missing the 'KYRA.DAT' file or it got corrupted, (re)get it from the ScummVM website");
    4559                        errorMsg.runModal();
    4660                        error("You're missing the 'KYRA.DAT' file or it got corrupted, (re)get it from the ScummVM website");
     
    5872                INSFile *insFile = new INSFile("WESTWOOD.001");
    5973                assert(insFile);
    6074                if (!insFile->isValid())
    61                         return;
     75                        error("'WESTWOOD.001' file not found or corrupt");
    6276                _pakfiles.push_back(insFile);
    6377        }
    6478
     
    7286                static const char *list[] = {
    7387                        "ADL.PAK", "CHAPTER1.VRM", "COL.PAK", "FINALE.PAK", "INTRO1.PAK", "INTRO2.PAK",
    7488                        "INTRO3.PAK", "INTRO4.PAK", "MISC.PAK", "SND.PAK", "STARTUP.PAK", "XMI.PAK",
    75                         "CAVE.APK", "DRAGON1.APK", "DRAGON2.APK", "LAGOON.APK", 0
     89                        "CAVE.APK", "DRAGON1.APK", "DRAGON2.APK", "LAGOON.APK"
    7690                };
    7791
    78                 for (int i = 0; list[i]; ++i) {
    79                         if (!loadPakFile(list[i]))
    80                                 error("couldn't open pakfile '%s'", list[i]);
    81                 }
    82 
    83                 Common::List<ResourceFile*>::iterator start = _pakfiles.begin();
    84                 for (;start != _pakfiles.end(); ++start)
    85                         (*start)->protect();
     92                Common::for_each(list, list + ARRAYSIZE(list), Common::bind1st(Common::mem_fun(&Resource::loadPakFile), this));
     93                Common::for_each(_pakfiles.begin(), _pakfiles.end(), Common::bind2nd(Common::mem_fun(&ResourceFile::protect), true));
    8694        } else {
    8795                for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
    8896                        Common::String filename = file->name();
     
    99107                }
    100108
    101109                if (_vm->gameFlags().platform == Common::kPlatformFMTowns) {
    102                         Common::List<ResourceFile*>::iterator start = _pakfiles.begin();
    103110                        uint unloadHash = (_vm->gameFlags().lang == Common::EN_ANY) ? Common::hashit_lower("JMC.PAK") : Common::hashit_lower("EMC.PAK");
    104111
    105                         for (;start != _pakfiles.end(); ++start) {
    106                                 if ((*start)->filename() == unloadHash) {
    107                                         delete *start;
    108                                         *start = 0;
    109                                         _pakfiles.erase(start);
    110                                         break;
    111                                 }
     112                        ResIterator file = Common::find_if(_pakfiles.begin(), _pakfiles.end(), ResFilenameEqual(unloadHash));
     113                        if (file != _pakfiles.end()) {
     114                                delete *file;
     115                                _pakfiles.erase(file);
    112116                        }
    113117                }
    114118        }
    115119}
    116120
    117121Resource::~Resource() {
    118         Common::List<ResourceFile*>::iterator start = _pakfiles.begin();
    119 
    120         for (;start != _pakfiles.end(); ++start) {
     122        for (ResIterator start = _pakfiles.begin() ;start != _pakfiles.end(); ++start) {
    121123                delete *start;
    122124                *start = 0;
    123125        }
    124126}
    125127
    126 bool Resource::loadPakFile(const Common::String &filename, const bool forcePC) {
    127         Common::List<ResourceFile*>::iterator start = _pakfiles.begin();
    128         uint hash = Common::hashit_lower(filename.c_str());
    129 
    130         for (;start != _pakfiles.end(); ++start) {
    131                 if ((*start)->filename() == hash) {
    132                         (*start)->open();
    133                         return true;
    134                 }
     128bool Resource::loadPakFile(const Common::String &filename) {
     129        ResIterator listFile = Common::find_if(_pakfiles.begin(), _pakfiles.end(), ResFilenameEqual(Common::hashit_lower(filename)));
     130        if (listFile != _pakfiles.end()) {
     131                (*listFile)->open();
     132                return true;
    135133        }
    136134
     135        const bool isKyraDat = filename.equalsIgnoreCase("KYRA.DAT");
    137136        uint32 size = 0;
    138137       
    139138        Common::File handle;
    140139        if (!getFileHandle(filename.c_str(), &size, handle)) {
    141                 warning("couldn't load file: '%s'", filename.c_str());
     140                (!isKyraDat ? error : warning)("couldn't load file: '%s'", filename.c_str());
    142141                return false;
    143142        }
    144143
    145         PAKFile *file = new PAKFile(filename.c_str(), handle.name(), handle, (_vm->gameFlags().platform == Common::kPlatformAmiga) && !forcePC);
     144        PAKFile *file = new PAKFile(filename.c_str(), handle.name(), handle, (_vm->gameFlags().platform == Common::kPlatformAmiga) && !isKyraDat);
    146145        handle.close();
    147146
    148147        if (!file)
    149148                return false;
    150149
    151150        if (!file->isValid()) {
    152                 warning("'%s' is no valid pak file", filename.c_str());
     151                error("'%s' is no valid pak file", filename.c_str());
    153152                delete file;
    154153                return false;
    155154        }
     
    159158}
    160159
    161160void Resource::unloadPakFile(const Common::String &filename) {
    162         Common::List<ResourceFile*>::iterator start = _pakfiles.begin();
    163         uint hash = Common::hashit_lower(filename.c_str());
    164         for (;start != _pakfiles.end(); ++start) {
    165                 if ((*start)->filename() == hash) {
    166                         (*start)->close();
    167                         break;
    168                 }
    169         }
    170         return;
     161        ResIterator pak = Common::find_if(_pakfiles.begin(), _pakfiles.end(), ResFilenameEqual(Common::hashit_lower(filename)));
     162        if (pak != _pakfiles.end())
     163                (*pak)->close();
    171164}
    172165
    173 bool Resource::isInPakList(const Common::String &filename) {
    174         Common::List<ResourceFile*>::iterator start = _pakfiles.begin();
    175         uint hash = Common::hashit_lower(filename.c_str());
    176         for (;start != _pakfiles.end(); ++start) {
    177                 if ((*start)->filename() == hash)
    178                         return true;
    179         }
    180         return false;
     166bool Resource::isInPakList(const Common::String &filename) const {
     167        return (Common::find_if(_pakfiles.begin(), _pakfiles.end(), ResFilenameEqual(Common::hashit_lower(filename))) != _pakfiles.end());
    181168}
    182169
    183 uint8 *Resource::fileData(const char *file, uint32 *size) {
     170uint8 *Resource::fileData(const char *file, uint32 *size) const {
    184171        Common::File fileHandle;
    185172
    186173        if (size)
     
    199186
    200187                return buffer;
    201188        } else {
    202                 // opens the file in a PAK File
    203                 Common::List<ResourceFile*>::iterator start = _pakfiles.begin();
    204 
     189                // opens the file inside a PAK File
    205190                uint fileHash = Common::hashit_lower(file);
    206                 for (;start != _pakfiles.end(); ++start) {
    207                         if (!(*start)->isOpen())
     191                for (ConstResIterator cur = _pakfiles.begin(); cur != _pakfiles.end(); ++cur) {
     192                        if (!(*cur)->isOpen())
    208193                                continue;
    209194
    210                         uint32 fileSize = (*start)->getFileSize(fileHash);
     195                        uint32 fileSize = (*cur)->getFileSize(fileHash);
    211196
    212197                        if (!fileSize)
    213198                                continue;
     
    215200                        if (size)
    216201                                *size = fileSize;
    217202
    218                         return (*start)->getFile(fileHash);
     203                        return (*cur)->getFile(fileHash);
    219204                }
    220205        }
    221206
     
    228213        if (filehandle.open(file))
    229214                return true;
    230215
    231         Common::List<ResourceFile*>::iterator start = _pakfiles.begin();
    232 
    233216        uint fileHash = Common::hashit_lower(file);
    234         for (;start != _pakfiles.end(); ++start) {
     217        for (ResIterator start = _pakfiles.begin() ;start != _pakfiles.end(); ++start) {
    235218                if (!(*start)->isOpen())
    236219                        continue;
    237220
     
    247230        return false;
    248231}
    249232
    250 uint32 Resource::getFileSize(const char *file) {
    251         Common::List<ResourceFile*>::iterator start = _pakfiles.begin();
    252 
     233uint32 Resource::getFileSize(const char *file) const {
    253234        Common::File temp;
    254235        if (temp.open(file))
    255236                return temp.size();
    256237
    257238        uint fileHash = Common::hashit_lower(file);
    258         for (;start != _pakfiles.end(); ++start) {
     239        for (ConstResIterator start = _pakfiles.begin() ;start != _pakfiles.end(); ++start) {
    259240                if (!(*start)->isOpen())
    260241                        continue;
    261242
     
    286267
    287268///////////////////////////////////////////
    288269// Pak file manager
    289 #define PAKFile_Iterate Common::List<PakChunk>::iterator start=_files.begin();start != _files.end(); ++start
    290270PAKFile::PAKFile(const char *file, const char *physfile, Common::File &pakfile, bool isAmiga) : ResourceFile() {
    291271        _open = false;
    292272
     
    300280
    301281        uint32 pos = 0, startoffset = 0, endoffset = 0;
    302282
    303         if (!isAmiga)
    304                 startoffset = pakfile.readUint32LE();
    305         else
     283        if (isAmiga)
    306284                startoffset = pakfile.readUint32BE();
     285        else
     286                startoffset = pakfile.readUint32LE();
    307287
    308288        if (startoffset > filesize) {
    309289                warning("PAK file '%s' is corrupted", file);
     
    338318                        return;
    339319                }
    340320
    341                 if (!isAmiga)
    342                         endoffset = READ_LE_UINT32(buffer + nameLength);
    343                 else
     321                if (isAmiga)
    344322                        endoffset = READ_BE_UINT32(buffer + nameLength);
     323                else
     324                        endoffset = READ_LE_UINT32(buffer + nameLength);
    345325
    346326                if (!endoffset) {
    347327                        endoffset = filesize;
     
    378358        _files.clear();
    379359}
    380360
    381 uint8 *PAKFile::getFile(uint hash) {
    382         for (PAKFile_Iterate) {
    383                 if (start->_name == hash) {
    384                         Common::File pakfile;
    385                         if (!openFile(pakfile))
    386                                 return false;
     361uint8 *PAKFile::getFile(uint hash) const {
     362        ConstPakIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash));
     363        if (file == _files.end())
     364                return 0;
    387365
    388                         pakfile.seek(start->_start, SEEK_CUR);
    389                         uint8 *buffer = new uint8[start->_size];
    390                         assert(buffer);
    391                         pakfile.read(buffer, start->_size);
    392                         return buffer;
    393                 }
    394         }
    395         return 0;
     366        Common::File pakfile;
     367        if (!openFile(pakfile))
     368                return false;
     369
     370        pakfile.seek(file->_start, SEEK_CUR);
     371        uint8 *buffer = new uint8[file->_size];
     372        assert(buffer);
     373        pakfile.read(buffer, file->_size);
     374        return buffer;
    396375}
    397376
    398 bool PAKFile::getFileHandle(uint hash, Common::File &filehandle) {
     377bool PAKFile::getFileHandle(uint hash, Common::File &filehandle) const {
    399378        filehandle.close();
    400379
    401         for (PAKFile_Iterate) {
    402                 if (start->_name == hash) {
    403                         if (!openFile(filehandle))
    404                                 return false;
     380        ConstPakIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash));
     381        if (file == _files.end())
     382                return false;
    405383
    406                         filehandle.seek(start->_start, SEEK_CUR);
    407                         return true;
    408                 }
    409         }
    410         return false;
     384        if (!openFile(filehandle))
     385                return false;
     386
     387        filehandle.seek(file->_start, SEEK_CUR);
     388        return true;
    411389}
    412390
    413 uint32 PAKFile::getFileSize(uint hash) {
    414         for (PAKFile_Iterate) {
    415                 if (start->_name == hash)
    416                         return start->_size;
    417         }
    418         return 0;
     391uint32 PAKFile::getFileSize(uint hash) const {
     392        ConstPakIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash));
     393        return (file != _files.end()) ? file->_size : 0;
    419394}
    420395
    421 bool PAKFile::openFile(Common::File &filehandle) {
     396bool PAKFile::openFile(Common::File &filehandle) const {
    422397        filehandle.close();
    423398
    424399        if (!filehandle.open(_physfile))
     
    430405
    431406///////////////////////////////////////////
    432407// Ins file manager
    433 #define INSFile_Iterate Common::List<FileEntry>::iterator start=_files.begin();start != _files.end(); ++start
    434408INSFile::INSFile(const char *file) : ResourceFile(), _files() {
    435409        Common::File pakfile;
    436410        _open = false;
     
    475449
    476450        pakfile.seek(3);
    477451
    478         for (INSFile_Iterate) {
     452        for (FileIterator start = _files.begin(); start != _files.end(); ++start) {
    479453                filesize = pakfile.readUint32LE();
    480454                start->_size = filesize;
    481455                start->_start = pakfile.pos();
     
    493467        _files.clear();
    494468}
    495469
    496 uint8 *INSFile::getFile(uint hash) {
    497         for (INSFile_Iterate) {
    498                 if (start->_name == hash) {
    499                         Common::File pakfile;
    500                         if (!pakfile.open(_physfile))
    501                                 return false;
     470uint8 *INSFile::getFile(uint hash) const {
     471        ConstFileIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash));
     472        if (file == _files.end())
     473                return 0;
    502474
    503                         pakfile.seek(start->_start);
    504                         uint8 *buffer = new uint8[start->_size];
    505                         assert(buffer);
    506                         pakfile.read(buffer, start->_size);
    507                         return buffer;
    508                 }
    509         }
    510         return 0;
     475        Common::File pakfile;
     476        if (!pakfile.open(_physfile))
     477                return false;
     478
     479        pakfile.seek(file->_start);
     480        uint8 *buffer = new uint8[file->_size];
     481        assert(buffer);
     482        pakfile.read(buffer, file->_size);
     483        return buffer;
    511484}
    512485
    513 bool INSFile::getFileHandle(uint hash, Common::File &filehandle) {
    514         for (INSFile_Iterate) {
    515                 if (start->_name == hash) {
    516                         if (!filehandle.open(_physfile))
    517                                 return false;
     486bool INSFile::getFileHandle(uint hash, Common::File &filehandle) const {
     487        ConstFileIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash));
    518488
    519                         filehandle.seek(start->_start, SEEK_CUR);
    520                         return true;
    521                 }
    522         }
    523         return false;
     489        if (file == _files.end())
     490                return false;
     491
     492        if (!filehandle.open(_physfile))
     493                return false;
     494
     495        filehandle.seek(file->_start, SEEK_CUR);
     496        return true;
    524497}
    525498
    526 uint32 INSFile::getFileSize(uint hash) {
    527         for (INSFile_Iterate) {
    528                 if (start->_name == hash)
    529                         return start->_size;
    530         }
    531         return 0;
     499uint32 INSFile::getFileSize(uint hash) const {
     500        ConstFileIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash));
     501        return (file != _files.end()) ? file->_size : 0;
    532502}
    533503
    534504} // end of namespace Kyra