/// the elf64 program header table.
#[derive(Default)]
pub struct Elf64ProgramHeaderTable {
    /// the actual sequence of program headers.
    _headers: Vec<super::Elf64ProgramHeader>,
}

impl Elf64ProgramHeaderTable {
    /// returns the number of the table entries.
    pub fn len(&self) -> usize {
        self._headers.len()
    }

    /// returns true if the table has no entry.
    pub fn is_empty(&self) -> bool {
        self._headers.is_empty()
    }

    /// initializes a new program header table.
    pub fn new<T>(it: T) -> Self
    where
        T: IntoIterator<Item = super::Elf64ProgramHeader>,
    {
        Self {
            _headers: it.into_iter().collect(),
        }
    }

    /// returns a program-header iterator.
    pub fn iter(&self) -> impl Iterator<Item = &super::Elf64ProgramHeader> {
        self._headers.iter()
    }
}

impl std::iter::IntoIterator for Elf64ProgramHeaderTable {
    type Item = super::Elf64ProgramHeader;
    type IntoIter = std::vec::IntoIter<super::Elf64ProgramHeader>;

    fn into_iter(self) -> Self::IntoIter {
        self._headers.into_iter()
    }
}

impl std::convert::From<Elf64ProgramHeaderTable> for Vec<super::Elf64ProgramHeader> {
    fn from(value: Elf64ProgramHeaderTable) -> Self {
        value._headers
    }
}

impl std::convert::From<Vec<super::Elf64ProgramHeader>> for Elf64ProgramHeaderTable {
    fn from(value: Vec<super::Elf64ProgramHeader>) -> Self {
        Self { _headers: value }
    }
}

/// the raw representation of elf64 program header table.
#[derive(Default, Debug)]
pub struct RawElf64ProgramHeaderTable {
    /// the actual sequence of program headers.
    _headers: Vec<super::RawElf64ProgramHeader>,
}

impl RawElf64ProgramHeaderTable {
    /// initializes a new program header table.
    pub fn new<T>(it: T) -> Self
    where
        T: IntoIterator<Item = super::RawElf64ProgramHeader>,
    {
        Self {
            _headers: it.into_iter().collect(),
        }
    }

    /// returns the length of the program header table.
    pub fn len(&self) -> usize {
        self._headers.len()
    }

    /// checks the table has no entries.
    pub fn is_empty(&self) -> bool {
        self._headers.is_empty()
    }

    /// returns a borrowed vector that references the tables.
    pub fn as_vec_ref(&self) -> &Vec<super::RawElf64ProgramHeader> {
        &self._headers
    }

    /// returns a program-header iterator.
    pub fn iter(&self) -> impl Iterator<Item = &super::RawElf64ProgramHeader> {
        self._headers.iter()
    }
}

impl std::iter::IntoIterator for RawElf64ProgramHeaderTable {
    type Item = super::RawElf64ProgramHeader;
    type IntoIter = std::vec::IntoIter<super::RawElf64ProgramHeader>;

    fn into_iter(self) -> Self::IntoIter {
        self._headers.into_iter()
    }
}

impl std::convert::From<RawElf64ProgramHeaderTable> for Vec<super::RawElf64ProgramHeader> {
    fn from(value: RawElf64ProgramHeaderTable) -> Self {
        value._headers
    }
}

impl std::convert::From<Vec<super::RawElf64ProgramHeader>> for RawElf64ProgramHeaderTable {
    fn from(value: Vec<super::RawElf64ProgramHeader>) -> Self {
        Self { _headers: value }
    }
}
