日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

boost源码剖析之:Tuple Types(rev#2)

發(fā)布時(shí)間:2025/3/21 编程问答 69 豆豆
生活随笔 收集整理的這篇文章主要介紹了 boost源码剖析之:Tuple Types(rev#2) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

boost源碼剖析之:Tuple Types(rev#2)

?

劉未鵬(pongba)

C++的羅浮宮(http://blog.csdn.net/pongba)

?

Note:?并非新作,04年曾放在blog上,后來(lái)刪掉了,不過(guò)網(wǎng)上到處有轉(zhuǎn)載。這是修改之后的版本。

?

動(dòng)機(jī)[1]

假設(shè)你有這樣一個(gè)函數(shù):它接受兩個(gè)整型數(shù)據(jù)并返回它們整除的結(jié)果,像這樣:

?

int?DevideInts(int?n,int?d)

{

???return?n/d;

}

?

但是我們可能需要更多信息,比如,余數(shù)。函數(shù)的返回值已被占用,我們可以為函數(shù)加一個(gè)參數(shù):

?

int?DevideInts(int?n,int?d,int& Remainder)?

{

????Remainer=n%d;?

????return?n/d;

}

?

但是這樣的函數(shù)形式未免有些拖沓丑陋。我們可以使用std::pair<>來(lái)定義函數(shù)的返回值類型(顧名思義,std::pair<>可以將兩個(gè)值湊成一對(duì)),像這樣:

?

std::pair<int,int> DevideInts(int?n,int?d)

{

????return?std::pair<int,int>(n/d,n%d);

}

?

這是個(gè)可行的方案。簡(jiǎn)潔,優(yōu)雅。

然而,這個(gè)方案只能提供兩個(gè)返回值的捆綁,如果現(xiàn)在需要返回三個(gè)int呢?唔...你可能很快想到這樣組織代碼:

?

std::pair<int,std::pair<int,int> > someFunc();

?

的確,這也能夠工作,但是畢竟不夠精致!如果返回值再增加,代碼將會(huì)愈發(fā)丑陋不堪。另一個(gè)可行的方案是自己定義一個(gè)結(jié)構(gòu)來(lái)保存三個(gè)乃至更多值,然而隨著不同函數(shù)的需要你可能需要定義各種不同的類似這樣的結(jié)構(gòu),這太費(fèi)神了。

所以,我們需要的是一個(gè)高度可復(fù)用的,能夠用來(lái)保存任意型別的任意多個(gè)變量的類——Tuple Types(Tuple的意思是“元組,數(shù)組”)。正如你所想象的,泛型正是提供代碼復(fù)用的最佳手段,它將型別信息抽象出來(lái),直到用戶真正使用那些代碼時(shí),型別信息才得以落實(shí)(所謂“具現(xiàn)化”)。

Boost庫(kù)提供了所謂的Tuple Types,它沒有std::pair的限制,于是你可以寫:

?

//tuple<>目前能夠支持多達(dá)10個(gè)模板參數(shù)

boost::tuple<int,int,int> someFunc();

?

事實(shí)上tuple能夠提供的不止這個(gè),tuple對(duì)IO流的支持能夠允許你寫這樣的代碼:

?

tuple<int,int,int> t(8,9,10);

std::cout<<t;??//輸出(8??9??10)

?

tuple甚至還支持類似的流控制,像這樣:

?

std::cout << tuples::set_open(‘[‘)

<< tuples::set_close(‘]’)

<< tuples::set_delimiter(‘,’)

<< t;

//輸出[8,9,10]

?

好了,你可能已經(jīng)不耐煩了,畢竟,以上的內(nèi)容非常淺顯。然而我必須要告訴你這些,因?yàn)槟闶紫鹊弥纓uple的設(shè)計(jì)目的才能夠去了解它。好在這個(gè)枯燥的過(guò)程已經(jīng)結(jié)束了。深吸一口氣,我們?nèi)タ匆豢磘uple的設(shè)計(jì)細(xì)節(jié)和最本質(zhì)的東西——源代碼。

?

設(shè)計(jì)目標(biāo)

首先,了解tuple的設(shè)計(jì)目標(biāo)十分重要。上面所講的只是一個(gè)總的設(shè)計(jì)目標(biāo)。下面兩個(gè)細(xì)節(jié)設(shè)計(jì)目標(biāo)才是真正需要和體現(xiàn)技術(shù)的地方(并且考慮它們?nèi)绾文軌蜃罴褜?shí)現(xiàn)是非常有趣的事情,當(dāng)然,在你的種種考慮之后,你得承認(rèn),Boost庫(kù)的設(shè)計(jì)無(wú)疑是最精致和高效的),容我向你闡述它們:

?

tuple中的數(shù)據(jù)成員的個(gè)數(shù)應(yīng)該具有某種動(dòng)態(tài)特性。具體的說(shuō)就是如果你像這樣具現(xiàn)化tuple: tuple<int,int> t。則t某種程度上應(yīng)該只需要sizeof(int)*2大小的內(nèi)存來(lái)存放它的數(shù)值,不應(yīng)該有多余的內(nèi)存分配。而如果是tuple<int,int,int> t;則sizeof(t)某種程度上應(yīng)該為sizeof(int)*3。當(dāng)然,你可以利用模板偏特化來(lái)實(shí)現(xiàn)這一點(diǎn)——為提供不同模板參數(shù)個(gè)數(shù)的tuple實(shí)現(xiàn)不同的偏特化版本(也就是說(shuō),對(duì)提供了N個(gè)模板參數(shù)的tuple準(zhǔn)備的偏特化版本中具有N個(gè)數(shù)據(jù)成員)——但是,想想這樣做的代碼數(shù)量吧!你也可以使用動(dòng)態(tài)分配底層容器的策略,然而那會(huì)帶來(lái)額外的負(fù)擔(dān),顯然不如將數(shù)據(jù)直接放在tuple對(duì)象里,況且底層容器又該如何設(shè)計(jì)呢?事實(shí)上,boost::tuple并沒有使用以上任何一種手法,它使用了一種類似Loki庫(kù)[2]里的TypeList設(shè)施的手法來(lái)定義它的底層容器,這種精致的手法利用了某種遞歸的概念,極大的減少了代碼量。后面我會(huì)為你介紹它。

tuple?必須提供某種途徑以獲取它內(nèi)部保存的數(shù)值。類似的,通過(guò)某種編譯期的遞歸,Boost極其巧妙地達(dá)到了這個(gè)目標(biāo)。遺憾的是,由于技術(shù)上的原因,當(dāng)你需要獲取第N個(gè)數(shù)據(jù)時(shí),你所提供的N必須是編譯期可計(jì)算出的常量。這也體現(xiàn)出C++泛型缺少一些運(yùn)行期的特性——是的,C++泛型幾乎完全是編譯期的。

?

其實(shí),雖然上面我只為你描述了兩個(gè)設(shè)計(jì)目標(biāo),但是實(shí)作時(shí)仍會(huì)有各種小問(wèn)題出現(xiàn)。下面的源碼剖析中我會(huì)一一為你解惑。

好吧,在你發(fā)出抱怨聲之前,我還是快點(diǎn)轉(zhuǎn)入我們的主題:

?

boost::tuple源碼剖析

boost::tuple的實(shí)現(xiàn)有許多精妙之處,真是千頭萬(wàn)緒不知從何說(shuō)起。還是從一個(gè)最簡(jiǎn)單的應(yīng)用展開吧:

?

//請(qǐng)記住它,后面我們將一直圍繞這個(gè)例子

boost::tuple<int,long,bool> myTuple(10,10,true);

?

以上簡(jiǎn)單的代碼的背后其實(shí)發(fā)生了很多事,了解了這些事你幾乎就了解了關(guān)于tuple的一大半奧秘。首先我們肯定想知道tuple的聲明是什么樣子的,在boost/tuple/detail/tuple_basic.hpp中聲明了它,其中也包括tuple幾乎所有的實(shí)現(xiàn):

?

template?<?class?T0 = null_type,?class?T1 = null_type,?class?T2 = null_type,

class?T3 = null_type,?class?T4 = null_type,?class?T5 = null_type,

class?T6 = null_type,?class?T7 = null_type,?class?T8 = null_type,

class?T9 = null_type > //?null_type是個(gè)空類

class?tuple;??//?注意這個(gè)聲明的所有模板參數(shù)都有缺省值

?

下面是boost::tuple的定義(也摘自boost/tuple/detail/tuple_basic.hpp):

?

????template?<class?T0,?class?T1,?class?T2,?class?T3,?class?T4,

???????????????class?T5,?class?T6,?class?T7,?class?T8,?class?T9>

????class?tuple :

??????public?detail::map_tuple_to_cons<T0, T1, T2, T3, T4,

T5, T6, T7, T8, T9>::type

{

// tuple的定義體十分簡(jiǎn)單,其中是若干構(gòu)造函數(shù)(將參數(shù)轉(zhuǎn)交給基類)和模板賦值操作符

??…

}; //?為了凸顯重點(diǎn),以下先講tuple的基類

?

其實(shí)tuple本身的定義并無(wú)奧秘和技巧可言,所有秘密都藏在它的基類里面,tuple只是將參數(shù)轉(zhuǎn)交給基類處理。下面我為你剖析它的基類:

?

基類大廈的構(gòu)建

?

構(gòu)建大廈的腳手架——map_tuple_to_cons<>

在我們給出的極其簡(jiǎn)單的應(yīng)用代碼中:tuple<int,long,bool> myTuple(10,10,true);其實(shí)相當(dāng)于:

?

tuple<int,long,bool,

