Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2984 connectés 

  FORUM HardWare.fr
  Programmation

  [C] Accéder à une valeur dans un champ de bits

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Accéder à une valeur dans un champ de bits

n°42324
Alload
Posté le 23-06-2001 à 20:04:43  profilanswer
 

Je viens de voir qu'on pouvait créer des champs de bits afin de gagner de la place mémoire.
 
Mais si je veux créer un champ de width*height bits, je l'initialise de cette façon:
 
int champ : (width*heigh)
 
Mais une fois initalisé, comment j'accède par exemple à l'état du bit (x+y*width)? Et d'ailleurs comment je décide de l'état du bit (x+y*width)?

mood
Publicité
Posté le 23-06-2001 à 20:04:43  profilanswer
 

n°42328
la viper
Posté le 23-06-2001 à 21:18:57  profilanswer
 

il faut faire des masques
 
imaginons : xxx@ xxxx ton octet et tu souhaites recuperer @
 
et bien tu mets dans char A = (la valeur de ton octet);
A >> 4; 4 decalages vers la droite
puis tu fais un masque logique
 
A = A & 0x01;
 
tu retrouves dans A la valeur de @

n°42332
Alload
Posté le 23-06-2001 à 21:50:59  profilanswer
 

Et si le champs est composé de plus de 8 bits? Comment fait-on? Pareil?

n°42334
Alload
Posté le 23-06-2001 à 22:01:20  profilanswer
 

Et comment on change la valeur d'un bit?

n°42336
Alload
Posté le 23-06-2001 à 22:17:24  profilanswer
 

Et c'est quoi le nom anglais pour "champ de bits"? Que je puisse aller chercher sous Google un peu d'infos.
:D

n°42340
gilou
Modérateur
Modzilla
Posté le 23-06-2001 à 22:57:10  profilanswer
 

bitfield
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°42341
Alload
Posté le 23-06-2001 à 23:09:25  profilanswer
 

C'est un peu la merde les champs de bits dès qu'on veut une grande quantité de bits...
 
N'y a-t-il pas moyen de gérer une plus grande quantité mémoire de la même manière?  
 
Sinon quelle la taille d'une variable bool? Elle est pas spécifiée dans mon bouquin de C++.

n°42344
janoscoder
Posté le 23-06-2001 à 23:43:46  profilanswer
 

sérieux, les vecteurs de bool
vector<bool>
c'est cool. C'est dans le standard C++ 1998 ansi et est implémenté entre autres dans gcc et Visual, et c'est un tableau de bits accessibles individuellement.


---------------
-----------------------
n°42345
janoscoder
Posté le 23-06-2001 à 23:45:19  profilanswer
 

D'ailleurs, j'ai répondu dans un post d'il y qqes jours une classe de tableau Bidimensionnel de bool. Si tu veux, je peux tu filer un fichier .h avec le type défini et qui a plein de fonctions qui marchent bien.


---------------
-----------------------
n°42348
Alload
Posté le 23-06-2001 à 23:52:55  profilanswer
 

Oui je veux bien, et en m'expliquant un peu comment ça marche, parce que dans mon bouquin de C++ ils en parlent même pas de vector... Honte sur eux...

mood
Publicité
Posté le 23-06-2001 à 23:52:55  profilanswer
 

n°42353
janoscoder
Posté le 24-06-2001 à 00:17:25  profilanswer
 

alors voilà, c'est pas trop compliqué en fait. Un vector, c'est un peu comme un tableau, sauf qu'on se fait pas chier à l'allouer, ou à le désallouer, et y'a une implémentation pour les bool avec les bits côte à côte:
 
exemple:
 
#include <vector>
using namespace std;
 
void main
{
 vector<bool> tabbits(100);    //je crée un tableau de 100 bits;
 for (int i=0; i<100;< i++)
   tabbits[i]= (i%2==0);        //j'y écris la parité par exemple
 vector<bool> tabback=tabbits;  //je fais un backup du tableau
 tabbits.clear();               //pour effacer le contenu
 for (int j=0; j<tabback.size(); j++)
   cout << tabback[j] << ' ';   //j'affiche le contenu!  
 
}//tabbits est détruit (par le destructeur) et donc désalloué à la sortie du bloc;


---------------
-----------------------
n°42354
Alload
Posté le 24-06-2001 à 00:20:04  profilanswer
 

Cool, ça a l'air bien ce <vector>, c'est un peu comme un champ de bits sans restriction de place et plus simple d'accès.
 
Par contre, on peut stocker quoi dedans? 1, 0 ou true, false?

n°42355
janoscoder
Posté le 24-06-2001 à 00:24:28  profilanswer
 

Bon, je t'ai filé deux fichiers
BidimArray.h
et
BidimArrayImp.h
qui te serviront à faire des tableaux bidimensionnels de types de ton choix, des bits, des octets, des RGBA,....
C'est documenté dans le code, et si tu downloades
http://www.stack.nl/~dimitri/doxygen
le logiciel de doc C++ cool, tu pourras générer l'aide html de cette classe.
 
J'ai écrit cette classe en faisant bon usage de la STL (même si y'a des choses que je changerais aujourd'hui, mais j'insiste pour que tu essayes de piger ce que j'y fais, c'est pas trop dur, et ça t'évitera de buter contre des problèmes comme moi dans le passé.
 
N'hésite pas à aller voir mon site web
http://janos.boudet.free.fr/
sur le C++. Je le mets à jour régulièrement
 
 
 
/*!
\file BidimArray.h
\date 24/01/2001
\author Janos Boudet
\brief définit les vecteurs bidimensionnels avec une base d'opérateurs associés. Les Images notamment en seront et on pourra aussi faire des transformations en ondelettes avec. Les constructeurs par recopie (en fait ceux de vector<T> doivent se comporter admirablement
*/
 
#ifndef __BidimArray_hh__
#define __BidimArray_hh__
 
#ifdef _msvc
#include <vector>
using namespace std;
#else
#include <vector.h>
#endif
 
/*!
\class BidimArray
\Author Janos Boudet
\brief La classe de vecteur bidimensionnel. Les données sont rangées en x consécutifs
*/
template <class T>
class BidimArray: protected vector<T>
{
protected:
 //!largeur  
 int w;
 //! hauteur
 int h;
public:
 //! constructeur par défaut: Vecteur de 0x0 pixels
 BidimArray();
 /*!
 \brief constructeur d'un vecteur de x*y valeurs
 \param x largeur du vecteur à créer
 \param y hauteur du vecteur à créer
 */
 BidimArray(int x, int y);
 /*!
 \brief constructeur avec éventuellement conversion de type
 \param other le modèle a partir duquel on construit
 */
 template <class X>
   BidimArray(const BidimArray<X> & other);
 /*!
   \brief accède à la valeur (x,y)
   \param x abscisses de la case à laquelle on veut accéder
   \param y ordonnées de la case à laquelle on veut accéder
   \return valeur de la case
 */  
 T & operator()(int x, int y);
 /*!
   \brief accède à la valeur (x,y) const
   \param x abscisses de la case à laquelle on veut accéder
   \param y ordonnées de la case à laquelle on veut accéder
   \return valeur de la case
 */  
 const T & operator ()(int x, int y) const;
 /*!
   \brief accède au ième pixel avec i=x+y*w
   \param i pixel auquel on veut accéder
   \return valeur du pixel
 */    
 T & operator[](int i);
 /*!
   \brief accède au ième pixel avec i=x+y*w const
   \param i pixel auquel on veut accéder
   \return valeur du pixel
 */    
 const T & operator[](int i) const;
 /*!
   \brief lit la largeur
 \return la largeur du vecteur
 */
 int GetW() const;
 /*!
   \brief lit la hauteur
   \return la hauteur du vecteur
 */
 int GetH() const;
 /*!
   \brief impose une valeur constante à tout le vecteur
   \param value la valeur constante à donner à tout le vecteur
 */
 void SetConstantValue(const T & value);
 /*!
   \brief Copie une portion rectangulaire du vecteur
   \param x la plus petite abscisse du rectangle à copier
   \param y la plus petite ordonnée du rectangle à copier
   \param dx largeur du vecteur à copier
   \param dy hauteur du vecteur à copier
   \return le rectangle copié
 */
 BidimArray<T> Copy(int x=0, int y=0, int dx=0, int dy=0) const;
 /*!
   \brief insère un vecteur dans le vecteur courant
   \param other le vecteur à insérer
   \param x abscisse de l'insertion
   \param y ordonnée de l'insertion
   \renvoit l'image courante ainsi modifiée
 */
 BidimArray<T> & Paste(const BidimArray<T> & other, int x, int y);
 /*!
   \brief opérateur ==
   \param other vecteur auquel comparer (tous les éléments et la taille)
   \return true ou false
 */
 bool operator == (const BidimArray<T> & other);
 /*!
   \brief envoit l'exception length_error correctement formatée en cas de différence de taille
   \param other vecteur auquel comparer
 */
 void TestSizeMatch(const BidimArray<T> & other) const;
 /*!
   \brief met le vecteur à une taille de 0x0 (et au passage libère la mémoire)
 */
 void Clear();
 /*!
   \brief redimensionne le vecteur à une nouvelle taille. L'état des données à la sortie doit être considéré comme indéfini
   \param x nouvelle largeur
   \param y nouvelle hauteur
 */
 void BruteResize(int x, int y);
 /*!
   \brief écrit une ligne dans l'image. NB la ligne doit avoir une longueur égale à w
   \param line la ligne à écrire
   \param y quelle ligne remplacer
 */
 void WriteLine(const vector<T> & line, int y);
 /*!
   \brief écrit une colonne dans l'image. NB la colonne doit avoir une hauteur égale à h
   \param column la colonne à écrire
   \param x quelle colonne remplacer
 */
 void WriteColumn(const vector<T> & column, int x);
 /*!
   \brief lit une ligne dans l'image.
   \param y quelle ligne lire
   \return la ligne lue
 */
 vector<T> ReadLine(int y) const;
 /*!
   \brief lit une colonne dans l'image.
   \param x quelle colonne lire
   \return la colonne lue
 */
 vector<T> ReadColumn(int x) const;
};
 