null_type,null_type,null_type,null_type,

null_type,null_type,null_type

>?myTuple(10,10,true);

?

這是因?yàn)閠uple的定義中所有模板參數(shù)都有缺省值,所以你沒有給出值的模板參數(shù)自然會(huì)被編譯器認(rèn)為是缺省值null_type。這樣T0,T1,...,T9分別是int,long,bool,null_type,.....null_type。你發(fā)現(xiàn)基類的表現(xiàn)方式非常怪異——是一個(gè)map_tuple_to_cons<>中的內(nèi)嵌型別::type。很自然,你該知道map_tuple_to_const<>的定義,下面就是:

?

????template?<class?T0,?class?T1,?class?T2,?class?T3,?class?T4,

???????????????class?T5,?class?T6,?class?T7,?class?T8,?class?T9>

????struct?map_tuple_to_cons

????{

????//?cons<>是數(shù)據(jù)的容器,也是所有奧秘所在

????1?typedef?cons<

T0, //第一個(gè)參數(shù)T0被孤立出來(lái)

?????????typename?map_tuple_to_cons< //剩下的模板參數(shù)后跟一個(gè)null_type進(jìn)入下一輪

T1, T2, T3, T4, T5,T6, T7, T8, T9,?null_type

>::type

???????> type;

};

?

以及它的一個(gè)特化版本:

?

template?<>??//這個(gè)特化版本是終止某種遞歸式的自包含定義的關(guān)鍵,后面你會(huì)明白

struct?map_tuple_to_cons<null_type, null_type, null_type, null_type,

null_type, null_type, null_type, null_type,

null_type, null_type>

???{

??????2?typedef?null_type type;

};

?

就這么簡(jiǎn)單。但是它的機(jī)理卻并非那么明顯:上面已經(jīng)知道T0,T1,...,T9被推導(dǎo)為int,long,bool,null_type,...,null_type(其中省略號(hào)表示null_type,下同)。因此tuple的基類:

?

detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type

?

被推導(dǎo)為

?

map_tuple_to_cons<int,long,bool,null_type,...,null_type>::type

?

而根據(jù)map_tuple_to_cons的定義1,這其實(shí)就是:

?

cons<?int,

typename?map_tuple_to_cons<long,bool,null_type,...,null_type>::type

>

?

其中的
typename?map_tuple_to_cons<long,bool,null_type,...,null_type>::type
再一次涉及1處的typedef,因而它被推導(dǎo)為

?

cons<long,typename?map_tuple_to_cons<bool,null_type,...,null_type>::type>

?

所以現(xiàn)在看看基類的定義的形式被推導(dǎo)成為的樣子吧:

?

cons<int,

cons<long,

typename?map_tuple_to_cons<bool,null_type,...,null_type>::type

>?

>?

?

看出端倪了嗎?其中
typename?map_tuple_to_cons<bool,null_type,...,null_type>::type
仍然使用1處的typedef,從而為

cons<bool,

typename?map_tuple_to_cons<null_type,null_type,...,null_type>::type

>?

?

現(xiàn)在,我們推導(dǎo)至這樣一種遞歸嵌套的模式:

?

cons<int,

cons<long,

cons<bool,

typename?map_tuple_to_cons<null_type,...,null_type>::type

>?

>?

>?

?

好了,該是結(jié)束這場(chǎng)游戲的時(shí)候了,你應(yīng)該看出來(lái)了,map_tuple_to_cons<>準(zhǔn)備了一個(gè)特化版本來(lái)作為這場(chǎng)類似繞口令的遞歸式包含的休止符。所以,以上的定義再作最后一重推導(dǎo),使用2處的typedef,將
typename?map_tuple_to_cons<null_type,...,null_type>::type
推導(dǎo)為null_type,得到最終的形式:

?

cons<int,cons<long,cons<bool,null_type> > >?

//?這實(shí)際上只是為int,long,bool各分配一份空間

?

這就是tuple<int,long,bool>的基類!!現(xiàn)在,你應(yīng)該可以類似地推導(dǎo)出:如果tuple的形式為tuple<int,long,bool,double>,則其基類為:

?

cons<int,cons<long,cons<bool,cons<double,null_type> > > >

?

這樣,隨著你給出的模板參數(shù)個(gè)數(shù)的不同(意味著你要求保存的數(shù)據(jù)的個(gè)數(shù)不同,tuple的基類竟能夠呈現(xiàn)出某種動(dòng)態(tài)的特性(用戶提供的模板參數(shù)個(gè)數(shù)的變化(反映用戶需要保存的數(shù)據(jù)的個(gè)數(shù))導(dǎo)致cons<>容器的嵌套層數(shù)的變化,進(jìn)而導(dǎo)致tuple的底層內(nèi)存的分配量也作相應(yīng)變化)

map_tuple_to_cons<>以一種遞歸的方式不斷將它的第一個(gè)模板參數(shù)割裂出來(lái),并使tuple的基類呈現(xiàn)像這樣的形式:

?

cons<T0,cons<T1,cons<T2,cons<T3,... ... > > > >

?

這種遞歸當(dāng)map_tuple_to_cons<>的模板參數(shù)都為null_type時(shí)才恰好停止,由于map_tuple_to_cons<>不斷將第一個(gè)模板參數(shù)取出,并將剩余的參數(shù)在尾部添一個(gè)null_type再傳遞下去。所以當(dāng)用戶給出的模板參數(shù)全部被分離出來(lái)時(shí),map_tuple_to_cons<>所接受的參數(shù)就全部都是null_type了,于是使用其特化版本,其中將內(nèi)嵌型別type typedefnull_type。從而結(jié)束這場(chǎng)遞歸。

map_tuple_to_cons<>其實(shí)在tuple的定義中充當(dāng)了十分重要的角色,如果沒有它的介入,難道還有更簡(jiǎn)潔美妙的方式來(lái)達(dá)到這個(gè)目的嗎?

?

構(gòu)建大廈的磚石——cons<>

現(xiàn)在,你一定非常想看一看cons<>的定義,下面就是:

?

template?<class?HT,?class?TT>

???struct?cons {

?????typedef?HT head_type; //?這是個(gè)用戶提供的型別

?????typedef?TT tail_type;???//?這通常是個(gè)cons<>的具現(xiàn)體

?????????????????????????????//?以上兩個(gè)typedef很重要,并非可有可無(wú)

?????typedef

???????typename?detail::wrap_non_storeable_type<head_type>::type

stored_head_type;

3???stored_head_type?head; //?這是其中第一個(gè)數(shù)據(jù)成員

4???tail_type?tail;????????????//?第二個(gè)數(shù)據(jù)成員

?...????????????????????????//?其成員函數(shù)將在后面解釋,此處先略去

};

// cons<>還有一個(gè)偏特化版本:

template?<class?HT>

???struct?cons<HT, null_type> {

typedef?HT head_type;

?????typedef?null_type tail_type;

?????typedef?cons<HT, null_type> self_type;

?????typedef?typename

???????detail::wrap_non_storeable_type<head_type>::type stored_head_type;

?

stored_head_type?head;

//?注意,不像上面的主模板,這里沒有tail成員

?????... //?成員函數(shù)將在后面解釋

};

?

根據(jù)cons<>的定義顯示它有兩個(gè)數(shù)據(jù)成員:34兩處描述了它們,對(duì)于第一個(gè)數(shù)據(jù)成員的型別stored_head_type,往它上面看一行,它被typedef為:

?

detail::wrap_non_storeable_type<head_type>::type

//?而head_type又被typedef為HT

?

這又是個(gè)什么玩意?其實(shí)它只是用來(lái)偵測(cè)你是否使用了void型別和函數(shù)類型(所謂函數(shù)型別就是像void(int,int)這樣的型別,它表示接受兩個(gè)int型參數(shù)返回void的函數(shù)的型別,注意,它不同于函數(shù)指針型別,后者形式為void(*)(int,int),void(*f)(int,int)定義了一個(gè)函數(shù)指針f,而void f(int,int)無(wú)疑是聲明了一個(gè)函數(shù)f)來(lái)具現(xiàn)化tuple,如果是的,那它得采取特殊手段,因?yàn)檫@兩種型別不能像int那樣定義它們的變量(你見過(guò)void val;這樣定義val變量的嗎)。“但是”你急忙補(bǔ)充“這本就應(yīng)該不能通過(guò)編譯呀?”是的,寫void?val;這樣的語(yǔ)句不應(yīng)該通過(guò)編譯,寫tuple<void> myTuple;這樣的語(yǔ)句也應(yīng)該不能通過(guò)編譯。但是,typedef?void?VoidType;這樣的typedef卻應(yīng)該是能夠通過(guò)編譯的,所以typedef?tuple<void> voidTupleType;這樣的typedef也該能夠通過(guò)編譯。然而如果在cons<>里單純地寫上:

?

HT head;??//如果HTvoid則這將導(dǎo)致編譯錯(cuò)誤

?

這個(gè)成員,則tuple<void>這樣的具現(xiàn)化肯定會(huì)惹惱編譯器(因?yàn)樗鼘?huì)發(fā)覺cons<>里試圖定義一個(gè)void型的變量)

所以,對(duì)于這種情況,boost使用了wrap_non_storeable_type<>,它的定義是這樣的:

?

template?<class?T>

struct?wrap_non_storeable_type {

typedef?typename?IF<?????????????// IF<>相當(dāng)于編譯期的if...then...else

???????::boost::is_function<T>::value, //?如果為函數(shù)類型則特殊處理

non_storeable_type<T>, T??????//?如果不是函數(shù)類型則type就是T

?????>::RET type;

};