#include "BidimArrayImp.h"
 
#endif //__BidimArray_hh__
 
 
***************************
****************************
*****************************
******************************
******************************
 
/*!
\file BidimArrayImp.h
\Author Janos Boudet
\date 24/01/2001
\brief implémentation du vecteur bidimentionnel
*/
 
#include "BidimArray.h"
#include <assert.h>
 
#ifdef _msvc
#include <stdexcept>
#include <strstream>
using namespace std;
#endif
 
#ifdef _linux
#include <stdexcept>
#include <strstream>
using namespace std;
#endif
 
 
#ifdef _sgi
#include <stdexcept.h>
#include <strstream.h>
#endif
 
 
 
#ifdef DEBUG
//#define BIDIM_ARRAY_RANGE_TEST
#endif
 
template <class T>
BidimArray<T>::BidimArray(): vector<T>(0), w(0), h(0)
{
 //nothing
}
 
template <class T>
BidimArray<T>::BidimArray(int x, int y): w(x), h(y), vector<T>(x*y)
{
 if (w<0)
 {
  strstream errmsg;
  errmsg<<"w="<<w<<"<0 for BidimArray constructor BidimArray(int,int)";
  throw(out_of_range(errmsg.str()));
 }
 if (h<0)
 {
  strstream errmsg;
  errmsg<<"h="<<h<<"<0 for BidimArray constructor BidimArray(int,int)";
  throw(out_of_range(errmsg.str()));
 }
 //on voit bien que l'on aura pas les deux
}
 
#ifdef _msvc
template <class X, class T>
#else
template <class T>
template <class X>
#endif
BidimArray<T>::BidimArray(const BidimArray<X> & other): w(other.GetW()), h(other.GetH())
{
 for (int i=0; i<w*h; i++)
  operator[](i)=other[i];
}
 