?

以及其特化版本:

?

???template?<>

struct?wrap_non_storeable_type<void> { //?如果為void型也特殊處理

?????typedef?non_storeable_type<void> type;?

???};

?

里面的non_storeable_type<>其實(shí)是函數(shù)型別void型別的外覆類,以使得它們可以合法的作為數(shù)據(jù)成員被定義。你不能將void?dataMember;作為數(shù)據(jù)成員,但你可以將non_storeable_type<void> wrappedData;作為成員。你不能將void?f(int,int)作為數(shù)據(jù)成員,但你可以將non_storeable_type<void(int,int)> wrapperdData;作為成員。但是,雖然這樣能夠使tuple<void>這樣的型別得以具現(xiàn)出來(lái),然而你仍然不能擁有它們的對(duì)象,像tuple<void> myTuple;這樣的代碼仍然無(wú)法通過(guò)編譯,原因是non_storeable_type<>模板類是這樣定義的:

?

???template?<class?T>

class?non_storeable_type {

??????non_storeable_type();??//?僅有私有的構(gòu)造函數(shù),意味著不能擁有該類的對(duì)象實(shí)體

???};

?

一旦你以tuple<void>為型別定義了一個(gè)變量,則該類內(nèi)部的成員須被初始化,而non_storeable_type<>的構(gòu)造函數(shù)為私有,所以初始化失敗,產(chǎn)生編譯錯(cuò)誤。

所有這些正符合void及函數(shù)型別的特性——能夠被typedef,卻不能擁有數(shù)據(jù)對(duì)象實(shí)體。(boost的實(shí)現(xiàn)者可真夠細(xì)心的)

好了,從細(xì)節(jié)中回過(guò)神來(lái)。我們通常顯然不會(huì)用void和函數(shù)型別來(lái)具現(xiàn)化tuple。所以,通常,cons<>內(nèi)部的兩個(gè)數(shù)據(jù)成員的型別通常其實(shí)就是:

?

?????HT head;

?????TT tail;

?

現(xiàn)在回顧我們的示例代碼:tuple<int,long,bool> myTuple;tuple<int,long,bool>的基類為:

?

????cons<int,cons<long,cons<bool,null_type> > >

?

所以,最外層的cons<>的模板參數(shù)被推導(dǎo)為:

?

typename?HT=int,typename?TT=?cons<long,cons<bool,null_type> >

?

這樣,tuple<int,long,bool>的基類cons<int,cons<long,cons<bool,null_type> > >其實(shí)只擁有兩個(gè)成員:

?

int?head;

cons<long,cons<bool,null_type> > tail; //?注意這又是一個(gè)cons<>對(duì)象

?

tail成員又是cons<>的一個(gè)對(duì)象,不同的是tail的型別不同了——具現(xiàn)化cons<>的模板參數(shù)不同。可想而知,tail內(nèi)部包含兩個(gè)成員:

?

long?head;

cons<bool,null_type> tail;

?

值得注意的是,第二個(gè)tail的型別匹配的是cons<>的偏特化版本,其中只有一個(gè)數(shù)據(jù)成員:

?

bool?head;

?

所以整個(gè)基類的內(nèi)存布局其實(shí)就是cons<>的三重嵌套。三個(gè)head數(shù)據(jù)成員就是需要分配內(nèi)存的主體。如果將這種布局?jǐn)U展,大概就像這樣:

?

?

這種布局正像一種玩具——開始是一個(gè)盒子,揭開盒子其內(nèi)部又是個(gè)更小的盒子,再揭,還是盒子...

現(xiàn)在,基類的內(nèi)存布局已經(jīng)展現(xiàn)在你面前。這一切其實(shí)就是由那個(gè)魔棒般的map_tuple_to_cons<>所造就的,它建造了這種嵌套式的結(jié)構(gòu)。這樣構(gòu)建的好處就是嵌套的重?cái)?shù)可以由用戶給出的模板參數(shù)個(gè)數(shù)來(lái)控制。前者體現(xiàn)了底層內(nèi)存的占用量(如果重?cái)?shù)為N重,則只有N個(gè)head占用內(nèi)存),后者體現(xiàn)用戶的需求量。這正是一種“按需分配”。

在基類的大廈構(gòu)架完畢后,問(wèn)題自然是,如何將材料填入這幢蜂窩般的大廈。這得從tuple的構(gòu)造函數(shù)入手,下面我就帶你作一次跟蹤。

?

初始化的全過(guò)程

然而在跟蹤之前我們須了解tuple的構(gòu)造函數(shù),因?yàn)樗谐跏蓟瘏?shù)由此進(jìn)入:

?

???template?<class?T0,?class?T1,?class?T2,?class?T3,?class?T4,

??????????????class?T5,?class?T6,?class?T7,?class?T8,?class?T9>

???class?tuple :

????public?detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type

???{

???public:

?????typedef?typename

???????detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type

inherited; //?基類

?????typedef?typename?inherited::head_type head_type;

//?基類的head_type(通常即T0,見cons<>的定義)

?????typedef?typename?inherited::tail_type tail_type;

//?基類的tail_type(一般仍為一個(gè)cons<>)

????

?????//下面有十一個(gè)構(gòu)造函數(shù),我只給出兩個(gè),其它類同,只不過(guò)參數(shù)個(gè)數(shù)增加而已

????tuple() {} //?這里也調(diào)用基類的默認(rèn)構(gòu)造函數(shù)

????

// access_traits<>的定義后面解釋

????tuple(typename?access_traits<T0>::parameter_type t0)

?????: inherited(t0, detail::cnull(),????????????// cnull函數(shù)返回null_type()對(duì)象

detail::cnull(), detail::cnull(), //?可將detail::cnull()看作null_type()

detail::cnull(), detail::cnull(),

detail::cnull(), detail::cnull(),

detail::cnull(), detail::cnull())

{ }

????tuple(typename?access_traits<T0>::parameter_type?t0,

????????typename?access_traits<T1>::parameter_type?t1) //增加了一個(gè)參數(shù)t1

????: inherited(t0, t1, detail::cnull(), detail::cnull(),

????????????????detail::cnull(), detail::cnull(), detail::cnull(),

????????????????detail::cnull(), detail::cnull(), detail::cnull())

{ }

????...

??};

?

其中構(gòu)造函數(shù)的參數(shù)型別以access_traits<>來(lái)表現(xiàn)是有原因的,它的定義如下:

?

???template?<class?T>

struct?access_traits {

?????typedef?const?T& const_type;

?????typedef?T& non_const_type;

?????typedef?const?typename?boost::remove_cv<T>::type& parameter_type;

};

?

parameter_type正是在tuple構(gòu)造函數(shù)中被用作參數(shù)型別的。先由remove_cv將T型別可能具有的const或volatile修飾符去掉,然后再加上const修飾符以及表示引用的符號(hào)&,就是parameter_type。舉個(gè)例子,如果我們給T0的模板參數(shù)為int,則typenameaccess_traits<T0>::parameter_type就是const int&。為什么要作這么麻煩的舉動(dòng),就是因?yàn)槟憧赡軙?huì)將常量或臨時(shí)對(duì)象作為參數(shù)傳遞給構(gòu)造函數(shù),而C++標(biāo)準(zhǔn)不允許它們綁定到非const引用。為什么要用引用型別作參數(shù)型別?自然是為了效率著想。

當(dāng)然,如果你想直接在tuple內(nèi)保存引用也可以,如果你將T0賦為int&,這時(shí)候parameter_type并不會(huì)被推導(dǎo)為int&&(引用的引用是非法的),原因是access_traits為此準(zhǔn)備了一個(gè)偏特化版本,如下:

?

???template?<class?T>?struct?access_traits<T&> {

??????typedef?T& const_type;

??????typedef?T& non_const_type;

??????typedef?T& parameter_type;??

???};

?

如果T0本身是個(gè)引用,則對(duì)parameter_type的推導(dǎo)將使用該偏特化版本。不過(guò)你該會(huì)發(fā)現(xiàn)這個(gè)偏特化版本中的parameter_type被定義為T&而非const T&,這是因?yàn)?#xff0c;如果你的意圖是在tuple中保存一個(gè)int&,則出現(xiàn)在構(gòu)造函數(shù)中的參數(shù)的型別就該是int&而非const int&,因?yàn)椴荒苡胏onst int&型別的參數(shù)來(lái)初始化int&型別的成員。

好吧,現(xiàn)在回到我們的例子,我們具現(xiàn)化tuple為tuple<int,long,bool>則該具現(xiàn)體的構(gòu)造函數(shù)應(yīng)該是這樣子:

?

A??tuple(){}

B??tuple(const?int& t0) : inherited(t0, detail::cnull(),...,detail::cnull()){}

C??tuple(const?int& t0,const?long& t1)

: inherited(t0,t1,detail::cnull(),...,detail::cnull())

{ }

D??tuple(const?int& t0,const?long& t1,const?bool& t2)

??: inherited(t0,t1,t2,detail::cnull(),...,detail::cnull())

{ }

E??tuple(const?int& t0,const?long& t1,const?bool& t2,const?null_type&?t3)

?:?inherited(t0,t1,t2,detail::cnull(),..)

{ } //?這不可用

...??//?其他構(gòu)造函數(shù)以此類推

?

這樣一堆構(gòu)造函數(shù),有那些可用呢。事實(shí)上,你可以有以下幾種初始化方法:

?

tuple<int,long,bool> MyTuple; //ok,所有成員默認(rèn)初始化,調(diào)用A

tuple<int,long,bool> MyTuple(10); //ok,第一個(gè)成員賦值為10,其它兩個(gè)默認(rèn)初始化,調(diào)用B

tuple<int,long,bool> MyTuple(10,10);//ok,給第一第二個(gè)成員賦值,調(diào)用C

tuple<int,long,bool> MyTuple(10,10,true);//ok,給三個(gè)成員都賦初始值,調(diào)用D

?

在tuple的構(gòu)造函數(shù)背后發(fā)生了什么事情呢?當(dāng)然是其基類的構(gòu)造函數(shù)被調(diào)用,于是我們跟蹤到cons<>的構(gòu)造函數(shù),它的代碼是這樣的:

?

???template?<class?HT,?class?TT>

struct?cons {

...

?????template?<class?T1,?class?T2,?class?T3,?class?T4,?class?T5,

????????????????class?T6,?class?T7,?class?T8,?class?T9,?class?T10>

?????cons( T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,

???????????T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )

??????????:?head?(t1),?tail?(t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())

??{ }

...

};

?

現(xiàn)在假設(shè)我們這樣初始化一個(gè)tuple:

?

tuple<int,long,bool> MyTuple(10,11,true);

?

則調(diào)用tuple的D構(gòu)造函數(shù)被喚起,并將三個(gè)參數(shù)傳給其基類,第一重cons<>將其head賦為10,再將剩下的參數(shù)悉數(shù)傳給其tail,后者又是個(gè)cons<>,它將它的head賦為11(注意,這時(shí)它接受到的第一個(gè)參數(shù)是11),然后將僅剩的true加上后面的九個(gè)null_type一股腦兒傳給它的tail—cons<bool,null_type>(最內(nèi)層的cons<>)。cons<HT,null_type>這個(gè)偏特化版本的構(gòu)造函數(shù)是獨(dú)特的,因?yàn)樗挥衕ead沒有tail成員,所以構(gòu)造函數(shù)的初始化列表里不能初始化tail:

?

???template?<class?HT>

struct?cons<HT, null_type> {

...

????template<class?T1>

????cons(T1& t1,?const?null_type&,?const?null_type&,?const?null_type&,

????????const?null_type&,?const?null_type&,?const?null_type&,

????????const?null_type&,?const?null_type&,?const?null_type&)

????:?head?(t1) {} //?只初始化僅有的head

...

};

?

當(dāng)參數(shù)被傳至最內(nèi)層cons<>,一定是至少有尾部的九個(gè)null_type。這是因?yàn)槿绻阋訬個(gè)模板參數(shù)來(lái)具現(xiàn)化tuple,則你初始化該tuple時(shí)最多只能提供N個(gè)參數(shù),因?yàn)闉镹+i個(gè)參數(shù)準(zhǔn)備的構(gòu)造函數(shù)的第N+1至N+i個(gè)參數(shù)型別將推導(dǎo)為null_type(請(qǐng)回顧上面的各個(gè)構(gòu)造函數(shù),這是因?yàn)槟銢]有提供的模板參數(shù)都默認(rèn)為null_type的緣故),而經(jīng)過(guò)cons<>構(gòu)造函數(shù)的重重“剝削”,直到最內(nèi)層cons<>的構(gòu)造函數(shù)被調(diào)用時(shí),你給出的N個(gè)參數(shù)就只剩一個(gè)了(另外還有九個(gè)null_type)。所以這個(gè)偏特化版本的構(gòu)造函數(shù)與上面的cons<>未特化版本中的并不相同。

這就是初始化的全過(guò)程。然而,事實(shí)上,在上例中,你不一定要將三個(gè)初始化參數(shù)全部給出,你可以給出0個(gè)1個(gè)或者2個(gè)。假設(shè)你這樣寫:

?

tuple<int,long,bool> MyTuple(10);

?

這將調(diào)用tuple的B構(gòu)造函數(shù),后者再將這唯一的參數(shù)后跟九個(gè)null_type傳給其基類—最外層的cons<>,這將使最外層的cons<>將其head初始化為10,然后—它將十個(gè)null_type傳給其tail的構(gòu)造函數(shù),而后者的head為long型數(shù)據(jù)成員,如果后者仍然使用上面給出的構(gòu)造函數(shù),則它會(huì)試圖用它接受的第一個(gè)參數(shù)null_type來(lái)初始化long?head成員,這將導(dǎo)致編譯錯(cuò)誤,然而事實(shí)上這種初始化方式是語(yǔ)意上被允許的,對(duì)于這種特殊情況,cons<>提供了另一個(gè)構(gòu)造函數(shù):

?

???template?<class?T2,?class?T3,?class?T4,?class?T5,

??????????????class?T6,?class?T7,?class?T8,?class?T9,?class?T10>

?????cons(?const?null_type&?t1, //?當(dāng)接受的第一個(gè)參數(shù)為null_type時(shí)

T2& t2, T3& t3, T4& t4, T5& t5,

????????????T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )

??????:?head?(),?tail?(t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())

?????{}

?

如果提供的初始化參數(shù)“不夠”,十個(gè)參數(shù)將在cons<>的某一層(還不到最后一層)被“剝削”為全是null_type,這時(shí)將匹配cons<>的這個(gè)構(gòu)造函數(shù),它將head默認(rèn)初始化(head(),而不是head(t1))。而cons<>的偏特化版本亦有類似的版本:

?

???cons(const?null_type&,

???????const?null_type&,?const?null_type&,?const?null_type&,

???????const?null_type&,?const?null_type&,?const?null_type&,

???????const?null_type&,?const?null_type&,?const?null_type&)

??: head () {}

?

這真是個(gè)隱晦繁復(fù)的過(guò)程,但愿你能理清頭緒。既然填充這幢基類“大廈”(cons<>)的材料(初始化tuple的參數(shù))都能夠被安放到位。我們也得清楚如何再將它們?nèi)〕鰜?lái)才是。這個(gè)“取”的過(guò)程又甚為精巧。

?

Tuple的取值過(guò)程

tuple允許你用這樣的方式取值:

?

someTuple.get<N>();??// get是模板函數(shù)

?

其中N必須得是編譯期可計(jì)算的常量。Boost庫(kù)的實(shí)現(xiàn)者不能實(shí)現(xiàn)這樣一個(gè)get版本——它允許你用一個(gè)變量指出想要獲取哪個(gè)元素:

?

someTuple.get(N);?????// N為變量-->錯(cuò)誤

?

這個(gè)事實(shí)是有原因的,原因就在于get函數(shù)的返回值,你知道,用戶可以將不同形式的變量保存在tuple中,但是get函數(shù)是不能在運(yùn)行期決定它的返回值的,返回值必須在編譯期就決議出來(lái)。然而用什么型別作為返回值呢?這取決于你想要保存的哪個(gè)對(duì)象。我們的例子:

?

tuple<int,long,bool> MyTuple;

?

中有三個(gè)變量。如果你寫MyTuple.get<0>()則該get的具現(xiàn)化版本的返回值將被推導(dǎo)為int。如果你寫MyTuple.get<1>()則這個(gè)get的具現(xiàn)化版本返回值將被推導(dǎo)為long。get的模板參數(shù)N就好象下標(biāo),不過(guò)卻是“型別數(shù)組”的下標(biāo)。可見,get的返回值由其模板參數(shù)決定,而所有這些都在編譯期。這就是為什么你不能試圖用變量作“下標(biāo)”來(lái)獲取tuple中的變量的原因。

顯然,我們很關(guān)心這個(gè)get模板函數(shù)是怎樣由它的模板參數(shù)(一個(gè)編譯期整型數(shù))來(lái)推導(dǎo)出其返回值的。事實(shí)上,它通過(guò)一個(gè)traits來(lái)實(shí)現(xiàn)這點(diǎn)。下面是cons<>成員get函數(shù)的源代碼:

?

template?<int?N>

???typename?access_traits<???// access_traits<>上面已經(jīng)講過(guò)

?????typename?element<N, cons<HT, TT> >::type //?element<>就是那個(gè)關(guān)鍵的traits

>::non_const_type //?注意這個(gè)復(fù)雜的返回類型

???get() {

?????return?boost::tuples::get<N>(*this);??//轉(zhuǎn)向全局的get<>函數(shù)

???}

?

所以我們下面跟蹤element<>的推導(dǎo)動(dòng)作。請(qǐng)回顧我們的例子。假設(shè)我們現(xiàn)在寫:

?

MyTuple.get<2>();

?

這將導(dǎo)致tuple<int,long,bool>::get<2>()的返回值被推導(dǎo)為bool。下面就是如何推導(dǎo)的過(guò)程:

首先,最外層cons<>的HT=int,TT=cons<long,cons<bool,null_type> >;而調(diào)用的get正是最外層的。所以,上面的代碼中element<N,cons<HT,TT> >::type被推導(dǎo)為:

?

element<2,cons<int,cons<long,cons<bool,null_type> > > >::type

?

現(xiàn)在來(lái)看一看element<>的定義吧:

?

template<int?N,?class?T> //?這個(gè)int N會(huì)遞減,以呈現(xiàn)遞歸的形式

???struct?element

???{

???private:

?????typedef?typename?T::tail_type?Next;

???????????????????????//?在cons<>內(nèi)部tail_type被typedef為TT,請(qǐng)回顧上面cons<>的代碼

???public:?????????????// cons<>內(nèi)部有兩個(gè)關(guān)鍵的typedef:head_type、tail_type

?????typedef?typename?element<N-1,?Next>::type?type; //遞歸

???};

?

???template<class?T>

???struct?element<0,T>??//遞歸至N=0時(shí),山窮水盡

???{

?????typedef?typename?T::head_type?type; //?山窮水盡時(shí)直接將head_type定義為type

???};

?

它看起來(lái)是如此的精巧簡(jiǎn)練。其中的推導(dǎo)是這樣的:

?

element<>的內(nèi)部有typedef?T::tail_type?Next;所以對(duì)于剛才我們推導(dǎo)出的:

?

element<2,cons<int,cons<long,cons<bool,null_type> > > >::type

?

其中的Next就是cons<int,cons<long,cons<bool,null_type> > >::tail_type,也就是:

?

cons<long,cons<bool,null_type> >

?

element中的type的typedef是這樣的:

?

typedef?typename?element<N-1,?Next>::type type;

?

對(duì)于本例,也就是:

?

typedef?typename?element<1, cons<long,cons<bool,null_type> > >::type?type;

?

同樣的方式,你可以推導(dǎo)出:

?

typename?element<1, cons<long,cons<bool,null_type> > >::type

?

其實(shí)就是:

?

typename?element<0,cons<bool,null_type> >::type

?

這下編譯器得采用element<>的偏特化版本了(因?yàn)榈谝粋€(gè)模板參數(shù)為0),根據(jù)偏特化版本的定義(其中對(duì)type的typedef為:typedef?typename?T::head_type?type;)你可以看出這實(shí)際就是:bool

唔,經(jīng)過(guò)重重剝削,element<>traits準(zhǔn)確無(wú)誤的將第三個(gè)元素的型別萃取了出來(lái)!

再想一下,如果N為1,那么編譯器將這樣推導(dǎo):

?

?typename?element<1, cons<int,cons<long,cons<bool,null_type> > > >::type

e???????typename?element<0, cons<long,cons<bool,null_type> > >::type

?

第二行編譯器會(huì)決定采用element<>的偏特化版本,從而這就是long

這是個(gè)由typedef和整型模板參數(shù)的遞減所構(gòu)筑的遞歸世界。編譯期的遞歸!(事實(shí)上,這種編譯期的編程被稱為metaprograming)現(xiàn)在你對(duì)這種遞歸方式應(yīng)該有充分的自信。下面還有——真正取值的過(guò)程又是個(gè)遞歸調(diào)用的過(guò)程。類似的分析方法將再次采用。

請(qǐng)回顧上面給出的get<>的源代碼,其中只有一行——調(diào)用全局的get<>模板函數(shù)并將*this傳遞給它。所以重點(diǎn)是全局的get<>函數(shù),它的源代碼是這樣的:

?

template<int?N,?class?HT,?class?TT>

???inline

typename?access_traits<??// access_traits<>的代碼請(qǐng)回顧上面

?????typename?element<N, cons<HT, TT> >::type

???>::non_const_type????????//?返回類型

???get(cons<HT, TT>& c) {???//?全局的get<>()函數(shù)

??????return?detail::get_class<N>::template?get<

?????????????????typename?access_traits<

?????????????????????typename?element<N, cons<HT, TT> >::type

?????????????????>::non_const_type

>(c);

}

?

你可以輕易看出玄機(jī)都在get_class<N>::template?get<>()上面。下面我將它的代碼挖給你看:

?

template<?int?N >??//這又是個(gè)用作遞歸之用的模板參數(shù)

???struct?get_class {

?????template<class?RET,?class?HT,?class?TT >

?????inline?static?RET get(cons<HT, TT>& t)

?????{

???????return?get_class<N-1>::template?get<RET>(t.tail);

?????}

???};

???template<>

???struct?get_class<0> {

?????template<class?RET,?class?HT,?class?TT>

?????inline?static?RET get(cons<HT, TT>& t)

?????{

???????return?t.head;

?????}

};

?

天哪,這真簡(jiǎn)潔。因?yàn)檫f歸能夠使程序變得簡(jiǎn)潔。這里的遞歸仍然是通過(guò)遞減模板參數(shù)N實(shí)現(xiàn),同時(shí)不斷將t.tail傳給get_class<N-1>::template get<RET>()直到N減為0,從而調(diào)用get_class<0>::get<RET>(),后者直接將t.head返回。就像這樣一種情境:(盒子表示cons<>,通常其中包括head元素和另一個(gè)盒子(cons<>)(除非是偏特化版本的cons<>))

有一排人,第一個(gè)人手里拿著一塊記數(shù)牌和一個(gè)盒子(記數(shù)牌上的數(shù)字表示模板參數(shù)N,盒子當(dāng)然是cons<>數(shù)據(jù)容器)。現(xiàn)在,比如說(shuō),你告訴第一個(gè)人你像要那個(gè)盒子里的4號(hào)(第五個(gè))元素(它深藏在第5重盒子里),他于是將記數(shù)牌上寫上4,然后再減去一,并將盒子打開一層,將里面的小盒子(t.tail,也是個(gè)cons<>容器,cons<>容器不正是一重套一重的嗎?)和記數(shù)牌一并傳給第二個(gè)人,第二個(gè)人將記數(shù)牌上的3減去一,然后再剝?nèi)ヒ粚雍凶?#xff0c;將里面的盒子以及記數(shù)牌(現(xiàn)在是2了)傳給下一個(gè)人,下一個(gè)人做同樣的工作,直到第5個(gè)人(get_class<0>)發(fā)現(xiàn)記數(shù)牌上為0,那么他打開盒子,將里面的head元素傳給第四個(gè),后者再傳給第三個(gè)...,一直傳至你手里。

并且,為了提高效率,get函數(shù)是inline的。

呼~是的,這真夠夸張,并且...不夠優(yōu)雅!?是的,或許它的代碼非常丑陋,然而隱藏在它背后的思想確實(shí)無(wú)與倫比的優(yōu)雅和精巧。更何況對(duì)于一個(gè)能夠應(yīng)付千萬(wàn)種情況,并具備高度復(fù)用性的類,這樣的實(shí)在可算是夠“優(yōu)雅”的了。

另外boost還提供了一個(gè)length<>來(lái)獲得tuple的長(zhǎng)度(即所含元素個(gè)數(shù))

?

template<class?T>

???struct?length {

?????static const?int?value = 1 +?length<typename?T::tail_type>::value; //遞歸

};

???template<>

???struct?length<null_type> {

????static const?int?value = 0;

};

?

我想,有了上面的經(jīng)驗(yàn),這種編譯期遞歸對(duì)于你應(yīng)該了無(wú)秘密。我就不多說(shuō)了。length<>位于namespace tuples里面。

?

最后一點(diǎn)細(xì)節(jié)

??為了方便用戶,boost庫(kù)還提供了make_tuple和tie函數(shù),前者很簡(jiǎn)單:產(chǎn)生一個(gè)臨時(shí)的tuple,你可以這樣使用它:

?

???tuple<int,long,bool> MyTuple=make_tuple(10,10,true);

?

??而tie則意為將參數(shù)綁在個(gè)tuple里面,不同的是因?yàn)槭墙?#xff0c;所以它返回的tuple保存引用,像這樣使用它:

?

???int ival=10;??long lval=10; bool bval=true;

???tuple<int&,long&,bool&> MyTuple=tie(ival,lval,bval);

???... //?這里,你修改MyTuple里的數(shù)據(jù)會(huì)直接影響到ival,lval,bval;

?

??你還可以用一行代碼來(lái)更改三個(gè)變量的值,像這樣:

?

???tie(ival,lval,bval)=make_tuple(9,9,false); //?同時(shí)更改了三個(gè)變量值

?????????????????????????????????????????????//?現(xiàn)在ival,lval,bval分別為9,9,false。

?

??你還可以忽略make_tuple()返回的部分值,像這樣:

???tie(ival,tuples::ignore,bval)=make_tuple(9,9,false);

//?只有ival,bval被更改,lval維持原值

??????// tuples::ignore是個(gè)預(yù)定義的對(duì)象,它有一個(gè)模板化的operator =函數(shù),

//?從而可以接受向它賦的任何值。

?

本文沒有涉及的

本文沒有涉及tuple對(duì)IO的支持——實(shí)際上它幾乎只是對(duì)tuple中的每一個(gè)元素進(jìn)行輸出。

?

本文沒有涉及tuple的拷貝構(gòu)造函數(shù),cons<>的拷貝構(gòu)造函數(shù),以及cons<>const成員函數(shù)——事實(shí)上,在了解了以上那些秘密后,這就微不足道了。

?

本文沒有涉及tuple提供的比較函數(shù)——事實(shí)上那比較簡(jiǎn)單,它只是轉(zhuǎn)而比較各個(gè)元素。

?

目錄(展開《boost源碼剖析》系列文章)

總結(jié)

以上是生活随笔為你收集整理的boost源码剖析之:Tuple Types(rev#2)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

国产91在线看 | 国产午夜激情视频 | 韩国av免费观看 | 日韩精品一区电影 | 午夜天天操| 色欧美88888久久久久久影院 | 日日干夜夜操视频 | 成人h电影 | 男女免费视频观看 | 精品福利在线视频 | 一本一道久久a久久综合蜜桃 | 婷婷六月天天 | 一本一道久久a久久精品 | 日韩在线视频在线观看 | 日韩精品不卡 | 蜜臀av夜夜澡人人爽人人桃色 | 国产精品麻豆三级一区视频 | 欧美激情第八页 | 日本性xxx| 一区二区三区在线观看免费 | 国产精品日韩久久久久 | 99在线视频播放 | 欧美一区二区三区特黄 | 精品福利视频在线 | 精品一二三四五区 | 国偷自产中文字幕亚洲手机在线 | 日韩视频一区二区三区在线播放免费观看 | 欧美日韩电影在线播放 | 天天爽网站 | 国产欧美精品一区aⅴ影院 99视频国产精品免费观看 | 91在线你懂的 | 亚洲专区中文字幕 | 精品毛片一区二区免费看 | 久久久国产精品久久久 | 国产成人61精品免费看片 | 国内偷拍精品视频 | 97在线观看视频国产 | 国产精品久久久久久久妇 | 99久久久国产精品免费99 | 2019免费中文字幕 | 国产精品露脸在线 | 九九九视频精品 | 日韩在线中文字幕视频 | 国产在线观看你懂得 | 91视频最新网址 | 天天综合成人 | 久在线观看 | 丁香婷婷色月天 | 国产免费又粗又猛又爽 | 成人一区二区在线观看 | 国产在线精品二区 | 69精品久久 | 欧美激情精品久久久 | 在线岛国av | 久久久久久国产精品免费 | 在线免费观看的av网站 | 精品国产伦一区二区三区免费 | 深爱五月网| 播五月综合 | 久久久激情视频 | 伊人网av | 国产一区二区在线免费播放 | 久久久久久蜜桃一区二区 | 天天干,天天射,天天操,天天摸 | 激情五月播播久久久精品 | 亚洲最大av在线播放 | 国产精选视频 | 人人干免费 | 亚洲视频axxx | 免费在线观看91 | 国产视频二区三区 | 色综合久久久久网 | 最近高清中文字幕在线国语5 | 激情视频91 | 99精品免费网 | 成人午夜影院 | 免费欧美 | 不卡中文字幕av | 国产福利专区 | 麻豆视频91 | 中文字幕一区二区三区乱码不卡 | 91麻豆精品国产自产 | 国产精品6| 天天干,天天操 | 91av在线看 | 91人人网 | 91久草视频| 在线观看免费av片 | 欧美成人性战久久 | 欧美粗又大 | 精品影院 | 蜜臀av夜夜澡人人爽人人桃色 | 国产经典三级 | 国产精品嫩草在线 | 天天射一射 | 97精品超碰一区二区三区 | 99热在线网站| 欧美色图亚洲图片 | 不卡的av电影在线观看 | 亚洲欧美成人在线 | 天堂在线视频免费观看 | 在线www色| 国产成人性色生活片 | 国产在线一线 | 日韩欧美在线播放 | 日本公乱妇视频 | 国产专区视频在线观看 | 最近中文字幕高清字幕在线视频 | 九色最新网址 | 黄污视频网站 | 日韩免费高清在线 | 色综合久久久久久中文网 | 国产精品久久久影视 | 色网站国产精品 | 国产视频美女 | 国产成人一区二区三区在线观看 | 亚洲电影久久久 | 免费亚洲精品 | 国产视频不卡 | 99在线精品观看 | 97在线观看免费观看 | 日本一区二区三区免费观看 | 看全黄大色黄大片 | 深爱婷婷网 | 国语精品久久 | 99热在线精品观看 | 欧美日韩高清一区二区 国产亚洲免费看 | 日日干日日色 | a视频免费看 | 日韩中文在线视频 | 91成年人在线观看 | 91传媒在线看 | 日韩欧美综合在线视频 | 国产99在线播放 | 中文字幕黄色av | 国内一级片在线观看 | 国产精品18久久久久久久 | 特黄特色特刺激视频免费播放 | 亚洲一区二区三区在线看 | 成人免费在线观看入口 | 久久久久国产免费免费 | 午夜色影院 | av高清一区二区三区 | 9色在线视频 | 免费网站在线观看成人 | 国产偷在线| 久久久精品网 | 91污视频在线观看 | 日日干夜夜干 | 免费日韩 精品中文字幕视频在线 | 国产亚洲一级高清 | 99久久精品国产欧美主题曲 | 婷婷综合在线 | 成人一级片视频 | www国产亚洲| 操处女逼 | 欧美日韩久久 | 久久久免费视频播放 | 国产一二三在线视频 | 夜夜干天天操 | 国产午夜精品久久 | 久操久 | 99久久爱| 成人黄大片 | 中文字幕制服丝袜av久久 | 国产欧美日韩精品一区二区免费 | 精品综合久久久 | 亚洲人av免费网站 | 久久99精品久久久久久久久久久久 | 激情久久一区二区三区 | 国产91在线看 | 黄色大片入口 | 日韩一区二区三 | 美女网站色免费 | 久久超碰网 | 国产精品一区免费在线观看 | 欧美日比视频 | 国产日韩精品一区二区三区 | 亚洲va在线va天堂va偷拍 | 日韩成人精品在线观看 | 午夜久久久影院 | 久久人人射 | 国产精品一区二区在线看 | 亚洲影院一区 | 国产麻豆视频免费观看 | 99自拍视频在线观看 | 久久精品在线免费观看 | 欧美成人h版在线观看 | 免费国产黄线在线观看视频 | 中文久草| 色视频网址| 国产一线二线三线性视频 | 特黄色大片 | 欧美激情另类 | 国产精品大全 | 国产中文视频 | 久久免费看毛片 | 亚洲一区久久 | 国产99爱| 国产在线观看你懂的 | 九九九视频精品 | 性色va| 免费在线观看av网站 | 欧美一区二区视频97 | 国产精品中文久久久久久久 | 国产在线欧美日韩 | 天天干夜夜爽 | 成人毛片一区 | 欧美a在线免费观看 | 中国精品一区二区 | 中文字幕国产精品一区二区 | 国产精品18久久久久久久网站 | 日本精品在线 | 久人人 | 一区二区欧美日韩 | 国产精品一区在线观看你懂的 | 免费日韩一区 | 综合网av | 久久国产精品久久精品国产演员表 | 激情图片区 | www.av在线.com| 国产中文视 | 男女全黄一级一级高潮免费看 | 97在线视频免费观看 | 国产精品视频一二三 | 麻豆av一区二区三区在线观看 | 国产午夜剧场 | 国产日产av | 久久九九免费 | 久久这里只有精品9 | 永久免费的啪啪网站免费观看浪潮 | 国产 视频 久久 | 国产中文字幕三区 | 久精品视频在线观看 | 久久久久久久久久久久久久电影 | 97碰碰精品嫩模在线播放 | 干天天| www.777奇米| 亚洲一级久久 | 成人久久国产 | 在线免费亚洲 | 夜夜躁天天躁很躁波 | 四虎影视精品成人 | 92国产精品久久久久首页 | 日日干狠狠操 | 超碰大片 | 黄网站色 | 国产视频精选 | 色狠狠一区二区 | 亚洲黄色大片 | 成人av在线亚洲 | 四虎成人精品永久免费av | 91一区二区三区久久久久国产乱 | 高清久久久久久 | 色偷偷网站视频 | 精品9999| 日韩经典一区二区三区 | 国产色婷婷 | 一级黄色片毛片 | 国产午夜精品在线 | 久久久久国产免费免费 | 国产性天天综合网 | 国产不卡一区二区视频 | 色综合色综合久久综合频道88 | 一区二区三区免费在线播放 | 麻豆激情电影 | 九九欧美视频 | 日本公妇在线观看高清 | 欧美日韩国产精品一区二区亚洲 | 日日夜夜婷婷 | 日本性xxx | 亚洲精品1234区 | 国产精品视频地址 | 色综合久久精品 | 黄色av三级在线 | 欧美国产精品一区二区 | 午夜av免费在线观看 | 国产精品欧美日韩在线观看 | 国产美女免费视频 | 中文字幕一区二区三 | 国产一区二区三精品久久久无广告 | 成人在线观看免费 | 亚洲精品午夜aaa久久久 | 国产精品欧美一区二区三区不卡 | 在线看黄网站 | 日韩激情中文字幕 | 在线观看av免费 | 婷婷中文在线 | 久久只精品99品免费久23小说 | 精品一区二区免费在线观看 | 国产精品三级视频 | 欧美激情xxxx性bbbb | 岛国av在线| 国产成人福利片 | 精品一区久久 | 欧美精品久久久久久久久久白贞 | 日韩精品在线观看视频 | 日韩在线电影一区二区 | 亚洲三级黄色 | 精品美女国产在线 | 二区在线播放 | 亚洲 欧洲av | 丁香花中文在线免费观看 | 黄网站app在线观看免费视频 | 这里只有精品视频在线观看 | 国产又粗又硬又爽视频 | 国产第一福利网 | 2022中文字幕在线观看 | 日日干av | 日日射av| 欧美成人91 | 国产福利不卡视频 | 最新日韩在线 | wwwav视频| 欧美日韩免费在线观看视频 | aa级黄色大片 | 日韩欧美在线视频一区二区 | 午夜三级毛片 | 天天射天天操天天 | 伊人影院av | 日韩成人黄色av | 五月婷婷激情网 | 婷婷色在线播放 | caobi视频| 中文字幕一区二区三区久久蜜桃 | 欧美日韩精品二区第二页 | 激情五月婷婷激情 | 97超碰在线久草超碰在线观看 | 久草网在线观看 | 亚洲精品国产区 | 中文字幕资源网 国产 | 国产精品视频最多的网站 | 久久久免费观看视频 | 色哟哟国产精品 | 在线99| 日本高清久久久 | 91在线观看欧美日韩 | 天天伊人狠狠 | 青青草国产免费 | 免费观看特级毛片 | 国产一区电影在线观看 | 视频成人永久免费视频 | 亚洲理论在线观看电影 | 欧美精品午夜 | 精品久久久久久久久久岛国gif | 亚洲视频久久久 | 碰天天操天天 | 黄色av观看 | 国产99久久久精品 | 日日干天天插 | 精产嫩模国品一二三区 | 久久99亚洲热视 | 久久99亚洲热视 | 99视频在线免费观看 | 香蕉视频网址 | 色偷偷网站视频 | 最新av在线免费观看 | 免费的黄色av| 欧美综合干 | 天天操偷偷干 | 青青色影院 | 日韩高清www| 在线超碰av | 韩日在线一区 | 久久在现 | 97人人射 | 中文字幕文字幕一区二区 | 在线韩国电影免费观影完整版 | 日韩在线观看视频在线 | 日韩在线电影观看 | 深爱五月激情五月 | 国产丝袜高跟 | 亚洲精品中文在线资源 | 久久少妇免费视频 | 日韩av快播电影网 | 欧美aⅴ在线观看 | 国产精品久久影院 | 免费亚洲片 | 午夜视频黄 | 中文字幕电影在线 | 98涩涩国产露脸精品国产网 | 天天操天天摸天天射 | 亚洲国产剧情 | 在线99视频| 日日干综合 | 久久高清片 | 亚洲天堂色婷婷 | 中文字幕免费高清av | 久久久久久99精品 | 中文字幕在线免费看 | av在线免费网站 | 色综合欧洲 | 一区二区三区免费在线 | 美女精品 | 麻豆你懂的 | 黄色在线成人 | 日韩在线 一区二区 | 天天操偷偷干 | 欧美在线18 | 亚洲欧洲久久久 | 国产视频欧美视频 | 国产手机在线精品 | 久久午夜精品 | 九九视频免费观看视频精品 | 免费高清在线一区 | av电影免费在线看 | 免费91在线| 福利视频一二区 | 免费看的黄色录像 | 午夜少妇av | 国产精品理论在线观看 | 97视频在线观看视频免费视频 | 又黄又爽又色无遮挡免费 | 中文av日韩 | 丝袜美腿在线视频 | 国产免费资源 | 黄色成年 | 久久深夜福利免费观看 | 日本最新中文字幕 | 久久99精品国产99久久 | 国产在线资源 | 天天弄天天操 | av三级av| 国产精品久久久久久久久久三级 | 国产精品不卡视频 | 久久99国产视频 | 黄色一级大片在线免费看国产一 | 香蕉91视频 | 色婷婷综合五月 | se视频网址 | 狠狠色伊人亚洲综合网站色 | 夜夜爱av | 人人玩人人弄 | 久久69av| 国产一级二级三级在线观看 | 免费看的黄网站软件 | 正在播放亚洲精品 | 免费在线激情电影 | 美女视频网 | 久久成人午夜 | 久久精品电影院 | 天天操夜夜逼 | 日韩欧美在线观看 | 特级a毛片 | 欧美经典久久 | 欧美人操人 | 激情婷婷| 91丨精品丨蝌蚪丨白丝jk | 天堂av官网| 丁香激情五月婷婷 | 欧洲黄色片 | 在线免费国产 | 国产自产在线视频 | 99在线视频播放 | 99久久精品免费看国产免费软件 | 久草国产精品 | 香蕉影院在线播放 | 欧美在线观看视频 | 色姑娘综合 | 在线性视频日韩欧美 | 91传媒在线观看 | 99久久精品国 | 69国产精品视频免费观看 | 97国产大学生情侣白嫩酒店 | 欧美日韩精品在线免费观看 | 午夜狠狠干 | 国产人免费人成免费视频 | 91中文字幕永久在线 | 久久,天天综合 | 欧美日韩在线免费视频 | 国产91免费看 | 国产正在播放 | 一区二区三区在线免费观看 | 午夜丰满寂寞少妇精品 | 欧美巨乳波霸 | 在线观看91久久久久久 | 国产中文 | 啪啪激情网 | 成年人黄色大片在线 | 中文字幕黄色 | 成人aⅴ视频 | www视频在线观看 | 国产精品一区二区62 | 久久手机免费视频 | 国产免费久久久久 | 日日操天天操狠狠操 | 伊人狠狠 | 深爱五月网 | 91av蜜桃 | 久久久久久免费网 | 欧美日韩不卡在线观看 | 99精品在线 | 国产精品手机看片 | 国产精品网红直播 | 久草在在线视频 | 久久经典视频 | 免费高清av在线看 | 免费视频久久久久 | 一区二区三区视频网站 | 精品一区电影 | 日日夜夜人人精品 | 天天干天天搞天天射 | 91精品啪| 99在线高清视频在线播放 | 日韩二区三区 | 香蕉久久国产 | 激情五月婷婷激情 | 久久久久久久久网站 | 五月婷在线播放 | 日韩免费在线观看网站 | 福利视频网址 | 激情在线五月天 | 久久色在线观看 | 免费色视频在线 | 国产成人精品不卡 | 免费色视频网址 | 日本久久久久久 | 亚洲免费av电影 | 88av网站| 狠狠色丁香九九婷婷综合五月 | 九九热1 | 亚洲精品玖玖玖av在线看 | 一区二区三区在线影院 | 国产亚洲精品av | 午夜精品久久久久久久久久久久久久 | 91精品在线播放 | 天天天干夜夜夜操 | 亚洲精品国产精品久久99 | 精品视频中文字幕 | 亚洲一级片av | 91精品久 | 手机看片国产日韩 | 免费看黄在线网站 | 国产h在线播放 | 国产精品a级 | 在线国产一区二区 | 久久免费精品一区二区三区 | 操老逼免费视频 | 在线观看视频在线观看 | 五月丁色 | 玖玖玖在线 | 亚洲精品国偷拍自产在线观看 | 中文字幕色播 | 久久永久免费 | 成人免费在线视频 | 91精品在线播放 | 日本中文乱码卡一卡二新区 | 久久在视频| 国产成人久久av | 天天曰天天射 | av免费电影在线观看 | 日韩精品免费一区二区在线观看 | 91精品麻豆 | 99视频在线精品国自产拍免费观看 | 91桃色在线免费观看 | 黄色91在线观看 | 国产在线欧美在线 | 伊人开心激情 | 国产高清中文字幕 | 91久久人澡人人添人人爽欧美 | 国产精品字幕 | 国产精品一区二区三区在线免费观看 | 玖玖玖影院 | av免费黄色 | 国产精品入口久久 | 91丨九色丨蝌蚪丨对白 | 麻豆传媒视频在线播放 | 欧美贵妇性狂欢 | 18做爰免费视频网站 | 国产麻豆果冻传媒在线观看 | 99久热在线精品视频观看 | 日韩在线观看一区二区三区 | 国产成人免费在线观看 | 天堂在线视频免费观看 | 狠狠干网 | 久久久久久高潮国产精品视 | 中文字幕一区在线观看视频 | 麻豆传媒电影在线观看 | 国产精品99久久久精品 | 亚洲1区 在线 | 欧美日产在线观看 | 天天操人| 久久久99国产精品免费 | 在线性视频日韩欧美 | 日韩电影一区二区三区在线观看 | a√天堂资源 | 日韩免费观看视频 | 在线观看av不卡 | 亚洲午夜av久久乱码 | 国产成人精品福利 | 五月婷婷久草 | 91视频免费 | 99久久国产免费免费 | 久久综合色天天久久综合图片 | 日韩视频一| 狠狠狠色丁香综合久久天下网 | 亚洲国产中文字幕在线观看 | 最近中文字幕mv免费高清在线 | 最近中文字幕完整视频高清1 | 天天操天天干天天操天天干 | 国产在线观看你懂的 | 人人干,人人爽 | 精品国产电影一区二区 | 中文字幕有码在线播放 | 久久国产品 | 成人av免费看 | 国产精品美女毛片真酒店 | japanesexxx乱女另类 | 三级午夜片 | 久久久久久久久艹 | 丁香婷婷激情国产高清秒播 | 婷婷丁香五 | 深爱激情五月网 | 日韩高清毛片 | 国产成人综合精品 | 久久女教师 | 国产成人久久精品 | 日韩,中文字幕 | 色视频在线观看免费 | 在线观看视频三级 | 国产v欧美 | av资源中文字幕 | 伊人中文字幕在线 | 91日韩精品一区 | 免费合欢视频成人app | 五月天中文在线 | 婷婷色资源 | 九九久久视频 | 国产区精品 | 中文字幕电影高清在线观看 | 国产精品欧美久久久久天天影视 | 97超碰精品 | 天天射天天搞 | 天天爽网站| 亚洲成熟女人毛片在线 | 欧美中文字幕第一页 | 日韩在线电影一区二区 | 天天操天天摸天天射 | 91黄视频在线 | 国产九九九视频 | 国内小视频在线观看 | 色停停五月天 | 色婷婷电影 | 免费一级黄色 | 日本女人在线观看 | 精品久久久久一区二区国产 | 99热最新在线 | 欧美综合在线观看 | 一区二区精品在线视频 | 久久精品日产第一区二区三区乱码 | 久久女教师 | 999视频在线播放 | 人人澡人人添人人爽一区二区 | 成人性生活大片 | 黄色三级免费网址 | 夜夜夜草 | 久久精品91久久久久久再现 | 四虎www.| 欧美极度另类性三渗透 | 久久噜噜少妇网站 | 成人午夜电影网站 | 久久精品成人热国产成 | 久久久久免费精品视频 | 日韩专区中文字幕 | 久久草在线免费 | 欧美精品一二三 | 97视频免费 | 国产又粗又猛又黄又爽 | 日韩字幕 | 91精品国产综合久久福利 | 免费一级日韩欧美性大片 | 狠狠色丁香婷婷综合基地 | 欧美日本在线视频 | 色综合久久五月天 | 免费在线观看91 | 午夜少妇一区二区三区 | 香蕉视频国产在线观看 | 看片的网址 | 射久久久 | 九九色网 | 人人草人人草 | 欧美日韩视频在线一区 | 免费看色的网站 | 中文字幕在线成人 | 激情电影在线观看 | 视频一区二区免费 | 在线欧美国产 | 国产黄色片久久久 | 黄色av在 | 深夜精品福利 | 亚洲少妇xxxx | 去看片| 国产精品午夜在线观看 | 久久精品视频在线播放 | 国产欧美最新羞羞视频在线观看 | a级片久久 | 国产高清日韩欧美 | 在线视频日韩欧美 | 91在线中字 | 亚洲一区不卡视频 | 久久国产精品系列 | 日韩网站在线看片你懂的 | 人人干天天干 | 五月天亚洲综合 | 亚洲午夜精品久久久 | 在线中文视频 | 超碰日韩在线 | 午夜在线日韩 | 久久午夜影视 | 国产精品麻豆果冻传媒在线播放 | a在线观看视频 | 91黄色影视 | 久久午夜网 | 最新真实国产在线视频 | 中文字幕日本电影 | 美女黄濒| 青青草视频精品 | 国产一级做a爱片久久毛片a | 激情综合亚洲精品 | 国产精品亚洲综合久久 | 人人爱爱 | 国产精品电影一区 | 国产免费作爱视频 | 国产高清在线看 | 国产在线 一区二区三区 | 一区二区三区日韩视频在线观看 | 狠狠狠狠狠狠狠狠 | 久久久久北条麻妃免费看 | 成年人免费av| 日韩精品久久久 | 久久综合婷婷 | 在线看一区二区 | 久久在线免费观看 | 成人观看视频 | 欧美久久久久久久久久 | 日韩精品一区二区在线观看视频 | 黄色片免费在线 | 综合色亚洲 | 97超碰人人模人人人爽人人爱 | 亚洲成av人片在线观看www | 成年人在线看视频 | 久久久国产精品一区二区中文 | 国产亚洲精品久久久久久久久久 | 日韩精品字幕 | 亚洲精品视频第一页 | 九九九九免费视频 | 三级免费黄色 | 久久av免费 | 成人国产一区二区 | 国产精品丝袜久久久久久久不卡 | 2019中文字幕网站 | 五月天天天操 | 黄色大全免费网站 | 欧美日韩亚洲在线观看 | 国产精品久久久久一区二区三区共 | 国内精品视频一区二区三区八戒 | 天天激情天天干 | 五月亚洲婷婷 | 99精品视频免费在线观看 | 99国产在线观看 | 91麻豆精品国产91久久久使用方法 | 欧美一级性视频 | 国产精品第一页在线观看 | www.色午夜.com | 精品一区二区久久久久久久网站 | 色com| 国产色秀视频 | 天天射,天天干 | 9992tv成人免费看片 | 狠狠操.com | 国产精品美女毛片真酒店 | 99久久精品国产一区二区三区 | 在线观看视频亚洲 | 免费网站黄 | 欧美 日韩 成人 | 国产精品成人一区二区 | 日产中文字幕 | 黄色视屏在线免费观看 | 中文字幕中文字幕 | 免费视频一区二区 | 国产专区一 | av网址最新 | 在线天堂日本 | 亚洲区视频在线观看 | 日韩av在线看 | 啪啪免费观看网站 | 97伊人网 | 国产不卡在线观看视频 | 欧美日韩精品影院 | 五月天国产 | 最新在线你懂的 | 久久看片网 | 91精品国产电影 | 色婷婷国产 | 日韩综合色 | 99精品视频一区 | 午夜私人影院 | 96精品在线| 国产精品午夜在线观看 | 91丨九色丨国产在线 | 婷婷在线免费 | 亚洲高清视频一区二区三区 | 国产在线日韩 | 国产精品刺激对白麻豆99 | 日日夜夜干 | 在线视频99 | 精品一区二区免费在线观看 | 国产视频午夜 | 国产福利精品一区二区 | 免费黄色特级片 | 成人av网页 | 夜夜躁日日躁狠狠久久88av | 国产日韩精品久久 | 在线看一区二区 | 黄色精品一区二区 | 国产精品美女久久久久久久网站 | 五月婷婷中文字幕 | 美腿丝袜一区二区三区 | 97在线视频免费看 | 午夜av在线 | 草久久久久久久 | 国产美女在线精品免费观看 | 国产99在线免费 | 在线观看91视频 | 国产 欧美 日产久久 | 亚洲男男gaygayxxxgv | 国内精品小视频 | 亚洲欧美视频一区二区三区 | 天天天天天干 | 国产a视频免费观看 | 成人黄色av网站 | 人人爽人人av | 久草视频免费在线播放 | 中文字幕久久久精品 | 婷婷视频在线观看 | 国产韩国日本高清视频 | 久久图 | 成人在线网站观看 | 亚洲妇女av| 久久久久久久亚洲精品 | 日韩大片在线免费观看 | www.久久久.com | 玖玖精品在线 | 碰超在线| 日日夜夜天天操 | 成年人视频在线免费观看 | 国产精品久久久久久69 | 99精品热 | 激情视频免费在线 | 成人亚洲综合 | 久久婷婷久久 | 在线亚洲激情 | 国产综合香蕉五月婷在线 | 国产69精品久久久久99尤 | 亚洲精品国产第一综合99久久 | 操操操影院 | 人人干天天射 | 久久久久久久免费看 | 久久精品一二区 | 中文字幕av全部资源www中文字幕在线观看 | www成人av | 国产精品国产亚洲精品看不卡15 | 色综合久久中文字幕综合网 | 91麻豆精品国产91久久久使用方法 | 色婷婷色 | 天天干天天在线 | 免费中文字幕在线观看 | 久草在线中文888 | 久草视频免费播放 | 00av视频| 天天天综合 | 97精品国产 | 久久网址| 五月婷婷视频在线 | 久草在线免费资源站 | 精品国自产在线观看 | 欧美一级片在线观看视频 | 狠狠操夜夜操 | 成人在线播放免费观看 | 亚洲一级在线观看 | 日韩剧情 | 在线观看亚洲免费视频 | 热久久视久久精品18亚洲精品 | 99色99| 99热官网 | 午夜在线日韩 | 午夜av免费在线观看 | 天堂av影院| 久久小视频 | 夜色资源站国产www在线视频 | 日本精品一区二区 | 国产精品久久亚洲 | 最近中文字幕免费观看 | 欧美大片aaa | 欧美激情综合色综合啪啪五月 | 日韩高清免费电影 | 亚洲综合在线观看视频 | 日日摸日日爽 | 好看av在线 | 久久爱综合 | 日日草av | 久久国产区 | 亚洲精品乱码久久久久久蜜桃不爽 | 中文av影院 | 天天综合网在线 | 免费视频区| 国产精品免费成人 | 国产麻豆视频网站 | 欧美日韩国产精品一区二区三区 | 日韩精品免费一区二区在线观看 | 奇米网8888| www.激情五月.com | 91福利影院在线观看 | 日p视频在线观看 | 91伊人| 国内成人综合 | 久久久影院一区二区三区 | 久久手机在线视频 | 天海翼一区二区三区免费 | www.香蕉视频在线观看 | 久久人人97超碰com | 丁香在线视频 | 黄色片免费看 | 五月婷网站 | 美女网站视频色 | 97av精品| 天天夜夜狠狠操 | 日日日视频 | av片在线观看免费 | 人人精久 | 国产成人精品不卡 | 精品一区二区三区香蕉蜜桃 | 国产一区免费看 | 色综合久久久久 | 在线国产中文字幕 | 久久久国产一区二区三区四区小说 | 中文字幕在线观看1 | 欧洲av不卡 | 国产黄网在线 | 日韩欧美一区二区三区免费观看 | 久久久精品久久日韩一区综合 | 国产在线高清视频 | 国内久久久 | 亚洲黄色在线免费观看 | 亚洲精品视频网站在线观看 | 香蕉视频在线观看免费 | 亚洲一区二区观看 | 91三级在线观看 | 精品产品国产在线不卡 | 一区二区三区四区精品 | 久久a v电影 | 黄色福利网| 九九久久精品视频 | 精品视频久久久 | 色婷婷亚洲精品 | 日韩三级视频在线看 | 一区二区三区四区五区在线 | 97超级碰碰 | 亚色视频在线观看 | 毛片美女网站 | 日韩精品观看 | 成年人网站免费在线观看 | 国产精品1024 | 在线国产视频观看 | 国产精品一区在线播放 | 日韩在线大片 | 日韩免费成人av | 美女搞黄国产视频网站 | 国产午夜精品一区二区三区 | 91福利区一区二区三区 | 天天色天天爱天天射综合 | 免费男女羞羞的视频网站中文字幕 | 国产精品久久99 | 欧美福利网址 | 亚洲人人精品 | 九九九九免费视频 | 国产在线污 | 97av视频在线观看 | 国产成人av综合色 | 蜜桃视频日韩 | 日韩欧美在线一区 | 国产福利一区二区三区视频 | 国产成人福利在线观看 | 精品久久久久久久久久久久久久久久 | 国产99在线 | 亚洲国产精品久久久 | 久久黄色片子 | 在线看的av网站 | 日韩欧美视频一区 | av中文在线观看 | 黄色国产大片 | 欧美 日韩 成人 | a√天堂中文在线 | 伊人国产在线播放 | 色天天综合久久久久综合片 | 韩日色视频 | 欧美在线视频日韩 | 国产精品网站 |