/*
NB: il faudrait remplacer tous les strstream par des stringstreams, mais un comportement
bizarre de la STL qui m'interdit ente autres d'inclure les fichiers .h sans le .h et de taper
-LANG:std dans les options de compilation, m'oblige à prendre des strstreams, moins propres
plutôt que des stringstreams.
lors du portage il serait propre de régler cela
*/
template <class T>
inline T & BidimArray<T>::operator()(int x, int y)
{  
#ifdef BIDIM_ARRAY_RANGE_TEST
 if (x<0)
 {
  strstream errmsg;
  errmsg<<"x="<<x<<"<0 for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
 if (x>=w)
 {
  strstream errmsg;
  errmsg<<"x="<<x<<">=width="<<w<<" for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
 if (y<0)
 {
  strstream errmsg;
  errmsg<<"y="<<y<<"<0 for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
 if (y>=h)
 {
  strstream errmsg;
  errmsg<<"y="<<y<<">=height="<<h<<" for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
#endif
 return operator[](x+w*y);
}
 
template <class T>
inline const T & BidimArray<T>::operator()(int x, int y) const
{
#ifdef BIDIM_ARRAY_RANGE_TEST
 if (x<0)
 {
  strstream errmsg;
  errmsg<<"x="<<x<<"<0 for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
 if (x>=w)
 {
  strstream errmsg;
  errmsg<<"x="<<x<<">=width="<<w<<" for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
 if (y<0)
 {
  strstream errmsg;
  errmsg<<"y="<<y<<"<0 for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
 if (y>=h)
 {
  strstream errmsg;
  errmsg<<"y="<<y<<">=height="<<h<<" for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
#endif
 return operator[](x+w*y);
}
 
template <class T>
inline T & BidimArray<T>::operator[](int i)
{
#ifdef BIDIM_ARRAY_RANGE_TEST
 if (i<0)
 {
  strstream errmsg;
  errmsg<<"i="<<i<<"<0 for BidimArray operator[]";
  throw(out_of_range(errmsg.str()));
 }
 if (i>=w*h)
 {
  strstream errmsg;
  errmsg<<"i="<<i<<">=width*height="<<w*h<<" for BidimArray operator[]";
  throw(out_of_range(errmsg.str()));
 }
#endif
 return vector<T>::operator[](i);
}
 
template <class T>
inline const T & BidimArray<T>::operator[](int i) const
{
#ifdef BIDIM_ARRAY_RANGE_TEST
 if (i<0)
 {
  strstream errmsg;
  errmsg<<"i="<<i<<"<0 for BidimArray operator[]";
  throw(out_of_range(errmsg.str()));
 }
 if (i>=w*h)
 {
  strstream errmsg;
  errmsg<<"i="<<i<<">=width*height="<<w*h<<" for BidimArray operator[]";
  throw(out_of_range(errmsg.str()));
 }
#endif
 return vector<T>::operator[](i);
}
 
template <class T>
inline int BidimArray<T>::GetW() const
{
 return w;
}
 
template <class T>
inline int BidimArray<T>::GetH() const
{
 return h;
}
 
template <class T>
void BidimArray<T>::SetConstantValue(const T & value)
{
 fill(begin(), end(), value);
}
 
template <class T>
BidimArray<T> BidimArray<T>::Copy(int x, int y, int dx, int dy) const
{
 assert(x>0);
 assert(y>0);
 assert(dx>0);
 assert(dy>0);
 assert(x+dx<=w);
 assert(y+dy<=h);
 //test
 //if(x<0)
 //  throw(out_of_range((stringstream("x out of range : " )<<x<<"!E["<<0<<", "<<w<<"]);
 BidimArray<T> newimage(dx,dy);
 for (int j=0; j<dy; j++)
  for (int i=0; i<dx; i++)
   newimage(i,j)=operator()(i+x, j+y);
  return newimage;
}
 
template <class T>
BidimArray<T> & BidimArray<T>::Paste(const BidimArray<T> & other, int x, int y)
{
 assert(x>0);
 assert(y>0);
 assert(x+other.w<=w);
 assert(y+other.h<=h);
 for (int j=0; j<other.h; j++)
  for (int i=0; i<other.w; i++)
   operator()(i+x,j+y)=other(i,j);
  return *this;
}
 
template <class T>
bool BidimArray<T>::operator == (const BidimArray<T> & other)
{
 if (w!=other.w)
  return false;
 //if (h!=other.h)
 //return false //on ne le fait pas car c'est redondant avec le test suivant
 return vector<T>::operator==(other);
}
 
template <class T>
inline void  BidimArray<T>::TestSizeMatch(const BidimArray<T> & other) const
{
 if (w!=other.w || h!=other.h)
 {
  strstream s; //mettre stringstream quand ça bugge pas
  s<<"Size mismatch : "<<w<<"x"<<h<<"!="<<other.w<<"x"<<other.h<<
endl;
  throw(length_error(s.str()));
 }
}
 
template <class T>
void  BidimArray<T>::Clear()
{
 BruteResize(0,0);
}
 
template <class T>
void  BidimArray<T>::BruteResize(int x, int y)
{
 w=x;
 h=y;
 resize(x*y);
}
 
template <class T>
void BidimArray<T>::WriteLine(const vector<T> & line, int y)
{
 int wr=y*w;
 for (int i=0; i<w; i++, wr++)
  operator[](wr)=line[i];
}
 
template <class T>
void BidimArray<T>::WriteColumn(const vector<T> & column, int x)
{
 int wr=x;
 for (int i=0; i<h; i++, wr+=w)
  operator[](wr)=column[i];
}
 
template <class T>
vector<T> BidimArray<T>::ReadLine(int y) const
{
 int rd=y*w;
 vector<T> line(w);
 for (int i=0; i<w; i++, rd++)
  line[i]=operator[](rd);
 return line;
}
 
template <class T>
vector<T> BidimArray<T>::ReadColumn(int x) const
{
 int rd=x;
 vector<T> column(h);
 for (int i=0; i<h; i++, rd+=w)
  column[i]=operator[](rd);
 return column;
}


---------------
-----------------------
n°42356
janoscoder
Posté le 24-06-2001 à 00:25:22  profilanswer
 

Repost mais sans les smileys:
 
Bon, je t'ai filé deux fichiers
BidimArray.h
et
BidimArrayImp.h
qui te serviront à faire des tableaux bidimensionnels de types de ton choix, des bits, des octets, des RGBA,....
C'est documenté dans le code, et si tu downloades
http://www.stack.nl/~dimitri/doxygen
le logiciel de doc C++ cool, tu pourras générer l'aide html de cette classe.
 
J'ai écrit cette classe en faisant bon usage de la STL (même si y'a des choses que je changerais aujourd'hui, mais j'insiste pour que tu essayes de piger ce que j'y fais, c'est pas trop dur, et ça t'évitera de buter contre des problèmes comme moi dans le passé.
 
N'hésite pas à aller voir mon site web
http://janos.boudet.free.fr/
sur le C++. Je le mets à jour régulièrement
 
 
 
/*!
\file BidimArray.h
\date 24/01/2001
\author Janos Boudet
\brief définit les vecteurs bidimensionnels avec une base d'opérateurs associés. Les Images notamment en seront et on pourra aussi faire des transformations en ondelettes avec. Les constructeurs par recopie (en fait ceux de vector<T> doivent se comporter admirablement
*/
 
#ifndef __BidimArray_hh__
#define __BidimArray_hh__
 
#ifdef _msvc
#include <vector>
using namespace std;
#else
#include <vector.h>
#endif
 
/*!
\class BidimArray
\Author Janos Boudet
\brief La classe de vecteur bidimensionnel. Les données sont rangées en x consécutifs
*/
template <class T>
class BidimArray: protected vector<T>
{
protected:
 //!largeur  
 int w;
 //! hauteur
 int h;
public:
 //! constructeur par défaut: Vecteur de 0x0 pixels
 BidimArray();
 /*!
 \brief constructeur d'un vecteur de x*y valeurs
 \param x largeur du vecteur à créer
 \param y hauteur du vecteur à créer
 */
 BidimArray(int x, int y);
 /*!
 \brief constructeur avec éventuellement conversion de type
 \param other le modèle a partir duquel on construit
 */
 template <class X>
   BidimArray(const BidimArray<X> & other);
 /*!
   \brief accède à la valeur (x,y)
   \param x abscisses de la case à laquelle on veut accéder
   \param y ordonnées de la case à laquelle on veut accéder
   \return valeur de la case
 */  
 T & operator()(int x, int y);
 /*!
   \brief accède à la valeur (x,y) const
   \param x abscisses de la case à laquelle on veut accéder
   \param y ordonnées de la case à laquelle on veut accéder
   \return valeur de la case
 */  
 const T & operator ()(int x, int y) const;
 /*!
   \brief accède au ième pixel avec i=x+y*w
   \param i pixel auquel on veut accéder
   \return valeur du pixel
 */    
 T & operator[](int i);
 /*!
   \brief accède au ième pixel avec i=x+y*w const
   \param i pixel auquel on veut accéder
   \return valeur du pixel
 */    
 const T & operator[](int i) const;
 /*!
   \brief lit la largeur
 \return la largeur du vecteur
 */
 int GetW() const;
 /*!
   \brief lit la hauteur
   \return la hauteur du vecteur
 */
 int GetH() const;
 /*!
   \brief impose une valeur constante à tout le vecteur
   \param value la valeur constante à donner à tout le vecteur
 */
 void SetConstantValue(const T & value);
 /*!
   \brief Copie une portion rectangulaire du vecteur
   \param x la plus petite abscisse du rectangle à copier
   \param y la plus petite ordonnée du rectangle à copier
   \param dx largeur du vecteur à copier
   \param dy hauteur du vecteur à copier
   \return le rectangle copié
 */
 BidimArray<T> Copy(int x=0, int y=0, int dx=0, int dy=0) const;
 /*!
   \brief insère un vecteur dans le vecteur courant
   \param other le vecteur à insérer
   \param x abscisse de l'insertion
   \param y ordonnée de l'insertion
   \renvoit l'image courante ainsi modifiée
 */
 BidimArray<T> & Paste(const BidimArray<T> & other, int x, int y);
 /*!
   \brief opérateur ==
   \param other vecteur auquel comparer (tous les éléments et la taille)
   \return true ou false
 */
 bool operator == (const BidimArray<T> & other);
 /*!
   \brief envoit l'exception length_error correctement formatée en cas de différence de taille
   \param other vecteur auquel comparer
 */
 void TestSizeMatch(const BidimArray<T> & other) const;
 /*!
   \brief met le vecteur à une taille de 0x0 (et au passage libère la mémoire)
 */
 void Clear();
 /*!
   \brief redimensionne le vecteur à une nouvelle taille. L'état des données à la sortie doit être considéré comme indéfini
   \param x nouvelle largeur
   \param y nouvelle hauteur
 */
 void BruteResize(int x, int y);
 /*!
   \brief écrit une ligne dans l'image. NB la ligne doit avoir une longueur égale à w
   \param line la ligne à écrire
   \param y quelle ligne remplacer
 */
 void WriteLine(const vector<T> & line, int y);
 /*!
   \brief écrit une colonne dans l'image. NB la colonne doit avoir une hauteur égale à h
   \param column la colonne à écrire
   \param x quelle colonne remplacer
 */
 void WriteColumn(const vector<T> & column, int x);
 /*!
   \brief lit une ligne dans l'image.
   \param y quelle ligne lire
   \return la ligne lue
 */
 vector<T> ReadLine(int y) const;
 /*!
   \brief lit une colonne dans l'image.
   \param x quelle colonne lire
   \return la colonne lue
 */
 vector<T> ReadColumn(int x) const;
};
 
#include "BidimArrayImp.h"
 
#endif //__BidimArray_hh__
 
 
***************************
****************************
*****************************
******************************
******************************
 
/*!
\file BidimArrayImp.h
\Author Janos Boudet
\date 24/01/2001
\brief implémentation du vecteur bidimentionnel
*/
 
#include "BidimArray.h"
#include <assert.h>
 
#ifdef _msvc
#include <stdexcept>
#include <strstream>
using namespace std;
#endif
 
#ifdef _linux
#include <stdexcept>
#include <strstream>
using namespace std;
#endif
 
 
#ifdef _sgi
#include <stdexcept.h>
#include <strstream.h>
#endif
 
 
 
#ifdef DEBUG
//#define BIDIM_ARRAY_RANGE_TEST
#endif
 
template <class T>
BidimArray<T>::BidimArray(): vector<T>(0), w(0), h(0)
{
 //nothing
}
 
template <class T>
BidimArray<T>::BidimArray(int x, int y): w(x), h(y), vector<T>(x*y)
{
 if (w<0)
 {
  strstream errmsg;
  errmsg<<"w="<<w<<"<0 for BidimArray constructor BidimArray(int,int)";
  throw(out_of_range(errmsg.str()));
 }
 if (h<0)
 {
  strstream errmsg;
  errmsg<<"h="<<h<<"<0 for BidimArray constructor BidimArray(int,int)";
  throw(out_of_range(errmsg.str()));
 }
 //on voit bien que l'on aura pas les deux
}
 
#ifdef _msvc
template <class X, class T>
#else
template <class T>
template <class X>
#endif
BidimArray<T>::BidimArray(const BidimArray<X> & other): w(other.GetW()), h(other.GetH())
{
 for (int i=0; i<w*h; i++)
  operator[](i)=other[i];
}
 
/*
NB: il faudrait remplacer tous les strstream par des stringstreams, mais un comportement
bizarre de la STL qui m'interdit ente autres d'inclure les fichiers .h sans le .h et de taper
-LANG:std dans les options de compilation, m'oblige à prendre des strstreams, moins propres
plutôt que des stringstreams.
lors du portage il serait propre de régler cela
*/
template <class T>
inline T & BidimArray<T>::operator()(int x, int y)
{  
#ifdef BIDIM_ARRAY_RANGE_TEST
 if (x<0)
 {
  strstream errmsg;
  errmsg<<"x="<<x<<"<0 for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
 if (x>=w)
 {
  strstream errmsg;
  errmsg<<"x="<<x<<">=width="<<w<<" for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
 if (y<0)
 {
  strstream errmsg;
  errmsg<<"y="<<y<<"<0 for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
 if (y>=h)
 {
  strstream errmsg;
  errmsg<<"y="<<y<<">=height="<<h<<" for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
#endif
 return operator[](x+w*y);
}
 
template <class T>
inline const T & BidimArray<T>::operator()(int x, int y) const
{
#ifdef BIDIM_ARRAY_RANGE_TEST
 if (x<0)
 {
  strstream errmsg;
  errmsg<<"x="<<x<<"<0 for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
 if (x>=w)
 {
  strstream errmsg;
  errmsg<<"x="<<x<<">=width="<<w<<" for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
 if (y<0)
 {
  strstream errmsg;
  errmsg<<"y="<<y<<"<0 for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
 if (y>=h)
 {
  strstream errmsg;
  errmsg<<"y="<<y<<">=height="<<h<<" for BidimArray operator()";
  throw(out_of_range(errmsg.str()));
 }
#endif
 return operator[](x+w*y);
}
 
template <class T>
inline T & BidimArray<T>::operator[](int i)
{
#ifdef BIDIM_ARRAY_RANGE_TEST
 if (i<0)
 {
  strstream errmsg;
  errmsg<<"i="<<i<<"<0 for BidimArray operator[]";
  throw(out_of_range(errmsg.str()));
 }
 if (i>=w*h)
 {
  strstream errmsg;
  errmsg<<"i="<<i<<">=width*height="<<w*h<<" for BidimArray operator[]";
  throw(out_of_range(errmsg.str()));
 }
#endif
 return vector<T>::operator[](i);
}
 
template <class T>
inline const T & BidimArray<T>::operator[](int i) const
{
#ifdef BIDIM_ARRAY_RANGE_TEST
 if (i<0)
 {
  strstream errmsg;
  errmsg<<"i="<<i<<"<0 for BidimArray operator[]";
  throw(out_of_range(errmsg.str()));
 }
 if (i>=w*h)
 {
  strstream errmsg;
  errmsg<<"i="<<i<<">=width*height="<<w*h<<" for BidimArray operator[]";
  throw(out_of_range(errmsg.str()));
 }
#endif
 return vector<T>::operator[](i);
}
 
template <class T>
inline int BidimArray<T>::GetW() const
{
 return w;
}
 
template <class T>
inline int BidimArray<T>::GetH() const
{
 return h;
}
 
template <class T>
void BidimArray<T>::SetConstantValue(const T & value)
{
 fill(begin(), end(), value);
}
 
template <class T>
BidimArray<T> BidimArray<T>::Copy(int x, int y, int dx, int dy) const
{
 assert(x>0);
 assert(y>0);
 assert(dx>0);
 assert(dy>0);
 assert(x+dx<=w);
 assert(y+dy<=h);
 //test
 //if(x<0)
 //  throw(out_of_range((stringstream("x out of range : " )<<x<<"!E["<<0<<", "<<w<<"]);
 BidimArray<T> newimage(dx,dy);
 for (int j=0; j<dy; j++)
  for (int i=0; i<dx; i++)
   newimage(i,j)=operator()(i+x, j+y);
  return newimage;
}
 
template <class T>
BidimArray<T> & BidimArray<T>::Paste(const BidimArray<T> & other, int x, int y)
{
 assert(x>0);
 assert(y>0);
 assert(x+other.w<=w);
 assert(y+other.h<=h);
 for (int j=0; j<other.h; j++)
  for (int i=0; i<other.w; i++)
   operator()(i+x,j+y)=other(i,j);
  return *this;
}
 
template <class T>
bool BidimArray<T>::operator == (const BidimArray<T> & other)
{
 if (w!=other.w)
  return false;
 //if (h!=other.h)
 //return false //on ne le fait pas car c'est redondant avec le test suivant
 return vector<T>::operator==(other);
}
 
template <class T>
inline void  BidimArray<T>::TestSizeMatch(const BidimArray<T> & other) const
{
 if (w!=other.w || h!=other.h)
 {
  strstream s; //mettre stringstream quand ça bugge pas
  s<<"Size mismatch : "<<w<<"x"<<h<<"!="<<other.w<<"x"<<other.h<<
endl;
  throw(length_error(s.str()));
 }
}
 
template <class T>
void  BidimArray<T>::Clear()
{
 BruteResize(0,0);
}
 
template <class T>
void  BidimArray<T>::BruteResize(int x, int y)
{
 w=x;
 h=y;
 resize(x*y);
}
 
template <class T>
void BidimArray<T>::WriteLine(const vector<T> & line, int y)
{
 int wr=y*w;
 for (int i=0; i<w; i++, wr++)
  operator[](wr)=line[i];
}
 
template <class T>
void BidimArray<T>::WriteColumn(const vector<T> & column, int x)
{
 int wr=x;
 for (int i=0; i<h; i++, wr+=w)
  operator[](wr)=column[i];
}
 
template <class T>
vector<T> BidimArray<T>::ReadLine(int y) const
{
 int rd=y*w;
 vector<T> line(w);
 for (int i=0; i<w; i++, rd++)
  line[i]=operator[](rd);
 return line;
}
 
template <class T>
vector<T> BidimArray<T>::ReadColumn(int x) const
{
 int rd=x;
 vector<T> column(h);
 for (int i=0; i<h; i++, rd+=w)
  column[i]=operator[](rd);
 return column;
}


---------------
-----------------------

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation

  [C] Accéder à une valeur dans un champ de bits

 

Sujets relatifs
[VB6] Tout bête bis : Accéder aux champs d'une tableMySQL selectionner une valeur
[SQL] convertir en champ texte ...Comment acceder aux t° et freq des ventilos sur une carte mère via ?
[PHP/MySQL] accéder à un champs dans un résultatrafraichir un champ en vb
[SHELL UNIX] Passer une valeur d'un script a un autre[VB6] Comment faire appel à un champ d'une table
[ASP][SQL] type de champ dans une requete[SQL] [access] problème avec requête sur un champ de type date
Plus de sujets relatifs à : [C] Accéder à une valeur dans un champ de bits


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR